1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 29)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
159 [(UNSPECV_BLOCKAGE 0)
160 (UNSPECV_STACK_PROBE 1)
169 (UNSPECV_CMPXCHG_1 10)
170 (UNSPECV_CMPXCHG_2 11)
175 ;; Registers by name.
186 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
189 ;; In C guard expressions, put expressions which may be compile-time
190 ;; constants first. This allows for better optimization. For
191 ;; example, write "TARGET_64BIT && reload_completed", not
192 ;; "reload_completed && TARGET_64BIT".
195 ;; Processor type. This attribute must exactly match the processor_type
196 ;; enumeration in i386.h.
197 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
198 (const (symbol_ref "ix86_tune")))
200 ;; A basic instruction type. Refinements due to arguments to be
201 ;; provided in other attributes.
204 alu,alu1,negnot,imov,imovx,lea,
205 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
206 icmp,test,ibr,setcc,icmov,
207 push,pop,call,callv,leave,
209 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
210 sselog,sselog1,sseiadd,sseishft,sseimul,
211 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
212 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
213 (const_string "other"))
215 ;; Main data type used by the insn
217 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
218 (const_string "unknown"))
220 ;; The CPU unit operations uses.
221 (define_attr "unit" "integer,i387,sse,mmx,unknown"
222 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
223 (const_string "i387")
224 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
225 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
227 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
229 (eq_attr "type" "other")
230 (const_string "unknown")]
231 (const_string "integer")))
233 ;; The (bounding maximum) length of an instruction immediate.
234 (define_attr "length_immediate" ""
235 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave")
237 (eq_attr "unit" "i387,sse,mmx")
239 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
241 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
242 (eq_attr "type" "imov,test")
243 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
244 (eq_attr "type" "call")
245 (if_then_else (match_operand 0 "constant_call_address_operand" "")
248 (eq_attr "type" "callv")
249 (if_then_else (match_operand 1 "constant_call_address_operand" "")
252 ;; We don't know the size before shorten_branches. Expect
253 ;; the instruction to fit for better scheduling.
254 (eq_attr "type" "ibr")
257 (symbol_ref "/* Update immediate_length and other attributes! */
258 gcc_unreachable (),1")))
260 ;; The (bounding maximum) length of an instruction address.
261 (define_attr "length_address" ""
262 (cond [(eq_attr "type" "str,other,multi,fxch")
264 (and (eq_attr "type" "call")
265 (match_operand 0 "constant_call_address_operand" ""))
267 (and (eq_attr "type" "callv")
268 (match_operand 1 "constant_call_address_operand" ""))
271 (symbol_ref "ix86_attr_length_address_default (insn)")))
273 ;; Set when length prefix is used.
274 (define_attr "prefix_data16" ""
275 (if_then_else (ior (eq_attr "mode" "HI")
276 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
280 ;; Set when string REP prefix is used.
281 (define_attr "prefix_rep" ""
282 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
286 ;; Set when 0f opcode prefix is used.
287 (define_attr "prefix_0f" ""
289 (ior (eq_attr "type" "imovx,setcc,icmov")
290 (eq_attr "unit" "sse,mmx"))
294 ;; Set when REX opcode prefix is used.
295 (define_attr "prefix_rex" ""
296 (cond [(and (eq_attr "mode" "DI")
297 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
299 (and (eq_attr "mode" "QI")
300 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
303 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
309 ;; Set when modrm byte is used.
310 (define_attr "modrm" ""
311 (cond [(eq_attr "type" "str,leave")
313 (eq_attr "unit" "i387")
315 (and (eq_attr "type" "incdec")
316 (ior (match_operand:SI 1 "register_operand" "")
317 (match_operand:HI 1 "register_operand" "")))
319 (and (eq_attr "type" "push")
320 (not (match_operand 1 "memory_operand" "")))
322 (and (eq_attr "type" "pop")
323 (not (match_operand 0 "memory_operand" "")))
325 (and (eq_attr "type" "imov")
326 (ior (and (match_operand 0 "register_operand" "")
327 (match_operand 1 "immediate_operand" ""))
328 (ior (and (match_operand 0 "ax_reg_operand" "")
329 (match_operand 1 "memory_displacement_only_operand" ""))
330 (and (match_operand 0 "memory_displacement_only_operand" "")
331 (match_operand 1 "ax_reg_operand" "")))))
333 (and (eq_attr "type" "call")
334 (match_operand 0 "constant_call_address_operand" ""))
336 (and (eq_attr "type" "callv")
337 (match_operand 1 "constant_call_address_operand" ""))
342 ;; The (bounding maximum) length of an instruction in bytes.
343 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
344 ;; Later we may want to split them and compute proper length as for
346 (define_attr "length" ""
347 (cond [(eq_attr "type" "other,multi,fistp,frndint")
349 (eq_attr "type" "fcmp")
351 (eq_attr "unit" "i387")
353 (plus (attr "prefix_data16")
354 (attr "length_address")))]
355 (plus (plus (attr "modrm")
356 (plus (attr "prefix_0f")
357 (plus (attr "prefix_rex")
359 (plus (attr "prefix_rep")
360 (plus (attr "prefix_data16")
361 (plus (attr "length_immediate")
362 (attr "length_address")))))))
364 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
365 ;; `store' if there is a simple memory reference therein, or `unknown'
366 ;; if the instruction is complex.
368 (define_attr "memory" "none,load,store,both,unknown"
369 (cond [(eq_attr "type" "other,multi,str")
370 (const_string "unknown")
371 (eq_attr "type" "lea,fcmov,fpspc")
372 (const_string "none")
373 (eq_attr "type" "fistp,leave")
374 (const_string "both")
375 (eq_attr "type" "frndint")
376 (const_string "load")
377 (eq_attr "type" "push")
378 (if_then_else (match_operand 1 "memory_operand" "")
379 (const_string "both")
380 (const_string "store"))
381 (eq_attr "type" "pop")
382 (if_then_else (match_operand 0 "memory_operand" "")
383 (const_string "both")
384 (const_string "load"))
385 (eq_attr "type" "setcc")
386 (if_then_else (match_operand 0 "memory_operand" "")
387 (const_string "store")
388 (const_string "none"))
389 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
390 (if_then_else (ior (match_operand 0 "memory_operand" "")
391 (match_operand 1 "memory_operand" ""))
392 (const_string "load")
393 (const_string "none"))
394 (eq_attr "type" "ibr")
395 (if_then_else (match_operand 0 "memory_operand" "")
396 (const_string "load")
397 (const_string "none"))
398 (eq_attr "type" "call")
399 (if_then_else (match_operand 0 "constant_call_address_operand" "")
400 (const_string "none")
401 (const_string "load"))
402 (eq_attr "type" "callv")
403 (if_then_else (match_operand 1 "constant_call_address_operand" "")
404 (const_string "none")
405 (const_string "load"))
406 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
407 (match_operand 1 "memory_operand" ""))
408 (const_string "both")
409 (and (match_operand 0 "memory_operand" "")
410 (match_operand 1 "memory_operand" ""))
411 (const_string "both")
412 (match_operand 0 "memory_operand" "")
413 (const_string "store")
414 (match_operand 1 "memory_operand" "")
415 (const_string "load")
417 "!alu1,negnot,ishift1,
418 imov,imovx,icmp,test,
420 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
421 mmx,mmxmov,mmxcmp,mmxcvt")
422 (match_operand 2 "memory_operand" ""))
423 (const_string "load")
424 (and (eq_attr "type" "icmov")
425 (match_operand 3 "memory_operand" ""))
426 (const_string "load")
428 (const_string "none")))
430 ;; Indicates if an instruction has both an immediate and a displacement.
432 (define_attr "imm_disp" "false,true,unknown"
433 (cond [(eq_attr "type" "other,multi")
434 (const_string "unknown")
435 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
436 (and (match_operand 0 "memory_displacement_operand" "")
437 (match_operand 1 "immediate_operand" "")))
438 (const_string "true")
439 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
440 (and (match_operand 0 "memory_displacement_operand" "")
441 (match_operand 2 "immediate_operand" "")))
442 (const_string "true")
444 (const_string "false")))
446 ;; Indicates if an FP operation has an integer source.
448 (define_attr "fp_int_src" "false,true"
449 (const_string "false"))
451 ;; Defines rounding mode of an FP operation.
453 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
454 (const_string "any"))
456 ;; Describe a user's asm statement.
457 (define_asm_attributes
458 [(set_attr "length" "128")
459 (set_attr "type" "multi")])
461 ;; All x87 floating point modes
462 (define_mode_macro X87MODEF [SF DF XF])
464 ;; x87 SFmode and DFMode floating point modes
465 (define_mode_macro X87MODEF12 [SF DF])
467 ;; All integer modes handled by x87 fisttp operator.
468 (define_mode_macro X87MODEI [HI SI DI])
470 ;; All integer modes handled by integer x87 operators.
471 (define_mode_macro X87MODEI12 [HI SI])
473 ;; All SSE floating point modes
474 (define_mode_macro SSEMODEF [SF DF])
476 ;; All integer modes handled by SSE cvtts?2si* operators.
477 (define_mode_macro SSEMODEI24 [SI DI])
479 ;; SSE asm suffix for floating point modes
480 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
483 ;; Scheduling descriptions
485 (include "pentium.md")
488 (include "athlon.md")
492 ;; Operand and operator predicates and constraints
494 (include "predicates.md")
495 (include "constraints.md")
498 ;; Compare instructions.
500 ;; All compare insns have expanders that save the operands away without
501 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
502 ;; after the cmp) will actually emit the cmpM.
504 (define_expand "cmpti"
505 [(set (reg:CC FLAGS_REG)
506 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507 (match_operand:TI 1 "x86_64_general_operand" "")))]
510 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
511 operands[0] = force_reg (TImode, operands[0]);
512 ix86_compare_op0 = operands[0];
513 ix86_compare_op1 = operands[1];
517 (define_expand "cmpdi"
518 [(set (reg:CC FLAGS_REG)
519 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520 (match_operand:DI 1 "x86_64_general_operand" "")))]
523 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
524 operands[0] = force_reg (DImode, operands[0]);
525 ix86_compare_op0 = operands[0];
526 ix86_compare_op1 = operands[1];
530 (define_expand "cmpsi"
531 [(set (reg:CC FLAGS_REG)
532 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533 (match_operand:SI 1 "general_operand" "")))]
536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
537 operands[0] = force_reg (SImode, operands[0]);
538 ix86_compare_op0 = operands[0];
539 ix86_compare_op1 = operands[1];
543 (define_expand "cmphi"
544 [(set (reg:CC FLAGS_REG)
545 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546 (match_operand:HI 1 "general_operand" "")))]
549 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
550 operands[0] = force_reg (HImode, operands[0]);
551 ix86_compare_op0 = operands[0];
552 ix86_compare_op1 = operands[1];
556 (define_expand "cmpqi"
557 [(set (reg:CC FLAGS_REG)
558 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559 (match_operand:QI 1 "general_operand" "")))]
562 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
563 operands[0] = force_reg (QImode, operands[0]);
564 ix86_compare_op0 = operands[0];
565 ix86_compare_op1 = operands[1];
569 (define_insn "cmpdi_ccno_1_rex64"
570 [(set (reg FLAGS_REG)
571 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572 (match_operand:DI 1 "const0_operand" "n,n")))]
573 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
575 test{q}\t{%0, %0|%0, %0}
576 cmp{q}\t{%1, %0|%0, %1}"
577 [(set_attr "type" "test,icmp")
578 (set_attr "length_immediate" "0,1")
579 (set_attr "mode" "DI")])
581 (define_insn "*cmpdi_minus_1_rex64"
582 [(set (reg FLAGS_REG)
583 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
586 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587 "cmp{q}\t{%1, %0|%0, %1}"
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "DI")])
591 (define_expand "cmpdi_1_rex64"
592 [(set (reg:CC FLAGS_REG)
593 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594 (match_operand:DI 1 "general_operand" "")))]
598 (define_insn "cmpdi_1_insn_rex64"
599 [(set (reg FLAGS_REG)
600 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603 "cmp{q}\t{%1, %0|%0, %1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "DI")])
608 (define_insn "*cmpsi_ccno_1"
609 [(set (reg FLAGS_REG)
610 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611 (match_operand:SI 1 "const0_operand" "n,n")))]
612 "ix86_match_ccmode (insn, CCNOmode)"
614 test{l}\t{%0, %0|%0, %0}
615 cmp{l}\t{%1, %0|%0, %1}"
616 [(set_attr "type" "test,icmp")
617 (set_attr "length_immediate" "0,1")
618 (set_attr "mode" "SI")])
620 (define_insn "*cmpsi_minus_1"
621 [(set (reg FLAGS_REG)
622 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623 (match_operand:SI 1 "general_operand" "ri,mr"))
625 "ix86_match_ccmode (insn, CCGOCmode)"
626 "cmp{l}\t{%1, %0|%0, %1}"
627 [(set_attr "type" "icmp")
628 (set_attr "mode" "SI")])
630 (define_expand "cmpsi_1"
631 [(set (reg:CC FLAGS_REG)
632 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633 (match_operand:SI 1 "general_operand" "ri,mr")))]
637 (define_insn "*cmpsi_1_insn"
638 [(set (reg FLAGS_REG)
639 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640 (match_operand:SI 1 "general_operand" "ri,mr")))]
641 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
642 && ix86_match_ccmode (insn, CCmode)"
643 "cmp{l}\t{%1, %0|%0, %1}"
644 [(set_attr "type" "icmp")
645 (set_attr "mode" "SI")])
647 (define_insn "*cmphi_ccno_1"
648 [(set (reg FLAGS_REG)
649 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650 (match_operand:HI 1 "const0_operand" "n,n")))]
651 "ix86_match_ccmode (insn, CCNOmode)"
653 test{w}\t{%0, %0|%0, %0}
654 cmp{w}\t{%1, %0|%0, %1}"
655 [(set_attr "type" "test,icmp")
656 (set_attr "length_immediate" "0,1")
657 (set_attr "mode" "HI")])
659 (define_insn "*cmphi_minus_1"
660 [(set (reg FLAGS_REG)
661 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662 (match_operand:HI 1 "general_operand" "ri,mr"))
664 "ix86_match_ccmode (insn, CCGOCmode)"
665 "cmp{w}\t{%1, %0|%0, %1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "HI")])
669 (define_insn "*cmphi_1"
670 [(set (reg FLAGS_REG)
671 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672 (match_operand:HI 1 "general_operand" "ri,mr")))]
673 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
674 && ix86_match_ccmode (insn, CCmode)"
675 "cmp{w}\t{%1, %0|%0, %1}"
676 [(set_attr "type" "icmp")
677 (set_attr "mode" "HI")])
679 (define_insn "*cmpqi_ccno_1"
680 [(set (reg FLAGS_REG)
681 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682 (match_operand:QI 1 "const0_operand" "n,n")))]
683 "ix86_match_ccmode (insn, CCNOmode)"
685 test{b}\t{%0, %0|%0, %0}
686 cmp{b}\t{$0, %0|%0, 0}"
687 [(set_attr "type" "test,icmp")
688 (set_attr "length_immediate" "0,1")
689 (set_attr "mode" "QI")])
691 (define_insn "*cmpqi_1"
692 [(set (reg FLAGS_REG)
693 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694 (match_operand:QI 1 "general_operand" "qi,mq")))]
695 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
696 && ix86_match_ccmode (insn, CCmode)"
697 "cmp{b}\t{%1, %0|%0, %1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "QI")])
701 (define_insn "*cmpqi_minus_1"
702 [(set (reg FLAGS_REG)
703 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704 (match_operand:QI 1 "general_operand" "qi,mq"))
706 "ix86_match_ccmode (insn, CCGOCmode)"
707 "cmp{b}\t{%1, %0|%0, %1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "QI")])
711 (define_insn "*cmpqi_ext_1"
712 [(set (reg FLAGS_REG)
714 (match_operand:QI 0 "general_operand" "Qm")
717 (match_operand 1 "ext_register_operand" "Q")
720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%h1, %0|%0, %h1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_1_rex64"
726 [(set (reg FLAGS_REG)
728 (match_operand:QI 0 "register_operand" "Q")
731 (match_operand 1 "ext_register_operand" "Q")
734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735 "cmp{b}\t{%h1, %0|%0, %h1}"
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "QI")])
739 (define_insn "*cmpqi_ext_2"
740 [(set (reg FLAGS_REG)
744 (match_operand 0 "ext_register_operand" "Q")
747 (match_operand:QI 1 "const0_operand" "n")))]
748 "ix86_match_ccmode (insn, CCNOmode)"
750 [(set_attr "type" "test")
751 (set_attr "length_immediate" "0")
752 (set_attr "mode" "QI")])
754 (define_expand "cmpqi_ext_3"
755 [(set (reg:CC FLAGS_REG)
759 (match_operand 0 "ext_register_operand" "")
762 (match_operand:QI 1 "general_operand" "")))]
766 (define_insn "cmpqi_ext_3_insn"
767 [(set (reg FLAGS_REG)
771 (match_operand 0 "ext_register_operand" "Q")
774 (match_operand:QI 1 "general_operand" "Qmn")))]
775 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776 "cmp{b}\t{%1, %h0|%h0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "QI")])
780 (define_insn "cmpqi_ext_3_insn_rex64"
781 [(set (reg FLAGS_REG)
785 (match_operand 0 "ext_register_operand" "Q")
788 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790 "cmp{b}\t{%1, %h0|%h0, %1}"
791 [(set_attr "type" "icmp")
792 (set_attr "mode" "QI")])
794 (define_insn "*cmpqi_ext_4"
795 [(set (reg FLAGS_REG)
799 (match_operand 0 "ext_register_operand" "Q")
804 (match_operand 1 "ext_register_operand" "Q")
807 "ix86_match_ccmode (insn, CCmode)"
808 "cmp{b}\t{%h1, %h0|%h0, %h1}"
809 [(set_attr "type" "icmp")
810 (set_attr "mode" "QI")])
812 ;; These implement float point compares.
813 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
814 ;; which would allow mix and match FP modes on the compares. Which is what
815 ;; the old patterns did, but with many more of them.
817 (define_expand "cmpxf"
818 [(set (reg:CC FLAGS_REG)
819 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820 (match_operand:XF 1 "nonmemory_operand" "")))]
823 ix86_compare_op0 = operands[0];
824 ix86_compare_op1 = operands[1];
828 (define_expand "cmpdf"
829 [(set (reg:CC FLAGS_REG)
830 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
834 ix86_compare_op0 = operands[0];
835 ix86_compare_op1 = operands[1];
839 (define_expand "cmpsf"
840 [(set (reg:CC FLAGS_REG)
841 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843 "TARGET_80387 || TARGET_SSE_MATH"
845 ix86_compare_op0 = operands[0];
846 ix86_compare_op1 = operands[1];
850 ;; FP compares, step 1:
851 ;; Set the FP condition codes.
853 ;; CCFPmode compare with exceptions
854 ;; CCFPUmode compare with no exceptions
856 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
857 ;; used to manage the reg stack popping would not be preserved.
859 (define_insn "*cmpfp_0"
860 [(set (match_operand:HI 0 "register_operand" "=a")
863 (match_operand 1 "register_operand" "f")
864 (match_operand 2 "const0_operand" "X"))]
867 && FLOAT_MODE_P (GET_MODE (operands[1]))
868 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869 "* return output_fp_compare (insn, operands, 0, 0);"
870 [(set_attr "type" "multi")
871 (set_attr "unit" "i387")
873 (cond [(match_operand:SF 1 "" "")
875 (match_operand:DF 1 "" "")
878 (const_string "XF")))])
880 (define_insn "*cmpfp_sf"
881 [(set (match_operand:HI 0 "register_operand" "=a")
884 (match_operand:SF 1 "register_operand" "f")
885 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
888 "* return output_fp_compare (insn, operands, 0, 0);"
889 [(set_attr "type" "multi")
890 (set_attr "unit" "i387")
891 (set_attr "mode" "SF")])
893 (define_insn "*cmpfp_df"
894 [(set (match_operand:HI 0 "register_operand" "=a")
897 (match_operand:DF 1 "register_operand" "f")
898 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
901 "* return output_fp_compare (insn, operands, 0, 0);"
902 [(set_attr "type" "multi")
903 (set_attr "unit" "i387")
904 (set_attr "mode" "DF")])
906 (define_insn "*cmpfp_xf"
907 [(set (match_operand:HI 0 "register_operand" "=a")
910 (match_operand:XF 1 "register_operand" "f")
911 (match_operand:XF 2 "register_operand" "f"))]
914 "* return output_fp_compare (insn, operands, 0, 0);"
915 [(set_attr "type" "multi")
916 (set_attr "unit" "i387")
917 (set_attr "mode" "XF")])
919 (define_insn "*cmpfp_u"
920 [(set (match_operand:HI 0 "register_operand" "=a")
923 (match_operand 1 "register_operand" "f")
924 (match_operand 2 "register_operand" "f"))]
927 && FLOAT_MODE_P (GET_MODE (operands[1]))
928 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929 "* return output_fp_compare (insn, operands, 0, 1);"
930 [(set_attr "type" "multi")
931 (set_attr "unit" "i387")
933 (cond [(match_operand:SF 1 "" "")
935 (match_operand:DF 1 "" "")
938 (const_string "XF")))])
940 (define_insn "*cmpfp_<mode>"
941 [(set (match_operand:HI 0 "register_operand" "=a")
944 (match_operand 1 "register_operand" "f")
945 (match_operator 3 "float_operator"
946 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
948 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949 && FLOAT_MODE_P (GET_MODE (operands[1]))
950 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951 "* return output_fp_compare (insn, operands, 0, 0);"
952 [(set_attr "type" "multi")
953 (set_attr "unit" "i387")
954 (set_attr "fp_int_src" "true")
955 (set_attr "mode" "<MODE>")])
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
960 (define_insn "x86_fnstsw_1"
961 [(set (match_operand:HI 0 "register_operand" "=a")
962 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
965 [(set_attr "length" "2")
966 (set_attr "mode" "SI")
967 (set_attr "unit" "i387")])
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
972 (define_insn "x86_sahf_1"
973 [(set (reg:CC FLAGS_REG)
974 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
977 [(set_attr "length" "1")
978 (set_attr "athlon_decode" "vector")
979 (set_attr "mode" "SI")])
981 ;; Pentium Pro can do steps 1 through 3 in one go.
983 (define_insn "*cmpfp_i_mixed"
984 [(set (reg:CCFP FLAGS_REG)
985 (compare:CCFP (match_operand 0 "register_operand" "f,x")
986 (match_operand 1 "nonimmediate_operand" "f,xm")))]
988 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990 "* return output_fp_compare (insn, operands, 1, 0);"
991 [(set_attr "type" "fcmp,ssecomi")
993 (if_then_else (match_operand:SF 1 "" "")
995 (const_string "DF")))
996 (set_attr "athlon_decode" "vector")])
998 (define_insn "*cmpfp_i_sse"
999 [(set (reg:CCFP FLAGS_REG)
1000 (compare:CCFP (match_operand 0 "register_operand" "x")
1001 (match_operand 1 "nonimmediate_operand" "xm")))]
1003 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1004 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1005 "* return output_fp_compare (insn, operands, 1, 0);"
1006 [(set_attr "type" "ssecomi")
1008 (if_then_else (match_operand:SF 1 "" "")
1010 (const_string "DF")))
1011 (set_attr "athlon_decode" "vector")])
1013 (define_insn "*cmpfp_i_i387"
1014 [(set (reg:CCFP FLAGS_REG)
1015 (compare:CCFP (match_operand 0 "register_operand" "f")
1016 (match_operand 1 "register_operand" "f")))]
1017 "TARGET_80387 && TARGET_CMOVE
1018 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1019 && FLOAT_MODE_P (GET_MODE (operands[0]))
1020 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1021 "* return output_fp_compare (insn, operands, 1, 0);"
1022 [(set_attr "type" "fcmp")
1024 (cond [(match_operand:SF 1 "" "")
1026 (match_operand:DF 1 "" "")
1029 (const_string "XF")))
1030 (set_attr "athlon_decode" "vector")])
1032 (define_insn "*cmpfp_iu_mixed"
1033 [(set (reg:CCFPU FLAGS_REG)
1034 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1035 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1036 "TARGET_MIX_SSE_I387
1037 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039 "* return output_fp_compare (insn, operands, 1, 1);"
1040 [(set_attr "type" "fcmp,ssecomi")
1042 (if_then_else (match_operand:SF 1 "" "")
1044 (const_string "DF")))
1045 (set_attr "athlon_decode" "vector")])
1047 (define_insn "*cmpfp_iu_sse"
1048 [(set (reg:CCFPU FLAGS_REG)
1049 (compare:CCFPU (match_operand 0 "register_operand" "x")
1050 (match_operand 1 "nonimmediate_operand" "xm")))]
1052 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1053 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1054 "* return output_fp_compare (insn, operands, 1, 1);"
1055 [(set_attr "type" "ssecomi")
1057 (if_then_else (match_operand:SF 1 "" "")
1059 (const_string "DF")))
1060 (set_attr "athlon_decode" "vector")])
1062 (define_insn "*cmpfp_iu_387"
1063 [(set (reg:CCFPU FLAGS_REG)
1064 (compare:CCFPU (match_operand 0 "register_operand" "f")
1065 (match_operand 1 "register_operand" "f")))]
1066 "TARGET_80387 && TARGET_CMOVE
1067 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1068 && FLOAT_MODE_P (GET_MODE (operands[0]))
1069 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1070 "* return output_fp_compare (insn, operands, 1, 1);"
1071 [(set_attr "type" "fcmp")
1073 (cond [(match_operand:SF 1 "" "")
1075 (match_operand:DF 1 "" "")
1078 (const_string "XF")))
1079 (set_attr "athlon_decode" "vector")])
1081 ;; Move instructions.
1083 ;; General case of fullword move.
1085 (define_expand "movsi"
1086 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1087 (match_operand:SI 1 "general_operand" ""))]
1089 "ix86_expand_move (SImode, operands); DONE;")
1091 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1094 ;; %%% We don't use a post-inc memory reference because x86 is not a
1095 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1096 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1097 ;; targets without our curiosities, and it is just as easy to represent
1098 ;; this differently.
1100 (define_insn "*pushsi2"
1101 [(set (match_operand:SI 0 "push_operand" "=<")
1102 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1105 [(set_attr "type" "push")
1106 (set_attr "mode" "SI")])
1108 ;; For 64BIT abi we always round up to 8 bytes.
1109 (define_insn "*pushsi2_rex64"
1110 [(set (match_operand:SI 0 "push_operand" "=X")
1111 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1114 [(set_attr "type" "push")
1115 (set_attr "mode" "SI")])
1117 (define_insn "*pushsi2_prologue"
1118 [(set (match_operand:SI 0 "push_operand" "=<")
1119 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1120 (clobber (mem:BLK (scratch)))]
1123 [(set_attr "type" "push")
1124 (set_attr "mode" "SI")])
1126 (define_insn "*popsi1_epilogue"
1127 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1128 (mem:SI (reg:SI SP_REG)))
1129 (set (reg:SI SP_REG)
1130 (plus:SI (reg:SI SP_REG) (const_int 4)))
1131 (clobber (mem:BLK (scratch)))]
1134 [(set_attr "type" "pop")
1135 (set_attr "mode" "SI")])
1137 (define_insn "popsi1"
1138 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1139 (mem:SI (reg:SI SP_REG)))
1140 (set (reg:SI SP_REG)
1141 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1144 [(set_attr "type" "pop")
1145 (set_attr "mode" "SI")])
1147 (define_insn "*movsi_xor"
1148 [(set (match_operand:SI 0 "register_operand" "=r")
1149 (match_operand:SI 1 "const0_operand" "i"))
1150 (clobber (reg:CC FLAGS_REG))]
1151 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1152 "xor{l}\t{%0, %0|%0, %0}"
1153 [(set_attr "type" "alu1")
1154 (set_attr "mode" "SI")
1155 (set_attr "length_immediate" "0")])
1157 (define_insn "*movsi_or"
1158 [(set (match_operand:SI 0 "register_operand" "=r")
1159 (match_operand:SI 1 "immediate_operand" "i"))
1160 (clobber (reg:CC FLAGS_REG))]
1162 && operands[1] == constm1_rtx
1163 && (TARGET_PENTIUM || optimize_size)"
1165 operands[1] = constm1_rtx;
1166 return "or{l}\t{%1, %0|%0, %1}";
1168 [(set_attr "type" "alu1")
1169 (set_attr "mode" "SI")
1170 (set_attr "length_immediate" "1")])
1172 (define_insn "*movsi_1"
1173 [(set (match_operand:SI 0 "nonimmediate_operand"
1174 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1175 (match_operand:SI 1 "general_operand"
1176 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1177 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1179 switch (get_attr_type (insn))
1182 if (get_attr_mode (insn) == MODE_TI)
1183 return "pxor\t%0, %0";
1184 return "xorps\t%0, %0";
1187 switch (get_attr_mode (insn))
1190 return "movdqa\t{%1, %0|%0, %1}";
1192 return "movaps\t{%1, %0|%0, %1}";
1194 return "movd\t{%1, %0|%0, %1}";
1196 return "movss\t{%1, %0|%0, %1}";
1202 return "pxor\t%0, %0";
1205 if (get_attr_mode (insn) == MODE_DI)
1206 return "movq\t{%1, %0|%0, %1}";
1207 return "movd\t{%1, %0|%0, %1}";
1210 return "lea{l}\t{%1, %0|%0, %1}";
1213 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1214 return "mov{l}\t{%1, %0|%0, %1}";
1218 (cond [(eq_attr "alternative" "2")
1219 (const_string "mmxadd")
1220 (eq_attr "alternative" "3,4,5")
1221 (const_string "mmxmov")
1222 (eq_attr "alternative" "6")
1223 (const_string "sselog1")
1224 (eq_attr "alternative" "7,8,9,10,11")
1225 (const_string "ssemov")
1226 (match_operand:DI 1 "pic_32bit_operand" "")
1227 (const_string "lea")
1229 (const_string "imov")))
1231 (cond [(eq_attr "alternative" "2,3")
1233 (eq_attr "alternative" "6,7")
1235 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1236 (const_string "V4SF")
1237 (const_string "TI"))
1238 (and (eq_attr "alternative" "8,9,10,11")
1239 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1242 (const_string "SI")))])
1244 ;; Stores and loads of ax to arbitrary constant address.
1245 ;; We fake an second form of instruction to force reload to load address
1246 ;; into register when rax is not available
1247 (define_insn "*movabssi_1_rex64"
1248 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1249 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1250 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1252 movabs{l}\t{%1, %P0|%P0, %1}
1253 mov{l}\t{%1, %a0|%a0, %1}"
1254 [(set_attr "type" "imov")
1255 (set_attr "modrm" "0,*")
1256 (set_attr "length_address" "8,0")
1257 (set_attr "length_immediate" "0,*")
1258 (set_attr "memory" "store")
1259 (set_attr "mode" "SI")])
1261 (define_insn "*movabssi_2_rex64"
1262 [(set (match_operand:SI 0 "register_operand" "=a,r")
1263 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1264 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1266 movabs{l}\t{%P1, %0|%0, %P1}
1267 mov{l}\t{%a1, %0|%0, %a1}"
1268 [(set_attr "type" "imov")
1269 (set_attr "modrm" "0,*")
1270 (set_attr "length_address" "8,0")
1271 (set_attr "length_immediate" "0")
1272 (set_attr "memory" "load")
1273 (set_attr "mode" "SI")])
1275 (define_insn "*swapsi"
1276 [(set (match_operand:SI 0 "register_operand" "+r")
1277 (match_operand:SI 1 "register_operand" "+r"))
1282 [(set_attr "type" "imov")
1283 (set_attr "mode" "SI")
1284 (set_attr "pent_pair" "np")
1285 (set_attr "athlon_decode" "vector")])
1287 (define_expand "movhi"
1288 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1289 (match_operand:HI 1 "general_operand" ""))]
1291 "ix86_expand_move (HImode, operands); DONE;")
1293 (define_insn "*pushhi2"
1294 [(set (match_operand:HI 0 "push_operand" "=X")
1295 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1298 [(set_attr "type" "push")
1299 (set_attr "mode" "SI")])
1301 ;; For 64BIT abi we always round up to 8 bytes.
1302 (define_insn "*pushhi2_rex64"
1303 [(set (match_operand:HI 0 "push_operand" "=X")
1304 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1307 [(set_attr "type" "push")
1308 (set_attr "mode" "DI")])
1310 (define_insn "*movhi_1"
1311 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1312 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1313 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1315 switch (get_attr_type (insn))
1318 /* movzwl is faster than movw on p2 due to partial word stalls,
1319 though not as fast as an aligned movl. */
1320 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1322 if (get_attr_mode (insn) == MODE_SI)
1323 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1325 return "mov{w}\t{%1, %0|%0, %1}";
1329 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1330 (const_string "imov")
1331 (and (eq_attr "alternative" "0")
1332 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1334 (eq (symbol_ref "TARGET_HIMODE_MATH")
1336 (const_string "imov")
1337 (and (eq_attr "alternative" "1,2")
1338 (match_operand:HI 1 "aligned_operand" ""))
1339 (const_string "imov")
1340 (and (ne (symbol_ref "TARGET_MOVX")
1342 (eq_attr "alternative" "0,2"))
1343 (const_string "imovx")
1345 (const_string "imov")))
1347 (cond [(eq_attr "type" "imovx")
1349 (and (eq_attr "alternative" "1,2")
1350 (match_operand:HI 1 "aligned_operand" ""))
1352 (and (eq_attr "alternative" "0")
1353 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1355 (eq (symbol_ref "TARGET_HIMODE_MATH")
1359 (const_string "HI")))])
1361 ;; Stores and loads of ax to arbitrary constant address.
1362 ;; We fake an second form of instruction to force reload to load address
1363 ;; into register when rax is not available
1364 (define_insn "*movabshi_1_rex64"
1365 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1366 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1367 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1369 movabs{w}\t{%1, %P0|%P0, %1}
1370 mov{w}\t{%1, %a0|%a0, %1}"
1371 [(set_attr "type" "imov")
1372 (set_attr "modrm" "0,*")
1373 (set_attr "length_address" "8,0")
1374 (set_attr "length_immediate" "0,*")
1375 (set_attr "memory" "store")
1376 (set_attr "mode" "HI")])
1378 (define_insn "*movabshi_2_rex64"
1379 [(set (match_operand:HI 0 "register_operand" "=a,r")
1380 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1381 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1383 movabs{w}\t{%P1, %0|%0, %P1}
1384 mov{w}\t{%a1, %0|%0, %a1}"
1385 [(set_attr "type" "imov")
1386 (set_attr "modrm" "0,*")
1387 (set_attr "length_address" "8,0")
1388 (set_attr "length_immediate" "0")
1389 (set_attr "memory" "load")
1390 (set_attr "mode" "HI")])
1392 (define_insn "*swaphi_1"
1393 [(set (match_operand:HI 0 "register_operand" "+r")
1394 (match_operand:HI 1 "register_operand" "+r"))
1397 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1399 [(set_attr "type" "imov")
1400 (set_attr "mode" "SI")
1401 (set_attr "pent_pair" "np")
1402 (set_attr "athlon_decode" "vector")])
1404 (define_insn "*swaphi_2"
1405 [(set (match_operand:HI 0 "register_operand" "+r")
1406 (match_operand:HI 1 "register_operand" "+r"))
1409 "TARGET_PARTIAL_REG_STALL"
1411 [(set_attr "type" "imov")
1412 (set_attr "mode" "HI")
1413 (set_attr "pent_pair" "np")
1414 (set_attr "athlon_decode" "vector")])
1416 (define_expand "movstricthi"
1417 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1418 (match_operand:HI 1 "general_operand" ""))]
1419 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1421 /* Don't generate memory->memory moves, go through a register */
1422 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1423 operands[1] = force_reg (HImode, operands[1]);
1426 (define_insn "*movstricthi_1"
1427 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1428 (match_operand:HI 1 "general_operand" "rn,m"))]
1429 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1430 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1431 "mov{w}\t{%1, %0|%0, %1}"
1432 [(set_attr "type" "imov")
1433 (set_attr "mode" "HI")])
1435 (define_insn "*movstricthi_xor"
1436 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1437 (match_operand:HI 1 "const0_operand" "i"))
1438 (clobber (reg:CC FLAGS_REG))]
1440 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1441 "xor{w}\t{%0, %0|%0, %0}"
1442 [(set_attr "type" "alu1")
1443 (set_attr "mode" "HI")
1444 (set_attr "length_immediate" "0")])
1446 (define_expand "movqi"
1447 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1448 (match_operand:QI 1 "general_operand" ""))]
1450 "ix86_expand_move (QImode, operands); DONE;")
1452 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1453 ;; "push a byte". But actually we use pushl, which has the effect
1454 ;; of rounding the amount pushed up to a word.
1456 (define_insn "*pushqi2"
1457 [(set (match_operand:QI 0 "push_operand" "=X")
1458 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1461 [(set_attr "type" "push")
1462 (set_attr "mode" "SI")])
1464 ;; For 64BIT abi we always round up to 8 bytes.
1465 (define_insn "*pushqi2_rex64"
1466 [(set (match_operand:QI 0 "push_operand" "=X")
1467 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1470 [(set_attr "type" "push")
1471 (set_attr "mode" "DI")])
1473 ;; Situation is quite tricky about when to choose full sized (SImode) move
1474 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1475 ;; partial register dependency machines (such as AMD Athlon), where QImode
1476 ;; moves issue extra dependency and for partial register stalls machines
1477 ;; that don't use QImode patterns (and QImode move cause stall on the next
1480 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1481 ;; register stall machines with, where we use QImode instructions, since
1482 ;; partial register stall can be caused there. Then we use movzx.
1483 (define_insn "*movqi_1"
1484 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1485 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1486 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1488 switch (get_attr_type (insn))
1491 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1492 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1494 if (get_attr_mode (insn) == MODE_SI)
1495 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1497 return "mov{b}\t{%1, %0|%0, %1}";
1501 (cond [(and (eq_attr "alternative" "5")
1502 (not (match_operand:QI 1 "aligned_operand" "")))
1503 (const_string "imovx")
1504 (ne (symbol_ref "optimize_size") (const_int 0))
1505 (const_string "imov")
1506 (and (eq_attr "alternative" "3")
1507 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1509 (eq (symbol_ref "TARGET_QIMODE_MATH")
1511 (const_string "imov")
1512 (eq_attr "alternative" "3,5")
1513 (const_string "imovx")
1514 (and (ne (symbol_ref "TARGET_MOVX")
1516 (eq_attr "alternative" "2"))
1517 (const_string "imovx")
1519 (const_string "imov")))
1521 (cond [(eq_attr "alternative" "3,4,5")
1523 (eq_attr "alternative" "6")
1525 (eq_attr "type" "imovx")
1527 (and (eq_attr "type" "imov")
1528 (and (eq_attr "alternative" "0,1")
1529 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1531 (and (eq (symbol_ref "optimize_size")
1533 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1536 ;; Avoid partial register stalls when not using QImode arithmetic
1537 (and (eq_attr "type" "imov")
1538 (and (eq_attr "alternative" "0,1")
1539 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1541 (eq (symbol_ref "TARGET_QIMODE_MATH")
1545 (const_string "QI")))])
1547 (define_expand "reload_outqi"
1548 [(parallel [(match_operand:QI 0 "" "=m")
1549 (match_operand:QI 1 "register_operand" "r")
1550 (match_operand:QI 2 "register_operand" "=&q")])]
1554 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1556 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1557 if (! q_regs_operand (op1, QImode))
1559 emit_insn (gen_movqi (op2, op1));
1562 emit_insn (gen_movqi (op0, op1));
1566 (define_insn "*swapqi_1"
1567 [(set (match_operand:QI 0 "register_operand" "+r")
1568 (match_operand:QI 1 "register_operand" "+r"))
1571 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1573 [(set_attr "type" "imov")
1574 (set_attr "mode" "SI")
1575 (set_attr "pent_pair" "np")
1576 (set_attr "athlon_decode" "vector")])
1578 (define_insn "*swapqi_2"
1579 [(set (match_operand:QI 0 "register_operand" "+q")
1580 (match_operand:QI 1 "register_operand" "+q"))
1583 "TARGET_PARTIAL_REG_STALL"
1585 [(set_attr "type" "imov")
1586 (set_attr "mode" "QI")
1587 (set_attr "pent_pair" "np")
1588 (set_attr "athlon_decode" "vector")])
1590 (define_expand "movstrictqi"
1591 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1592 (match_operand:QI 1 "general_operand" ""))]
1593 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1595 /* Don't generate memory->memory moves, go through a register. */
1596 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1597 operands[1] = force_reg (QImode, operands[1]);
1600 (define_insn "*movstrictqi_1"
1601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1602 (match_operand:QI 1 "general_operand" "*qn,m"))]
1603 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1604 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1605 "mov{b}\t{%1, %0|%0, %1}"
1606 [(set_attr "type" "imov")
1607 (set_attr "mode" "QI")])
1609 (define_insn "*movstrictqi_xor"
1610 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1611 (match_operand:QI 1 "const0_operand" "i"))
1612 (clobber (reg:CC FLAGS_REG))]
1613 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1614 "xor{b}\t{%0, %0|%0, %0}"
1615 [(set_attr "type" "alu1")
1616 (set_attr "mode" "QI")
1617 (set_attr "length_immediate" "0")])
1619 (define_insn "*movsi_extv_1"
1620 [(set (match_operand:SI 0 "register_operand" "=R")
1621 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1625 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1626 [(set_attr "type" "imovx")
1627 (set_attr "mode" "SI")])
1629 (define_insn "*movhi_extv_1"
1630 [(set (match_operand:HI 0 "register_operand" "=R")
1631 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1635 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1636 [(set_attr "type" "imovx")
1637 (set_attr "mode" "SI")])
1639 (define_insn "*movqi_extv_1"
1640 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1641 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1646 switch (get_attr_type (insn))
1649 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1651 return "mov{b}\t{%h1, %0|%0, %h1}";
1655 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1656 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1657 (ne (symbol_ref "TARGET_MOVX")
1659 (const_string "imovx")
1660 (const_string "imov")))
1662 (if_then_else (eq_attr "type" "imovx")
1664 (const_string "QI")))])
1666 (define_insn "*movqi_extv_1_rex64"
1667 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1668 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1673 switch (get_attr_type (insn))
1676 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1678 return "mov{b}\t{%h1, %0|%0, %h1}";
1682 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1683 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1684 (ne (symbol_ref "TARGET_MOVX")
1686 (const_string "imovx")
1687 (const_string "imov")))
1689 (if_then_else (eq_attr "type" "imovx")
1691 (const_string "QI")))])
1693 ;; Stores and loads of ax to arbitrary constant address.
1694 ;; We fake an second form of instruction to force reload to load address
1695 ;; into register when rax is not available
1696 (define_insn "*movabsqi_1_rex64"
1697 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1698 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1699 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1701 movabs{b}\t{%1, %P0|%P0, %1}
1702 mov{b}\t{%1, %a0|%a0, %1}"
1703 [(set_attr "type" "imov")
1704 (set_attr "modrm" "0,*")
1705 (set_attr "length_address" "8,0")
1706 (set_attr "length_immediate" "0,*")
1707 (set_attr "memory" "store")
1708 (set_attr "mode" "QI")])
1710 (define_insn "*movabsqi_2_rex64"
1711 [(set (match_operand:QI 0 "register_operand" "=a,r")
1712 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1713 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1715 movabs{b}\t{%P1, %0|%0, %P1}
1716 mov{b}\t{%a1, %0|%0, %a1}"
1717 [(set_attr "type" "imov")
1718 (set_attr "modrm" "0,*")
1719 (set_attr "length_address" "8,0")
1720 (set_attr "length_immediate" "0")
1721 (set_attr "memory" "load")
1722 (set_attr "mode" "QI")])
1724 (define_insn "*movdi_extzv_1"
1725 [(set (match_operand:DI 0 "register_operand" "=R")
1726 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1730 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1731 [(set_attr "type" "imovx")
1732 (set_attr "mode" "DI")])
1734 (define_insn "*movsi_extzv_1"
1735 [(set (match_operand:SI 0 "register_operand" "=R")
1736 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1740 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1741 [(set_attr "type" "imovx")
1742 (set_attr "mode" "SI")])
1744 (define_insn "*movqi_extzv_2"
1745 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1746 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1751 switch (get_attr_type (insn))
1754 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1756 return "mov{b}\t{%h1, %0|%0, %h1}";
1760 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1761 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1762 (ne (symbol_ref "TARGET_MOVX")
1764 (const_string "imovx")
1765 (const_string "imov")))
1767 (if_then_else (eq_attr "type" "imovx")
1769 (const_string "QI")))])
1771 (define_insn "*movqi_extzv_2_rex64"
1772 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1773 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1778 switch (get_attr_type (insn))
1781 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1783 return "mov{b}\t{%h1, %0|%0, %h1}";
1787 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1788 (ne (symbol_ref "TARGET_MOVX")
1790 (const_string "imovx")
1791 (const_string "imov")))
1793 (if_then_else (eq_attr "type" "imovx")
1795 (const_string "QI")))])
1797 (define_insn "movsi_insv_1"
1798 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1801 (match_operand:SI 1 "general_operand" "Qmn"))]
1803 "mov{b}\t{%b1, %h0|%h0, %b1}"
1804 [(set_attr "type" "imov")
1805 (set_attr "mode" "QI")])
1807 (define_insn "*movsi_insv_1_rex64"
1808 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1813 "mov{b}\t{%b1, %h0|%h0, %b1}"
1814 [(set_attr "type" "imov")
1815 (set_attr "mode" "QI")])
1817 (define_insn "movdi_insv_1_rex64"
1818 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1821 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1823 "mov{b}\t{%b1, %h0|%h0, %b1}"
1824 [(set_attr "type" "imov")
1825 (set_attr "mode" "QI")])
1827 (define_insn "*movqi_insv_2"
1828 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1831 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1834 "mov{b}\t{%h1, %h0|%h0, %h1}"
1835 [(set_attr "type" "imov")
1836 (set_attr "mode" "QI")])
1838 (define_expand "movdi"
1839 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1840 (match_operand:DI 1 "general_operand" ""))]
1842 "ix86_expand_move (DImode, operands); DONE;")
1844 (define_insn "*pushdi"
1845 [(set (match_operand:DI 0 "push_operand" "=<")
1846 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1850 (define_insn "*pushdi2_rex64"
1851 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1852 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1857 [(set_attr "type" "push,multi")
1858 (set_attr "mode" "DI")])
1860 ;; Convert impossible pushes of immediate to existing instructions.
1861 ;; First try to get scratch register and go through it. In case this
1862 ;; fails, push sign extended lower part first and then overwrite
1863 ;; upper part by 32bit move.
1865 [(match_scratch:DI 2 "r")
1866 (set (match_operand:DI 0 "push_operand" "")
1867 (match_operand:DI 1 "immediate_operand" ""))]
1868 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1869 && !x86_64_immediate_operand (operands[1], DImode)"
1870 [(set (match_dup 2) (match_dup 1))
1871 (set (match_dup 0) (match_dup 2))]
1874 ;; We need to define this as both peepholer and splitter for case
1875 ;; peephole2 pass is not run.
1876 ;; "&& 1" is needed to keep it from matching the previous pattern.
1878 [(set (match_operand:DI 0 "push_operand" "")
1879 (match_operand:DI 1 "immediate_operand" ""))]
1880 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1881 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1882 [(set (match_dup 0) (match_dup 1))
1883 (set (match_dup 2) (match_dup 3))]
1884 "split_di (operands + 1, 1, operands + 2, operands + 3);
1885 operands[1] = gen_lowpart (DImode, operands[2]);
1886 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1891 [(set (match_operand:DI 0 "push_operand" "")
1892 (match_operand:DI 1 "immediate_operand" ""))]
1893 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1894 ? flow2_completed : reload_completed)
1895 && !symbolic_operand (operands[1], DImode)
1896 && !x86_64_immediate_operand (operands[1], DImode)"
1897 [(set (match_dup 0) (match_dup 1))
1898 (set (match_dup 2) (match_dup 3))]
1899 "split_di (operands + 1, 1, operands + 2, operands + 3);
1900 operands[1] = gen_lowpart (DImode, operands[2]);
1901 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1905 (define_insn "*pushdi2_prologue_rex64"
1906 [(set (match_operand:DI 0 "push_operand" "=<")
1907 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1908 (clobber (mem:BLK (scratch)))]
1911 [(set_attr "type" "push")
1912 (set_attr "mode" "DI")])
1914 (define_insn "*popdi1_epilogue_rex64"
1915 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1916 (mem:DI (reg:DI SP_REG)))
1917 (set (reg:DI SP_REG)
1918 (plus:DI (reg:DI SP_REG) (const_int 8)))
1919 (clobber (mem:BLK (scratch)))]
1922 [(set_attr "type" "pop")
1923 (set_attr "mode" "DI")])
1925 (define_insn "popdi1"
1926 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1927 (mem:DI (reg:DI SP_REG)))
1928 (set (reg:DI SP_REG)
1929 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1932 [(set_attr "type" "pop")
1933 (set_attr "mode" "DI")])
1935 (define_insn "*movdi_xor_rex64"
1936 [(set (match_operand:DI 0 "register_operand" "=r")
1937 (match_operand:DI 1 "const0_operand" "i"))
1938 (clobber (reg:CC FLAGS_REG))]
1939 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1940 && reload_completed"
1941 "xor{l}\t{%k0, %k0|%k0, %k0}"
1942 [(set_attr "type" "alu1")
1943 (set_attr "mode" "SI")
1944 (set_attr "length_immediate" "0")])
1946 (define_insn "*movdi_or_rex64"
1947 [(set (match_operand:DI 0 "register_operand" "=r")
1948 (match_operand:DI 1 "const_int_operand" "i"))
1949 (clobber (reg:CC FLAGS_REG))]
1950 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1952 && operands[1] == constm1_rtx"
1954 operands[1] = constm1_rtx;
1955 return "or{q}\t{%1, %0|%0, %1}";
1957 [(set_attr "type" "alu1")
1958 (set_attr "mode" "DI")
1959 (set_attr "length_immediate" "1")])
1961 (define_insn "*movdi_2"
1962 [(set (match_operand:DI 0 "nonimmediate_operand"
1963 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1964 (match_operand:DI 1 "general_operand"
1965 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1966 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971 movq\t{%1, %0|%0, %1}
1972 movq\t{%1, %0|%0, %1}
1974 movq\t{%1, %0|%0, %1}
1975 movdqa\t{%1, %0|%0, %1}
1976 movq\t{%1, %0|%0, %1}
1978 movlps\t{%1, %0|%0, %1}
1979 movaps\t{%1, %0|%0, %1}
1980 movlps\t{%1, %0|%0, %1}"
1981 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1982 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1985 [(set (match_operand:DI 0 "push_operand" "")
1986 (match_operand:DI 1 "general_operand" ""))]
1987 "!TARGET_64BIT && reload_completed
1988 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1990 "ix86_split_long_move (operands); DONE;")
1992 ;; %%% This multiword shite has got to go.
1994 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1995 (match_operand:DI 1 "general_operand" ""))]
1996 "!TARGET_64BIT && reload_completed
1997 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1998 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2000 "ix86_split_long_move (operands); DONE;")
2002 (define_insn "*movdi_1_rex64"
2003 [(set (match_operand:DI 0 "nonimmediate_operand"
2004 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2005 (match_operand:DI 1 "general_operand"
2006 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2007 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2009 switch (get_attr_type (insn))
2012 if (which_alternative == 13)
2013 return "movq2dq\t{%1, %0|%0, %1}";
2015 return "movdq2q\t{%1, %0|%0, %1}";
2017 if (get_attr_mode (insn) == MODE_TI)
2018 return "movdqa\t{%1, %0|%0, %1}";
2021 /* Moves from and into integer register is done using movd opcode with
2023 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2024 return "movd\t{%1, %0|%0, %1}";
2025 return "movq\t{%1, %0|%0, %1}";
2028 return "pxor\t%0, %0";
2032 return "lea{q}\t{%a1, %0|%0, %a1}";
2034 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2035 if (get_attr_mode (insn) == MODE_SI)
2036 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2037 else if (which_alternative == 2)
2038 return "movabs{q}\t{%1, %0|%0, %1}";
2040 return "mov{q}\t{%1, %0|%0, %1}";
2044 (cond [(eq_attr "alternative" "5")
2045 (const_string "mmxadd")
2046 (eq_attr "alternative" "6,7,8")
2047 (const_string "mmxmov")
2048 (eq_attr "alternative" "9")
2049 (const_string "sselog1")
2050 (eq_attr "alternative" "10,11,12")
2051 (const_string "ssemov")
2052 (eq_attr "alternative" "13,14")
2053 (const_string "ssecvt")
2054 (eq_attr "alternative" "4")
2055 (const_string "multi")
2056 (match_operand:DI 1 "pic_32bit_operand" "")
2057 (const_string "lea")
2059 (const_string "imov")))
2060 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2061 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2062 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2064 ;; Stores and loads of ax to arbitrary constant address.
2065 ;; We fake an second form of instruction to force reload to load address
2066 ;; into register when rax is not available
2067 (define_insn "*movabsdi_1_rex64"
2068 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2069 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2070 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2072 movabs{q}\t{%1, %P0|%P0, %1}
2073 mov{q}\t{%1, %a0|%a0, %1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "modrm" "0,*")
2076 (set_attr "length_address" "8,0")
2077 (set_attr "length_immediate" "0,*")
2078 (set_attr "memory" "store")
2079 (set_attr "mode" "DI")])
2081 (define_insn "*movabsdi_2_rex64"
2082 [(set (match_operand:DI 0 "register_operand" "=a,r")
2083 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2084 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2086 movabs{q}\t{%P1, %0|%0, %P1}
2087 mov{q}\t{%a1, %0|%0, %a1}"
2088 [(set_attr "type" "imov")
2089 (set_attr "modrm" "0,*")
2090 (set_attr "length_address" "8,0")
2091 (set_attr "length_immediate" "0")
2092 (set_attr "memory" "load")
2093 (set_attr "mode" "DI")])
2095 ;; Convert impossible stores of immediate to existing instructions.
2096 ;; First try to get scratch register and go through it. In case this
2097 ;; fails, move by 32bit parts.
2099 [(match_scratch:DI 2 "r")
2100 (set (match_operand:DI 0 "memory_operand" "")
2101 (match_operand:DI 1 "immediate_operand" ""))]
2102 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2103 && !x86_64_immediate_operand (operands[1], DImode)"
2104 [(set (match_dup 2) (match_dup 1))
2105 (set (match_dup 0) (match_dup 2))]
2108 ;; We need to define this as both peepholer and splitter for case
2109 ;; peephole2 pass is not run.
2110 ;; "&& 1" is needed to keep it from matching the previous pattern.
2112 [(set (match_operand:DI 0 "memory_operand" "")
2113 (match_operand:DI 1 "immediate_operand" ""))]
2114 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2115 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2116 [(set (match_dup 2) (match_dup 3))
2117 (set (match_dup 4) (match_dup 5))]
2118 "split_di (operands, 2, operands + 2, operands + 4);")
2121 [(set (match_operand:DI 0 "memory_operand" "")
2122 (match_operand:DI 1 "immediate_operand" ""))]
2123 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2124 ? flow2_completed : reload_completed)
2125 && !symbolic_operand (operands[1], DImode)
2126 && !x86_64_immediate_operand (operands[1], DImode)"
2127 [(set (match_dup 2) (match_dup 3))
2128 (set (match_dup 4) (match_dup 5))]
2129 "split_di (operands, 2, operands + 2, operands + 4);")
2131 (define_insn "*swapdi_rex64"
2132 [(set (match_operand:DI 0 "register_operand" "+r")
2133 (match_operand:DI 1 "register_operand" "+r"))
2138 [(set_attr "type" "imov")
2139 (set_attr "mode" "DI")
2140 (set_attr "pent_pair" "np")
2141 (set_attr "athlon_decode" "vector")])
2143 (define_expand "movti"
2144 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2145 (match_operand:TI 1 "nonimmediate_operand" ""))]
2146 "TARGET_SSE || TARGET_64BIT"
2149 ix86_expand_move (TImode, operands);
2151 ix86_expand_vector_move (TImode, operands);
2155 (define_insn "*movti_internal"
2156 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2157 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2158 "TARGET_SSE && !TARGET_64BIT
2159 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2161 switch (which_alternative)
2164 if (get_attr_mode (insn) == MODE_V4SF)
2165 return "xorps\t%0, %0";
2167 return "pxor\t%0, %0";
2170 if (get_attr_mode (insn) == MODE_V4SF)
2171 return "movaps\t{%1, %0|%0, %1}";
2173 return "movdqa\t{%1, %0|%0, %1}";
2178 [(set_attr "type" "sselog1,ssemov,ssemov")
2180 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2181 (ne (symbol_ref "optimize_size") (const_int 0)))
2182 (const_string "V4SF")
2183 (and (eq_attr "alternative" "2")
2184 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2186 (const_string "V4SF")]
2187 (const_string "TI")))])
2189 (define_insn "*movti_rex64"
2190 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2191 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2193 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2195 switch (which_alternative)
2201 if (get_attr_mode (insn) == MODE_V4SF)
2202 return "xorps\t%0, %0";
2204 return "pxor\t%0, %0";
2207 if (get_attr_mode (insn) == MODE_V4SF)
2208 return "movaps\t{%1, %0|%0, %1}";
2210 return "movdqa\t{%1, %0|%0, %1}";
2215 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2217 (cond [(eq_attr "alternative" "2,3")
2219 (ne (symbol_ref "optimize_size")
2221 (const_string "V4SF")
2222 (const_string "TI"))
2223 (eq_attr "alternative" "4")
2225 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2227 (ne (symbol_ref "optimize_size")
2229 (const_string "V4SF")
2230 (const_string "TI"))]
2231 (const_string "DI")))])
2234 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2235 (match_operand:TI 1 "general_operand" ""))]
2236 "reload_completed && !SSE_REG_P (operands[0])
2237 && !SSE_REG_P (operands[1])"
2239 "ix86_split_long_move (operands); DONE;")
2241 (define_expand "movsf"
2242 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2243 (match_operand:SF 1 "general_operand" ""))]
2245 "ix86_expand_move (SFmode, operands); DONE;")
2247 (define_insn "*pushsf"
2248 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2249 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2252 /* Anything else should be already split before reg-stack. */
2253 gcc_assert (which_alternative == 1);
2254 return "push{l}\t%1";
2256 [(set_attr "type" "multi,push,multi")
2257 (set_attr "unit" "i387,*,*")
2258 (set_attr "mode" "SF,SI,SF")])
2260 (define_insn "*pushsf_rex64"
2261 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2262 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2265 /* Anything else should be already split before reg-stack. */
2266 gcc_assert (which_alternative == 1);
2267 return "push{q}\t%q1";
2269 [(set_attr "type" "multi,push,multi")
2270 (set_attr "unit" "i387,*,*")
2271 (set_attr "mode" "SF,DI,SF")])
2274 [(set (match_operand:SF 0 "push_operand" "")
2275 (match_operand:SF 1 "memory_operand" ""))]
2277 && GET_CODE (operands[1]) == MEM
2278 && constant_pool_reference_p (operands[1])"
2281 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2284 ;; %%% Kill this when call knows how to work this out.
2286 [(set (match_operand:SF 0 "push_operand" "")
2287 (match_operand:SF 1 "any_fp_register_operand" ""))]
2289 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2290 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2293 [(set (match_operand:SF 0 "push_operand" "")
2294 (match_operand:SF 1 "any_fp_register_operand" ""))]
2296 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2297 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2299 (define_insn "*movsf_1"
2300 [(set (match_operand:SF 0 "nonimmediate_operand"
2301 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2302 (match_operand:SF 1 "general_operand"
2303 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2304 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2305 && (reload_in_progress || reload_completed
2306 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2307 || (!TARGET_SSE_MATH && optimize_size
2308 && standard_80387_constant_p (operands[1]))
2309 || GET_CODE (operands[1]) != CONST_DOUBLE
2310 || memory_operand (operands[0], SFmode))"
2312 switch (which_alternative)
2315 return output_387_reg_move (insn, operands);
2318 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319 return "fstp%z0\t%y0";
2321 return "fst%z0\t%y0";
2324 return standard_80387_constant_opcode (operands[1]);
2328 return "mov{l}\t{%1, %0|%0, %1}";
2330 if (get_attr_mode (insn) == MODE_TI)
2331 return "pxor\t%0, %0";
2333 return "xorps\t%0, %0";
2335 if (get_attr_mode (insn) == MODE_V4SF)
2336 return "movaps\t{%1, %0|%0, %1}";
2338 return "movss\t{%1, %0|%0, %1}";
2341 return "movss\t{%1, %0|%0, %1}";
2345 return "movd\t{%1, %0|%0, %1}";
2348 return "movq\t{%1, %0|%0, %1}";
2354 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356 (cond [(eq_attr "alternative" "3,4,9,10")
2358 (eq_attr "alternative" "5")
2360 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362 (ne (symbol_ref "TARGET_SSE2")
2364 (eq (symbol_ref "optimize_size")
2367 (const_string "V4SF"))
2368 /* For architectures resolving dependencies on
2369 whole SSE registers use APS move to break dependency
2370 chains, otherwise use short move to avoid extra work.
2372 Do the same for architectures resolving dependencies on
2373 the parts. While in DF mode it is better to always handle
2374 just register parts, the SF mode is different due to lack
2375 of instructions to load just part of the register. It is
2376 better to maintain the whole registers in single format
2377 to avoid problems on using packed logical operations. */
2378 (eq_attr "alternative" "6")
2380 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2384 (const_string "V4SF")
2385 (const_string "SF"))
2386 (eq_attr "alternative" "11")
2387 (const_string "DI")]
2388 (const_string "SF")))])
2390 (define_insn "*swapsf"
2391 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2392 (match_operand:SF 1 "fp_register_operand" "+f"))
2395 "reload_completed || TARGET_80387"
2397 if (STACK_TOP_P (operands[0]))
2402 [(set_attr "type" "fxch")
2403 (set_attr "mode" "SF")])
2405 (define_expand "movdf"
2406 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2407 (match_operand:DF 1 "general_operand" ""))]
2409 "ix86_expand_move (DFmode, operands); DONE;")
2411 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2412 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2413 ;; On the average, pushdf using integers can be still shorter. Allow this
2414 ;; pattern for optimize_size too.
2416 (define_insn "*pushdf_nointeger"
2417 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2418 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2419 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421 /* This insn should be already split before reg-stack. */
2424 [(set_attr "type" "multi")
2425 (set_attr "unit" "i387,*,*,*")
2426 (set_attr "mode" "DF,SI,SI,DF")])
2428 (define_insn "*pushdf_integer"
2429 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2430 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2431 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433 /* This insn should be already split before reg-stack. */
2436 [(set_attr "type" "multi")
2437 (set_attr "unit" "i387,*,*")
2438 (set_attr "mode" "DF,SI,DF")])
2440 ;; %%% Kill this when call knows how to work this out.
2442 [(set (match_operand:DF 0 "push_operand" "")
2443 (match_operand:DF 1 "any_fp_register_operand" ""))]
2444 "!TARGET_64BIT && reload_completed"
2445 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2446 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2450 [(set (match_operand:DF 0 "push_operand" "")
2451 (match_operand:DF 1 "any_fp_register_operand" ""))]
2452 "TARGET_64BIT && reload_completed"
2453 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2454 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2458 [(set (match_operand:DF 0 "push_operand" "")
2459 (match_operand:DF 1 "general_operand" ""))]
2462 "ix86_split_long_move (operands); DONE;")
2464 ;; Moving is usually shorter when only FP registers are used. This separate
2465 ;; movdf pattern avoids the use of integer registers for FP operations
2466 ;; when optimizing for size.
2468 (define_insn "*movdf_nointeger"
2469 [(set (match_operand:DF 0 "nonimmediate_operand"
2470 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2471 (match_operand:DF 1 "general_operand"
2472 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2473 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2474 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2475 && (reload_in_progress || reload_completed
2476 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2477 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2478 && standard_80387_constant_p (operands[1]))
2479 || GET_CODE (operands[1]) != CONST_DOUBLE
2480 || memory_operand (operands[0], DFmode))"
2482 switch (which_alternative)
2485 return output_387_reg_move (insn, operands);
2488 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2489 return "fstp%z0\t%y0";
2491 return "fst%z0\t%y0";
2494 return standard_80387_constant_opcode (operands[1]);
2500 switch (get_attr_mode (insn))
2503 return "xorps\t%0, %0";
2505 return "xorpd\t%0, %0";
2507 return "pxor\t%0, %0";
2514 switch (get_attr_mode (insn))
2517 return "movaps\t{%1, %0|%0, %1}";
2519 return "movapd\t{%1, %0|%0, %1}";
2521 return "movdqa\t{%1, %0|%0, %1}";
2523 return "movq\t{%1, %0|%0, %1}";
2525 return "movsd\t{%1, %0|%0, %1}";
2527 return "movlpd\t{%1, %0|%0, %1}";
2529 return "movlps\t{%1, %0|%0, %1}";
2538 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2540 (cond [(eq_attr "alternative" "0,1,2")
2542 (eq_attr "alternative" "3,4")
2545 /* For SSE1, we have many fewer alternatives. */
2546 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2547 (cond [(eq_attr "alternative" "5,6")
2548 (const_string "V4SF")
2550 (const_string "V2SF"))
2552 /* xorps is one byte shorter. */
2553 (eq_attr "alternative" "5")
2554 (cond [(ne (symbol_ref "optimize_size")
2556 (const_string "V4SF")
2557 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2561 (const_string "V2DF"))
2563 /* For architectures resolving dependencies on
2564 whole SSE registers use APD move to break dependency
2565 chains, otherwise use short move to avoid extra work.
2567 movaps encodes one byte shorter. */
2568 (eq_attr "alternative" "6")
2570 [(ne (symbol_ref "optimize_size")
2572 (const_string "V4SF")
2573 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2575 (const_string "V2DF")
2577 (const_string "DF"))
2578 /* For architectures resolving dependencies on register
2579 parts we may avoid extra work to zero out upper part
2581 (eq_attr "alternative" "7")
2583 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2585 (const_string "V1DF")
2586 (const_string "DF"))
2588 (const_string "DF")))])
2590 (define_insn "*movdf_integer"
2591 [(set (match_operand:DF 0 "nonimmediate_operand"
2592 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2593 (match_operand:DF 1 "general_operand"
2594 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2595 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2596 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2597 && (reload_in_progress || reload_completed
2598 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2599 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2600 && standard_80387_constant_p (operands[1]))
2601 || GET_CODE (operands[1]) != CONST_DOUBLE
2602 || memory_operand (operands[0], DFmode))"
2604 switch (which_alternative)
2607 return output_387_reg_move (insn, operands);
2610 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2611 return "fstp%z0\t%y0";
2613 return "fst%z0\t%y0";
2616 return standard_80387_constant_opcode (operands[1]);
2623 switch (get_attr_mode (insn))
2626 return "xorps\t%0, %0";
2628 return "xorpd\t%0, %0";
2630 return "pxor\t%0, %0";
2637 switch (get_attr_mode (insn))
2640 return "movaps\t{%1, %0|%0, %1}";
2642 return "movapd\t{%1, %0|%0, %1}";
2644 return "movdqa\t{%1, %0|%0, %1}";
2646 return "movq\t{%1, %0|%0, %1}";
2648 return "movsd\t{%1, %0|%0, %1}";
2650 return "movlpd\t{%1, %0|%0, %1}";
2652 return "movlps\t{%1, %0|%0, %1}";
2661 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2663 (cond [(eq_attr "alternative" "0,1,2")
2665 (eq_attr "alternative" "3,4")
2668 /* For SSE1, we have many fewer alternatives. */
2669 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2670 (cond [(eq_attr "alternative" "5,6")
2671 (const_string "V4SF")
2673 (const_string "V2SF"))
2675 /* xorps is one byte shorter. */
2676 (eq_attr "alternative" "5")
2677 (cond [(ne (symbol_ref "optimize_size")
2679 (const_string "V4SF")
2680 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2684 (const_string "V2DF"))
2686 /* For architectures resolving dependencies on
2687 whole SSE registers use APD move to break dependency
2688 chains, otherwise use short move to avoid extra work.
2690 movaps encodes one byte shorter. */
2691 (eq_attr "alternative" "6")
2693 [(ne (symbol_ref "optimize_size")
2695 (const_string "V4SF")
2696 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2698 (const_string "V2DF")
2700 (const_string "DF"))
2701 /* For architectures resolving dependencies on register
2702 parts we may avoid extra work to zero out upper part
2704 (eq_attr "alternative" "7")
2706 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2708 (const_string "V1DF")
2709 (const_string "DF"))
2711 (const_string "DF")))])
2714 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2715 (match_operand:DF 1 "general_operand" ""))]
2717 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2718 && ! (ANY_FP_REG_P (operands[0]) ||
2719 (GET_CODE (operands[0]) == SUBREG
2720 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2721 && ! (ANY_FP_REG_P (operands[1]) ||
2722 (GET_CODE (operands[1]) == SUBREG
2723 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2725 "ix86_split_long_move (operands); DONE;")
2727 (define_insn "*swapdf"
2728 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2729 (match_operand:DF 1 "fp_register_operand" "+f"))
2732 "reload_completed || TARGET_80387"
2734 if (STACK_TOP_P (operands[0]))
2739 [(set_attr "type" "fxch")
2740 (set_attr "mode" "DF")])
2742 (define_expand "movxf"
2743 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2744 (match_operand:XF 1 "general_operand" ""))]
2746 "ix86_expand_move (XFmode, operands); DONE;")
2748 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2749 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2750 ;; Pushing using integer instructions is longer except for constants
2751 ;; and direct memory references.
2752 ;; (assuming that any given constant is pushed only once, but this ought to be
2753 ;; handled elsewhere).
2755 (define_insn "*pushxf_nointeger"
2756 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2757 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2760 /* This insn should be already split before reg-stack. */
2763 [(set_attr "type" "multi")
2764 (set_attr "unit" "i387,*,*")
2765 (set_attr "mode" "XF,SI,SI")])
2767 (define_insn "*pushxf_integer"
2768 [(set (match_operand:XF 0 "push_operand" "=<,<")
2769 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2772 /* This insn should be already split before reg-stack. */
2775 [(set_attr "type" "multi")
2776 (set_attr "unit" "i387,*")
2777 (set_attr "mode" "XF,SI")])
2780 [(set (match_operand 0 "push_operand" "")
2781 (match_operand 1 "general_operand" ""))]
2783 && (GET_MODE (operands[0]) == XFmode
2784 || GET_MODE (operands[0]) == DFmode)
2785 && !ANY_FP_REG_P (operands[1])"
2787 "ix86_split_long_move (operands); DONE;")
2790 [(set (match_operand:XF 0 "push_operand" "")
2791 (match_operand:XF 1 "any_fp_register_operand" ""))]
2793 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2794 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2795 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2798 [(set (match_operand:XF 0 "push_operand" "")
2799 (match_operand:XF 1 "any_fp_register_operand" ""))]
2801 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2802 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2803 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2805 ;; Do not use integer registers when optimizing for size
2806 (define_insn "*movxf_nointeger"
2807 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2808 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2810 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2811 && (reload_in_progress || reload_completed
2812 || (optimize_size && standard_80387_constant_p (operands[1]))
2813 || GET_CODE (operands[1]) != CONST_DOUBLE
2814 || memory_operand (operands[0], XFmode))"
2816 switch (which_alternative)
2819 return output_387_reg_move (insn, operands);
2822 /* There is no non-popping store to memory for XFmode. So if
2823 we need one, follow the store with a load. */
2824 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825 return "fstp%z0\t%y0\;fld%z0\t%y0";
2827 return "fstp%z0\t%y0";
2830 return standard_80387_constant_opcode (operands[1]);
2838 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839 (set_attr "mode" "XF,XF,XF,SI,SI")])
2841 (define_insn "*movxf_integer"
2842 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2843 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2845 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846 && (reload_in_progress || reload_completed
2847 || (optimize_size && standard_80387_constant_p (operands[1]))
2848 || GET_CODE (operands[1]) != CONST_DOUBLE
2849 || memory_operand (operands[0], XFmode))"
2851 switch (which_alternative)
2854 return output_387_reg_move (insn, operands);
2857 /* There is no non-popping store to memory for XFmode. So if
2858 we need one, follow the store with a load. */
2859 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2860 return "fstp%z0\t%y0\;fld%z0\t%y0";
2862 return "fstp%z0\t%y0";
2865 return standard_80387_constant_opcode (operands[1]);
2874 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2875 (set_attr "mode" "XF,XF,XF,SI,SI")])
2878 [(set (match_operand 0 "nonimmediate_operand" "")
2879 (match_operand 1 "general_operand" ""))]
2881 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2882 && GET_MODE (operands[0]) == XFmode
2883 && ! (ANY_FP_REG_P (operands[0]) ||
2884 (GET_CODE (operands[0]) == SUBREG
2885 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2886 && ! (ANY_FP_REG_P (operands[1]) ||
2887 (GET_CODE (operands[1]) == SUBREG
2888 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2890 "ix86_split_long_move (operands); DONE;")
2893 [(set (match_operand 0 "register_operand" "")
2894 (match_operand 1 "memory_operand" ""))]
2896 && GET_CODE (operands[1]) == MEM
2897 && (GET_MODE (operands[0]) == XFmode
2898 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2899 && constant_pool_reference_p (operands[1])"
2900 [(set (match_dup 0) (match_dup 1))]
2902 rtx c = avoid_constant_pool_reference (operands[1]);
2903 rtx r = operands[0];
2905 if (GET_CODE (r) == SUBREG)
2910 if (!standard_sse_constant_p (c))
2913 else if (FP_REG_P (r))
2915 if (!standard_80387_constant_p (c))
2918 else if (MMX_REG_P (r))
2925 [(set (match_operand 0 "register_operand" "")
2926 (float_extend (match_operand 1 "memory_operand" "")))]
2928 && GET_CODE (operands[1]) == MEM
2929 && (GET_MODE (operands[0]) == XFmode
2930 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2931 && constant_pool_reference_p (operands[1])"
2932 [(set (match_dup 0) (match_dup 1))]
2934 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2935 rtx r = operands[0];
2937 if (GET_CODE (r) == SUBREG)
2942 if (!standard_sse_constant_p (c))
2945 else if (FP_REG_P (r))
2947 if (!standard_80387_constant_p (c))
2950 else if (MMX_REG_P (r))
2956 (define_insn "swapxf"
2957 [(set (match_operand:XF 0 "register_operand" "+f")
2958 (match_operand:XF 1 "register_operand" "+f"))
2963 if (STACK_TOP_P (operands[0]))
2968 [(set_attr "type" "fxch")
2969 (set_attr "mode" "XF")])
2971 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2973 [(set (match_operand:X87MODEF 0 "register_operand" "")
2974 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2975 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2976 && (standard_80387_constant_p (operands[1]) == 8
2977 || standard_80387_constant_p (operands[1]) == 9)"
2978 [(set (match_dup 0)(match_dup 1))
2980 (neg:X87MODEF (match_dup 0)))]
2984 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2985 if (real_isnegzero (&r))
2986 operands[1] = CONST0_RTX (<MODE>mode);
2988 operands[1] = CONST1_RTX (<MODE>mode);
2991 (define_expand "movtf"
2992 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2993 (match_operand:TF 1 "nonimmediate_operand" ""))]
2996 ix86_expand_move (TFmode, operands);
3000 (define_insn "*movtf_internal"
3001 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3002 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3004 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3006 switch (which_alternative)
3012 if (get_attr_mode (insn) == MODE_V4SF)
3013 return "xorps\t%0, %0";
3015 return "pxor\t%0, %0";
3018 if (get_attr_mode (insn) == MODE_V4SF)
3019 return "movaps\t{%1, %0|%0, %1}";
3021 return "movdqa\t{%1, %0|%0, %1}";
3026 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3028 (cond [(eq_attr "alternative" "2,3")
3030 (ne (symbol_ref "optimize_size")
3032 (const_string "V4SF")
3033 (const_string "TI"))
3034 (eq_attr "alternative" "4")
3036 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3038 (ne (symbol_ref "optimize_size")
3040 (const_string "V4SF")
3041 (const_string "TI"))]
3042 (const_string "DI")))])
3045 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3046 (match_operand:TF 1 "general_operand" ""))]
3047 "reload_completed && !SSE_REG_P (operands[0])
3048 && !SSE_REG_P (operands[1])"
3050 "ix86_split_long_move (operands); DONE;")
3052 ;; Zero extension instructions
3054 (define_expand "zero_extendhisi2"
3055 [(set (match_operand:SI 0 "register_operand" "")
3056 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3059 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3061 operands[1] = force_reg (HImode, operands[1]);
3062 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3067 (define_insn "zero_extendhisi2_and"
3068 [(set (match_operand:SI 0 "register_operand" "=r")
3069 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3070 (clobber (reg:CC FLAGS_REG))]
3071 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3073 [(set_attr "type" "alu1")
3074 (set_attr "mode" "SI")])
3077 [(set (match_operand:SI 0 "register_operand" "")
3078 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3079 (clobber (reg:CC FLAGS_REG))]
3080 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3081 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3082 (clobber (reg:CC FLAGS_REG))])]
3085 (define_insn "*zero_extendhisi2_movzwl"
3086 [(set (match_operand:SI 0 "register_operand" "=r")
3087 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3088 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3089 "movz{wl|x}\t{%1, %0|%0, %1}"
3090 [(set_attr "type" "imovx")
3091 (set_attr "mode" "SI")])
3093 (define_expand "zero_extendqihi2"
3095 [(set (match_operand:HI 0 "register_operand" "")
3096 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3097 (clobber (reg:CC FLAGS_REG))])]
3101 (define_insn "*zero_extendqihi2_and"
3102 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3103 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3104 (clobber (reg:CC FLAGS_REG))]
3105 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3107 [(set_attr "type" "alu1")
3108 (set_attr "mode" "HI")])
3110 (define_insn "*zero_extendqihi2_movzbw_and"
3111 [(set (match_operand:HI 0 "register_operand" "=r,r")
3112 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3113 (clobber (reg:CC FLAGS_REG))]
3114 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3116 [(set_attr "type" "imovx,alu1")
3117 (set_attr "mode" "HI")])
3119 ; zero extend to SImode here to avoid partial register stalls
3120 (define_insn "*zero_extendqihi2_movzbl"
3121 [(set (match_operand:HI 0 "register_operand" "=r")
3122 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3123 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3124 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3125 [(set_attr "type" "imovx")
3126 (set_attr "mode" "SI")])
3128 ;; For the movzbw case strip only the clobber
3130 [(set (match_operand:HI 0 "register_operand" "")
3131 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3132 (clobber (reg:CC FLAGS_REG))]
3134 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3135 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3136 [(set (match_operand:HI 0 "register_operand" "")
3137 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3139 ;; When source and destination does not overlap, clear destination
3140 ;; first and then do the movb
3142 [(set (match_operand:HI 0 "register_operand" "")
3143 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3144 (clobber (reg:CC FLAGS_REG))]
3146 && ANY_QI_REG_P (operands[0])
3147 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3148 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3149 [(set (match_dup 0) (const_int 0))
3150 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3151 "operands[2] = gen_lowpart (QImode, operands[0]);")
3153 ;; Rest is handled by single and.
3155 [(set (match_operand:HI 0 "register_operand" "")
3156 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3157 (clobber (reg:CC FLAGS_REG))]
3159 && true_regnum (operands[0]) == true_regnum (operands[1])"
3160 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3161 (clobber (reg:CC FLAGS_REG))])]
3164 (define_expand "zero_extendqisi2"
3166 [(set (match_operand:SI 0 "register_operand" "")
3167 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3168 (clobber (reg:CC FLAGS_REG))])]
3172 (define_insn "*zero_extendqisi2_and"
3173 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3174 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3175 (clobber (reg:CC FLAGS_REG))]
3176 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3178 [(set_attr "type" "alu1")
3179 (set_attr "mode" "SI")])
3181 (define_insn "*zero_extendqisi2_movzbw_and"
3182 [(set (match_operand:SI 0 "register_operand" "=r,r")
3183 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3184 (clobber (reg:CC FLAGS_REG))]
3185 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3187 [(set_attr "type" "imovx,alu1")
3188 (set_attr "mode" "SI")])
3190 (define_insn "*zero_extendqisi2_movzbw"
3191 [(set (match_operand:SI 0 "register_operand" "=r")
3192 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3193 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3194 "movz{bl|x}\t{%1, %0|%0, %1}"
3195 [(set_attr "type" "imovx")
3196 (set_attr "mode" "SI")])
3198 ;; For the movzbl case strip only the clobber
3200 [(set (match_operand:SI 0 "register_operand" "")
3201 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3202 (clobber (reg:CC FLAGS_REG))]
3204 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3205 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3207 (zero_extend:SI (match_dup 1)))])
3209 ;; When source and destination does not overlap, clear destination
3210 ;; first and then do the movb
3212 [(set (match_operand:SI 0 "register_operand" "")
3213 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3214 (clobber (reg:CC FLAGS_REG))]
3216 && ANY_QI_REG_P (operands[0])
3217 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3218 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3219 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3220 [(set (match_dup 0) (const_int 0))
3221 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3222 "operands[2] = gen_lowpart (QImode, operands[0]);")
3224 ;; Rest is handled by single and.
3226 [(set (match_operand:SI 0 "register_operand" "")
3227 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3228 (clobber (reg:CC FLAGS_REG))]
3230 && true_regnum (operands[0]) == true_regnum (operands[1])"
3231 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3232 (clobber (reg:CC FLAGS_REG))])]
3235 ;; %%% Kill me once multi-word ops are sane.
3236 (define_expand "zero_extendsidi2"
3237 [(set (match_operand:DI 0 "register_operand" "=r")
3238 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3242 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3247 (define_insn "zero_extendsidi2_32"
3248 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3249 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3250 (clobber (reg:CC FLAGS_REG))]
3256 movd\t{%1, %0|%0, %1}
3257 movd\t{%1, %0|%0, %1}"
3258 [(set_attr "mode" "SI,SI,SI,DI,TI")
3259 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3261 (define_insn "zero_extendsidi2_rex64"
3262 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3263 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3266 mov\t{%k1, %k0|%k0, %k1}
3268 movd\t{%1, %0|%0, %1}
3269 movd\t{%1, %0|%0, %1}"
3270 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3271 (set_attr "mode" "SI,DI,SI,SI")])
3274 [(set (match_operand:DI 0 "memory_operand" "")
3275 (zero_extend:DI (match_dup 0)))]
3277 [(set (match_dup 4) (const_int 0))]
3278 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3281 [(set (match_operand:DI 0 "register_operand" "")
3282 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3283 (clobber (reg:CC FLAGS_REG))]
3284 "!TARGET_64BIT && reload_completed
3285 && true_regnum (operands[0]) == true_regnum (operands[1])"
3286 [(set (match_dup 4) (const_int 0))]
3287 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3290 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3291 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3292 (clobber (reg:CC FLAGS_REG))]
3293 "!TARGET_64BIT && reload_completed
3294 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3295 [(set (match_dup 3) (match_dup 1))
3296 (set (match_dup 4) (const_int 0))]
3297 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3299 (define_insn "zero_extendhidi2"
3300 [(set (match_operand:DI 0 "register_operand" "=r")
3301 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3303 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3304 [(set_attr "type" "imovx")
3305 (set_attr "mode" "DI")])
3307 (define_insn "zero_extendqidi2"
3308 [(set (match_operand:DI 0 "register_operand" "=r")
3309 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3311 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3312 [(set_attr "type" "imovx")
3313 (set_attr "mode" "DI")])
3315 ;; Sign extension instructions
3317 (define_expand "extendsidi2"
3318 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3319 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3320 (clobber (reg:CC FLAGS_REG))
3321 (clobber (match_scratch:SI 2 ""))])]
3326 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3331 (define_insn "*extendsidi2_1"
3332 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3333 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3334 (clobber (reg:CC FLAGS_REG))
3335 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3339 (define_insn "extendsidi2_rex64"
3340 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3341 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3345 movs{lq|x}\t{%1,%0|%0, %1}"
3346 [(set_attr "type" "imovx")
3347 (set_attr "mode" "DI")
3348 (set_attr "prefix_0f" "0")
3349 (set_attr "modrm" "0,1")])
3351 (define_insn "extendhidi2"
3352 [(set (match_operand:DI 0 "register_operand" "=r")
3353 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3355 "movs{wq|x}\t{%1,%0|%0, %1}"
3356 [(set_attr "type" "imovx")
3357 (set_attr "mode" "DI")])
3359 (define_insn "extendqidi2"
3360 [(set (match_operand:DI 0 "register_operand" "=r")
3361 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3363 "movs{bq|x}\t{%1,%0|%0, %1}"
3364 [(set_attr "type" "imovx")
3365 (set_attr "mode" "DI")])
3367 ;; Extend to memory case when source register does die.
3369 [(set (match_operand:DI 0 "memory_operand" "")
3370 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3371 (clobber (reg:CC FLAGS_REG))
3372 (clobber (match_operand:SI 2 "register_operand" ""))]
3374 && dead_or_set_p (insn, operands[1])
3375 && !reg_mentioned_p (operands[1], operands[0]))"
3376 [(set (match_dup 3) (match_dup 1))
3377 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3378 (clobber (reg:CC FLAGS_REG))])
3379 (set (match_dup 4) (match_dup 1))]
3380 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3382 ;; Extend to memory case when source register does not die.
3384 [(set (match_operand:DI 0 "memory_operand" "")
3385 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3386 (clobber (reg:CC FLAGS_REG))
3387 (clobber (match_operand:SI 2 "register_operand" ""))]
3391 split_di (&operands[0], 1, &operands[3], &operands[4]);
3393 emit_move_insn (operands[3], operands[1]);
3395 /* Generate a cltd if possible and doing so it profitable. */
3396 if (true_regnum (operands[1]) == 0
3397 && true_regnum (operands[2]) == 1
3398 && (optimize_size || TARGET_USE_CLTD))
3400 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3404 emit_move_insn (operands[2], operands[1]);
3405 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3407 emit_move_insn (operands[4], operands[2]);
3411 ;; Extend to register case. Optimize case where source and destination
3412 ;; registers match and cases where we can use cltd.
3414 [(set (match_operand:DI 0 "register_operand" "")
3415 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3416 (clobber (reg:CC FLAGS_REG))
3417 (clobber (match_scratch:SI 2 ""))]
3421 split_di (&operands[0], 1, &operands[3], &operands[4]);
3423 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3424 emit_move_insn (operands[3], operands[1]);
3426 /* Generate a cltd if possible and doing so it profitable. */
3427 if (true_regnum (operands[3]) == 0
3428 && (optimize_size || TARGET_USE_CLTD))
3430 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3434 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3435 emit_move_insn (operands[4], operands[1]);
3437 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3441 (define_insn "extendhisi2"
3442 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3443 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3446 switch (get_attr_prefix_0f (insn))
3449 return "{cwtl|cwde}";
3451 return "movs{wl|x}\t{%1,%0|%0, %1}";
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "SI")
3456 (set (attr "prefix_0f")
3457 ;; movsx is short decodable while cwtl is vector decoded.
3458 (if_then_else (and (eq_attr "cpu" "!k6")
3459 (eq_attr "alternative" "0"))
3461 (const_string "1")))
3463 (if_then_else (eq_attr "prefix_0f" "0")
3465 (const_string "1")))])
3467 (define_insn "*extendhisi2_zext"
3468 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3470 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3473 switch (get_attr_prefix_0f (insn))
3476 return "{cwtl|cwde}";
3478 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3481 [(set_attr "type" "imovx")
3482 (set_attr "mode" "SI")
3483 (set (attr "prefix_0f")
3484 ;; movsx is short decodable while cwtl is vector decoded.
3485 (if_then_else (and (eq_attr "cpu" "!k6")
3486 (eq_attr "alternative" "0"))
3488 (const_string "1")))
3490 (if_then_else (eq_attr "prefix_0f" "0")
3492 (const_string "1")))])
3494 (define_insn "extendqihi2"
3495 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3496 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3499 switch (get_attr_prefix_0f (insn))
3502 return "{cbtw|cbw}";
3504 return "movs{bw|x}\t{%1,%0|%0, %1}";
3507 [(set_attr "type" "imovx")
3508 (set_attr "mode" "HI")
3509 (set (attr "prefix_0f")
3510 ;; movsx is short decodable while cwtl is vector decoded.
3511 (if_then_else (and (eq_attr "cpu" "!k6")
3512 (eq_attr "alternative" "0"))
3514 (const_string "1")))
3516 (if_then_else (eq_attr "prefix_0f" "0")
3518 (const_string "1")))])
3520 (define_insn "extendqisi2"
3521 [(set (match_operand:SI 0 "register_operand" "=r")
3522 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524 "movs{bl|x}\t{%1,%0|%0, %1}"
3525 [(set_attr "type" "imovx")
3526 (set_attr "mode" "SI")])
3528 (define_insn "*extendqisi2_zext"
3529 [(set (match_operand:DI 0 "register_operand" "=r")
3531 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3533 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3534 [(set_attr "type" "imovx")
3535 (set_attr "mode" "SI")])
3537 ;; Conversions between float and double.
3539 ;; These are all no-ops in the model used for the 80387. So just
3542 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3543 (define_insn "*dummy_extendsfdf2"
3544 [(set (match_operand:DF 0 "push_operand" "=<")
3545 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3550 [(set (match_operand:DF 0 "push_operand" "")
3551 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3553 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3554 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3557 [(set (match_operand:DF 0 "push_operand" "")
3558 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3560 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3561 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3563 (define_insn "*dummy_extendsfxf2"
3564 [(set (match_operand:XF 0 "push_operand" "=<")
3565 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3570 [(set (match_operand:XF 0 "push_operand" "")
3571 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3573 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3574 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3575 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3578 [(set (match_operand:XF 0 "push_operand" "")
3579 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3581 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3582 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3583 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3586 [(set (match_operand:XF 0 "push_operand" "")
3587 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3589 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3590 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3591 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3594 [(set (match_operand:XF 0 "push_operand" "")
3595 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3597 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3598 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3599 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3601 (define_expand "extendsfdf2"
3602 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3603 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3604 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3606 /* ??? Needed for compress_float_constant since all fp constants
3607 are LEGITIMATE_CONSTANT_P. */
3608 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3610 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3611 && standard_80387_constant_p (operands[1]) > 0)
3613 operands[1] = simplify_const_unary_operation
3614 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3615 emit_move_insn_1 (operands[0], operands[1]);
3618 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3622 (define_insn "*extendsfdf2_mixed"
3623 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3624 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3625 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3627 switch (which_alternative)
3630 return output_387_reg_move (insn, operands);
3633 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3634 return "fstp%z0\t%y0";
3636 return "fst%z0\t%y0";
3639 return "cvtss2sd\t{%1, %0|%0, %1}";
3645 [(set_attr "type" "fmov,fmov,ssecvt")
3646 (set_attr "mode" "SF,XF,DF")])
3648 (define_insn "*extendsfdf2_sse"
3649 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3650 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3651 "TARGET_SSE2 && TARGET_SSE_MATH"
3652 "cvtss2sd\t{%1, %0|%0, %1}"
3653 [(set_attr "type" "ssecvt")
3654 (set_attr "mode" "DF")])
3656 (define_insn "*extendsfdf2_i387"
3657 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3658 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3661 switch (which_alternative)
3664 return output_387_reg_move (insn, operands);
3667 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668 return "fstp%z0\t%y0";
3670 return "fst%z0\t%y0";
3676 [(set_attr "type" "fmov")
3677 (set_attr "mode" "SF,XF")])
3679 (define_expand "extendsfxf2"
3680 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3681 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3684 /* ??? Needed for compress_float_constant since all fp constants
3685 are LEGITIMATE_CONSTANT_P. */
3686 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3688 if (standard_80387_constant_p (operands[1]) > 0)
3690 operands[1] = simplify_const_unary_operation
3691 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3692 emit_move_insn_1 (operands[0], operands[1]);
3695 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3699 (define_insn "*extendsfxf2_i387"
3700 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3701 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3704 switch (which_alternative)
3707 return output_387_reg_move (insn, operands);
3710 /* There is no non-popping store to memory for XFmode. So if
3711 we need one, follow the store with a load. */
3712 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3713 return "fstp%z0\t%y0";
3715 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3721 [(set_attr "type" "fmov")
3722 (set_attr "mode" "SF,XF")])
3724 (define_expand "extenddfxf2"
3725 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3726 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3729 /* ??? Needed for compress_float_constant since all fp constants
3730 are LEGITIMATE_CONSTANT_P. */
3731 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3733 if (standard_80387_constant_p (operands[1]) > 0)
3735 operands[1] = simplify_const_unary_operation
3736 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3737 emit_move_insn_1 (operands[0], operands[1]);
3740 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3744 (define_insn "*extenddfxf2_i387"
3745 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3746 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3749 switch (which_alternative)
3752 return output_387_reg_move (insn, operands);
3755 /* There is no non-popping store to memory for XFmode. So if
3756 we need one, follow the store with a load. */
3757 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3758 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3760 return "fstp%z0\t%y0";
3766 [(set_attr "type" "fmov")
3767 (set_attr "mode" "DF,XF")])
3769 ;; %%% This seems bad bad news.
3770 ;; This cannot output into an f-reg because there is no way to be sure
3771 ;; of truncating in that case. Otherwise this is just like a simple move
3772 ;; insn. So we pretend we can output to a reg in order to get better
3773 ;; register preferencing, but we really use a stack slot.
3775 ;; Conversion from DFmode to SFmode.
3777 (define_expand "truncdfsf2"
3778 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3780 (match_operand:DF 1 "nonimmediate_operand" "")))]
3781 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3783 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3785 else if (flag_unsafe_math_optimizations)
3789 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3790 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3795 (define_expand "truncdfsf2_with_temp"
3796 [(parallel [(set (match_operand:SF 0 "" "")
3797 (float_truncate:SF (match_operand:DF 1 "" "")))
3798 (clobber (match_operand:SF 2 "" ""))])]
3801 (define_insn "*truncdfsf_fast_mixed"
3802 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3804 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3805 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3807 switch (which_alternative)
3810 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811 return "fstp%z0\t%y0";
3813 return "fst%z0\t%y0";
3815 return output_387_reg_move (insn, operands);
3817 return "cvtsd2ss\t{%1, %0|%0, %1}";
3822 [(set_attr "type" "fmov,fmov,ssecvt")
3823 (set_attr "mode" "SF")])
3825 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3826 ;; because nothing we do here is unsafe.
3827 (define_insn "*truncdfsf_fast_sse"
3828 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3830 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3831 "TARGET_SSE2 && TARGET_SSE_MATH"
3832 "cvtsd2ss\t{%1, %0|%0, %1}"
3833 [(set_attr "type" "ssecvt")
3834 (set_attr "mode" "SF")])
3836 (define_insn "*truncdfsf_fast_i387"
3837 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3839 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3840 "TARGET_80387 && flag_unsafe_math_optimizations"
3841 "* return output_387_reg_move (insn, operands);"
3842 [(set_attr "type" "fmov")
3843 (set_attr "mode" "SF")])
3845 (define_insn "*truncdfsf_mixed"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3848 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3849 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3850 "TARGET_MIX_SSE_I387"
3852 switch (which_alternative)
3855 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3856 return "fstp%z0\t%y0";
3858 return "fst%z0\t%y0";
3862 return "cvtsd2ss\t{%1, %0|%0, %1}";
3867 [(set_attr "type" "fmov,multi,ssecvt")
3868 (set_attr "unit" "*,i387,*")
3869 (set_attr "mode" "SF")])
3871 (define_insn "*truncdfsf_i387"
3872 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3874 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3875 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3878 switch (which_alternative)
3881 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3882 return "fstp%z0\t%y0";
3884 return "fst%z0\t%y0";
3891 [(set_attr "type" "fmov,multi")
3892 (set_attr "unit" "*,i387")
3893 (set_attr "mode" "SF")])
3895 (define_insn "*truncdfsf2_i387_1"
3896 [(set (match_operand:SF 0 "memory_operand" "=m")
3898 (match_operand:DF 1 "register_operand" "f")))]
3900 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3901 && !TARGET_MIX_SSE_I387"
3903 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3904 return "fstp%z0\t%y0";
3906 return "fst%z0\t%y0";
3908 [(set_attr "type" "fmov")
3909 (set_attr "mode" "SF")])
3912 [(set (match_operand:SF 0 "register_operand" "")
3914 (match_operand:DF 1 "fp_register_operand" "")))
3915 (clobber (match_operand 2 "" ""))]
3917 [(set (match_dup 2) (match_dup 1))
3918 (set (match_dup 0) (match_dup 2))]
3920 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3923 ;; Conversion from XFmode to SFmode.
3925 (define_expand "truncxfsf2"
3926 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3928 (match_operand:XF 1 "register_operand" "")))
3929 (clobber (match_dup 2))])]
3932 if (flag_unsafe_math_optimizations)
3934 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3935 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3936 if (reg != operands[0])
3937 emit_move_insn (operands[0], reg);
3941 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3944 (define_insn "*truncxfsf2_mixed"
3945 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3947 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3948 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3951 gcc_assert (!which_alternative);
3952 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3953 return "fstp%z0\t%y0";
3955 return "fst%z0\t%y0";
3957 [(set_attr "type" "fmov,multi,multi,multi")
3958 (set_attr "unit" "*,i387,i387,i387")
3959 (set_attr "mode" "SF")])
3961 (define_insn "truncxfsf2_i387_noop"
3962 [(set (match_operand:SF 0 "register_operand" "=f")
3963 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3964 "TARGET_80387 && flag_unsafe_math_optimizations"
3965 "* return output_387_reg_move (insn, operands);"
3966 [(set_attr "type" "fmov")
3967 (set_attr "mode" "SF")])
3969 (define_insn "*truncxfsf2_i387"
3970 [(set (match_operand:SF 0 "memory_operand" "=m")
3972 (match_operand:XF 1 "register_operand" "f")))]
3975 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3976 return "fstp%z0\t%y0";
3978 return "fst%z0\t%y0";
3980 [(set_attr "type" "fmov")
3981 (set_attr "mode" "SF")])
3984 [(set (match_operand:SF 0 "register_operand" "")
3986 (match_operand:XF 1 "register_operand" "")))
3987 (clobber (match_operand:SF 2 "memory_operand" ""))]
3988 "TARGET_80387 && reload_completed"
3989 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3990 (set (match_dup 0) (match_dup 2))]
3994 [(set (match_operand:SF 0 "memory_operand" "")
3996 (match_operand:XF 1 "register_operand" "")))
3997 (clobber (match_operand:SF 2 "memory_operand" ""))]
3999 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4002 ;; Conversion from XFmode to DFmode.
4004 (define_expand "truncxfdf2"
4005 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4007 (match_operand:XF 1 "register_operand" "")))
4008 (clobber (match_dup 2))])]
4011 if (flag_unsafe_math_optimizations)
4013 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4014 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4015 if (reg != operands[0])
4016 emit_move_insn (operands[0], reg);
4020 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4023 (define_insn "*truncxfdf2_mixed"
4024 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4026 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4027 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4030 gcc_assert (!which_alternative);
4031 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4032 return "fstp%z0\t%y0";
4034 return "fst%z0\t%y0";
4036 [(set_attr "type" "fmov,multi,multi,multi")
4037 (set_attr "unit" "*,i387,i387,i387")
4038 (set_attr "mode" "DF")])
4040 (define_insn "truncxfdf2_i387_noop"
4041 [(set (match_operand:DF 0 "register_operand" "=f")
4042 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4043 "TARGET_80387 && flag_unsafe_math_optimizations"
4044 "* return output_387_reg_move (insn, operands);"
4045 [(set_attr "type" "fmov")
4046 (set_attr "mode" "DF")])
4048 (define_insn "*truncxfdf2_i387"
4049 [(set (match_operand:DF 0 "memory_operand" "=m")
4051 (match_operand:XF 1 "register_operand" "f")))]
4054 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4055 return "fstp%z0\t%y0";
4057 return "fst%z0\t%y0";
4059 [(set_attr "type" "fmov")
4060 (set_attr "mode" "DF")])
4063 [(set (match_operand:DF 0 "register_operand" "")
4065 (match_operand:XF 1 "register_operand" "")))
4066 (clobber (match_operand:DF 2 "memory_operand" ""))]
4067 "TARGET_80387 && reload_completed"
4068 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4069 (set (match_dup 0) (match_dup 2))]
4073 [(set (match_operand:DF 0 "memory_operand" "")
4075 (match_operand:XF 1 "register_operand" "")))
4076 (clobber (match_operand:DF 2 "memory_operand" ""))]
4078 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4081 ;; Signed conversion to DImode.
4083 (define_expand "fix_truncxfdi2"
4084 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4085 (fix:DI (match_operand:XF 1 "register_operand" "")))
4086 (clobber (reg:CC FLAGS_REG))])]
4091 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4096 (define_expand "fix_trunc<mode>di2"
4097 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4098 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4099 (clobber (reg:CC FLAGS_REG))])]
4100 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4103 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4105 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4108 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4110 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4111 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4112 if (out != operands[0])
4113 emit_move_insn (operands[0], out);
4118 ;; Signed conversion to SImode.
4120 (define_expand "fix_truncxfsi2"
4121 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4122 (fix:SI (match_operand:XF 1 "register_operand" "")))
4123 (clobber (reg:CC FLAGS_REG))])]
4128 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4133 (define_expand "fix_trunc<mode>si2"
4134 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4135 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4136 (clobber (reg:CC FLAGS_REG))])]
4137 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4140 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4142 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4145 if (SSE_FLOAT_MODE_P (<MODE>mode))
4147 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4148 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4149 if (out != operands[0])
4150 emit_move_insn (operands[0], out);
4155 ;; Signed conversion to HImode.
4157 (define_expand "fix_trunc<mode>hi2"
4158 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4159 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4160 (clobber (reg:CC FLAGS_REG))])]
4162 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4166 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4171 ;; When SSE is available, it is always faster to use it!
4172 (define_insn "fix_truncsfdi_sse"
4173 [(set (match_operand:DI 0 "register_operand" "=r,r")
4174 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4175 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4176 "cvttss2si{q}\t{%1, %0|%0, %1}"
4177 [(set_attr "type" "sseicvt")
4178 (set_attr "mode" "SF")
4179 (set_attr "athlon_decode" "double,vector")])
4181 (define_insn "fix_truncdfdi_sse"
4182 [(set (match_operand:DI 0 "register_operand" "=r,r")
4183 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4184 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4185 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4186 [(set_attr "type" "sseicvt")
4187 (set_attr "mode" "DF")
4188 (set_attr "athlon_decode" "double,vector")])
4190 (define_insn "fix_truncsfsi_sse"
4191 [(set (match_operand:SI 0 "register_operand" "=r,r")
4192 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4193 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4194 "cvttss2si\t{%1, %0|%0, %1}"
4195 [(set_attr "type" "sseicvt")
4196 (set_attr "mode" "DF")
4197 (set_attr "athlon_decode" "double,vector")])
4199 (define_insn "fix_truncdfsi_sse"
4200 [(set (match_operand:SI 0 "register_operand" "=r,r")
4201 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4202 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4203 "cvttsd2si\t{%1, %0|%0, %1}"
4204 [(set_attr "type" "sseicvt")
4205 (set_attr "mode" "DF")
4206 (set_attr "athlon_decode" "double,vector")])
4208 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4210 [(set (match_operand:DF 0 "register_operand" "")
4211 (match_operand:DF 1 "memory_operand" ""))
4212 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4213 (fix:SSEMODEI24 (match_dup 0)))]
4215 && peep2_reg_dead_p (2, operands[0])"
4216 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4220 [(set (match_operand:SF 0 "register_operand" "")
4221 (match_operand:SF 1 "memory_operand" ""))
4222 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4223 (fix:SSEMODEI24 (match_dup 0)))]
4225 && peep2_reg_dead_p (2, operands[0])"
4226 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4229 ;; Avoid vector decoded forms of the instruction.
4231 [(match_scratch:DF 2 "Y")
4232 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4233 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4234 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4235 [(set (match_dup 2) (match_dup 1))
4236 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4240 [(match_scratch:SF 2 "x")
4241 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4242 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4243 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4244 [(set (match_dup 2) (match_dup 1))
4245 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4248 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4249 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4250 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4252 && FLOAT_MODE_P (GET_MODE (operands[1]))
4253 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4254 && (TARGET_64BIT || <MODE>mode != DImode))
4256 && !(reload_completed || reload_in_progress)"
4261 if (memory_operand (operands[0], VOIDmode))
4262 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4265 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4266 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4272 [(set_attr "type" "fisttp")
4273 (set_attr "mode" "<MODE>")])
4275 (define_insn "fix_trunc<mode>_i387_fisttp"
4276 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4277 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4278 (clobber (match_scratch:XF 2 "=&1f"))]
4280 && FLOAT_MODE_P (GET_MODE (operands[1]))
4281 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282 && (TARGET_64BIT || <MODE>mode != DImode))
4283 && TARGET_SSE_MATH)"
4284 "* return output_fix_trunc (insn, operands, 1);"
4285 [(set_attr "type" "fisttp")
4286 (set_attr "mode" "<MODE>")])
4288 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4289 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4290 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4291 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4292 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4294 && FLOAT_MODE_P (GET_MODE (operands[1]))
4295 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4296 && (TARGET_64BIT || <MODE>mode != DImode))
4297 && TARGET_SSE_MATH)"
4299 [(set_attr "type" "fisttp")
4300 (set_attr "mode" "<MODE>")])
4303 [(set (match_operand:X87MODEI 0 "register_operand" "")
4304 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4305 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4306 (clobber (match_scratch 3 ""))]
4308 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4309 (clobber (match_dup 3))])
4310 (set (match_dup 0) (match_dup 2))]
4314 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4315 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4316 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4317 (clobber (match_scratch 3 ""))]
4319 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4320 (clobber (match_dup 3))])]
4323 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4324 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4325 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4326 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4327 ;; function in i386.c.
4328 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4329 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4330 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4331 (clobber (reg:CC FLAGS_REG))]
4332 "TARGET_80387 && !TARGET_FISTTP
4333 && FLOAT_MODE_P (GET_MODE (operands[1]))
4334 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4335 && (TARGET_64BIT || <MODE>mode != DImode))
4336 && !(reload_completed || reload_in_progress)"
4341 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4343 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4344 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4345 if (memory_operand (operands[0], VOIDmode))
4346 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4347 operands[2], operands[3]));
4350 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4351 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4352 operands[2], operands[3],
4357 [(set_attr "type" "fistp")
4358 (set_attr "i387_cw" "trunc")
4359 (set_attr "mode" "<MODE>")])
4361 (define_insn "fix_truncdi_i387"
4362 [(set (match_operand:DI 0 "memory_operand" "=m")
4363 (fix:DI (match_operand 1 "register_operand" "f")))
4364 (use (match_operand:HI 2 "memory_operand" "m"))
4365 (use (match_operand:HI 3 "memory_operand" "m"))
4366 (clobber (match_scratch:XF 4 "=&1f"))]
4367 "TARGET_80387 && !TARGET_FISTTP
4368 && FLOAT_MODE_P (GET_MODE (operands[1]))
4369 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4370 "* return output_fix_trunc (insn, operands, 0);"
4371 [(set_attr "type" "fistp")
4372 (set_attr "i387_cw" "trunc")
4373 (set_attr "mode" "DI")])
4375 (define_insn "fix_truncdi_i387_with_temp"
4376 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4377 (fix:DI (match_operand 1 "register_operand" "f,f")))
4378 (use (match_operand:HI 2 "memory_operand" "m,m"))
4379 (use (match_operand:HI 3 "memory_operand" "m,m"))
4380 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4381 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4382 "TARGET_80387 && !TARGET_FISTTP
4383 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4386 [(set_attr "type" "fistp")
4387 (set_attr "i387_cw" "trunc")
4388 (set_attr "mode" "DI")])
4391 [(set (match_operand:DI 0 "register_operand" "")
4392 (fix:DI (match_operand 1 "register_operand" "")))
4393 (use (match_operand:HI 2 "memory_operand" ""))
4394 (use (match_operand:HI 3 "memory_operand" ""))
4395 (clobber (match_operand:DI 4 "memory_operand" ""))
4396 (clobber (match_scratch 5 ""))]
4398 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4401 (clobber (match_dup 5))])
4402 (set (match_dup 0) (match_dup 4))]
4406 [(set (match_operand:DI 0 "memory_operand" "")
4407 (fix:DI (match_operand 1 "register_operand" "")))
4408 (use (match_operand:HI 2 "memory_operand" ""))
4409 (use (match_operand:HI 3 "memory_operand" ""))
4410 (clobber (match_operand:DI 4 "memory_operand" ""))
4411 (clobber (match_scratch 5 ""))]
4413 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4416 (clobber (match_dup 5))])]
4419 (define_insn "fix_trunc<mode>_i387"
4420 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4421 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4422 (use (match_operand:HI 2 "memory_operand" "m"))
4423 (use (match_operand:HI 3 "memory_operand" "m"))]
4424 "TARGET_80387 && !TARGET_FISTTP
4425 && FLOAT_MODE_P (GET_MODE (operands[1]))
4426 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4427 "* return output_fix_trunc (insn, operands, 0);"
4428 [(set_attr "type" "fistp")
4429 (set_attr "i387_cw" "trunc")
4430 (set_attr "mode" "<MODE>")])
4432 (define_insn "fix_trunc<mode>_i387_with_temp"
4433 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4434 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4435 (use (match_operand:HI 2 "memory_operand" "m,m"))
4436 (use (match_operand:HI 3 "memory_operand" "m,m"))
4437 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4438 "TARGET_80387 && !TARGET_FISTTP
4439 && FLOAT_MODE_P (GET_MODE (operands[1]))
4440 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4442 [(set_attr "type" "fistp")
4443 (set_attr "i387_cw" "trunc")
4444 (set_attr "mode" "<MODE>")])
4447 [(set (match_operand:X87MODEI12 0 "register_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 4) (fix:X87MODEI12 (match_dup 1)))
4455 (use (match_dup 3))])
4456 (set (match_dup 0) (match_dup 4))]
4460 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4461 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4462 (use (match_operand:HI 2 "memory_operand" ""))
4463 (use (match_operand:HI 3 "memory_operand" ""))
4464 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4466 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4468 (use (match_dup 3))])]
4471 (define_insn "x86_fnstcw_1"
4472 [(set (match_operand:HI 0 "memory_operand" "=m")
4473 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4476 [(set_attr "length" "2")
4477 (set_attr "mode" "HI")
4478 (set_attr "unit" "i387")])
4480 (define_insn "x86_fldcw_1"
4481 [(set (reg:HI FPCR_REG)
4482 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4485 [(set_attr "length" "2")
4486 (set_attr "mode" "HI")
4487 (set_attr "unit" "i387")
4488 (set_attr "athlon_decode" "vector")])
4490 ;; Conversion between fixed point and floating point.
4492 ;; Even though we only accept memory inputs, the backend _really_
4493 ;; wants to be able to do this between registers.
4495 (define_expand "floathisf2"
4496 [(set (match_operand:SF 0 "register_operand" "")
4497 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4498 "TARGET_80387 || TARGET_SSE_MATH"
4500 if (TARGET_SSE_MATH)
4502 emit_insn (gen_floatsisf2 (operands[0],
4503 convert_to_mode (SImode, operands[1], 0)));
4508 (define_insn "*floathisf2_i387"
4509 [(set (match_operand:SF 0 "register_operand" "=f,f")
4510 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4511 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4515 [(set_attr "type" "fmov,multi")
4516 (set_attr "mode" "SF")
4517 (set_attr "unit" "*,i387")
4518 (set_attr "fp_int_src" "true")])
4520 (define_expand "floatsisf2"
4521 [(set (match_operand:SF 0 "register_operand" "")
4522 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4523 "TARGET_80387 || TARGET_SSE_MATH"
4526 (define_insn "*floatsisf2_mixed"
4527 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4528 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4529 "TARGET_MIX_SSE_I387"
4533 cvtsi2ss\t{%1, %0|%0, %1}
4534 cvtsi2ss\t{%1, %0|%0, %1}"
4535 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4536 (set_attr "mode" "SF")
4537 (set_attr "unit" "*,i387,*,*")
4538 (set_attr "athlon_decode" "*,*,vector,double")
4539 (set_attr "fp_int_src" "true")])
4541 (define_insn "*floatsisf2_sse"
4542 [(set (match_operand:SF 0 "register_operand" "=x,x")
4543 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4545 "cvtsi2ss\t{%1, %0|%0, %1}"
4546 [(set_attr "type" "sseicvt")
4547 (set_attr "mode" "SF")
4548 (set_attr "athlon_decode" "vector,double")
4549 (set_attr "fp_int_src" "true")])
4551 (define_insn "*floatsisf2_i387"
4552 [(set (match_operand:SF 0 "register_operand" "=f,f")
4553 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4558 [(set_attr "type" "fmov,multi")
4559 (set_attr "mode" "SF")
4560 (set_attr "unit" "*,i387")
4561 (set_attr "fp_int_src" "true")])
4563 (define_expand "floatdisf2"
4564 [(set (match_operand:SF 0 "register_operand" "")
4565 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4566 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4569 (define_insn "*floatdisf2_mixed"
4570 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4571 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4572 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4576 cvtsi2ss{q}\t{%1, %0|%0, %1}
4577 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4578 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4579 (set_attr "mode" "SF")
4580 (set_attr "unit" "*,i387,*,*")
4581 (set_attr "athlon_decode" "*,*,vector,double")
4582 (set_attr "fp_int_src" "true")])
4584 (define_insn "*floatdisf2_sse"
4585 [(set (match_operand:SF 0 "register_operand" "=x,x")
4586 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4587 "TARGET_64BIT && TARGET_SSE_MATH"
4588 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4589 [(set_attr "type" "sseicvt")
4590 (set_attr "mode" "SF")
4591 (set_attr "athlon_decode" "vector,double")
4592 (set_attr "fp_int_src" "true")])
4594 (define_insn "*floatdisf2_i387"
4595 [(set (match_operand:SF 0 "register_operand" "=f,f")
4596 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4601 [(set_attr "type" "fmov,multi")
4602 (set_attr "mode" "SF")
4603 (set_attr "unit" "*,i387")
4604 (set_attr "fp_int_src" "true")])
4606 (define_expand "floathidf2"
4607 [(set (match_operand:DF 0 "register_operand" "")
4608 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4609 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4611 if (TARGET_SSE2 && TARGET_SSE_MATH)
4613 emit_insn (gen_floatsidf2 (operands[0],
4614 convert_to_mode (SImode, operands[1], 0)));
4619 (define_insn "*floathidf2_i387"
4620 [(set (match_operand:DF 0 "register_operand" "=f,f")
4621 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4622 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4626 [(set_attr "type" "fmov,multi")
4627 (set_attr "mode" "DF")
4628 (set_attr "unit" "*,i387")
4629 (set_attr "fp_int_src" "true")])
4631 (define_expand "floatsidf2"
4632 [(set (match_operand:DF 0 "register_operand" "")
4633 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4634 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4637 (define_insn "*floatsidf2_mixed"
4638 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4639 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4640 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4644 cvtsi2sd\t{%1, %0|%0, %1}
4645 cvtsi2sd\t{%1, %0|%0, %1}"
4646 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4647 (set_attr "mode" "DF")
4648 (set_attr "unit" "*,i387,*,*")
4649 (set_attr "athlon_decode" "*,*,double,direct")
4650 (set_attr "fp_int_src" "true")])
4652 (define_insn "*floatsidf2_sse"
4653 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4654 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4655 "TARGET_SSE2 && TARGET_SSE_MATH"
4656 "cvtsi2sd\t{%1, %0|%0, %1}"
4657 [(set_attr "type" "sseicvt")
4658 (set_attr "mode" "DF")
4659 (set_attr "athlon_decode" "double,direct")
4660 (set_attr "fp_int_src" "true")])
4662 (define_insn "*floatsidf2_i387"
4663 [(set (match_operand:DF 0 "register_operand" "=f,f")
4664 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4669 [(set_attr "type" "fmov,multi")
4670 (set_attr "mode" "DF")
4671 (set_attr "unit" "*,i387")
4672 (set_attr "fp_int_src" "true")])
4674 (define_expand "floatdidf2"
4675 [(set (match_operand:DF 0 "register_operand" "")
4676 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4677 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4680 (define_insn "*floatdidf2_mixed"
4681 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4682 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4683 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4687 cvtsi2sd{q}\t{%1, %0|%0, %1}
4688 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4689 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4690 (set_attr "mode" "DF")
4691 (set_attr "unit" "*,i387,*,*")
4692 (set_attr "athlon_decode" "*,*,double,direct")
4693 (set_attr "fp_int_src" "true")])
4695 (define_insn "*floatdidf2_sse"
4696 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4697 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4698 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4699 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4700 [(set_attr "type" "sseicvt")
4701 (set_attr "mode" "DF")
4702 (set_attr "athlon_decode" "double,direct")
4703 (set_attr "fp_int_src" "true")])
4705 (define_insn "*floatdidf2_i387"
4706 [(set (match_operand:DF 0 "register_operand" "=f,f")
4707 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4712 [(set_attr "type" "fmov,multi")
4713 (set_attr "mode" "DF")
4714 (set_attr "unit" "*,i387")
4715 (set_attr "fp_int_src" "true")])
4717 (define_insn "floathixf2"
4718 [(set (match_operand:XF 0 "register_operand" "=f,f")
4719 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4724 [(set_attr "type" "fmov,multi")
4725 (set_attr "mode" "XF")
4726 (set_attr "unit" "*,i387")
4727 (set_attr "fp_int_src" "true")])
4729 (define_insn "floatsixf2"
4730 [(set (match_operand:XF 0 "register_operand" "=f,f")
4731 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4736 [(set_attr "type" "fmov,multi")
4737 (set_attr "mode" "XF")
4738 (set_attr "unit" "*,i387")
4739 (set_attr "fp_int_src" "true")])
4741 (define_insn "floatdixf2"
4742 [(set (match_operand:XF 0 "register_operand" "=f,f")
4743 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4748 [(set_attr "type" "fmov,multi")
4749 (set_attr "mode" "XF")
4750 (set_attr "unit" "*,i387")
4751 (set_attr "fp_int_src" "true")])
4753 ;; %%% Kill these when reload knows how to do it.
4755 [(set (match_operand 0 "fp_register_operand" "")
4756 (float (match_operand 1 "register_operand" "")))]
4759 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4762 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4763 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4764 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4765 ix86_free_from_memory (GET_MODE (operands[1]));
4769 (define_expand "floatunssisf2"
4770 [(use (match_operand:SF 0 "register_operand" ""))
4771 (use (match_operand:SI 1 "register_operand" ""))]
4772 "!TARGET_64BIT && TARGET_SSE_MATH"
4773 "x86_emit_floatuns (operands); DONE;")
4775 (define_expand "floatunsdisf2"
4776 [(use (match_operand:SF 0 "register_operand" ""))
4777 (use (match_operand:DI 1 "register_operand" ""))]
4778 "TARGET_64BIT && TARGET_SSE_MATH"
4779 "x86_emit_floatuns (operands); DONE;")
4781 (define_expand "floatunsdidf2"
4782 [(use (match_operand:DF 0 "register_operand" ""))
4783 (use (match_operand:DI 1 "register_operand" ""))]
4784 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4785 "x86_emit_floatuns (operands); DONE;")
4787 ;; SSE extract/set expanders
4792 ;; %%% splits for addditi3
4794 (define_expand "addti3"
4795 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4796 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4797 (match_operand:TI 2 "x86_64_general_operand" "")))
4798 (clobber (reg:CC FLAGS_REG))]
4800 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4802 (define_insn "*addti3_1"
4803 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4804 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4805 (match_operand:TI 2 "general_operand" "roiF,riF")))
4806 (clobber (reg:CC FLAGS_REG))]
4807 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4811 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4812 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4813 (match_operand:TI 2 "general_operand" "")))
4814 (clobber (reg:CC FLAGS_REG))]
4815 "TARGET_64BIT && reload_completed"
4816 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4818 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4819 (parallel [(set (match_dup 3)
4820 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4823 (clobber (reg:CC FLAGS_REG))])]
4824 "split_ti (operands+0, 1, operands+0, operands+3);
4825 split_ti (operands+1, 1, operands+1, operands+4);
4826 split_ti (operands+2, 1, operands+2, operands+5);")
4828 ;; %%% splits for addsidi3
4829 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4830 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4831 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4833 (define_expand "adddi3"
4834 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4835 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4836 (match_operand:DI 2 "x86_64_general_operand" "")))
4837 (clobber (reg:CC FLAGS_REG))]
4839 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4841 (define_insn "*adddi3_1"
4842 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4843 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4844 (match_operand:DI 2 "general_operand" "roiF,riF")))
4845 (clobber (reg:CC FLAGS_REG))]
4846 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4850 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4851 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4852 (match_operand:DI 2 "general_operand" "")))
4853 (clobber (reg:CC FLAGS_REG))]
4854 "!TARGET_64BIT && reload_completed"
4855 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4857 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4858 (parallel [(set (match_dup 3)
4859 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4862 (clobber (reg:CC FLAGS_REG))])]
4863 "split_di (operands+0, 1, operands+0, operands+3);
4864 split_di (operands+1, 1, operands+1, operands+4);
4865 split_di (operands+2, 1, operands+2, operands+5);")
4867 (define_insn "adddi3_carry_rex64"
4868 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4869 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4870 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4871 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4872 (clobber (reg:CC FLAGS_REG))]
4873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4874 "adc{q}\t{%2, %0|%0, %2}"
4875 [(set_attr "type" "alu")
4876 (set_attr "pent_pair" "pu")
4877 (set_attr "mode" "DI")])
4879 (define_insn "*adddi3_cc_rex64"
4880 [(set (reg:CC FLAGS_REG)
4881 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4882 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4884 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4885 (plus:DI (match_dup 1) (match_dup 2)))]
4886 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4887 "add{q}\t{%2, %0|%0, %2}"
4888 [(set_attr "type" "alu")
4889 (set_attr "mode" "DI")])
4891 (define_insn "addqi3_carry"
4892 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4893 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4894 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4895 (match_operand:QI 2 "general_operand" "qi,qm")))
4896 (clobber (reg:CC FLAGS_REG))]
4897 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4898 "adc{b}\t{%2, %0|%0, %2}"
4899 [(set_attr "type" "alu")
4900 (set_attr "pent_pair" "pu")
4901 (set_attr "mode" "QI")])
4903 (define_insn "addhi3_carry"
4904 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4905 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4906 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4907 (match_operand:HI 2 "general_operand" "ri,rm")))
4908 (clobber (reg:CC FLAGS_REG))]
4909 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4910 "adc{w}\t{%2, %0|%0, %2}"
4911 [(set_attr "type" "alu")
4912 (set_attr "pent_pair" "pu")
4913 (set_attr "mode" "HI")])
4915 (define_insn "addsi3_carry"
4916 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4917 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4918 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4919 (match_operand:SI 2 "general_operand" "ri,rm")))
4920 (clobber (reg:CC FLAGS_REG))]
4921 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4922 "adc{l}\t{%2, %0|%0, %2}"
4923 [(set_attr "type" "alu")
4924 (set_attr "pent_pair" "pu")
4925 (set_attr "mode" "SI")])
4927 (define_insn "*addsi3_carry_zext"
4928 [(set (match_operand:DI 0 "register_operand" "=r")
4930 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4931 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4932 (match_operand:SI 2 "general_operand" "rim"))))
4933 (clobber (reg:CC FLAGS_REG))]
4934 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4935 "adc{l}\t{%2, %k0|%k0, %2}"
4936 [(set_attr "type" "alu")
4937 (set_attr "pent_pair" "pu")
4938 (set_attr "mode" "SI")])
4940 (define_insn "*addsi3_cc"
4941 [(set (reg:CC FLAGS_REG)
4942 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4943 (match_operand:SI 2 "general_operand" "ri,rm")]
4945 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4946 (plus:SI (match_dup 1) (match_dup 2)))]
4947 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4948 "add{l}\t{%2, %0|%0, %2}"
4949 [(set_attr "type" "alu")
4950 (set_attr "mode" "SI")])
4952 (define_insn "addqi3_cc"
4953 [(set (reg:CC FLAGS_REG)
4954 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4955 (match_operand:QI 2 "general_operand" "qi,qm")]
4957 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4958 (plus:QI (match_dup 1) (match_dup 2)))]
4959 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4960 "add{b}\t{%2, %0|%0, %2}"
4961 [(set_attr "type" "alu")
4962 (set_attr "mode" "QI")])
4964 (define_expand "addsi3"
4965 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4966 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4967 (match_operand:SI 2 "general_operand" "")))
4968 (clobber (reg:CC FLAGS_REG))])]
4970 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4972 (define_insn "*lea_1"
4973 [(set (match_operand:SI 0 "register_operand" "=r")
4974 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4976 "lea{l}\t{%a1, %0|%0, %a1}"
4977 [(set_attr "type" "lea")
4978 (set_attr "mode" "SI")])
4980 (define_insn "*lea_1_rex64"
4981 [(set (match_operand:SI 0 "register_operand" "=r")
4982 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4984 "lea{l}\t{%a1, %0|%0, %a1}"
4985 [(set_attr "type" "lea")
4986 (set_attr "mode" "SI")])
4988 (define_insn "*lea_1_zext"
4989 [(set (match_operand:DI 0 "register_operand" "=r")
4991 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4993 "lea{l}\t{%a1, %k0|%k0, %a1}"
4994 [(set_attr "type" "lea")
4995 (set_attr "mode" "SI")])
4997 (define_insn "*lea_2_rex64"
4998 [(set (match_operand:DI 0 "register_operand" "=r")
4999 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5001 "lea{q}\t{%a1, %0|%0, %a1}"
5002 [(set_attr "type" "lea")
5003 (set_attr "mode" "DI")])
5005 ;; The lea patterns for non-Pmodes needs to be matched by several
5006 ;; insns converted to real lea by splitters.
5008 (define_insn_and_split "*lea_general_1"
5009 [(set (match_operand 0 "register_operand" "=r")
5010 (plus (plus (match_operand 1 "index_register_operand" "l")
5011 (match_operand 2 "register_operand" "r"))
5012 (match_operand 3 "immediate_operand" "i")))]
5013 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5014 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5015 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5016 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5017 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5018 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5019 || GET_MODE (operands[3]) == VOIDmode)"
5021 "&& reload_completed"
5025 operands[0] = gen_lowpart (SImode, operands[0]);
5026 operands[1] = gen_lowpart (Pmode, operands[1]);
5027 operands[2] = gen_lowpart (Pmode, operands[2]);
5028 operands[3] = gen_lowpart (Pmode, operands[3]);
5029 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5031 if (Pmode != SImode)
5032 pat = gen_rtx_SUBREG (SImode, pat, 0);
5033 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5036 [(set_attr "type" "lea")
5037 (set_attr "mode" "SI")])
5039 (define_insn_and_split "*lea_general_1_zext"
5040 [(set (match_operand:DI 0 "register_operand" "=r")
5042 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5043 (match_operand:SI 2 "register_operand" "r"))
5044 (match_operand:SI 3 "immediate_operand" "i"))))]
5047 "&& reload_completed"
5049 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5051 (match_dup 3)) 0)))]
5053 operands[1] = gen_lowpart (Pmode, operands[1]);
5054 operands[2] = gen_lowpart (Pmode, operands[2]);
5055 operands[3] = gen_lowpart (Pmode, operands[3]);
5057 [(set_attr "type" "lea")
5058 (set_attr "mode" "SI")])
5060 (define_insn_and_split "*lea_general_2"
5061 [(set (match_operand 0 "register_operand" "=r")
5062 (plus (mult (match_operand 1 "index_register_operand" "l")
5063 (match_operand 2 "const248_operand" "i"))
5064 (match_operand 3 "nonmemory_operand" "ri")))]
5065 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5066 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5067 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5068 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5069 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5070 || GET_MODE (operands[3]) == VOIDmode)"
5072 "&& reload_completed"
5076 operands[0] = gen_lowpart (SImode, operands[0]);
5077 operands[1] = gen_lowpart (Pmode, operands[1]);
5078 operands[3] = gen_lowpart (Pmode, operands[3]);
5079 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5081 if (Pmode != SImode)
5082 pat = gen_rtx_SUBREG (SImode, pat, 0);
5083 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5086 [(set_attr "type" "lea")
5087 (set_attr "mode" "SI")])
5089 (define_insn_and_split "*lea_general_2_zext"
5090 [(set (match_operand:DI 0 "register_operand" "=r")
5092 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5093 (match_operand:SI 2 "const248_operand" "n"))
5094 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5097 "&& reload_completed"
5099 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5101 (match_dup 3)) 0)))]
5103 operands[1] = gen_lowpart (Pmode, operands[1]);
5104 operands[3] = gen_lowpart (Pmode, operands[3]);
5106 [(set_attr "type" "lea")
5107 (set_attr "mode" "SI")])
5109 (define_insn_and_split "*lea_general_3"
5110 [(set (match_operand 0 "register_operand" "=r")
5111 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5112 (match_operand 2 "const248_operand" "i"))
5113 (match_operand 3 "register_operand" "r"))
5114 (match_operand 4 "immediate_operand" "i")))]
5115 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5116 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5117 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5118 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5119 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5121 "&& reload_completed"
5125 operands[0] = gen_lowpart (SImode, operands[0]);
5126 operands[1] = gen_lowpart (Pmode, operands[1]);
5127 operands[3] = gen_lowpart (Pmode, operands[3]);
5128 operands[4] = gen_lowpart (Pmode, operands[4]);
5129 pat = gen_rtx_PLUS (Pmode,
5130 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5134 if (Pmode != SImode)
5135 pat = gen_rtx_SUBREG (SImode, pat, 0);
5136 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5139 [(set_attr "type" "lea")
5140 (set_attr "mode" "SI")])
5142 (define_insn_and_split "*lea_general_3_zext"
5143 [(set (match_operand:DI 0 "register_operand" "=r")
5145 (plus:SI (plus:SI (mult:SI
5146 (match_operand:SI 1 "index_register_operand" "l")
5147 (match_operand:SI 2 "const248_operand" "n"))
5148 (match_operand:SI 3 "register_operand" "r"))
5149 (match_operand:SI 4 "immediate_operand" "i"))))]
5152 "&& reload_completed"
5154 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5157 (match_dup 4)) 0)))]
5159 operands[1] = gen_lowpart (Pmode, operands[1]);
5160 operands[3] = gen_lowpart (Pmode, operands[3]);
5161 operands[4] = gen_lowpart (Pmode, operands[4]);
5163 [(set_attr "type" "lea")
5164 (set_attr "mode" "SI")])
5166 (define_insn "*adddi_1_rex64"
5167 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5168 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5169 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5170 (clobber (reg:CC FLAGS_REG))]
5171 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5173 switch (get_attr_type (insn))
5176 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5177 return "lea{q}\t{%a2, %0|%0, %a2}";
5180 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5181 if (operands[2] == const1_rtx)
5182 return "inc{q}\t%0";
5185 gcc_assert (operands[2] == constm1_rtx);
5186 return "dec{q}\t%0";
5190 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5192 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5193 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5194 if (GET_CODE (operands[2]) == CONST_INT
5195 /* Avoid overflows. */
5196 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5197 && (INTVAL (operands[2]) == 128
5198 || (INTVAL (operands[2]) < 0
5199 && INTVAL (operands[2]) != -128)))
5201 operands[2] = GEN_INT (-INTVAL (operands[2]));
5202 return "sub{q}\t{%2, %0|%0, %2}";
5204 return "add{q}\t{%2, %0|%0, %2}";
5208 (cond [(eq_attr "alternative" "2")
5209 (const_string "lea")
5210 ; Current assemblers are broken and do not allow @GOTOFF in
5211 ; ought but a memory context.
5212 (match_operand:DI 2 "pic_symbolic_operand" "")
5213 (const_string "lea")
5214 (match_operand:DI 2 "incdec_operand" "")
5215 (const_string "incdec")
5217 (const_string "alu")))
5218 (set_attr "mode" "DI")])
5220 ;; Convert lea to the lea pattern to avoid flags dependency.
5222 [(set (match_operand:DI 0 "register_operand" "")
5223 (plus:DI (match_operand:DI 1 "register_operand" "")
5224 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5225 (clobber (reg:CC FLAGS_REG))]
5226 "TARGET_64BIT && reload_completed
5227 && true_regnum (operands[0]) != true_regnum (operands[1])"
5229 (plus:DI (match_dup 1)
5233 (define_insn "*adddi_2_rex64"
5234 [(set (reg FLAGS_REG)
5236 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5237 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5239 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5240 (plus:DI (match_dup 1) (match_dup 2)))]
5241 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5242 && ix86_binary_operator_ok (PLUS, DImode, operands)
5243 /* Current assemblers are broken and do not allow @GOTOFF in
5244 ought but a memory context. */
5245 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5247 switch (get_attr_type (insn))
5250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5251 if (operands[2] == const1_rtx)
5252 return "inc{q}\t%0";
5255 gcc_assert (operands[2] == constm1_rtx);
5256 return "dec{q}\t%0";
5260 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5261 /* ???? We ought to handle there the 32bit case too
5262 - do we need new constraint? */
5263 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5264 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5265 if (GET_CODE (operands[2]) == CONST_INT
5266 /* Avoid overflows. */
5267 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5268 && (INTVAL (operands[2]) == 128
5269 || (INTVAL (operands[2]) < 0
5270 && INTVAL (operands[2]) != -128)))
5272 operands[2] = GEN_INT (-INTVAL (operands[2]));
5273 return "sub{q}\t{%2, %0|%0, %2}";
5275 return "add{q}\t{%2, %0|%0, %2}";
5279 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5280 (const_string "incdec")
5281 (const_string "alu")))
5282 (set_attr "mode" "DI")])
5284 (define_insn "*adddi_3_rex64"
5285 [(set (reg FLAGS_REG)
5286 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5287 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5288 (clobber (match_scratch:DI 0 "=r"))]
5290 && ix86_match_ccmode (insn, CCZmode)
5291 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5292 /* Current assemblers are broken and do not allow @GOTOFF in
5293 ought but a memory context. */
5294 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5296 switch (get_attr_type (insn))
5299 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5300 if (operands[2] == const1_rtx)
5301 return "inc{q}\t%0";
5304 gcc_assert (operands[2] == constm1_rtx);
5305 return "dec{q}\t%0";
5309 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5310 /* ???? We ought to handle there the 32bit case too
5311 - do we need new constraint? */
5312 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5313 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5314 if (GET_CODE (operands[2]) == CONST_INT
5315 /* Avoid overflows. */
5316 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5317 && (INTVAL (operands[2]) == 128
5318 || (INTVAL (operands[2]) < 0
5319 && INTVAL (operands[2]) != -128)))
5321 operands[2] = GEN_INT (-INTVAL (operands[2]));
5322 return "sub{q}\t{%2, %0|%0, %2}";
5324 return "add{q}\t{%2, %0|%0, %2}";
5328 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5329 (const_string "incdec")
5330 (const_string "alu")))
5331 (set_attr "mode" "DI")])
5333 ; For comparisons against 1, -1 and 128, we may generate better code
5334 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5335 ; is matched then. We can't accept general immediate, because for
5336 ; case of overflows, the result is messed up.
5337 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5339 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5340 ; only for comparisons not depending on it.
5341 (define_insn "*adddi_4_rex64"
5342 [(set (reg FLAGS_REG)
5343 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5344 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5345 (clobber (match_scratch:DI 0 "=rm"))]
5347 && ix86_match_ccmode (insn, CCGCmode)"
5349 switch (get_attr_type (insn))
5352 if (operands[2] == constm1_rtx)
5353 return "inc{q}\t%0";
5356 gcc_assert (operands[2] == const1_rtx);
5357 return "dec{q}\t%0";
5361 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5362 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5363 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5364 if ((INTVAL (operands[2]) == -128
5365 || (INTVAL (operands[2]) > 0
5366 && INTVAL (operands[2]) != 128))
5367 /* Avoid overflows. */
5368 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5369 return "sub{q}\t{%2, %0|%0, %2}";
5370 operands[2] = GEN_INT (-INTVAL (operands[2]));
5371 return "add{q}\t{%2, %0|%0, %2}";
5375 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5376 (const_string "incdec")
5377 (const_string "alu")))
5378 (set_attr "mode" "DI")])
5380 (define_insn "*adddi_5_rex64"
5381 [(set (reg FLAGS_REG)
5383 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5384 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5386 (clobber (match_scratch:DI 0 "=r"))]
5388 && ix86_match_ccmode (insn, CCGOCmode)
5389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390 /* Current assemblers are broken and do not allow @GOTOFF in
5391 ought but a memory context. */
5392 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5394 switch (get_attr_type (insn))
5397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398 if (operands[2] == const1_rtx)
5399 return "inc{q}\t%0";
5402 gcc_assert (operands[2] == constm1_rtx);
5403 return "dec{q}\t%0";
5407 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5408 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5409 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5410 if (GET_CODE (operands[2]) == CONST_INT
5411 /* Avoid overflows. */
5412 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5413 && (INTVAL (operands[2]) == 128
5414 || (INTVAL (operands[2]) < 0
5415 && INTVAL (operands[2]) != -128)))
5417 operands[2] = GEN_INT (-INTVAL (operands[2]));
5418 return "sub{q}\t{%2, %0|%0, %2}";
5420 return "add{q}\t{%2, %0|%0, %2}";
5424 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5425 (const_string "incdec")
5426 (const_string "alu")))
5427 (set_attr "mode" "DI")])
5430 (define_insn "*addsi_1"
5431 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5432 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5433 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5434 (clobber (reg:CC FLAGS_REG))]
5435 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5437 switch (get_attr_type (insn))
5440 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5441 return "lea{l}\t{%a2, %0|%0, %a2}";
5444 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5445 if (operands[2] == const1_rtx)
5446 return "inc{l}\t%0";
5449 gcc_assert (operands[2] == constm1_rtx);
5450 return "dec{l}\t%0";
5454 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5456 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5457 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5458 if (GET_CODE (operands[2]) == CONST_INT
5459 && (INTVAL (operands[2]) == 128
5460 || (INTVAL (operands[2]) < 0
5461 && INTVAL (operands[2]) != -128)))
5463 operands[2] = GEN_INT (-INTVAL (operands[2]));
5464 return "sub{l}\t{%2, %0|%0, %2}";
5466 return "add{l}\t{%2, %0|%0, %2}";
5470 (cond [(eq_attr "alternative" "2")
5471 (const_string "lea")
5472 ; Current assemblers are broken and do not allow @GOTOFF in
5473 ; ought but a memory context.
5474 (match_operand:SI 2 "pic_symbolic_operand" "")
5475 (const_string "lea")
5476 (match_operand:SI 2 "incdec_operand" "")
5477 (const_string "incdec")
5479 (const_string "alu")))
5480 (set_attr "mode" "SI")])
5482 ;; Convert lea to the lea pattern to avoid flags dependency.
5484 [(set (match_operand 0 "register_operand" "")
5485 (plus (match_operand 1 "register_operand" "")
5486 (match_operand 2 "nonmemory_operand" "")))
5487 (clobber (reg:CC FLAGS_REG))]
5489 && true_regnum (operands[0]) != true_regnum (operands[1])"
5493 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5494 may confuse gen_lowpart. */
5495 if (GET_MODE (operands[0]) != Pmode)
5497 operands[1] = gen_lowpart (Pmode, operands[1]);
5498 operands[2] = gen_lowpart (Pmode, operands[2]);
5500 operands[0] = gen_lowpart (SImode, operands[0]);
5501 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5502 if (Pmode != SImode)
5503 pat = gen_rtx_SUBREG (SImode, pat, 0);
5504 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5508 ;; It may seem that nonimmediate operand is proper one for operand 1.
5509 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5510 ;; we take care in ix86_binary_operator_ok to not allow two memory
5511 ;; operands so proper swapping will be done in reload. This allow
5512 ;; patterns constructed from addsi_1 to match.
5513 (define_insn "addsi_1_zext"
5514 [(set (match_operand:DI 0 "register_operand" "=r,r")
5516 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5517 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5518 (clobber (reg:CC FLAGS_REG))]
5519 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5521 switch (get_attr_type (insn))
5524 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5525 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5528 if (operands[2] == const1_rtx)
5529 return "inc{l}\t%k0";
5532 gcc_assert (operands[2] == constm1_rtx);
5533 return "dec{l}\t%k0";
5537 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5538 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5539 if (GET_CODE (operands[2]) == CONST_INT
5540 && (INTVAL (operands[2]) == 128
5541 || (INTVAL (operands[2]) < 0
5542 && INTVAL (operands[2]) != -128)))
5544 operands[2] = GEN_INT (-INTVAL (operands[2]));
5545 return "sub{l}\t{%2, %k0|%k0, %2}";
5547 return "add{l}\t{%2, %k0|%k0, %2}";
5551 (cond [(eq_attr "alternative" "1")
5552 (const_string "lea")
5553 ; Current assemblers are broken and do not allow @GOTOFF in
5554 ; ought but a memory context.
5555 (match_operand:SI 2 "pic_symbolic_operand" "")
5556 (const_string "lea")
5557 (match_operand:SI 2 "incdec_operand" "")
5558 (const_string "incdec")
5560 (const_string "alu")))
5561 (set_attr "mode" "SI")])
5563 ;; Convert lea to the lea pattern to avoid flags dependency.
5565 [(set (match_operand:DI 0 "register_operand" "")
5567 (plus:SI (match_operand:SI 1 "register_operand" "")
5568 (match_operand:SI 2 "nonmemory_operand" ""))))
5569 (clobber (reg:CC FLAGS_REG))]
5570 "TARGET_64BIT && reload_completed
5571 && true_regnum (operands[0]) != true_regnum (operands[1])"
5573 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5575 operands[1] = gen_lowpart (Pmode, operands[1]);
5576 operands[2] = gen_lowpart (Pmode, operands[2]);
5579 (define_insn "*addsi_2"
5580 [(set (reg FLAGS_REG)
5582 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5583 (match_operand:SI 2 "general_operand" "rmni,rni"))
5585 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5586 (plus:SI (match_dup 1) (match_dup 2)))]
5587 "ix86_match_ccmode (insn, CCGOCmode)
5588 && ix86_binary_operator_ok (PLUS, SImode, operands)
5589 /* Current assemblers are broken and do not allow @GOTOFF in
5590 ought but a memory context. */
5591 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5593 switch (get_attr_type (insn))
5596 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5597 if (operands[2] == const1_rtx)
5598 return "inc{l}\t%0";
5601 gcc_assert (operands[2] == constm1_rtx);
5602 return "dec{l}\t%0";
5606 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5607 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5608 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5609 if (GET_CODE (operands[2]) == CONST_INT
5610 && (INTVAL (operands[2]) == 128
5611 || (INTVAL (operands[2]) < 0
5612 && INTVAL (operands[2]) != -128)))
5614 operands[2] = GEN_INT (-INTVAL (operands[2]));
5615 return "sub{l}\t{%2, %0|%0, %2}";
5617 return "add{l}\t{%2, %0|%0, %2}";
5621 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5622 (const_string "incdec")
5623 (const_string "alu")))
5624 (set_attr "mode" "SI")])
5626 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5627 (define_insn "*addsi_2_zext"
5628 [(set (reg FLAGS_REG)
5630 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5631 (match_operand:SI 2 "general_operand" "rmni"))
5633 (set (match_operand:DI 0 "register_operand" "=r")
5634 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5635 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5636 && ix86_binary_operator_ok (PLUS, SImode, operands)
5637 /* Current assemblers are broken and do not allow @GOTOFF in
5638 ought but a memory context. */
5639 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5641 switch (get_attr_type (insn))
5644 if (operands[2] == const1_rtx)
5645 return "inc{l}\t%k0";
5648 gcc_assert (operands[2] == constm1_rtx);
5649 return "dec{l}\t%k0";
5653 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5654 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5655 if (GET_CODE (operands[2]) == CONST_INT
5656 && (INTVAL (operands[2]) == 128
5657 || (INTVAL (operands[2]) < 0
5658 && INTVAL (operands[2]) != -128)))
5660 operands[2] = GEN_INT (-INTVAL (operands[2]));
5661 return "sub{l}\t{%2, %k0|%k0, %2}";
5663 return "add{l}\t{%2, %k0|%k0, %2}";
5667 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5668 (const_string "incdec")
5669 (const_string "alu")))
5670 (set_attr "mode" "SI")])
5672 (define_insn "*addsi_3"
5673 [(set (reg FLAGS_REG)
5674 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5675 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5676 (clobber (match_scratch:SI 0 "=r"))]
5677 "ix86_match_ccmode (insn, CCZmode)
5678 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5679 /* Current assemblers are broken and do not allow @GOTOFF in
5680 ought but a memory context. */
5681 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5683 switch (get_attr_type (insn))
5686 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5687 if (operands[2] == const1_rtx)
5688 return "inc{l}\t%0";
5691 gcc_assert (operands[2] == constm1_rtx);
5692 return "dec{l}\t%0";
5696 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5697 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5698 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5699 if (GET_CODE (operands[2]) == CONST_INT
5700 && (INTVAL (operands[2]) == 128
5701 || (INTVAL (operands[2]) < 0
5702 && INTVAL (operands[2]) != -128)))
5704 operands[2] = GEN_INT (-INTVAL (operands[2]));
5705 return "sub{l}\t{%2, %0|%0, %2}";
5707 return "add{l}\t{%2, %0|%0, %2}";
5711 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5712 (const_string "incdec")
5713 (const_string "alu")))
5714 (set_attr "mode" "SI")])
5716 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5717 (define_insn "*addsi_3_zext"
5718 [(set (reg FLAGS_REG)
5719 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5720 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5721 (set (match_operand:DI 0 "register_operand" "=r")
5722 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5723 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5724 && ix86_binary_operator_ok (PLUS, SImode, operands)
5725 /* Current assemblers are broken and do not allow @GOTOFF in
5726 ought but a memory context. */
5727 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5729 switch (get_attr_type (insn))
5732 if (operands[2] == const1_rtx)
5733 return "inc{l}\t%k0";
5736 gcc_assert (operands[2] == constm1_rtx);
5737 return "dec{l}\t%k0";
5741 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5742 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5743 if (GET_CODE (operands[2]) == CONST_INT
5744 && (INTVAL (operands[2]) == 128
5745 || (INTVAL (operands[2]) < 0
5746 && INTVAL (operands[2]) != -128)))
5748 operands[2] = GEN_INT (-INTVAL (operands[2]));
5749 return "sub{l}\t{%2, %k0|%k0, %2}";
5751 return "add{l}\t{%2, %k0|%k0, %2}";
5755 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5756 (const_string "incdec")
5757 (const_string "alu")))
5758 (set_attr "mode" "SI")])
5760 ; For comparisons against 1, -1 and 128, we may generate better code
5761 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5762 ; is matched then. We can't accept general immediate, because for
5763 ; case of overflows, the result is messed up.
5764 ; This pattern also don't hold of 0x80000000, since the value overflows
5766 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5767 ; only for comparisons not depending on it.
5768 (define_insn "*addsi_4"
5769 [(set (reg FLAGS_REG)
5770 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5771 (match_operand:SI 2 "const_int_operand" "n")))
5772 (clobber (match_scratch:SI 0 "=rm"))]
5773 "ix86_match_ccmode (insn, CCGCmode)
5774 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5776 switch (get_attr_type (insn))
5779 if (operands[2] == constm1_rtx)
5780 return "inc{l}\t%0";
5783 gcc_assert (operands[2] == const1_rtx);
5784 return "dec{l}\t%0";
5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5791 if ((INTVAL (operands[2]) == -128
5792 || (INTVAL (operands[2]) > 0
5793 && INTVAL (operands[2]) != 128)))
5794 return "sub{l}\t{%2, %0|%0, %2}";
5795 operands[2] = GEN_INT (-INTVAL (operands[2]));
5796 return "add{l}\t{%2, %0|%0, %2}";
5800 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5801 (const_string "incdec")
5802 (const_string "alu")))
5803 (set_attr "mode" "SI")])
5805 (define_insn "*addsi_5"
5806 [(set (reg FLAGS_REG)
5808 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5809 (match_operand:SI 2 "general_operand" "rmni"))
5811 (clobber (match_scratch:SI 0 "=r"))]
5812 "ix86_match_ccmode (insn, CCGOCmode)
5813 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5814 /* Current assemblers are broken and do not allow @GOTOFF in
5815 ought but a memory context. */
5816 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5818 switch (get_attr_type (insn))
5821 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5822 if (operands[2] == const1_rtx)
5823 return "inc{l}\t%0";
5826 gcc_assert (operands[2] == constm1_rtx);
5827 return "dec{l}\t%0";
5831 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5832 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5834 if (GET_CODE (operands[2]) == CONST_INT
5835 && (INTVAL (operands[2]) == 128
5836 || (INTVAL (operands[2]) < 0
5837 && INTVAL (operands[2]) != -128)))
5839 operands[2] = GEN_INT (-INTVAL (operands[2]));
5840 return "sub{l}\t{%2, %0|%0, %2}";
5842 return "add{l}\t{%2, %0|%0, %2}";
5846 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5847 (const_string "incdec")
5848 (const_string "alu")))
5849 (set_attr "mode" "SI")])
5851 (define_expand "addhi3"
5852 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5853 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5854 (match_operand:HI 2 "general_operand" "")))
5855 (clobber (reg:CC FLAGS_REG))])]
5856 "TARGET_HIMODE_MATH"
5857 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5859 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5860 ;; type optimizations enabled by define-splits. This is not important
5861 ;; for PII, and in fact harmful because of partial register stalls.
5863 (define_insn "*addhi_1_lea"
5864 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5865 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5866 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5867 (clobber (reg:CC FLAGS_REG))]
5868 "!TARGET_PARTIAL_REG_STALL
5869 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5871 switch (get_attr_type (insn))
5876 if (operands[2] == const1_rtx)
5877 return "inc{w}\t%0";
5880 gcc_assert (operands[2] == constm1_rtx);
5881 return "dec{w}\t%0";
5885 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5886 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5887 if (GET_CODE (operands[2]) == CONST_INT
5888 && (INTVAL (operands[2]) == 128
5889 || (INTVAL (operands[2]) < 0
5890 && INTVAL (operands[2]) != -128)))
5892 operands[2] = GEN_INT (-INTVAL (operands[2]));
5893 return "sub{w}\t{%2, %0|%0, %2}";
5895 return "add{w}\t{%2, %0|%0, %2}";
5899 (if_then_else (eq_attr "alternative" "2")
5900 (const_string "lea")
5901 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5902 (const_string "incdec")
5903 (const_string "alu"))))
5904 (set_attr "mode" "HI,HI,SI")])
5906 (define_insn "*addhi_1"
5907 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5908 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5909 (match_operand:HI 2 "general_operand" "ri,rm")))
5910 (clobber (reg:CC FLAGS_REG))]
5911 "TARGET_PARTIAL_REG_STALL
5912 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5914 switch (get_attr_type (insn))
5917 if (operands[2] == const1_rtx)
5918 return "inc{w}\t%0";
5921 gcc_assert (operands[2] == constm1_rtx);
5922 return "dec{w}\t%0";
5926 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5927 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5928 if (GET_CODE (operands[2]) == CONST_INT
5929 && (INTVAL (operands[2]) == 128
5930 || (INTVAL (operands[2]) < 0
5931 && INTVAL (operands[2]) != -128)))
5933 operands[2] = GEN_INT (-INTVAL (operands[2]));
5934 return "sub{w}\t{%2, %0|%0, %2}";
5936 return "add{w}\t{%2, %0|%0, %2}";
5940 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5941 (const_string "incdec")
5942 (const_string "alu")))
5943 (set_attr "mode" "HI")])
5945 (define_insn "*addhi_2"
5946 [(set (reg FLAGS_REG)
5948 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5949 (match_operand:HI 2 "general_operand" "rmni,rni"))
5951 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5952 (plus:HI (match_dup 1) (match_dup 2)))]
5953 "ix86_match_ccmode (insn, CCGOCmode)
5954 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5956 switch (get_attr_type (insn))
5959 if (operands[2] == const1_rtx)
5960 return "inc{w}\t%0";
5963 gcc_assert (operands[2] == constm1_rtx);
5964 return "dec{w}\t%0";
5968 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5969 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5970 if (GET_CODE (operands[2]) == CONST_INT
5971 && (INTVAL (operands[2]) == 128
5972 || (INTVAL (operands[2]) < 0
5973 && INTVAL (operands[2]) != -128)))
5975 operands[2] = GEN_INT (-INTVAL (operands[2]));
5976 return "sub{w}\t{%2, %0|%0, %2}";
5978 return "add{w}\t{%2, %0|%0, %2}";
5982 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5983 (const_string "incdec")
5984 (const_string "alu")))
5985 (set_attr "mode" "HI")])
5987 (define_insn "*addhi_3"
5988 [(set (reg FLAGS_REG)
5989 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5990 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5991 (clobber (match_scratch:HI 0 "=r"))]
5992 "ix86_match_ccmode (insn, CCZmode)
5993 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5995 switch (get_attr_type (insn))
5998 if (operands[2] == const1_rtx)
5999 return "inc{w}\t%0";
6002 gcc_assert (operands[2] == constm1_rtx);
6003 return "dec{w}\t%0";
6007 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6009 if (GET_CODE (operands[2]) == CONST_INT
6010 && (INTVAL (operands[2]) == 128
6011 || (INTVAL (operands[2]) < 0
6012 && INTVAL (operands[2]) != -128)))
6014 operands[2] = GEN_INT (-INTVAL (operands[2]));
6015 return "sub{w}\t{%2, %0|%0, %2}";
6017 return "add{w}\t{%2, %0|%0, %2}";
6021 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022 (const_string "incdec")
6023 (const_string "alu")))
6024 (set_attr "mode" "HI")])
6026 ; See comments above addsi_4 for details.
6027 (define_insn "*addhi_4"
6028 [(set (reg FLAGS_REG)
6029 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6030 (match_operand:HI 2 "const_int_operand" "n")))
6031 (clobber (match_scratch:HI 0 "=rm"))]
6032 "ix86_match_ccmode (insn, CCGCmode)
6033 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6035 switch (get_attr_type (insn))
6038 if (operands[2] == constm1_rtx)
6039 return "inc{w}\t%0";
6042 gcc_assert (operands[2] == const1_rtx);
6043 return "dec{w}\t%0";
6047 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6048 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6049 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6050 if ((INTVAL (operands[2]) == -128
6051 || (INTVAL (operands[2]) > 0
6052 && INTVAL (operands[2]) != 128)))
6053 return "sub{w}\t{%2, %0|%0, %2}";
6054 operands[2] = GEN_INT (-INTVAL (operands[2]));
6055 return "add{w}\t{%2, %0|%0, %2}";
6059 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6060 (const_string "incdec")
6061 (const_string "alu")))
6062 (set_attr "mode" "SI")])
6065 (define_insn "*addhi_5"
6066 [(set (reg FLAGS_REG)
6068 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6069 (match_operand:HI 2 "general_operand" "rmni"))
6071 (clobber (match_scratch:HI 0 "=r"))]
6072 "ix86_match_ccmode (insn, CCGOCmode)
6073 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6075 switch (get_attr_type (insn))
6078 if (operands[2] == const1_rtx)
6079 return "inc{w}\t%0";
6082 gcc_assert (operands[2] == constm1_rtx);
6083 return "dec{w}\t%0";
6087 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6088 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6089 if (GET_CODE (operands[2]) == CONST_INT
6090 && (INTVAL (operands[2]) == 128
6091 || (INTVAL (operands[2]) < 0
6092 && INTVAL (operands[2]) != -128)))
6094 operands[2] = GEN_INT (-INTVAL (operands[2]));
6095 return "sub{w}\t{%2, %0|%0, %2}";
6097 return "add{w}\t{%2, %0|%0, %2}";
6101 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6102 (const_string "incdec")
6103 (const_string "alu")))
6104 (set_attr "mode" "HI")])
6106 (define_expand "addqi3"
6107 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6108 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6109 (match_operand:QI 2 "general_operand" "")))
6110 (clobber (reg:CC FLAGS_REG))])]
6111 "TARGET_QIMODE_MATH"
6112 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6114 ;; %%% Potential partial reg stall on alternative 2. What to do?
6115 (define_insn "*addqi_1_lea"
6116 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6117 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6118 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6119 (clobber (reg:CC FLAGS_REG))]
6120 "!TARGET_PARTIAL_REG_STALL
6121 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6123 int widen = (which_alternative == 2);
6124 switch (get_attr_type (insn))
6129 if (operands[2] == const1_rtx)
6130 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6133 gcc_assert (operands[2] == constm1_rtx);
6134 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6138 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6139 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6140 if (GET_CODE (operands[2]) == CONST_INT
6141 && (INTVAL (operands[2]) == 128
6142 || (INTVAL (operands[2]) < 0
6143 && INTVAL (operands[2]) != -128)))
6145 operands[2] = GEN_INT (-INTVAL (operands[2]));
6147 return "sub{l}\t{%2, %k0|%k0, %2}";
6149 return "sub{b}\t{%2, %0|%0, %2}";
6152 return "add{l}\t{%k2, %k0|%k0, %k2}";
6154 return "add{b}\t{%2, %0|%0, %2}";
6158 (if_then_else (eq_attr "alternative" "3")
6159 (const_string "lea")
6160 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6161 (const_string "incdec")
6162 (const_string "alu"))))
6163 (set_attr "mode" "QI,QI,SI,SI")])
6165 (define_insn "*addqi_1"
6166 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6167 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6168 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6169 (clobber (reg:CC FLAGS_REG))]
6170 "TARGET_PARTIAL_REG_STALL
6171 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6173 int widen = (which_alternative == 2);
6174 switch (get_attr_type (insn))
6177 if (operands[2] == const1_rtx)
6178 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6181 gcc_assert (operands[2] == constm1_rtx);
6182 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6186 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6187 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6188 if (GET_CODE (operands[2]) == CONST_INT
6189 && (INTVAL (operands[2]) == 128
6190 || (INTVAL (operands[2]) < 0
6191 && INTVAL (operands[2]) != -128)))
6193 operands[2] = GEN_INT (-INTVAL (operands[2]));
6195 return "sub{l}\t{%2, %k0|%k0, %2}";
6197 return "sub{b}\t{%2, %0|%0, %2}";
6200 return "add{l}\t{%k2, %k0|%k0, %k2}";
6202 return "add{b}\t{%2, %0|%0, %2}";
6206 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6207 (const_string "incdec")
6208 (const_string "alu")))
6209 (set_attr "mode" "QI,QI,SI")])
6211 (define_insn "*addqi_1_slp"
6212 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6213 (plus:QI (match_dup 0)
6214 (match_operand:QI 1 "general_operand" "qn,qnm")))
6215 (clobber (reg:CC FLAGS_REG))]
6216 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6217 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6219 switch (get_attr_type (insn))
6222 if (operands[1] == const1_rtx)
6223 return "inc{b}\t%0";
6226 gcc_assert (operands[1] == constm1_rtx);
6227 return "dec{b}\t%0";
6231 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6232 if (GET_CODE (operands[1]) == CONST_INT
6233 && INTVAL (operands[1]) < 0)
6235 operands[1] = GEN_INT (-INTVAL (operands[1]));
6236 return "sub{b}\t{%1, %0|%0, %1}";
6238 return "add{b}\t{%1, %0|%0, %1}";
6242 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6243 (const_string "incdec")
6244 (const_string "alu1")))
6245 (set (attr "memory")
6246 (if_then_else (match_operand 1 "memory_operand" "")
6247 (const_string "load")
6248 (const_string "none")))
6249 (set_attr "mode" "QI")])
6251 (define_insn "*addqi_2"
6252 [(set (reg FLAGS_REG)
6254 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6255 (match_operand:QI 2 "general_operand" "qmni,qni"))
6257 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6258 (plus:QI (match_dup 1) (match_dup 2)))]
6259 "ix86_match_ccmode (insn, CCGOCmode)
6260 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6262 switch (get_attr_type (insn))
6265 if (operands[2] == const1_rtx)
6266 return "inc{b}\t%0";
6269 gcc_assert (operands[2] == constm1_rtx
6270 || (GET_CODE (operands[2]) == CONST_INT
6271 && INTVAL (operands[2]) == 255));
6272 return "dec{b}\t%0";
6276 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6277 if (GET_CODE (operands[2]) == CONST_INT
6278 && INTVAL (operands[2]) < 0)
6280 operands[2] = GEN_INT (-INTVAL (operands[2]));
6281 return "sub{b}\t{%2, %0|%0, %2}";
6283 return "add{b}\t{%2, %0|%0, %2}";
6287 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288 (const_string "incdec")
6289 (const_string "alu")))
6290 (set_attr "mode" "QI")])
6292 (define_insn "*addqi_3"
6293 [(set (reg FLAGS_REG)
6294 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6295 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6296 (clobber (match_scratch:QI 0 "=q"))]
6297 "ix86_match_ccmode (insn, CCZmode)
6298 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6300 switch (get_attr_type (insn))
6303 if (operands[2] == const1_rtx)
6304 return "inc{b}\t%0";
6307 gcc_assert (operands[2] == constm1_rtx
6308 || (GET_CODE (operands[2]) == CONST_INT
6309 && INTVAL (operands[2]) == 255));
6310 return "dec{b}\t%0";
6314 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6315 if (GET_CODE (operands[2]) == CONST_INT
6316 && INTVAL (operands[2]) < 0)
6318 operands[2] = GEN_INT (-INTVAL (operands[2]));
6319 return "sub{b}\t{%2, %0|%0, %2}";
6321 return "add{b}\t{%2, %0|%0, %2}";
6325 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6326 (const_string "incdec")
6327 (const_string "alu")))
6328 (set_attr "mode" "QI")])
6330 ; See comments above addsi_4 for details.
6331 (define_insn "*addqi_4"
6332 [(set (reg FLAGS_REG)
6333 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6334 (match_operand:QI 2 "const_int_operand" "n")))
6335 (clobber (match_scratch:QI 0 "=qm"))]
6336 "ix86_match_ccmode (insn, CCGCmode)
6337 && (INTVAL (operands[2]) & 0xff) != 0x80"
6339 switch (get_attr_type (insn))
6342 if (operands[2] == constm1_rtx
6343 || (GET_CODE (operands[2]) == CONST_INT
6344 && INTVAL (operands[2]) == 255))
6345 return "inc{b}\t%0";
6348 gcc_assert (operands[2] == const1_rtx);
6349 return "dec{b}\t%0";
6353 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6354 if (INTVAL (operands[2]) < 0)
6356 operands[2] = GEN_INT (-INTVAL (operands[2]));
6357 return "add{b}\t{%2, %0|%0, %2}";
6359 return "sub{b}\t{%2, %0|%0, %2}";
6363 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6364 (const_string "incdec")
6365 (const_string "alu")))
6366 (set_attr "mode" "QI")])
6369 (define_insn "*addqi_5"
6370 [(set (reg FLAGS_REG)
6372 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6373 (match_operand:QI 2 "general_operand" "qmni"))
6375 (clobber (match_scratch:QI 0 "=q"))]
6376 "ix86_match_ccmode (insn, CCGOCmode)
6377 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6379 switch (get_attr_type (insn))
6382 if (operands[2] == const1_rtx)
6383 return "inc{b}\t%0";
6386 gcc_assert (operands[2] == constm1_rtx
6387 || (GET_CODE (operands[2]) == CONST_INT
6388 && INTVAL (operands[2]) == 255));
6389 return "dec{b}\t%0";
6393 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6394 if (GET_CODE (operands[2]) == CONST_INT
6395 && INTVAL (operands[2]) < 0)
6397 operands[2] = GEN_INT (-INTVAL (operands[2]));
6398 return "sub{b}\t{%2, %0|%0, %2}";
6400 return "add{b}\t{%2, %0|%0, %2}";
6404 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6405 (const_string "incdec")
6406 (const_string "alu")))
6407 (set_attr "mode" "QI")])
6410 (define_insn "addqi_ext_1"
6411 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6416 (match_operand 1 "ext_register_operand" "0")
6419 (match_operand:QI 2 "general_operand" "Qmn")))
6420 (clobber (reg:CC FLAGS_REG))]
6423 switch (get_attr_type (insn))
6426 if (operands[2] == const1_rtx)
6427 return "inc{b}\t%h0";
6430 gcc_assert (operands[2] == constm1_rtx
6431 || (GET_CODE (operands[2]) == CONST_INT
6432 && INTVAL (operands[2]) == 255));
6433 return "dec{b}\t%h0";
6437 return "add{b}\t{%2, %h0|%h0, %2}";
6441 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6442 (const_string "incdec")
6443 (const_string "alu")))
6444 (set_attr "mode" "QI")])
6446 (define_insn "*addqi_ext_1_rex64"
6447 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6452 (match_operand 1 "ext_register_operand" "0")
6455 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6456 (clobber (reg:CC FLAGS_REG))]
6459 switch (get_attr_type (insn))
6462 if (operands[2] == const1_rtx)
6463 return "inc{b}\t%h0";
6466 gcc_assert (operands[2] == constm1_rtx
6467 || (GET_CODE (operands[2]) == CONST_INT
6468 && INTVAL (operands[2]) == 255));
6469 return "dec{b}\t%h0";
6473 return "add{b}\t{%2, %h0|%h0, %2}";
6477 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6478 (const_string "incdec")
6479 (const_string "alu")))
6480 (set_attr "mode" "QI")])
6482 (define_insn "*addqi_ext_2"
6483 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6488 (match_operand 1 "ext_register_operand" "%0")
6492 (match_operand 2 "ext_register_operand" "Q")
6495 (clobber (reg:CC FLAGS_REG))]
6497 "add{b}\t{%h2, %h0|%h0, %h2}"
6498 [(set_attr "type" "alu")
6499 (set_attr "mode" "QI")])
6501 ;; The patterns that match these are at the end of this file.
6503 (define_expand "addxf3"
6504 [(set (match_operand:XF 0 "register_operand" "")
6505 (plus:XF (match_operand:XF 1 "register_operand" "")
6506 (match_operand:XF 2 "register_operand" "")))]
6510 (define_expand "adddf3"
6511 [(set (match_operand:DF 0 "register_operand" "")
6512 (plus:DF (match_operand:DF 1 "register_operand" "")
6513 (match_operand:DF 2 "nonimmediate_operand" "")))]
6514 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6517 (define_expand "addsf3"
6518 [(set (match_operand:SF 0 "register_operand" "")
6519 (plus:SF (match_operand:SF 1 "register_operand" "")
6520 (match_operand:SF 2 "nonimmediate_operand" "")))]
6521 "TARGET_80387 || TARGET_SSE_MATH"
6524 ;; Subtract instructions
6526 ;; %%% splits for subditi3
6528 (define_expand "subti3"
6529 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6530 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6531 (match_operand:TI 2 "x86_64_general_operand" "")))
6532 (clobber (reg:CC FLAGS_REG))])]
6534 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6536 (define_insn "*subti3_1"
6537 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6538 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6539 (match_operand:TI 2 "general_operand" "roiF,riF")))
6540 (clobber (reg:CC FLAGS_REG))]
6541 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6545 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6546 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6547 (match_operand:TI 2 "general_operand" "")))
6548 (clobber (reg:CC FLAGS_REG))]
6549 "TARGET_64BIT && reload_completed"
6550 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6551 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6552 (parallel [(set (match_dup 3)
6553 (minus:DI (match_dup 4)
6554 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6556 (clobber (reg:CC FLAGS_REG))])]
6557 "split_ti (operands+0, 1, operands+0, operands+3);
6558 split_ti (operands+1, 1, operands+1, operands+4);
6559 split_ti (operands+2, 1, operands+2, operands+5);")
6561 ;; %%% splits for subsidi3
6563 (define_expand "subdi3"
6564 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6565 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6566 (match_operand:DI 2 "x86_64_general_operand" "")))
6567 (clobber (reg:CC FLAGS_REG))])]
6569 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6571 (define_insn "*subdi3_1"
6572 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6573 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6574 (match_operand:DI 2 "general_operand" "roiF,riF")))
6575 (clobber (reg:CC FLAGS_REG))]
6576 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6580 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6581 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6582 (match_operand:DI 2 "general_operand" "")))
6583 (clobber (reg:CC FLAGS_REG))]
6584 "!TARGET_64BIT && reload_completed"
6585 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6586 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6587 (parallel [(set (match_dup 3)
6588 (minus:SI (match_dup 4)
6589 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6591 (clobber (reg:CC FLAGS_REG))])]
6592 "split_di (operands+0, 1, operands+0, operands+3);
6593 split_di (operands+1, 1, operands+1, operands+4);
6594 split_di (operands+2, 1, operands+2, operands+5);")
6596 (define_insn "subdi3_carry_rex64"
6597 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6598 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6599 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6600 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6601 (clobber (reg:CC FLAGS_REG))]
6602 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6603 "sbb{q}\t{%2, %0|%0, %2}"
6604 [(set_attr "type" "alu")
6605 (set_attr "pent_pair" "pu")
6606 (set_attr "mode" "DI")])
6608 (define_insn "*subdi_1_rex64"
6609 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6610 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6611 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6612 (clobber (reg:CC FLAGS_REG))]
6613 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6614 "sub{q}\t{%2, %0|%0, %2}"
6615 [(set_attr "type" "alu")
6616 (set_attr "mode" "DI")])
6618 (define_insn "*subdi_2_rex64"
6619 [(set (reg FLAGS_REG)
6621 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6624 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6625 (minus:DI (match_dup 1) (match_dup 2)))]
6626 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6627 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6628 "sub{q}\t{%2, %0|%0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "mode" "DI")])
6632 (define_insn "*subdi_3_rex63"
6633 [(set (reg FLAGS_REG)
6634 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6635 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6636 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6637 (minus:DI (match_dup 1) (match_dup 2)))]
6638 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6639 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6640 "sub{q}\t{%2, %0|%0, %2}"
6641 [(set_attr "type" "alu")
6642 (set_attr "mode" "DI")])
6644 (define_insn "subqi3_carry"
6645 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6646 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6647 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6648 (match_operand:QI 2 "general_operand" "qi,qm"))))
6649 (clobber (reg:CC FLAGS_REG))]
6650 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6651 "sbb{b}\t{%2, %0|%0, %2}"
6652 [(set_attr "type" "alu")
6653 (set_attr "pent_pair" "pu")
6654 (set_attr "mode" "QI")])
6656 (define_insn "subhi3_carry"
6657 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6658 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6659 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6660 (match_operand:HI 2 "general_operand" "ri,rm"))))
6661 (clobber (reg:CC FLAGS_REG))]
6662 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6663 "sbb{w}\t{%2, %0|%0, %2}"
6664 [(set_attr "type" "alu")
6665 (set_attr "pent_pair" "pu")
6666 (set_attr "mode" "HI")])
6668 (define_insn "subsi3_carry"
6669 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6670 (minus:SI (match_operand:SI 1 "nonimmediate_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 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6675 "sbb{l}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "pent_pair" "pu")
6678 (set_attr "mode" "SI")])
6680 (define_insn "subsi3_carry_zext"
6681 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6683 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6684 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6685 (match_operand:SI 2 "general_operand" "ri,rm")))))
6686 (clobber (reg:CC FLAGS_REG))]
6687 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6688 "sbb{l}\t{%2, %k0|%k0, %2}"
6689 [(set_attr "type" "alu")
6690 (set_attr "pent_pair" "pu")
6691 (set_attr "mode" "SI")])
6693 (define_expand "subsi3"
6694 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6695 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6696 (match_operand:SI 2 "general_operand" "")))
6697 (clobber (reg:CC FLAGS_REG))])]
6699 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6701 (define_insn "*subsi_1"
6702 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6703 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6704 (match_operand:SI 2 "general_operand" "ri,rm")))
6705 (clobber (reg:CC FLAGS_REG))]
6706 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6707 "sub{l}\t{%2, %0|%0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "mode" "SI")])
6711 (define_insn "*subsi_1_zext"
6712 [(set (match_operand:DI 0 "register_operand" "=r")
6714 (minus:SI (match_operand:SI 1 "register_operand" "0")
6715 (match_operand:SI 2 "general_operand" "rim"))))
6716 (clobber (reg:CC FLAGS_REG))]
6717 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6718 "sub{l}\t{%2, %k0|%k0, %2}"
6719 [(set_attr "type" "alu")
6720 (set_attr "mode" "SI")])
6722 (define_insn "*subsi_2"
6723 [(set (reg FLAGS_REG)
6725 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6726 (match_operand:SI 2 "general_operand" "ri,rm"))
6728 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6729 (minus:SI (match_dup 1) (match_dup 2)))]
6730 "ix86_match_ccmode (insn, CCGOCmode)
6731 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6732 "sub{l}\t{%2, %0|%0, %2}"
6733 [(set_attr "type" "alu")
6734 (set_attr "mode" "SI")])
6736 (define_insn "*subsi_2_zext"
6737 [(set (reg FLAGS_REG)
6739 (minus:SI (match_operand:SI 1 "register_operand" "0")
6740 (match_operand:SI 2 "general_operand" "rim"))
6742 (set (match_operand:DI 0 "register_operand" "=r")
6744 (minus:SI (match_dup 1)
6746 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6747 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6748 "sub{l}\t{%2, %k0|%k0, %2}"
6749 [(set_attr "type" "alu")
6750 (set_attr "mode" "SI")])
6752 (define_insn "*subsi_3"
6753 [(set (reg FLAGS_REG)
6754 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6755 (match_operand:SI 2 "general_operand" "ri,rm")))
6756 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6757 (minus:SI (match_dup 1) (match_dup 2)))]
6758 "ix86_match_ccmode (insn, CCmode)
6759 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6760 "sub{l}\t{%2, %0|%0, %2}"
6761 [(set_attr "type" "alu")
6762 (set_attr "mode" "SI")])
6764 (define_insn "*subsi_3_zext"
6765 [(set (reg FLAGS_REG)
6766 (compare (match_operand:SI 1 "register_operand" "0")
6767 (match_operand:SI 2 "general_operand" "rim")))
6768 (set (match_operand:DI 0 "register_operand" "=r")
6770 (minus:SI (match_dup 1)
6772 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6773 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6774 "sub{l}\t{%2, %1|%1, %2}"
6775 [(set_attr "type" "alu")
6776 (set_attr "mode" "DI")])
6778 (define_expand "subhi3"
6779 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6780 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6781 (match_operand:HI 2 "general_operand" "")))
6782 (clobber (reg:CC FLAGS_REG))])]
6783 "TARGET_HIMODE_MATH"
6784 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6786 (define_insn "*subhi_1"
6787 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6788 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6789 (match_operand:HI 2 "general_operand" "ri,rm")))
6790 (clobber (reg:CC FLAGS_REG))]
6791 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6792 "sub{w}\t{%2, %0|%0, %2}"
6793 [(set_attr "type" "alu")
6794 (set_attr "mode" "HI")])
6796 (define_insn "*subhi_2"
6797 [(set (reg FLAGS_REG)
6799 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6800 (match_operand:HI 2 "general_operand" "ri,rm"))
6802 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6803 (minus:HI (match_dup 1) (match_dup 2)))]
6804 "ix86_match_ccmode (insn, CCGOCmode)
6805 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6806 "sub{w}\t{%2, %0|%0, %2}"
6807 [(set_attr "type" "alu")
6808 (set_attr "mode" "HI")])
6810 (define_insn "*subhi_3"
6811 [(set (reg FLAGS_REG)
6812 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6813 (match_operand:HI 2 "general_operand" "ri,rm")))
6814 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6815 (minus:HI (match_dup 1) (match_dup 2)))]
6816 "ix86_match_ccmode (insn, CCmode)
6817 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6818 "sub{w}\t{%2, %0|%0, %2}"
6819 [(set_attr "type" "alu")
6820 (set_attr "mode" "HI")])
6822 (define_expand "subqi3"
6823 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6824 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6825 (match_operand:QI 2 "general_operand" "")))
6826 (clobber (reg:CC FLAGS_REG))])]
6827 "TARGET_QIMODE_MATH"
6828 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6830 (define_insn "*subqi_1"
6831 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6832 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6833 (match_operand:QI 2 "general_operand" "qn,qmn")))
6834 (clobber (reg:CC FLAGS_REG))]
6835 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6836 "sub{b}\t{%2, %0|%0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "mode" "QI")])
6840 (define_insn "*subqi_1_slp"
6841 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6842 (minus:QI (match_dup 0)
6843 (match_operand:QI 1 "general_operand" "qn,qmn")))
6844 (clobber (reg:CC FLAGS_REG))]
6845 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6846 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6847 "sub{b}\t{%1, %0|%0, %1}"
6848 [(set_attr "type" "alu1")
6849 (set_attr "mode" "QI")])
6851 (define_insn "*subqi_2"
6852 [(set (reg FLAGS_REG)
6854 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855 (match_operand:QI 2 "general_operand" "qi,qm"))
6857 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6858 (minus:HI (match_dup 1) (match_dup 2)))]
6859 "ix86_match_ccmode (insn, CCGOCmode)
6860 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6861 "sub{b}\t{%2, %0|%0, %2}"
6862 [(set_attr "type" "alu")
6863 (set_attr "mode" "QI")])
6865 (define_insn "*subqi_3"
6866 [(set (reg FLAGS_REG)
6867 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6868 (match_operand:QI 2 "general_operand" "qi,qm")))
6869 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6870 (minus:HI (match_dup 1) (match_dup 2)))]
6871 "ix86_match_ccmode (insn, CCmode)
6872 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6873 "sub{b}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "alu")
6875 (set_attr "mode" "QI")])
6877 ;; The patterns that match these are at the end of this file.
6879 (define_expand "subxf3"
6880 [(set (match_operand:XF 0 "register_operand" "")
6881 (minus:XF (match_operand:XF 1 "register_operand" "")
6882 (match_operand:XF 2 "register_operand" "")))]
6886 (define_expand "subdf3"
6887 [(set (match_operand:DF 0 "register_operand" "")
6888 (minus:DF (match_operand:DF 1 "register_operand" "")
6889 (match_operand:DF 2 "nonimmediate_operand" "")))]
6890 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6893 (define_expand "subsf3"
6894 [(set (match_operand:SF 0 "register_operand" "")
6895 (minus:SF (match_operand:SF 1 "register_operand" "")
6896 (match_operand:SF 2 "nonimmediate_operand" "")))]
6897 "TARGET_80387 || TARGET_SSE_MATH"
6900 ;; Multiply instructions
6902 (define_expand "muldi3"
6903 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6904 (mult:DI (match_operand:DI 1 "register_operand" "")
6905 (match_operand:DI 2 "x86_64_general_operand" "")))
6906 (clobber (reg:CC FLAGS_REG))])]
6910 (define_insn "*muldi3_1_rex64"
6911 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6912 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6913 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6914 (clobber (reg:CC FLAGS_REG))]
6916 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6918 imul{q}\t{%2, %1, %0|%0, %1, %2}
6919 imul{q}\t{%2, %1, %0|%0, %1, %2}
6920 imul{q}\t{%2, %0|%0, %2}"
6921 [(set_attr "type" "imul")
6922 (set_attr "prefix_0f" "0,0,1")
6923 (set (attr "athlon_decode")
6924 (cond [(eq_attr "cpu" "athlon")
6925 (const_string "vector")
6926 (eq_attr "alternative" "1")
6927 (const_string "vector")
6928 (and (eq_attr "alternative" "2")
6929 (match_operand 1 "memory_operand" ""))
6930 (const_string "vector")]
6931 (const_string "direct")))
6932 (set_attr "mode" "DI")])
6934 (define_expand "mulsi3"
6935 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6936 (mult:SI (match_operand:SI 1 "register_operand" "")
6937 (match_operand:SI 2 "general_operand" "")))
6938 (clobber (reg:CC FLAGS_REG))])]
6942 (define_insn "*mulsi3_1"
6943 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6944 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6945 (match_operand:SI 2 "general_operand" "K,i,mr")))
6946 (clobber (reg:CC FLAGS_REG))]
6947 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6949 imul{l}\t{%2, %1, %0|%0, %1, %2}
6950 imul{l}\t{%2, %1, %0|%0, %1, %2}
6951 imul{l}\t{%2, %0|%0, %2}"
6952 [(set_attr "type" "imul")
6953 (set_attr "prefix_0f" "0,0,1")
6954 (set (attr "athlon_decode")
6955 (cond [(eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (eq_attr "alternative" "1")
6958 (const_string "vector")
6959 (and (eq_attr "alternative" "2")
6960 (match_operand 1 "memory_operand" ""))
6961 (const_string "vector")]
6962 (const_string "direct")))
6963 (set_attr "mode" "SI")])
6965 (define_insn "*mulsi3_1_zext"
6966 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6968 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6969 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6970 (clobber (reg:CC FLAGS_REG))]
6972 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6974 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6975 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6976 imul{l}\t{%2, %k0|%k0, %2}"
6977 [(set_attr "type" "imul")
6978 (set_attr "prefix_0f" "0,0,1")
6979 (set (attr "athlon_decode")
6980 (cond [(eq_attr "cpu" "athlon")
6981 (const_string "vector")
6982 (eq_attr "alternative" "1")
6983 (const_string "vector")
6984 (and (eq_attr "alternative" "2")
6985 (match_operand 1 "memory_operand" ""))
6986 (const_string "vector")]
6987 (const_string "direct")))
6988 (set_attr "mode" "SI")])
6990 (define_expand "mulhi3"
6991 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6992 (mult:HI (match_operand:HI 1 "register_operand" "")
6993 (match_operand:HI 2 "general_operand" "")))
6994 (clobber (reg:CC FLAGS_REG))])]
6995 "TARGET_HIMODE_MATH"
6998 (define_insn "*mulhi3_1"
6999 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7000 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7001 (match_operand:HI 2 "general_operand" "K,i,mr")))
7002 (clobber (reg:CC FLAGS_REG))]
7003 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7005 imul{w}\t{%2, %1, %0|%0, %1, %2}
7006 imul{w}\t{%2, %1, %0|%0, %1, %2}
7007 imul{w}\t{%2, %0|%0, %2}"
7008 [(set_attr "type" "imul")
7009 (set_attr "prefix_0f" "0,0,1")
7010 (set (attr "athlon_decode")
7011 (cond [(eq_attr "cpu" "athlon")
7012 (const_string "vector")
7013 (eq_attr "alternative" "1,2")
7014 (const_string "vector")]
7015 (const_string "direct")))
7016 (set_attr "mode" "HI")])
7018 (define_expand "mulqi3"
7019 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7020 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7021 (match_operand:QI 2 "register_operand" "")))
7022 (clobber (reg:CC FLAGS_REG))])]
7023 "TARGET_QIMODE_MATH"
7026 (define_insn "*mulqi3_1"
7027 [(set (match_operand:QI 0 "register_operand" "=a")
7028 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7029 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7030 (clobber (reg:CC FLAGS_REG))]
7032 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7034 [(set_attr "type" "imul")
7035 (set_attr "length_immediate" "0")
7036 (set (attr "athlon_decode")
7037 (if_then_else (eq_attr "cpu" "athlon")
7038 (const_string "vector")
7039 (const_string "direct")))
7040 (set_attr "mode" "QI")])
7042 (define_expand "umulqihi3"
7043 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7044 (mult:HI (zero_extend:HI
7045 (match_operand:QI 1 "nonimmediate_operand" ""))
7047 (match_operand:QI 2 "register_operand" ""))))
7048 (clobber (reg:CC FLAGS_REG))])]
7049 "TARGET_QIMODE_MATH"
7052 (define_insn "*umulqihi3_1"
7053 [(set (match_operand:HI 0 "register_operand" "=a")
7054 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7055 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7056 (clobber (reg:CC FLAGS_REG))]
7058 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7060 [(set_attr "type" "imul")
7061 (set_attr "length_immediate" "0")
7062 (set (attr "athlon_decode")
7063 (if_then_else (eq_attr "cpu" "athlon")
7064 (const_string "vector")
7065 (const_string "direct")))
7066 (set_attr "mode" "QI")])
7068 (define_expand "mulqihi3"
7069 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7070 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7071 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7072 (clobber (reg:CC FLAGS_REG))])]
7073 "TARGET_QIMODE_MATH"
7076 (define_insn "*mulqihi3_insn"
7077 [(set (match_operand:HI 0 "register_operand" "=a")
7078 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7079 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7080 (clobber (reg:CC FLAGS_REG))]
7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7084 [(set_attr "type" "imul")
7085 (set_attr "length_immediate" "0")
7086 (set (attr "athlon_decode")
7087 (if_then_else (eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (const_string "direct")))
7090 (set_attr "mode" "QI")])
7092 (define_expand "umulditi3"
7093 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7094 (mult:TI (zero_extend:TI
7095 (match_operand:DI 1 "nonimmediate_operand" ""))
7097 (match_operand:DI 2 "register_operand" ""))))
7098 (clobber (reg:CC FLAGS_REG))])]
7102 (define_insn "*umulditi3_insn"
7103 [(set (match_operand:TI 0 "register_operand" "=A")
7104 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7105 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7106 (clobber (reg:CC FLAGS_REG))]
7108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7110 [(set_attr "type" "imul")
7111 (set_attr "length_immediate" "0")
7112 (set (attr "athlon_decode")
7113 (if_then_else (eq_attr "cpu" "athlon")
7114 (const_string "vector")
7115 (const_string "double")))
7116 (set_attr "mode" "DI")])
7118 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7119 (define_expand "umulsidi3"
7120 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7121 (mult:DI (zero_extend:DI
7122 (match_operand:SI 1 "nonimmediate_operand" ""))
7124 (match_operand:SI 2 "register_operand" ""))))
7125 (clobber (reg:CC FLAGS_REG))])]
7129 (define_insn "*umulsidi3_insn"
7130 [(set (match_operand:DI 0 "register_operand" "=A")
7131 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7132 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7133 (clobber (reg:CC FLAGS_REG))]
7135 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7137 [(set_attr "type" "imul")
7138 (set_attr "length_immediate" "0")
7139 (set (attr "athlon_decode")
7140 (if_then_else (eq_attr "cpu" "athlon")
7141 (const_string "vector")
7142 (const_string "double")))
7143 (set_attr "mode" "SI")])
7145 (define_expand "mulditi3"
7146 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7147 (mult:TI (sign_extend:TI
7148 (match_operand:DI 1 "nonimmediate_operand" ""))
7150 (match_operand:DI 2 "register_operand" ""))))
7151 (clobber (reg:CC FLAGS_REG))])]
7155 (define_insn "*mulditi3_insn"
7156 [(set (match_operand:TI 0 "register_operand" "=A")
7157 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7158 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7159 (clobber (reg:CC FLAGS_REG))]
7161 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7163 [(set_attr "type" "imul")
7164 (set_attr "length_immediate" "0")
7165 (set (attr "athlon_decode")
7166 (if_then_else (eq_attr "cpu" "athlon")
7167 (const_string "vector")
7168 (const_string "double")))
7169 (set_attr "mode" "DI")])
7171 (define_expand "mulsidi3"
7172 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7173 (mult:DI (sign_extend:DI
7174 (match_operand:SI 1 "nonimmediate_operand" ""))
7176 (match_operand:SI 2 "register_operand" ""))))
7177 (clobber (reg:CC FLAGS_REG))])]
7181 (define_insn "*mulsidi3_insn"
7182 [(set (match_operand:DI 0 "register_operand" "=A")
7183 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7184 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7185 (clobber (reg:CC FLAGS_REG))]
7187 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7189 [(set_attr "type" "imul")
7190 (set_attr "length_immediate" "0")
7191 (set (attr "athlon_decode")
7192 (if_then_else (eq_attr "cpu" "athlon")
7193 (const_string "vector")
7194 (const_string "double")))
7195 (set_attr "mode" "SI")])
7197 (define_expand "umuldi3_highpart"
7198 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7201 (mult:TI (zero_extend:TI
7202 (match_operand:DI 1 "nonimmediate_operand" ""))
7204 (match_operand:DI 2 "register_operand" "")))
7206 (clobber (match_scratch:DI 3 ""))
7207 (clobber (reg:CC FLAGS_REG))])]
7211 (define_insn "*umuldi3_highpart_rex64"
7212 [(set (match_operand:DI 0 "register_operand" "=d")
7215 (mult:TI (zero_extend:TI
7216 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7218 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7220 (clobber (match_scratch:DI 3 "=1"))
7221 (clobber (reg:CC FLAGS_REG))]
7223 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7225 [(set_attr "type" "imul")
7226 (set_attr "length_immediate" "0")
7227 (set (attr "athlon_decode")
7228 (if_then_else (eq_attr "cpu" "athlon")
7229 (const_string "vector")
7230 (const_string "double")))
7231 (set_attr "mode" "DI")])
7233 (define_expand "umulsi3_highpart"
7234 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7237 (mult:DI (zero_extend:DI
7238 (match_operand:SI 1 "nonimmediate_operand" ""))
7240 (match_operand:SI 2 "register_operand" "")))
7242 (clobber (match_scratch:SI 3 ""))
7243 (clobber (reg:CC FLAGS_REG))])]
7247 (define_insn "*umulsi3_highpart_insn"
7248 [(set (match_operand:SI 0 "register_operand" "=d")
7251 (mult:DI (zero_extend:DI
7252 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7254 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7256 (clobber (match_scratch:SI 3 "=1"))
7257 (clobber (reg:CC FLAGS_REG))]
7258 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7260 [(set_attr "type" "imul")
7261 (set_attr "length_immediate" "0")
7262 (set (attr "athlon_decode")
7263 (if_then_else (eq_attr "cpu" "athlon")
7264 (const_string "vector")
7265 (const_string "double")))
7266 (set_attr "mode" "SI")])
7268 (define_insn "*umulsi3_highpart_zext"
7269 [(set (match_operand:DI 0 "register_operand" "=d")
7270 (zero_extend:DI (truncate:SI
7272 (mult:DI (zero_extend:DI
7273 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7275 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7277 (clobber (match_scratch:SI 3 "=1"))
7278 (clobber (reg:CC FLAGS_REG))]
7280 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7282 [(set_attr "type" "imul")
7283 (set_attr "length_immediate" "0")
7284 (set (attr "athlon_decode")
7285 (if_then_else (eq_attr "cpu" "athlon")
7286 (const_string "vector")
7287 (const_string "double")))
7288 (set_attr "mode" "SI")])
7290 (define_expand "smuldi3_highpart"
7291 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7294 (mult:TI (sign_extend:TI
7295 (match_operand:DI 1 "nonimmediate_operand" ""))
7297 (match_operand:DI 2 "register_operand" "")))
7299 (clobber (match_scratch:DI 3 ""))
7300 (clobber (reg:CC FLAGS_REG))])]
7304 (define_insn "*smuldi3_highpart_rex64"
7305 [(set (match_operand:DI 0 "register_operand" "=d")
7308 (mult:TI (sign_extend:TI
7309 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7311 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7313 (clobber (match_scratch:DI 3 "=1"))
7314 (clobber (reg:CC FLAGS_REG))]
7316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7318 [(set_attr "type" "imul")
7319 (set (attr "athlon_decode")
7320 (if_then_else (eq_attr "cpu" "athlon")
7321 (const_string "vector")
7322 (const_string "double")))
7323 (set_attr "mode" "DI")])
7325 (define_expand "smulsi3_highpart"
7326 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7329 (mult:DI (sign_extend:DI
7330 (match_operand:SI 1 "nonimmediate_operand" ""))
7332 (match_operand:SI 2 "register_operand" "")))
7334 (clobber (match_scratch:SI 3 ""))
7335 (clobber (reg:CC FLAGS_REG))])]
7339 (define_insn "*smulsi3_highpart_insn"
7340 [(set (match_operand:SI 0 "register_operand" "=d")
7343 (mult:DI (sign_extend:DI
7344 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7346 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7348 (clobber (match_scratch:SI 3 "=1"))
7349 (clobber (reg:CC FLAGS_REG))]
7350 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7352 [(set_attr "type" "imul")
7353 (set (attr "athlon_decode")
7354 (if_then_else (eq_attr "cpu" "athlon")
7355 (const_string "vector")
7356 (const_string "double")))
7357 (set_attr "mode" "SI")])
7359 (define_insn "*smulsi3_highpart_zext"
7360 [(set (match_operand:DI 0 "register_operand" "=d")
7361 (zero_extend:DI (truncate:SI
7363 (mult:DI (sign_extend:DI
7364 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7366 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7368 (clobber (match_scratch:SI 3 "=1"))
7369 (clobber (reg:CC FLAGS_REG))]
7371 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7373 [(set_attr "type" "imul")
7374 (set (attr "athlon_decode")
7375 (if_then_else (eq_attr "cpu" "athlon")
7376 (const_string "vector")
7377 (const_string "double")))
7378 (set_attr "mode" "SI")])
7380 ;; The patterns that match these are at the end of this file.
7382 (define_expand "mulxf3"
7383 [(set (match_operand:XF 0 "register_operand" "")
7384 (mult:XF (match_operand:XF 1 "register_operand" "")
7385 (match_operand:XF 2 "register_operand" "")))]
7389 (define_expand "muldf3"
7390 [(set (match_operand:DF 0 "register_operand" "")
7391 (mult:DF (match_operand:DF 1 "register_operand" "")
7392 (match_operand:DF 2 "nonimmediate_operand" "")))]
7393 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7396 (define_expand "mulsf3"
7397 [(set (match_operand:SF 0 "register_operand" "")
7398 (mult:SF (match_operand:SF 1 "register_operand" "")
7399 (match_operand:SF 2 "nonimmediate_operand" "")))]
7400 "TARGET_80387 || TARGET_SSE_MATH"
7403 ;; Divide instructions
7405 (define_insn "divqi3"
7406 [(set (match_operand:QI 0 "register_operand" "=a")
7407 (div:QI (match_operand:HI 1 "register_operand" "0")
7408 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7409 (clobber (reg:CC FLAGS_REG))]
7410 "TARGET_QIMODE_MATH"
7412 [(set_attr "type" "idiv")
7413 (set_attr "mode" "QI")])
7415 (define_insn "udivqi3"
7416 [(set (match_operand:QI 0 "register_operand" "=a")
7417 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7418 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7419 (clobber (reg:CC FLAGS_REG))]
7420 "TARGET_QIMODE_MATH"
7422 [(set_attr "type" "idiv")
7423 (set_attr "mode" "QI")])
7425 ;; The patterns that match these are at the end of this file.
7427 (define_expand "divxf3"
7428 [(set (match_operand:XF 0 "register_operand" "")
7429 (div:XF (match_operand:XF 1 "register_operand" "")
7430 (match_operand:XF 2 "register_operand" "")))]
7434 (define_expand "divdf3"
7435 [(set (match_operand:DF 0 "register_operand" "")
7436 (div:DF (match_operand:DF 1 "register_operand" "")
7437 (match_operand:DF 2 "nonimmediate_operand" "")))]
7438 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7441 (define_expand "divsf3"
7442 [(set (match_operand:SF 0 "register_operand" "")
7443 (div:SF (match_operand:SF 1 "register_operand" "")
7444 (match_operand:SF 2 "nonimmediate_operand" "")))]
7445 "TARGET_80387 || TARGET_SSE_MATH"
7448 ;; Remainder instructions.
7450 (define_expand "divmoddi4"
7451 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7452 (div:DI (match_operand:DI 1 "register_operand" "")
7453 (match_operand:DI 2 "nonimmediate_operand" "")))
7454 (set (match_operand:DI 3 "register_operand" "")
7455 (mod:DI (match_dup 1) (match_dup 2)))
7456 (clobber (reg:CC FLAGS_REG))])]
7460 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7461 ;; Penalize eax case slightly because it results in worse scheduling
7463 (define_insn "*divmoddi4_nocltd_rex64"
7464 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7465 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7466 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7467 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7468 (mod:DI (match_dup 2) (match_dup 3)))
7469 (clobber (reg:CC FLAGS_REG))]
7470 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7472 [(set_attr "type" "multi")])
7474 (define_insn "*divmoddi4_cltd_rex64"
7475 [(set (match_operand:DI 0 "register_operand" "=a")
7476 (div:DI (match_operand:DI 2 "register_operand" "a")
7477 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7478 (set (match_operand:DI 1 "register_operand" "=&d")
7479 (mod:DI (match_dup 2) (match_dup 3)))
7480 (clobber (reg:CC FLAGS_REG))]
7481 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7483 [(set_attr "type" "multi")])
7485 (define_insn "*divmoddi_noext_rex64"
7486 [(set (match_operand:DI 0 "register_operand" "=a")
7487 (div:DI (match_operand:DI 1 "register_operand" "0")
7488 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7489 (set (match_operand:DI 3 "register_operand" "=d")
7490 (mod:DI (match_dup 1) (match_dup 2)))
7491 (use (match_operand:DI 4 "register_operand" "3"))
7492 (clobber (reg:CC FLAGS_REG))]
7495 [(set_attr "type" "idiv")
7496 (set_attr "mode" "DI")])
7499 [(set (match_operand:DI 0 "register_operand" "")
7500 (div:DI (match_operand:DI 1 "register_operand" "")
7501 (match_operand:DI 2 "nonimmediate_operand" "")))
7502 (set (match_operand:DI 3 "register_operand" "")
7503 (mod:DI (match_dup 1) (match_dup 2)))
7504 (clobber (reg:CC FLAGS_REG))]
7505 "TARGET_64BIT && reload_completed"
7506 [(parallel [(set (match_dup 3)
7507 (ashiftrt:DI (match_dup 4) (const_int 63)))
7508 (clobber (reg:CC FLAGS_REG))])
7509 (parallel [(set (match_dup 0)
7510 (div:DI (reg:DI 0) (match_dup 2)))
7512 (mod:DI (reg:DI 0) (match_dup 2)))
7514 (clobber (reg:CC FLAGS_REG))])]
7516 /* Avoid use of cltd in favor of a mov+shift. */
7517 if (!TARGET_USE_CLTD && !optimize_size)
7519 if (true_regnum (operands[1]))
7520 emit_move_insn (operands[0], operands[1]);
7522 emit_move_insn (operands[3], operands[1]);
7523 operands[4] = operands[3];
7527 gcc_assert (!true_regnum (operands[1]));
7528 operands[4] = operands[1];
7533 (define_expand "divmodsi4"
7534 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7535 (div:SI (match_operand:SI 1 "register_operand" "")
7536 (match_operand:SI 2 "nonimmediate_operand" "")))
7537 (set (match_operand:SI 3 "register_operand" "")
7538 (mod:SI (match_dup 1) (match_dup 2)))
7539 (clobber (reg:CC FLAGS_REG))])]
7543 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7544 ;; Penalize eax case slightly because it results in worse scheduling
7546 (define_insn "*divmodsi4_nocltd"
7547 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7548 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7549 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7550 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7551 (mod:SI (match_dup 2) (match_dup 3)))
7552 (clobber (reg:CC FLAGS_REG))]
7553 "!optimize_size && !TARGET_USE_CLTD"
7555 [(set_attr "type" "multi")])
7557 (define_insn "*divmodsi4_cltd"
7558 [(set (match_operand:SI 0 "register_operand" "=a")
7559 (div:SI (match_operand:SI 2 "register_operand" "a")
7560 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7561 (set (match_operand:SI 1 "register_operand" "=&d")
7562 (mod:SI (match_dup 2) (match_dup 3)))
7563 (clobber (reg:CC FLAGS_REG))]
7564 "optimize_size || TARGET_USE_CLTD"
7566 [(set_attr "type" "multi")])
7568 (define_insn "*divmodsi_noext"
7569 [(set (match_operand:SI 0 "register_operand" "=a")
7570 (div:SI (match_operand:SI 1 "register_operand" "0")
7571 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7572 (set (match_operand:SI 3 "register_operand" "=d")
7573 (mod:SI (match_dup 1) (match_dup 2)))
7574 (use (match_operand:SI 4 "register_operand" "3"))
7575 (clobber (reg:CC FLAGS_REG))]
7578 [(set_attr "type" "idiv")
7579 (set_attr "mode" "SI")])
7582 [(set (match_operand:SI 0 "register_operand" "")
7583 (div:SI (match_operand:SI 1 "register_operand" "")
7584 (match_operand:SI 2 "nonimmediate_operand" "")))
7585 (set (match_operand:SI 3 "register_operand" "")
7586 (mod:SI (match_dup 1) (match_dup 2)))
7587 (clobber (reg:CC FLAGS_REG))]
7589 [(parallel [(set (match_dup 3)
7590 (ashiftrt:SI (match_dup 4) (const_int 31)))
7591 (clobber (reg:CC FLAGS_REG))])
7592 (parallel [(set (match_dup 0)
7593 (div:SI (reg:SI 0) (match_dup 2)))
7595 (mod:SI (reg:SI 0) (match_dup 2)))
7597 (clobber (reg:CC FLAGS_REG))])]
7599 /* Avoid use of cltd in favor of a mov+shift. */
7600 if (!TARGET_USE_CLTD && !optimize_size)
7602 if (true_regnum (operands[1]))
7603 emit_move_insn (operands[0], operands[1]);
7605 emit_move_insn (operands[3], operands[1]);
7606 operands[4] = operands[3];
7610 gcc_assert (!true_regnum (operands[1]));
7611 operands[4] = operands[1];
7615 (define_insn "divmodhi4"
7616 [(set (match_operand:HI 0 "register_operand" "=a")
7617 (div:HI (match_operand:HI 1 "register_operand" "0")
7618 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7619 (set (match_operand:HI 3 "register_operand" "=&d")
7620 (mod:HI (match_dup 1) (match_dup 2)))
7621 (clobber (reg:CC FLAGS_REG))]
7622 "TARGET_HIMODE_MATH"
7624 [(set_attr "type" "multi")
7625 (set_attr "length_immediate" "0")
7626 (set_attr "mode" "SI")])
7628 (define_insn "udivmoddi4"
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)))
7634 (clobber (reg:CC FLAGS_REG))]
7636 "xor{q}\t%3, %3\;div{q}\t%2"
7637 [(set_attr "type" "multi")
7638 (set_attr "length_immediate" "0")
7639 (set_attr "mode" "DI")])
7641 (define_insn "*udivmoddi4_noext"
7642 [(set (match_operand:DI 0 "register_operand" "=a")
7643 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7644 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7645 (set (match_operand:DI 3 "register_operand" "=d")
7646 (umod:DI (match_dup 1) (match_dup 2)))
7648 (clobber (reg:CC FLAGS_REG))]
7651 [(set_attr "type" "idiv")
7652 (set_attr "mode" "DI")])
7655 [(set (match_operand:DI 0 "register_operand" "")
7656 (udiv:DI (match_operand:DI 1 "register_operand" "")
7657 (match_operand:DI 2 "nonimmediate_operand" "")))
7658 (set (match_operand:DI 3 "register_operand" "")
7659 (umod:DI (match_dup 1) (match_dup 2)))
7660 (clobber (reg:CC FLAGS_REG))]
7661 "TARGET_64BIT && reload_completed"
7662 [(set (match_dup 3) (const_int 0))
7663 (parallel [(set (match_dup 0)
7664 (udiv:DI (match_dup 1) (match_dup 2)))
7666 (umod:DI (match_dup 1) (match_dup 2)))
7668 (clobber (reg:CC FLAGS_REG))])]
7671 (define_insn "udivmodsi4"
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)))
7677 (clobber (reg:CC FLAGS_REG))]
7679 "xor{l}\t%3, %3\;div{l}\t%2"
7680 [(set_attr "type" "multi")
7681 (set_attr "length_immediate" "0")
7682 (set_attr "mode" "SI")])
7684 (define_insn "*udivmodsi4_noext"
7685 [(set (match_operand:SI 0 "register_operand" "=a")
7686 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7687 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7688 (set (match_operand:SI 3 "register_operand" "=d")
7689 (umod:SI (match_dup 1) (match_dup 2)))
7691 (clobber (reg:CC FLAGS_REG))]
7694 [(set_attr "type" "idiv")
7695 (set_attr "mode" "SI")])
7698 [(set (match_operand:SI 0 "register_operand" "")
7699 (udiv:SI (match_operand:SI 1 "register_operand" "")
7700 (match_operand:SI 2 "nonimmediate_operand" "")))
7701 (set (match_operand:SI 3 "register_operand" "")
7702 (umod:SI (match_dup 1) (match_dup 2)))
7703 (clobber (reg:CC FLAGS_REG))]
7705 [(set (match_dup 3) (const_int 0))
7706 (parallel [(set (match_dup 0)
7707 (udiv:SI (match_dup 1) (match_dup 2)))
7709 (umod:SI (match_dup 1) (match_dup 2)))
7711 (clobber (reg:CC FLAGS_REG))])]
7714 (define_expand "udivmodhi4"
7715 [(set (match_dup 4) (const_int 0))
7716 (parallel [(set (match_operand:HI 0 "register_operand" "")
7717 (udiv:HI (match_operand:HI 1 "register_operand" "")
7718 (match_operand:HI 2 "nonimmediate_operand" "")))
7719 (set (match_operand:HI 3 "register_operand" "")
7720 (umod:HI (match_dup 1) (match_dup 2)))
7722 (clobber (reg:CC FLAGS_REG))])]
7723 "TARGET_HIMODE_MATH"
7724 "operands[4] = gen_reg_rtx (HImode);")
7726 (define_insn "*udivmodhi_noext"
7727 [(set (match_operand:HI 0 "register_operand" "=a")
7728 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7729 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7730 (set (match_operand:HI 3 "register_operand" "=d")
7731 (umod:HI (match_dup 1) (match_dup 2)))
7732 (use (match_operand:HI 4 "register_operand" "3"))
7733 (clobber (reg:CC FLAGS_REG))]
7736 [(set_attr "type" "idiv")
7737 (set_attr "mode" "HI")])
7739 ;; We cannot use div/idiv for double division, because it causes
7740 ;; "division by zero" on the overflow and that's not what we expect
7741 ;; from truncate. Because true (non truncating) double division is
7742 ;; never generated, we can't create this insn anyway.
7745 ; [(set (match_operand:SI 0 "register_operand" "=a")
7747 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7749 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7750 ; (set (match_operand:SI 3 "register_operand" "=d")
7752 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7753 ; (clobber (reg:CC FLAGS_REG))]
7755 ; "div{l}\t{%2, %0|%0, %2}"
7756 ; [(set_attr "type" "idiv")])
7758 ;;- Logical AND instructions
7760 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7761 ;; Note that this excludes ah.
7763 (define_insn "*testdi_1_rex64"
7764 [(set (reg FLAGS_REG)
7766 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7767 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7769 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7770 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7772 test{l}\t{%k1, %k0|%k0, %k1}
7773 test{l}\t{%k1, %k0|%k0, %k1}
7774 test{q}\t{%1, %0|%0, %1}
7775 test{q}\t{%1, %0|%0, %1}
7776 test{q}\t{%1, %0|%0, %1}"
7777 [(set_attr "type" "test")
7778 (set_attr "modrm" "0,1,0,1,1")
7779 (set_attr "mode" "SI,SI,DI,DI,DI")
7780 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7782 (define_insn "testsi_1"
7783 [(set (reg FLAGS_REG)
7785 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7786 (match_operand:SI 1 "general_operand" "in,in,rin"))
7788 "ix86_match_ccmode (insn, CCNOmode)
7789 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7790 "test{l}\t{%1, %0|%0, %1}"
7791 [(set_attr "type" "test")
7792 (set_attr "modrm" "0,1,1")
7793 (set_attr "mode" "SI")
7794 (set_attr "pent_pair" "uv,np,uv")])
7796 (define_expand "testsi_ccno_1"
7797 [(set (reg:CCNO FLAGS_REG)
7799 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7800 (match_operand:SI 1 "nonmemory_operand" ""))
7805 (define_insn "*testhi_1"
7806 [(set (reg FLAGS_REG)
7807 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7808 (match_operand:HI 1 "general_operand" "n,n,rn"))
7810 "ix86_match_ccmode (insn, CCNOmode)
7811 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7812 "test{w}\t{%1, %0|%0, %1}"
7813 [(set_attr "type" "test")
7814 (set_attr "modrm" "0,1,1")
7815 (set_attr "mode" "HI")
7816 (set_attr "pent_pair" "uv,np,uv")])
7818 (define_expand "testqi_ccz_1"
7819 [(set (reg:CCZ FLAGS_REG)
7820 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7821 (match_operand:QI 1 "nonmemory_operand" ""))
7826 (define_insn "*testqi_1_maybe_si"
7827 [(set (reg FLAGS_REG)
7830 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7831 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7833 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7834 && ix86_match_ccmode (insn,
7835 GET_CODE (operands[1]) == CONST_INT
7836 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7838 if (which_alternative == 3)
7840 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7841 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7842 return "test{l}\t{%1, %k0|%k0, %1}";
7844 return "test{b}\t{%1, %0|%0, %1}";
7846 [(set_attr "type" "test")
7847 (set_attr "modrm" "0,1,1,1")
7848 (set_attr "mode" "QI,QI,QI,SI")
7849 (set_attr "pent_pair" "uv,np,uv,np")])
7851 (define_insn "*testqi_1"
7852 [(set (reg FLAGS_REG)
7855 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7856 (match_operand:QI 1 "general_operand" "n,n,qn"))
7858 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7859 && ix86_match_ccmode (insn, CCNOmode)"
7860 "test{b}\t{%1, %0|%0, %1}"
7861 [(set_attr "type" "test")
7862 (set_attr "modrm" "0,1,1")
7863 (set_attr "mode" "QI")
7864 (set_attr "pent_pair" "uv,np,uv")])
7866 (define_expand "testqi_ext_ccno_0"
7867 [(set (reg:CCNO FLAGS_REG)
7871 (match_operand 0 "ext_register_operand" "")
7874 (match_operand 1 "const_int_operand" ""))
7879 (define_insn "*testqi_ext_0"
7880 [(set (reg FLAGS_REG)
7884 (match_operand 0 "ext_register_operand" "Q")
7887 (match_operand 1 "const_int_operand" "n"))
7889 "ix86_match_ccmode (insn, CCNOmode)"
7890 "test{b}\t{%1, %h0|%h0, %1}"
7891 [(set_attr "type" "test")
7892 (set_attr "mode" "QI")
7893 (set_attr "length_immediate" "1")
7894 (set_attr "pent_pair" "np")])
7896 (define_insn "*testqi_ext_1"
7897 [(set (reg FLAGS_REG)
7901 (match_operand 0 "ext_register_operand" "Q")
7905 (match_operand:QI 1 "general_operand" "Qm")))
7907 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7908 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7909 "test{b}\t{%1, %h0|%h0, %1}"
7910 [(set_attr "type" "test")
7911 (set_attr "mode" "QI")])
7913 (define_insn "*testqi_ext_1_rex64"
7914 [(set (reg FLAGS_REG)
7918 (match_operand 0 "ext_register_operand" "Q")
7922 (match_operand:QI 1 "register_operand" "Q")))
7924 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7925 "test{b}\t{%1, %h0|%h0, %1}"
7926 [(set_attr "type" "test")
7927 (set_attr "mode" "QI")])
7929 (define_insn "*testqi_ext_2"
7930 [(set (reg FLAGS_REG)
7934 (match_operand 0 "ext_register_operand" "Q")
7938 (match_operand 1 "ext_register_operand" "Q")
7942 "ix86_match_ccmode (insn, CCNOmode)"
7943 "test{b}\t{%h1, %h0|%h0, %h1}"
7944 [(set_attr "type" "test")
7945 (set_attr "mode" "QI")])
7947 ;; Combine likes to form bit extractions for some tests. Humor it.
7948 (define_insn "*testqi_ext_3"
7949 [(set (reg FLAGS_REG)
7950 (compare (zero_extract:SI
7951 (match_operand 0 "nonimmediate_operand" "rm")
7952 (match_operand:SI 1 "const_int_operand" "")
7953 (match_operand:SI 2 "const_int_operand" ""))
7955 "ix86_match_ccmode (insn, CCNOmode)
7956 && INTVAL (operands[1]) > 0
7957 && INTVAL (operands[2]) >= 0
7958 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7959 && (GET_MODE (operands[0]) == SImode
7960 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7961 || GET_MODE (operands[0]) == HImode
7962 || GET_MODE (operands[0]) == QImode)"
7965 (define_insn "*testqi_ext_3_rex64"
7966 [(set (reg FLAGS_REG)
7967 (compare (zero_extract:DI
7968 (match_operand 0 "nonimmediate_operand" "rm")
7969 (match_operand:DI 1 "const_int_operand" "")
7970 (match_operand:DI 2 "const_int_operand" ""))
7973 && ix86_match_ccmode (insn, CCNOmode)
7974 && INTVAL (operands[1]) > 0
7975 && INTVAL (operands[2]) >= 0
7976 /* Ensure that resulting mask is zero or sign extended operand. */
7977 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7978 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7979 && INTVAL (operands[1]) > 32))
7980 && (GET_MODE (operands[0]) == SImode
7981 || GET_MODE (operands[0]) == DImode
7982 || GET_MODE (operands[0]) == HImode
7983 || GET_MODE (operands[0]) == QImode)"
7987 [(set (match_operand 0 "flags_reg_operand" "")
7988 (match_operator 1 "compare_operator"
7990 (match_operand 2 "nonimmediate_operand" "")
7991 (match_operand 3 "const_int_operand" "")
7992 (match_operand 4 "const_int_operand" ""))
7994 "ix86_match_ccmode (insn, CCNOmode)"
7995 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7997 rtx val = operands[2];
7998 HOST_WIDE_INT len = INTVAL (operands[3]);
7999 HOST_WIDE_INT pos = INTVAL (operands[4]);
8001 enum machine_mode mode, submode;
8003 mode = GET_MODE (val);
8004 if (GET_CODE (val) == MEM)
8006 /* ??? Combine likes to put non-volatile mem extractions in QImode
8007 no matter the size of the test. So find a mode that works. */
8008 if (! MEM_VOLATILE_P (val))
8010 mode = smallest_mode_for_size (pos + len, MODE_INT);
8011 val = adjust_address (val, mode, 0);
8014 else if (GET_CODE (val) == SUBREG
8015 && (submode = GET_MODE (SUBREG_REG (val)),
8016 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8017 && pos + len <= GET_MODE_BITSIZE (submode))
8019 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8021 val = SUBREG_REG (val);
8023 else if (mode == HImode && pos + len <= 8)
8025 /* Small HImode tests can be converted to QImode. */
8027 val = gen_lowpart (QImode, val);
8030 if (len == HOST_BITS_PER_WIDE_INT)
8033 mask = ((HOST_WIDE_INT)1 << len) - 1;
8036 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8039 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8040 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8041 ;; this is relatively important trick.
8042 ;; Do the conversion only post-reload to avoid limiting of the register class
8045 [(set (match_operand 0 "flags_reg_operand" "")
8046 (match_operator 1 "compare_operator"
8047 [(and (match_operand 2 "register_operand" "")
8048 (match_operand 3 "const_int_operand" ""))
8051 && QI_REG_P (operands[2])
8052 && GET_MODE (operands[2]) != QImode
8053 && ((ix86_match_ccmode (insn, CCZmode)
8054 && !(INTVAL (operands[3]) & ~(255 << 8)))
8055 || (ix86_match_ccmode (insn, CCNOmode)
8056 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8059 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8062 "operands[2] = gen_lowpart (SImode, operands[2]);
8063 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8066 [(set (match_operand 0 "flags_reg_operand" "")
8067 (match_operator 1 "compare_operator"
8068 [(and (match_operand 2 "nonimmediate_operand" "")
8069 (match_operand 3 "const_int_operand" ""))
8072 && GET_MODE (operands[2]) != QImode
8073 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8074 && ((ix86_match_ccmode (insn, CCZmode)
8075 && !(INTVAL (operands[3]) & ~255))
8076 || (ix86_match_ccmode (insn, CCNOmode)
8077 && !(INTVAL (operands[3]) & ~127)))"
8079 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8081 "operands[2] = gen_lowpart (QImode, operands[2]);
8082 operands[3] = gen_lowpart (QImode, operands[3]);")
8085 ;; %%% This used to optimize known byte-wide and operations to memory,
8086 ;; and sometimes to QImode registers. If this is considered useful,
8087 ;; it should be done with splitters.
8089 (define_expand "anddi3"
8090 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8091 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8092 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8093 (clobber (reg:CC FLAGS_REG))]
8095 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8097 (define_insn "*anddi_1_rex64"
8098 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8099 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8100 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8101 (clobber (reg:CC FLAGS_REG))]
8102 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8104 switch (get_attr_type (insn))
8108 enum machine_mode mode;
8110 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8111 if (INTVAL (operands[2]) == 0xff)
8115 gcc_assert (INTVAL (operands[2]) == 0xffff);
8119 operands[1] = gen_lowpart (mode, operands[1]);
8121 return "movz{bq|x}\t{%1,%0|%0, %1}";
8123 return "movz{wq|x}\t{%1,%0|%0, %1}";
8127 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8128 if (get_attr_mode (insn) == MODE_SI)
8129 return "and{l}\t{%k2, %k0|%k0, %k2}";
8131 return "and{q}\t{%2, %0|%0, %2}";
8134 [(set_attr "type" "alu,alu,alu,imovx")
8135 (set_attr "length_immediate" "*,*,*,0")
8136 (set_attr "mode" "SI,DI,DI,DI")])
8138 (define_insn "*anddi_2"
8139 [(set (reg FLAGS_REG)
8140 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8141 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8143 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8144 (and:DI (match_dup 1) (match_dup 2)))]
8145 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8146 && ix86_binary_operator_ok (AND, DImode, operands)"
8148 and{l}\t{%k2, %k0|%k0, %k2}
8149 and{q}\t{%2, %0|%0, %2}
8150 and{q}\t{%2, %0|%0, %2}"
8151 [(set_attr "type" "alu")
8152 (set_attr "mode" "SI,DI,DI")])
8154 (define_expand "andsi3"
8155 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8156 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8157 (match_operand:SI 2 "general_operand" "")))
8158 (clobber (reg:CC FLAGS_REG))]
8160 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8162 (define_insn "*andsi_1"
8163 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8164 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8165 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "ix86_binary_operator_ok (AND, SImode, operands)"
8169 switch (get_attr_type (insn))
8173 enum machine_mode mode;
8175 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8176 if (INTVAL (operands[2]) == 0xff)
8180 gcc_assert (INTVAL (operands[2]) == 0xffff);
8184 operands[1] = gen_lowpart (mode, operands[1]);
8186 return "movz{bl|x}\t{%1,%0|%0, %1}";
8188 return "movz{wl|x}\t{%1,%0|%0, %1}";
8192 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8193 return "and{l}\t{%2, %0|%0, %2}";
8196 [(set_attr "type" "alu,alu,imovx")
8197 (set_attr "length_immediate" "*,*,0")
8198 (set_attr "mode" "SI")])
8201 [(set (match_operand 0 "register_operand" "")
8203 (const_int -65536)))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8206 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8207 "operands[1] = gen_lowpart (HImode, operands[0]);")
8210 [(set (match_operand 0 "ext_register_operand" "")
8213 (clobber (reg:CC FLAGS_REG))]
8214 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8215 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8216 "operands[1] = gen_lowpart (QImode, operands[0]);")
8219 [(set (match_operand 0 "ext_register_operand" "")
8221 (const_int -65281)))
8222 (clobber (reg:CC FLAGS_REG))]
8223 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8224 [(parallel [(set (zero_extract:SI (match_dup 0)
8228 (zero_extract:SI (match_dup 0)
8231 (zero_extract:SI (match_dup 0)
8234 (clobber (reg:CC FLAGS_REG))])]
8235 "operands[0] = gen_lowpart (SImode, operands[0]);")
8237 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8238 (define_insn "*andsi_1_zext"
8239 [(set (match_operand:DI 0 "register_operand" "=r")
8241 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8242 (match_operand:SI 2 "general_operand" "rim"))))
8243 (clobber (reg:CC FLAGS_REG))]
8244 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8245 "and{l}\t{%2, %k0|%k0, %2}"
8246 [(set_attr "type" "alu")
8247 (set_attr "mode" "SI")])
8249 (define_insn "*andsi_2"
8250 [(set (reg FLAGS_REG)
8251 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8252 (match_operand:SI 2 "general_operand" "rim,ri"))
8254 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8255 (and:SI (match_dup 1) (match_dup 2)))]
8256 "ix86_match_ccmode (insn, CCNOmode)
8257 && ix86_binary_operator_ok (AND, SImode, operands)"
8258 "and{l}\t{%2, %0|%0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "mode" "SI")])
8262 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8263 (define_insn "*andsi_2_zext"
8264 [(set (reg FLAGS_REG)
8265 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8266 (match_operand:SI 2 "general_operand" "rim"))
8268 (set (match_operand:DI 0 "register_operand" "=r")
8269 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8270 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8271 && ix86_binary_operator_ok (AND, SImode, operands)"
8272 "and{l}\t{%2, %k0|%k0, %2}"
8273 [(set_attr "type" "alu")
8274 (set_attr "mode" "SI")])
8276 (define_expand "andhi3"
8277 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8278 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8279 (match_operand:HI 2 "general_operand" "")))
8280 (clobber (reg:CC FLAGS_REG))]
8281 "TARGET_HIMODE_MATH"
8282 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8284 (define_insn "*andhi_1"
8285 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8286 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8287 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8288 (clobber (reg:CC FLAGS_REG))]
8289 "ix86_binary_operator_ok (AND, HImode, operands)"
8291 switch (get_attr_type (insn))
8294 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8295 gcc_assert (INTVAL (operands[2]) == 0xff);
8296 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8299 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8301 return "and{w}\t{%2, %0|%0, %2}";
8304 [(set_attr "type" "alu,alu,imovx")
8305 (set_attr "length_immediate" "*,*,0")
8306 (set_attr "mode" "HI,HI,SI")])
8308 (define_insn "*andhi_2"
8309 [(set (reg FLAGS_REG)
8310 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8311 (match_operand:HI 2 "general_operand" "rim,ri"))
8313 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8314 (and:HI (match_dup 1) (match_dup 2)))]
8315 "ix86_match_ccmode (insn, CCNOmode)
8316 && ix86_binary_operator_ok (AND, HImode, operands)"
8317 "and{w}\t{%2, %0|%0, %2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "HI")])
8321 (define_expand "andqi3"
8322 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8323 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8324 (match_operand:QI 2 "general_operand" "")))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "TARGET_QIMODE_MATH"
8327 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8329 ;; %%% Potential partial reg stall on alternative 2. What to do?
8330 (define_insn "*andqi_1"
8331 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8332 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8333 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8334 (clobber (reg:CC FLAGS_REG))]
8335 "ix86_binary_operator_ok (AND, QImode, operands)"
8337 and{b}\t{%2, %0|%0, %2}
8338 and{b}\t{%2, %0|%0, %2}
8339 and{l}\t{%k2, %k0|%k0, %k2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "mode" "QI,QI,SI")])
8343 (define_insn "*andqi_1_slp"
8344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8345 (and:QI (match_dup 0)
8346 (match_operand:QI 1 "general_operand" "qi,qmi")))
8347 (clobber (reg:CC FLAGS_REG))]
8348 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8349 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350 "and{b}\t{%1, %0|%0, %1}"
8351 [(set_attr "type" "alu1")
8352 (set_attr "mode" "QI")])
8354 (define_insn "*andqi_2_maybe_si"
8355 [(set (reg FLAGS_REG)
8357 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8360 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8361 (and:QI (match_dup 1) (match_dup 2)))]
8362 "ix86_binary_operator_ok (AND, QImode, operands)
8363 && ix86_match_ccmode (insn,
8364 GET_CODE (operands[2]) == CONST_INT
8365 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8367 if (which_alternative == 2)
8369 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8370 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8371 return "and{l}\t{%2, %k0|%k0, %2}";
8373 return "and{b}\t{%2, %0|%0, %2}";
8375 [(set_attr "type" "alu")
8376 (set_attr "mode" "QI,QI,SI")])
8378 (define_insn "*andqi_2"
8379 [(set (reg FLAGS_REG)
8381 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8382 (match_operand:QI 2 "general_operand" "qim,qi"))
8384 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8385 (and:QI (match_dup 1) (match_dup 2)))]
8386 "ix86_match_ccmode (insn, CCNOmode)
8387 && ix86_binary_operator_ok (AND, QImode, operands)"
8388 "and{b}\t{%2, %0|%0, %2}"
8389 [(set_attr "type" "alu")
8390 (set_attr "mode" "QI")])
8392 (define_insn "*andqi_2_slp"
8393 [(set (reg FLAGS_REG)
8395 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8396 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8398 (set (strict_low_part (match_dup 0))
8399 (and:QI (match_dup 0) (match_dup 1)))]
8400 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8401 && ix86_match_ccmode (insn, CCNOmode)
8402 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8403 "and{b}\t{%1, %0|%0, %1}"
8404 [(set_attr "type" "alu1")
8405 (set_attr "mode" "QI")])
8407 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8408 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8409 ;; for a QImode operand, which of course failed.
8411 (define_insn "andqi_ext_0"
8412 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8417 (match_operand 1 "ext_register_operand" "0")
8420 (match_operand 2 "const_int_operand" "n")))
8421 (clobber (reg:CC FLAGS_REG))]
8423 "and{b}\t{%2, %h0|%h0, %2}"
8424 [(set_attr "type" "alu")
8425 (set_attr "length_immediate" "1")
8426 (set_attr "mode" "QI")])
8428 ;; Generated by peephole translating test to and. This shows up
8429 ;; often in fp comparisons.
8431 (define_insn "*andqi_ext_0_cc"
8432 [(set (reg FLAGS_REG)
8436 (match_operand 1 "ext_register_operand" "0")
8439 (match_operand 2 "const_int_operand" "n"))
8441 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8450 "ix86_match_ccmode (insn, CCNOmode)"
8451 "and{b}\t{%2, %h0|%h0, %2}"
8452 [(set_attr "type" "alu")
8453 (set_attr "length_immediate" "1")
8454 (set_attr "mode" "QI")])
8456 (define_insn "*andqi_ext_1"
8457 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462 (match_operand 1 "ext_register_operand" "0")
8466 (match_operand:QI 2 "general_operand" "Qm"))))
8467 (clobber (reg:CC FLAGS_REG))]
8469 "and{b}\t{%2, %h0|%h0, %2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "length_immediate" "0")
8472 (set_attr "mode" "QI")])
8474 (define_insn "*andqi_ext_1_rex64"
8475 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8480 (match_operand 1 "ext_register_operand" "0")
8484 (match_operand 2 "ext_register_operand" "Q"))))
8485 (clobber (reg:CC FLAGS_REG))]
8487 "and{b}\t{%2, %h0|%h0, %2}"
8488 [(set_attr "type" "alu")
8489 (set_attr "length_immediate" "0")
8490 (set_attr "mode" "QI")])
8492 (define_insn "*andqi_ext_2"
8493 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8498 (match_operand 1 "ext_register_operand" "%0")
8502 (match_operand 2 "ext_register_operand" "Q")
8505 (clobber (reg:CC FLAGS_REG))]
8507 "and{b}\t{%h2, %h0|%h0, %h2}"
8508 [(set_attr "type" "alu")
8509 (set_attr "length_immediate" "0")
8510 (set_attr "mode" "QI")])
8512 ;; Convert wide AND instructions with immediate operand to shorter QImode
8513 ;; equivalents when possible.
8514 ;; Don't do the splitting with memory operands, since it introduces risk
8515 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8516 ;; for size, but that can (should?) be handled by generic code instead.
8518 [(set (match_operand 0 "register_operand" "")
8519 (and (match_operand 1 "register_operand" "")
8520 (match_operand 2 "const_int_operand" "")))
8521 (clobber (reg:CC FLAGS_REG))]
8523 && QI_REG_P (operands[0])
8524 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8525 && !(~INTVAL (operands[2]) & ~(255 << 8))
8526 && GET_MODE (operands[0]) != QImode"
8527 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8528 (and:SI (zero_extract:SI (match_dup 1)
8529 (const_int 8) (const_int 8))
8531 (clobber (reg:CC FLAGS_REG))])]
8532 "operands[0] = gen_lowpart (SImode, operands[0]);
8533 operands[1] = gen_lowpart (SImode, operands[1]);
8534 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8536 ;; Since AND can be encoded with sign extended immediate, this is only
8537 ;; profitable when 7th bit is not set.
8539 [(set (match_operand 0 "register_operand" "")
8540 (and (match_operand 1 "general_operand" "")
8541 (match_operand 2 "const_int_operand" "")))
8542 (clobber (reg:CC FLAGS_REG))]
8544 && ANY_QI_REG_P (operands[0])
8545 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8546 && !(~INTVAL (operands[2]) & ~255)
8547 && !(INTVAL (operands[2]) & 128)
8548 && GET_MODE (operands[0]) != QImode"
8549 [(parallel [(set (strict_low_part (match_dup 0))
8550 (and:QI (match_dup 1)
8552 (clobber (reg:CC FLAGS_REG))])]
8553 "operands[0] = gen_lowpart (QImode, operands[0]);
8554 operands[1] = gen_lowpart (QImode, operands[1]);
8555 operands[2] = gen_lowpart (QImode, operands[2]);")
8557 ;; Logical inclusive OR instructions
8559 ;; %%% This used to optimize known byte-wide and operations to memory.
8560 ;; If this is considered useful, it should be done with splitters.
8562 (define_expand "iordi3"
8563 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8564 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8565 (match_operand:DI 2 "x86_64_general_operand" "")))
8566 (clobber (reg:CC FLAGS_REG))]
8568 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8570 (define_insn "*iordi_1_rex64"
8571 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8572 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8573 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8574 (clobber (reg:CC FLAGS_REG))]
8576 && ix86_binary_operator_ok (IOR, DImode, operands)"
8577 "or{q}\t{%2, %0|%0, %2}"
8578 [(set_attr "type" "alu")
8579 (set_attr "mode" "DI")])
8581 (define_insn "*iordi_2_rex64"
8582 [(set (reg FLAGS_REG)
8583 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8584 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8586 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8587 (ior:DI (match_dup 1) (match_dup 2)))]
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")])
8595 (define_insn "*iordi_3_rex64"
8596 [(set (reg FLAGS_REG)
8597 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8598 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8600 (clobber (match_scratch:DI 0 "=r"))]
8602 && ix86_match_ccmode (insn, CCNOmode)
8603 && ix86_binary_operator_ok (IOR, DImode, operands)"
8604 "or{q}\t{%2, %0|%0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "mode" "DI")])
8609 (define_expand "iorsi3"
8610 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8611 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8612 (match_operand:SI 2 "general_operand" "")))
8613 (clobber (reg:CC FLAGS_REG))]
8615 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8617 (define_insn "*iorsi_1"
8618 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8619 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8620 (match_operand:SI 2 "general_operand" "ri,rmi")))
8621 (clobber (reg:CC FLAGS_REG))]
8622 "ix86_binary_operator_ok (IOR, SImode, operands)"
8623 "or{l}\t{%2, %0|%0, %2}"
8624 [(set_attr "type" "alu")
8625 (set_attr "mode" "SI")])
8627 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8628 (define_insn "*iorsi_1_zext"
8629 [(set (match_operand:DI 0 "register_operand" "=rm")
8631 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8632 (match_operand:SI 2 "general_operand" "rim"))))
8633 (clobber (reg:CC FLAGS_REG))]
8634 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8635 "or{l}\t{%2, %k0|%k0, %2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "mode" "SI")])
8639 (define_insn "*iorsi_1_zext_imm"
8640 [(set (match_operand:DI 0 "register_operand" "=rm")
8641 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8642 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8643 (clobber (reg:CC FLAGS_REG))]
8645 "or{l}\t{%2, %k0|%k0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "mode" "SI")])
8649 (define_insn "*iorsi_2"
8650 [(set (reg FLAGS_REG)
8651 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8652 (match_operand:SI 2 "general_operand" "rim,ri"))
8654 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8655 (ior:SI (match_dup 1) (match_dup 2)))]
8656 "ix86_match_ccmode (insn, CCNOmode)
8657 && ix86_binary_operator_ok (IOR, SImode, operands)"
8658 "or{l}\t{%2, %0|%0, %2}"
8659 [(set_attr "type" "alu")
8660 (set_attr "mode" "SI")])
8662 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8663 ;; ??? Special case for immediate operand is missing - it is tricky.
8664 (define_insn "*iorsi_2_zext"
8665 [(set (reg FLAGS_REG)
8666 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8667 (match_operand:SI 2 "general_operand" "rim"))
8669 (set (match_operand:DI 0 "register_operand" "=r")
8670 (zero_extend:DI (ior:SI (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_2_zext_imm"
8678 [(set (reg FLAGS_REG)
8679 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8682 (set (match_operand:DI 0 "register_operand" "=r")
8683 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8684 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8685 && ix86_binary_operator_ok (IOR, SImode, operands)"
8686 "or{l}\t{%2, %k0|%k0, %2}"
8687 [(set_attr "type" "alu")
8688 (set_attr "mode" "SI")])
8690 (define_insn "*iorsi_3"
8691 [(set (reg FLAGS_REG)
8692 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693 (match_operand:SI 2 "general_operand" "rim"))
8695 (clobber (match_scratch:SI 0 "=r"))]
8696 "ix86_match_ccmode (insn, CCNOmode)
8697 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8698 "or{l}\t{%2, %0|%0, %2}"
8699 [(set_attr "type" "alu")
8700 (set_attr "mode" "SI")])
8702 (define_expand "iorhi3"
8703 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8704 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8705 (match_operand:HI 2 "general_operand" "")))
8706 (clobber (reg:CC FLAGS_REG))]
8707 "TARGET_HIMODE_MATH"
8708 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8710 (define_insn "*iorhi_1"
8711 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8712 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8713 (match_operand:HI 2 "general_operand" "rmi,ri")))
8714 (clobber (reg:CC FLAGS_REG))]
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_2"
8721 [(set (reg FLAGS_REG)
8722 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8723 (match_operand:HI 2 "general_operand" "rim,ri"))
8725 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8726 (ior:HI (match_dup 1) (match_dup 2)))]
8727 "ix86_match_ccmode (insn, CCNOmode)
8728 && ix86_binary_operator_ok (IOR, HImode, operands)"
8729 "or{w}\t{%2, %0|%0, %2}"
8730 [(set_attr "type" "alu")
8731 (set_attr "mode" "HI")])
8733 (define_insn "*iorhi_3"
8734 [(set (reg FLAGS_REG)
8735 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8736 (match_operand:HI 2 "general_operand" "rim"))
8738 (clobber (match_scratch:HI 0 "=r"))]
8739 "ix86_match_ccmode (insn, CCNOmode)
8740 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8741 "or{w}\t{%2, %0|%0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "mode" "HI")])
8745 (define_expand "iorqi3"
8746 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8747 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8748 (match_operand:QI 2 "general_operand" "")))
8749 (clobber (reg:CC FLAGS_REG))]
8750 "TARGET_QIMODE_MATH"
8751 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8753 ;; %%% Potential partial reg stall on alternative 2. What to do?
8754 (define_insn "*iorqi_1"
8755 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8756 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8757 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8758 (clobber (reg:CC FLAGS_REG))]
8759 "ix86_binary_operator_ok (IOR, QImode, operands)"
8761 or{b}\t{%2, %0|%0, %2}
8762 or{b}\t{%2, %0|%0, %2}
8763 or{l}\t{%k2, %k0|%k0, %k2}"
8764 [(set_attr "type" "alu")
8765 (set_attr "mode" "QI,QI,SI")])
8767 (define_insn "*iorqi_1_slp"
8768 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8769 (ior:QI (match_dup 0)
8770 (match_operand:QI 1 "general_operand" "qmi,qi")))
8771 (clobber (reg:CC FLAGS_REG))]
8772 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8773 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8774 "or{b}\t{%1, %0|%0, %1}"
8775 [(set_attr "type" "alu1")
8776 (set_attr "mode" "QI")])
8778 (define_insn "*iorqi_2"
8779 [(set (reg FLAGS_REG)
8780 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8781 (match_operand:QI 2 "general_operand" "qim,qi"))
8783 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8784 (ior:QI (match_dup 1) (match_dup 2)))]
8785 "ix86_match_ccmode (insn, CCNOmode)
8786 && ix86_binary_operator_ok (IOR, QImode, operands)"
8787 "or{b}\t{%2, %0|%0, %2}"
8788 [(set_attr "type" "alu")
8789 (set_attr "mode" "QI")])
8791 (define_insn "*iorqi_2_slp"
8792 [(set (reg FLAGS_REG)
8793 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8794 (match_operand:QI 1 "general_operand" "qim,qi"))
8796 (set (strict_low_part (match_dup 0))
8797 (ior:QI (match_dup 0) (match_dup 1)))]
8798 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8799 && ix86_match_ccmode (insn, CCNOmode)
8800 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8801 "or{b}\t{%1, %0|%0, %1}"
8802 [(set_attr "type" "alu1")
8803 (set_attr "mode" "QI")])
8805 (define_insn "*iorqi_3"
8806 [(set (reg FLAGS_REG)
8807 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8808 (match_operand:QI 2 "general_operand" "qim"))
8810 (clobber (match_scratch:QI 0 "=q"))]
8811 "ix86_match_ccmode (insn, CCNOmode)
8812 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8813 "or{b}\t{%2, %0|%0, %2}"
8814 [(set_attr "type" "alu")
8815 (set_attr "mode" "QI")])
8817 (define_insn "iorqi_ext_0"
8818 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8823 (match_operand 1 "ext_register_operand" "0")
8826 (match_operand 2 "const_int_operand" "n")))
8827 (clobber (reg:CC FLAGS_REG))]
8828 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8829 "or{b}\t{%2, %h0|%h0, %2}"
8830 [(set_attr "type" "alu")
8831 (set_attr "length_immediate" "1")
8832 (set_attr "mode" "QI")])
8834 (define_insn "*iorqi_ext_1"
8835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8840 (match_operand 1 "ext_register_operand" "0")
8844 (match_operand:QI 2 "general_operand" "Qm"))))
8845 (clobber (reg:CC FLAGS_REG))]
8847 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8848 "or{b}\t{%2, %h0|%h0, %2}"
8849 [(set_attr "type" "alu")
8850 (set_attr "length_immediate" "0")
8851 (set_attr "mode" "QI")])
8853 (define_insn "*iorqi_ext_1_rex64"
8854 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8859 (match_operand 1 "ext_register_operand" "0")
8863 (match_operand 2 "ext_register_operand" "Q"))))
8864 (clobber (reg:CC FLAGS_REG))]
8866 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8867 "or{b}\t{%2, %h0|%h0, %2}"
8868 [(set_attr "type" "alu")
8869 (set_attr "length_immediate" "0")
8870 (set_attr "mode" "QI")])
8872 (define_insn "*iorqi_ext_2"
8873 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8877 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8880 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8883 (clobber (reg:CC FLAGS_REG))]
8884 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8885 "ior{b}\t{%h2, %h0|%h0, %h2}"
8886 [(set_attr "type" "alu")
8887 (set_attr "length_immediate" "0")
8888 (set_attr "mode" "QI")])
8891 [(set (match_operand 0 "register_operand" "")
8892 (ior (match_operand 1 "register_operand" "")
8893 (match_operand 2 "const_int_operand" "")))
8894 (clobber (reg:CC FLAGS_REG))]
8896 && QI_REG_P (operands[0])
8897 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8898 && !(INTVAL (operands[2]) & ~(255 << 8))
8899 && GET_MODE (operands[0]) != QImode"
8900 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8901 (ior:SI (zero_extract:SI (match_dup 1)
8902 (const_int 8) (const_int 8))
8904 (clobber (reg:CC FLAGS_REG))])]
8905 "operands[0] = gen_lowpart (SImode, operands[0]);
8906 operands[1] = gen_lowpart (SImode, operands[1]);
8907 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8909 ;; Since OR can be encoded with sign extended immediate, this is only
8910 ;; profitable when 7th bit is set.
8912 [(set (match_operand 0 "register_operand" "")
8913 (ior (match_operand 1 "general_operand" "")
8914 (match_operand 2 "const_int_operand" "")))
8915 (clobber (reg:CC FLAGS_REG))]
8917 && ANY_QI_REG_P (operands[0])
8918 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8919 && !(INTVAL (operands[2]) & ~255)
8920 && (INTVAL (operands[2]) & 128)
8921 && GET_MODE (operands[0]) != QImode"
8922 [(parallel [(set (strict_low_part (match_dup 0))
8923 (ior:QI (match_dup 1)
8925 (clobber (reg:CC FLAGS_REG))])]
8926 "operands[0] = gen_lowpart (QImode, operands[0]);
8927 operands[1] = gen_lowpart (QImode, operands[1]);
8928 operands[2] = gen_lowpart (QImode, operands[2]);")
8930 ;; Logical XOR instructions
8932 ;; %%% This used to optimize known byte-wide and operations to memory.
8933 ;; If this is considered useful, it should be done with splitters.
8935 (define_expand "xordi3"
8936 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8937 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8938 (match_operand:DI 2 "x86_64_general_operand" "")))
8939 (clobber (reg:CC FLAGS_REG))]
8941 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8943 (define_insn "*xordi_1_rex64"
8944 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8945 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8946 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8947 (clobber (reg:CC FLAGS_REG))]
8949 && ix86_binary_operator_ok (XOR, DImode, operands)"
8951 xor{q}\t{%2, %0|%0, %2}
8952 xor{q}\t{%2, %0|%0, %2}"
8953 [(set_attr "type" "alu")
8954 (set_attr "mode" "DI,DI")])
8956 (define_insn "*xordi_2_rex64"
8957 [(set (reg FLAGS_REG)
8958 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8959 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8961 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8962 (xor:DI (match_dup 1) (match_dup 2)))]
8964 && ix86_match_ccmode (insn, CCNOmode)
8965 && ix86_binary_operator_ok (XOR, DImode, operands)"
8967 xor{q}\t{%2, %0|%0, %2}
8968 xor{q}\t{%2, %0|%0, %2}"
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "DI,DI")])
8972 (define_insn "*xordi_3_rex64"
8973 [(set (reg FLAGS_REG)
8974 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8975 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8977 (clobber (match_scratch:DI 0 "=r"))]
8979 && ix86_match_ccmode (insn, CCNOmode)
8980 && ix86_binary_operator_ok (XOR, DImode, operands)"
8981 "xor{q}\t{%2, %0|%0, %2}"
8982 [(set_attr "type" "alu")
8983 (set_attr "mode" "DI")])
8985 (define_expand "xorsi3"
8986 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8987 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8988 (match_operand:SI 2 "general_operand" "")))
8989 (clobber (reg:CC FLAGS_REG))]
8991 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8993 (define_insn "*xorsi_1"
8994 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8995 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8996 (match_operand:SI 2 "general_operand" "ri,rm")))
8997 (clobber (reg:CC FLAGS_REG))]
8998 "ix86_binary_operator_ok (XOR, SImode, operands)"
8999 "xor{l}\t{%2, %0|%0, %2}"
9000 [(set_attr "type" "alu")
9001 (set_attr "mode" "SI")])
9003 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9004 ;; Add speccase for immediates
9005 (define_insn "*xorsi_1_zext"
9006 [(set (match_operand:DI 0 "register_operand" "=r")
9008 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9009 (match_operand:SI 2 "general_operand" "rim"))))
9010 (clobber (reg:CC FLAGS_REG))]
9011 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9012 "xor{l}\t{%2, %k0|%k0, %2}"
9013 [(set_attr "type" "alu")
9014 (set_attr "mode" "SI")])
9016 (define_insn "*xorsi_1_zext_imm"
9017 [(set (match_operand:DI 0 "register_operand" "=r")
9018 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9019 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9020 (clobber (reg:CC FLAGS_REG))]
9021 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9022 "xor{l}\t{%2, %k0|%k0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "SI")])
9026 (define_insn "*xorsi_2"
9027 [(set (reg FLAGS_REG)
9028 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9029 (match_operand:SI 2 "general_operand" "rim,ri"))
9031 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9032 (xor:SI (match_dup 1) (match_dup 2)))]
9033 "ix86_match_ccmode (insn, CCNOmode)
9034 && ix86_binary_operator_ok (XOR, SImode, operands)"
9035 "xor{l}\t{%2, %0|%0, %2}"
9036 [(set_attr "type" "alu")
9037 (set_attr "mode" "SI")])
9039 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9040 ;; ??? Special case for immediate operand is missing - it is tricky.
9041 (define_insn "*xorsi_2_zext"
9042 [(set (reg FLAGS_REG)
9043 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9044 (match_operand:SI 2 "general_operand" "rim"))
9046 (set (match_operand:DI 0 "register_operand" "=r")
9047 (zero_extend:DI (xor:SI (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_2_zext_imm"
9055 [(set (reg FLAGS_REG)
9056 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9059 (set (match_operand:DI 0 "register_operand" "=r")
9060 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9061 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9062 && ix86_binary_operator_ok (XOR, SImode, operands)"
9063 "xor{l}\t{%2, %k0|%k0, %2}"
9064 [(set_attr "type" "alu")
9065 (set_attr "mode" "SI")])
9067 (define_insn "*xorsi_3"
9068 [(set (reg FLAGS_REG)
9069 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9070 (match_operand:SI 2 "general_operand" "rim"))
9072 (clobber (match_scratch:SI 0 "=r"))]
9073 "ix86_match_ccmode (insn, CCNOmode)
9074 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9075 "xor{l}\t{%2, %0|%0, %2}"
9076 [(set_attr "type" "alu")
9077 (set_attr "mode" "SI")])
9079 (define_expand "xorhi3"
9080 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9081 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9082 (match_operand:HI 2 "general_operand" "")))
9083 (clobber (reg:CC FLAGS_REG))]
9084 "TARGET_HIMODE_MATH"
9085 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9087 (define_insn "*xorhi_1"
9088 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9089 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9090 (match_operand:HI 2 "general_operand" "rmi,ri")))
9091 (clobber (reg:CC FLAGS_REG))]
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_2"
9098 [(set (reg FLAGS_REG)
9099 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9100 (match_operand:HI 2 "general_operand" "rim,ri"))
9102 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9103 (xor:HI (match_dup 1) (match_dup 2)))]
9104 "ix86_match_ccmode (insn, CCNOmode)
9105 && ix86_binary_operator_ok (XOR, HImode, operands)"
9106 "xor{w}\t{%2, %0|%0, %2}"
9107 [(set_attr "type" "alu")
9108 (set_attr "mode" "HI")])
9110 (define_insn "*xorhi_3"
9111 [(set (reg FLAGS_REG)
9112 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9113 (match_operand:HI 2 "general_operand" "rim"))
9115 (clobber (match_scratch:HI 0 "=r"))]
9116 "ix86_match_ccmode (insn, CCNOmode)
9117 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9118 "xor{w}\t{%2, %0|%0, %2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "HI")])
9122 (define_expand "xorqi3"
9123 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9124 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9125 (match_operand:QI 2 "general_operand" "")))
9126 (clobber (reg:CC FLAGS_REG))]
9127 "TARGET_QIMODE_MATH"
9128 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9130 ;; %%% Potential partial reg stall on alternative 2. What to do?
9131 (define_insn "*xorqi_1"
9132 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9133 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9134 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9135 (clobber (reg:CC FLAGS_REG))]
9136 "ix86_binary_operator_ok (XOR, QImode, operands)"
9138 xor{b}\t{%2, %0|%0, %2}
9139 xor{b}\t{%2, %0|%0, %2}
9140 xor{l}\t{%k2, %k0|%k0, %k2}"
9141 [(set_attr "type" "alu")
9142 (set_attr "mode" "QI,QI,SI")])
9144 (define_insn "*xorqi_1_slp"
9145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9146 (xor:QI (match_dup 0)
9147 (match_operand:QI 1 "general_operand" "qi,qmi")))
9148 (clobber (reg:CC FLAGS_REG))]
9149 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9150 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9151 "xor{b}\t{%1, %0|%0, %1}"
9152 [(set_attr "type" "alu1")
9153 (set_attr "mode" "QI")])
9155 (define_insn "xorqi_ext_0"
9156 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9161 (match_operand 1 "ext_register_operand" "0")
9164 (match_operand 2 "const_int_operand" "n")))
9165 (clobber (reg:CC FLAGS_REG))]
9166 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167 "xor{b}\t{%2, %h0|%h0, %2}"
9168 [(set_attr "type" "alu")
9169 (set_attr "length_immediate" "1")
9170 (set_attr "mode" "QI")])
9172 (define_insn "*xorqi_ext_1"
9173 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9178 (match_operand 1 "ext_register_operand" "0")
9182 (match_operand:QI 2 "general_operand" "Qm"))))
9183 (clobber (reg:CC FLAGS_REG))]
9185 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186 "xor{b}\t{%2, %h0|%h0, %2}"
9187 [(set_attr "type" "alu")
9188 (set_attr "length_immediate" "0")
9189 (set_attr "mode" "QI")])
9191 (define_insn "*xorqi_ext_1_rex64"
9192 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9197 (match_operand 1 "ext_register_operand" "0")
9201 (match_operand 2 "ext_register_operand" "Q"))))
9202 (clobber (reg:CC FLAGS_REG))]
9204 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9205 "xor{b}\t{%2, %h0|%h0, %2}"
9206 [(set_attr "type" "alu")
9207 (set_attr "length_immediate" "0")
9208 (set_attr "mode" "QI")])
9210 (define_insn "*xorqi_ext_2"
9211 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9215 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9218 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9221 (clobber (reg:CC FLAGS_REG))]
9222 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9223 "xor{b}\t{%h2, %h0|%h0, %h2}"
9224 [(set_attr "type" "alu")
9225 (set_attr "length_immediate" "0")
9226 (set_attr "mode" "QI")])
9228 (define_insn "*xorqi_cc_1"
9229 [(set (reg FLAGS_REG)
9231 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9232 (match_operand:QI 2 "general_operand" "qim,qi"))
9234 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9235 (xor:QI (match_dup 1) (match_dup 2)))]
9236 "ix86_match_ccmode (insn, CCNOmode)
9237 && ix86_binary_operator_ok (XOR, QImode, operands)"
9238 "xor{b}\t{%2, %0|%0, %2}"
9239 [(set_attr "type" "alu")
9240 (set_attr "mode" "QI")])
9242 (define_insn "*xorqi_2_slp"
9243 [(set (reg FLAGS_REG)
9244 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9245 (match_operand:QI 1 "general_operand" "qim,qi"))
9247 (set (strict_low_part (match_dup 0))
9248 (xor:QI (match_dup 0) (match_dup 1)))]
9249 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9250 && ix86_match_ccmode (insn, CCNOmode)
9251 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9252 "xor{b}\t{%1, %0|%0, %1}"
9253 [(set_attr "type" "alu1")
9254 (set_attr "mode" "QI")])
9256 (define_insn "*xorqi_cc_2"
9257 [(set (reg FLAGS_REG)
9259 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9260 (match_operand:QI 2 "general_operand" "qim"))
9262 (clobber (match_scratch:QI 0 "=q"))]
9263 "ix86_match_ccmode (insn, CCNOmode)
9264 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9265 "xor{b}\t{%2, %0|%0, %2}"
9266 [(set_attr "type" "alu")
9267 (set_attr "mode" "QI")])
9269 (define_insn "*xorqi_cc_ext_1"
9270 [(set (reg FLAGS_REG)
9274 (match_operand 1 "ext_register_operand" "0")
9277 (match_operand:QI 2 "general_operand" "qmn"))
9279 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9283 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9285 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9286 "xor{b}\t{%2, %h0|%h0, %2}"
9287 [(set_attr "type" "alu")
9288 (set_attr "mode" "QI")])
9290 (define_insn "*xorqi_cc_ext_1_rex64"
9291 [(set (reg FLAGS_REG)
9295 (match_operand 1 "ext_register_operand" "0")
9298 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9300 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9304 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9306 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9307 "xor{b}\t{%2, %h0|%h0, %2}"
9308 [(set_attr "type" "alu")
9309 (set_attr "mode" "QI")])
9311 (define_expand "xorqi_cc_ext_1"
9313 (set (reg:CCNO FLAGS_REG)
9317 (match_operand 1 "ext_register_operand" "")
9320 (match_operand:QI 2 "general_operand" ""))
9322 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9326 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9332 [(set (match_operand 0 "register_operand" "")
9333 (xor (match_operand 1 "register_operand" "")
9334 (match_operand 2 "const_int_operand" "")))
9335 (clobber (reg:CC FLAGS_REG))]
9337 && QI_REG_P (operands[0])
9338 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9339 && !(INTVAL (operands[2]) & ~(255 << 8))
9340 && GET_MODE (operands[0]) != QImode"
9341 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9342 (xor:SI (zero_extract:SI (match_dup 1)
9343 (const_int 8) (const_int 8))
9345 (clobber (reg:CC FLAGS_REG))])]
9346 "operands[0] = gen_lowpart (SImode, operands[0]);
9347 operands[1] = gen_lowpart (SImode, operands[1]);
9348 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9350 ;; Since XOR can be encoded with sign extended immediate, this is only
9351 ;; profitable when 7th bit is set.
9353 [(set (match_operand 0 "register_operand" "")
9354 (xor (match_operand 1 "general_operand" "")
9355 (match_operand 2 "const_int_operand" "")))
9356 (clobber (reg:CC FLAGS_REG))]
9358 && ANY_QI_REG_P (operands[0])
9359 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9360 && !(INTVAL (operands[2]) & ~255)
9361 && (INTVAL (operands[2]) & 128)
9362 && GET_MODE (operands[0]) != QImode"
9363 [(parallel [(set (strict_low_part (match_dup 0))
9364 (xor:QI (match_dup 1)
9366 (clobber (reg:CC FLAGS_REG))])]
9367 "operands[0] = gen_lowpart (QImode, operands[0]);
9368 operands[1] = gen_lowpart (QImode, operands[1]);
9369 operands[2] = gen_lowpart (QImode, operands[2]);")
9371 ;; Negation instructions
9373 (define_expand "negti2"
9374 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9375 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9376 (clobber (reg:CC FLAGS_REG))])]
9378 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9380 (define_insn "*negti2_1"
9381 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9382 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9383 (clobber (reg:CC FLAGS_REG))]
9385 && ix86_unary_operator_ok (NEG, TImode, operands)"
9389 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9390 (neg:TI (match_operand:TI 1 "general_operand" "")))
9391 (clobber (reg:CC FLAGS_REG))]
9392 "TARGET_64BIT && reload_completed"
9394 [(set (reg:CCZ FLAGS_REG)
9395 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9396 (set (match_dup 0) (neg:DI (match_dup 2)))])
9399 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9402 (clobber (reg:CC FLAGS_REG))])
9405 (neg:DI (match_dup 1)))
9406 (clobber (reg:CC FLAGS_REG))])]
9407 "split_ti (operands+1, 1, operands+2, operands+3);
9408 split_ti (operands+0, 1, operands+0, operands+1);")
9410 (define_expand "negdi2"
9411 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9412 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9413 (clobber (reg:CC FLAGS_REG))])]
9415 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9417 (define_insn "*negdi2_1"
9418 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9419 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9420 (clobber (reg:CC FLAGS_REG))]
9422 && ix86_unary_operator_ok (NEG, DImode, operands)"
9426 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9427 (neg:DI (match_operand:DI 1 "general_operand" "")))
9428 (clobber (reg:CC FLAGS_REG))]
9429 "!TARGET_64BIT && reload_completed"
9431 [(set (reg:CCZ FLAGS_REG)
9432 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9433 (set (match_dup 0) (neg:SI (match_dup 2)))])
9436 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9439 (clobber (reg:CC FLAGS_REG))])
9442 (neg:SI (match_dup 1)))
9443 (clobber (reg:CC FLAGS_REG))])]
9444 "split_di (operands+1, 1, operands+2, operands+3);
9445 split_di (operands+0, 1, operands+0, operands+1);")
9447 (define_insn "*negdi2_1_rex64"
9448 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9450 (clobber (reg:CC FLAGS_REG))]
9451 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9453 [(set_attr "type" "negnot")
9454 (set_attr "mode" "DI")])
9456 ;; The problem with neg is that it does not perform (compare x 0),
9457 ;; it really performs (compare 0 x), which leaves us with the zero
9458 ;; flag being the only useful item.
9460 (define_insn "*negdi2_cmpz_rex64"
9461 [(set (reg:CCZ FLAGS_REG)
9462 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9464 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9465 (neg:DI (match_dup 1)))]
9466 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9468 [(set_attr "type" "negnot")
9469 (set_attr "mode" "DI")])
9472 (define_expand "negsi2"
9473 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9474 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9475 (clobber (reg:CC FLAGS_REG))])]
9477 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9479 (define_insn "*negsi2_1"
9480 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9481 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9482 (clobber (reg:CC FLAGS_REG))]
9483 "ix86_unary_operator_ok (NEG, SImode, operands)"
9485 [(set_attr "type" "negnot")
9486 (set_attr "mode" "SI")])
9488 ;; Combine is quite creative about this pattern.
9489 (define_insn "*negsi2_1_zext"
9490 [(set (match_operand:DI 0 "register_operand" "=r")
9491 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9494 (clobber (reg:CC FLAGS_REG))]
9495 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9497 [(set_attr "type" "negnot")
9498 (set_attr "mode" "SI")])
9500 ;; The problem with neg is that it does not perform (compare x 0),
9501 ;; it really performs (compare 0 x), which leaves us with the zero
9502 ;; flag being the only useful item.
9504 (define_insn "*negsi2_cmpz"
9505 [(set (reg:CCZ FLAGS_REG)
9506 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9508 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9509 (neg:SI (match_dup 1)))]
9510 "ix86_unary_operator_ok (NEG, SImode, operands)"
9512 [(set_attr "type" "negnot")
9513 (set_attr "mode" "SI")])
9515 (define_insn "*negsi2_cmpz_zext"
9516 [(set (reg:CCZ FLAGS_REG)
9517 (compare:CCZ (lshiftrt:DI
9519 (match_operand:DI 1 "register_operand" "0")
9523 (set (match_operand:DI 0 "register_operand" "=r")
9524 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9527 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9529 [(set_attr "type" "negnot")
9530 (set_attr "mode" "SI")])
9532 (define_expand "neghi2"
9533 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9534 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9535 (clobber (reg:CC FLAGS_REG))])]
9536 "TARGET_HIMODE_MATH"
9537 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9539 (define_insn "*neghi2_1"
9540 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9541 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9542 (clobber (reg:CC FLAGS_REG))]
9543 "ix86_unary_operator_ok (NEG, HImode, operands)"
9545 [(set_attr "type" "negnot")
9546 (set_attr "mode" "HI")])
9548 (define_insn "*neghi2_cmpz"
9549 [(set (reg:CCZ FLAGS_REG)
9550 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9552 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9553 (neg:HI (match_dup 1)))]
9554 "ix86_unary_operator_ok (NEG, HImode, operands)"
9556 [(set_attr "type" "negnot")
9557 (set_attr "mode" "HI")])
9559 (define_expand "negqi2"
9560 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9561 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9562 (clobber (reg:CC FLAGS_REG))])]
9563 "TARGET_QIMODE_MATH"
9564 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9566 (define_insn "*negqi2_1"
9567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9568 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9569 (clobber (reg:CC FLAGS_REG))]
9570 "ix86_unary_operator_ok (NEG, QImode, operands)"
9572 [(set_attr "type" "negnot")
9573 (set_attr "mode" "QI")])
9575 (define_insn "*negqi2_cmpz"
9576 [(set (reg:CCZ FLAGS_REG)
9577 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9579 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9580 (neg:QI (match_dup 1)))]
9581 "ix86_unary_operator_ok (NEG, QImode, operands)"
9583 [(set_attr "type" "negnot")
9584 (set_attr "mode" "QI")])
9586 ;; Changing of sign for FP values is doable using integer unit too.
9588 (define_expand "negsf2"
9589 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9590 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9591 "TARGET_80387 || TARGET_SSE_MATH"
9592 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9594 (define_expand "abssf2"
9595 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9596 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9597 "TARGET_80387 || TARGET_SSE_MATH"
9598 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9600 (define_insn "*absnegsf2_mixed"
9601 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9602 (match_operator:SF 3 "absneg_operator"
9603 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9604 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9605 (clobber (reg:CC FLAGS_REG))]
9606 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9607 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9610 (define_insn "*absnegsf2_sse"
9611 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9612 (match_operator:SF 3 "absneg_operator"
9613 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9614 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9615 (clobber (reg:CC FLAGS_REG))]
9617 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9620 (define_insn "*absnegsf2_i387"
9621 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9622 (match_operator:SF 3 "absneg_operator"
9623 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9624 (use (match_operand 2 "" ""))
9625 (clobber (reg:CC FLAGS_REG))]
9626 "TARGET_80387 && !TARGET_SSE_MATH
9627 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9630 (define_expand "copysignsf3"
9631 [(match_operand:SF 0 "register_operand" "")
9632 (match_operand:SF 1 "nonmemory_operand" "")
9633 (match_operand:SF 2 "register_operand" "")]
9636 ix86_expand_copysign (operands);
9640 (define_insn_and_split "copysignsf3_const"
9641 [(set (match_operand:SF 0 "register_operand" "=x")
9643 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9644 (match_operand:SF 2 "register_operand" "0")
9645 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9649 "&& reload_completed"
9652 ix86_split_copysign_const (operands);
9656 (define_insn "copysignsf3_var"
9657 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9659 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9660 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9661 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9662 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9664 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9669 [(set (match_operand:SF 0 "register_operand" "")
9671 [(match_operand:SF 2 "register_operand" "")
9672 (match_operand:SF 3 "register_operand" "")
9673 (match_operand:V4SF 4 "" "")
9674 (match_operand:V4SF 5 "" "")]
9676 (clobber (match_scratch:V4SF 1 ""))]
9677 "TARGET_SSE_MATH && reload_completed"
9680 ix86_split_copysign_var (operands);
9684 (define_expand "negdf2"
9685 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9686 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9687 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9688 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9690 (define_expand "absdf2"
9691 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9692 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9693 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9694 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9696 (define_insn "*absnegdf2_mixed"
9697 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9698 (match_operator:DF 3 "absneg_operator"
9699 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9700 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9703 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9706 (define_insn "*absnegdf2_sse"
9707 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9708 (match_operator:DF 3 "absneg_operator"
9709 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9710 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "TARGET_SSE2 && TARGET_SSE_MATH
9713 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9716 (define_insn "*absnegdf2_i387"
9717 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9718 (match_operator:DF 3 "absneg_operator"
9719 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9720 (use (match_operand 2 "" ""))
9721 (clobber (reg:CC FLAGS_REG))]
9722 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9723 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9726 (define_expand "copysigndf3"
9727 [(match_operand:DF 0 "register_operand" "")
9728 (match_operand:DF 1 "nonmemory_operand" "")
9729 (match_operand:DF 2 "register_operand" "")]
9730 "TARGET_SSE2 && TARGET_SSE_MATH"
9732 ix86_expand_copysign (operands);
9736 (define_insn_and_split "copysigndf3_const"
9737 [(set (match_operand:DF 0 "register_operand" "=x")
9739 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9740 (match_operand:DF 2 "register_operand" "0")
9741 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9743 "TARGET_SSE2 && TARGET_SSE_MATH"
9745 "&& reload_completed"
9748 ix86_split_copysign_const (operands);
9752 (define_insn "copysigndf3_var"
9753 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9755 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9756 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9757 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9758 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9760 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9761 "TARGET_SSE2 && TARGET_SSE_MATH"
9765 [(set (match_operand:DF 0 "register_operand" "")
9767 [(match_operand:DF 2 "register_operand" "")
9768 (match_operand:DF 3 "register_operand" "")
9769 (match_operand:V2DF 4 "" "")
9770 (match_operand:V2DF 5 "" "")]
9772 (clobber (match_scratch:V2DF 1 ""))]
9773 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9776 ix86_split_copysign_var (operands);
9780 (define_expand "negxf2"
9781 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9782 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9784 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9786 (define_expand "absxf2"
9787 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9788 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9790 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9792 (define_insn "*absnegxf2_i387"
9793 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9794 (match_operator:XF 3 "absneg_operator"
9795 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9796 (use (match_operand 2 "" ""))
9797 (clobber (reg:CC FLAGS_REG))]
9799 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9802 ;; Splitters for fp abs and neg.
9805 [(set (match_operand 0 "fp_register_operand" "")
9806 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9807 (use (match_operand 2 "" ""))
9808 (clobber (reg:CC FLAGS_REG))]
9810 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9813 [(set (match_operand 0 "register_operand" "")
9814 (match_operator 3 "absneg_operator"
9815 [(match_operand 1 "register_operand" "")]))
9816 (use (match_operand 2 "nonimmediate_operand" ""))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "reload_completed && SSE_REG_P (operands[0])"
9819 [(set (match_dup 0) (match_dup 3))]
9821 enum machine_mode mode = GET_MODE (operands[0]);
9822 enum machine_mode vmode = GET_MODE (operands[2]);
9825 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9826 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9827 if (operands_match_p (operands[0], operands[2]))
9830 operands[1] = operands[2];
9833 if (GET_CODE (operands[3]) == ABS)
9834 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9836 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9841 [(set (match_operand:SF 0 "register_operand" "")
9842 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9843 (use (match_operand:V4SF 2 "" ""))
9844 (clobber (reg:CC FLAGS_REG))]
9846 [(parallel [(set (match_dup 0) (match_dup 1))
9847 (clobber (reg:CC FLAGS_REG))])]
9850 operands[0] = gen_lowpart (SImode, operands[0]);
9851 if (GET_CODE (operands[1]) == ABS)
9853 tmp = gen_int_mode (0x7fffffff, SImode);
9854 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9858 tmp = gen_int_mode (0x80000000, SImode);
9859 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9865 [(set (match_operand:DF 0 "register_operand" "")
9866 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9867 (use (match_operand 2 "" ""))
9868 (clobber (reg:CC FLAGS_REG))]
9870 [(parallel [(set (match_dup 0) (match_dup 1))
9871 (clobber (reg:CC FLAGS_REG))])]
9876 tmp = gen_lowpart (DImode, operands[0]);
9877 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9880 if (GET_CODE (operands[1]) == ABS)
9883 tmp = gen_rtx_NOT (DImode, tmp);
9887 operands[0] = gen_highpart (SImode, operands[0]);
9888 if (GET_CODE (operands[1]) == ABS)
9890 tmp = gen_int_mode (0x7fffffff, SImode);
9891 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9895 tmp = gen_int_mode (0x80000000, SImode);
9896 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9903 [(set (match_operand:XF 0 "register_operand" "")
9904 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9905 (use (match_operand 2 "" ""))
9906 (clobber (reg:CC FLAGS_REG))]
9908 [(parallel [(set (match_dup 0) (match_dup 1))
9909 (clobber (reg:CC FLAGS_REG))])]
9912 operands[0] = gen_rtx_REG (SImode,
9913 true_regnum (operands[0])
9914 + (TARGET_64BIT ? 1 : 2));
9915 if (GET_CODE (operands[1]) == ABS)
9917 tmp = GEN_INT (0x7fff);
9918 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9922 tmp = GEN_INT (0x8000);
9923 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9929 [(set (match_operand 0 "memory_operand" "")
9930 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9931 (use (match_operand 2 "" ""))
9932 (clobber (reg:CC FLAGS_REG))]
9934 [(parallel [(set (match_dup 0) (match_dup 1))
9935 (clobber (reg:CC FLAGS_REG))])]
9937 enum machine_mode mode = GET_MODE (operands[0]);
9938 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9941 operands[0] = adjust_address (operands[0], QImode, size - 1);
9942 if (GET_CODE (operands[1]) == ABS)
9944 tmp = gen_int_mode (0x7f, QImode);
9945 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9949 tmp = gen_int_mode (0x80, QImode);
9950 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9955 ;; Conditionalize these after reload. If they match before reload, we
9956 ;; lose the clobber and ability to use integer instructions.
9958 (define_insn "*negsf2_1"
9959 [(set (match_operand:SF 0 "register_operand" "=f")
9960 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9961 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9963 [(set_attr "type" "fsgn")
9964 (set_attr "mode" "SF")])
9966 (define_insn "*negdf2_1"
9967 [(set (match_operand:DF 0 "register_operand" "=f")
9968 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9969 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9971 [(set_attr "type" "fsgn")
9972 (set_attr "mode" "DF")])
9974 (define_insn "*negxf2_1"
9975 [(set (match_operand:XF 0 "register_operand" "=f")
9976 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9979 [(set_attr "type" "fsgn")
9980 (set_attr "mode" "XF")])
9982 (define_insn "*abssf2_1"
9983 [(set (match_operand:SF 0 "register_operand" "=f")
9984 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9985 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9987 [(set_attr "type" "fsgn")
9988 (set_attr "mode" "SF")])
9990 (define_insn "*absdf2_1"
9991 [(set (match_operand:DF 0 "register_operand" "=f")
9992 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9993 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9995 [(set_attr "type" "fsgn")
9996 (set_attr "mode" "DF")])
9998 (define_insn "*absxf2_1"
9999 [(set (match_operand:XF 0 "register_operand" "=f")
10000 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10003 [(set_attr "type" "fsgn")
10004 (set_attr "mode" "DF")])
10006 (define_insn "*negextendsfdf2"
10007 [(set (match_operand:DF 0 "register_operand" "=f")
10008 (neg:DF (float_extend:DF
10009 (match_operand:SF 1 "register_operand" "0"))))]
10010 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10012 [(set_attr "type" "fsgn")
10013 (set_attr "mode" "DF")])
10015 (define_insn "*negextenddfxf2"
10016 [(set (match_operand:XF 0 "register_operand" "=f")
10017 (neg:XF (float_extend:XF
10018 (match_operand:DF 1 "register_operand" "0"))))]
10021 [(set_attr "type" "fsgn")
10022 (set_attr "mode" "XF")])
10024 (define_insn "*negextendsfxf2"
10025 [(set (match_operand:XF 0 "register_operand" "=f")
10026 (neg:XF (float_extend:XF
10027 (match_operand:SF 1 "register_operand" "0"))))]
10030 [(set_attr "type" "fsgn")
10031 (set_attr "mode" "XF")])
10033 (define_insn "*absextendsfdf2"
10034 [(set (match_operand:DF 0 "register_operand" "=f")
10035 (abs:DF (float_extend:DF
10036 (match_operand:SF 1 "register_operand" "0"))))]
10037 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10039 [(set_attr "type" "fsgn")
10040 (set_attr "mode" "DF")])
10042 (define_insn "*absextenddfxf2"
10043 [(set (match_operand:XF 0 "register_operand" "=f")
10044 (abs:XF (float_extend:XF
10045 (match_operand:DF 1 "register_operand" "0"))))]
10048 [(set_attr "type" "fsgn")
10049 (set_attr "mode" "XF")])
10051 (define_insn "*absextendsfxf2"
10052 [(set (match_operand:XF 0 "register_operand" "=f")
10053 (abs:XF (float_extend:XF
10054 (match_operand:SF 1 "register_operand" "0"))))]
10057 [(set_attr "type" "fsgn")
10058 (set_attr "mode" "XF")])
10060 ;; One complement instructions
10062 (define_expand "one_cmpldi2"
10063 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10064 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10066 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10068 (define_insn "*one_cmpldi2_1_rex64"
10069 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10070 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10071 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10073 [(set_attr "type" "negnot")
10074 (set_attr "mode" "DI")])
10076 (define_insn "*one_cmpldi2_2_rex64"
10077 [(set (reg FLAGS_REG)
10078 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10080 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10081 (not:DI (match_dup 1)))]
10082 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10083 && ix86_unary_operator_ok (NOT, DImode, operands)"
10085 [(set_attr "type" "alu1")
10086 (set_attr "mode" "DI")])
10089 [(set (match_operand 0 "flags_reg_operand" "")
10090 (match_operator 2 "compare_operator"
10091 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10093 (set (match_operand:DI 1 "nonimmediate_operand" "")
10094 (not:DI (match_dup 3)))]
10095 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10096 [(parallel [(set (match_dup 0)
10098 [(xor:DI (match_dup 3) (const_int -1))
10101 (xor:DI (match_dup 3) (const_int -1)))])]
10104 (define_expand "one_cmplsi2"
10105 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10106 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10108 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10110 (define_insn "*one_cmplsi2_1"
10111 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10112 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10113 "ix86_unary_operator_ok (NOT, SImode, operands)"
10115 [(set_attr "type" "negnot")
10116 (set_attr "mode" "SI")])
10118 ;; ??? Currently never generated - xor is used instead.
10119 (define_insn "*one_cmplsi2_1_zext"
10120 [(set (match_operand:DI 0 "register_operand" "=r")
10121 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10122 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10124 [(set_attr "type" "negnot")
10125 (set_attr "mode" "SI")])
10127 (define_insn "*one_cmplsi2_2"
10128 [(set (reg FLAGS_REG)
10129 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10131 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10132 (not:SI (match_dup 1)))]
10133 "ix86_match_ccmode (insn, CCNOmode)
10134 && ix86_unary_operator_ok (NOT, SImode, operands)"
10136 [(set_attr "type" "alu1")
10137 (set_attr "mode" "SI")])
10140 [(set (match_operand 0 "flags_reg_operand" "")
10141 (match_operator 2 "compare_operator"
10142 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10144 (set (match_operand:SI 1 "nonimmediate_operand" "")
10145 (not:SI (match_dup 3)))]
10146 "ix86_match_ccmode (insn, CCNOmode)"
10147 [(parallel [(set (match_dup 0)
10148 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10151 (xor:SI (match_dup 3) (const_int -1)))])]
10154 ;; ??? Currently never generated - xor is used instead.
10155 (define_insn "*one_cmplsi2_2_zext"
10156 [(set (reg FLAGS_REG)
10157 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10159 (set (match_operand:DI 0 "register_operand" "=r")
10160 (zero_extend:DI (not:SI (match_dup 1))))]
10161 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10162 && ix86_unary_operator_ok (NOT, SImode, operands)"
10164 [(set_attr "type" "alu1")
10165 (set_attr "mode" "SI")])
10168 [(set (match_operand 0 "flags_reg_operand" "")
10169 (match_operator 2 "compare_operator"
10170 [(not:SI (match_operand:SI 3 "register_operand" ""))
10172 (set (match_operand:DI 1 "register_operand" "")
10173 (zero_extend:DI (not:SI (match_dup 3))))]
10174 "ix86_match_ccmode (insn, CCNOmode)"
10175 [(parallel [(set (match_dup 0)
10176 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10179 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10182 (define_expand "one_cmplhi2"
10183 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10184 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10185 "TARGET_HIMODE_MATH"
10186 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10188 (define_insn "*one_cmplhi2_1"
10189 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10190 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10191 "ix86_unary_operator_ok (NOT, HImode, operands)"
10193 [(set_attr "type" "negnot")
10194 (set_attr "mode" "HI")])
10196 (define_insn "*one_cmplhi2_2"
10197 [(set (reg FLAGS_REG)
10198 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10200 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10201 (not:HI (match_dup 1)))]
10202 "ix86_match_ccmode (insn, CCNOmode)
10203 && ix86_unary_operator_ok (NEG, HImode, operands)"
10205 [(set_attr "type" "alu1")
10206 (set_attr "mode" "HI")])
10209 [(set (match_operand 0 "flags_reg_operand" "")
10210 (match_operator 2 "compare_operator"
10211 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10213 (set (match_operand:HI 1 "nonimmediate_operand" "")
10214 (not:HI (match_dup 3)))]
10215 "ix86_match_ccmode (insn, CCNOmode)"
10216 [(parallel [(set (match_dup 0)
10217 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10220 (xor:HI (match_dup 3) (const_int -1)))])]
10223 ;; %%% Potential partial reg stall on alternative 1. What to do?
10224 (define_expand "one_cmplqi2"
10225 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10226 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10227 "TARGET_QIMODE_MATH"
10228 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10230 (define_insn "*one_cmplqi2_1"
10231 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10232 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10233 "ix86_unary_operator_ok (NOT, QImode, operands)"
10237 [(set_attr "type" "negnot")
10238 (set_attr "mode" "QI,SI")])
10240 (define_insn "*one_cmplqi2_2"
10241 [(set (reg FLAGS_REG)
10242 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10244 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10245 (not:QI (match_dup 1)))]
10246 "ix86_match_ccmode (insn, CCNOmode)
10247 && ix86_unary_operator_ok (NOT, QImode, operands)"
10249 [(set_attr "type" "alu1")
10250 (set_attr "mode" "QI")])
10253 [(set (match_operand 0 "flags_reg_operand" "")
10254 (match_operator 2 "compare_operator"
10255 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10257 (set (match_operand:QI 1 "nonimmediate_operand" "")
10258 (not:QI (match_dup 3)))]
10259 "ix86_match_ccmode (insn, CCNOmode)"
10260 [(parallel [(set (match_dup 0)
10261 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10264 (xor:QI (match_dup 3) (const_int -1)))])]
10267 ;; Arithmetic shift instructions
10269 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10270 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10271 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10272 ;; from the assembler input.
10274 ;; This instruction shifts the target reg/mem as usual, but instead of
10275 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10276 ;; is a left shift double, bits are taken from the high order bits of
10277 ;; reg, else if the insn is a shift right double, bits are taken from the
10278 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10279 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10281 ;; Since sh[lr]d does not change the `reg' operand, that is done
10282 ;; separately, making all shifts emit pairs of shift double and normal
10283 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10284 ;; support a 63 bit shift, each shift where the count is in a reg expands
10285 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10287 ;; If the shift count is a constant, we need never emit more than one
10288 ;; shift pair, instead using moves and sign extension for counts greater
10291 (define_expand "ashlti3"
10292 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10293 (ashift:TI (match_operand:TI 1 "register_operand" "")
10294 (match_operand:QI 2 "nonmemory_operand" "")))
10295 (clobber (reg:CC FLAGS_REG))])]
10298 if (! immediate_operand (operands[2], QImode))
10300 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10303 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10307 (define_insn "ashlti3_1"
10308 [(set (match_operand:TI 0 "register_operand" "=r")
10309 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10310 (match_operand:QI 2 "register_operand" "c")))
10311 (clobber (match_scratch:DI 3 "=&r"))
10312 (clobber (reg:CC FLAGS_REG))]
10315 [(set_attr "type" "multi")])
10317 (define_insn "*ashlti3_2"
10318 [(set (match_operand:TI 0 "register_operand" "=r")
10319 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10320 (match_operand:QI 2 "immediate_operand" "O")))
10321 (clobber (reg:CC FLAGS_REG))]
10324 [(set_attr "type" "multi")])
10327 [(set (match_operand:TI 0 "register_operand" "")
10328 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10329 (match_operand:QI 2 "register_operand" "")))
10330 (clobber (match_scratch:DI 3 ""))
10331 (clobber (reg:CC FLAGS_REG))]
10332 "TARGET_64BIT && reload_completed"
10334 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10337 [(set (match_operand:TI 0 "register_operand" "")
10338 (ashift:TI (match_operand:TI 1 "register_operand" "")
10339 (match_operand:QI 2 "immediate_operand" "")))
10340 (clobber (reg:CC FLAGS_REG))]
10341 "TARGET_64BIT && reload_completed"
10343 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10345 (define_insn "x86_64_shld"
10346 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10347 (ior:DI (ashift:DI (match_dup 0)
10348 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10349 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10350 (minus:QI (const_int 64) (match_dup 2)))))
10351 (clobber (reg:CC FLAGS_REG))]
10354 shld{q}\t{%2, %1, %0|%0, %1, %2}
10355 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10356 [(set_attr "type" "ishift")
10357 (set_attr "prefix_0f" "1")
10358 (set_attr "mode" "DI")
10359 (set_attr "athlon_decode" "vector")])
10361 (define_expand "x86_64_shift_adj"
10362 [(set (reg:CCZ FLAGS_REG)
10363 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10366 (set (match_operand:DI 0 "register_operand" "")
10367 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10368 (match_operand:DI 1 "register_operand" "")
10371 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10372 (match_operand:DI 3 "register_operand" "r")
10377 (define_expand "ashldi3"
10378 [(set (match_operand:DI 0 "shiftdi_operand" "")
10379 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10380 (match_operand:QI 2 "nonmemory_operand" "")))]
10382 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10384 (define_insn "*ashldi3_1_rex64"
10385 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10386 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10387 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10388 (clobber (reg:CC FLAGS_REG))]
10389 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10391 switch (get_attr_type (insn))
10394 gcc_assert (operands[2] == const1_rtx);
10395 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10396 return "add{q}\t{%0, %0|%0, %0}";
10399 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10400 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10401 operands[1] = gen_rtx_MULT (DImode, operands[1],
10402 GEN_INT (1 << INTVAL (operands[2])));
10403 return "lea{q}\t{%a1, %0|%0, %a1}";
10406 if (REG_P (operands[2]))
10407 return "sal{q}\t{%b2, %0|%0, %b2}";
10408 else if (operands[2] == const1_rtx
10409 && (TARGET_SHIFT1 || optimize_size))
10410 return "sal{q}\t%0";
10412 return "sal{q}\t{%2, %0|%0, %2}";
10415 [(set (attr "type")
10416 (cond [(eq_attr "alternative" "1")
10417 (const_string "lea")
10418 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10420 (match_operand 0 "register_operand" ""))
10421 (match_operand 2 "const1_operand" ""))
10422 (const_string "alu")
10424 (const_string "ishift")))
10425 (set_attr "mode" "DI")])
10427 ;; Convert lea to the lea pattern to avoid flags dependency.
10429 [(set (match_operand:DI 0 "register_operand" "")
10430 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10431 (match_operand:QI 2 "immediate_operand" "")))
10432 (clobber (reg:CC FLAGS_REG))]
10433 "TARGET_64BIT && reload_completed
10434 && true_regnum (operands[0]) != true_regnum (operands[1])"
10435 [(set (match_dup 0)
10436 (mult:DI (match_dup 1)
10438 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10440 ;; This pattern can't accept a variable shift count, since shifts by
10441 ;; zero don't affect the flags. We assume that shifts by constant
10442 ;; zero are optimized away.
10443 (define_insn "*ashldi3_cmp_rex64"
10444 [(set (reg FLAGS_REG)
10446 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10447 (match_operand:QI 2 "immediate_operand" "e"))
10449 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10450 (ashift:DI (match_dup 1) (match_dup 2)))]
10451 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10452 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10454 || !TARGET_PARTIAL_FLAG_REG_STALL
10455 || (operands[2] == const1_rtx
10457 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10459 switch (get_attr_type (insn))
10462 gcc_assert (operands[2] == const1_rtx);
10463 return "add{q}\t{%0, %0|%0, %0}";
10466 if (REG_P (operands[2]))
10467 return "sal{q}\t{%b2, %0|%0, %b2}";
10468 else if (operands[2] == const1_rtx
10469 && (TARGET_SHIFT1 || optimize_size))
10470 return "sal{q}\t%0";
10472 return "sal{q}\t{%2, %0|%0, %2}";
10475 [(set (attr "type")
10476 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10478 (match_operand 0 "register_operand" ""))
10479 (match_operand 2 "const1_operand" ""))
10480 (const_string "alu")
10482 (const_string "ishift")))
10483 (set_attr "mode" "DI")])
10485 (define_insn "*ashldi3_cconly_rex64"
10486 [(set (reg FLAGS_REG)
10488 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10489 (match_operand:QI 2 "immediate_operand" "e"))
10491 (clobber (match_scratch:DI 0 "=r"))]
10492 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10493 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10495 || !TARGET_PARTIAL_FLAG_REG_STALL
10496 || (operands[2] == const1_rtx
10498 || TARGET_DOUBLE_WITH_ADD)))"
10500 switch (get_attr_type (insn))
10503 gcc_assert (operands[2] == const1_rtx);
10504 return "add{q}\t{%0, %0|%0, %0}";
10507 if (REG_P (operands[2]))
10508 return "sal{q}\t{%b2, %0|%0, %b2}";
10509 else if (operands[2] == const1_rtx
10510 && (TARGET_SHIFT1 || optimize_size))
10511 return "sal{q}\t%0";
10513 return "sal{q}\t{%2, %0|%0, %2}";
10516 [(set (attr "type")
10517 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10519 (match_operand 0 "register_operand" ""))
10520 (match_operand 2 "const1_operand" ""))
10521 (const_string "alu")
10523 (const_string "ishift")))
10524 (set_attr "mode" "DI")])
10526 (define_insn "*ashldi3_1"
10527 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10528 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10529 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10530 (clobber (reg:CC FLAGS_REG))]
10533 [(set_attr "type" "multi")])
10535 ;; By default we don't ask for a scratch register, because when DImode
10536 ;; values are manipulated, registers are already at a premium. But if
10537 ;; we have one handy, we won't turn it away.
10539 [(match_scratch:SI 3 "r")
10540 (parallel [(set (match_operand:DI 0 "register_operand" "")
10541 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10542 (match_operand:QI 2 "nonmemory_operand" "")))
10543 (clobber (reg:CC FLAGS_REG))])
10545 "!TARGET_64BIT && TARGET_CMOVE"
10547 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10550 [(set (match_operand:DI 0 "register_operand" "")
10551 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10552 (match_operand:QI 2 "nonmemory_operand" "")))
10553 (clobber (reg:CC FLAGS_REG))]
10554 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10555 ? flow2_completed : reload_completed)"
10557 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10559 (define_insn "x86_shld_1"
10560 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10561 (ior:SI (ashift:SI (match_dup 0)
10562 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10563 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10564 (minus:QI (const_int 32) (match_dup 2)))))
10565 (clobber (reg:CC FLAGS_REG))]
10568 shld{l}\t{%2, %1, %0|%0, %1, %2}
10569 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10570 [(set_attr "type" "ishift")
10571 (set_attr "prefix_0f" "1")
10572 (set_attr "mode" "SI")
10573 (set_attr "pent_pair" "np")
10574 (set_attr "athlon_decode" "vector")])
10576 (define_expand "x86_shift_adj_1"
10577 [(set (reg:CCZ FLAGS_REG)
10578 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10581 (set (match_operand:SI 0 "register_operand" "")
10582 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10583 (match_operand:SI 1 "register_operand" "")
10586 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10587 (match_operand:SI 3 "register_operand" "r")
10592 (define_expand "x86_shift_adj_2"
10593 [(use (match_operand:SI 0 "register_operand" ""))
10594 (use (match_operand:SI 1 "register_operand" ""))
10595 (use (match_operand:QI 2 "register_operand" ""))]
10598 rtx label = gen_label_rtx ();
10601 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10603 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10604 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10605 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10606 gen_rtx_LABEL_REF (VOIDmode, label),
10608 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10609 JUMP_LABEL (tmp) = label;
10611 emit_move_insn (operands[0], operands[1]);
10612 ix86_expand_clear (operands[1]);
10614 emit_label (label);
10615 LABEL_NUSES (label) = 1;
10620 (define_expand "ashlsi3"
10621 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10622 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10623 (match_operand:QI 2 "nonmemory_operand" "")))
10624 (clobber (reg:CC FLAGS_REG))]
10626 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10628 (define_insn "*ashlsi3_1"
10629 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10630 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10631 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10635 switch (get_attr_type (insn))
10638 gcc_assert (operands[2] == const1_rtx);
10639 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10640 return "add{l}\t{%0, %0|%0, %0}";
10646 if (REG_P (operands[2]))
10647 return "sal{l}\t{%b2, %0|%0, %b2}";
10648 else if (operands[2] == const1_rtx
10649 && (TARGET_SHIFT1 || optimize_size))
10650 return "sal{l}\t%0";
10652 return "sal{l}\t{%2, %0|%0, %2}";
10655 [(set (attr "type")
10656 (cond [(eq_attr "alternative" "1")
10657 (const_string "lea")
10658 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10660 (match_operand 0 "register_operand" ""))
10661 (match_operand 2 "const1_operand" ""))
10662 (const_string "alu")
10664 (const_string "ishift")))
10665 (set_attr "mode" "SI")])
10667 ;; Convert lea to the lea pattern to avoid flags dependency.
10669 [(set (match_operand 0 "register_operand" "")
10670 (ashift (match_operand 1 "index_register_operand" "")
10671 (match_operand:QI 2 "const_int_operand" "")))
10672 (clobber (reg:CC FLAGS_REG))]
10674 && true_regnum (operands[0]) != true_regnum (operands[1])
10675 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10679 enum machine_mode mode = GET_MODE (operands[0]);
10681 if (GET_MODE_SIZE (mode) < 4)
10682 operands[0] = gen_lowpart (SImode, operands[0]);
10684 operands[1] = gen_lowpart (Pmode, operands[1]);
10685 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10687 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10688 if (Pmode != SImode)
10689 pat = gen_rtx_SUBREG (SImode, pat, 0);
10690 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10694 ;; Rare case of shifting RSP is handled by generating move and shift
10696 [(set (match_operand 0 "register_operand" "")
10697 (ashift (match_operand 1 "register_operand" "")
10698 (match_operand:QI 2 "const_int_operand" "")))
10699 (clobber (reg:CC FLAGS_REG))]
10701 && true_regnum (operands[0]) != true_regnum (operands[1])"
10705 emit_move_insn (operands[0], operands[1]);
10706 pat = gen_rtx_SET (VOIDmode, operands[0],
10707 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10708 operands[0], operands[2]));
10709 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10710 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10714 (define_insn "*ashlsi3_1_zext"
10715 [(set (match_operand:DI 0 "register_operand" "=r,r")
10716 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10717 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10718 (clobber (reg:CC FLAGS_REG))]
10719 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10721 switch (get_attr_type (insn))
10724 gcc_assert (operands[2] == const1_rtx);
10725 return "add{l}\t{%k0, %k0|%k0, %k0}";
10731 if (REG_P (operands[2]))
10732 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10733 else if (operands[2] == const1_rtx
10734 && (TARGET_SHIFT1 || optimize_size))
10735 return "sal{l}\t%k0";
10737 return "sal{l}\t{%2, %k0|%k0, %2}";
10740 [(set (attr "type")
10741 (cond [(eq_attr "alternative" "1")
10742 (const_string "lea")
10743 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10745 (match_operand 2 "const1_operand" ""))
10746 (const_string "alu")
10748 (const_string "ishift")))
10749 (set_attr "mode" "SI")])
10751 ;; Convert lea to the lea pattern to avoid flags dependency.
10753 [(set (match_operand:DI 0 "register_operand" "")
10754 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10755 (match_operand:QI 2 "const_int_operand" ""))))
10756 (clobber (reg:CC FLAGS_REG))]
10757 "TARGET_64BIT && reload_completed
10758 && true_regnum (operands[0]) != true_regnum (operands[1])"
10759 [(set (match_dup 0) (zero_extend:DI
10760 (subreg:SI (mult:SI (match_dup 1)
10761 (match_dup 2)) 0)))]
10763 operands[1] = gen_lowpart (Pmode, operands[1]);
10764 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10767 ;; This pattern can't accept a variable shift count, since shifts by
10768 ;; zero don't affect the flags. We assume that shifts by constant
10769 ;; zero are optimized away.
10770 (define_insn "*ashlsi3_cmp"
10771 [(set (reg FLAGS_REG)
10773 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10774 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10776 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10777 (ashift:SI (match_dup 1) (match_dup 2)))]
10778 "ix86_match_ccmode (insn, CCGOCmode)
10779 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10781 || !TARGET_PARTIAL_FLAG_REG_STALL
10782 || (operands[2] == const1_rtx
10784 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10786 switch (get_attr_type (insn))
10789 gcc_assert (operands[2] == const1_rtx);
10790 return "add{l}\t{%0, %0|%0, %0}";
10793 if (REG_P (operands[2]))
10794 return "sal{l}\t{%b2, %0|%0, %b2}";
10795 else if (operands[2] == const1_rtx
10796 && (TARGET_SHIFT1 || optimize_size))
10797 return "sal{l}\t%0";
10799 return "sal{l}\t{%2, %0|%0, %2}";
10802 [(set (attr "type")
10803 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10805 (match_operand 0 "register_operand" ""))
10806 (match_operand 2 "const1_operand" ""))
10807 (const_string "alu")
10809 (const_string "ishift")))
10810 (set_attr "mode" "SI")])
10812 (define_insn "*ashlsi3_cconly"
10813 [(set (reg FLAGS_REG)
10815 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10816 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10818 (clobber (match_scratch:SI 0 "=r"))]
10819 "ix86_match_ccmode (insn, CCGOCmode)
10820 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10822 || !TARGET_PARTIAL_FLAG_REG_STALL
10823 || (operands[2] == const1_rtx
10825 || TARGET_DOUBLE_WITH_ADD)))"
10827 switch (get_attr_type (insn))
10830 gcc_assert (operands[2] == const1_rtx);
10831 return "add{l}\t{%0, %0|%0, %0}";
10834 if (REG_P (operands[2]))
10835 return "sal{l}\t{%b2, %0|%0, %b2}";
10836 else if (operands[2] == const1_rtx
10837 && (TARGET_SHIFT1 || optimize_size))
10838 return "sal{l}\t%0";
10840 return "sal{l}\t{%2, %0|%0, %2}";
10843 [(set (attr "type")
10844 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10846 (match_operand 0 "register_operand" ""))
10847 (match_operand 2 "const1_operand" ""))
10848 (const_string "alu")
10850 (const_string "ishift")))
10851 (set_attr "mode" "SI")])
10853 (define_insn "*ashlsi3_cmp_zext"
10854 [(set (reg FLAGS_REG)
10856 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10857 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10859 (set (match_operand:DI 0 "register_operand" "=r")
10860 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10861 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10862 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10864 || !TARGET_PARTIAL_FLAG_REG_STALL
10865 || (operands[2] == const1_rtx
10867 || TARGET_DOUBLE_WITH_ADD)))"
10869 switch (get_attr_type (insn))
10872 gcc_assert (operands[2] == const1_rtx);
10873 return "add{l}\t{%k0, %k0|%k0, %k0}";
10876 if (REG_P (operands[2]))
10877 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10878 else if (operands[2] == const1_rtx
10879 && (TARGET_SHIFT1 || optimize_size))
10880 return "sal{l}\t%k0";
10882 return "sal{l}\t{%2, %k0|%k0, %2}";
10885 [(set (attr "type")
10886 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10888 (match_operand 2 "const1_operand" ""))
10889 (const_string "alu")
10891 (const_string "ishift")))
10892 (set_attr "mode" "SI")])
10894 (define_expand "ashlhi3"
10895 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10896 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10897 (match_operand:QI 2 "nonmemory_operand" "")))
10898 (clobber (reg:CC FLAGS_REG))]
10899 "TARGET_HIMODE_MATH"
10900 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10902 (define_insn "*ashlhi3_1_lea"
10903 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10904 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10905 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10906 (clobber (reg:CC FLAGS_REG))]
10907 "!TARGET_PARTIAL_REG_STALL
10908 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10910 switch (get_attr_type (insn))
10915 gcc_assert (operands[2] == const1_rtx);
10916 return "add{w}\t{%0, %0|%0, %0}";
10919 if (REG_P (operands[2]))
10920 return "sal{w}\t{%b2, %0|%0, %b2}";
10921 else if (operands[2] == const1_rtx
10922 && (TARGET_SHIFT1 || optimize_size))
10923 return "sal{w}\t%0";
10925 return "sal{w}\t{%2, %0|%0, %2}";
10928 [(set (attr "type")
10929 (cond [(eq_attr "alternative" "1")
10930 (const_string "lea")
10931 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10933 (match_operand 0 "register_operand" ""))
10934 (match_operand 2 "const1_operand" ""))
10935 (const_string "alu")
10937 (const_string "ishift")))
10938 (set_attr "mode" "HI,SI")])
10940 (define_insn "*ashlhi3_1"
10941 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10942 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10943 (match_operand:QI 2 "nonmemory_operand" "cI")))
10944 (clobber (reg:CC FLAGS_REG))]
10945 "TARGET_PARTIAL_REG_STALL
10946 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10948 switch (get_attr_type (insn))
10951 gcc_assert (operands[2] == const1_rtx);
10952 return "add{w}\t{%0, %0|%0, %0}";
10955 if (REG_P (operands[2]))
10956 return "sal{w}\t{%b2, %0|%0, %b2}";
10957 else if (operands[2] == const1_rtx
10958 && (TARGET_SHIFT1 || optimize_size))
10959 return "sal{w}\t%0";
10961 return "sal{w}\t{%2, %0|%0, %2}";
10964 [(set (attr "type")
10965 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10967 (match_operand 0 "register_operand" ""))
10968 (match_operand 2 "const1_operand" ""))
10969 (const_string "alu")
10971 (const_string "ishift")))
10972 (set_attr "mode" "HI")])
10974 ;; This pattern can't accept a variable shift count, since shifts by
10975 ;; zero don't affect the flags. We assume that shifts by constant
10976 ;; zero are optimized away.
10977 (define_insn "*ashlhi3_cmp"
10978 [(set (reg FLAGS_REG)
10980 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10981 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10983 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10984 (ashift:HI (match_dup 1) (match_dup 2)))]
10985 "ix86_match_ccmode (insn, CCGOCmode)
10986 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10988 || !TARGET_PARTIAL_FLAG_REG_STALL
10989 || (operands[2] == const1_rtx
10991 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10993 switch (get_attr_type (insn))
10996 gcc_assert (operands[2] == const1_rtx);
10997 return "add{w}\t{%0, %0|%0, %0}";
11000 if (REG_P (operands[2]))
11001 return "sal{w}\t{%b2, %0|%0, %b2}";
11002 else if (operands[2] == const1_rtx
11003 && (TARGET_SHIFT1 || optimize_size))
11004 return "sal{w}\t%0";
11006 return "sal{w}\t{%2, %0|%0, %2}";
11009 [(set (attr "type")
11010 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11012 (match_operand 0 "register_operand" ""))
11013 (match_operand 2 "const1_operand" ""))
11014 (const_string "alu")
11016 (const_string "ishift")))
11017 (set_attr "mode" "HI")])
11019 (define_insn "*ashlhi3_cconly"
11020 [(set (reg FLAGS_REG)
11022 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11023 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11025 (clobber (match_scratch:HI 0 "=r"))]
11026 "ix86_match_ccmode (insn, CCGOCmode)
11027 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11029 || !TARGET_PARTIAL_FLAG_REG_STALL
11030 || (operands[2] == const1_rtx
11032 || TARGET_DOUBLE_WITH_ADD)))"
11034 switch (get_attr_type (insn))
11037 gcc_assert (operands[2] == const1_rtx);
11038 return "add{w}\t{%0, %0|%0, %0}";
11041 if (REG_P (operands[2]))
11042 return "sal{w}\t{%b2, %0|%0, %b2}";
11043 else if (operands[2] == const1_rtx
11044 && (TARGET_SHIFT1 || optimize_size))
11045 return "sal{w}\t%0";
11047 return "sal{w}\t{%2, %0|%0, %2}";
11050 [(set (attr "type")
11051 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11053 (match_operand 0 "register_operand" ""))
11054 (match_operand 2 "const1_operand" ""))
11055 (const_string "alu")
11057 (const_string "ishift")))
11058 (set_attr "mode" "HI")])
11060 (define_expand "ashlqi3"
11061 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11062 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11063 (match_operand:QI 2 "nonmemory_operand" "")))
11064 (clobber (reg:CC FLAGS_REG))]
11065 "TARGET_QIMODE_MATH"
11066 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11068 ;; %%% Potential partial reg stall on alternative 2. What to do?
11070 (define_insn "*ashlqi3_1_lea"
11071 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11072 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11073 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11074 (clobber (reg:CC FLAGS_REG))]
11075 "!TARGET_PARTIAL_REG_STALL
11076 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11078 switch (get_attr_type (insn))
11083 gcc_assert (operands[2] == const1_rtx);
11084 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11085 return "add{l}\t{%k0, %k0|%k0, %k0}";
11087 return "add{b}\t{%0, %0|%0, %0}";
11090 if (REG_P (operands[2]))
11092 if (get_attr_mode (insn) == MODE_SI)
11093 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11095 return "sal{b}\t{%b2, %0|%0, %b2}";
11097 else if (operands[2] == const1_rtx
11098 && (TARGET_SHIFT1 || optimize_size))
11100 if (get_attr_mode (insn) == MODE_SI)
11101 return "sal{l}\t%0";
11103 return "sal{b}\t%0";
11107 if (get_attr_mode (insn) == MODE_SI)
11108 return "sal{l}\t{%2, %k0|%k0, %2}";
11110 return "sal{b}\t{%2, %0|%0, %2}";
11114 [(set (attr "type")
11115 (cond [(eq_attr "alternative" "2")
11116 (const_string "lea")
11117 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11119 (match_operand 0 "register_operand" ""))
11120 (match_operand 2 "const1_operand" ""))
11121 (const_string "alu")
11123 (const_string "ishift")))
11124 (set_attr "mode" "QI,SI,SI")])
11126 (define_insn "*ashlqi3_1"
11127 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11128 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11129 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11130 (clobber (reg:CC FLAGS_REG))]
11131 "TARGET_PARTIAL_REG_STALL
11132 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11134 switch (get_attr_type (insn))
11137 gcc_assert (operands[2] == const1_rtx);
11138 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11139 return "add{l}\t{%k0, %k0|%k0, %k0}";
11141 return "add{b}\t{%0, %0|%0, %0}";
11144 if (REG_P (operands[2]))
11146 if (get_attr_mode (insn) == MODE_SI)
11147 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11149 return "sal{b}\t{%b2, %0|%0, %b2}";
11151 else if (operands[2] == const1_rtx
11152 && (TARGET_SHIFT1 || optimize_size))
11154 if (get_attr_mode (insn) == MODE_SI)
11155 return "sal{l}\t%0";
11157 return "sal{b}\t%0";
11161 if (get_attr_mode (insn) == MODE_SI)
11162 return "sal{l}\t{%2, %k0|%k0, %2}";
11164 return "sal{b}\t{%2, %0|%0, %2}";
11168 [(set (attr "type")
11169 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11171 (match_operand 0 "register_operand" ""))
11172 (match_operand 2 "const1_operand" ""))
11173 (const_string "alu")
11175 (const_string "ishift")))
11176 (set_attr "mode" "QI,SI")])
11178 ;; This pattern can't accept a variable shift count, since shifts by
11179 ;; zero don't affect the flags. We assume that shifts by constant
11180 ;; zero are optimized away.
11181 (define_insn "*ashlqi3_cmp"
11182 [(set (reg FLAGS_REG)
11184 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11185 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11187 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11188 (ashift:QI (match_dup 1) (match_dup 2)))]
11189 "ix86_match_ccmode (insn, CCGOCmode)
11190 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11192 || !TARGET_PARTIAL_FLAG_REG_STALL
11193 || (operands[2] == const1_rtx
11195 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11197 switch (get_attr_type (insn))
11200 gcc_assert (operands[2] == const1_rtx);
11201 return "add{b}\t{%0, %0|%0, %0}";
11204 if (REG_P (operands[2]))
11205 return "sal{b}\t{%b2, %0|%0, %b2}";
11206 else if (operands[2] == const1_rtx
11207 && (TARGET_SHIFT1 || optimize_size))
11208 return "sal{b}\t%0";
11210 return "sal{b}\t{%2, %0|%0, %2}";
11213 [(set (attr "type")
11214 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11216 (match_operand 0 "register_operand" ""))
11217 (match_operand 2 "const1_operand" ""))
11218 (const_string "alu")
11220 (const_string "ishift")))
11221 (set_attr "mode" "QI")])
11223 (define_insn "*ashlqi3_cconly"
11224 [(set (reg FLAGS_REG)
11226 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11227 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11229 (clobber (match_scratch:QI 0 "=q"))]
11230 "ix86_match_ccmode (insn, CCGOCmode)
11231 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11233 || !TARGET_PARTIAL_FLAG_REG_STALL
11234 || (operands[2] == const1_rtx
11236 || TARGET_DOUBLE_WITH_ADD)))"
11238 switch (get_attr_type (insn))
11241 gcc_assert (operands[2] == const1_rtx);
11242 return "add{b}\t{%0, %0|%0, %0}";
11245 if (REG_P (operands[2]))
11246 return "sal{b}\t{%b2, %0|%0, %b2}";
11247 else if (operands[2] == const1_rtx
11248 && (TARGET_SHIFT1 || optimize_size))
11249 return "sal{b}\t%0";
11251 return "sal{b}\t{%2, %0|%0, %2}";
11254 [(set (attr "type")
11255 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11257 (match_operand 0 "register_operand" ""))
11258 (match_operand 2 "const1_operand" ""))
11259 (const_string "alu")
11261 (const_string "ishift")))
11262 (set_attr "mode" "QI")])
11264 ;; See comment above `ashldi3' about how this works.
11266 (define_expand "ashrti3"
11267 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11268 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11269 (match_operand:QI 2 "nonmemory_operand" "")))
11270 (clobber (reg:CC FLAGS_REG))])]
11273 if (! immediate_operand (operands[2], QImode))
11275 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11278 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11282 (define_insn "ashrti3_1"
11283 [(set (match_operand:TI 0 "register_operand" "=r")
11284 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11285 (match_operand:QI 2 "register_operand" "c")))
11286 (clobber (match_scratch:DI 3 "=&r"))
11287 (clobber (reg:CC FLAGS_REG))]
11290 [(set_attr "type" "multi")])
11292 (define_insn "*ashrti3_2"
11293 [(set (match_operand:TI 0 "register_operand" "=r")
11294 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11295 (match_operand:QI 2 "immediate_operand" "O")))
11296 (clobber (reg:CC FLAGS_REG))]
11299 [(set_attr "type" "multi")])
11302 [(set (match_operand:TI 0 "register_operand" "")
11303 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11304 (match_operand:QI 2 "register_operand" "")))
11305 (clobber (match_scratch:DI 3 ""))
11306 (clobber (reg:CC FLAGS_REG))]
11307 "TARGET_64BIT && reload_completed"
11309 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11312 [(set (match_operand:TI 0 "register_operand" "")
11313 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11314 (match_operand:QI 2 "immediate_operand" "")))
11315 (clobber (reg:CC FLAGS_REG))]
11316 "TARGET_64BIT && reload_completed"
11318 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11320 (define_insn "x86_64_shrd"
11321 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11322 (ior:DI (ashiftrt:DI (match_dup 0)
11323 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11324 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11325 (minus:QI (const_int 64) (match_dup 2)))))
11326 (clobber (reg:CC FLAGS_REG))]
11329 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11330 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11331 [(set_attr "type" "ishift")
11332 (set_attr "prefix_0f" "1")
11333 (set_attr "mode" "DI")
11334 (set_attr "athlon_decode" "vector")])
11336 (define_expand "ashrdi3"
11337 [(set (match_operand:DI 0 "shiftdi_operand" "")
11338 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11339 (match_operand:QI 2 "nonmemory_operand" "")))]
11341 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11343 (define_insn "*ashrdi3_63_rex64"
11344 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11345 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11346 (match_operand:DI 2 "const_int_operand" "i,i")))
11347 (clobber (reg:CC FLAGS_REG))]
11348 "TARGET_64BIT && INTVAL (operands[2]) == 63
11349 && (TARGET_USE_CLTD || optimize_size)
11350 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353 sar{q}\t{%2, %0|%0, %2}"
11354 [(set_attr "type" "imovx,ishift")
11355 (set_attr "prefix_0f" "0,*")
11356 (set_attr "length_immediate" "0,*")
11357 (set_attr "modrm" "0,1")
11358 (set_attr "mode" "DI")])
11360 (define_insn "*ashrdi3_1_one_bit_rex64"
11361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11362 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11363 (match_operand:QI 2 "const1_operand" "")))
11364 (clobber (reg:CC FLAGS_REG))]
11365 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11366 && (TARGET_SHIFT1 || optimize_size)"
11368 [(set_attr "type" "ishift")
11369 (set (attr "length")
11370 (if_then_else (match_operand:DI 0 "register_operand" "")
11372 (const_string "*")))])
11374 (define_insn "*ashrdi3_1_rex64"
11375 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11376 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11377 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11378 (clobber (reg:CC FLAGS_REG))]
11379 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11381 sar{q}\t{%2, %0|%0, %2}
11382 sar{q}\t{%b2, %0|%0, %b2}"
11383 [(set_attr "type" "ishift")
11384 (set_attr "mode" "DI")])
11386 ;; This pattern can't accept a variable shift count, since shifts by
11387 ;; zero don't affect the flags. We assume that shifts by constant
11388 ;; zero are optimized away.
11389 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11390 [(set (reg FLAGS_REG)
11392 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11393 (match_operand:QI 2 "const1_operand" ""))
11395 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11396 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11397 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11398 && (TARGET_SHIFT1 || optimize_size)
11399 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11401 [(set_attr "type" "ishift")
11402 (set (attr "length")
11403 (if_then_else (match_operand:DI 0 "register_operand" "")
11405 (const_string "*")))])
11407 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11408 [(set (reg FLAGS_REG)
11410 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11411 (match_operand:QI 2 "const1_operand" ""))
11413 (clobber (match_scratch:DI 0 "=r"))]
11414 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11415 && (TARGET_SHIFT1 || optimize_size)
11416 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11418 [(set_attr "type" "ishift")
11419 (set_attr "length" "2")])
11421 ;; This pattern can't accept a variable shift count, since shifts by
11422 ;; zero don't affect the flags. We assume that shifts by constant
11423 ;; zero are optimized away.
11424 (define_insn "*ashrdi3_cmp_rex64"
11425 [(set (reg FLAGS_REG)
11427 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11428 (match_operand:QI 2 "const_int_operand" "n"))
11430 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11431 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11432 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11433 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11435 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11436 "sar{q}\t{%2, %0|%0, %2}"
11437 [(set_attr "type" "ishift")
11438 (set_attr "mode" "DI")])
11440 (define_insn "*ashrdi3_cconly_rex64"
11441 [(set (reg FLAGS_REG)
11443 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11444 (match_operand:QI 2 "const_int_operand" "n"))
11446 (clobber (match_scratch:DI 0 "=r"))]
11447 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11450 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11451 "sar{q}\t{%2, %0|%0, %2}"
11452 [(set_attr "type" "ishift")
11453 (set_attr "mode" "DI")])
11455 (define_insn "*ashrdi3_1"
11456 [(set (match_operand:DI 0 "register_operand" "=r")
11457 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11458 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11459 (clobber (reg:CC FLAGS_REG))]
11462 [(set_attr "type" "multi")])
11464 ;; By default we don't ask for a scratch register, because when DImode
11465 ;; values are manipulated, registers are already at a premium. But if
11466 ;; we have one handy, we won't turn it away.
11468 [(match_scratch:SI 3 "r")
11469 (parallel [(set (match_operand:DI 0 "register_operand" "")
11470 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11471 (match_operand:QI 2 "nonmemory_operand" "")))
11472 (clobber (reg:CC FLAGS_REG))])
11474 "!TARGET_64BIT && TARGET_CMOVE"
11476 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11479 [(set (match_operand:DI 0 "register_operand" "")
11480 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11481 (match_operand:QI 2 "nonmemory_operand" "")))
11482 (clobber (reg:CC FLAGS_REG))]
11483 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11484 ? flow2_completed : reload_completed)"
11486 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11488 (define_insn "x86_shrd_1"
11489 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11490 (ior:SI (ashiftrt:SI (match_dup 0)
11491 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11492 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11493 (minus:QI (const_int 32) (match_dup 2)))))
11494 (clobber (reg:CC FLAGS_REG))]
11497 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11498 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11499 [(set_attr "type" "ishift")
11500 (set_attr "prefix_0f" "1")
11501 (set_attr "pent_pair" "np")
11502 (set_attr "mode" "SI")])
11504 (define_expand "x86_shift_adj_3"
11505 [(use (match_operand:SI 0 "register_operand" ""))
11506 (use (match_operand:SI 1 "register_operand" ""))
11507 (use (match_operand:QI 2 "register_operand" ""))]
11510 rtx label = gen_label_rtx ();
11513 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11515 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11516 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11517 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11518 gen_rtx_LABEL_REF (VOIDmode, label),
11520 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11521 JUMP_LABEL (tmp) = label;
11523 emit_move_insn (operands[0], operands[1]);
11524 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11526 emit_label (label);
11527 LABEL_NUSES (label) = 1;
11532 (define_insn "ashrsi3_31"
11533 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11534 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11535 (match_operand:SI 2 "const_int_operand" "i,i")))
11536 (clobber (reg:CC FLAGS_REG))]
11537 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11538 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11541 sar{l}\t{%2, %0|%0, %2}"
11542 [(set_attr "type" "imovx,ishift")
11543 (set_attr "prefix_0f" "0,*")
11544 (set_attr "length_immediate" "0,*")
11545 (set_attr "modrm" "0,1")
11546 (set_attr "mode" "SI")])
11548 (define_insn "*ashrsi3_31_zext"
11549 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11550 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11551 (match_operand:SI 2 "const_int_operand" "i,i"))))
11552 (clobber (reg:CC FLAGS_REG))]
11553 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11554 && INTVAL (operands[2]) == 31
11555 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558 sar{l}\t{%2, %k0|%k0, %2}"
11559 [(set_attr "type" "imovx,ishift")
11560 (set_attr "prefix_0f" "0,*")
11561 (set_attr "length_immediate" "0,*")
11562 (set_attr "modrm" "0,1")
11563 (set_attr "mode" "SI")])
11565 (define_expand "ashrsi3"
11566 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11567 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11568 (match_operand:QI 2 "nonmemory_operand" "")))
11569 (clobber (reg:CC FLAGS_REG))]
11571 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11573 (define_insn "*ashrsi3_1_one_bit"
11574 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11575 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11576 (match_operand:QI 2 "const1_operand" "")))
11577 (clobber (reg:CC FLAGS_REG))]
11578 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11579 && (TARGET_SHIFT1 || optimize_size)"
11581 [(set_attr "type" "ishift")
11582 (set (attr "length")
11583 (if_then_else (match_operand:SI 0 "register_operand" "")
11585 (const_string "*")))])
11587 (define_insn "*ashrsi3_1_one_bit_zext"
11588 [(set (match_operand:DI 0 "register_operand" "=r")
11589 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11590 (match_operand:QI 2 "const1_operand" ""))))
11591 (clobber (reg:CC FLAGS_REG))]
11592 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11593 && (TARGET_SHIFT1 || optimize_size)"
11595 [(set_attr "type" "ishift")
11596 (set_attr "length" "2")])
11598 (define_insn "*ashrsi3_1"
11599 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11600 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11601 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11602 (clobber (reg:CC FLAGS_REG))]
11603 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11605 sar{l}\t{%2, %0|%0, %2}
11606 sar{l}\t{%b2, %0|%0, %b2}"
11607 [(set_attr "type" "ishift")
11608 (set_attr "mode" "SI")])
11610 (define_insn "*ashrsi3_1_zext"
11611 [(set (match_operand:DI 0 "register_operand" "=r,r")
11612 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11613 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11614 (clobber (reg:CC FLAGS_REG))]
11615 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11617 sar{l}\t{%2, %k0|%k0, %2}
11618 sar{l}\t{%b2, %k0|%k0, %b2}"
11619 [(set_attr "type" "ishift")
11620 (set_attr "mode" "SI")])
11622 ;; This pattern can't accept a variable shift count, since shifts by
11623 ;; zero don't affect the flags. We assume that shifts by constant
11624 ;; zero are optimized away.
11625 (define_insn "*ashrsi3_one_bit_cmp"
11626 [(set (reg FLAGS_REG)
11628 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11629 (match_operand:QI 2 "const1_operand" ""))
11631 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11632 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11633 "ix86_match_ccmode (insn, CCGOCmode)
11634 && (TARGET_SHIFT1 || optimize_size)
11635 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11637 [(set_attr "type" "ishift")
11638 (set (attr "length")
11639 (if_then_else (match_operand:SI 0 "register_operand" "")
11641 (const_string "*")))])
11643 (define_insn "*ashrsi3_one_bit_cconly"
11644 [(set (reg FLAGS_REG)
11646 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11647 (match_operand:QI 2 "const1_operand" ""))
11649 (clobber (match_scratch:SI 0 "=r"))]
11650 "ix86_match_ccmode (insn, CCGOCmode)
11651 && (TARGET_SHIFT1 || optimize_size)
11652 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11654 [(set_attr "type" "ishift")
11655 (set_attr "length" "2")])
11657 (define_insn "*ashrsi3_one_bit_cmp_zext"
11658 [(set (reg FLAGS_REG)
11660 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11661 (match_operand:QI 2 "const1_operand" ""))
11663 (set (match_operand:DI 0 "register_operand" "=r")
11664 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11665 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11666 && (TARGET_SHIFT1 || optimize_size)
11667 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11669 [(set_attr "type" "ishift")
11670 (set_attr "length" "2")])
11672 ;; This pattern can't accept a variable shift count, since shifts by
11673 ;; zero don't affect the flags. We assume that shifts by constant
11674 ;; zero are optimized away.
11675 (define_insn "*ashrsi3_cmp"
11676 [(set (reg FLAGS_REG)
11678 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11679 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11681 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11682 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11683 "ix86_match_ccmode (insn, CCGOCmode)
11684 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11686 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11687 "sar{l}\t{%2, %0|%0, %2}"
11688 [(set_attr "type" "ishift")
11689 (set_attr "mode" "SI")])
11691 (define_insn "*ashrsi3_cconly"
11692 [(set (reg FLAGS_REG)
11694 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11695 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11697 (clobber (match_scratch:SI 0 "=r"))]
11698 "ix86_match_ccmode (insn, CCGOCmode)
11699 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11701 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11702 "sar{l}\t{%2, %0|%0, %2}"
11703 [(set_attr "type" "ishift")
11704 (set_attr "mode" "SI")])
11706 (define_insn "*ashrsi3_cmp_zext"
11707 [(set (reg FLAGS_REG)
11709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11710 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11712 (set (match_operand:DI 0 "register_operand" "=r")
11713 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11714 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11715 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11717 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11718 "sar{l}\t{%2, %k0|%k0, %2}"
11719 [(set_attr "type" "ishift")
11720 (set_attr "mode" "SI")])
11722 (define_expand "ashrhi3"
11723 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11724 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11725 (match_operand:QI 2 "nonmemory_operand" "")))
11726 (clobber (reg:CC FLAGS_REG))]
11727 "TARGET_HIMODE_MATH"
11728 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11730 (define_insn "*ashrhi3_1_one_bit"
11731 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11732 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11733 (match_operand:QI 2 "const1_operand" "")))
11734 (clobber (reg:CC FLAGS_REG))]
11735 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11736 && (TARGET_SHIFT1 || optimize_size)"
11738 [(set_attr "type" "ishift")
11739 (set (attr "length")
11740 (if_then_else (match_operand 0 "register_operand" "")
11742 (const_string "*")))])
11744 (define_insn "*ashrhi3_1"
11745 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11746 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11747 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11748 (clobber (reg:CC FLAGS_REG))]
11749 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11751 sar{w}\t{%2, %0|%0, %2}
11752 sar{w}\t{%b2, %0|%0, %b2}"
11753 [(set_attr "type" "ishift")
11754 (set_attr "mode" "HI")])
11756 ;; This pattern can't accept a variable shift count, since shifts by
11757 ;; zero don't affect the flags. We assume that shifts by constant
11758 ;; zero are optimized away.
11759 (define_insn "*ashrhi3_one_bit_cmp"
11760 [(set (reg FLAGS_REG)
11762 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11763 (match_operand:QI 2 "const1_operand" ""))
11765 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11766 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11767 "ix86_match_ccmode (insn, CCGOCmode)
11768 && (TARGET_SHIFT1 || optimize_size)
11769 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11771 [(set_attr "type" "ishift")
11772 (set (attr "length")
11773 (if_then_else (match_operand 0 "register_operand" "")
11775 (const_string "*")))])
11777 (define_insn "*ashrhi3_one_bit_cconly"
11778 [(set (reg FLAGS_REG)
11780 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11781 (match_operand:QI 2 "const1_operand" ""))
11783 (clobber (match_scratch:HI 0 "=r"))]
11784 "ix86_match_ccmode (insn, CCGOCmode)
11785 && (TARGET_SHIFT1 || optimize_size)
11786 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11788 [(set_attr "type" "ishift")
11789 (set_attr "length" "2")])
11791 ;; This pattern can't accept a variable shift count, since shifts by
11792 ;; zero don't affect the flags. We assume that shifts by constant
11793 ;; zero are optimized away.
11794 (define_insn "*ashrhi3_cmp"
11795 [(set (reg FLAGS_REG)
11797 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11798 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11800 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11801 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11802 "ix86_match_ccmode (insn, CCGOCmode)
11803 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11805 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11806 "sar{w}\t{%2, %0|%0, %2}"
11807 [(set_attr "type" "ishift")
11808 (set_attr "mode" "HI")])
11810 (define_insn "*ashrhi3_cconly"
11811 [(set (reg FLAGS_REG)
11813 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11814 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11816 (clobber (match_scratch:HI 0 "=r"))]
11817 "ix86_match_ccmode (insn, CCGOCmode)
11818 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11820 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11821 "sar{w}\t{%2, %0|%0, %2}"
11822 [(set_attr "type" "ishift")
11823 (set_attr "mode" "HI")])
11825 (define_expand "ashrqi3"
11826 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11827 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11828 (match_operand:QI 2 "nonmemory_operand" "")))
11829 (clobber (reg:CC FLAGS_REG))]
11830 "TARGET_QIMODE_MATH"
11831 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11833 (define_insn "*ashrqi3_1_one_bit"
11834 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11835 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11836 (match_operand:QI 2 "const1_operand" "")))
11837 (clobber (reg:CC FLAGS_REG))]
11838 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11839 && (TARGET_SHIFT1 || optimize_size)"
11841 [(set_attr "type" "ishift")
11842 (set (attr "length")
11843 (if_then_else (match_operand 0 "register_operand" "")
11845 (const_string "*")))])
11847 (define_insn "*ashrqi3_1_one_bit_slp"
11848 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11849 (ashiftrt:QI (match_dup 0)
11850 (match_operand:QI 1 "const1_operand" "")))
11851 (clobber (reg:CC FLAGS_REG))]
11852 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11853 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11854 && (TARGET_SHIFT1 || optimize_size)"
11856 [(set_attr "type" "ishift1")
11857 (set (attr "length")
11858 (if_then_else (match_operand 0 "register_operand" "")
11860 (const_string "*")))])
11862 (define_insn "*ashrqi3_1"
11863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11864 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11865 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11866 (clobber (reg:CC FLAGS_REG))]
11867 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11869 sar{b}\t{%2, %0|%0, %2}
11870 sar{b}\t{%b2, %0|%0, %b2}"
11871 [(set_attr "type" "ishift")
11872 (set_attr "mode" "QI")])
11874 (define_insn "*ashrqi3_1_slp"
11875 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11876 (ashiftrt:QI (match_dup 0)
11877 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11878 (clobber (reg:CC FLAGS_REG))]
11879 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11880 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11882 sar{b}\t{%1, %0|%0, %1}
11883 sar{b}\t{%b1, %0|%0, %b1}"
11884 [(set_attr "type" "ishift1")
11885 (set_attr "mode" "QI")])
11887 ;; This pattern can't accept a variable shift count, since shifts by
11888 ;; zero don't affect the flags. We assume that shifts by constant
11889 ;; zero are optimized away.
11890 (define_insn "*ashrqi3_one_bit_cmp"
11891 [(set (reg FLAGS_REG)
11893 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11894 (match_operand:QI 2 "const1_operand" "I"))
11896 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11897 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11898 "ix86_match_ccmode (insn, CCGOCmode)
11899 && (TARGET_SHIFT1 || optimize_size)
11900 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11902 [(set_attr "type" "ishift")
11903 (set (attr "length")
11904 (if_then_else (match_operand 0 "register_operand" "")
11906 (const_string "*")))])
11908 (define_insn "*ashrqi3_one_bit_cconly"
11909 [(set (reg FLAGS_REG)
11911 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11912 (match_operand:QI 2 "const1_operand" "I"))
11914 (clobber (match_scratch:QI 0 "=q"))]
11915 "ix86_match_ccmode (insn, CCGOCmode)
11916 && (TARGET_SHIFT1 || optimize_size)
11917 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11919 [(set_attr "type" "ishift")
11920 (set_attr "length" "2")])
11922 ;; This pattern can't accept a variable shift count, since shifts by
11923 ;; zero don't affect the flags. We assume that shifts by constant
11924 ;; zero are optimized away.
11925 (define_insn "*ashrqi3_cmp"
11926 [(set (reg FLAGS_REG)
11928 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11929 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11931 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11932 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11933 "ix86_match_ccmode (insn, CCGOCmode)
11934 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11936 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11937 "sar{b}\t{%2, %0|%0, %2}"
11938 [(set_attr "type" "ishift")
11939 (set_attr "mode" "QI")])
11941 (define_insn "*ashrqi3_cconly"
11942 [(set (reg FLAGS_REG)
11944 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11945 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11947 (clobber (match_scratch:QI 0 "=q"))]
11948 "ix86_match_ccmode (insn, CCGOCmode)
11949 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11951 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11952 "sar{b}\t{%2, %0|%0, %2}"
11953 [(set_attr "type" "ishift")
11954 (set_attr "mode" "QI")])
11957 ;; Logical shift instructions
11959 ;; See comment above `ashldi3' about how this works.
11961 (define_expand "lshrti3"
11962 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11963 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11964 (match_operand:QI 2 "nonmemory_operand" "")))
11965 (clobber (reg:CC FLAGS_REG))])]
11968 if (! immediate_operand (operands[2], QImode))
11970 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11973 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11977 (define_insn "lshrti3_1"
11978 [(set (match_operand:TI 0 "register_operand" "=r")
11979 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11980 (match_operand:QI 2 "register_operand" "c")))
11981 (clobber (match_scratch:DI 3 "=&r"))
11982 (clobber (reg:CC FLAGS_REG))]
11985 [(set_attr "type" "multi")])
11987 (define_insn "*lshrti3_2"
11988 [(set (match_operand:TI 0 "register_operand" "=r")
11989 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11990 (match_operand:QI 2 "immediate_operand" "O")))
11991 (clobber (reg:CC FLAGS_REG))]
11994 [(set_attr "type" "multi")])
11997 [(set (match_operand:TI 0 "register_operand" "")
11998 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11999 (match_operand:QI 2 "register_operand" "")))
12000 (clobber (match_scratch:DI 3 ""))
12001 (clobber (reg:CC FLAGS_REG))]
12002 "TARGET_64BIT && reload_completed"
12004 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12007 [(set (match_operand:TI 0 "register_operand" "")
12008 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12009 (match_operand:QI 2 "immediate_operand" "")))
12010 (clobber (reg:CC FLAGS_REG))]
12011 "TARGET_64BIT && reload_completed"
12013 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12015 (define_expand "lshrdi3"
12016 [(set (match_operand:DI 0 "shiftdi_operand" "")
12017 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12018 (match_operand:QI 2 "nonmemory_operand" "")))]
12020 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12022 (define_insn "*lshrdi3_1_one_bit_rex64"
12023 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12024 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12025 (match_operand:QI 2 "const1_operand" "")))
12026 (clobber (reg:CC FLAGS_REG))]
12027 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12028 && (TARGET_SHIFT1 || optimize_size)"
12030 [(set_attr "type" "ishift")
12031 (set (attr "length")
12032 (if_then_else (match_operand:DI 0 "register_operand" "")
12034 (const_string "*")))])
12036 (define_insn "*lshrdi3_1_rex64"
12037 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12038 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12039 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12040 (clobber (reg:CC FLAGS_REG))]
12041 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12043 shr{q}\t{%2, %0|%0, %2}
12044 shr{q}\t{%b2, %0|%0, %b2}"
12045 [(set_attr "type" "ishift")
12046 (set_attr "mode" "DI")])
12048 ;; This pattern can't accept a variable shift count, since shifts by
12049 ;; zero don't affect the flags. We assume that shifts by constant
12050 ;; zero are optimized away.
12051 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12052 [(set (reg FLAGS_REG)
12054 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12055 (match_operand:QI 2 "const1_operand" ""))
12057 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12058 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12059 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12060 && (TARGET_SHIFT1 || optimize_size)
12061 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12063 [(set_attr "type" "ishift")
12064 (set (attr "length")
12065 (if_then_else (match_operand:DI 0 "register_operand" "")
12067 (const_string "*")))])
12069 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12070 [(set (reg FLAGS_REG)
12072 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12073 (match_operand:QI 2 "const1_operand" ""))
12075 (clobber (match_scratch:DI 0 "=r"))]
12076 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12077 && (TARGET_SHIFT1 || optimize_size)
12078 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12080 [(set_attr "type" "ishift")
12081 (set_attr "length" "2")])
12083 ;; This pattern can't accept a variable shift count, since shifts by
12084 ;; zero don't affect the flags. We assume that shifts by constant
12085 ;; zero are optimized away.
12086 (define_insn "*lshrdi3_cmp_rex64"
12087 [(set (reg FLAGS_REG)
12089 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12090 (match_operand:QI 2 "const_int_operand" "e"))
12092 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12093 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12094 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12095 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12097 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12098 "shr{q}\t{%2, %0|%0, %2}"
12099 [(set_attr "type" "ishift")
12100 (set_attr "mode" "DI")])
12102 (define_insn "*lshrdi3_cconly_rex64"
12103 [(set (reg FLAGS_REG)
12105 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12106 (match_operand:QI 2 "const_int_operand" "e"))
12108 (clobber (match_scratch:DI 0 "=r"))]
12109 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12110 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12112 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12113 "shr{q}\t{%2, %0|%0, %2}"
12114 [(set_attr "type" "ishift")
12115 (set_attr "mode" "DI")])
12117 (define_insn "*lshrdi3_1"
12118 [(set (match_operand:DI 0 "register_operand" "=r")
12119 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12120 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12121 (clobber (reg:CC FLAGS_REG))]
12124 [(set_attr "type" "multi")])
12126 ;; By default we don't ask for a scratch register, because when DImode
12127 ;; values are manipulated, registers are already at a premium. But if
12128 ;; we have one handy, we won't turn it away.
12130 [(match_scratch:SI 3 "r")
12131 (parallel [(set (match_operand:DI 0 "register_operand" "")
12132 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12133 (match_operand:QI 2 "nonmemory_operand" "")))
12134 (clobber (reg:CC FLAGS_REG))])
12136 "!TARGET_64BIT && TARGET_CMOVE"
12138 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12141 [(set (match_operand:DI 0 "register_operand" "")
12142 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12143 (match_operand:QI 2 "nonmemory_operand" "")))
12144 (clobber (reg:CC FLAGS_REG))]
12145 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12146 ? flow2_completed : reload_completed)"
12148 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12150 (define_expand "lshrsi3"
12151 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12152 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12153 (match_operand:QI 2 "nonmemory_operand" "")))
12154 (clobber (reg:CC FLAGS_REG))]
12156 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12158 (define_insn "*lshrsi3_1_one_bit"
12159 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12160 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12161 (match_operand:QI 2 "const1_operand" "")))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12164 && (TARGET_SHIFT1 || optimize_size)"
12166 [(set_attr "type" "ishift")
12167 (set (attr "length")
12168 (if_then_else (match_operand:SI 0 "register_operand" "")
12170 (const_string "*")))])
12172 (define_insn "*lshrsi3_1_one_bit_zext"
12173 [(set (match_operand:DI 0 "register_operand" "=r")
12174 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12175 (match_operand:QI 2 "const1_operand" "")))
12176 (clobber (reg:CC FLAGS_REG))]
12177 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12178 && (TARGET_SHIFT1 || optimize_size)"
12180 [(set_attr "type" "ishift")
12181 (set_attr "length" "2")])
12183 (define_insn "*lshrsi3_1"
12184 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
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 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12190 shr{l}\t{%2, %0|%0, %2}
12191 shr{l}\t{%b2, %0|%0, %b2}"
12192 [(set_attr "type" "ishift")
12193 (set_attr "mode" "SI")])
12195 (define_insn "*lshrsi3_1_zext"
12196 [(set (match_operand:DI 0 "register_operand" "=r,r")
12198 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12199 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12203 shr{l}\t{%2, %k0|%k0, %2}
12204 shr{l}\t{%b2, %k0|%k0, %b2}"
12205 [(set_attr "type" "ishift")
12206 (set_attr "mode" "SI")])
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags. We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*lshrsi3_one_bit_cmp"
12212 [(set (reg FLAGS_REG)
12214 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12215 (match_operand:QI 2 "const1_operand" ""))
12217 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12218 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12219 "ix86_match_ccmode (insn, CCGOCmode)
12220 && (TARGET_SHIFT1 || optimize_size)
12221 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12223 [(set_attr "type" "ishift")
12224 (set (attr "length")
12225 (if_then_else (match_operand:SI 0 "register_operand" "")
12227 (const_string "*")))])
12229 (define_insn "*lshrsi3_one_bit_cconly"
12230 [(set (reg FLAGS_REG)
12232 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12233 (match_operand:QI 2 "const1_operand" ""))
12235 (clobber (match_scratch:SI 0 "=r"))]
12236 "ix86_match_ccmode (insn, CCGOCmode)
12237 && (TARGET_SHIFT1 || optimize_size)
12238 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12240 [(set_attr "type" "ishift")
12241 (set_attr "length" "2")])
12243 (define_insn "*lshrsi3_cmp_one_bit_zext"
12244 [(set (reg FLAGS_REG)
12246 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12247 (match_operand:QI 2 "const1_operand" ""))
12249 (set (match_operand:DI 0 "register_operand" "=r")
12250 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12251 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12252 && (TARGET_SHIFT1 || optimize_size)
12253 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12255 [(set_attr "type" "ishift")
12256 (set_attr "length" "2")])
12258 ;; This pattern can't accept a variable shift count, since shifts by
12259 ;; zero don't affect the flags. We assume that shifts by constant
12260 ;; zero are optimized away.
12261 (define_insn "*lshrsi3_cmp"
12262 [(set (reg FLAGS_REG)
12264 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12265 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12267 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12268 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12269 "ix86_match_ccmode (insn, CCGOCmode)
12270 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12272 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12273 "shr{l}\t{%2, %0|%0, %2}"
12274 [(set_attr "type" "ishift")
12275 (set_attr "mode" "SI")])
12277 (define_insn "*lshrsi3_cconly"
12278 [(set (reg FLAGS_REG)
12280 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12281 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12283 (clobber (match_scratch:SI 0 "=r"))]
12284 "ix86_match_ccmode (insn, CCGOCmode)
12285 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12287 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12288 "shr{l}\t{%2, %0|%0, %2}"
12289 [(set_attr "type" "ishift")
12290 (set_attr "mode" "SI")])
12292 (define_insn "*lshrsi3_cmp_zext"
12293 [(set (reg FLAGS_REG)
12295 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12298 (set (match_operand:DI 0 "register_operand" "=r")
12299 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12300 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12301 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12303 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12304 "shr{l}\t{%2, %k0|%k0, %2}"
12305 [(set_attr "type" "ishift")
12306 (set_attr "mode" "SI")])
12308 (define_expand "lshrhi3"
12309 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12310 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12311 (match_operand:QI 2 "nonmemory_operand" "")))
12312 (clobber (reg:CC FLAGS_REG))]
12313 "TARGET_HIMODE_MATH"
12314 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12316 (define_insn "*lshrhi3_1_one_bit"
12317 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12318 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12319 (match_operand:QI 2 "const1_operand" "")))
12320 (clobber (reg:CC FLAGS_REG))]
12321 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12322 && (TARGET_SHIFT1 || optimize_size)"
12324 [(set_attr "type" "ishift")
12325 (set (attr "length")
12326 (if_then_else (match_operand 0 "register_operand" "")
12328 (const_string "*")))])
12330 (define_insn "*lshrhi3_1"
12331 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12332 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12333 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12334 (clobber (reg:CC FLAGS_REG))]
12335 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12337 shr{w}\t{%2, %0|%0, %2}
12338 shr{w}\t{%b2, %0|%0, %b2}"
12339 [(set_attr "type" "ishift")
12340 (set_attr "mode" "HI")])
12342 ;; This pattern can't accept a variable shift count, since shifts by
12343 ;; zero don't affect the flags. We assume that shifts by constant
12344 ;; zero are optimized away.
12345 (define_insn "*lshrhi3_one_bit_cmp"
12346 [(set (reg FLAGS_REG)
12348 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12349 (match_operand:QI 2 "const1_operand" ""))
12351 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12352 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12353 "ix86_match_ccmode (insn, CCGOCmode)
12354 && (TARGET_SHIFT1 || optimize_size)
12355 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12357 [(set_attr "type" "ishift")
12358 (set (attr "length")
12359 (if_then_else (match_operand:SI 0 "register_operand" "")
12361 (const_string "*")))])
12363 (define_insn "*lshrhi3_one_bit_cconly"
12364 [(set (reg FLAGS_REG)
12366 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12367 (match_operand:QI 2 "const1_operand" ""))
12369 (clobber (match_scratch:HI 0 "=r"))]
12370 "ix86_match_ccmode (insn, CCGOCmode)
12371 && (TARGET_SHIFT1 || optimize_size)
12372 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12374 [(set_attr "type" "ishift")
12375 (set_attr "length" "2")])
12377 ;; This pattern can't accept a variable shift count, since shifts by
12378 ;; zero don't affect the flags. We assume that shifts by constant
12379 ;; zero are optimized away.
12380 (define_insn "*lshrhi3_cmp"
12381 [(set (reg FLAGS_REG)
12383 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12386 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12387 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12388 "ix86_match_ccmode (insn, CCGOCmode)
12389 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12391 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12392 "shr{w}\t{%2, %0|%0, %2}"
12393 [(set_attr "type" "ishift")
12394 (set_attr "mode" "HI")])
12396 (define_insn "*lshrhi3_cconly"
12397 [(set (reg FLAGS_REG)
12399 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12400 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12402 (clobber (match_scratch:HI 0 "=r"))]
12403 "ix86_match_ccmode (insn, CCGOCmode)
12404 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12406 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12407 "shr{w}\t{%2, %0|%0, %2}"
12408 [(set_attr "type" "ishift")
12409 (set_attr "mode" "HI")])
12411 (define_expand "lshrqi3"
12412 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12413 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12414 (match_operand:QI 2 "nonmemory_operand" "")))
12415 (clobber (reg:CC FLAGS_REG))]
12416 "TARGET_QIMODE_MATH"
12417 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12419 (define_insn "*lshrqi3_1_one_bit"
12420 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12421 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12422 (match_operand:QI 2 "const1_operand" "")))
12423 (clobber (reg:CC FLAGS_REG))]
12424 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12425 && (TARGET_SHIFT1 || optimize_size)"
12427 [(set_attr "type" "ishift")
12428 (set (attr "length")
12429 (if_then_else (match_operand 0 "register_operand" "")
12431 (const_string "*")))])
12433 (define_insn "*lshrqi3_1_one_bit_slp"
12434 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12435 (lshiftrt:QI (match_dup 0)
12436 (match_operand:QI 1 "const1_operand" "")))
12437 (clobber (reg:CC FLAGS_REG))]
12438 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12439 && (TARGET_SHIFT1 || optimize_size)"
12441 [(set_attr "type" "ishift1")
12442 (set (attr "length")
12443 (if_then_else (match_operand 0 "register_operand" "")
12445 (const_string "*")))])
12447 (define_insn "*lshrqi3_1"
12448 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12449 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12450 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12451 (clobber (reg:CC FLAGS_REG))]
12452 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12454 shr{b}\t{%2, %0|%0, %2}
12455 shr{b}\t{%b2, %0|%0, %b2}"
12456 [(set_attr "type" "ishift")
12457 (set_attr "mode" "QI")])
12459 (define_insn "*lshrqi3_1_slp"
12460 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12461 (lshiftrt:QI (match_dup 0)
12462 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12463 (clobber (reg:CC FLAGS_REG))]
12464 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12465 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12467 shr{b}\t{%1, %0|%0, %1}
12468 shr{b}\t{%b1, %0|%0, %b1}"
12469 [(set_attr "type" "ishift1")
12470 (set_attr "mode" "QI")])
12472 ;; This pattern can't accept a variable shift count, since shifts by
12473 ;; zero don't affect the flags. We assume that shifts by constant
12474 ;; zero are optimized away.
12475 (define_insn "*lshrqi2_one_bit_cmp"
12476 [(set (reg FLAGS_REG)
12478 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12479 (match_operand:QI 2 "const1_operand" ""))
12481 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12482 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12483 "ix86_match_ccmode (insn, CCGOCmode)
12484 && (TARGET_SHIFT1 || optimize_size)
12485 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12487 [(set_attr "type" "ishift")
12488 (set (attr "length")
12489 (if_then_else (match_operand:SI 0 "register_operand" "")
12491 (const_string "*")))])
12493 (define_insn "*lshrqi2_one_bit_cconly"
12494 [(set (reg FLAGS_REG)
12496 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12497 (match_operand:QI 2 "const1_operand" ""))
12499 (clobber (match_scratch:QI 0 "=q"))]
12500 "ix86_match_ccmode (insn, CCGOCmode)
12501 && (TARGET_SHIFT1 || optimize_size)
12502 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12504 [(set_attr "type" "ishift")
12505 (set_attr "length" "2")])
12507 ;; This pattern can't accept a variable shift count, since shifts by
12508 ;; zero don't affect the flags. We assume that shifts by constant
12509 ;; zero are optimized away.
12510 (define_insn "*lshrqi2_cmp"
12511 [(set (reg FLAGS_REG)
12513 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12514 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12516 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12517 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12518 "ix86_match_ccmode (insn, CCGOCmode)
12519 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12521 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12522 "shr{b}\t{%2, %0|%0, %2}"
12523 [(set_attr "type" "ishift")
12524 (set_attr "mode" "QI")])
12526 (define_insn "*lshrqi2_cconly"
12527 [(set (reg FLAGS_REG)
12529 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12530 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12532 (clobber (match_scratch:QI 0 "=q"))]
12533 "ix86_match_ccmode (insn, CCGOCmode)
12534 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12536 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12537 "shr{b}\t{%2, %0|%0, %2}"
12538 [(set_attr "type" "ishift")
12539 (set_attr "mode" "QI")])
12541 ;; Rotate instructions
12543 (define_expand "rotldi3"
12544 [(set (match_operand:DI 0 "shiftdi_operand" "")
12545 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12546 (match_operand:QI 2 "nonmemory_operand" "")))
12547 (clobber (reg:CC FLAGS_REG))]
12552 ix86_expand_binary_operator (ROTATE, DImode, operands);
12555 if (!const_1_to_31_operand (operands[2], VOIDmode))
12557 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12561 ;; Implement rotation using two double-precision shift instructions
12562 ;; and a scratch register.
12563 (define_insn_and_split "ix86_rotldi3"
12564 [(set (match_operand:DI 0 "register_operand" "=r")
12565 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12566 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12567 (clobber (reg:CC FLAGS_REG))
12568 (clobber (match_scratch:SI 3 "=&r"))]
12571 "&& reload_completed"
12572 [(set (match_dup 3) (match_dup 4))
12574 [(set (match_dup 4)
12575 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12576 (lshiftrt:SI (match_dup 5)
12577 (minus:QI (const_int 32) (match_dup 2)))))
12578 (clobber (reg:CC FLAGS_REG))])
12580 [(set (match_dup 5)
12581 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12582 (lshiftrt:SI (match_dup 3)
12583 (minus:QI (const_int 32) (match_dup 2)))))
12584 (clobber (reg:CC FLAGS_REG))])]
12585 "split_di (operands, 1, operands + 4, operands + 5);")
12587 (define_insn "*rotlsi3_1_one_bit_rex64"
12588 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12589 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12590 (match_operand:QI 2 "const1_operand" "")))
12591 (clobber (reg:CC FLAGS_REG))]
12592 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12593 && (TARGET_SHIFT1 || optimize_size)"
12595 [(set_attr "type" "rotate")
12596 (set (attr "length")
12597 (if_then_else (match_operand:DI 0 "register_operand" "")
12599 (const_string "*")))])
12601 (define_insn "*rotldi3_1_rex64"
12602 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12603 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12604 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12605 (clobber (reg:CC FLAGS_REG))]
12606 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12608 rol{q}\t{%2, %0|%0, %2}
12609 rol{q}\t{%b2, %0|%0, %b2}"
12610 [(set_attr "type" "rotate")
12611 (set_attr "mode" "DI")])
12613 (define_expand "rotlsi3"
12614 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12615 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12616 (match_operand:QI 2 "nonmemory_operand" "")))
12617 (clobber (reg:CC FLAGS_REG))]
12619 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12621 (define_insn "*rotlsi3_1_one_bit"
12622 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12623 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12624 (match_operand:QI 2 "const1_operand" "")))
12625 (clobber (reg:CC FLAGS_REG))]
12626 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12627 && (TARGET_SHIFT1 || optimize_size)"
12629 [(set_attr "type" "rotate")
12630 (set (attr "length")
12631 (if_then_else (match_operand:SI 0 "register_operand" "")
12633 (const_string "*")))])
12635 (define_insn "*rotlsi3_1_one_bit_zext"
12636 [(set (match_operand:DI 0 "register_operand" "=r")
12638 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12639 (match_operand:QI 2 "const1_operand" ""))))
12640 (clobber (reg:CC FLAGS_REG))]
12641 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12642 && (TARGET_SHIFT1 || optimize_size)"
12644 [(set_attr "type" "rotate")
12645 (set_attr "length" "2")])
12647 (define_insn "*rotlsi3_1"
12648 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12649 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12650 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12651 (clobber (reg:CC FLAGS_REG))]
12652 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12654 rol{l}\t{%2, %0|%0, %2}
12655 rol{l}\t{%b2, %0|%0, %b2}"
12656 [(set_attr "type" "rotate")
12657 (set_attr "mode" "SI")])
12659 (define_insn "*rotlsi3_1_zext"
12660 [(set (match_operand:DI 0 "register_operand" "=r,r")
12662 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12663 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12664 (clobber (reg:CC FLAGS_REG))]
12665 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12667 rol{l}\t{%2, %k0|%k0, %2}
12668 rol{l}\t{%b2, %k0|%k0, %b2}"
12669 [(set_attr "type" "rotate")
12670 (set_attr "mode" "SI")])
12672 (define_expand "rotlhi3"
12673 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12674 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12675 (match_operand:QI 2 "nonmemory_operand" "")))
12676 (clobber (reg:CC FLAGS_REG))]
12677 "TARGET_HIMODE_MATH"
12678 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12680 (define_insn "*rotlhi3_1_one_bit"
12681 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12682 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12683 (match_operand:QI 2 "const1_operand" "")))
12684 (clobber (reg:CC FLAGS_REG))]
12685 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12686 && (TARGET_SHIFT1 || optimize_size)"
12688 [(set_attr "type" "rotate")
12689 (set (attr "length")
12690 (if_then_else (match_operand 0 "register_operand" "")
12692 (const_string "*")))])
12694 (define_insn "*rotlhi3_1"
12695 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12696 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12697 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12698 (clobber (reg:CC FLAGS_REG))]
12699 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12701 rol{w}\t{%2, %0|%0, %2}
12702 rol{w}\t{%b2, %0|%0, %b2}"
12703 [(set_attr "type" "rotate")
12704 (set_attr "mode" "HI")])
12706 (define_expand "rotlqi3"
12707 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12708 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12709 (match_operand:QI 2 "nonmemory_operand" "")))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "TARGET_QIMODE_MATH"
12712 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12714 (define_insn "*rotlqi3_1_one_bit_slp"
12715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12716 (rotate:QI (match_dup 0)
12717 (match_operand:QI 1 "const1_operand" "")))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12720 && (TARGET_SHIFT1 || optimize_size)"
12722 [(set_attr "type" "rotate1")
12723 (set (attr "length")
12724 (if_then_else (match_operand 0 "register_operand" "")
12726 (const_string "*")))])
12728 (define_insn "*rotlqi3_1_one_bit"
12729 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12730 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12731 (match_operand:QI 2 "const1_operand" "")))
12732 (clobber (reg:CC FLAGS_REG))]
12733 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12734 && (TARGET_SHIFT1 || optimize_size)"
12736 [(set_attr "type" "rotate")
12737 (set (attr "length")
12738 (if_then_else (match_operand 0 "register_operand" "")
12740 (const_string "*")))])
12742 (define_insn "*rotlqi3_1_slp"
12743 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12744 (rotate:QI (match_dup 0)
12745 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12746 (clobber (reg:CC FLAGS_REG))]
12747 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12748 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12750 rol{b}\t{%1, %0|%0, %1}
12751 rol{b}\t{%b1, %0|%0, %b1}"
12752 [(set_attr "type" "rotate1")
12753 (set_attr "mode" "QI")])
12755 (define_insn "*rotlqi3_1"
12756 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12757 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12758 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12762 rol{b}\t{%2, %0|%0, %2}
12763 rol{b}\t{%b2, %0|%0, %b2}"
12764 [(set_attr "type" "rotate")
12765 (set_attr "mode" "QI")])
12767 (define_expand "rotrdi3"
12768 [(set (match_operand:DI 0 "shiftdi_operand" "")
12769 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12770 (match_operand:QI 2 "nonmemory_operand" "")))
12771 (clobber (reg:CC FLAGS_REG))]
12776 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12779 if (!const_1_to_31_operand (operands[2], VOIDmode))
12781 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12785 ;; Implement rotation using two double-precision shift instructions
12786 ;; and a scratch register.
12787 (define_insn_and_split "ix86_rotrdi3"
12788 [(set (match_operand:DI 0 "register_operand" "=r")
12789 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12790 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12791 (clobber (reg:CC FLAGS_REG))
12792 (clobber (match_scratch:SI 3 "=&r"))]
12795 "&& reload_completed"
12796 [(set (match_dup 3) (match_dup 4))
12798 [(set (match_dup 4)
12799 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12800 (ashift:SI (match_dup 5)
12801 (minus:QI (const_int 32) (match_dup 2)))))
12802 (clobber (reg:CC FLAGS_REG))])
12804 [(set (match_dup 5)
12805 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12806 (ashift:SI (match_dup 3)
12807 (minus:QI (const_int 32) (match_dup 2)))))
12808 (clobber (reg:CC FLAGS_REG))])]
12809 "split_di (operands, 1, operands + 4, operands + 5);")
12811 (define_insn "*rotrdi3_1_one_bit_rex64"
12812 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12813 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12814 (match_operand:QI 2 "const1_operand" "")))
12815 (clobber (reg:CC FLAGS_REG))]
12816 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12817 && (TARGET_SHIFT1 || optimize_size)"
12819 [(set_attr "type" "rotate")
12820 (set (attr "length")
12821 (if_then_else (match_operand:DI 0 "register_operand" "")
12823 (const_string "*")))])
12825 (define_insn "*rotrdi3_1_rex64"
12826 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12827 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12828 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12829 (clobber (reg:CC FLAGS_REG))]
12830 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12832 ror{q}\t{%2, %0|%0, %2}
12833 ror{q}\t{%b2, %0|%0, %b2}"
12834 [(set_attr "type" "rotate")
12835 (set_attr "mode" "DI")])
12837 (define_expand "rotrsi3"
12838 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12839 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12840 (match_operand:QI 2 "nonmemory_operand" "")))
12841 (clobber (reg:CC FLAGS_REG))]
12843 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12845 (define_insn "*rotrsi3_1_one_bit"
12846 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12847 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12848 (match_operand:QI 2 "const1_operand" "")))
12849 (clobber (reg:CC FLAGS_REG))]
12850 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12851 && (TARGET_SHIFT1 || optimize_size)"
12853 [(set_attr "type" "rotate")
12854 (set (attr "length")
12855 (if_then_else (match_operand:SI 0 "register_operand" "")
12857 (const_string "*")))])
12859 (define_insn "*rotrsi3_1_one_bit_zext"
12860 [(set (match_operand:DI 0 "register_operand" "=r")
12862 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12863 (match_operand:QI 2 "const1_operand" ""))))
12864 (clobber (reg:CC FLAGS_REG))]
12865 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12866 && (TARGET_SHIFT1 || optimize_size)"
12868 [(set_attr "type" "rotate")
12869 (set (attr "length")
12870 (if_then_else (match_operand:SI 0 "register_operand" "")
12872 (const_string "*")))])
12874 (define_insn "*rotrsi3_1"
12875 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12876 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12877 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12881 ror{l}\t{%2, %0|%0, %2}
12882 ror{l}\t{%b2, %0|%0, %b2}"
12883 [(set_attr "type" "rotate")
12884 (set_attr "mode" "SI")])
12886 (define_insn "*rotrsi3_1_zext"
12887 [(set (match_operand:DI 0 "register_operand" "=r,r")
12889 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12890 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12891 (clobber (reg:CC FLAGS_REG))]
12892 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12894 ror{l}\t{%2, %k0|%k0, %2}
12895 ror{l}\t{%b2, %k0|%k0, %b2}"
12896 [(set_attr "type" "rotate")
12897 (set_attr "mode" "SI")])
12899 (define_expand "rotrhi3"
12900 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12901 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12902 (match_operand:QI 2 "nonmemory_operand" "")))
12903 (clobber (reg:CC FLAGS_REG))]
12904 "TARGET_HIMODE_MATH"
12905 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12907 (define_insn "*rotrhi3_one_bit"
12908 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12909 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12910 (match_operand:QI 2 "const1_operand" "")))
12911 (clobber (reg:CC FLAGS_REG))]
12912 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12913 && (TARGET_SHIFT1 || optimize_size)"
12915 [(set_attr "type" "rotate")
12916 (set (attr "length")
12917 (if_then_else (match_operand 0 "register_operand" "")
12919 (const_string "*")))])
12921 (define_insn "*rotrhi3"
12922 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12923 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12924 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12925 (clobber (reg:CC FLAGS_REG))]
12926 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12928 ror{w}\t{%2, %0|%0, %2}
12929 ror{w}\t{%b2, %0|%0, %b2}"
12930 [(set_attr "type" "rotate")
12931 (set_attr "mode" "HI")])
12933 (define_expand "rotrqi3"
12934 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12935 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12936 (match_operand:QI 2 "nonmemory_operand" "")))
12937 (clobber (reg:CC FLAGS_REG))]
12938 "TARGET_QIMODE_MATH"
12939 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12941 (define_insn "*rotrqi3_1_one_bit"
12942 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12943 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12944 (match_operand:QI 2 "const1_operand" "")))
12945 (clobber (reg:CC FLAGS_REG))]
12946 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12947 && (TARGET_SHIFT1 || optimize_size)"
12949 [(set_attr "type" "rotate")
12950 (set (attr "length")
12951 (if_then_else (match_operand 0 "register_operand" "")
12953 (const_string "*")))])
12955 (define_insn "*rotrqi3_1_one_bit_slp"
12956 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12957 (rotatert:QI (match_dup 0)
12958 (match_operand:QI 1 "const1_operand" "")))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12961 && (TARGET_SHIFT1 || optimize_size)"
12963 [(set_attr "type" "rotate1")
12964 (set (attr "length")
12965 (if_then_else (match_operand 0 "register_operand" "")
12967 (const_string "*")))])
12969 (define_insn "*rotrqi3_1"
12970 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12971 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12972 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12973 (clobber (reg:CC FLAGS_REG))]
12974 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12976 ror{b}\t{%2, %0|%0, %2}
12977 ror{b}\t{%b2, %0|%0, %b2}"
12978 [(set_attr "type" "rotate")
12979 (set_attr "mode" "QI")])
12981 (define_insn "*rotrqi3_1_slp"
12982 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12983 (rotatert:QI (match_dup 0)
12984 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12985 (clobber (reg:CC FLAGS_REG))]
12986 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12987 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12989 ror{b}\t{%1, %0|%0, %1}
12990 ror{b}\t{%b1, %0|%0, %b1}"
12991 [(set_attr "type" "rotate1")
12992 (set_attr "mode" "QI")])
12994 ;; Bit set / bit test instructions
12996 (define_expand "extv"
12997 [(set (match_operand:SI 0 "register_operand" "")
12998 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12999 (match_operand:SI 2 "const8_operand" "")
13000 (match_operand:SI 3 "const8_operand" "")))]
13003 /* Handle extractions from %ah et al. */
13004 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13007 /* From mips.md: extract_bit_field doesn't verify that our source
13008 matches the predicate, so check it again here. */
13009 if (! ext_register_operand (operands[1], VOIDmode))
13013 (define_expand "extzv"
13014 [(set (match_operand:SI 0 "register_operand" "")
13015 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13016 (match_operand:SI 2 "const8_operand" "")
13017 (match_operand:SI 3 "const8_operand" "")))]
13020 /* Handle extractions from %ah et al. */
13021 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13024 /* From mips.md: extract_bit_field doesn't verify that our source
13025 matches the predicate, so check it again here. */
13026 if (! ext_register_operand (operands[1], VOIDmode))
13030 (define_expand "insv"
13031 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13032 (match_operand 1 "const8_operand" "")
13033 (match_operand 2 "const8_operand" ""))
13034 (match_operand 3 "register_operand" ""))]
13037 /* Handle insertions to %ah et al. */
13038 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13041 /* From mips.md: insert_bit_field doesn't verify that our source
13042 matches the predicate, so check it again here. */
13043 if (! ext_register_operand (operands[0], VOIDmode))
13047 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13049 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13054 ;; %%% bts, btr, btc, bt.
13055 ;; In general these instructions are *slow* when applied to memory,
13056 ;; since they enforce atomic operation. When applied to registers,
13057 ;; it depends on the cpu implementation. They're never faster than
13058 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13059 ;; no point. But in 64-bit, we can't hold the relevant immediates
13060 ;; within the instruction itself, so operating on bits in the high
13061 ;; 32-bits of a register becomes easier.
13063 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13064 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13065 ;; negdf respectively, so they can never be disabled entirely.
13067 (define_insn "*btsq"
13068 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13070 (match_operand:DI 1 "const_0_to_63_operand" ""))
13072 (clobber (reg:CC FLAGS_REG))]
13073 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13075 [(set_attr "type" "alu1")])
13077 (define_insn "*btrq"
13078 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13080 (match_operand:DI 1 "const_0_to_63_operand" ""))
13082 (clobber (reg:CC FLAGS_REG))]
13083 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13085 [(set_attr "type" "alu1")])
13087 (define_insn "*btcq"
13088 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13090 (match_operand:DI 1 "const_0_to_63_operand" ""))
13091 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13092 (clobber (reg:CC FLAGS_REG))]
13093 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13095 [(set_attr "type" "alu1")])
13097 ;; Allow Nocona to avoid these instructions if a register is available.
13100 [(match_scratch:DI 2 "r")
13101 (parallel [(set (zero_extract:DI
13102 (match_operand:DI 0 "register_operand" "")
13104 (match_operand:DI 1 "const_0_to_63_operand" ""))
13106 (clobber (reg:CC FLAGS_REG))])]
13107 "TARGET_64BIT && !TARGET_USE_BT"
13110 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13113 if (HOST_BITS_PER_WIDE_INT >= 64)
13114 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13115 else if (i < HOST_BITS_PER_WIDE_INT)
13116 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13118 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13120 op1 = immed_double_const (lo, hi, DImode);
13123 emit_move_insn (operands[2], op1);
13127 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13132 [(match_scratch:DI 2 "r")
13133 (parallel [(set (zero_extract:DI
13134 (match_operand:DI 0 "register_operand" "")
13136 (match_operand:DI 1 "const_0_to_63_operand" ""))
13138 (clobber (reg:CC FLAGS_REG))])]
13139 "TARGET_64BIT && !TARGET_USE_BT"
13142 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13145 if (HOST_BITS_PER_WIDE_INT >= 64)
13146 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13147 else if (i < HOST_BITS_PER_WIDE_INT)
13148 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13150 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13152 op1 = immed_double_const (~lo, ~hi, DImode);
13155 emit_move_insn (operands[2], op1);
13159 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13164 [(match_scratch:DI 2 "r")
13165 (parallel [(set (zero_extract:DI
13166 (match_operand:DI 0 "register_operand" "")
13168 (match_operand:DI 1 "const_0_to_63_operand" ""))
13169 (not:DI (zero_extract:DI
13170 (match_dup 0) (const_int 1) (match_dup 1))))
13171 (clobber (reg:CC FLAGS_REG))])]
13172 "TARGET_64BIT && !TARGET_USE_BT"
13175 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13178 if (HOST_BITS_PER_WIDE_INT >= 64)
13179 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13180 else if (i < HOST_BITS_PER_WIDE_INT)
13181 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13183 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13185 op1 = immed_double_const (lo, hi, DImode);
13188 emit_move_insn (operands[2], op1);
13192 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13196 ;; Store-flag instructions.
13198 ;; For all sCOND expanders, also expand the compare or test insn that
13199 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13201 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13202 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13203 ;; way, which can later delete the movzx if only QImode is needed.
13205 (define_expand "seq"
13206 [(set (match_operand:QI 0 "register_operand" "")
13207 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13209 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13211 (define_expand "sne"
13212 [(set (match_operand:QI 0 "register_operand" "")
13213 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13217 (define_expand "sgt"
13218 [(set (match_operand:QI 0 "register_operand" "")
13219 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13223 (define_expand "sgtu"
13224 [(set (match_operand:QI 0 "register_operand" "")
13225 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13229 (define_expand "slt"
13230 [(set (match_operand:QI 0 "register_operand" "")
13231 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13235 (define_expand "sltu"
13236 [(set (match_operand:QI 0 "register_operand" "")
13237 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13241 (define_expand "sge"
13242 [(set (match_operand:QI 0 "register_operand" "")
13243 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13247 (define_expand "sgeu"
13248 [(set (match_operand:QI 0 "register_operand" "")
13249 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13253 (define_expand "sle"
13254 [(set (match_operand:QI 0 "register_operand" "")
13255 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13259 (define_expand "sleu"
13260 [(set (match_operand:QI 0 "register_operand" "")
13261 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13265 (define_expand "sunordered"
13266 [(set (match_operand:QI 0 "register_operand" "")
13267 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13268 "TARGET_80387 || TARGET_SSE"
13269 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13271 (define_expand "sordered"
13272 [(set (match_operand:QI 0 "register_operand" "")
13273 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13277 (define_expand "suneq"
13278 [(set (match_operand:QI 0 "register_operand" "")
13279 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13280 "TARGET_80387 || TARGET_SSE"
13281 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13283 (define_expand "sunge"
13284 [(set (match_operand:QI 0 "register_operand" "")
13285 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13286 "TARGET_80387 || TARGET_SSE"
13287 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13289 (define_expand "sungt"
13290 [(set (match_operand:QI 0 "register_operand" "")
13291 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13292 "TARGET_80387 || TARGET_SSE"
13293 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13295 (define_expand "sunle"
13296 [(set (match_operand:QI 0 "register_operand" "")
13297 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13298 "TARGET_80387 || TARGET_SSE"
13299 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13301 (define_expand "sunlt"
13302 [(set (match_operand:QI 0 "register_operand" "")
13303 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13304 "TARGET_80387 || TARGET_SSE"
13305 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13307 (define_expand "sltgt"
13308 [(set (match_operand:QI 0 "register_operand" "")
13309 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13310 "TARGET_80387 || TARGET_SSE"
13311 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13313 (define_insn "*setcc_1"
13314 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13315 (match_operator:QI 1 "ix86_comparison_operator"
13316 [(reg FLAGS_REG) (const_int 0)]))]
13319 [(set_attr "type" "setcc")
13320 (set_attr "mode" "QI")])
13322 (define_insn "*setcc_2"
13323 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13324 (match_operator:QI 1 "ix86_comparison_operator"
13325 [(reg FLAGS_REG) (const_int 0)]))]
13328 [(set_attr "type" "setcc")
13329 (set_attr "mode" "QI")])
13331 ;; In general it is not safe to assume too much about CCmode registers,
13332 ;; so simplify-rtx stops when it sees a second one. Under certain
13333 ;; conditions this is safe on x86, so help combine not create
13340 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13341 (ne:QI (match_operator 1 "ix86_comparison_operator"
13342 [(reg FLAGS_REG) (const_int 0)])
13345 [(set (match_dup 0) (match_dup 1))]
13347 PUT_MODE (operands[1], QImode);
13351 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13352 (ne:QI (match_operator 1 "ix86_comparison_operator"
13353 [(reg FLAGS_REG) (const_int 0)])
13356 [(set (match_dup 0) (match_dup 1))]
13358 PUT_MODE (operands[1], QImode);
13362 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13363 (eq:QI (match_operator 1 "ix86_comparison_operator"
13364 [(reg FLAGS_REG) (const_int 0)])
13367 [(set (match_dup 0) (match_dup 1))]
13369 rtx new_op1 = copy_rtx (operands[1]);
13370 operands[1] = new_op1;
13371 PUT_MODE (new_op1, QImode);
13372 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13373 GET_MODE (XEXP (new_op1, 0))));
13375 /* Make sure that (a) the CCmode we have for the flags is strong
13376 enough for the reversed compare or (b) we have a valid FP compare. */
13377 if (! ix86_comparison_operator (new_op1, VOIDmode))
13382 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13383 (eq:QI (match_operator 1 "ix86_comparison_operator"
13384 [(reg FLAGS_REG) (const_int 0)])
13387 [(set (match_dup 0) (match_dup 1))]
13389 rtx new_op1 = copy_rtx (operands[1]);
13390 operands[1] = new_op1;
13391 PUT_MODE (new_op1, QImode);
13392 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13393 GET_MODE (XEXP (new_op1, 0))));
13395 /* Make sure that (a) the CCmode we have for the flags is strong
13396 enough for the reversed compare or (b) we have a valid FP compare. */
13397 if (! ix86_comparison_operator (new_op1, VOIDmode))
13401 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13402 ;; subsequent logical operations are used to imitate conditional moves.
13403 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13406 (define_insn "*sse_setccsf"
13407 [(set (match_operand:SF 0 "register_operand" "=x")
13408 (match_operator:SF 1 "sse_comparison_operator"
13409 [(match_operand:SF 2 "register_operand" "0")
13410 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13412 "cmp%D1ss\t{%3, %0|%0, %3}"
13413 [(set_attr "type" "ssecmp")
13414 (set_attr "mode" "SF")])
13416 (define_insn "*sse_setccdf"
13417 [(set (match_operand:DF 0 "register_operand" "=Y")
13418 (match_operator:DF 1 "sse_comparison_operator"
13419 [(match_operand:DF 2 "register_operand" "0")
13420 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13422 "cmp%D1sd\t{%3, %0|%0, %3}"
13423 [(set_attr "type" "ssecmp")
13424 (set_attr "mode" "DF")])
13426 ;; Basic conditional jump instructions.
13427 ;; We ignore the overflow flag for signed branch instructions.
13429 ;; For all bCOND expanders, also expand the compare or test insn that
13430 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13432 (define_expand "beq"
13434 (if_then_else (match_dup 1)
13435 (label_ref (match_operand 0 "" ""))
13438 "ix86_expand_branch (EQ, operands[0]); DONE;")
13440 (define_expand "bne"
13442 (if_then_else (match_dup 1)
13443 (label_ref (match_operand 0 "" ""))
13446 "ix86_expand_branch (NE, operands[0]); DONE;")
13448 (define_expand "bgt"
13450 (if_then_else (match_dup 1)
13451 (label_ref (match_operand 0 "" ""))
13454 "ix86_expand_branch (GT, operands[0]); DONE;")
13456 (define_expand "bgtu"
13458 (if_then_else (match_dup 1)
13459 (label_ref (match_operand 0 "" ""))
13462 "ix86_expand_branch (GTU, operands[0]); DONE;")
13464 (define_expand "blt"
13466 (if_then_else (match_dup 1)
13467 (label_ref (match_operand 0 "" ""))
13470 "ix86_expand_branch (LT, operands[0]); DONE;")
13472 (define_expand "bltu"
13474 (if_then_else (match_dup 1)
13475 (label_ref (match_operand 0 "" ""))
13478 "ix86_expand_branch (LTU, operands[0]); DONE;")
13480 (define_expand "bge"
13482 (if_then_else (match_dup 1)
13483 (label_ref (match_operand 0 "" ""))
13486 "ix86_expand_branch (GE, operands[0]); DONE;")
13488 (define_expand "bgeu"
13490 (if_then_else (match_dup 1)
13491 (label_ref (match_operand 0 "" ""))
13494 "ix86_expand_branch (GEU, operands[0]); DONE;")
13496 (define_expand "ble"
13498 (if_then_else (match_dup 1)
13499 (label_ref (match_operand 0 "" ""))
13502 "ix86_expand_branch (LE, operands[0]); DONE;")
13504 (define_expand "bleu"
13506 (if_then_else (match_dup 1)
13507 (label_ref (match_operand 0 "" ""))
13510 "ix86_expand_branch (LEU, operands[0]); DONE;")
13512 (define_expand "bunordered"
13514 (if_then_else (match_dup 1)
13515 (label_ref (match_operand 0 "" ""))
13517 "TARGET_80387 || TARGET_SSE_MATH"
13518 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13520 (define_expand "bordered"
13522 (if_then_else (match_dup 1)
13523 (label_ref (match_operand 0 "" ""))
13525 "TARGET_80387 || TARGET_SSE_MATH"
13526 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13528 (define_expand "buneq"
13530 (if_then_else (match_dup 1)
13531 (label_ref (match_operand 0 "" ""))
13533 "TARGET_80387 || TARGET_SSE_MATH"
13534 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13536 (define_expand "bunge"
13538 (if_then_else (match_dup 1)
13539 (label_ref (match_operand 0 "" ""))
13541 "TARGET_80387 || TARGET_SSE_MATH"
13542 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13544 (define_expand "bungt"
13546 (if_then_else (match_dup 1)
13547 (label_ref (match_operand 0 "" ""))
13549 "TARGET_80387 || TARGET_SSE_MATH"
13550 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13552 (define_expand "bunle"
13554 (if_then_else (match_dup 1)
13555 (label_ref (match_operand 0 "" ""))
13557 "TARGET_80387 || TARGET_SSE_MATH"
13558 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13560 (define_expand "bunlt"
13562 (if_then_else (match_dup 1)
13563 (label_ref (match_operand 0 "" ""))
13565 "TARGET_80387 || TARGET_SSE_MATH"
13566 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13568 (define_expand "bltgt"
13570 (if_then_else (match_dup 1)
13571 (label_ref (match_operand 0 "" ""))
13573 "TARGET_80387 || TARGET_SSE_MATH"
13574 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13576 (define_insn "*jcc_1"
13578 (if_then_else (match_operator 1 "ix86_comparison_operator"
13579 [(reg FLAGS_REG) (const_int 0)])
13580 (label_ref (match_operand 0 "" ""))
13584 [(set_attr "type" "ibr")
13585 (set_attr "modrm" "0")
13586 (set (attr "length")
13587 (if_then_else (and (ge (minus (match_dup 0) (pc))
13589 (lt (minus (match_dup 0) (pc))
13594 (define_insn "*jcc_2"
13596 (if_then_else (match_operator 1 "ix86_comparison_operator"
13597 [(reg FLAGS_REG) (const_int 0)])
13599 (label_ref (match_operand 0 "" ""))))]
13602 [(set_attr "type" "ibr")
13603 (set_attr "modrm" "0")
13604 (set (attr "length")
13605 (if_then_else (and (ge (minus (match_dup 0) (pc))
13607 (lt (minus (match_dup 0) (pc))
13612 ;; In general it is not safe to assume too much about CCmode registers,
13613 ;; so simplify-rtx stops when it sees a second one. Under certain
13614 ;; conditions this is safe on x86, so help combine not create
13622 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13623 [(reg FLAGS_REG) (const_int 0)])
13625 (label_ref (match_operand 1 "" ""))
13629 (if_then_else (match_dup 0)
13630 (label_ref (match_dup 1))
13633 PUT_MODE (operands[0], VOIDmode);
13638 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13639 [(reg FLAGS_REG) (const_int 0)])
13641 (label_ref (match_operand 1 "" ""))
13645 (if_then_else (match_dup 0)
13646 (label_ref (match_dup 1))
13649 rtx new_op0 = copy_rtx (operands[0]);
13650 operands[0] = new_op0;
13651 PUT_MODE (new_op0, VOIDmode);
13652 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13653 GET_MODE (XEXP (new_op0, 0))));
13655 /* Make sure that (a) the CCmode we have for the flags is strong
13656 enough for the reversed compare or (b) we have a valid FP compare. */
13657 if (! ix86_comparison_operator (new_op0, VOIDmode))
13661 ;; Define combination compare-and-branch fp compare instructions to use
13662 ;; during early optimization. Splitting the operation apart early makes
13663 ;; for bad code when we want to reverse the operation.
13665 (define_insn "*fp_jcc_1_mixed"
13667 (if_then_else (match_operator 0 "comparison_operator"
13668 [(match_operand 1 "register_operand" "f,x")
13669 (match_operand 2 "nonimmediate_operand" "f,xm")])
13670 (label_ref (match_operand 3 "" ""))
13672 (clobber (reg:CCFP FPSR_REG))
13673 (clobber (reg:CCFP FLAGS_REG))]
13674 "TARGET_MIX_SSE_I387
13675 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13676 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13677 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13680 (define_insn "*fp_jcc_1_sse"
13682 (if_then_else (match_operator 0 "comparison_operator"
13683 [(match_operand 1 "register_operand" "x")
13684 (match_operand 2 "nonimmediate_operand" "xm")])
13685 (label_ref (match_operand 3 "" ""))
13687 (clobber (reg:CCFP FPSR_REG))
13688 (clobber (reg:CCFP FLAGS_REG))]
13690 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13691 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13692 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13695 (define_insn "*fp_jcc_1_387"
13697 (if_then_else (match_operator 0 "comparison_operator"
13698 [(match_operand 1 "register_operand" "f")
13699 (match_operand 2 "register_operand" "f")])
13700 (label_ref (match_operand 3 "" ""))
13702 (clobber (reg:CCFP FPSR_REG))
13703 (clobber (reg:CCFP FLAGS_REG))]
13704 "TARGET_CMOVE && TARGET_80387
13705 && FLOAT_MODE_P (GET_MODE (operands[1]))
13706 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13707 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13710 (define_insn "*fp_jcc_2_mixed"
13712 (if_then_else (match_operator 0 "comparison_operator"
13713 [(match_operand 1 "register_operand" "f,x")
13714 (match_operand 2 "nonimmediate_operand" "f,xm")])
13716 (label_ref (match_operand 3 "" ""))))
13717 (clobber (reg:CCFP FPSR_REG))
13718 (clobber (reg:CCFP FLAGS_REG))]
13719 "TARGET_MIX_SSE_I387
13720 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13721 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13722 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725 (define_insn "*fp_jcc_2_sse"
13727 (if_then_else (match_operator 0 "comparison_operator"
13728 [(match_operand 1 "register_operand" "x")
13729 (match_operand 2 "nonimmediate_operand" "xm")])
13731 (label_ref (match_operand 3 "" ""))))
13732 (clobber (reg:CCFP FPSR_REG))
13733 (clobber (reg:CCFP FLAGS_REG))]
13735 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13736 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13737 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13740 (define_insn "*fp_jcc_2_387"
13742 (if_then_else (match_operator 0 "comparison_operator"
13743 [(match_operand 1 "register_operand" "f")
13744 (match_operand 2 "register_operand" "f")])
13746 (label_ref (match_operand 3 "" ""))))
13747 (clobber (reg:CCFP FPSR_REG))
13748 (clobber (reg:CCFP FLAGS_REG))]
13749 "TARGET_CMOVE && TARGET_80387
13750 && FLOAT_MODE_P (GET_MODE (operands[1]))
13751 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13752 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13755 (define_insn "*fp_jcc_3_387"
13757 (if_then_else (match_operator 0 "comparison_operator"
13758 [(match_operand 1 "register_operand" "f")
13759 (match_operand 2 "nonimmediate_operand" "fm")])
13760 (label_ref (match_operand 3 "" ""))
13762 (clobber (reg:CCFP FPSR_REG))
13763 (clobber (reg:CCFP FLAGS_REG))
13764 (clobber (match_scratch:HI 4 "=a"))]
13766 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13767 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13768 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13769 && SELECT_CC_MODE (GET_CODE (operands[0]),
13770 operands[1], operands[2]) == CCFPmode
13771 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13774 (define_insn "*fp_jcc_4_387"
13776 (if_then_else (match_operator 0 "comparison_operator"
13777 [(match_operand 1 "register_operand" "f")
13778 (match_operand 2 "nonimmediate_operand" "fm")])
13780 (label_ref (match_operand 3 "" ""))))
13781 (clobber (reg:CCFP FPSR_REG))
13782 (clobber (reg:CCFP FLAGS_REG))
13783 (clobber (match_scratch:HI 4 "=a"))]
13785 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13786 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13787 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13788 && SELECT_CC_MODE (GET_CODE (operands[0]),
13789 operands[1], operands[2]) == CCFPmode
13790 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13793 (define_insn "*fp_jcc_5_387"
13795 (if_then_else (match_operator 0 "comparison_operator"
13796 [(match_operand 1 "register_operand" "f")
13797 (match_operand 2 "register_operand" "f")])
13798 (label_ref (match_operand 3 "" ""))
13800 (clobber (reg:CCFP FPSR_REG))
13801 (clobber (reg:CCFP FLAGS_REG))
13802 (clobber (match_scratch:HI 4 "=a"))]
13804 && FLOAT_MODE_P (GET_MODE (operands[1]))
13805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13809 (define_insn "*fp_jcc_6_387"
13811 (if_then_else (match_operator 0 "comparison_operator"
13812 [(match_operand 1 "register_operand" "f")
13813 (match_operand 2 "register_operand" "f")])
13815 (label_ref (match_operand 3 "" ""))))
13816 (clobber (reg:CCFP FPSR_REG))
13817 (clobber (reg:CCFP FLAGS_REG))
13818 (clobber (match_scratch:HI 4 "=a"))]
13820 && FLOAT_MODE_P (GET_MODE (operands[1]))
13821 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13822 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13825 (define_insn "*fp_jcc_7_387"
13827 (if_then_else (match_operator 0 "comparison_operator"
13828 [(match_operand 1 "register_operand" "f")
13829 (match_operand 2 "const0_operand" "X")])
13830 (label_ref (match_operand 3 "" ""))
13832 (clobber (reg:CCFP FPSR_REG))
13833 (clobber (reg:CCFP FLAGS_REG))
13834 (clobber (match_scratch:HI 4 "=a"))]
13836 && FLOAT_MODE_P (GET_MODE (operands[1]))
13837 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13838 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13839 && SELECT_CC_MODE (GET_CODE (operands[0]),
13840 operands[1], operands[2]) == CCFPmode
13841 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13844 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13845 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13846 ;; with a precedence over other operators and is always put in the first
13847 ;; place. Swap condition and operands to match ficom instruction.
13849 (define_insn "*fp_jcc_8<mode>_387"
13851 (if_then_else (match_operator 0 "comparison_operator"
13852 [(match_operator 1 "float_operator"
13853 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13854 (match_operand 3 "register_operand" "f,f")])
13855 (label_ref (match_operand 4 "" ""))
13857 (clobber (reg:CCFP FPSR_REG))
13858 (clobber (reg:CCFP FLAGS_REG))
13859 (clobber (match_scratch:HI 5 "=a,a"))]
13860 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13861 && FLOAT_MODE_P (GET_MODE (operands[3]))
13862 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13863 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13864 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13865 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13870 (if_then_else (match_operator 0 "comparison_operator"
13871 [(match_operand 1 "register_operand" "")
13872 (match_operand 2 "nonimmediate_operand" "")])
13873 (match_operand 3 "" "")
13874 (match_operand 4 "" "")))
13875 (clobber (reg:CCFP FPSR_REG))
13876 (clobber (reg:CCFP FLAGS_REG))]
13880 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13881 operands[3], operands[4], NULL_RTX, NULL_RTX);
13887 (if_then_else (match_operator 0 "comparison_operator"
13888 [(match_operand 1 "register_operand" "")
13889 (match_operand 2 "general_operand" "")])
13890 (match_operand 3 "" "")
13891 (match_operand 4 "" "")))
13892 (clobber (reg:CCFP FPSR_REG))
13893 (clobber (reg:CCFP FLAGS_REG))
13894 (clobber (match_scratch:HI 5 "=a"))]
13898 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13899 operands[3], operands[4], operands[5], NULL_RTX);
13905 (if_then_else (match_operator 0 "comparison_operator"
13906 [(match_operator 1 "float_operator"
13907 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13908 (match_operand 3 "register_operand" "")])
13909 (match_operand 4 "" "")
13910 (match_operand 5 "" "")))
13911 (clobber (reg:CCFP FPSR_REG))
13912 (clobber (reg:CCFP FLAGS_REG))
13913 (clobber (match_scratch:HI 6 "=a"))]
13917 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13918 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13919 operands[3], operands[7],
13920 operands[4], operands[5], operands[6], NULL_RTX);
13924 ;; %%% Kill this when reload knows how to do it.
13927 (if_then_else (match_operator 0 "comparison_operator"
13928 [(match_operator 1 "float_operator"
13929 [(match_operand:X87MODEI12 2 "register_operand" "")])
13930 (match_operand 3 "register_operand" "")])
13931 (match_operand 4 "" "")
13932 (match_operand 5 "" "")))
13933 (clobber (reg:CCFP FPSR_REG))
13934 (clobber (reg:CCFP FLAGS_REG))
13935 (clobber (match_scratch:HI 6 "=a"))]
13939 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13940 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13941 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13942 operands[3], operands[7],
13943 operands[4], operands[5], operands[6], operands[2]);
13947 ;; Unconditional and other jump instructions
13949 (define_insn "jump"
13951 (label_ref (match_operand 0 "" "")))]
13954 [(set_attr "type" "ibr")
13955 (set (attr "length")
13956 (if_then_else (and (ge (minus (match_dup 0) (pc))
13958 (lt (minus (match_dup 0) (pc))
13962 (set_attr "modrm" "0")])
13964 (define_expand "indirect_jump"
13965 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13969 (define_insn "*indirect_jump"
13970 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13973 [(set_attr "type" "ibr")
13974 (set_attr "length_immediate" "0")])
13976 (define_insn "*indirect_jump_rtx64"
13977 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13980 [(set_attr "type" "ibr")
13981 (set_attr "length_immediate" "0")])
13983 (define_expand "tablejump"
13984 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13985 (use (label_ref (match_operand 1 "" "")))])]
13988 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13989 relative. Convert the relative address to an absolute address. */
13993 enum rtx_code code;
13999 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14001 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14005 op1 = pic_offset_table_rtx;
14010 op0 = pic_offset_table_rtx;
14014 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14019 (define_insn "*tablejump_1"
14020 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14021 (use (label_ref (match_operand 1 "" "")))]
14024 [(set_attr "type" "ibr")
14025 (set_attr "length_immediate" "0")])
14027 (define_insn "*tablejump_1_rtx64"
14028 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14029 (use (label_ref (match_operand 1 "" "")))]
14032 [(set_attr "type" "ibr")
14033 (set_attr "length_immediate" "0")])
14035 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14038 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14039 (set (match_operand:QI 1 "register_operand" "")
14040 (match_operator:QI 2 "ix86_comparison_operator"
14041 [(reg FLAGS_REG) (const_int 0)]))
14042 (set (match_operand 3 "q_regs_operand" "")
14043 (zero_extend (match_dup 1)))]
14044 "(peep2_reg_dead_p (3, operands[1])
14045 || operands_match_p (operands[1], operands[3]))
14046 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14047 [(set (match_dup 4) (match_dup 0))
14048 (set (strict_low_part (match_dup 5))
14051 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14052 operands[5] = gen_lowpart (QImode, operands[3]);
14053 ix86_expand_clear (operands[3]);
14056 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14059 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14060 (set (match_operand:QI 1 "register_operand" "")
14061 (match_operator:QI 2 "ix86_comparison_operator"
14062 [(reg FLAGS_REG) (const_int 0)]))
14063 (parallel [(set (match_operand 3 "q_regs_operand" "")
14064 (zero_extend (match_dup 1)))
14065 (clobber (reg:CC FLAGS_REG))])]
14066 "(peep2_reg_dead_p (3, operands[1])
14067 || operands_match_p (operands[1], operands[3]))
14068 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14069 [(set (match_dup 4) (match_dup 0))
14070 (set (strict_low_part (match_dup 5))
14073 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14074 operands[5] = gen_lowpart (QImode, operands[3]);
14075 ix86_expand_clear (operands[3]);
14078 ;; Call instructions.
14080 ;; The predicates normally associated with named expanders are not properly
14081 ;; checked for calls. This is a bug in the generic code, but it isn't that
14082 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14084 ;; Call subroutine returning no value.
14086 (define_expand "call_pop"
14087 [(parallel [(call (match_operand:QI 0 "" "")
14088 (match_operand:SI 1 "" ""))
14089 (set (reg:SI SP_REG)
14090 (plus:SI (reg:SI SP_REG)
14091 (match_operand:SI 3 "" "")))])]
14094 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14098 (define_insn "*call_pop_0"
14099 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14100 (match_operand:SI 1 "" ""))
14101 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14102 (match_operand:SI 2 "immediate_operand" "")))]
14105 if (SIBLING_CALL_P (insn))
14108 return "call\t%P0";
14110 [(set_attr "type" "call")])
14112 (define_insn "*call_pop_1"
14113 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14114 (match_operand:SI 1 "" ""))
14115 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14116 (match_operand:SI 2 "immediate_operand" "i")))]
14119 if (constant_call_address_operand (operands[0], Pmode))
14121 if (SIBLING_CALL_P (insn))
14124 return "call\t%P0";
14126 if (SIBLING_CALL_P (insn))
14129 return "call\t%A0";
14131 [(set_attr "type" "call")])
14133 (define_expand "call"
14134 [(call (match_operand:QI 0 "" "")
14135 (match_operand 1 "" ""))
14136 (use (match_operand 2 "" ""))]
14139 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14143 (define_expand "sibcall"
14144 [(call (match_operand:QI 0 "" "")
14145 (match_operand 1 "" ""))
14146 (use (match_operand 2 "" ""))]
14149 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14153 (define_insn "*call_0"
14154 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14155 (match_operand 1 "" ""))]
14158 if (SIBLING_CALL_P (insn))
14161 return "call\t%P0";
14163 [(set_attr "type" "call")])
14165 (define_insn "*call_1"
14166 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14167 (match_operand 1 "" ""))]
14168 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14170 if (constant_call_address_operand (operands[0], Pmode))
14171 return "call\t%P0";
14172 return "call\t%A0";
14174 [(set_attr "type" "call")])
14176 (define_insn "*sibcall_1"
14177 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14178 (match_operand 1 "" ""))]
14179 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14181 if (constant_call_address_operand (operands[0], Pmode))
14185 [(set_attr "type" "call")])
14187 (define_insn "*call_1_rex64"
14188 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14189 (match_operand 1 "" ""))]
14190 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14192 if (constant_call_address_operand (operands[0], Pmode))
14193 return "call\t%P0";
14194 return "call\t%A0";
14196 [(set_attr "type" "call")])
14198 (define_insn "*sibcall_1_rex64"
14199 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14200 (match_operand 1 "" ""))]
14201 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14203 [(set_attr "type" "call")])
14205 (define_insn "*sibcall_1_rex64_v"
14206 [(call (mem:QI (reg:DI R11_REG))
14207 (match_operand 0 "" ""))]
14208 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14210 [(set_attr "type" "call")])
14213 ;; Call subroutine, returning value in operand 0
14215 (define_expand "call_value_pop"
14216 [(parallel [(set (match_operand 0 "" "")
14217 (call (match_operand:QI 1 "" "")
14218 (match_operand:SI 2 "" "")))
14219 (set (reg:SI SP_REG)
14220 (plus:SI (reg:SI SP_REG)
14221 (match_operand:SI 4 "" "")))])]
14224 ix86_expand_call (operands[0], operands[1], operands[2],
14225 operands[3], operands[4], 0);
14229 (define_expand "call_value"
14230 [(set (match_operand 0 "" "")
14231 (call (match_operand:QI 1 "" "")
14232 (match_operand:SI 2 "" "")))
14233 (use (match_operand:SI 3 "" ""))]
14234 ;; Operand 2 not used on the i386.
14237 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14241 (define_expand "sibcall_value"
14242 [(set (match_operand 0 "" "")
14243 (call (match_operand:QI 1 "" "")
14244 (match_operand:SI 2 "" "")))
14245 (use (match_operand:SI 3 "" ""))]
14246 ;; Operand 2 not used on the i386.
14249 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14253 ;; Call subroutine returning any type.
14255 (define_expand "untyped_call"
14256 [(parallel [(call (match_operand 0 "" "")
14258 (match_operand 1 "" "")
14259 (match_operand 2 "" "")])]
14264 /* In order to give reg-stack an easier job in validating two
14265 coprocessor registers as containing a possible return value,
14266 simply pretend the untyped call returns a complex long double
14269 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14270 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14271 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14274 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14276 rtx set = XVECEXP (operands[2], 0, i);
14277 emit_move_insn (SET_DEST (set), SET_SRC (set));
14280 /* The optimizer does not know that the call sets the function value
14281 registers we stored in the result block. We avoid problems by
14282 claiming that all hard registers are used and clobbered at this
14284 emit_insn (gen_blockage (const0_rtx));
14289 ;; Prologue and epilogue instructions
14291 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14292 ;; all of memory. This blocks insns from being moved across this point.
14294 (define_insn "blockage"
14295 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14298 [(set_attr "length" "0")])
14300 ;; Insn emitted into the body of a function to return from a function.
14301 ;; This is only done if the function's epilogue is known to be simple.
14302 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14304 (define_expand "return"
14306 "ix86_can_use_return_insn_p ()"
14308 if (current_function_pops_args)
14310 rtx popc = GEN_INT (current_function_pops_args);
14311 emit_jump_insn (gen_return_pop_internal (popc));
14316 (define_insn "return_internal"
14320 [(set_attr "length" "1")
14321 (set_attr "length_immediate" "0")
14322 (set_attr "modrm" "0")])
14324 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14325 ;; instruction Athlon and K8 have.
14327 (define_insn "return_internal_long"
14329 (unspec [(const_int 0)] UNSPEC_REP)]
14332 [(set_attr "length" "1")
14333 (set_attr "length_immediate" "0")
14334 (set_attr "prefix_rep" "1")
14335 (set_attr "modrm" "0")])
14337 (define_insn "return_pop_internal"
14339 (use (match_operand:SI 0 "const_int_operand" ""))]
14342 [(set_attr "length" "3")
14343 (set_attr "length_immediate" "2")
14344 (set_attr "modrm" "0")])
14346 (define_insn "return_indirect_internal"
14348 (use (match_operand:SI 0 "register_operand" "r"))]
14351 [(set_attr "type" "ibr")
14352 (set_attr "length_immediate" "0")])
14358 [(set_attr "length" "1")
14359 (set_attr "length_immediate" "0")
14360 (set_attr "modrm" "0")])
14362 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14363 ;; branch prediction penalty for the third jump in a 16-byte
14366 (define_insn "align"
14367 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14370 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14371 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14373 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14374 The align insn is used to avoid 3 jump instructions in the row to improve
14375 branch prediction and the benefits hardly outweigh the cost of extra 8
14376 nops on the average inserted by full alignment pseudo operation. */
14380 [(set_attr "length" "16")])
14382 (define_expand "prologue"
14385 "ix86_expand_prologue (); DONE;")
14387 (define_insn "set_got"
14388 [(set (match_operand:SI 0 "register_operand" "=r")
14389 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14390 (clobber (reg:CC FLAGS_REG))]
14392 { return output_set_got (operands[0], NULL_RTX); }
14393 [(set_attr "type" "multi")
14394 (set_attr "length" "12")])
14396 (define_insn "set_got_labelled"
14397 [(set (match_operand:SI 0 "register_operand" "=r")
14398 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14400 (clobber (reg:CC FLAGS_REG))]
14402 { return output_set_got (operands[0], operands[1]); }
14403 [(set_attr "type" "multi")
14404 (set_attr "length" "12")])
14406 (define_insn "set_got_rex64"
14407 [(set (match_operand:DI 0 "register_operand" "=r")
14408 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14410 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14411 [(set_attr "type" "lea")
14412 (set_attr "length" "6")])
14414 (define_expand "epilogue"
14417 "ix86_expand_epilogue (1); DONE;")
14419 (define_expand "sibcall_epilogue"
14422 "ix86_expand_epilogue (0); DONE;")
14424 (define_expand "eh_return"
14425 [(use (match_operand 0 "register_operand" ""))]
14428 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14430 /* Tricky bit: we write the address of the handler to which we will
14431 be returning into someone else's stack frame, one word below the
14432 stack address we wish to restore. */
14433 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14434 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14435 tmp = gen_rtx_MEM (Pmode, tmp);
14436 emit_move_insn (tmp, ra);
14438 if (Pmode == SImode)
14439 emit_jump_insn (gen_eh_return_si (sa));
14441 emit_jump_insn (gen_eh_return_di (sa));
14446 (define_insn_and_split "eh_return_si"
14448 (unspec [(match_operand:SI 0 "register_operand" "c")]
14449 UNSPEC_EH_RETURN))]
14454 "ix86_expand_epilogue (2); DONE;")
14456 (define_insn_and_split "eh_return_di"
14458 (unspec [(match_operand:DI 0 "register_operand" "c")]
14459 UNSPEC_EH_RETURN))]
14464 "ix86_expand_epilogue (2); DONE;")
14466 (define_insn "leave"
14467 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14468 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14469 (clobber (mem:BLK (scratch)))]
14472 [(set_attr "type" "leave")])
14474 (define_insn "leave_rex64"
14475 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14476 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14477 (clobber (mem:BLK (scratch)))]
14480 [(set_attr "type" "leave")])
14482 (define_expand "ffssi2"
14484 [(set (match_operand:SI 0 "register_operand" "")
14485 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14486 (clobber (match_scratch:SI 2 ""))
14487 (clobber (reg:CC FLAGS_REG))])]
14491 (define_insn_and_split "*ffs_cmove"
14492 [(set (match_operand:SI 0 "register_operand" "=r")
14493 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14494 (clobber (match_scratch:SI 2 "=&r"))
14495 (clobber (reg:CC FLAGS_REG))]
14498 "&& reload_completed"
14499 [(set (match_dup 2) (const_int -1))
14500 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14501 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14502 (set (match_dup 0) (if_then_else:SI
14503 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14506 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14507 (clobber (reg:CC FLAGS_REG))])]
14510 (define_insn_and_split "*ffs_no_cmove"
14511 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14512 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14513 (clobber (match_scratch:SI 2 "=&q"))
14514 (clobber (reg:CC FLAGS_REG))]
14518 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14519 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14520 (set (strict_low_part (match_dup 3))
14521 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14522 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14523 (clobber (reg:CC FLAGS_REG))])
14524 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14525 (clobber (reg:CC FLAGS_REG))])
14526 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14527 (clobber (reg:CC FLAGS_REG))])]
14529 operands[3] = gen_lowpart (QImode, operands[2]);
14530 ix86_expand_clear (operands[2]);
14533 (define_insn "*ffssi_1"
14534 [(set (reg:CCZ FLAGS_REG)
14535 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14537 (set (match_operand:SI 0 "register_operand" "=r")
14538 (ctz:SI (match_dup 1)))]
14540 "bsf{l}\t{%1, %0|%0, %1}"
14541 [(set_attr "prefix_0f" "1")])
14543 (define_expand "ffsdi2"
14545 [(set (match_operand:DI 0 "register_operand" "")
14546 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14547 (clobber (match_scratch:DI 2 ""))
14548 (clobber (reg:CC FLAGS_REG))])]
14549 "TARGET_64BIT && TARGET_CMOVE"
14552 (define_insn_and_split "*ffs_rex64"
14553 [(set (match_operand:DI 0 "register_operand" "=r")
14554 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14555 (clobber (match_scratch:DI 2 "=&r"))
14556 (clobber (reg:CC FLAGS_REG))]
14557 "TARGET_64BIT && TARGET_CMOVE"
14559 "&& reload_completed"
14560 [(set (match_dup 2) (const_int -1))
14561 (parallel [(set (reg:CCZ FLAGS_REG)
14562 (compare:CCZ (match_dup 1) (const_int 0)))
14563 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14564 (set (match_dup 0) (if_then_else:DI
14565 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14568 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14569 (clobber (reg:CC FLAGS_REG))])]
14572 (define_insn "*ffsdi_1"
14573 [(set (reg:CCZ FLAGS_REG)
14574 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14576 (set (match_operand:DI 0 "register_operand" "=r")
14577 (ctz:DI (match_dup 1)))]
14579 "bsf{q}\t{%1, %0|%0, %1}"
14580 [(set_attr "prefix_0f" "1")])
14582 (define_insn "ctzsi2"
14583 [(set (match_operand:SI 0 "register_operand" "=r")
14584 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14585 (clobber (reg:CC FLAGS_REG))]
14587 "bsf{l}\t{%1, %0|%0, %1}"
14588 [(set_attr "prefix_0f" "1")])
14590 (define_insn "ctzdi2"
14591 [(set (match_operand:DI 0 "register_operand" "=r")
14592 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14593 (clobber (reg:CC FLAGS_REG))]
14595 "bsf{q}\t{%1, %0|%0, %1}"
14596 [(set_attr "prefix_0f" "1")])
14598 (define_expand "clzsi2"
14600 [(set (match_operand:SI 0 "register_operand" "")
14601 (minus:SI (const_int 31)
14602 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14603 (clobber (reg:CC FLAGS_REG))])
14605 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14606 (clobber (reg:CC FLAGS_REG))])]
14610 (define_insn "*bsr"
14611 [(set (match_operand:SI 0 "register_operand" "=r")
14612 (minus:SI (const_int 31)
14613 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14614 (clobber (reg:CC FLAGS_REG))]
14616 "bsr{l}\t{%1, %0|%0, %1}"
14617 [(set_attr "prefix_0f" "1")])
14619 (define_insn "bswapsi2"
14620 [(set (match_operand:SI 0 "register_operand" "=r")
14621 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14622 (clobber (reg:CC FLAGS_REG))]
14625 [(set_attr "prefix_0f" "1")
14626 (set_attr "length" "2")])
14628 (define_insn "bswapdi2"
14629 [(set (match_operand:DI 0 "register_operand" "=r")
14630 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14631 (clobber (reg:CC FLAGS_REG))]
14632 "TARGET_64BIT && TARGET_BSWAP"
14634 [(set_attr "prefix_0f" "1")
14635 (set_attr "length" "3")])
14637 (define_expand "clzdi2"
14639 [(set (match_operand:DI 0 "register_operand" "")
14640 (minus:DI (const_int 63)
14641 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14642 (clobber (reg:CC FLAGS_REG))])
14644 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14645 (clobber (reg:CC FLAGS_REG))])]
14649 (define_insn "*bsr_rex64"
14650 [(set (match_operand:DI 0 "register_operand" "=r")
14651 (minus:DI (const_int 63)
14652 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14653 (clobber (reg:CC FLAGS_REG))]
14655 "bsr{q}\t{%1, %0|%0, %1}"
14656 [(set_attr "prefix_0f" "1")])
14658 ;; Thread-local storage patterns for ELF.
14660 ;; Note that these code sequences must appear exactly as shown
14661 ;; in order to allow linker relaxation.
14663 (define_insn "*tls_global_dynamic_32_gnu"
14664 [(set (match_operand:SI 0 "register_operand" "=a")
14665 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14666 (match_operand:SI 2 "tls_symbolic_operand" "")
14667 (match_operand:SI 3 "call_insn_operand" "")]
14669 (clobber (match_scratch:SI 4 "=d"))
14670 (clobber (match_scratch:SI 5 "=c"))
14671 (clobber (reg:CC FLAGS_REG))]
14672 "!TARGET_64BIT && TARGET_GNU_TLS"
14673 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14674 [(set_attr "type" "multi")
14675 (set_attr "length" "12")])
14677 (define_insn "*tls_global_dynamic_32_sun"
14678 [(set (match_operand:SI 0 "register_operand" "=a")
14679 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14680 (match_operand:SI 2 "tls_symbolic_operand" "")
14681 (match_operand:SI 3 "call_insn_operand" "")]
14683 (clobber (match_scratch:SI 4 "=d"))
14684 (clobber (match_scratch:SI 5 "=c"))
14685 (clobber (reg:CC FLAGS_REG))]
14686 "!TARGET_64BIT && TARGET_SUN_TLS"
14687 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14688 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14689 [(set_attr "type" "multi")
14690 (set_attr "length" "14")])
14692 (define_expand "tls_global_dynamic_32"
14693 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14696 (match_operand:SI 1 "tls_symbolic_operand" "")
14699 (clobber (match_scratch:SI 4 ""))
14700 (clobber (match_scratch:SI 5 ""))
14701 (clobber (reg:CC FLAGS_REG))])]
14705 operands[2] = pic_offset_table_rtx;
14708 operands[2] = gen_reg_rtx (Pmode);
14709 emit_insn (gen_set_got (operands[2]));
14711 if (TARGET_GNU2_TLS)
14713 emit_insn (gen_tls_dynamic_gnu2_32
14714 (operands[0], operands[1], operands[2]));
14717 operands[3] = ix86_tls_get_addr ();
14720 (define_insn "*tls_global_dynamic_64"
14721 [(set (match_operand:DI 0 "register_operand" "=a")
14722 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14723 (match_operand:DI 3 "" "")))
14724 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14727 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14728 [(set_attr "type" "multi")
14729 (set_attr "length" "16")])
14731 (define_expand "tls_global_dynamic_64"
14732 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14733 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14734 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14738 if (TARGET_GNU2_TLS)
14740 emit_insn (gen_tls_dynamic_gnu2_64
14741 (operands[0], operands[1]));
14744 operands[2] = ix86_tls_get_addr ();
14747 (define_insn "*tls_local_dynamic_base_32_gnu"
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_GNU_TLS"
14756 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14757 [(set_attr "type" "multi")
14758 (set_attr "length" "11")])
14760 (define_insn "*tls_local_dynamic_base_32_sun"
14761 [(set (match_operand:SI 0 "register_operand" "=a")
14762 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14763 (match_operand:SI 2 "call_insn_operand" "")]
14764 UNSPEC_TLS_LD_BASE))
14765 (clobber (match_scratch:SI 3 "=d"))
14766 (clobber (match_scratch:SI 4 "=c"))
14767 (clobber (reg:CC FLAGS_REG))]
14768 "!TARGET_64BIT && TARGET_SUN_TLS"
14769 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14770 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14771 [(set_attr "type" "multi")
14772 (set_attr "length" "13")])
14774 (define_expand "tls_local_dynamic_base_32"
14775 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14776 (unspec:SI [(match_dup 1) (match_dup 2)]
14777 UNSPEC_TLS_LD_BASE))
14778 (clobber (match_scratch:SI 3 ""))
14779 (clobber (match_scratch:SI 4 ""))
14780 (clobber (reg:CC FLAGS_REG))])]
14784 operands[1] = pic_offset_table_rtx;
14787 operands[1] = gen_reg_rtx (Pmode);
14788 emit_insn (gen_set_got (operands[1]));
14790 if (TARGET_GNU2_TLS)
14792 emit_insn (gen_tls_dynamic_gnu2_32
14793 (operands[0], ix86_tls_module_base (), operands[1]));
14796 operands[2] = ix86_tls_get_addr ();
14799 (define_insn "*tls_local_dynamic_base_64"
14800 [(set (match_operand:DI 0 "register_operand" "=a")
14801 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14802 (match_operand:DI 2 "" "")))
14803 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14805 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14806 [(set_attr "type" "multi")
14807 (set_attr "length" "12")])
14809 (define_expand "tls_local_dynamic_base_64"
14810 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14811 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14812 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14815 if (TARGET_GNU2_TLS)
14817 emit_insn (gen_tls_dynamic_gnu2_64
14818 (operands[0], ix86_tls_module_base ()));
14821 operands[1] = ix86_tls_get_addr ();
14824 ;; Local dynamic of a single variable is a lose. Show combine how
14825 ;; to convert that back to global dynamic.
14827 (define_insn_and_split "*tls_local_dynamic_32_once"
14828 [(set (match_operand:SI 0 "register_operand" "=a")
14829 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14830 (match_operand:SI 2 "call_insn_operand" "")]
14831 UNSPEC_TLS_LD_BASE)
14832 (const:SI (unspec:SI
14833 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14835 (clobber (match_scratch:SI 4 "=d"))
14836 (clobber (match_scratch:SI 5 "=c"))
14837 (clobber (reg:CC FLAGS_REG))]
14841 [(parallel [(set (match_dup 0)
14842 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14844 (clobber (match_dup 4))
14845 (clobber (match_dup 5))
14846 (clobber (reg:CC FLAGS_REG))])]
14849 ;; Load and add the thread base pointer from %gs:0.
14851 (define_insn "*load_tp_si"
14852 [(set (match_operand:SI 0 "register_operand" "=r")
14853 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14855 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14856 [(set_attr "type" "imov")
14857 (set_attr "modrm" "0")
14858 (set_attr "length" "7")
14859 (set_attr "memory" "load")
14860 (set_attr "imm_disp" "false")])
14862 (define_insn "*add_tp_si"
14863 [(set (match_operand:SI 0 "register_operand" "=r")
14864 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14865 (match_operand:SI 1 "register_operand" "0")))
14866 (clobber (reg:CC FLAGS_REG))]
14868 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14869 [(set_attr "type" "alu")
14870 (set_attr "modrm" "0")
14871 (set_attr "length" "7")
14872 (set_attr "memory" "load")
14873 (set_attr "imm_disp" "false")])
14875 (define_insn "*load_tp_di"
14876 [(set (match_operand:DI 0 "register_operand" "=r")
14877 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14879 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14880 [(set_attr "type" "imov")
14881 (set_attr "modrm" "0")
14882 (set_attr "length" "7")
14883 (set_attr "memory" "load")
14884 (set_attr "imm_disp" "false")])
14886 (define_insn "*add_tp_di"
14887 [(set (match_operand:DI 0 "register_operand" "=r")
14888 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14889 (match_operand:DI 1 "register_operand" "0")))
14890 (clobber (reg:CC FLAGS_REG))]
14892 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14893 [(set_attr "type" "alu")
14894 (set_attr "modrm" "0")
14895 (set_attr "length" "7")
14896 (set_attr "memory" "load")
14897 (set_attr "imm_disp" "false")])
14899 ;; GNU2 TLS patterns can be split.
14901 (define_expand "tls_dynamic_gnu2_32"
14902 [(set (match_dup 3)
14903 (plus:SI (match_operand:SI 2 "register_operand" "")
14905 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14908 [(set (match_operand:SI 0 "register_operand" "")
14909 (unspec:SI [(match_dup 1) (match_dup 3)
14910 (match_dup 2) (reg:SI SP_REG)]
14912 (clobber (reg:CC FLAGS_REG))])]
14913 "!TARGET_64BIT && TARGET_GNU2_TLS"
14915 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14916 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14919 (define_insn "*tls_dynamic_lea_32"
14920 [(set (match_operand:SI 0 "register_operand" "=r")
14921 (plus:SI (match_operand:SI 1 "register_operand" "b")
14923 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14924 UNSPEC_TLSDESC))))]
14925 "!TARGET_64BIT && TARGET_GNU2_TLS"
14926 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14927 [(set_attr "type" "lea")
14928 (set_attr "mode" "SI")
14929 (set_attr "length" "6")
14930 (set_attr "length_address" "4")])
14932 (define_insn "*tls_dynamic_call_32"
14933 [(set (match_operand:SI 0 "register_operand" "=a")
14934 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14935 (match_operand:SI 2 "register_operand" "0")
14936 ;; we have to make sure %ebx still points to the GOT
14937 (match_operand:SI 3 "register_operand" "b")
14940 (clobber (reg:CC FLAGS_REG))]
14941 "!TARGET_64BIT && TARGET_GNU2_TLS"
14942 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14943 [(set_attr "type" "call")
14944 (set_attr "length" "2")
14945 (set_attr "length_address" "0")])
14947 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14948 [(set (match_operand:SI 0 "register_operand" "=&a")
14950 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14951 (match_operand:SI 4 "" "")
14952 (match_operand:SI 2 "register_operand" "b")
14955 (const:SI (unspec:SI
14956 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14958 (clobber (reg:CC FLAGS_REG))]
14959 "!TARGET_64BIT && TARGET_GNU2_TLS"
14962 [(set (match_dup 0) (match_dup 5))]
14964 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14965 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14968 (define_expand "tls_dynamic_gnu2_64"
14969 [(set (match_dup 2)
14970 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14973 [(set (match_operand:DI 0 "register_operand" "")
14974 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14976 (clobber (reg:CC FLAGS_REG))])]
14977 "TARGET_64BIT && TARGET_GNU2_TLS"
14979 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14980 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14983 (define_insn "*tls_dynamic_lea_64"
14984 [(set (match_operand:DI 0 "register_operand" "=r")
14985 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14987 "TARGET_64BIT && TARGET_GNU2_TLS"
14988 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14989 [(set_attr "type" "lea")
14990 (set_attr "mode" "DI")
14991 (set_attr "length" "7")
14992 (set_attr "length_address" "4")])
14994 (define_insn "*tls_dynamic_call_64"
14995 [(set (match_operand:DI 0 "register_operand" "=a")
14996 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14997 (match_operand:DI 2 "register_operand" "0")
15000 (clobber (reg:CC FLAGS_REG))]
15001 "TARGET_64BIT && TARGET_GNU2_TLS"
15002 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15003 [(set_attr "type" "call")
15004 (set_attr "length" "2")
15005 (set_attr "length_address" "0")])
15007 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15008 [(set (match_operand:DI 0 "register_operand" "=&a")
15010 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15011 (match_operand:DI 3 "" "")
15014 (const:DI (unspec:DI
15015 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15017 (clobber (reg:CC FLAGS_REG))]
15018 "TARGET_64BIT && TARGET_GNU2_TLS"
15021 [(set (match_dup 0) (match_dup 4))]
15023 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15024 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15029 ;; These patterns match the binary 387 instructions for addM3, subM3,
15030 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15031 ;; SFmode. The first is the normal insn, the second the same insn but
15032 ;; with one operand a conversion, and the third the same insn but with
15033 ;; the other operand a conversion. The conversion may be SFmode or
15034 ;; SImode if the target mode DFmode, but only SImode if the target mode
15037 ;; Gcc is slightly more smart about handling normal two address instructions
15038 ;; so use special patterns for add and mull.
15040 (define_insn "*fop_sf_comm_mixed"
15041 [(set (match_operand:SF 0 "register_operand" "=f,x")
15042 (match_operator:SF 3 "binary_fp_operator"
15043 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15044 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15045 "TARGET_MIX_SSE_I387
15046 && COMMUTATIVE_ARITH_P (operands[3])
15047 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15048 "* return output_387_binary_op (insn, operands);"
15049 [(set (attr "type")
15050 (if_then_else (eq_attr "alternative" "1")
15051 (if_then_else (match_operand:SF 3 "mult_operator" "")
15052 (const_string "ssemul")
15053 (const_string "sseadd"))
15054 (if_then_else (match_operand:SF 3 "mult_operator" "")
15055 (const_string "fmul")
15056 (const_string "fop"))))
15057 (set_attr "mode" "SF")])
15059 (define_insn "*fop_sf_comm_sse"
15060 [(set (match_operand:SF 0 "register_operand" "=x")
15061 (match_operator:SF 3 "binary_fp_operator"
15062 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15063 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15065 && COMMUTATIVE_ARITH_P (operands[3])
15066 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15067 "* return output_387_binary_op (insn, operands);"
15068 [(set (attr "type")
15069 (if_then_else (match_operand:SF 3 "mult_operator" "")
15070 (const_string "ssemul")
15071 (const_string "sseadd")))
15072 (set_attr "mode" "SF")])
15074 (define_insn "*fop_sf_comm_i387"
15075 [(set (match_operand:SF 0 "register_operand" "=f")
15076 (match_operator:SF 3 "binary_fp_operator"
15077 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15078 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15080 && COMMUTATIVE_ARITH_P (operands[3])
15081 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15082 "* return output_387_binary_op (insn, operands);"
15083 [(set (attr "type")
15084 (if_then_else (match_operand:SF 3 "mult_operator" "")
15085 (const_string "fmul")
15086 (const_string "fop")))
15087 (set_attr "mode" "SF")])
15089 (define_insn "*fop_sf_1_mixed"
15090 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15091 (match_operator:SF 3 "binary_fp_operator"
15092 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15093 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15094 "TARGET_MIX_SSE_I387
15095 && !COMMUTATIVE_ARITH_P (operands[3])
15096 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15097 "* return output_387_binary_op (insn, operands);"
15098 [(set (attr "type")
15099 (cond [(and (eq_attr "alternative" "2")
15100 (match_operand:SF 3 "mult_operator" ""))
15101 (const_string "ssemul")
15102 (and (eq_attr "alternative" "2")
15103 (match_operand:SF 3 "div_operator" ""))
15104 (const_string "ssediv")
15105 (eq_attr "alternative" "2")
15106 (const_string "sseadd")
15107 (match_operand:SF 3 "mult_operator" "")
15108 (const_string "fmul")
15109 (match_operand:SF 3 "div_operator" "")
15110 (const_string "fdiv")
15112 (const_string "fop")))
15113 (set_attr "mode" "SF")])
15115 (define_insn "*fop_sf_1_sse"
15116 [(set (match_operand:SF 0 "register_operand" "=x")
15117 (match_operator:SF 3 "binary_fp_operator"
15118 [(match_operand:SF 1 "register_operand" "0")
15119 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15121 && !COMMUTATIVE_ARITH_P (operands[3])"
15122 "* return output_387_binary_op (insn, operands);"
15123 [(set (attr "type")
15124 (cond [(match_operand:SF 3 "mult_operator" "")
15125 (const_string "ssemul")
15126 (match_operand:SF 3 "div_operator" "")
15127 (const_string "ssediv")
15129 (const_string "sseadd")))
15130 (set_attr "mode" "SF")])
15132 ;; This pattern is not fully shadowed by the pattern above.
15133 (define_insn "*fop_sf_1_i387"
15134 [(set (match_operand:SF 0 "register_operand" "=f,f")
15135 (match_operator:SF 3 "binary_fp_operator"
15136 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15137 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15138 "TARGET_80387 && !TARGET_SSE_MATH
15139 && !COMMUTATIVE_ARITH_P (operands[3])
15140 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15141 "* return output_387_binary_op (insn, operands);"
15142 [(set (attr "type")
15143 (cond [(match_operand:SF 3 "mult_operator" "")
15144 (const_string "fmul")
15145 (match_operand:SF 3 "div_operator" "")
15146 (const_string "fdiv")
15148 (const_string "fop")))
15149 (set_attr "mode" "SF")])
15151 ;; ??? Add SSE splitters for these!
15152 (define_insn "*fop_sf_2<mode>_i387"
15153 [(set (match_operand:SF 0 "register_operand" "=f,f")
15154 (match_operator:SF 3 "binary_fp_operator"
15155 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15156 (match_operand:SF 2 "register_operand" "0,0")]))]
15157 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15158 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15159 [(set (attr "type")
15160 (cond [(match_operand:SF 3 "mult_operator" "")
15161 (const_string "fmul")
15162 (match_operand:SF 3 "div_operator" "")
15163 (const_string "fdiv")
15165 (const_string "fop")))
15166 (set_attr "fp_int_src" "true")
15167 (set_attr "mode" "<MODE>")])
15169 (define_insn "*fop_sf_3<mode>_i387"
15170 [(set (match_operand:SF 0 "register_operand" "=f,f")
15171 (match_operator:SF 3 "binary_fp_operator"
15172 [(match_operand:SF 1 "register_operand" "0,0")
15173 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15174 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15175 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15176 [(set (attr "type")
15177 (cond [(match_operand:SF 3 "mult_operator" "")
15178 (const_string "fmul")
15179 (match_operand:SF 3 "div_operator" "")
15180 (const_string "fdiv")
15182 (const_string "fop")))
15183 (set_attr "fp_int_src" "true")
15184 (set_attr "mode" "<MODE>")])
15186 (define_insn "*fop_df_comm_mixed"
15187 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15188 (match_operator:DF 3 "binary_fp_operator"
15189 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15190 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15191 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15192 && COMMUTATIVE_ARITH_P (operands[3])
15193 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15194 "* return output_387_binary_op (insn, operands);"
15195 [(set (attr "type")
15196 (if_then_else (eq_attr "alternative" "1")
15197 (if_then_else (match_operand:DF 3 "mult_operator" "")
15198 (const_string "ssemul")
15199 (const_string "sseadd"))
15200 (if_then_else (match_operand:DF 3 "mult_operator" "")
15201 (const_string "fmul")
15202 (const_string "fop"))))
15203 (set_attr "mode" "DF")])
15205 (define_insn "*fop_df_comm_sse"
15206 [(set (match_operand:DF 0 "register_operand" "=Y")
15207 (match_operator:DF 3 "binary_fp_operator"
15208 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15209 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15210 "TARGET_SSE2 && TARGET_SSE_MATH
15211 && COMMUTATIVE_ARITH_P (operands[3])
15212 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15213 "* return output_387_binary_op (insn, operands);"
15214 [(set (attr "type")
15215 (if_then_else (match_operand:DF 3 "mult_operator" "")
15216 (const_string "ssemul")
15217 (const_string "sseadd")))
15218 (set_attr "mode" "DF")])
15220 (define_insn "*fop_df_comm_i387"
15221 [(set (match_operand:DF 0 "register_operand" "=f")
15222 (match_operator:DF 3 "binary_fp_operator"
15223 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15224 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15226 && COMMUTATIVE_ARITH_P (operands[3])
15227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15228 "* return output_387_binary_op (insn, operands);"
15229 [(set (attr "type")
15230 (if_then_else (match_operand:DF 3 "mult_operator" "")
15231 (const_string "fmul")
15232 (const_string "fop")))
15233 (set_attr "mode" "DF")])
15235 (define_insn "*fop_df_1_mixed"
15236 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15237 (match_operator:DF 3 "binary_fp_operator"
15238 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15239 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15240 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15241 && !COMMUTATIVE_ARITH_P (operands[3])
15242 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15243 "* return output_387_binary_op (insn, operands);"
15244 [(set (attr "type")
15245 (cond [(and (eq_attr "alternative" "2")
15246 (match_operand:DF 3 "mult_operator" ""))
15247 (const_string "ssemul")
15248 (and (eq_attr "alternative" "2")
15249 (match_operand:DF 3 "div_operator" ""))
15250 (const_string "ssediv")
15251 (eq_attr "alternative" "2")
15252 (const_string "sseadd")
15253 (match_operand:DF 3 "mult_operator" "")
15254 (const_string "fmul")
15255 (match_operand:DF 3 "div_operator" "")
15256 (const_string "fdiv")
15258 (const_string "fop")))
15259 (set_attr "mode" "DF")])
15261 (define_insn "*fop_df_1_sse"
15262 [(set (match_operand:DF 0 "register_operand" "=Y")
15263 (match_operator:DF 3 "binary_fp_operator"
15264 [(match_operand:DF 1 "register_operand" "0")
15265 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15266 "TARGET_SSE2 && TARGET_SSE_MATH
15267 && !COMMUTATIVE_ARITH_P (operands[3])"
15268 "* return output_387_binary_op (insn, operands);"
15269 [(set_attr "mode" "DF")
15271 (cond [(match_operand:DF 3 "mult_operator" "")
15272 (const_string "ssemul")
15273 (match_operand:DF 3 "div_operator" "")
15274 (const_string "ssediv")
15276 (const_string "sseadd")))])
15278 ;; This pattern is not fully shadowed by the pattern above.
15279 (define_insn "*fop_df_1_i387"
15280 [(set (match_operand:DF 0 "register_operand" "=f,f")
15281 (match_operator:DF 3 "binary_fp_operator"
15282 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15283 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15284 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15285 && !COMMUTATIVE_ARITH_P (operands[3])
15286 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15287 "* return output_387_binary_op (insn, operands);"
15288 [(set (attr "type")
15289 (cond [(match_operand:DF 3 "mult_operator" "")
15290 (const_string "fmul")
15291 (match_operand:DF 3 "div_operator" "")
15292 (const_string "fdiv")
15294 (const_string "fop")))
15295 (set_attr "mode" "DF")])
15297 ;; ??? Add SSE splitters for these!
15298 (define_insn "*fop_df_2<mode>_i387"
15299 [(set (match_operand:DF 0 "register_operand" "=f,f")
15300 (match_operator:DF 3 "binary_fp_operator"
15301 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15302 (match_operand:DF 2 "register_operand" "0,0")]))]
15303 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15304 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15305 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15306 [(set (attr "type")
15307 (cond [(match_operand:DF 3 "mult_operator" "")
15308 (const_string "fmul")
15309 (match_operand:DF 3 "div_operator" "")
15310 (const_string "fdiv")
15312 (const_string "fop")))
15313 (set_attr "fp_int_src" "true")
15314 (set_attr "mode" "<MODE>")])
15316 (define_insn "*fop_df_3<mode>_i387"
15317 [(set (match_operand:DF 0 "register_operand" "=f,f")
15318 (match_operator:DF 3 "binary_fp_operator"
15319 [(match_operand:DF 1 "register_operand" "0,0")
15320 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15321 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15322 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15323 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15324 [(set (attr "type")
15325 (cond [(match_operand:DF 3 "mult_operator" "")
15326 (const_string "fmul")
15327 (match_operand:DF 3 "div_operator" "")
15328 (const_string "fdiv")
15330 (const_string "fop")))
15331 (set_attr "fp_int_src" "true")
15332 (set_attr "mode" "<MODE>")])
15334 (define_insn "*fop_df_4_i387"
15335 [(set (match_operand:DF 0 "register_operand" "=f,f")
15336 (match_operator:DF 3 "binary_fp_operator"
15337 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15338 (match_operand:DF 2 "register_operand" "0,f")]))]
15339 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15340 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15341 "* return output_387_binary_op (insn, operands);"
15342 [(set (attr "type")
15343 (cond [(match_operand:DF 3 "mult_operator" "")
15344 (const_string "fmul")
15345 (match_operand:DF 3 "div_operator" "")
15346 (const_string "fdiv")
15348 (const_string "fop")))
15349 (set_attr "mode" "SF")])
15351 (define_insn "*fop_df_5_i387"
15352 [(set (match_operand:DF 0 "register_operand" "=f,f")
15353 (match_operator:DF 3 "binary_fp_operator"
15354 [(match_operand:DF 1 "register_operand" "0,f")
15356 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15357 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15358 "* return output_387_binary_op (insn, operands);"
15359 [(set (attr "type")
15360 (cond [(match_operand:DF 3 "mult_operator" "")
15361 (const_string "fmul")
15362 (match_operand:DF 3 "div_operator" "")
15363 (const_string "fdiv")
15365 (const_string "fop")))
15366 (set_attr "mode" "SF")])
15368 (define_insn "*fop_df_6_i387"
15369 [(set (match_operand:DF 0 "register_operand" "=f,f")
15370 (match_operator:DF 3 "binary_fp_operator"
15372 (match_operand:SF 1 "register_operand" "0,f"))
15374 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15375 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15376 "* return output_387_binary_op (insn, operands);"
15377 [(set (attr "type")
15378 (cond [(match_operand:DF 3 "mult_operator" "")
15379 (const_string "fmul")
15380 (match_operand:DF 3 "div_operator" "")
15381 (const_string "fdiv")
15383 (const_string "fop")))
15384 (set_attr "mode" "SF")])
15386 (define_insn "*fop_xf_comm_i387"
15387 [(set (match_operand:XF 0 "register_operand" "=f")
15388 (match_operator:XF 3 "binary_fp_operator"
15389 [(match_operand:XF 1 "register_operand" "%0")
15390 (match_operand:XF 2 "register_operand" "f")]))]
15392 && COMMUTATIVE_ARITH_P (operands[3])"
15393 "* return output_387_binary_op (insn, operands);"
15394 [(set (attr "type")
15395 (if_then_else (match_operand:XF 3 "mult_operator" "")
15396 (const_string "fmul")
15397 (const_string "fop")))
15398 (set_attr "mode" "XF")])
15400 (define_insn "*fop_xf_1_i387"
15401 [(set (match_operand:XF 0 "register_operand" "=f,f")
15402 (match_operator:XF 3 "binary_fp_operator"
15403 [(match_operand:XF 1 "register_operand" "0,f")
15404 (match_operand:XF 2 "register_operand" "f,0")]))]
15406 && !COMMUTATIVE_ARITH_P (operands[3])"
15407 "* return output_387_binary_op (insn, operands);"
15408 [(set (attr "type")
15409 (cond [(match_operand:XF 3 "mult_operator" "")
15410 (const_string "fmul")
15411 (match_operand:XF 3 "div_operator" "")
15412 (const_string "fdiv")
15414 (const_string "fop")))
15415 (set_attr "mode" "XF")])
15417 (define_insn "*fop_xf_2<mode>_i387"
15418 [(set (match_operand:XF 0 "register_operand" "=f,f")
15419 (match_operator:XF 3 "binary_fp_operator"
15420 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15421 (match_operand:XF 2 "register_operand" "0,0")]))]
15422 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15423 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15424 [(set (attr "type")
15425 (cond [(match_operand:XF 3 "mult_operator" "")
15426 (const_string "fmul")
15427 (match_operand:XF 3 "div_operator" "")
15428 (const_string "fdiv")
15430 (const_string "fop")))
15431 (set_attr "fp_int_src" "true")
15432 (set_attr "mode" "<MODE>")])
15434 (define_insn "*fop_xf_3<mode>_i387"
15435 [(set (match_operand:XF 0 "register_operand" "=f,f")
15436 (match_operator:XF 3 "binary_fp_operator"
15437 [(match_operand:XF 1 "register_operand" "0,0")
15438 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15439 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15440 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15441 [(set (attr "type")
15442 (cond [(match_operand:XF 3 "mult_operator" "")
15443 (const_string "fmul")
15444 (match_operand:XF 3 "div_operator" "")
15445 (const_string "fdiv")
15447 (const_string "fop")))
15448 (set_attr "fp_int_src" "true")
15449 (set_attr "mode" "<MODE>")])
15451 (define_insn "*fop_xf_4_i387"
15452 [(set (match_operand:XF 0 "register_operand" "=f,f")
15453 (match_operator:XF 3 "binary_fp_operator"
15455 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15456 (match_operand:XF 2 "register_operand" "0,f")]))]
15458 "* return output_387_binary_op (insn, operands);"
15459 [(set (attr "type")
15460 (cond [(match_operand:XF 3 "mult_operator" "")
15461 (const_string "fmul")
15462 (match_operand:XF 3 "div_operator" "")
15463 (const_string "fdiv")
15465 (const_string "fop")))
15466 (set_attr "mode" "SF")])
15468 (define_insn "*fop_xf_5_i387"
15469 [(set (match_operand:XF 0 "register_operand" "=f,f")
15470 (match_operator:XF 3 "binary_fp_operator"
15471 [(match_operand:XF 1 "register_operand" "0,f")
15473 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15475 "* return output_387_binary_op (insn, operands);"
15476 [(set (attr "type")
15477 (cond [(match_operand:XF 3 "mult_operator" "")
15478 (const_string "fmul")
15479 (match_operand:XF 3 "div_operator" "")
15480 (const_string "fdiv")
15482 (const_string "fop")))
15483 (set_attr "mode" "SF")])
15485 (define_insn "*fop_xf_6_i387"
15486 [(set (match_operand:XF 0 "register_operand" "=f,f")
15487 (match_operator:XF 3 "binary_fp_operator"
15489 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15491 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15493 "* return output_387_binary_op (insn, operands);"
15494 [(set (attr "type")
15495 (cond [(match_operand:XF 3 "mult_operator" "")
15496 (const_string "fmul")
15497 (match_operand:XF 3 "div_operator" "")
15498 (const_string "fdiv")
15500 (const_string "fop")))
15501 (set_attr "mode" "SF")])
15504 [(set (match_operand 0 "register_operand" "")
15505 (match_operator 3 "binary_fp_operator"
15506 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15507 (match_operand 2 "register_operand" "")]))]
15508 "TARGET_80387 && reload_completed
15509 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15512 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15513 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15514 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15515 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15516 GET_MODE (operands[3]),
15519 ix86_free_from_memory (GET_MODE (operands[1]));
15524 [(set (match_operand 0 "register_operand" "")
15525 (match_operator 3 "binary_fp_operator"
15526 [(match_operand 1 "register_operand" "")
15527 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15528 "TARGET_80387 && reload_completed
15529 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15532 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15533 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15534 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15535 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15536 GET_MODE (operands[3]),
15539 ix86_free_from_memory (GET_MODE (operands[2]));
15543 ;; FPU special functions.
15545 ;; This pattern implements a no-op XFmode truncation for
15546 ;; all fancy i386 XFmode math functions.
15548 (define_insn "truncxf<mode>2_i387_noop_unspec"
15549 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15550 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15551 UNSPEC_TRUNC_NOOP))]
15552 "TARGET_USE_FANCY_MATH_387"
15553 "* return output_387_reg_move (insn, operands);"
15554 [(set_attr "type" "fmov")
15555 (set_attr "mode" "<MODE>")])
15557 (define_insn "sqrtxf2"
15558 [(set (match_operand:XF 0 "register_operand" "=f")
15559 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15560 "TARGET_USE_FANCY_MATH_387"
15562 [(set_attr "type" "fpspc")
15563 (set_attr "mode" "XF")
15564 (set_attr "athlon_decode" "direct")])
15566 (define_insn "sqrt_extend<mode>xf2_i387"
15567 [(set (match_operand:XF 0 "register_operand" "=f")
15570 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15571 "TARGET_USE_FANCY_MATH_387"
15573 [(set_attr "type" "fpspc")
15574 (set_attr "mode" "XF")
15575 (set_attr "athlon_decode" "direct")])
15577 (define_insn "*sqrt<mode>2_sse"
15578 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15580 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15581 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15582 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15583 [(set_attr "type" "sse")
15584 (set_attr "mode" "<MODE>")
15585 (set_attr "athlon_decode" "*")])
15587 (define_expand "sqrt<mode>2"
15588 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15590 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15591 "TARGET_USE_FANCY_MATH_387
15592 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15594 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15596 rtx op0 = gen_reg_rtx (XFmode);
15597 rtx op1 = force_reg (<MODE>mode, operands[1]);
15599 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15600 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15605 (define_insn "fpremxf4_i387"
15606 [(set (match_operand:XF 0 "register_operand" "=f")
15607 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15608 (match_operand:XF 3 "register_operand" "1")]
15610 (set (match_operand:XF 1 "register_operand" "=u")
15611 (unspec:XF [(match_dup 2) (match_dup 3)]
15613 (set (reg:CCFP FPSR_REG)
15614 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15615 "TARGET_USE_FANCY_MATH_387"
15617 [(set_attr "type" "fpspc")
15618 (set_attr "mode" "XF")])
15620 (define_expand "fmodxf3"
15621 [(use (match_operand:XF 0 "register_operand" ""))
15622 (use (match_operand:XF 1 "register_operand" ""))
15623 (use (match_operand:XF 2 "register_operand" ""))]
15624 "TARGET_USE_FANCY_MATH_387"
15626 rtx label = gen_label_rtx ();
15628 emit_label (label);
15630 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15631 operands[1], operands[2]));
15632 ix86_emit_fp_unordered_jump (label);
15634 emit_move_insn (operands[0], operands[1]);
15638 (define_expand "fmod<mode>3"
15639 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15640 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15641 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15642 "TARGET_USE_FANCY_MATH_387"
15644 rtx label = gen_label_rtx ();
15646 rtx op1 = gen_reg_rtx (XFmode);
15647 rtx op2 = gen_reg_rtx (XFmode);
15649 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15650 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15652 emit_label (label);
15653 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15654 ix86_emit_fp_unordered_jump (label);
15656 /* Truncate the result properly for strict SSE math. */
15657 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15658 && !TARGET_MIX_SSE_I387)
15659 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15661 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15666 (define_insn "fprem1xf4_i387"
15667 [(set (match_operand:XF 0 "register_operand" "=f")
15668 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15669 (match_operand:XF 3 "register_operand" "1")]
15671 (set (match_operand:XF 1 "register_operand" "=u")
15672 (unspec:XF [(match_dup 2) (match_dup 3)]
15674 (set (reg:CCFP FPSR_REG)
15675 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15676 "TARGET_USE_FANCY_MATH_387"
15678 [(set_attr "type" "fpspc")
15679 (set_attr "mode" "XF")])
15681 (define_expand "remainderxf3"
15682 [(use (match_operand:XF 0 "register_operand" ""))
15683 (use (match_operand:XF 1 "register_operand" ""))
15684 (use (match_operand:XF 2 "register_operand" ""))]
15685 "TARGET_USE_FANCY_MATH_387"
15687 rtx label = gen_label_rtx ();
15689 emit_label (label);
15691 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15692 operands[1], operands[2]));
15693 ix86_emit_fp_unordered_jump (label);
15695 emit_move_insn (operands[0], operands[1]);
15699 (define_expand "remainder<mode>3"
15700 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15701 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15702 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15703 "TARGET_USE_FANCY_MATH_387"
15705 rtx label = gen_label_rtx ();
15707 rtx op1 = gen_reg_rtx (XFmode);
15708 rtx op2 = gen_reg_rtx (XFmode);
15710 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15711 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15713 emit_label (label);
15715 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15716 ix86_emit_fp_unordered_jump (label);
15718 /* Truncate the result properly for strict SSE math. */
15719 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15720 && !TARGET_MIX_SSE_I387)
15721 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15723 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15728 (define_insn "*sinxf2_i387"
15729 [(set (match_operand:XF 0 "register_operand" "=f")
15730 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15731 "TARGET_USE_FANCY_MATH_387
15732 && flag_unsafe_math_optimizations"
15734 [(set_attr "type" "fpspc")
15735 (set_attr "mode" "XF")])
15737 (define_insn "*sin_extend<mode>xf2_i387"
15738 [(set (match_operand:XF 0 "register_operand" "=f")
15739 (unspec:XF [(float_extend:XF
15740 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15742 "TARGET_USE_FANCY_MATH_387
15743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744 || TARGET_MIX_SSE_I387)
15745 && flag_unsafe_math_optimizations"
15747 [(set_attr "type" "fpspc")
15748 (set_attr "mode" "XF")])
15750 (define_insn "*cosxf2_i387"
15751 [(set (match_operand:XF 0 "register_operand" "=f")
15752 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15753 "TARGET_USE_FANCY_MATH_387
15754 && flag_unsafe_math_optimizations"
15756 [(set_attr "type" "fpspc")
15757 (set_attr "mode" "XF")])
15759 (define_insn "*cos_extend<mode>xf2_i387"
15760 [(set (match_operand:XF 0 "register_operand" "=f")
15761 (unspec:XF [(float_extend:XF
15762 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15764 "TARGET_USE_FANCY_MATH_387
15765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15766 || TARGET_MIX_SSE_I387)
15767 && flag_unsafe_math_optimizations"
15769 [(set_attr "type" "fpspc")
15770 (set_attr "mode" "XF")])
15772 ;; When sincos pattern is defined, sin and cos builtin functions will be
15773 ;; expanded to sincos pattern with one of its outputs left unused.
15774 ;; CSE pass will figure out if two sincos patterns can be combined,
15775 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15776 ;; depending on the unused output.
15778 (define_insn "sincosxf3"
15779 [(set (match_operand:XF 0 "register_operand" "=f")
15780 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15781 UNSPEC_SINCOS_COS))
15782 (set (match_operand:XF 1 "register_operand" "=u")
15783 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15784 "TARGET_USE_FANCY_MATH_387
15785 && flag_unsafe_math_optimizations"
15787 [(set_attr "type" "fpspc")
15788 (set_attr "mode" "XF")])
15791 [(set (match_operand:XF 0 "register_operand" "")
15792 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15793 UNSPEC_SINCOS_COS))
15794 (set (match_operand:XF 1 "register_operand" "")
15795 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15796 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15797 && !reload_completed && !reload_in_progress"
15798 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15802 [(set (match_operand:XF 0 "register_operand" "")
15803 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15804 UNSPEC_SINCOS_COS))
15805 (set (match_operand:XF 1 "register_operand" "")
15806 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15807 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15808 && !reload_completed && !reload_in_progress"
15809 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15812 (define_insn "sincos_extend<mode>xf3_i387"
15813 [(set (match_operand:XF 0 "register_operand" "=f")
15814 (unspec:XF [(float_extend:XF
15815 (match_operand:X87MODEF12 2 "register_operand" "0"))]
15816 UNSPEC_SINCOS_COS))
15817 (set (match_operand:XF 1 "register_operand" "=u")
15818 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15819 "TARGET_USE_FANCY_MATH_387
15820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15821 || TARGET_MIX_SSE_I387)
15822 && flag_unsafe_math_optimizations"
15824 [(set_attr "type" "fpspc")
15825 (set_attr "mode" "XF")])
15828 [(set (match_operand:XF 0 "register_operand" "")
15829 (unspec:XF [(float_extend:XF
15830 (match_operand:X87MODEF12 2 "register_operand" ""))]
15831 UNSPEC_SINCOS_COS))
15832 (set (match_operand:XF 1 "register_operand" "")
15833 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15834 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15835 && !reload_completed && !reload_in_progress"
15836 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15840 [(set (match_operand:XF 0 "register_operand" "")
15841 (unspec:XF [(float_extend:XF
15842 (match_operand:X87MODEF12 2 "register_operand" ""))]
15843 UNSPEC_SINCOS_COS))
15844 (set (match_operand:XF 1 "register_operand" "")
15845 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15846 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15847 && !reload_completed && !reload_in_progress"
15848 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15851 (define_expand "sincos<mode>3"
15852 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15853 (use (match_operand:X87MODEF12 1 "register_operand" ""))
15854 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15855 "TARGET_USE_FANCY_MATH_387
15856 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15857 || TARGET_MIX_SSE_I387)
15858 && flag_unsafe_math_optimizations"
15860 rtx op0 = gen_reg_rtx (XFmode);
15861 rtx op1 = gen_reg_rtx (XFmode);
15863 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15864 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15865 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15869 (define_insn "fptanxf4_i387"
15870 [(set (match_operand:XF 0 "register_operand" "=f")
15871 (match_operand:XF 3 "const_double_operand" "F"))
15872 (set (match_operand:XF 1 "register_operand" "=u")
15873 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15875 "TARGET_USE_FANCY_MATH_387
15876 && flag_unsafe_math_optimizations
15877 && standard_80387_constant_p (operands[3]) == 2"
15879 [(set_attr "type" "fpspc")
15880 (set_attr "mode" "XF")])
15882 (define_insn "fptan_extend<mode>xf4_i387"
15883 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15884 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
15885 (set (match_operand:XF 1 "register_operand" "=u")
15886 (unspec:XF [(float_extend:XF
15887 (match_operand:X87MODEF12 2 "register_operand" "0"))]
15889 "TARGET_USE_FANCY_MATH_387
15890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15891 || TARGET_MIX_SSE_I387)
15892 && flag_unsafe_math_optimizations
15893 && standard_80387_constant_p (operands[3]) == 2"
15895 [(set_attr "type" "fpspc")
15896 (set_attr "mode" "XF")])
15898 (define_expand "tanxf2"
15899 [(use (match_operand:XF 0 "register_operand" ""))
15900 (use (match_operand:XF 1 "register_operand" ""))]
15901 "TARGET_USE_FANCY_MATH_387
15902 && flag_unsafe_math_optimizations"
15904 rtx one = gen_reg_rtx (XFmode);
15905 operands[2] = CONST1_RTX (XFmode); /* fld1 */
15907 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], operands[2]));
15911 (define_expand "tan<mode>2"
15912 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15913 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
15914 "TARGET_USE_FANCY_MATH_387
15915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15916 || TARGET_MIX_SSE_I387)
15917 && flag_unsafe_math_optimizations"
15919 rtx op0 = gen_reg_rtx (XFmode);
15921 rtx one = gen_reg_rtx (<MODE>mode);
15922 operands[2] = CONST1_RTX (<MODE>mode); /* fld1 */
15924 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15925 operands[1], operands[2]));
15926 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15930 (define_insn "*fpatanxf3_i387"
15931 [(set (match_operand:XF 0 "register_operand" "=f")
15932 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15933 (match_operand:XF 2 "register_operand" "u")]
15935 (clobber (match_scratch:XF 3 "=2"))]
15936 "TARGET_USE_FANCY_MATH_387
15937 && flag_unsafe_math_optimizations"
15939 [(set_attr "type" "fpspc")
15940 (set_attr "mode" "XF")])
15942 (define_insn "fpatan_extend<mode>xf3_i387"
15943 [(set (match_operand:XF 0 "register_operand" "=f")
15944 (unspec:XF [(float_extend:XF
15945 (match_operand:X87MODEF12 1 "register_operand" "0"))
15947 (match_operand:X87MODEF12 2 "register_operand" "u"))]
15949 (clobber (match_scratch:XF 3 "=2"))]
15950 "TARGET_USE_FANCY_MATH_387
15951 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15952 || TARGET_MIX_SSE_I387)
15953 && flag_unsafe_math_optimizations"
15955 [(set_attr "type" "fpspc")
15956 (set_attr "mode" "XF")])
15958 (define_expand "atan2xf3"
15959 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15960 (unspec:XF [(match_operand:XF 2 "register_operand" "")
15961 (match_operand:XF 1 "register_operand" "")]
15963 (clobber (match_scratch:XF 3 ""))])]
15964 "TARGET_USE_FANCY_MATH_387
15965 && flag_unsafe_math_optimizations"
15968 (define_expand "atan2<mode>3"
15969 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15970 (use (match_operand:X87MODEF12 1 "register_operand" ""))
15971 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15972 "TARGET_USE_FANCY_MATH_387
15973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15974 || TARGET_MIX_SSE_I387)
15975 && flag_unsafe_math_optimizations"
15977 rtx op0 = gen_reg_rtx (XFmode);
15979 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15980 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15984 (define_expand "atanxf2"
15985 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15986 (unspec:XF [(match_dup 2)
15987 (match_operand:XF 1 "register_operand" "")]
15989 (clobber (match_scratch:XF 3 ""))])]
15990 "TARGET_USE_FANCY_MATH_387
15991 && flag_unsafe_math_optimizations"
15993 operands[2] = gen_reg_rtx (XFmode);
15994 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15997 (define_expand "atan<mode>2"
15998 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15999 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16000 "TARGET_USE_FANCY_MATH_387
16001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16002 || TARGET_MIX_SSE_I387)
16003 && flag_unsafe_math_optimizations"
16005 rtx op0 = gen_reg_rtx (XFmode);
16007 operands[2] = gen_reg_rtx (<MODE>mode);
16008 emit_move_insn (operands[2], CONST1_RTX (<MODE>mode)); /* fld1 */
16010 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16011 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16015 (define_expand "asinxf2"
16016 [(set (match_dup 2)
16017 (mult:XF (match_operand:XF 1 "register_operand" "")
16019 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16020 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16021 (parallel [(set (match_operand:XF 0 "register_operand" "")
16022 (unspec:XF [(match_dup 5) (match_dup 1)]
16024 (clobber (match_scratch:XF 6 ""))])]
16025 "TARGET_USE_FANCY_MATH_387
16026 && flag_unsafe_math_optimizations && !optimize_size"
16030 for (i = 2; i < 6; i++)
16031 operands[i] = gen_reg_rtx (XFmode);
16033 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16036 (define_expand "asin<mode>2"
16037 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16038 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16039 "TARGET_USE_FANCY_MATH_387
16040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16041 || TARGET_MIX_SSE_I387)
16042 && flag_unsafe_math_optimizations && !optimize_size"
16044 rtx op0 = gen_reg_rtx (XFmode);
16045 rtx op1 = gen_reg_rtx (XFmode);
16047 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16048 emit_insn (gen_asinxf2 (op0, op1));
16049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16053 (define_expand "acosxf2"
16054 [(set (match_dup 2)
16055 (mult:XF (match_operand:XF 1 "register_operand" "")
16057 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16058 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16059 (parallel [(set (match_operand:XF 0 "register_operand" "")
16060 (unspec:XF [(match_dup 1) (match_dup 5)]
16062 (clobber (match_scratch:XF 6 ""))])]
16063 "TARGET_USE_FANCY_MATH_387
16064 && flag_unsafe_math_optimizations && !optimize_size"
16068 for (i = 2; i < 6; i++)
16069 operands[i] = gen_reg_rtx (XFmode);
16071 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16074 (define_expand "acos<mode>2"
16075 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16076 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16077 "TARGET_USE_FANCY_MATH_387
16078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16079 || TARGET_MIX_SSE_I387)
16080 && flag_unsafe_math_optimizations && !optimize_size"
16082 rtx op0 = gen_reg_rtx (XFmode);
16083 rtx op1 = gen_reg_rtx (XFmode);
16085 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16086 emit_insn (gen_acosxf2 (op0, op1));
16087 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16091 (define_insn "fyl2xxf3_i387"
16092 [(set (match_operand:XF 0 "register_operand" "=f")
16093 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16094 (match_operand:XF 2 "register_operand" "u")]
16096 (clobber (match_scratch:XF 3 "=2"))]
16097 "TARGET_USE_FANCY_MATH_387
16098 && flag_unsafe_math_optimizations"
16100 [(set_attr "type" "fpspc")
16101 (set_attr "mode" "XF")])
16103 (define_insn "fyl2x_extend<mode>xf3_i387"
16104 [(set (match_operand:XF 0 "register_operand" "=f")
16105 (unspec:XF [(float_extend:XF
16106 (match_operand:X87MODEF12 1 "register_operand" "0"))
16107 (match_operand:XF 2 "register_operand" "u")]
16109 (clobber (match_scratch:XF 3 "=2"))]
16110 "TARGET_USE_FANCY_MATH_387
16111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16112 || TARGET_MIX_SSE_I387)
16113 && flag_unsafe_math_optimizations"
16115 [(set_attr "type" "fpspc")
16116 (set_attr "mode" "XF")])
16118 (define_expand "logxf2"
16119 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16120 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16121 (match_dup 2)] UNSPEC_FYL2X))
16122 (clobber (match_scratch:XF 3 ""))])]
16123 "TARGET_USE_FANCY_MATH_387
16124 && flag_unsafe_math_optimizations"
16126 operands[2] = gen_reg_rtx (XFmode);
16127 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16130 (define_expand "log<mode>2"
16131 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16132 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16133 "TARGET_USE_FANCY_MATH_387
16134 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16135 || TARGET_MIX_SSE_I387)
16136 && flag_unsafe_math_optimizations"
16138 rtx op0 = gen_reg_rtx (XFmode);
16140 operands[2] = gen_reg_rtx (XFmode);
16141 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16143 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16144 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16148 (define_expand "log10xf2"
16149 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16150 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16151 (match_dup 2)] UNSPEC_FYL2X))
16152 (clobber (match_scratch:XF 3 ""))])]
16153 "TARGET_USE_FANCY_MATH_387
16154 && flag_unsafe_math_optimizations"
16156 operands[2] = gen_reg_rtx (XFmode);
16157 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16160 (define_expand "log10<mode>2"
16161 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16162 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16163 "TARGET_USE_FANCY_MATH_387
16164 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16165 || TARGET_MIX_SSE_I387)
16166 && flag_unsafe_math_optimizations"
16168 rtx op0 = gen_reg_rtx (XFmode);
16170 operands[2] = gen_reg_rtx (XFmode);
16171 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16173 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16178 (define_expand "log2xf2"
16179 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16180 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16181 (match_dup 2)] UNSPEC_FYL2X))
16182 (clobber (match_scratch:XF 3 ""))])]
16183 "TARGET_USE_FANCY_MATH_387
16184 && flag_unsafe_math_optimizations"
16186 operands[2] = gen_reg_rtx (XFmode);
16187 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16190 (define_expand "log2<mode>2"
16191 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16192 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16193 "TARGET_USE_FANCY_MATH_387
16194 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16195 || TARGET_MIX_SSE_I387)
16196 && flag_unsafe_math_optimizations"
16198 rtx op0 = gen_reg_rtx (XFmode);
16200 operands[2] = gen_reg_rtx (XFmode);
16201 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16203 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16204 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16208 (define_insn "fyl2xp1xf3_i387"
16209 [(set (match_operand:XF 0 "register_operand" "=f")
16210 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16211 (match_operand:XF 2 "register_operand" "u")]
16213 (clobber (match_scratch:XF 3 "=2"))]
16214 "TARGET_USE_FANCY_MATH_387
16215 && flag_unsafe_math_optimizations"
16217 [(set_attr "type" "fpspc")
16218 (set_attr "mode" "XF")])
16220 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16221 [(set (match_operand:XF 0 "register_operand" "=f")
16222 (unspec:XF [(float_extend:XF
16223 (match_operand:X87MODEF12 1 "register_operand" "0"))
16224 (match_operand:XF 2 "register_operand" "u")]
16226 (clobber (match_scratch:XF 3 "=2"))]
16227 "TARGET_USE_FANCY_MATH_387
16228 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16229 || TARGET_MIX_SSE_I387)
16230 && flag_unsafe_math_optimizations"
16232 [(set_attr "type" "fpspc")
16233 (set_attr "mode" "XF")])
16235 (define_expand "log1pxf2"
16236 [(use (match_operand:XF 0 "register_operand" ""))
16237 (use (match_operand:XF 1 "register_operand" ""))]
16238 "TARGET_USE_FANCY_MATH_387
16239 && flag_unsafe_math_optimizations && !optimize_size"
16241 ix86_emit_i387_log1p (operands[0], operands[1]);
16245 (define_expand "log1p<mode>2"
16246 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16247 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16248 "TARGET_USE_FANCY_MATH_387
16249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16250 || TARGET_MIX_SSE_I387)
16251 && flag_unsafe_math_optimizations && !optimize_size"
16253 rtx op0 = gen_reg_rtx (XFmode);
16255 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16257 ix86_emit_i387_log1p (op0, operands[1]);
16258 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16262 (define_insn "*fxtractxf3_i387"
16263 [(set (match_operand:XF 0 "register_operand" "=f")
16264 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16265 UNSPEC_XTRACT_FRACT))
16266 (set (match_operand:XF 1 "register_operand" "=u")
16267 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16268 "TARGET_USE_FANCY_MATH_387
16269 && flag_unsafe_math_optimizations"
16271 [(set_attr "type" "fpspc")
16272 (set_attr "mode" "XF")])
16274 (define_insn "fxtract_extend<mode>xf3_i387"
16275 [(set (match_operand:XF 0 "register_operand" "=f")
16276 (unspec:XF [(float_extend:XF
16277 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16278 UNSPEC_XTRACT_FRACT))
16279 (set (match_operand:XF 1 "register_operand" "=u")
16280 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16281 "TARGET_USE_FANCY_MATH_387
16282 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16283 || TARGET_MIX_SSE_I387)
16284 && flag_unsafe_math_optimizations"
16286 [(set_attr "type" "fpspc")
16287 (set_attr "mode" "XF")])
16289 (define_expand "logbxf2"
16290 [(parallel [(set (match_dup 2)
16291 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16292 UNSPEC_XTRACT_FRACT))
16293 (set (match_operand:XF 0 "register_operand" "")
16294 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16295 "TARGET_USE_FANCY_MATH_387
16296 && flag_unsafe_math_optimizations"
16298 operands[2] = gen_reg_rtx (XFmode);
16301 (define_expand "logb<mode>2"
16302 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16303 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16304 "TARGET_USE_FANCY_MATH_387
16305 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16306 || TARGET_MIX_SSE_I387)
16307 && flag_unsafe_math_optimizations"
16309 rtx op0 = gen_reg_rtx (XFmode);
16310 rtx op1 = gen_reg_rtx (XFmode);
16312 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16313 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16317 (define_expand "ilogbsi2"
16318 [(parallel [(set (match_dup 2)
16319 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16320 UNSPEC_XTRACT_FRACT))
16322 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16323 (parallel [(set (match_operand:SI 0 "register_operand" "")
16324 (fix:SI (match_dup 3)))
16325 (clobber (reg:CC FLAGS_REG))])]
16326 "TARGET_USE_FANCY_MATH_387
16327 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16328 && flag_unsafe_math_optimizations && !optimize_size"
16330 operands[2] = gen_reg_rtx (XFmode);
16331 operands[3] = gen_reg_rtx (XFmode);
16334 (define_insn "*f2xm1xf2_i387"
16335 [(set (match_operand:XF 0 "register_operand" "=f")
16336 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16338 "TARGET_USE_FANCY_MATH_387
16339 && flag_unsafe_math_optimizations"
16341 [(set_attr "type" "fpspc")
16342 (set_attr "mode" "XF")])
16344 (define_insn "*fscalexf4_i387"
16345 [(set (match_operand:XF 0 "register_operand" "=f")
16346 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16347 (match_operand:XF 3 "register_operand" "1")]
16348 UNSPEC_FSCALE_FRACT))
16349 (set (match_operand:XF 1 "register_operand" "=u")
16350 (unspec:XF [(match_dup 2) (match_dup 3)]
16351 UNSPEC_FSCALE_EXP))]
16352 "TARGET_USE_FANCY_MATH_387
16353 && flag_unsafe_math_optimizations"
16355 [(set_attr "type" "fpspc")
16356 (set_attr "mode" "XF")])
16358 (define_expand "expNcorexf3"
16359 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16360 (match_operand:XF 2 "register_operand" "")))
16361 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16362 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16363 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16364 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16365 (parallel [(set (match_operand:XF 0 "register_operand" "")
16366 (unspec:XF [(match_dup 8) (match_dup 4)]
16367 UNSPEC_FSCALE_FRACT))
16369 (unspec:XF [(match_dup 8) (match_dup 4)]
16370 UNSPEC_FSCALE_EXP))])]
16371 "TARGET_USE_FANCY_MATH_387
16372 && flag_unsafe_math_optimizations && !optimize_size"
16376 for (i = 3; i < 10; i++)
16377 operands[i] = gen_reg_rtx (XFmode);
16379 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16382 (define_expand "expxf2"
16383 [(use (match_operand:XF 0 "register_operand" ""))
16384 (use (match_operand:XF 1 "register_operand" ""))]
16385 "TARGET_USE_FANCY_MATH_387
16386 && flag_unsafe_math_optimizations && !optimize_size"
16388 operands[2] = gen_reg_rtx (XFmode);
16389 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16391 emit_insn (gen_expNcorexf3 (operands[0], operands[1], operands[2]));
16395 (define_expand "exp<mode>2"
16396 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16397 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16398 "TARGET_USE_FANCY_MATH_387
16399 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16400 || TARGET_MIX_SSE_I387)
16401 && flag_unsafe_math_optimizations && !optimize_size"
16403 rtx op0 = gen_reg_rtx (XFmode);
16404 rtx op1 = gen_reg_rtx (XFmode);
16406 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16407 emit_insn (gen_expxf2 (op0, op1));
16408 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16412 (define_expand "exp10xf2"
16413 [(use (match_operand:XF 0 "register_operand" ""))
16414 (use (match_operand:XF 1 "register_operand" ""))]
16415 "TARGET_USE_FANCY_MATH_387
16416 && flag_unsafe_math_optimizations && !optimize_size"
16418 operands[2] = gen_reg_rtx (XFmode);
16419 emit_move_insn (operands[2], standard_80387_constant_rtx (6)); /* fldl2t */
16421 emit_insn (gen_expNcorexf3 (operands[0], operands[1], operands[2]));
16425 (define_expand "exp10<mode>2"
16426 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16427 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16428 "TARGET_USE_FANCY_MATH_387
16429 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16430 || TARGET_MIX_SSE_I387)
16431 && flag_unsafe_math_optimizations && !optimize_size"
16433 rtx op0 = gen_reg_rtx (XFmode);
16434 rtx op1 = gen_reg_rtx (XFmode);
16436 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16437 emit_insn (gen_exp10xf2 (op0, op1));
16438 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16442 (define_expand "exp2xf2"
16443 [(use (match_operand:XF 0 "register_operand" ""))
16444 (use (match_operand:XF 1 "register_operand" ""))]
16445 "TARGET_USE_FANCY_MATH_387
16446 && flag_unsafe_math_optimizations && !optimize_size"
16448 operands[2] = gen_reg_rtx (XFmode);
16449 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16451 emit_insn (gen_expNcorexf3 (operands[0], operands[1], operands[2]));
16455 (define_expand "exp2<mode>2"
16456 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16457 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16458 "TARGET_USE_FANCY_MATH_387
16459 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16460 || TARGET_MIX_SSE_I387)
16461 && flag_unsafe_math_optimizations && !optimize_size"
16463 rtx op0 = gen_reg_rtx (XFmode);
16464 rtx op1 = gen_reg_rtx (XFmode);
16466 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16467 emit_insn (gen_exp2xf2 (op0, op1));
16468 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16472 (define_expand "expm1xf2"
16473 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16475 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16476 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16477 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16478 (parallel [(set (match_dup 7)
16479 (unspec:XF [(match_dup 6) (match_dup 4)]
16480 UNSPEC_FSCALE_FRACT))
16482 (unspec:XF [(match_dup 6) (match_dup 4)]
16483 UNSPEC_FSCALE_EXP))])
16484 (parallel [(set (match_dup 10)
16485 (unspec:XF [(match_dup 9) (match_dup 8)]
16486 UNSPEC_FSCALE_FRACT))
16487 (set (match_dup 11)
16488 (unspec:XF [(match_dup 9) (match_dup 8)]
16489 UNSPEC_FSCALE_EXP))])
16490 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16491 (set (match_operand:XF 0 "register_operand" "")
16492 (plus:XF (match_dup 12) (match_dup 7)))]
16493 "TARGET_USE_FANCY_MATH_387
16494 && flag_unsafe_math_optimizations && !optimize_size"
16498 for (i = 2; i < 13; i++)
16499 operands[i] = gen_reg_rtx (XFmode);
16501 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16502 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16505 (define_expand "expm1<mode>2"
16506 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16507 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16508 "TARGET_USE_FANCY_MATH_387
16509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16510 || TARGET_MIX_SSE_I387)
16511 && flag_unsafe_math_optimizations && !optimize_size"
16513 rtx op0 = gen_reg_rtx (XFmode);
16514 rtx op1 = gen_reg_rtx (XFmode);
16516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16517 emit_insn (gen_expm1xf2 (op0, op1));
16518 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16522 (define_expand "ldexpxf3"
16523 [(set (match_dup 3)
16524 (float:XF (match_operand:SI 2 "register_operand" "")))
16525 (parallel [(set (match_operand:XF 0 " register_operand" "")
16526 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16528 UNSPEC_FSCALE_FRACT))
16530 (unspec:XF [(match_dup 1) (match_dup 3)]
16531 UNSPEC_FSCALE_EXP))])]
16532 "TARGET_USE_FANCY_MATH_387
16533 && flag_unsafe_math_optimizations && !optimize_size"
16535 operands[3] = gen_reg_rtx (XFmode);
16536 operands[4] = gen_reg_rtx (XFmode);
16539 (define_expand "ldexp<mode>3"
16540 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16541 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16542 (use (match_operand:SI 2 "register_operand" ""))]
16543 "TARGET_USE_FANCY_MATH_387
16544 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16545 || TARGET_MIX_SSE_I387)
16546 && flag_unsafe_math_optimizations && !optimize_size"
16548 rtx op0 = gen_reg_rtx (XFmode);
16549 rtx op1 = gen_reg_rtx (XFmode);
16551 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16552 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16558 (define_insn "frndintxf2"
16559 [(set (match_operand:XF 0 "register_operand" "=f")
16560 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16562 "TARGET_USE_FANCY_MATH_387
16563 && flag_unsafe_math_optimizations"
16565 [(set_attr "type" "fpspc")
16566 (set_attr "mode" "XF")])
16568 (define_expand "rintdf2"
16569 [(use (match_operand:DF 0 "register_operand" ""))
16570 (use (match_operand:DF 1 "register_operand" ""))]
16571 "(TARGET_USE_FANCY_MATH_387
16572 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16573 && flag_unsafe_math_optimizations)
16574 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16575 && !flag_trapping_math
16576 && !optimize_size)"
16578 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16579 && !flag_trapping_math
16581 ix86_expand_rint (operand0, operand1);
16584 rtx op0 = gen_reg_rtx (XFmode);
16585 rtx op1 = gen_reg_rtx (XFmode);
16587 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16588 emit_insn (gen_frndintxf2 (op0, op1));
16590 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16595 (define_expand "rintsf2"
16596 [(use (match_operand:SF 0 "register_operand" ""))
16597 (use (match_operand:SF 1 "register_operand" ""))]
16598 "(TARGET_USE_FANCY_MATH_387
16599 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16600 && flag_unsafe_math_optimizations)
16601 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16602 && !flag_trapping_math
16603 && !optimize_size)"
16605 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16606 && !flag_trapping_math
16608 ix86_expand_rint (operand0, operand1);
16611 rtx op0 = gen_reg_rtx (XFmode);
16612 rtx op1 = gen_reg_rtx (XFmode);
16614 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16615 emit_insn (gen_frndintxf2 (op0, op1));
16617 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16622 (define_expand "rintxf2"
16623 [(use (match_operand:XF 0 "register_operand" ""))
16624 (use (match_operand:XF 1 "register_operand" ""))]
16625 "TARGET_USE_FANCY_MATH_387
16626 && flag_unsafe_math_optimizations && !optimize_size"
16628 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16632 (define_expand "roundsf2"
16633 [(match_operand:SF 0 "register_operand" "")
16634 (match_operand:SF 1 "nonimmediate_operand" "")]
16635 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16636 && !flag_trapping_math && !flag_rounding_math
16639 ix86_expand_round (operand0, operand1);
16643 (define_expand "rounddf2"
16644 [(match_operand:DF 0 "register_operand" "")
16645 (match_operand:DF 1 "nonimmediate_operand" "")]
16646 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16647 && !flag_trapping_math && !flag_rounding_math
16651 ix86_expand_round (operand0, operand1);
16653 ix86_expand_rounddf_32 (operand0, operand1);
16657 (define_insn_and_split "*fistdi2_1"
16658 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16659 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16661 "TARGET_USE_FANCY_MATH_387
16662 && !(reload_completed || reload_in_progress)"
16667 if (memory_operand (operands[0], VOIDmode))
16668 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16671 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16672 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16677 [(set_attr "type" "fpspc")
16678 (set_attr "mode" "DI")])
16680 (define_insn "fistdi2"
16681 [(set (match_operand:DI 0 "memory_operand" "=m")
16682 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16684 (clobber (match_scratch:XF 2 "=&1f"))]
16685 "TARGET_USE_FANCY_MATH_387"
16686 "* return output_fix_trunc (insn, operands, 0);"
16687 [(set_attr "type" "fpspc")
16688 (set_attr "mode" "DI")])
16690 (define_insn "fistdi2_with_temp"
16691 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16692 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16694 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16695 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16696 "TARGET_USE_FANCY_MATH_387"
16698 [(set_attr "type" "fpspc")
16699 (set_attr "mode" "DI")])
16702 [(set (match_operand:DI 0 "register_operand" "")
16703 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16705 (clobber (match_operand:DI 2 "memory_operand" ""))
16706 (clobber (match_scratch 3 ""))]
16708 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16709 (clobber (match_dup 3))])
16710 (set (match_dup 0) (match_dup 2))]
16714 [(set (match_operand:DI 0 "memory_operand" "")
16715 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16717 (clobber (match_operand:DI 2 "memory_operand" ""))
16718 (clobber (match_scratch 3 ""))]
16720 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16721 (clobber (match_dup 3))])]
16724 (define_insn_and_split "*fist<mode>2_1"
16725 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16726 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16728 "TARGET_USE_FANCY_MATH_387
16729 && !(reload_completed || reload_in_progress)"
16734 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16735 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16739 [(set_attr "type" "fpspc")
16740 (set_attr "mode" "<MODE>")])
16742 (define_insn "fist<mode>2"
16743 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16744 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16746 "TARGET_USE_FANCY_MATH_387"
16747 "* return output_fix_trunc (insn, operands, 0);"
16748 [(set_attr "type" "fpspc")
16749 (set_attr "mode" "<MODE>")])
16751 (define_insn "fist<mode>2_with_temp"
16752 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16753 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16755 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16756 "TARGET_USE_FANCY_MATH_387"
16758 [(set_attr "type" "fpspc")
16759 (set_attr "mode" "<MODE>")])
16762 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16763 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16765 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16767 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16769 (set (match_dup 0) (match_dup 2))]
16773 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16774 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16776 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16778 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16782 (define_expand "lrintxf<mode>2"
16783 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16784 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16786 "TARGET_USE_FANCY_MATH_387"
16789 (define_expand "lrint<mode>di2"
16790 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16791 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
16792 UNSPEC_FIX_NOTRUNC))]
16793 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
16796 (define_expand "lrint<mode>si2"
16797 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16798 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
16799 UNSPEC_FIX_NOTRUNC))]
16800 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16803 (define_expand "lround<mode>di2"
16804 [(match_operand:DI 0 "nonimmediate_operand" "")
16805 (match_operand:SSEMODEF 1 "register_operand" "")]
16806 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
16807 && !flag_trapping_math && !flag_rounding_math
16810 ix86_expand_lround (operand0, operand1);
16814 (define_expand "lround<mode>si2"
16815 [(match_operand:SI 0 "nonimmediate_operand" "")
16816 (match_operand:SSEMODEF 1 "register_operand" "")]
16817 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16818 && !flag_trapping_math && !flag_rounding_math
16821 ix86_expand_lround (operand0, operand1);
16825 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16826 (define_insn_and_split "frndintxf2_floor"
16827 [(set (match_operand:XF 0 "register_operand" "=f")
16828 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16829 UNSPEC_FRNDINT_FLOOR))
16830 (clobber (reg:CC FLAGS_REG))]
16831 "TARGET_USE_FANCY_MATH_387
16832 && flag_unsafe_math_optimizations
16833 && !(reload_completed || reload_in_progress)"
16838 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16840 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16841 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16843 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16844 operands[2], operands[3]));
16847 [(set_attr "type" "frndint")
16848 (set_attr "i387_cw" "floor")
16849 (set_attr "mode" "XF")])
16851 (define_insn "frndintxf2_floor_i387"
16852 [(set (match_operand:XF 0 "register_operand" "=f")
16853 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16854 UNSPEC_FRNDINT_FLOOR))
16855 (use (match_operand:HI 2 "memory_operand" "m"))
16856 (use (match_operand:HI 3 "memory_operand" "m"))]
16857 "TARGET_USE_FANCY_MATH_387
16858 && flag_unsafe_math_optimizations"
16859 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16860 [(set_attr "type" "frndint")
16861 (set_attr "i387_cw" "floor")
16862 (set_attr "mode" "XF")])
16864 (define_expand "floorxf2"
16865 [(use (match_operand:XF 0 "register_operand" ""))
16866 (use (match_operand:XF 1 "register_operand" ""))]
16867 "TARGET_USE_FANCY_MATH_387
16868 && flag_unsafe_math_optimizations && !optimize_size"
16870 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16874 (define_expand "floordf2"
16875 [(use (match_operand:DF 0 "register_operand" ""))
16876 (use (match_operand:DF 1 "register_operand" ""))]
16877 "((TARGET_USE_FANCY_MATH_387
16878 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16879 && flag_unsafe_math_optimizations)
16880 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16881 && !flag_trapping_math))
16884 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16885 && !flag_trapping_math)
16888 ix86_expand_floorceil (operand0, operand1, true);
16890 ix86_expand_floorceildf_32 (operand0, operand1, true);
16894 rtx op0 = gen_reg_rtx (XFmode);
16895 rtx op1 = gen_reg_rtx (XFmode);
16897 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16898 emit_insn (gen_frndintxf2_floor (op0, op1));
16900 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16905 (define_expand "floorsf2"
16906 [(use (match_operand:SF 0 "register_operand" ""))
16907 (use (match_operand:SF 1 "register_operand" ""))]
16908 "((TARGET_USE_FANCY_MATH_387
16909 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16910 && flag_unsafe_math_optimizations)
16911 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16912 && !flag_trapping_math))
16915 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16916 && !flag_trapping_math)
16917 ix86_expand_floorceil (operand0, operand1, true);
16920 rtx op0 = gen_reg_rtx (XFmode);
16921 rtx op1 = gen_reg_rtx (XFmode);
16923 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16924 emit_insn (gen_frndintxf2_floor (op0, op1));
16926 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16931 (define_insn_and_split "*fist<mode>2_floor_1"
16932 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16933 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16934 UNSPEC_FIST_FLOOR))
16935 (clobber (reg:CC FLAGS_REG))]
16936 "TARGET_USE_FANCY_MATH_387
16937 && flag_unsafe_math_optimizations
16938 && !(reload_completed || reload_in_progress)"
16943 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16945 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16946 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16947 if (memory_operand (operands[0], VOIDmode))
16948 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16949 operands[2], operands[3]));
16952 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16953 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16954 operands[2], operands[3],
16959 [(set_attr "type" "fistp")
16960 (set_attr "i387_cw" "floor")
16961 (set_attr "mode" "<MODE>")])
16963 (define_insn "fistdi2_floor"
16964 [(set (match_operand:DI 0 "memory_operand" "=m")
16965 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16966 UNSPEC_FIST_FLOOR))
16967 (use (match_operand:HI 2 "memory_operand" "m"))
16968 (use (match_operand:HI 3 "memory_operand" "m"))
16969 (clobber (match_scratch:XF 4 "=&1f"))]
16970 "TARGET_USE_FANCY_MATH_387
16971 && flag_unsafe_math_optimizations"
16972 "* return output_fix_trunc (insn, operands, 0);"
16973 [(set_attr "type" "fistp")
16974 (set_attr "i387_cw" "floor")
16975 (set_attr "mode" "DI")])
16977 (define_insn "fistdi2_floor_with_temp"
16978 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16979 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16980 UNSPEC_FIST_FLOOR))
16981 (use (match_operand:HI 2 "memory_operand" "m,m"))
16982 (use (match_operand:HI 3 "memory_operand" "m,m"))
16983 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16984 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16985 "TARGET_USE_FANCY_MATH_387
16986 && flag_unsafe_math_optimizations"
16988 [(set_attr "type" "fistp")
16989 (set_attr "i387_cw" "floor")
16990 (set_attr "mode" "DI")])
16993 [(set (match_operand:DI 0 "register_operand" "")
16994 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16995 UNSPEC_FIST_FLOOR))
16996 (use (match_operand:HI 2 "memory_operand" ""))
16997 (use (match_operand:HI 3 "memory_operand" ""))
16998 (clobber (match_operand:DI 4 "memory_operand" ""))
16999 (clobber (match_scratch 5 ""))]
17001 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17002 (use (match_dup 2))
17003 (use (match_dup 3))
17004 (clobber (match_dup 5))])
17005 (set (match_dup 0) (match_dup 4))]
17009 [(set (match_operand:DI 0 "memory_operand" "")
17010 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17011 UNSPEC_FIST_FLOOR))
17012 (use (match_operand:HI 2 "memory_operand" ""))
17013 (use (match_operand:HI 3 "memory_operand" ""))
17014 (clobber (match_operand:DI 4 "memory_operand" ""))
17015 (clobber (match_scratch 5 ""))]
17017 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17018 (use (match_dup 2))
17019 (use (match_dup 3))
17020 (clobber (match_dup 5))])]
17023 (define_insn "fist<mode>2_floor"
17024 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17025 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17026 UNSPEC_FIST_FLOOR))
17027 (use (match_operand:HI 2 "memory_operand" "m"))
17028 (use (match_operand:HI 3 "memory_operand" "m"))]
17029 "TARGET_USE_FANCY_MATH_387
17030 && flag_unsafe_math_optimizations"
17031 "* return output_fix_trunc (insn, operands, 0);"
17032 [(set_attr "type" "fistp")
17033 (set_attr "i387_cw" "floor")
17034 (set_attr "mode" "<MODE>")])
17036 (define_insn "fist<mode>2_floor_with_temp"
17037 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17038 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17039 UNSPEC_FIST_FLOOR))
17040 (use (match_operand:HI 2 "memory_operand" "m,m"))
17041 (use (match_operand:HI 3 "memory_operand" "m,m"))
17042 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17043 "TARGET_USE_FANCY_MATH_387
17044 && flag_unsafe_math_optimizations"
17046 [(set_attr "type" "fistp")
17047 (set_attr "i387_cw" "floor")
17048 (set_attr "mode" "<MODE>")])
17051 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17052 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17053 UNSPEC_FIST_FLOOR))
17054 (use (match_operand:HI 2 "memory_operand" ""))
17055 (use (match_operand:HI 3 "memory_operand" ""))
17056 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17058 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17059 UNSPEC_FIST_FLOOR))
17060 (use (match_dup 2))
17061 (use (match_dup 3))])
17062 (set (match_dup 0) (match_dup 4))]
17066 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17067 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17068 UNSPEC_FIST_FLOOR))
17069 (use (match_operand:HI 2 "memory_operand" ""))
17070 (use (match_operand:HI 3 "memory_operand" ""))
17071 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17073 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17074 UNSPEC_FIST_FLOOR))
17075 (use (match_dup 2))
17076 (use (match_dup 3))])]
17079 (define_expand "lfloorxf<mode>2"
17080 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17081 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17082 UNSPEC_FIST_FLOOR))
17083 (clobber (reg:CC FLAGS_REG))])]
17084 "TARGET_USE_FANCY_MATH_387
17085 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17086 && flag_unsafe_math_optimizations"
17089 (define_expand "lfloor<mode>di2"
17090 [(match_operand:DI 0 "nonimmediate_operand" "")
17091 (match_operand:SSEMODEF 1 "register_operand" "")]
17092 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17093 && !flag_trapping_math
17096 ix86_expand_lfloorceil (operand0, operand1, true);
17100 (define_expand "lfloor<mode>si2"
17101 [(match_operand:SI 0 "nonimmediate_operand" "")
17102 (match_operand:SSEMODEF 1 "register_operand" "")]
17103 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17104 && !flag_trapping_math
17105 && (!optimize_size || !TARGET_64BIT)"
17107 ix86_expand_lfloorceil (operand0, operand1, true);
17111 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17112 (define_insn_and_split "frndintxf2_ceil"
17113 [(set (match_operand:XF 0 "register_operand" "=f")
17114 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17115 UNSPEC_FRNDINT_CEIL))
17116 (clobber (reg:CC FLAGS_REG))]
17117 "TARGET_USE_FANCY_MATH_387
17118 && flag_unsafe_math_optimizations
17119 && !(reload_completed || reload_in_progress)"
17124 ix86_optimize_mode_switching[I387_CEIL] = 1;
17126 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17127 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17129 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17130 operands[2], operands[3]));
17133 [(set_attr "type" "frndint")
17134 (set_attr "i387_cw" "ceil")
17135 (set_attr "mode" "XF")])
17137 (define_insn "frndintxf2_ceil_i387"
17138 [(set (match_operand:XF 0 "register_operand" "=f")
17139 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17140 UNSPEC_FRNDINT_CEIL))
17141 (use (match_operand:HI 2 "memory_operand" "m"))
17142 (use (match_operand:HI 3 "memory_operand" "m"))]
17143 "TARGET_USE_FANCY_MATH_387
17144 && flag_unsafe_math_optimizations"
17145 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17146 [(set_attr "type" "frndint")
17147 (set_attr "i387_cw" "ceil")
17148 (set_attr "mode" "XF")])
17150 (define_expand "ceilxf2"
17151 [(use (match_operand:XF 0 "register_operand" ""))
17152 (use (match_operand:XF 1 "register_operand" ""))]
17153 "TARGET_USE_FANCY_MATH_387
17154 && flag_unsafe_math_optimizations && !optimize_size"
17156 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17160 (define_expand "ceildf2"
17161 [(use (match_operand:DF 0 "register_operand" ""))
17162 (use (match_operand:DF 1 "register_operand" ""))]
17163 "((TARGET_USE_FANCY_MATH_387
17164 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17165 && flag_unsafe_math_optimizations)
17166 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17167 && !flag_trapping_math))
17170 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17171 && !flag_trapping_math)
17174 ix86_expand_floorceil (operand0, operand1, false);
17176 ix86_expand_floorceildf_32 (operand0, operand1, false);
17180 rtx op0 = gen_reg_rtx (XFmode);
17181 rtx op1 = gen_reg_rtx (XFmode);
17183 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17184 emit_insn (gen_frndintxf2_ceil (op0, op1));
17186 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17191 (define_expand "ceilsf2"
17192 [(use (match_operand:SF 0 "register_operand" ""))
17193 (use (match_operand:SF 1 "register_operand" ""))]
17194 "((TARGET_USE_FANCY_MATH_387
17195 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17196 && flag_unsafe_math_optimizations)
17197 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17198 && !flag_trapping_math))
17201 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17202 && !flag_trapping_math)
17203 ix86_expand_floorceil (operand0, operand1, false);
17206 rtx op0 = gen_reg_rtx (XFmode);
17207 rtx op1 = gen_reg_rtx (XFmode);
17209 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17210 emit_insn (gen_frndintxf2_ceil (op0, op1));
17212 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17217 (define_insn_and_split "*fist<mode>2_ceil_1"
17218 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17219 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17221 (clobber (reg:CC FLAGS_REG))]
17222 "TARGET_USE_FANCY_MATH_387
17223 && flag_unsafe_math_optimizations
17224 && !(reload_completed || reload_in_progress)"
17229 ix86_optimize_mode_switching[I387_CEIL] = 1;
17231 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17232 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17233 if (memory_operand (operands[0], VOIDmode))
17234 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17235 operands[2], operands[3]));
17238 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17239 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17240 operands[2], operands[3],
17245 [(set_attr "type" "fistp")
17246 (set_attr "i387_cw" "ceil")
17247 (set_attr "mode" "<MODE>")])
17249 (define_insn "fistdi2_ceil"
17250 [(set (match_operand:DI 0 "memory_operand" "=m")
17251 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17253 (use (match_operand:HI 2 "memory_operand" "m"))
17254 (use (match_operand:HI 3 "memory_operand" "m"))
17255 (clobber (match_scratch:XF 4 "=&1f"))]
17256 "TARGET_USE_FANCY_MATH_387
17257 && flag_unsafe_math_optimizations"
17258 "* return output_fix_trunc (insn, operands, 0);"
17259 [(set_attr "type" "fistp")
17260 (set_attr "i387_cw" "ceil")
17261 (set_attr "mode" "DI")])
17263 (define_insn "fistdi2_ceil_with_temp"
17264 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17265 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17267 (use (match_operand:HI 2 "memory_operand" "m,m"))
17268 (use (match_operand:HI 3 "memory_operand" "m,m"))
17269 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17270 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17271 "TARGET_USE_FANCY_MATH_387
17272 && flag_unsafe_math_optimizations"
17274 [(set_attr "type" "fistp")
17275 (set_attr "i387_cw" "ceil")
17276 (set_attr "mode" "DI")])
17279 [(set (match_operand:DI 0 "register_operand" "")
17280 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17282 (use (match_operand:HI 2 "memory_operand" ""))
17283 (use (match_operand:HI 3 "memory_operand" ""))
17284 (clobber (match_operand:DI 4 "memory_operand" ""))
17285 (clobber (match_scratch 5 ""))]
17287 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17288 (use (match_dup 2))
17289 (use (match_dup 3))
17290 (clobber (match_dup 5))])
17291 (set (match_dup 0) (match_dup 4))]
17295 [(set (match_operand:DI 0 "memory_operand" "")
17296 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17298 (use (match_operand:HI 2 "memory_operand" ""))
17299 (use (match_operand:HI 3 "memory_operand" ""))
17300 (clobber (match_operand:DI 4 "memory_operand" ""))
17301 (clobber (match_scratch 5 ""))]
17303 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17304 (use (match_dup 2))
17305 (use (match_dup 3))
17306 (clobber (match_dup 5))])]
17309 (define_insn "fist<mode>2_ceil"
17310 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17311 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17313 (use (match_operand:HI 2 "memory_operand" "m"))
17314 (use (match_operand:HI 3 "memory_operand" "m"))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && flag_unsafe_math_optimizations"
17317 "* return output_fix_trunc (insn, operands, 0);"
17318 [(set_attr "type" "fistp")
17319 (set_attr "i387_cw" "ceil")
17320 (set_attr "mode" "<MODE>")])
17322 (define_insn "fist<mode>2_ceil_with_temp"
17323 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17324 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17326 (use (match_operand:HI 2 "memory_operand" "m,m"))
17327 (use (match_operand:HI 3 "memory_operand" "m,m"))
17328 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17329 "TARGET_USE_FANCY_MATH_387
17330 && flag_unsafe_math_optimizations"
17332 [(set_attr "type" "fistp")
17333 (set_attr "i387_cw" "ceil")
17334 (set_attr "mode" "<MODE>")])
17337 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17338 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17340 (use (match_operand:HI 2 "memory_operand" ""))
17341 (use (match_operand:HI 3 "memory_operand" ""))
17342 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17344 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17346 (use (match_dup 2))
17347 (use (match_dup 3))])
17348 (set (match_dup 0) (match_dup 4))]
17352 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17353 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17355 (use (match_operand:HI 2 "memory_operand" ""))
17356 (use (match_operand:HI 3 "memory_operand" ""))
17357 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17359 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17361 (use (match_dup 2))
17362 (use (match_dup 3))])]
17365 (define_expand "lceilxf<mode>2"
17366 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17367 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17369 (clobber (reg:CC FLAGS_REG))])]
17370 "TARGET_USE_FANCY_MATH_387
17371 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17372 && flag_unsafe_math_optimizations"
17375 (define_expand "lceil<mode>di2"
17376 [(match_operand:DI 0 "nonimmediate_operand" "")
17377 (match_operand:SSEMODEF 1 "register_operand" "")]
17378 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17379 && !flag_trapping_math"
17381 ix86_expand_lfloorceil (operand0, operand1, false);
17385 (define_expand "lceil<mode>si2"
17386 [(match_operand:SI 0 "nonimmediate_operand" "")
17387 (match_operand:SSEMODEF 1 "register_operand" "")]
17388 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17389 && !flag_trapping_math"
17391 ix86_expand_lfloorceil (operand0, operand1, false);
17395 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17396 (define_insn_and_split "frndintxf2_trunc"
17397 [(set (match_operand:XF 0 "register_operand" "=f")
17398 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17399 UNSPEC_FRNDINT_TRUNC))
17400 (clobber (reg:CC FLAGS_REG))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && flag_unsafe_math_optimizations
17403 && !(reload_completed || reload_in_progress)"
17408 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17410 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17411 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17413 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17414 operands[2], operands[3]));
17417 [(set_attr "type" "frndint")
17418 (set_attr "i387_cw" "trunc")
17419 (set_attr "mode" "XF")])
17421 (define_insn "frndintxf2_trunc_i387"
17422 [(set (match_operand:XF 0 "register_operand" "=f")
17423 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17424 UNSPEC_FRNDINT_TRUNC))
17425 (use (match_operand:HI 2 "memory_operand" "m"))
17426 (use (match_operand:HI 3 "memory_operand" "m"))]
17427 "TARGET_USE_FANCY_MATH_387
17428 && flag_unsafe_math_optimizations"
17429 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17430 [(set_attr "type" "frndint")
17431 (set_attr "i387_cw" "trunc")
17432 (set_attr "mode" "XF")])
17434 (define_expand "btruncxf2"
17435 [(use (match_operand:XF 0 "register_operand" ""))
17436 (use (match_operand:XF 1 "register_operand" ""))]
17437 "TARGET_USE_FANCY_MATH_387
17438 && flag_unsafe_math_optimizations && !optimize_size"
17440 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17444 (define_expand "btruncdf2"
17445 [(use (match_operand:DF 0 "register_operand" ""))
17446 (use (match_operand:DF 1 "register_operand" ""))]
17447 "((TARGET_USE_FANCY_MATH_387
17448 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17449 && flag_unsafe_math_optimizations)
17450 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17451 && !flag_trapping_math))
17454 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17455 && !flag_trapping_math)
17458 ix86_expand_trunc (operand0, operand1);
17460 ix86_expand_truncdf_32 (operand0, operand1);
17464 rtx op0 = gen_reg_rtx (XFmode);
17465 rtx op1 = gen_reg_rtx (XFmode);
17467 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17468 emit_insn (gen_frndintxf2_trunc (op0, op1));
17470 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17475 (define_expand "btruncsf2"
17476 [(use (match_operand:SF 0 "register_operand" ""))
17477 (use (match_operand:SF 1 "register_operand" ""))]
17478 "((TARGET_USE_FANCY_MATH_387
17479 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17480 && flag_unsafe_math_optimizations)
17481 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17482 && !flag_trapping_math))
17485 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17486 && !flag_trapping_math)
17487 ix86_expand_trunc (operand0, operand1);
17490 rtx op0 = gen_reg_rtx (XFmode);
17491 rtx op1 = gen_reg_rtx (XFmode);
17493 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17494 emit_insn (gen_frndintxf2_trunc (op0, op1));
17496 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17501 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17502 (define_insn_and_split "frndintxf2_mask_pm"
17503 [(set (match_operand:XF 0 "register_operand" "=f")
17504 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17505 UNSPEC_FRNDINT_MASK_PM))
17506 (clobber (reg:CC FLAGS_REG))]
17507 "TARGET_USE_FANCY_MATH_387
17508 && flag_unsafe_math_optimizations
17509 && !(reload_completed || reload_in_progress)"
17514 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17516 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17517 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17519 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17520 operands[2], operands[3]));
17523 [(set_attr "type" "frndint")
17524 (set_attr "i387_cw" "mask_pm")
17525 (set_attr "mode" "XF")])
17527 (define_insn "frndintxf2_mask_pm_i387"
17528 [(set (match_operand:XF 0 "register_operand" "=f")
17529 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17530 UNSPEC_FRNDINT_MASK_PM))
17531 (use (match_operand:HI 2 "memory_operand" "m"))
17532 (use (match_operand:HI 3 "memory_operand" "m"))]
17533 "TARGET_USE_FANCY_MATH_387
17534 && flag_unsafe_math_optimizations"
17535 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17536 [(set_attr "type" "frndint")
17537 (set_attr "i387_cw" "mask_pm")
17538 (set_attr "mode" "XF")])
17540 (define_expand "nearbyintxf2"
17541 [(use (match_operand:XF 0 "register_operand" ""))
17542 (use (match_operand:XF 1 "register_operand" ""))]
17543 "TARGET_USE_FANCY_MATH_387
17544 && flag_unsafe_math_optimizations"
17546 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17551 (define_expand "nearbyintdf2"
17552 [(use (match_operand:DF 0 "register_operand" ""))
17553 (use (match_operand:DF 1 "register_operand" ""))]
17554 "TARGET_USE_FANCY_MATH_387
17555 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17556 && flag_unsafe_math_optimizations"
17558 rtx op0 = gen_reg_rtx (XFmode);
17559 rtx op1 = gen_reg_rtx (XFmode);
17561 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17562 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17564 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17568 (define_expand "nearbyintsf2"
17569 [(use (match_operand:SF 0 "register_operand" ""))
17570 (use (match_operand:SF 1 "register_operand" ""))]
17571 "TARGET_USE_FANCY_MATH_387
17572 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17573 && flag_unsafe_math_optimizations"
17575 rtx op0 = gen_reg_rtx (XFmode);
17576 rtx op1 = gen_reg_rtx (XFmode);
17578 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17579 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17581 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17586 ;; Block operation instructions
17588 (define_expand "movmemsi"
17589 [(use (match_operand:BLK 0 "memory_operand" ""))
17590 (use (match_operand:BLK 1 "memory_operand" ""))
17591 (use (match_operand:SI 2 "nonmemory_operand" ""))
17592 (use (match_operand:SI 3 "const_int_operand" ""))]
17595 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17596 operands[3], constm1_rtx))
17602 (define_expand "movmemdi"
17603 [(use (match_operand:BLK 0 "memory_operand" ""))
17604 (use (match_operand:BLK 1 "memory_operand" ""))
17605 (use (match_operand:DI 2 "nonmemory_operand" ""))
17606 (use (match_operand:DI 3 "const_int_operand" ""))]
17609 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17610 operands[3], constm1_rtx))
17616 ;; Most CPUs don't like single string operations
17617 ;; Handle this case here to simplify previous expander.
17619 (define_expand "strmov"
17620 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17621 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17622 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17623 (clobber (reg:CC FLAGS_REG))])
17624 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17625 (clobber (reg:CC FLAGS_REG))])]
17628 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17630 /* If .md ever supports :P for Pmode, these can be directly
17631 in the pattern above. */
17632 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17633 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17635 if (TARGET_SINGLE_STRINGOP || optimize_size)
17637 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17638 operands[2], operands[3],
17639 operands[5], operands[6]));
17643 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17646 (define_expand "strmov_singleop"
17647 [(parallel [(set (match_operand 1 "memory_operand" "")
17648 (match_operand 3 "memory_operand" ""))
17649 (set (match_operand 0 "register_operand" "")
17650 (match_operand 4 "" ""))
17651 (set (match_operand 2 "register_operand" "")
17652 (match_operand 5 "" ""))])]
17653 "TARGET_SINGLE_STRINGOP || optimize_size"
17656 (define_insn "*strmovdi_rex_1"
17657 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17658 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17659 (set (match_operand:DI 0 "register_operand" "=D")
17660 (plus:DI (match_dup 2)
17662 (set (match_operand:DI 1 "register_operand" "=S")
17663 (plus:DI (match_dup 3)
17665 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17667 [(set_attr "type" "str")
17668 (set_attr "mode" "DI")
17669 (set_attr "memory" "both")])
17671 (define_insn "*strmovsi_1"
17672 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17673 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17674 (set (match_operand:SI 0 "register_operand" "=D")
17675 (plus:SI (match_dup 2)
17677 (set (match_operand:SI 1 "register_operand" "=S")
17678 (plus:SI (match_dup 3)
17680 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17682 [(set_attr "type" "str")
17683 (set_attr "mode" "SI")
17684 (set_attr "memory" "both")])
17686 (define_insn "*strmovsi_rex_1"
17687 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17688 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17689 (set (match_operand:DI 0 "register_operand" "=D")
17690 (plus:DI (match_dup 2)
17692 (set (match_operand:DI 1 "register_operand" "=S")
17693 (plus:DI (match_dup 3)
17695 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17697 [(set_attr "type" "str")
17698 (set_attr "mode" "SI")
17699 (set_attr "memory" "both")])
17701 (define_insn "*strmovhi_1"
17702 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17703 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17704 (set (match_operand:SI 0 "register_operand" "=D")
17705 (plus:SI (match_dup 2)
17707 (set (match_operand:SI 1 "register_operand" "=S")
17708 (plus:SI (match_dup 3)
17710 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17712 [(set_attr "type" "str")
17713 (set_attr "memory" "both")
17714 (set_attr "mode" "HI")])
17716 (define_insn "*strmovhi_rex_1"
17717 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17718 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17719 (set (match_operand:DI 0 "register_operand" "=D")
17720 (plus:DI (match_dup 2)
17722 (set (match_operand:DI 1 "register_operand" "=S")
17723 (plus:DI (match_dup 3)
17725 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17727 [(set_attr "type" "str")
17728 (set_attr "memory" "both")
17729 (set_attr "mode" "HI")])
17731 (define_insn "*strmovqi_1"
17732 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17733 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17734 (set (match_operand:SI 0 "register_operand" "=D")
17735 (plus:SI (match_dup 2)
17737 (set (match_operand:SI 1 "register_operand" "=S")
17738 (plus:SI (match_dup 3)
17740 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17742 [(set_attr "type" "str")
17743 (set_attr "memory" "both")
17744 (set_attr "mode" "QI")])
17746 (define_insn "*strmovqi_rex_1"
17747 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17748 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17749 (set (match_operand:DI 0 "register_operand" "=D")
17750 (plus:DI (match_dup 2)
17752 (set (match_operand:DI 1 "register_operand" "=S")
17753 (plus:DI (match_dup 3)
17755 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17757 [(set_attr "type" "str")
17758 (set_attr "memory" "both")
17759 (set_attr "mode" "QI")])
17761 (define_expand "rep_mov"
17762 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17763 (set (match_operand 0 "register_operand" "")
17764 (match_operand 5 "" ""))
17765 (set (match_operand 2 "register_operand" "")
17766 (match_operand 6 "" ""))
17767 (set (match_operand 1 "memory_operand" "")
17768 (match_operand 3 "memory_operand" ""))
17769 (use (match_dup 4))])]
17773 (define_insn "*rep_movdi_rex64"
17774 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17775 (set (match_operand:DI 0 "register_operand" "=D")
17776 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17778 (match_operand:DI 3 "register_operand" "0")))
17779 (set (match_operand:DI 1 "register_operand" "=S")
17780 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17781 (match_operand:DI 4 "register_operand" "1")))
17782 (set (mem:BLK (match_dup 3))
17783 (mem:BLK (match_dup 4)))
17784 (use (match_dup 5))]
17786 "{rep\;movsq|rep movsq}"
17787 [(set_attr "type" "str")
17788 (set_attr "prefix_rep" "1")
17789 (set_attr "memory" "both")
17790 (set_attr "mode" "DI")])
17792 (define_insn "*rep_movsi"
17793 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17794 (set (match_operand:SI 0 "register_operand" "=D")
17795 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17797 (match_operand:SI 3 "register_operand" "0")))
17798 (set (match_operand:SI 1 "register_operand" "=S")
17799 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17800 (match_operand:SI 4 "register_operand" "1")))
17801 (set (mem:BLK (match_dup 3))
17802 (mem:BLK (match_dup 4)))
17803 (use (match_dup 5))]
17805 "{rep\;movsl|rep movsd}"
17806 [(set_attr "type" "str")
17807 (set_attr "prefix_rep" "1")
17808 (set_attr "memory" "both")
17809 (set_attr "mode" "SI")])
17811 (define_insn "*rep_movsi_rex64"
17812 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17813 (set (match_operand:DI 0 "register_operand" "=D")
17814 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17816 (match_operand:DI 3 "register_operand" "0")))
17817 (set (match_operand:DI 1 "register_operand" "=S")
17818 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17819 (match_operand:DI 4 "register_operand" "1")))
17820 (set (mem:BLK (match_dup 3))
17821 (mem:BLK (match_dup 4)))
17822 (use (match_dup 5))]
17824 "{rep\;movsl|rep movsd}"
17825 [(set_attr "type" "str")
17826 (set_attr "prefix_rep" "1")
17827 (set_attr "memory" "both")
17828 (set_attr "mode" "SI")])
17830 (define_insn "*rep_movqi"
17831 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17832 (set (match_operand:SI 0 "register_operand" "=D")
17833 (plus:SI (match_operand:SI 3 "register_operand" "0")
17834 (match_operand:SI 5 "register_operand" "2")))
17835 (set (match_operand:SI 1 "register_operand" "=S")
17836 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17837 (set (mem:BLK (match_dup 3))
17838 (mem:BLK (match_dup 4)))
17839 (use (match_dup 5))]
17841 "{rep\;movsb|rep movsb}"
17842 [(set_attr "type" "str")
17843 (set_attr "prefix_rep" "1")
17844 (set_attr "memory" "both")
17845 (set_attr "mode" "SI")])
17847 (define_insn "*rep_movqi_rex64"
17848 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17849 (set (match_operand:DI 0 "register_operand" "=D")
17850 (plus:DI (match_operand:DI 3 "register_operand" "0")
17851 (match_operand:DI 5 "register_operand" "2")))
17852 (set (match_operand:DI 1 "register_operand" "=S")
17853 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17854 (set (mem:BLK (match_dup 3))
17855 (mem:BLK (match_dup 4)))
17856 (use (match_dup 5))]
17858 "{rep\;movsb|rep movsb}"
17859 [(set_attr "type" "str")
17860 (set_attr "prefix_rep" "1")
17861 (set_attr "memory" "both")
17862 (set_attr "mode" "SI")])
17864 (define_expand "setmemsi"
17865 [(use (match_operand:BLK 0 "memory_operand" ""))
17866 (use (match_operand:SI 1 "nonmemory_operand" ""))
17867 (use (match_operand 2 "const_int_operand" ""))
17868 (use (match_operand 3 "const_int_operand" ""))]
17871 if (ix86_expand_setmem (operands[0], operands[1],
17872 operands[2], operands[3],
17873 operands[3], constm1_rtx))
17879 (define_expand "setmemdi"
17880 [(use (match_operand:BLK 0 "memory_operand" ""))
17881 (use (match_operand:DI 1 "nonmemory_operand" ""))
17882 (use (match_operand 2 "const_int_operand" ""))
17883 (use (match_operand 3 "const_int_operand" ""))
17884 (use (match_operand 4 "const_int_operand" ""))
17885 (use (match_operand 5 "const_int_operand" ""))]
17888 if (ix86_expand_setmem (operands[0], operands[1],
17889 operands[2], operands[3],
17890 operands[3], constm1_rtx))
17896 ;; Most CPUs don't like single string operations
17897 ;; Handle this case here to simplify previous expander.
17899 (define_expand "strset"
17900 [(set (match_operand 1 "memory_operand" "")
17901 (match_operand 2 "register_operand" ""))
17902 (parallel [(set (match_operand 0 "register_operand" "")
17904 (clobber (reg:CC FLAGS_REG))])]
17907 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17908 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17910 /* If .md ever supports :P for Pmode, this can be directly
17911 in the pattern above. */
17912 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17913 GEN_INT (GET_MODE_SIZE (GET_MODE
17915 if (TARGET_SINGLE_STRINGOP || optimize_size)
17917 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17923 (define_expand "strset_singleop"
17924 [(parallel [(set (match_operand 1 "memory_operand" "")
17925 (match_operand 2 "register_operand" ""))
17926 (set (match_operand 0 "register_operand" "")
17927 (match_operand 3 "" ""))])]
17928 "TARGET_SINGLE_STRINGOP || optimize_size"
17931 (define_insn "*strsetdi_rex_1"
17932 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17933 (match_operand:DI 2 "register_operand" "a"))
17934 (set (match_operand:DI 0 "register_operand" "=D")
17935 (plus:DI (match_dup 1)
17937 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17939 [(set_attr "type" "str")
17940 (set_attr "memory" "store")
17941 (set_attr "mode" "DI")])
17943 (define_insn "*strsetsi_1"
17944 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17945 (match_operand:SI 2 "register_operand" "a"))
17946 (set (match_operand:SI 0 "register_operand" "=D")
17947 (plus:SI (match_dup 1)
17949 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17951 [(set_attr "type" "str")
17952 (set_attr "memory" "store")
17953 (set_attr "mode" "SI")])
17955 (define_insn "*strsetsi_rex_1"
17956 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17957 (match_operand:SI 2 "register_operand" "a"))
17958 (set (match_operand:DI 0 "register_operand" "=D")
17959 (plus:DI (match_dup 1)
17961 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17963 [(set_attr "type" "str")
17964 (set_attr "memory" "store")
17965 (set_attr "mode" "SI")])
17967 (define_insn "*strsethi_1"
17968 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17969 (match_operand:HI 2 "register_operand" "a"))
17970 (set (match_operand:SI 0 "register_operand" "=D")
17971 (plus:SI (match_dup 1)
17973 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17975 [(set_attr "type" "str")
17976 (set_attr "memory" "store")
17977 (set_attr "mode" "HI")])
17979 (define_insn "*strsethi_rex_1"
17980 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17981 (match_operand:HI 2 "register_operand" "a"))
17982 (set (match_operand:DI 0 "register_operand" "=D")
17983 (plus:DI (match_dup 1)
17985 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17987 [(set_attr "type" "str")
17988 (set_attr "memory" "store")
17989 (set_attr "mode" "HI")])
17991 (define_insn "*strsetqi_1"
17992 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17993 (match_operand:QI 2 "register_operand" "a"))
17994 (set (match_operand:SI 0 "register_operand" "=D")
17995 (plus:SI (match_dup 1)
17997 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17999 [(set_attr "type" "str")
18000 (set_attr "memory" "store")
18001 (set_attr "mode" "QI")])
18003 (define_insn "*strsetqi_rex_1"
18004 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18005 (match_operand:QI 2 "register_operand" "a"))
18006 (set (match_operand:DI 0 "register_operand" "=D")
18007 (plus:DI (match_dup 1)
18009 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18011 [(set_attr "type" "str")
18012 (set_attr "memory" "store")
18013 (set_attr "mode" "QI")])
18015 (define_expand "rep_stos"
18016 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18017 (set (match_operand 0 "register_operand" "")
18018 (match_operand 4 "" ""))
18019 (set (match_operand 2 "memory_operand" "") (const_int 0))
18020 (use (match_operand 3 "register_operand" ""))
18021 (use (match_dup 1))])]
18025 (define_insn "*rep_stosdi_rex64"
18026 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18027 (set (match_operand:DI 0 "register_operand" "=D")
18028 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18030 (match_operand:DI 3 "register_operand" "0")))
18031 (set (mem:BLK (match_dup 3))
18033 (use (match_operand:DI 2 "register_operand" "a"))
18034 (use (match_dup 4))]
18036 "{rep\;stosq|rep stosq}"
18037 [(set_attr "type" "str")
18038 (set_attr "prefix_rep" "1")
18039 (set_attr "memory" "store")
18040 (set_attr "mode" "DI")])
18042 (define_insn "*rep_stossi"
18043 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18044 (set (match_operand:SI 0 "register_operand" "=D")
18045 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18047 (match_operand:SI 3 "register_operand" "0")))
18048 (set (mem:BLK (match_dup 3))
18050 (use (match_operand:SI 2 "register_operand" "a"))
18051 (use (match_dup 4))]
18053 "{rep\;stosl|rep stosd}"
18054 [(set_attr "type" "str")
18055 (set_attr "prefix_rep" "1")
18056 (set_attr "memory" "store")
18057 (set_attr "mode" "SI")])
18059 (define_insn "*rep_stossi_rex64"
18060 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18061 (set (match_operand:DI 0 "register_operand" "=D")
18062 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18064 (match_operand:DI 3 "register_operand" "0")))
18065 (set (mem:BLK (match_dup 3))
18067 (use (match_operand:SI 2 "register_operand" "a"))
18068 (use (match_dup 4))]
18070 "{rep\;stosl|rep stosd}"
18071 [(set_attr "type" "str")
18072 (set_attr "prefix_rep" "1")
18073 (set_attr "memory" "store")
18074 (set_attr "mode" "SI")])
18076 (define_insn "*rep_stosqi"
18077 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18078 (set (match_operand:SI 0 "register_operand" "=D")
18079 (plus:SI (match_operand:SI 3 "register_operand" "0")
18080 (match_operand:SI 4 "register_operand" "1")))
18081 (set (mem:BLK (match_dup 3))
18083 (use (match_operand:QI 2 "register_operand" "a"))
18084 (use (match_dup 4))]
18086 "{rep\;stosb|rep stosb}"
18087 [(set_attr "type" "str")
18088 (set_attr "prefix_rep" "1")
18089 (set_attr "memory" "store")
18090 (set_attr "mode" "QI")])
18092 (define_insn "*rep_stosqi_rex64"
18093 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18094 (set (match_operand:DI 0 "register_operand" "=D")
18095 (plus:DI (match_operand:DI 3 "register_operand" "0")
18096 (match_operand:DI 4 "register_operand" "1")))
18097 (set (mem:BLK (match_dup 3))
18099 (use (match_operand:QI 2 "register_operand" "a"))
18100 (use (match_dup 4))]
18102 "{rep\;stosb|rep stosb}"
18103 [(set_attr "type" "str")
18104 (set_attr "prefix_rep" "1")
18105 (set_attr "memory" "store")
18106 (set_attr "mode" "QI")])
18108 (define_expand "cmpstrnsi"
18109 [(set (match_operand:SI 0 "register_operand" "")
18110 (compare:SI (match_operand:BLK 1 "general_operand" "")
18111 (match_operand:BLK 2 "general_operand" "")))
18112 (use (match_operand 3 "general_operand" ""))
18113 (use (match_operand 4 "immediate_operand" ""))]
18114 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18116 rtx addr1, addr2, out, outlow, count, countreg, align;
18118 /* Can't use this if the user has appropriated esi or edi. */
18119 if (global_regs[4] || global_regs[5])
18123 if (GET_CODE (out) != REG)
18124 out = gen_reg_rtx (SImode);
18126 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18127 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18128 if (addr1 != XEXP (operands[1], 0))
18129 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18130 if (addr2 != XEXP (operands[2], 0))
18131 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18133 count = operands[3];
18134 countreg = ix86_zero_extend_to_Pmode (count);
18136 /* %%% Iff we are testing strict equality, we can use known alignment
18137 to good advantage. This may be possible with combine, particularly
18138 once cc0 is dead. */
18139 align = operands[4];
18141 if (GET_CODE (count) == CONST_INT)
18143 if (INTVAL (count) == 0)
18145 emit_move_insn (operands[0], const0_rtx);
18148 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18149 operands[1], operands[2]));
18154 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18156 emit_insn (gen_cmpsi_1 (countreg, countreg));
18157 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18158 operands[1], operands[2]));
18161 outlow = gen_lowpart (QImode, out);
18162 emit_insn (gen_cmpintqi (outlow));
18163 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18165 if (operands[0] != out)
18166 emit_move_insn (operands[0], out);
18171 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18173 (define_expand "cmpintqi"
18174 [(set (match_dup 1)
18175 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18177 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18178 (parallel [(set (match_operand:QI 0 "register_operand" "")
18179 (minus:QI (match_dup 1)
18181 (clobber (reg:CC FLAGS_REG))])]
18183 "operands[1] = gen_reg_rtx (QImode);
18184 operands[2] = gen_reg_rtx (QImode);")
18186 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18187 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18189 (define_expand "cmpstrnqi_nz_1"
18190 [(parallel [(set (reg:CC FLAGS_REG)
18191 (compare:CC (match_operand 4 "memory_operand" "")
18192 (match_operand 5 "memory_operand" "")))
18193 (use (match_operand 2 "register_operand" ""))
18194 (use (match_operand:SI 3 "immediate_operand" ""))
18195 (clobber (match_operand 0 "register_operand" ""))
18196 (clobber (match_operand 1 "register_operand" ""))
18197 (clobber (match_dup 2))])]
18201 (define_insn "*cmpstrnqi_nz_1"
18202 [(set (reg:CC FLAGS_REG)
18203 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18204 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18205 (use (match_operand:SI 6 "register_operand" "2"))
18206 (use (match_operand:SI 3 "immediate_operand" "i"))
18207 (clobber (match_operand:SI 0 "register_operand" "=S"))
18208 (clobber (match_operand:SI 1 "register_operand" "=D"))
18209 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18212 [(set_attr "type" "str")
18213 (set_attr "mode" "QI")
18214 (set_attr "prefix_rep" "1")])
18216 (define_insn "*cmpstrnqi_nz_rex_1"
18217 [(set (reg:CC FLAGS_REG)
18218 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18219 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18220 (use (match_operand:DI 6 "register_operand" "2"))
18221 (use (match_operand:SI 3 "immediate_operand" "i"))
18222 (clobber (match_operand:DI 0 "register_operand" "=S"))
18223 (clobber (match_operand:DI 1 "register_operand" "=D"))
18224 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18227 [(set_attr "type" "str")
18228 (set_attr "mode" "QI")
18229 (set_attr "prefix_rep" "1")])
18231 ;; The same, but the count is not known to not be zero.
18233 (define_expand "cmpstrnqi_1"
18234 [(parallel [(set (reg:CC FLAGS_REG)
18235 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18237 (compare:CC (match_operand 4 "memory_operand" "")
18238 (match_operand 5 "memory_operand" ""))
18240 (use (match_operand:SI 3 "immediate_operand" ""))
18241 (use (reg:CC FLAGS_REG))
18242 (clobber (match_operand 0 "register_operand" ""))
18243 (clobber (match_operand 1 "register_operand" ""))
18244 (clobber (match_dup 2))])]
18248 (define_insn "*cmpstrnqi_1"
18249 [(set (reg:CC FLAGS_REG)
18250 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18252 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18253 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18255 (use (match_operand:SI 3 "immediate_operand" "i"))
18256 (use (reg:CC FLAGS_REG))
18257 (clobber (match_operand:SI 0 "register_operand" "=S"))
18258 (clobber (match_operand:SI 1 "register_operand" "=D"))
18259 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18262 [(set_attr "type" "str")
18263 (set_attr "mode" "QI")
18264 (set_attr "prefix_rep" "1")])
18266 (define_insn "*cmpstrnqi_rex_1"
18267 [(set (reg:CC FLAGS_REG)
18268 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18270 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18271 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18273 (use (match_operand:SI 3 "immediate_operand" "i"))
18274 (use (reg:CC FLAGS_REG))
18275 (clobber (match_operand:DI 0 "register_operand" "=S"))
18276 (clobber (match_operand:DI 1 "register_operand" "=D"))
18277 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18280 [(set_attr "type" "str")
18281 (set_attr "mode" "QI")
18282 (set_attr "prefix_rep" "1")])
18284 (define_expand "strlensi"
18285 [(set (match_operand:SI 0 "register_operand" "")
18286 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18287 (match_operand:QI 2 "immediate_operand" "")
18288 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18291 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18297 (define_expand "strlendi"
18298 [(set (match_operand:DI 0 "register_operand" "")
18299 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18300 (match_operand:QI 2 "immediate_operand" "")
18301 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18304 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18310 (define_expand "strlenqi_1"
18311 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18312 (clobber (match_operand 1 "register_operand" ""))
18313 (clobber (reg:CC FLAGS_REG))])]
18317 (define_insn "*strlenqi_1"
18318 [(set (match_operand:SI 0 "register_operand" "=&c")
18319 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18320 (match_operand:QI 2 "register_operand" "a")
18321 (match_operand:SI 3 "immediate_operand" "i")
18322 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18323 (clobber (match_operand:SI 1 "register_operand" "=D"))
18324 (clobber (reg:CC FLAGS_REG))]
18327 [(set_attr "type" "str")
18328 (set_attr "mode" "QI")
18329 (set_attr "prefix_rep" "1")])
18331 (define_insn "*strlenqi_rex_1"
18332 [(set (match_operand:DI 0 "register_operand" "=&c")
18333 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18334 (match_operand:QI 2 "register_operand" "a")
18335 (match_operand:DI 3 "immediate_operand" "i")
18336 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18337 (clobber (match_operand:DI 1 "register_operand" "=D"))
18338 (clobber (reg:CC FLAGS_REG))]
18341 [(set_attr "type" "str")
18342 (set_attr "mode" "QI")
18343 (set_attr "prefix_rep" "1")])
18345 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18346 ;; handled in combine, but it is not currently up to the task.
18347 ;; When used for their truth value, the cmpstrn* expanders generate
18356 ;; The intermediate three instructions are unnecessary.
18358 ;; This one handles cmpstrn*_nz_1...
18361 (set (reg:CC FLAGS_REG)
18362 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18363 (mem:BLK (match_operand 5 "register_operand" ""))))
18364 (use (match_operand 6 "register_operand" ""))
18365 (use (match_operand:SI 3 "immediate_operand" ""))
18366 (clobber (match_operand 0 "register_operand" ""))
18367 (clobber (match_operand 1 "register_operand" ""))
18368 (clobber (match_operand 2 "register_operand" ""))])
18369 (set (match_operand:QI 7 "register_operand" "")
18370 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18371 (set (match_operand:QI 8 "register_operand" "")
18372 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18373 (set (reg FLAGS_REG)
18374 (compare (match_dup 7) (match_dup 8)))
18376 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18378 (set (reg:CC FLAGS_REG)
18379 (compare:CC (mem:BLK (match_dup 4))
18380 (mem:BLK (match_dup 5))))
18381 (use (match_dup 6))
18382 (use (match_dup 3))
18383 (clobber (match_dup 0))
18384 (clobber (match_dup 1))
18385 (clobber (match_dup 2))])]
18388 ;; ...and this one handles cmpstrn*_1.
18391 (set (reg:CC FLAGS_REG)
18392 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18394 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18395 (mem:BLK (match_operand 5 "register_operand" "")))
18397 (use (match_operand:SI 3 "immediate_operand" ""))
18398 (use (reg:CC FLAGS_REG))
18399 (clobber (match_operand 0 "register_operand" ""))
18400 (clobber (match_operand 1 "register_operand" ""))
18401 (clobber (match_operand 2 "register_operand" ""))])
18402 (set (match_operand:QI 7 "register_operand" "")
18403 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18404 (set (match_operand:QI 8 "register_operand" "")
18405 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18406 (set (reg FLAGS_REG)
18407 (compare (match_dup 7) (match_dup 8)))
18409 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18411 (set (reg:CC FLAGS_REG)
18412 (if_then_else:CC (ne (match_dup 6)
18414 (compare:CC (mem:BLK (match_dup 4))
18415 (mem:BLK (match_dup 5)))
18417 (use (match_dup 3))
18418 (use (reg:CC FLAGS_REG))
18419 (clobber (match_dup 0))
18420 (clobber (match_dup 1))
18421 (clobber (match_dup 2))])]
18426 ;; Conditional move instructions.
18428 (define_expand "movdicc"
18429 [(set (match_operand:DI 0 "register_operand" "")
18430 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18431 (match_operand:DI 2 "general_operand" "")
18432 (match_operand:DI 3 "general_operand" "")))]
18434 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18436 (define_insn "x86_movdicc_0_m1_rex64"
18437 [(set (match_operand:DI 0 "register_operand" "=r")
18438 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18441 (clobber (reg:CC FLAGS_REG))]
18444 ; Since we don't have the proper number of operands for an alu insn,
18445 ; fill in all the blanks.
18446 [(set_attr "type" "alu")
18447 (set_attr "pent_pair" "pu")
18448 (set_attr "memory" "none")
18449 (set_attr "imm_disp" "false")
18450 (set_attr "mode" "DI")
18451 (set_attr "length_immediate" "0")])
18453 (define_insn "*movdicc_c_rex64"
18454 [(set (match_operand:DI 0 "register_operand" "=r,r")
18455 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18456 [(reg FLAGS_REG) (const_int 0)])
18457 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18458 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18459 "TARGET_64BIT && TARGET_CMOVE
18460 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18462 cmov%O2%C1\t{%2, %0|%0, %2}
18463 cmov%O2%c1\t{%3, %0|%0, %3}"
18464 [(set_attr "type" "icmov")
18465 (set_attr "mode" "DI")])
18467 (define_expand "movsicc"
18468 [(set (match_operand:SI 0 "register_operand" "")
18469 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18470 (match_operand:SI 2 "general_operand" "")
18471 (match_operand:SI 3 "general_operand" "")))]
18473 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18475 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18476 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18477 ;; So just document what we're doing explicitly.
18479 (define_insn "x86_movsicc_0_m1"
18480 [(set (match_operand:SI 0 "register_operand" "=r")
18481 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18484 (clobber (reg:CC FLAGS_REG))]
18487 ; Since we don't have the proper number of operands for an alu insn,
18488 ; fill in all the blanks.
18489 [(set_attr "type" "alu")
18490 (set_attr "pent_pair" "pu")
18491 (set_attr "memory" "none")
18492 (set_attr "imm_disp" "false")
18493 (set_attr "mode" "SI")
18494 (set_attr "length_immediate" "0")])
18496 (define_insn "*movsicc_noc"
18497 [(set (match_operand:SI 0 "register_operand" "=r,r")
18498 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18499 [(reg FLAGS_REG) (const_int 0)])
18500 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18501 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18503 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18505 cmov%O2%C1\t{%2, %0|%0, %2}
18506 cmov%O2%c1\t{%3, %0|%0, %3}"
18507 [(set_attr "type" "icmov")
18508 (set_attr "mode" "SI")])
18510 (define_expand "movhicc"
18511 [(set (match_operand:HI 0 "register_operand" "")
18512 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18513 (match_operand:HI 2 "general_operand" "")
18514 (match_operand:HI 3 "general_operand" "")))]
18515 "TARGET_HIMODE_MATH"
18516 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18518 (define_insn "*movhicc_noc"
18519 [(set (match_operand:HI 0 "register_operand" "=r,r")
18520 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18521 [(reg FLAGS_REG) (const_int 0)])
18522 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18523 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18525 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18527 cmov%O2%C1\t{%2, %0|%0, %2}
18528 cmov%O2%c1\t{%3, %0|%0, %3}"
18529 [(set_attr "type" "icmov")
18530 (set_attr "mode" "HI")])
18532 (define_expand "movqicc"
18533 [(set (match_operand:QI 0 "register_operand" "")
18534 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18535 (match_operand:QI 2 "general_operand" "")
18536 (match_operand:QI 3 "general_operand" "")))]
18537 "TARGET_QIMODE_MATH"
18538 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18540 (define_insn_and_split "*movqicc_noc"
18541 [(set (match_operand:QI 0 "register_operand" "=r,r")
18542 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18543 [(match_operand 4 "flags_reg_operand" "")
18545 (match_operand:QI 2 "register_operand" "r,0")
18546 (match_operand:QI 3 "register_operand" "0,r")))]
18547 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18549 "&& reload_completed"
18550 [(set (match_dup 0)
18551 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18554 "operands[0] = gen_lowpart (SImode, operands[0]);
18555 operands[2] = gen_lowpart (SImode, operands[2]);
18556 operands[3] = gen_lowpart (SImode, operands[3]);"
18557 [(set_attr "type" "icmov")
18558 (set_attr "mode" "SI")])
18560 (define_expand "movsfcc"
18561 [(set (match_operand:SF 0 "register_operand" "")
18562 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18563 (match_operand:SF 2 "register_operand" "")
18564 (match_operand:SF 3 "register_operand" "")))]
18565 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18566 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18568 (define_insn "*movsfcc_1_387"
18569 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18570 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18571 [(reg FLAGS_REG) (const_int 0)])
18572 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18573 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18574 "TARGET_80387 && TARGET_CMOVE
18575 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18577 fcmov%F1\t{%2, %0|%0, %2}
18578 fcmov%f1\t{%3, %0|%0, %3}
18579 cmov%O2%C1\t{%2, %0|%0, %2}
18580 cmov%O2%c1\t{%3, %0|%0, %3}"
18581 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18582 (set_attr "mode" "SF,SF,SI,SI")])
18584 (define_expand "movdfcc"
18585 [(set (match_operand:DF 0 "register_operand" "")
18586 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18587 (match_operand:DF 2 "register_operand" "")
18588 (match_operand:DF 3 "register_operand" "")))]
18589 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18590 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18592 (define_insn "*movdfcc_1"
18593 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18594 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18595 [(reg FLAGS_REG) (const_int 0)])
18596 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18597 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18598 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18599 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18601 fcmov%F1\t{%2, %0|%0, %2}
18602 fcmov%f1\t{%3, %0|%0, %3}
18605 [(set_attr "type" "fcmov,fcmov,multi,multi")
18606 (set_attr "mode" "DF")])
18608 (define_insn "*movdfcc_1_rex64"
18609 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18610 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18611 [(reg FLAGS_REG) (const_int 0)])
18612 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18613 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18614 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18615 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18617 fcmov%F1\t{%2, %0|%0, %2}
18618 fcmov%f1\t{%3, %0|%0, %3}
18619 cmov%O2%C1\t{%2, %0|%0, %2}
18620 cmov%O2%c1\t{%3, %0|%0, %3}"
18621 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18622 (set_attr "mode" "DF")])
18625 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18626 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18627 [(match_operand 4 "flags_reg_operand" "")
18629 (match_operand:DF 2 "nonimmediate_operand" "")
18630 (match_operand:DF 3 "nonimmediate_operand" "")))]
18631 "!TARGET_64BIT && reload_completed"
18632 [(set (match_dup 2)
18633 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18637 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18640 "split_di (operands+2, 1, operands+5, operands+6);
18641 split_di (operands+3, 1, operands+7, operands+8);
18642 split_di (operands, 1, operands+2, operands+3);")
18644 (define_expand "movxfcc"
18645 [(set (match_operand:XF 0 "register_operand" "")
18646 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18647 (match_operand:XF 2 "register_operand" "")
18648 (match_operand:XF 3 "register_operand" "")))]
18649 "TARGET_80387 && TARGET_CMOVE"
18650 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18652 (define_insn "*movxfcc_1"
18653 [(set (match_operand:XF 0 "register_operand" "=f,f")
18654 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18655 [(reg FLAGS_REG) (const_int 0)])
18656 (match_operand:XF 2 "register_operand" "f,0")
18657 (match_operand:XF 3 "register_operand" "0,f")))]
18658 "TARGET_80387 && TARGET_CMOVE"
18660 fcmov%F1\t{%2, %0|%0, %2}
18661 fcmov%f1\t{%3, %0|%0, %3}"
18662 [(set_attr "type" "fcmov")
18663 (set_attr "mode" "XF")])
18665 ;; These versions of the min/max patterns are intentionally ignorant of
18666 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18667 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18668 ;; are undefined in this condition, we're certain this is correct.
18670 (define_insn "sminsf3"
18671 [(set (match_operand:SF 0 "register_operand" "=x")
18672 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18673 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18675 "minss\t{%2, %0|%0, %2}"
18676 [(set_attr "type" "sseadd")
18677 (set_attr "mode" "SF")])
18679 (define_insn "smaxsf3"
18680 [(set (match_operand:SF 0 "register_operand" "=x")
18681 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18682 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18684 "maxss\t{%2, %0|%0, %2}"
18685 [(set_attr "type" "sseadd")
18686 (set_attr "mode" "SF")])
18688 (define_insn "smindf3"
18689 [(set (match_operand:DF 0 "register_operand" "=x")
18690 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18691 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18692 "TARGET_SSE2 && TARGET_SSE_MATH"
18693 "minsd\t{%2, %0|%0, %2}"
18694 [(set_attr "type" "sseadd")
18695 (set_attr "mode" "DF")])
18697 (define_insn "smaxdf3"
18698 [(set (match_operand:DF 0 "register_operand" "=x")
18699 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18700 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18701 "TARGET_SSE2 && TARGET_SSE_MATH"
18702 "maxsd\t{%2, %0|%0, %2}"
18703 [(set_attr "type" "sseadd")
18704 (set_attr "mode" "DF")])
18706 ;; These versions of the min/max patterns implement exactly the operations
18707 ;; min = (op1 < op2 ? op1 : op2)
18708 ;; max = (!(op1 < op2) ? op1 : op2)
18709 ;; Their operands are not commutative, and thus they may be used in the
18710 ;; presence of -0.0 and NaN.
18712 (define_insn "*ieee_sminsf3"
18713 [(set (match_operand:SF 0 "register_operand" "=x")
18714 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18715 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18718 "minss\t{%2, %0|%0, %2}"
18719 [(set_attr "type" "sseadd")
18720 (set_attr "mode" "SF")])
18722 (define_insn "*ieee_smaxsf3"
18723 [(set (match_operand:SF 0 "register_operand" "=x")
18724 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18725 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18728 "maxss\t{%2, %0|%0, %2}"
18729 [(set_attr "type" "sseadd")
18730 (set_attr "mode" "SF")])
18732 (define_insn "*ieee_smindf3"
18733 [(set (match_operand:DF 0 "register_operand" "=x")
18734 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18735 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18737 "TARGET_SSE2 && TARGET_SSE_MATH"
18738 "minsd\t{%2, %0|%0, %2}"
18739 [(set_attr "type" "sseadd")
18740 (set_attr "mode" "DF")])
18742 (define_insn "*ieee_smaxdf3"
18743 [(set (match_operand:DF 0 "register_operand" "=x")
18744 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18745 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18747 "TARGET_SSE2 && TARGET_SSE_MATH"
18748 "maxsd\t{%2, %0|%0, %2}"
18749 [(set_attr "type" "sseadd")
18750 (set_attr "mode" "DF")])
18752 ;; Make two stack loads independent:
18754 ;; fld %st(0) -> fld bb
18755 ;; fmul bb fmul %st(1), %st
18757 ;; Actually we only match the last two instructions for simplicity.
18759 [(set (match_operand 0 "fp_register_operand" "")
18760 (match_operand 1 "fp_register_operand" ""))
18762 (match_operator 2 "binary_fp_operator"
18764 (match_operand 3 "memory_operand" "")]))]
18765 "REGNO (operands[0]) != REGNO (operands[1])"
18766 [(set (match_dup 0) (match_dup 3))
18767 (set (match_dup 0) (match_dup 4))]
18769 ;; The % modifier is not operational anymore in peephole2's, so we have to
18770 ;; swap the operands manually in the case of addition and multiplication.
18771 "if (COMMUTATIVE_ARITH_P (operands[2]))
18772 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18773 operands[0], operands[1]);
18775 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18776 operands[1], operands[0]);")
18778 ;; Conditional addition patterns
18779 (define_expand "addqicc"
18780 [(match_operand:QI 0 "register_operand" "")
18781 (match_operand 1 "comparison_operator" "")
18782 (match_operand:QI 2 "register_operand" "")
18783 (match_operand:QI 3 "const_int_operand" "")]
18785 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18787 (define_expand "addhicc"
18788 [(match_operand:HI 0 "register_operand" "")
18789 (match_operand 1 "comparison_operator" "")
18790 (match_operand:HI 2 "register_operand" "")
18791 (match_operand:HI 3 "const_int_operand" "")]
18793 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18795 (define_expand "addsicc"
18796 [(match_operand:SI 0 "register_operand" "")
18797 (match_operand 1 "comparison_operator" "")
18798 (match_operand:SI 2 "register_operand" "")
18799 (match_operand:SI 3 "const_int_operand" "")]
18801 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18803 (define_expand "adddicc"
18804 [(match_operand:DI 0 "register_operand" "")
18805 (match_operand 1 "comparison_operator" "")
18806 (match_operand:DI 2 "register_operand" "")
18807 (match_operand:DI 3 "const_int_operand" "")]
18809 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18812 ;; Misc patterns (?)
18814 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18815 ;; Otherwise there will be nothing to keep
18817 ;; [(set (reg ebp) (reg esp))]
18818 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18819 ;; (clobber (eflags)]
18820 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18822 ;; in proper program order.
18823 (define_insn "pro_epilogue_adjust_stack_1"
18824 [(set (match_operand:SI 0 "register_operand" "=r,r")
18825 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18826 (match_operand:SI 2 "immediate_operand" "i,i")))
18827 (clobber (reg:CC FLAGS_REG))
18828 (clobber (mem:BLK (scratch)))]
18831 switch (get_attr_type (insn))
18834 return "mov{l}\t{%1, %0|%0, %1}";
18837 if (GET_CODE (operands[2]) == CONST_INT
18838 && (INTVAL (operands[2]) == 128
18839 || (INTVAL (operands[2]) < 0
18840 && INTVAL (operands[2]) != -128)))
18842 operands[2] = GEN_INT (-INTVAL (operands[2]));
18843 return "sub{l}\t{%2, %0|%0, %2}";
18845 return "add{l}\t{%2, %0|%0, %2}";
18848 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18849 return "lea{l}\t{%a2, %0|%0, %a2}";
18852 gcc_unreachable ();
18855 [(set (attr "type")
18856 (cond [(eq_attr "alternative" "0")
18857 (const_string "alu")
18858 (match_operand:SI 2 "const0_operand" "")
18859 (const_string "imov")
18861 (const_string "lea")))
18862 (set_attr "mode" "SI")])
18864 (define_insn "pro_epilogue_adjust_stack_rex64"
18865 [(set (match_operand:DI 0 "register_operand" "=r,r")
18866 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18867 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18868 (clobber (reg:CC FLAGS_REG))
18869 (clobber (mem:BLK (scratch)))]
18872 switch (get_attr_type (insn))
18875 return "mov{q}\t{%1, %0|%0, %1}";
18878 if (GET_CODE (operands[2]) == CONST_INT
18879 /* Avoid overflows. */
18880 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18881 && (INTVAL (operands[2]) == 128
18882 || (INTVAL (operands[2]) < 0
18883 && INTVAL (operands[2]) != -128)))
18885 operands[2] = GEN_INT (-INTVAL (operands[2]));
18886 return "sub{q}\t{%2, %0|%0, %2}";
18888 return "add{q}\t{%2, %0|%0, %2}";
18891 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18892 return "lea{q}\t{%a2, %0|%0, %a2}";
18895 gcc_unreachable ();
18898 [(set (attr "type")
18899 (cond [(eq_attr "alternative" "0")
18900 (const_string "alu")
18901 (match_operand:DI 2 "const0_operand" "")
18902 (const_string "imov")
18904 (const_string "lea")))
18905 (set_attr "mode" "DI")])
18907 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18908 [(set (match_operand:DI 0 "register_operand" "=r,r")
18909 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18910 (match_operand:DI 3 "immediate_operand" "i,i")))
18911 (use (match_operand:DI 2 "register_operand" "r,r"))
18912 (clobber (reg:CC FLAGS_REG))
18913 (clobber (mem:BLK (scratch)))]
18916 switch (get_attr_type (insn))
18919 return "add{q}\t{%2, %0|%0, %2}";
18922 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18923 return "lea{q}\t{%a2, %0|%0, %a2}";
18926 gcc_unreachable ();
18929 [(set_attr "type" "alu,lea")
18930 (set_attr "mode" "DI")])
18932 (define_expand "allocate_stack_worker"
18933 [(match_operand:SI 0 "register_operand" "")]
18934 "TARGET_STACK_PROBE"
18936 if (reload_completed)
18939 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18941 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18946 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18948 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18953 (define_insn "allocate_stack_worker_1"
18954 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18955 UNSPECV_STACK_PROBE)
18956 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18957 (clobber (match_scratch:SI 1 "=0"))
18958 (clobber (reg:CC FLAGS_REG))]
18959 "!TARGET_64BIT && TARGET_STACK_PROBE"
18961 [(set_attr "type" "multi")
18962 (set_attr "length" "5")])
18964 (define_expand "allocate_stack_worker_postreload"
18965 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18966 UNSPECV_STACK_PROBE)
18967 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18968 (clobber (match_dup 0))
18969 (clobber (reg:CC FLAGS_REG))])]
18973 (define_insn "allocate_stack_worker_rex64"
18974 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18975 UNSPECV_STACK_PROBE)
18976 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18977 (clobber (match_scratch:DI 1 "=0"))
18978 (clobber (reg:CC FLAGS_REG))]
18979 "TARGET_64BIT && TARGET_STACK_PROBE"
18981 [(set_attr "type" "multi")
18982 (set_attr "length" "5")])
18984 (define_expand "allocate_stack_worker_rex64_postreload"
18985 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18986 UNSPECV_STACK_PROBE)
18987 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18988 (clobber (match_dup 0))
18989 (clobber (reg:CC FLAGS_REG))])]
18993 (define_expand "allocate_stack"
18994 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18995 (minus:SI (reg:SI SP_REG)
18996 (match_operand:SI 1 "general_operand" "")))
18997 (clobber (reg:CC FLAGS_REG))])
18998 (parallel [(set (reg:SI SP_REG)
18999 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19000 (clobber (reg:CC FLAGS_REG))])]
19001 "TARGET_STACK_PROBE"
19003 #ifdef CHECK_STACK_LIMIT
19004 if (GET_CODE (operands[1]) == CONST_INT
19005 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19006 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19010 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19013 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19017 (define_expand "builtin_setjmp_receiver"
19018 [(label_ref (match_operand 0 "" ""))]
19019 "!TARGET_64BIT && flag_pic"
19024 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19025 rtx label_rtx = gen_label_rtx ();
19026 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19027 xops[0] = xops[1] = picreg;
19028 xops[2] = gen_rtx_CONST (SImode,
19029 gen_rtx_MINUS (SImode,
19030 gen_rtx_LABEL_REF (SImode, label_rtx),
19031 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19032 ix86_expand_binary_operator (MINUS, SImode, xops);
19035 emit_insn (gen_set_got (pic_offset_table_rtx));
19039 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19042 [(set (match_operand 0 "register_operand" "")
19043 (match_operator 3 "promotable_binary_operator"
19044 [(match_operand 1 "register_operand" "")
19045 (match_operand 2 "aligned_operand" "")]))
19046 (clobber (reg:CC FLAGS_REG))]
19047 "! TARGET_PARTIAL_REG_STALL && reload_completed
19048 && ((GET_MODE (operands[0]) == HImode
19049 && ((!optimize_size && !TARGET_FAST_PREFIX)
19050 /* ??? next two lines just !satisfies_constraint_K (...) */
19051 || GET_CODE (operands[2]) != CONST_INT
19052 || satisfies_constraint_K (operands[2])))
19053 || (GET_MODE (operands[0]) == QImode
19054 && (TARGET_PROMOTE_QImode || optimize_size)))"
19055 [(parallel [(set (match_dup 0)
19056 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19057 (clobber (reg:CC FLAGS_REG))])]
19058 "operands[0] = gen_lowpart (SImode, operands[0]);
19059 operands[1] = gen_lowpart (SImode, operands[1]);
19060 if (GET_CODE (operands[3]) != ASHIFT)
19061 operands[2] = gen_lowpart (SImode, operands[2]);
19062 PUT_MODE (operands[3], SImode);")
19064 ; Promote the QImode tests, as i386 has encoding of the AND
19065 ; instruction with 32-bit sign-extended immediate and thus the
19066 ; instruction size is unchanged, except in the %eax case for
19067 ; which it is increased by one byte, hence the ! optimize_size.
19069 [(set (match_operand 0 "flags_reg_operand" "")
19070 (match_operator 2 "compare_operator"
19071 [(and (match_operand 3 "aligned_operand" "")
19072 (match_operand 4 "const_int_operand" ""))
19074 (set (match_operand 1 "register_operand" "")
19075 (and (match_dup 3) (match_dup 4)))]
19076 "! TARGET_PARTIAL_REG_STALL && reload_completed
19077 /* Ensure that the operand will remain sign-extended immediate. */
19078 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19080 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19081 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19082 [(parallel [(set (match_dup 0)
19083 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19086 (and:SI (match_dup 3) (match_dup 4)))])]
19089 = gen_int_mode (INTVAL (operands[4])
19090 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19091 operands[1] = gen_lowpart (SImode, operands[1]);
19092 operands[3] = gen_lowpart (SImode, operands[3]);
19095 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19096 ; the TEST instruction with 32-bit sign-extended immediate and thus
19097 ; the instruction size would at least double, which is not what we
19098 ; want even with ! optimize_size.
19100 [(set (match_operand 0 "flags_reg_operand" "")
19101 (match_operator 1 "compare_operator"
19102 [(and (match_operand:HI 2 "aligned_operand" "")
19103 (match_operand:HI 3 "const_int_operand" ""))
19105 "! TARGET_PARTIAL_REG_STALL && reload_completed
19106 /* Ensure that the operand will remain sign-extended immediate. */
19107 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19108 && ! TARGET_FAST_PREFIX
19109 && ! optimize_size"
19110 [(set (match_dup 0)
19111 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19115 = gen_int_mode (INTVAL (operands[3])
19116 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19117 operands[2] = gen_lowpart (SImode, operands[2]);
19121 [(set (match_operand 0 "register_operand" "")
19122 (neg (match_operand 1 "register_operand" "")))
19123 (clobber (reg:CC FLAGS_REG))]
19124 "! TARGET_PARTIAL_REG_STALL && reload_completed
19125 && (GET_MODE (operands[0]) == HImode
19126 || (GET_MODE (operands[0]) == QImode
19127 && (TARGET_PROMOTE_QImode || optimize_size)))"
19128 [(parallel [(set (match_dup 0)
19129 (neg:SI (match_dup 1)))
19130 (clobber (reg:CC FLAGS_REG))])]
19131 "operands[0] = gen_lowpart (SImode, operands[0]);
19132 operands[1] = gen_lowpart (SImode, operands[1]);")
19135 [(set (match_operand 0 "register_operand" "")
19136 (not (match_operand 1 "register_operand" "")))]
19137 "! TARGET_PARTIAL_REG_STALL && reload_completed
19138 && (GET_MODE (operands[0]) == HImode
19139 || (GET_MODE (operands[0]) == QImode
19140 && (TARGET_PROMOTE_QImode || optimize_size)))"
19141 [(set (match_dup 0)
19142 (not:SI (match_dup 1)))]
19143 "operands[0] = gen_lowpart (SImode, operands[0]);
19144 operands[1] = gen_lowpart (SImode, operands[1]);")
19147 [(set (match_operand 0 "register_operand" "")
19148 (if_then_else (match_operator 1 "comparison_operator"
19149 [(reg FLAGS_REG) (const_int 0)])
19150 (match_operand 2 "register_operand" "")
19151 (match_operand 3 "register_operand" "")))]
19152 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19153 && (GET_MODE (operands[0]) == HImode
19154 || (GET_MODE (operands[0]) == QImode
19155 && (TARGET_PROMOTE_QImode || optimize_size)))"
19156 [(set (match_dup 0)
19157 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19158 "operands[0] = gen_lowpart (SImode, operands[0]);
19159 operands[2] = gen_lowpart (SImode, operands[2]);
19160 operands[3] = gen_lowpart (SImode, operands[3]);")
19163 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19164 ;; transform a complex memory operation into two memory to register operations.
19166 ;; Don't push memory operands
19168 [(set (match_operand:SI 0 "push_operand" "")
19169 (match_operand:SI 1 "memory_operand" ""))
19170 (match_scratch:SI 2 "r")]
19171 "!optimize_size && !TARGET_PUSH_MEMORY
19172 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19173 [(set (match_dup 2) (match_dup 1))
19174 (set (match_dup 0) (match_dup 2))]
19178 [(set (match_operand:DI 0 "push_operand" "")
19179 (match_operand:DI 1 "memory_operand" ""))
19180 (match_scratch:DI 2 "r")]
19181 "!optimize_size && !TARGET_PUSH_MEMORY
19182 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19183 [(set (match_dup 2) (match_dup 1))
19184 (set (match_dup 0) (match_dup 2))]
19187 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19190 [(set (match_operand:SF 0 "push_operand" "")
19191 (match_operand:SF 1 "memory_operand" ""))
19192 (match_scratch:SF 2 "r")]
19193 "!optimize_size && !TARGET_PUSH_MEMORY
19194 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19195 [(set (match_dup 2) (match_dup 1))
19196 (set (match_dup 0) (match_dup 2))]
19200 [(set (match_operand:HI 0 "push_operand" "")
19201 (match_operand:HI 1 "memory_operand" ""))
19202 (match_scratch:HI 2 "r")]
19203 "!optimize_size && !TARGET_PUSH_MEMORY
19204 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19205 [(set (match_dup 2) (match_dup 1))
19206 (set (match_dup 0) (match_dup 2))]
19210 [(set (match_operand:QI 0 "push_operand" "")
19211 (match_operand:QI 1 "memory_operand" ""))
19212 (match_scratch:QI 2 "q")]
19213 "!optimize_size && !TARGET_PUSH_MEMORY
19214 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19215 [(set (match_dup 2) (match_dup 1))
19216 (set (match_dup 0) (match_dup 2))]
19219 ;; Don't move an immediate directly to memory when the instruction
19222 [(match_scratch:SI 1 "r")
19223 (set (match_operand:SI 0 "memory_operand" "")
19226 && ! TARGET_USE_MOV0
19227 && TARGET_SPLIT_LONG_MOVES
19228 && get_attr_length (insn) >= ix86_cost->large_insn
19229 && peep2_regno_dead_p (0, FLAGS_REG)"
19230 [(parallel [(set (match_dup 1) (const_int 0))
19231 (clobber (reg:CC FLAGS_REG))])
19232 (set (match_dup 0) (match_dup 1))]
19236 [(match_scratch:HI 1 "r")
19237 (set (match_operand:HI 0 "memory_operand" "")
19240 && ! TARGET_USE_MOV0
19241 && TARGET_SPLIT_LONG_MOVES
19242 && get_attr_length (insn) >= ix86_cost->large_insn
19243 && peep2_regno_dead_p (0, FLAGS_REG)"
19244 [(parallel [(set (match_dup 2) (const_int 0))
19245 (clobber (reg:CC FLAGS_REG))])
19246 (set (match_dup 0) (match_dup 1))]
19247 "operands[2] = gen_lowpart (SImode, operands[1]);")
19250 [(match_scratch:QI 1 "q")
19251 (set (match_operand:QI 0 "memory_operand" "")
19254 && ! TARGET_USE_MOV0
19255 && TARGET_SPLIT_LONG_MOVES
19256 && get_attr_length (insn) >= ix86_cost->large_insn
19257 && peep2_regno_dead_p (0, FLAGS_REG)"
19258 [(parallel [(set (match_dup 2) (const_int 0))
19259 (clobber (reg:CC FLAGS_REG))])
19260 (set (match_dup 0) (match_dup 1))]
19261 "operands[2] = gen_lowpart (SImode, operands[1]);")
19264 [(match_scratch:SI 2 "r")
19265 (set (match_operand:SI 0 "memory_operand" "")
19266 (match_operand:SI 1 "immediate_operand" ""))]
19268 && get_attr_length (insn) >= ix86_cost->large_insn
19269 && TARGET_SPLIT_LONG_MOVES"
19270 [(set (match_dup 2) (match_dup 1))
19271 (set (match_dup 0) (match_dup 2))]
19275 [(match_scratch:HI 2 "r")
19276 (set (match_operand:HI 0 "memory_operand" "")
19277 (match_operand:HI 1 "immediate_operand" ""))]
19278 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19279 && TARGET_SPLIT_LONG_MOVES"
19280 [(set (match_dup 2) (match_dup 1))
19281 (set (match_dup 0) (match_dup 2))]
19285 [(match_scratch:QI 2 "q")
19286 (set (match_operand:QI 0 "memory_operand" "")
19287 (match_operand:QI 1 "immediate_operand" ""))]
19288 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19289 && TARGET_SPLIT_LONG_MOVES"
19290 [(set (match_dup 2) (match_dup 1))
19291 (set (match_dup 0) (match_dup 2))]
19294 ;; Don't compare memory with zero, load and use a test instead.
19296 [(set (match_operand 0 "flags_reg_operand" "")
19297 (match_operator 1 "compare_operator"
19298 [(match_operand:SI 2 "memory_operand" "")
19300 (match_scratch:SI 3 "r")]
19301 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19302 [(set (match_dup 3) (match_dup 2))
19303 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19306 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19307 ;; Don't split NOTs with a displacement operand, because resulting XOR
19308 ;; will not be pairable anyway.
19310 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19311 ;; represented using a modRM byte. The XOR replacement is long decoded,
19312 ;; so this split helps here as well.
19314 ;; Note: Can't do this as a regular split because we can't get proper
19315 ;; lifetime information then.
19318 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19319 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19321 && peep2_regno_dead_p (0, FLAGS_REG)
19322 && ((TARGET_PENTIUM
19323 && (GET_CODE (operands[0]) != MEM
19324 || !memory_displacement_operand (operands[0], SImode)))
19325 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19326 [(parallel [(set (match_dup 0)
19327 (xor:SI (match_dup 1) (const_int -1)))
19328 (clobber (reg:CC FLAGS_REG))])]
19332 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19333 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19335 && peep2_regno_dead_p (0, FLAGS_REG)
19336 && ((TARGET_PENTIUM
19337 && (GET_CODE (operands[0]) != MEM
19338 || !memory_displacement_operand (operands[0], HImode)))
19339 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19340 [(parallel [(set (match_dup 0)
19341 (xor:HI (match_dup 1) (const_int -1)))
19342 (clobber (reg:CC FLAGS_REG))])]
19346 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19347 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19349 && peep2_regno_dead_p (0, FLAGS_REG)
19350 && ((TARGET_PENTIUM
19351 && (GET_CODE (operands[0]) != MEM
19352 || !memory_displacement_operand (operands[0], QImode)))
19353 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19354 [(parallel [(set (match_dup 0)
19355 (xor:QI (match_dup 1) (const_int -1)))
19356 (clobber (reg:CC FLAGS_REG))])]
19359 ;; Non pairable "test imm, reg" instructions can be translated to
19360 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19361 ;; byte opcode instead of two, have a short form for byte operands),
19362 ;; so do it for other CPUs as well. Given that the value was dead,
19363 ;; this should not create any new dependencies. Pass on the sub-word
19364 ;; versions if we're concerned about partial register stalls.
19367 [(set (match_operand 0 "flags_reg_operand" "")
19368 (match_operator 1 "compare_operator"
19369 [(and:SI (match_operand:SI 2 "register_operand" "")
19370 (match_operand:SI 3 "immediate_operand" ""))
19372 "ix86_match_ccmode (insn, CCNOmode)
19373 && (true_regnum (operands[2]) != 0
19374 || satisfies_constraint_K (operands[3]))
19375 && peep2_reg_dead_p (1, operands[2])"
19377 [(set (match_dup 0)
19378 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19381 (and:SI (match_dup 2) (match_dup 3)))])]
19384 ;; We don't need to handle HImode case, because it will be promoted to SImode
19385 ;; on ! TARGET_PARTIAL_REG_STALL
19388 [(set (match_operand 0 "flags_reg_operand" "")
19389 (match_operator 1 "compare_operator"
19390 [(and:QI (match_operand:QI 2 "register_operand" "")
19391 (match_operand:QI 3 "immediate_operand" ""))
19393 "! TARGET_PARTIAL_REG_STALL
19394 && ix86_match_ccmode (insn, CCNOmode)
19395 && true_regnum (operands[2]) != 0
19396 && peep2_reg_dead_p (1, operands[2])"
19398 [(set (match_dup 0)
19399 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19402 (and:QI (match_dup 2) (match_dup 3)))])]
19406 [(set (match_operand 0 "flags_reg_operand" "")
19407 (match_operator 1 "compare_operator"
19410 (match_operand 2 "ext_register_operand" "")
19413 (match_operand 3 "const_int_operand" ""))
19415 "! TARGET_PARTIAL_REG_STALL
19416 && ix86_match_ccmode (insn, CCNOmode)
19417 && true_regnum (operands[2]) != 0
19418 && peep2_reg_dead_p (1, operands[2])"
19419 [(parallel [(set (match_dup 0)
19428 (set (zero_extract:SI (match_dup 2)
19439 ;; Don't do logical operations with memory inputs.
19441 [(match_scratch:SI 2 "r")
19442 (parallel [(set (match_operand:SI 0 "register_operand" "")
19443 (match_operator:SI 3 "arith_or_logical_operator"
19445 (match_operand:SI 1 "memory_operand" "")]))
19446 (clobber (reg:CC FLAGS_REG))])]
19447 "! optimize_size && ! TARGET_READ_MODIFY"
19448 [(set (match_dup 2) (match_dup 1))
19449 (parallel [(set (match_dup 0)
19450 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19451 (clobber (reg:CC FLAGS_REG))])]
19455 [(match_scratch:SI 2 "r")
19456 (parallel [(set (match_operand:SI 0 "register_operand" "")
19457 (match_operator:SI 3 "arith_or_logical_operator"
19458 [(match_operand:SI 1 "memory_operand" "")
19460 (clobber (reg:CC FLAGS_REG))])]
19461 "! optimize_size && ! TARGET_READ_MODIFY"
19462 [(set (match_dup 2) (match_dup 1))
19463 (parallel [(set (match_dup 0)
19464 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19465 (clobber (reg:CC FLAGS_REG))])]
19468 ; Don't do logical operations with memory outputs
19470 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19471 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19472 ; the same decoder scheduling characteristics as the original.
19475 [(match_scratch:SI 2 "r")
19476 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19477 (match_operator:SI 3 "arith_or_logical_operator"
19479 (match_operand:SI 1 "nonmemory_operand" "")]))
19480 (clobber (reg:CC FLAGS_REG))])]
19481 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19482 [(set (match_dup 2) (match_dup 0))
19483 (parallel [(set (match_dup 2)
19484 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19485 (clobber (reg:CC FLAGS_REG))])
19486 (set (match_dup 0) (match_dup 2))]
19490 [(match_scratch:SI 2 "r")
19491 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19492 (match_operator:SI 3 "arith_or_logical_operator"
19493 [(match_operand:SI 1 "nonmemory_operand" "")
19495 (clobber (reg:CC FLAGS_REG))])]
19496 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19497 [(set (match_dup 2) (match_dup 0))
19498 (parallel [(set (match_dup 2)
19499 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19500 (clobber (reg:CC FLAGS_REG))])
19501 (set (match_dup 0) (match_dup 2))]
19504 ;; Attempt to always use XOR for zeroing registers.
19506 [(set (match_operand 0 "register_operand" "")
19507 (match_operand 1 "const0_operand" ""))]
19508 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19509 && (! TARGET_USE_MOV0 || optimize_size)
19510 && GENERAL_REG_P (operands[0])
19511 && peep2_regno_dead_p (0, FLAGS_REG)"
19512 [(parallel [(set (match_dup 0) (const_int 0))
19513 (clobber (reg:CC FLAGS_REG))])]
19515 operands[0] = gen_lowpart (word_mode, operands[0]);
19519 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19521 "(GET_MODE (operands[0]) == QImode
19522 || GET_MODE (operands[0]) == HImode)
19523 && (! TARGET_USE_MOV0 || optimize_size)
19524 && peep2_regno_dead_p (0, FLAGS_REG)"
19525 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19526 (clobber (reg:CC FLAGS_REG))])])
19528 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19530 [(set (match_operand 0 "register_operand" "")
19532 "(GET_MODE (operands[0]) == HImode
19533 || GET_MODE (operands[0]) == SImode
19534 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19535 && (optimize_size || TARGET_PENTIUM)
19536 && peep2_regno_dead_p (0, FLAGS_REG)"
19537 [(parallel [(set (match_dup 0) (const_int -1))
19538 (clobber (reg:CC FLAGS_REG))])]
19539 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19542 ;; Attempt to convert simple leas to adds. These can be created by
19545 [(set (match_operand:SI 0 "register_operand" "")
19546 (plus:SI (match_dup 0)
19547 (match_operand:SI 1 "nonmemory_operand" "")))]
19548 "peep2_regno_dead_p (0, FLAGS_REG)"
19549 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19550 (clobber (reg:CC FLAGS_REG))])]
19554 [(set (match_operand:SI 0 "register_operand" "")
19555 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19556 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19557 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19558 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19559 (clobber (reg:CC FLAGS_REG))])]
19560 "operands[2] = gen_lowpart (SImode, operands[2]);")
19563 [(set (match_operand:DI 0 "register_operand" "")
19564 (plus:DI (match_dup 0)
19565 (match_operand:DI 1 "x86_64_general_operand" "")))]
19566 "peep2_regno_dead_p (0, FLAGS_REG)"
19567 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19568 (clobber (reg:CC FLAGS_REG))])]
19572 [(set (match_operand:SI 0 "register_operand" "")
19573 (mult:SI (match_dup 0)
19574 (match_operand:SI 1 "const_int_operand" "")))]
19575 "exact_log2 (INTVAL (operands[1])) >= 0
19576 && peep2_regno_dead_p (0, FLAGS_REG)"
19577 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19578 (clobber (reg:CC FLAGS_REG))])]
19579 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19582 [(set (match_operand:DI 0 "register_operand" "")
19583 (mult:DI (match_dup 0)
19584 (match_operand:DI 1 "const_int_operand" "")))]
19585 "exact_log2 (INTVAL (operands[1])) >= 0
19586 && peep2_regno_dead_p (0, FLAGS_REG)"
19587 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19588 (clobber (reg:CC FLAGS_REG))])]
19589 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19592 [(set (match_operand:SI 0 "register_operand" "")
19593 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19594 (match_operand:DI 2 "const_int_operand" "")) 0))]
19595 "exact_log2 (INTVAL (operands[2])) >= 0
19596 && REGNO (operands[0]) == REGNO (operands[1])
19597 && peep2_regno_dead_p (0, FLAGS_REG)"
19598 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19599 (clobber (reg:CC FLAGS_REG))])]
19600 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19602 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19603 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19604 ;; many CPUs it is also faster, since special hardware to avoid esp
19605 ;; dependencies is present.
19607 ;; While some of these conversions may be done using splitters, we use peepholes
19608 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19610 ;; Convert prologue esp subtractions to push.
19611 ;; We need register to push. In order to keep verify_flow_info happy we have
19613 ;; - use scratch and clobber it in order to avoid dependencies
19614 ;; - use already live register
19615 ;; We can't use the second way right now, since there is no reliable way how to
19616 ;; verify that given register is live. First choice will also most likely in
19617 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19618 ;; call clobbered registers are dead. We may want to use base pointer as an
19619 ;; alternative when no register is available later.
19622 [(match_scratch:SI 0 "r")
19623 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19624 (clobber (reg:CC FLAGS_REG))
19625 (clobber (mem:BLK (scratch)))])]
19626 "optimize_size || !TARGET_SUB_ESP_4"
19627 [(clobber (match_dup 0))
19628 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19629 (clobber (mem:BLK (scratch)))])])
19632 [(match_scratch:SI 0 "r")
19633 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19634 (clobber (reg:CC FLAGS_REG))
19635 (clobber (mem:BLK (scratch)))])]
19636 "optimize_size || !TARGET_SUB_ESP_8"
19637 [(clobber (match_dup 0))
19638 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19639 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19640 (clobber (mem:BLK (scratch)))])])
19642 ;; Convert esp subtractions to push.
19644 [(match_scratch:SI 0 "r")
19645 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19646 (clobber (reg:CC FLAGS_REG))])]
19647 "optimize_size || !TARGET_SUB_ESP_4"
19648 [(clobber (match_dup 0))
19649 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19652 [(match_scratch:SI 0 "r")
19653 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19654 (clobber (reg:CC FLAGS_REG))])]
19655 "optimize_size || !TARGET_SUB_ESP_8"
19656 [(clobber (match_dup 0))
19657 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19658 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19660 ;; Convert epilogue deallocator to pop.
19662 [(match_scratch:SI 0 "r")
19663 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19664 (clobber (reg:CC FLAGS_REG))
19665 (clobber (mem:BLK (scratch)))])]
19666 "optimize_size || !TARGET_ADD_ESP_4"
19667 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19668 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19669 (clobber (mem:BLK (scratch)))])]
19672 ;; Two pops case is tricky, since pop causes dependency on destination register.
19673 ;; We use two registers if available.
19675 [(match_scratch:SI 0 "r")
19676 (match_scratch:SI 1 "r")
19677 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19678 (clobber (reg:CC FLAGS_REG))
19679 (clobber (mem:BLK (scratch)))])]
19680 "optimize_size || !TARGET_ADD_ESP_8"
19681 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19682 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19683 (clobber (mem:BLK (scratch)))])
19684 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19685 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19689 [(match_scratch:SI 0 "r")
19690 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19691 (clobber (reg:CC FLAGS_REG))
19692 (clobber (mem:BLK (scratch)))])]
19694 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19695 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19696 (clobber (mem:BLK (scratch)))])
19697 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19698 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19701 ;; Convert esp additions to pop.
19703 [(match_scratch:SI 0 "r")
19704 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19705 (clobber (reg:CC FLAGS_REG))])]
19707 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19708 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19711 ;; Two pops case is tricky, since pop causes dependency on destination register.
19712 ;; We use two registers if available.
19714 [(match_scratch:SI 0 "r")
19715 (match_scratch:SI 1 "r")
19716 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19717 (clobber (reg:CC FLAGS_REG))])]
19719 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19720 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19721 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19722 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19726 [(match_scratch:SI 0 "r")
19727 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19728 (clobber (reg:CC FLAGS_REG))])]
19730 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19731 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19732 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19733 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19736 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19737 ;; required and register dies. Similarly for 128 to plus -128.
19739 [(set (match_operand 0 "flags_reg_operand" "")
19740 (match_operator 1 "compare_operator"
19741 [(match_operand 2 "register_operand" "")
19742 (match_operand 3 "const_int_operand" "")]))]
19743 "(INTVAL (operands[3]) == -1
19744 || INTVAL (operands[3]) == 1
19745 || INTVAL (operands[3]) == 128)
19746 && ix86_match_ccmode (insn, CCGCmode)
19747 && peep2_reg_dead_p (1, operands[2])"
19748 [(parallel [(set (match_dup 0)
19749 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19750 (clobber (match_dup 2))])]
19754 [(match_scratch:DI 0 "r")
19755 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19756 (clobber (reg:CC FLAGS_REG))
19757 (clobber (mem:BLK (scratch)))])]
19758 "optimize_size || !TARGET_SUB_ESP_4"
19759 [(clobber (match_dup 0))
19760 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19761 (clobber (mem:BLK (scratch)))])])
19764 [(match_scratch:DI 0 "r")
19765 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19766 (clobber (reg:CC FLAGS_REG))
19767 (clobber (mem:BLK (scratch)))])]
19768 "optimize_size || !TARGET_SUB_ESP_8"
19769 [(clobber (match_dup 0))
19770 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19771 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19772 (clobber (mem:BLK (scratch)))])])
19774 ;; Convert esp subtractions to push.
19776 [(match_scratch:DI 0 "r")
19777 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19778 (clobber (reg:CC FLAGS_REG))])]
19779 "optimize_size || !TARGET_SUB_ESP_4"
19780 [(clobber (match_dup 0))
19781 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19784 [(match_scratch:DI 0 "r")
19785 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19786 (clobber (reg:CC FLAGS_REG))])]
19787 "optimize_size || !TARGET_SUB_ESP_8"
19788 [(clobber (match_dup 0))
19789 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19790 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19792 ;; Convert epilogue deallocator to pop.
19794 [(match_scratch:DI 0 "r")
19795 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19796 (clobber (reg:CC FLAGS_REG))
19797 (clobber (mem:BLK (scratch)))])]
19798 "optimize_size || !TARGET_ADD_ESP_4"
19799 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19800 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19801 (clobber (mem:BLK (scratch)))])]
19804 ;; Two pops case is tricky, since pop causes dependency on destination register.
19805 ;; We use two registers if available.
19807 [(match_scratch:DI 0 "r")
19808 (match_scratch:DI 1 "r")
19809 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19810 (clobber (reg:CC FLAGS_REG))
19811 (clobber (mem:BLK (scratch)))])]
19812 "optimize_size || !TARGET_ADD_ESP_8"
19813 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19814 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19815 (clobber (mem:BLK (scratch)))])
19816 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19817 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19821 [(match_scratch:DI 0 "r")
19822 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19823 (clobber (reg:CC FLAGS_REG))
19824 (clobber (mem:BLK (scratch)))])]
19826 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19827 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19828 (clobber (mem:BLK (scratch)))])
19829 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19830 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19833 ;; Convert esp additions to pop.
19835 [(match_scratch:DI 0 "r")
19836 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19837 (clobber (reg:CC FLAGS_REG))])]
19839 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19840 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19843 ;; Two pops case is tricky, since pop causes dependency on destination register.
19844 ;; We use two registers if available.
19846 [(match_scratch:DI 0 "r")
19847 (match_scratch:DI 1 "r")
19848 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19849 (clobber (reg:CC FLAGS_REG))])]
19851 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19852 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19853 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19854 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19858 [(match_scratch:DI 0 "r")
19859 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19860 (clobber (reg:CC FLAGS_REG))])]
19862 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19863 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19864 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19865 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19868 ;; Convert imul by three, five and nine into lea
19871 [(set (match_operand:SI 0 "register_operand" "")
19872 (mult:SI (match_operand:SI 1 "register_operand" "")
19873 (match_operand:SI 2 "const_int_operand" "")))
19874 (clobber (reg:CC FLAGS_REG))])]
19875 "INTVAL (operands[2]) == 3
19876 || INTVAL (operands[2]) == 5
19877 || INTVAL (operands[2]) == 9"
19878 [(set (match_dup 0)
19879 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19881 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19885 [(set (match_operand:SI 0 "register_operand" "")
19886 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19887 (match_operand:SI 2 "const_int_operand" "")))
19888 (clobber (reg:CC FLAGS_REG))])]
19890 && (INTVAL (operands[2]) == 3
19891 || INTVAL (operands[2]) == 5
19892 || INTVAL (operands[2]) == 9)"
19893 [(set (match_dup 0) (match_dup 1))
19895 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19897 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19901 [(set (match_operand:DI 0 "register_operand" "")
19902 (mult:DI (match_operand:DI 1 "register_operand" "")
19903 (match_operand:DI 2 "const_int_operand" "")))
19904 (clobber (reg:CC FLAGS_REG))])]
19906 && (INTVAL (operands[2]) == 3
19907 || INTVAL (operands[2]) == 5
19908 || INTVAL (operands[2]) == 9)"
19909 [(set (match_dup 0)
19910 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19912 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19916 [(set (match_operand:DI 0 "register_operand" "")
19917 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19918 (match_operand:DI 2 "const_int_operand" "")))
19919 (clobber (reg:CC FLAGS_REG))])]
19922 && (INTVAL (operands[2]) == 3
19923 || INTVAL (operands[2]) == 5
19924 || INTVAL (operands[2]) == 9)"
19925 [(set (match_dup 0) (match_dup 1))
19927 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19929 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19931 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19932 ;; imul $32bit_imm, reg, reg is direct decoded.
19934 [(match_scratch:DI 3 "r")
19935 (parallel [(set (match_operand:DI 0 "register_operand" "")
19936 (mult:DI (match_operand:DI 1 "memory_operand" "")
19937 (match_operand:DI 2 "immediate_operand" "")))
19938 (clobber (reg:CC FLAGS_REG))])]
19939 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19940 && !satisfies_constraint_K (operands[2])"
19941 [(set (match_dup 3) (match_dup 1))
19942 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19943 (clobber (reg:CC FLAGS_REG))])]
19947 [(match_scratch:SI 3 "r")
19948 (parallel [(set (match_operand:SI 0 "register_operand" "")
19949 (mult:SI (match_operand:SI 1 "memory_operand" "")
19950 (match_operand:SI 2 "immediate_operand" "")))
19951 (clobber (reg:CC FLAGS_REG))])]
19952 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19953 && !satisfies_constraint_K (operands[2])"
19954 [(set (match_dup 3) (match_dup 1))
19955 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19956 (clobber (reg:CC FLAGS_REG))])]
19960 [(match_scratch:SI 3 "r")
19961 (parallel [(set (match_operand:DI 0 "register_operand" "")
19963 (mult:SI (match_operand:SI 1 "memory_operand" "")
19964 (match_operand:SI 2 "immediate_operand" ""))))
19965 (clobber (reg:CC FLAGS_REG))])]
19966 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19967 && !satisfies_constraint_K (operands[2])"
19968 [(set (match_dup 3) (match_dup 1))
19969 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19970 (clobber (reg:CC FLAGS_REG))])]
19973 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19974 ;; Convert it into imul reg, reg
19975 ;; It would be better to force assembler to encode instruction using long
19976 ;; immediate, but there is apparently no way to do so.
19978 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19979 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19980 (match_operand:DI 2 "const_int_operand" "")))
19981 (clobber (reg:CC FLAGS_REG))])
19982 (match_scratch:DI 3 "r")]
19983 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19984 && satisfies_constraint_K (operands[2])"
19985 [(set (match_dup 3) (match_dup 2))
19986 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19987 (clobber (reg:CC FLAGS_REG))])]
19989 if (!rtx_equal_p (operands[0], operands[1]))
19990 emit_move_insn (operands[0], operands[1]);
19994 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19995 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19996 (match_operand:SI 2 "const_int_operand" "")))
19997 (clobber (reg:CC FLAGS_REG))])
19998 (match_scratch:SI 3 "r")]
19999 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20000 && satisfies_constraint_K (operands[2])"
20001 [(set (match_dup 3) (match_dup 2))
20002 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20003 (clobber (reg:CC FLAGS_REG))])]
20005 if (!rtx_equal_p (operands[0], operands[1]))
20006 emit_move_insn (operands[0], operands[1]);
20010 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20011 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20012 (match_operand:HI 2 "immediate_operand" "")))
20013 (clobber (reg:CC FLAGS_REG))])
20014 (match_scratch:HI 3 "r")]
20015 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20016 [(set (match_dup 3) (match_dup 2))
20017 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20018 (clobber (reg:CC FLAGS_REG))])]
20020 if (!rtx_equal_p (operands[0], operands[1]))
20021 emit_move_insn (operands[0], operands[1]);
20024 ;; After splitting up read-modify operations, array accesses with memory
20025 ;; operands might end up in form:
20027 ;; movl 4(%esp), %edx
20029 ;; instead of pre-splitting:
20031 ;; addl 4(%esp), %eax
20033 ;; movl 4(%esp), %edx
20034 ;; leal (%edx,%eax,4), %eax
20037 [(parallel [(set (match_operand 0 "register_operand" "")
20038 (ashift (match_operand 1 "register_operand" "")
20039 (match_operand 2 "const_int_operand" "")))
20040 (clobber (reg:CC FLAGS_REG))])
20041 (set (match_operand 3 "register_operand")
20042 (match_operand 4 "x86_64_general_operand" ""))
20043 (parallel [(set (match_operand 5 "register_operand" "")
20044 (plus (match_operand 6 "register_operand" "")
20045 (match_operand 7 "register_operand" "")))
20046 (clobber (reg:CC FLAGS_REG))])]
20047 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20048 /* Validate MODE for lea. */
20049 && ((!TARGET_PARTIAL_REG_STALL
20050 && (GET_MODE (operands[0]) == QImode
20051 || GET_MODE (operands[0]) == HImode))
20052 || GET_MODE (operands[0]) == SImode
20053 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20054 /* We reorder load and the shift. */
20055 && !rtx_equal_p (operands[1], operands[3])
20056 && !reg_overlap_mentioned_p (operands[0], operands[4])
20057 /* Last PLUS must consist of operand 0 and 3. */
20058 && !rtx_equal_p (operands[0], operands[3])
20059 && (rtx_equal_p (operands[3], operands[6])
20060 || rtx_equal_p (operands[3], operands[7]))
20061 && (rtx_equal_p (operands[0], operands[6])
20062 || rtx_equal_p (operands[0], operands[7]))
20063 /* The intermediate operand 0 must die or be same as output. */
20064 && (rtx_equal_p (operands[0], operands[5])
20065 || peep2_reg_dead_p (3, operands[0]))"
20066 [(set (match_dup 3) (match_dup 4))
20067 (set (match_dup 0) (match_dup 1))]
20069 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20070 int scale = 1 << INTVAL (operands[2]);
20071 rtx index = gen_lowpart (Pmode, operands[1]);
20072 rtx base = gen_lowpart (Pmode, operands[3]);
20073 rtx dest = gen_lowpart (mode, operands[5]);
20075 operands[1] = gen_rtx_PLUS (Pmode, base,
20076 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20078 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20079 operands[0] = dest;
20082 ;; Call-value patterns last so that the wildcard operand does not
20083 ;; disrupt insn-recog's switch tables.
20085 (define_insn "*call_value_pop_0"
20086 [(set (match_operand 0 "" "")
20087 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20088 (match_operand:SI 2 "" "")))
20089 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20090 (match_operand:SI 3 "immediate_operand" "")))]
20093 if (SIBLING_CALL_P (insn))
20096 return "call\t%P1";
20098 [(set_attr "type" "callv")])
20100 (define_insn "*call_value_pop_1"
20101 [(set (match_operand 0 "" "")
20102 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20103 (match_operand:SI 2 "" "")))
20104 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20105 (match_operand:SI 3 "immediate_operand" "i")))]
20108 if (constant_call_address_operand (operands[1], Pmode))
20110 if (SIBLING_CALL_P (insn))
20113 return "call\t%P1";
20115 if (SIBLING_CALL_P (insn))
20118 return "call\t%A1";
20120 [(set_attr "type" "callv")])
20122 (define_insn "*call_value_0"
20123 [(set (match_operand 0 "" "")
20124 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20125 (match_operand:SI 2 "" "")))]
20128 if (SIBLING_CALL_P (insn))
20131 return "call\t%P1";
20133 [(set_attr "type" "callv")])
20135 (define_insn "*call_value_0_rex64"
20136 [(set (match_operand 0 "" "")
20137 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20138 (match_operand:DI 2 "const_int_operand" "")))]
20141 if (SIBLING_CALL_P (insn))
20144 return "call\t%P1";
20146 [(set_attr "type" "callv")])
20148 (define_insn "*call_value_1"
20149 [(set (match_operand 0 "" "")
20150 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20151 (match_operand:SI 2 "" "")))]
20152 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20154 if (constant_call_address_operand (operands[1], Pmode))
20155 return "call\t%P1";
20156 return "call\t%A1";
20158 [(set_attr "type" "callv")])
20160 (define_insn "*sibcall_value_1"
20161 [(set (match_operand 0 "" "")
20162 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20163 (match_operand:SI 2 "" "")))]
20164 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20166 if (constant_call_address_operand (operands[1], Pmode))
20170 [(set_attr "type" "callv")])
20172 (define_insn "*call_value_1_rex64"
20173 [(set (match_operand 0 "" "")
20174 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20175 (match_operand:DI 2 "" "")))]
20176 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20178 if (constant_call_address_operand (operands[1], Pmode))
20179 return "call\t%P1";
20180 return "call\t%A1";
20182 [(set_attr "type" "callv")])
20184 (define_insn "*sibcall_value_1_rex64"
20185 [(set (match_operand 0 "" "")
20186 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20187 (match_operand:DI 2 "" "")))]
20188 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20190 [(set_attr "type" "callv")])
20192 (define_insn "*sibcall_value_1_rex64_v"
20193 [(set (match_operand 0 "" "")
20194 (call (mem:QI (reg:DI R11_REG))
20195 (match_operand:DI 1 "" "")))]
20196 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20198 [(set_attr "type" "callv")])
20200 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20201 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20202 ;; caught for use by garbage collectors and the like. Using an insn that
20203 ;; maps to SIGILL makes it more likely the program will rightfully die.
20204 ;; Keeping with tradition, "6" is in honor of #UD.
20205 (define_insn "trap"
20206 [(trap_if (const_int 1) (const_int 6))]
20208 { return ASM_SHORT "0x0b0f"; }
20209 [(set_attr "length" "2")])
20211 (define_expand "sse_prologue_save"
20212 [(parallel [(set (match_operand:BLK 0 "" "")
20213 (unspec:BLK [(reg:DI 21)
20220 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20221 (use (match_operand:DI 1 "register_operand" ""))
20222 (use (match_operand:DI 2 "immediate_operand" ""))
20223 (use (label_ref:DI (match_operand 3 "" "")))])]
20227 (define_insn "*sse_prologue_save_insn"
20228 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20229 (match_operand:DI 4 "const_int_operand" "n")))
20230 (unspec:BLK [(reg:DI 21)
20237 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20238 (use (match_operand:DI 1 "register_operand" "r"))
20239 (use (match_operand:DI 2 "const_int_operand" "i"))
20240 (use (label_ref:DI (match_operand 3 "" "X")))]
20242 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20243 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20247 operands[0] = gen_rtx_MEM (Pmode,
20248 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20249 output_asm_insn (\"jmp\\t%A1\", operands);
20250 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20252 operands[4] = adjust_address (operands[0], DImode, i*16);
20253 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20254 PUT_MODE (operands[4], TImode);
20255 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20256 output_asm_insn (\"rex\", operands);
20257 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20259 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20260 CODE_LABEL_NUMBER (operands[3]));
20264 [(set_attr "type" "other")
20265 (set_attr "length_immediate" "0")
20266 (set_attr "length_address" "0")
20267 (set_attr "length" "135")
20268 (set_attr "memory" "store")
20269 (set_attr "modrm" "0")
20270 (set_attr "mode" "DI")])
20272 (define_expand "prefetch"
20273 [(prefetch (match_operand 0 "address_operand" "")
20274 (match_operand:SI 1 "const_int_operand" "")
20275 (match_operand:SI 2 "const_int_operand" ""))]
20276 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20278 int rw = INTVAL (operands[1]);
20279 int locality = INTVAL (operands[2]);
20281 gcc_assert (rw == 0 || rw == 1);
20282 gcc_assert (locality >= 0 && locality <= 3);
20283 gcc_assert (GET_MODE (operands[0]) == Pmode
20284 || GET_MODE (operands[0]) == VOIDmode);
20286 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20287 supported by SSE counterpart or the SSE prefetch is not available
20288 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20290 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20291 operands[2] = GEN_INT (3);
20293 operands[1] = const0_rtx;
20296 (define_insn "*prefetch_sse"
20297 [(prefetch (match_operand:SI 0 "address_operand" "p")
20299 (match_operand:SI 1 "const_int_operand" ""))]
20300 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20302 static const char * const patterns[4] = {
20303 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20306 int locality = INTVAL (operands[1]);
20307 gcc_assert (locality >= 0 && locality <= 3);
20309 return patterns[locality];
20311 [(set_attr "type" "sse")
20312 (set_attr "memory" "none")])
20314 (define_insn "*prefetch_sse_rex"
20315 [(prefetch (match_operand:DI 0 "address_operand" "p")
20317 (match_operand:SI 1 "const_int_operand" ""))]
20318 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20320 static const char * const patterns[4] = {
20321 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20324 int locality = INTVAL (operands[1]);
20325 gcc_assert (locality >= 0 && locality <= 3);
20327 return patterns[locality];
20329 [(set_attr "type" "sse")
20330 (set_attr "memory" "none")])
20332 (define_insn "*prefetch_3dnow"
20333 [(prefetch (match_operand:SI 0 "address_operand" "p")
20334 (match_operand:SI 1 "const_int_operand" "n")
20336 "TARGET_3DNOW && !TARGET_64BIT"
20338 if (INTVAL (operands[1]) == 0)
20339 return "prefetch\t%a0";
20341 return "prefetchw\t%a0";
20343 [(set_attr "type" "mmx")
20344 (set_attr "memory" "none")])
20346 (define_insn "*prefetch_3dnow_rex"
20347 [(prefetch (match_operand:DI 0 "address_operand" "p")
20348 (match_operand:SI 1 "const_int_operand" "n")
20350 "TARGET_3DNOW && TARGET_64BIT"
20352 if (INTVAL (operands[1]) == 0)
20353 return "prefetch\t%a0";
20355 return "prefetchw\t%a0";
20357 [(set_attr "type" "mmx")
20358 (set_attr "memory" "none")])
20360 (define_expand "stack_protect_set"
20361 [(match_operand 0 "memory_operand" "")
20362 (match_operand 1 "memory_operand" "")]
20365 #ifdef TARGET_THREAD_SSP_OFFSET
20367 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20368 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20370 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20371 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20374 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20376 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20381 (define_insn "stack_protect_set_si"
20382 [(set (match_operand:SI 0 "memory_operand" "=m")
20383 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20384 (set (match_scratch:SI 2 "=&r") (const_int 0))
20385 (clobber (reg:CC FLAGS_REG))]
20387 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20388 [(set_attr "type" "multi")])
20390 (define_insn "stack_protect_set_di"
20391 [(set (match_operand:DI 0 "memory_operand" "=m")
20392 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20393 (set (match_scratch:DI 2 "=&r") (const_int 0))
20394 (clobber (reg:CC FLAGS_REG))]
20396 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20397 [(set_attr "type" "multi")])
20399 (define_insn "stack_tls_protect_set_si"
20400 [(set (match_operand:SI 0 "memory_operand" "=m")
20401 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20402 (set (match_scratch:SI 2 "=&r") (const_int 0))
20403 (clobber (reg:CC FLAGS_REG))]
20405 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20406 [(set_attr "type" "multi")])
20408 (define_insn "stack_tls_protect_set_di"
20409 [(set (match_operand:DI 0 "memory_operand" "=m")
20410 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20411 (set (match_scratch:DI 2 "=&r") (const_int 0))
20412 (clobber (reg:CC FLAGS_REG))]
20415 /* The kernel uses a different segment register for performance reasons; a
20416 system call would not have to trash the userspace segment register,
20417 which would be expensive */
20418 if (ix86_cmodel != CM_KERNEL)
20419 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20421 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20423 [(set_attr "type" "multi")])
20425 (define_expand "stack_protect_test"
20426 [(match_operand 0 "memory_operand" "")
20427 (match_operand 1 "memory_operand" "")
20428 (match_operand 2 "" "")]
20431 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20432 ix86_compare_op0 = operands[0];
20433 ix86_compare_op1 = operands[1];
20434 ix86_compare_emitted = flags;
20436 #ifdef TARGET_THREAD_SSP_OFFSET
20438 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20439 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20441 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20442 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20445 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20447 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20449 emit_jump_insn (gen_beq (operands[2]));
20453 (define_insn "stack_protect_test_si"
20454 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20455 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20456 (match_operand:SI 2 "memory_operand" "m")]
20458 (clobber (match_scratch:SI 3 "=&r"))]
20460 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20461 [(set_attr "type" "multi")])
20463 (define_insn "stack_protect_test_di"
20464 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20465 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20466 (match_operand:DI 2 "memory_operand" "m")]
20468 (clobber (match_scratch:DI 3 "=&r"))]
20470 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20471 [(set_attr "type" "multi")])
20473 (define_insn "stack_tls_protect_test_si"
20474 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20475 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20476 (match_operand:SI 2 "const_int_operand" "i")]
20477 UNSPEC_SP_TLS_TEST))
20478 (clobber (match_scratch:SI 3 "=r"))]
20480 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20481 [(set_attr "type" "multi")])
20483 (define_insn "stack_tls_protect_test_di"
20484 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20485 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20486 (match_operand:DI 2 "const_int_operand" "i")]
20487 UNSPEC_SP_TLS_TEST))
20488 (clobber (match_scratch:DI 3 "=r"))]
20491 /* The kernel uses a different segment register for performance reasons; a
20492 system call would not have to trash the userspace segment register,
20493 which would be expensive */
20494 if (ix86_cmodel != CM_KERNEL)
20495 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20497 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20499 [(set_attr "type" "multi")])
20503 (include "sync.md")