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, 2008
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 3, 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 COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
108 ; Generic math support
110 (UNSPEC_IEEE_MIN 51) ; not commutative
111 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
136 (UNSPEC_XTRACT_FRACT 84)
137 (UNSPEC_XTRACT_EXP 85)
138 (UNSPEC_FSCALE_FRACT 86)
139 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 (UNSPEC_INSERTPS 135)
168 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_PHMINPOSUW 139)
176 (UNSPEC_PCMPESTR 144)
177 (UNSPEC_PCMPISTR 145)
180 (UNSPEC_SSE5_INTRINSIC 150)
181 (UNSPEC_SSE5_UNSIGNED_CMP 151)
182 (UNSPEC_SSE5_TRUEFALSE 152)
183 (UNSPEC_SSE5_PERMUTE 153)
184 (UNSPEC_SSE5_ASHIFT 154)
185 (UNSPEC_SSE5_LSHIFT 155)
187 (UNSPEC_CVTPH2PS 157)
188 (UNSPEC_CVTPS2PH 158)
192 [(UNSPECV_BLOCKAGE 0)
193 (UNSPECV_STACK_PROBE 1)
202 (UNSPECV_CMPXCHG_1 10)
203 (UNSPECV_CMPXCHG_2 11)
206 (UNSPECV_PROLOGUE_USE 14)
209 ;; Constants to represent pcomtrue/pcomfalse variants
219 ;; Registers by name.
235 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
238 ;; In C guard expressions, put expressions which may be compile-time
239 ;; constants first. This allows for better optimization. For
240 ;; example, write "TARGET_64BIT && reload_completed", not
241 ;; "reload_completed && TARGET_64BIT".
244 ;; Processor type. This attribute must exactly match the processor_type
245 ;; enumeration in i386.h.
246 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
247 nocona,core2,generic32,generic64,amdfam10"
248 (const (symbol_ref "ix86_tune")))
250 ;; A basic instruction type. Refinements due to arguments to be
251 ;; provided in other attributes.
254 alu,alu1,negnot,imov,imovx,lea,
255 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
256 icmp,test,ibr,setcc,icmov,
257 push,pop,call,callv,leave,
259 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
260 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
261 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
263 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
264 (const_string "other"))
266 ;; Main data type used by the insn
268 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
269 (const_string "unknown"))
271 ;; The CPU unit operations uses.
272 (define_attr "unit" "integer,i387,sse,mmx,unknown"
273 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
274 (const_string "i387")
275 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
276 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
277 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
279 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
281 (eq_attr "type" "other")
282 (const_string "unknown")]
283 (const_string "integer")))
285 ;; The (bounding maximum) length of an instruction immediate.
286 (define_attr "length_immediate" ""
287 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
290 (eq_attr "unit" "i387,sse,mmx")
292 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
294 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
295 (eq_attr "type" "imov,test")
296 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
297 (eq_attr "type" "call")
298 (if_then_else (match_operand 0 "constant_call_address_operand" "")
301 (eq_attr "type" "callv")
302 (if_then_else (match_operand 1 "constant_call_address_operand" "")
305 ;; We don't know the size before shorten_branches. Expect
306 ;; the instruction to fit for better scheduling.
307 (eq_attr "type" "ibr")
310 (symbol_ref "/* Update immediate_length and other attributes! */
311 gcc_unreachable (),1")))
313 ;; The (bounding maximum) length of an instruction address.
314 (define_attr "length_address" ""
315 (cond [(eq_attr "type" "str,other,multi,fxch")
317 (and (eq_attr "type" "call")
318 (match_operand 0 "constant_call_address_operand" ""))
320 (and (eq_attr "type" "callv")
321 (match_operand 1 "constant_call_address_operand" ""))
324 (symbol_ref "ix86_attr_length_address_default (insn)")))
326 ;; Set when length prefix is used.
327 (define_attr "prefix_data16" ""
328 (if_then_else (ior (eq_attr "mode" "HI")
329 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
333 ;; Set when string REP prefix is used.
334 (define_attr "prefix_rep" ""
335 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
339 ;; Set when 0f opcode prefix is used.
340 (define_attr "prefix_0f" ""
342 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
343 (eq_attr "unit" "sse,mmx"))
347 ;; Set when REX opcode prefix is used.
348 (define_attr "prefix_rex" ""
349 (cond [(and (eq_attr "mode" "DI")
350 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
352 (and (eq_attr "mode" "QI")
353 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
356 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
362 ;; There are also additional prefixes in SSSE3.
363 (define_attr "prefix_extra" "" (const_int 0))
365 ;; Set when modrm byte is used.
366 (define_attr "modrm" ""
367 (cond [(eq_attr "type" "str,leave")
369 (eq_attr "unit" "i387")
371 (and (eq_attr "type" "incdec")
372 (ior (match_operand:SI 1 "register_operand" "")
373 (match_operand:HI 1 "register_operand" "")))
375 (and (eq_attr "type" "push")
376 (not (match_operand 1 "memory_operand" "")))
378 (and (eq_attr "type" "pop")
379 (not (match_operand 0 "memory_operand" "")))
381 (and (eq_attr "type" "imov")
382 (ior (and (match_operand 0 "register_operand" "")
383 (match_operand 1 "immediate_operand" ""))
384 (ior (and (match_operand 0 "ax_reg_operand" "")
385 (match_operand 1 "memory_displacement_only_operand" ""))
386 (and (match_operand 0 "memory_displacement_only_operand" "")
387 (match_operand 1 "ax_reg_operand" "")))))
389 (and (eq_attr "type" "call")
390 (match_operand 0 "constant_call_address_operand" ""))
392 (and (eq_attr "type" "callv")
393 (match_operand 1 "constant_call_address_operand" ""))
398 ;; The (bounding maximum) length of an instruction in bytes.
399 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
400 ;; Later we may want to split them and compute proper length as for
402 (define_attr "length" ""
403 (cond [(eq_attr "type" "other,multi,fistp,frndint")
405 (eq_attr "type" "fcmp")
407 (eq_attr "unit" "i387")
409 (plus (attr "prefix_data16")
410 (attr "length_address")))]
411 (plus (plus (attr "modrm")
412 (plus (attr "prefix_0f")
413 (plus (attr "prefix_rex")
414 (plus (attr "prefix_extra")
416 (plus (attr "prefix_rep")
417 (plus (attr "prefix_data16")
418 (plus (attr "length_immediate")
419 (attr "length_address")))))))
421 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
422 ;; `store' if there is a simple memory reference therein, or `unknown'
423 ;; if the instruction is complex.
425 (define_attr "memory" "none,load,store,both,unknown"
426 (cond [(eq_attr "type" "other,multi,str")
427 (const_string "unknown")
428 (eq_attr "type" "lea,fcmov,fpspc")
429 (const_string "none")
430 (eq_attr "type" "fistp,leave")
431 (const_string "both")
432 (eq_attr "type" "frndint")
433 (const_string "load")
434 (eq_attr "type" "push")
435 (if_then_else (match_operand 1 "memory_operand" "")
436 (const_string "both")
437 (const_string "store"))
438 (eq_attr "type" "pop")
439 (if_then_else (match_operand 0 "memory_operand" "")
440 (const_string "both")
441 (const_string "load"))
442 (eq_attr "type" "setcc")
443 (if_then_else (match_operand 0 "memory_operand" "")
444 (const_string "store")
445 (const_string "none"))
446 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
447 (if_then_else (ior (match_operand 0 "memory_operand" "")
448 (match_operand 1 "memory_operand" ""))
449 (const_string "load")
450 (const_string "none"))
451 (eq_attr "type" "ibr")
452 (if_then_else (match_operand 0 "memory_operand" "")
453 (const_string "load")
454 (const_string "none"))
455 (eq_attr "type" "call")
456 (if_then_else (match_operand 0 "constant_call_address_operand" "")
457 (const_string "none")
458 (const_string "load"))
459 (eq_attr "type" "callv")
460 (if_then_else (match_operand 1 "constant_call_address_operand" "")
461 (const_string "none")
462 (const_string "load"))
463 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
464 (match_operand 1 "memory_operand" ""))
465 (const_string "both")
466 (and (match_operand 0 "memory_operand" "")
467 (match_operand 1 "memory_operand" ""))
468 (const_string "both")
469 (match_operand 0 "memory_operand" "")
470 (const_string "store")
471 (match_operand 1 "memory_operand" "")
472 (const_string "load")
474 "!alu1,negnot,ishift1,
475 imov,imovx,icmp,test,bitmanip,
477 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
478 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
479 (match_operand 2 "memory_operand" ""))
480 (const_string "load")
481 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
482 (match_operand 3 "memory_operand" ""))
483 (const_string "load")
485 (const_string "none")))
487 ;; Indicates if an instruction has both an immediate and a displacement.
489 (define_attr "imm_disp" "false,true,unknown"
490 (cond [(eq_attr "type" "other,multi")
491 (const_string "unknown")
492 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
493 (and (match_operand 0 "memory_displacement_operand" "")
494 (match_operand 1 "immediate_operand" "")))
495 (const_string "true")
496 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
497 (and (match_operand 0 "memory_displacement_operand" "")
498 (match_operand 2 "immediate_operand" "")))
499 (const_string "true")
501 (const_string "false")))
503 ;; Indicates if an FP operation has an integer source.
505 (define_attr "fp_int_src" "false,true"
506 (const_string "false"))
508 ;; Defines rounding mode of an FP operation.
510 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
511 (const_string "any"))
513 ;; Describe a user's asm statement.
514 (define_asm_attributes
515 [(set_attr "length" "128")
516 (set_attr "type" "multi")])
518 ;; All integer comparison codes.
519 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
521 ;; All floating-point comparison codes.
522 (define_code_iterator fp_cond [unordered ordered
523 uneq unge ungt unle unlt ltgt ])
525 (define_code_iterator plusminus [plus minus])
527 ;; Base name for define_insn and insn mnemonic.
528 (define_code_attr addsub [(plus "add") (minus "sub")])
530 ;; Mark commutative operators as such in constraints.
531 (define_code_attr comm [(plus "%") (minus "")])
533 ;; All single word integer modes.
534 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
536 ;; Instruction suffix for integer modes.
537 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
539 ;; Register class for integer modes.
540 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
542 ;; Immediate operand constraint for integer modes.
543 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
545 ;; General operand predicate for integer modes.
546 (define_mode_attr general_operand
547 [(QI "general_operand")
548 (HI "general_operand")
549 (SI "general_operand")
550 (DI "x86_64_general_operand")])
552 ;; SSE and x87 SFmode and DFmode floating point modes
553 (define_mode_iterator MODEF [SF DF])
555 ;; All x87 floating point modes
556 (define_mode_iterator X87MODEF [SF DF XF])
558 ;; All integer modes handled by x87 fisttp operator.
559 (define_mode_iterator X87MODEI [HI SI DI])
561 ;; All integer modes handled by integer x87 operators.
562 (define_mode_iterator X87MODEI12 [HI SI])
564 ;; All integer modes handled by SSE cvtts?2si* operators.
565 (define_mode_iterator SSEMODEI24 [SI DI])
567 ;; SSE asm suffix for floating point modes
568 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
570 ;; SSE vector mode corresponding to a scalar mode
571 (define_mode_attr ssevecmode
572 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
574 ;; Scheduling descriptions
576 (include "pentium.md")
579 (include "athlon.md")
583 ;; Operand and operator predicates and constraints
585 (include "predicates.md")
586 (include "constraints.md")
589 ;; Compare instructions.
591 ;; All compare insns have expanders that save the operands away without
592 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
593 ;; after the cmp) will actually emit the cmpM.
595 (define_expand "cmpti"
596 [(set (reg:CC FLAGS_REG)
597 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
598 (match_operand:TI 1 "x86_64_general_operand" "")))]
601 if (MEM_P (operands[0]) && MEM_P (operands[1]))
602 operands[0] = force_reg (TImode, operands[0]);
603 ix86_compare_op0 = operands[0];
604 ix86_compare_op1 = operands[1];
608 (define_expand "cmpdi"
609 [(set (reg:CC FLAGS_REG)
610 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
611 (match_operand:DI 1 "x86_64_general_operand" "")))]
614 if (MEM_P (operands[0]) && MEM_P (operands[1]))
615 operands[0] = force_reg (DImode, operands[0]);
616 ix86_compare_op0 = operands[0];
617 ix86_compare_op1 = operands[1];
621 (define_expand "cmpsi"
622 [(set (reg:CC FLAGS_REG)
623 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
624 (match_operand:SI 1 "general_operand" "")))]
627 if (MEM_P (operands[0]) && MEM_P (operands[1]))
628 operands[0] = force_reg (SImode, operands[0]);
629 ix86_compare_op0 = operands[0];
630 ix86_compare_op1 = operands[1];
634 (define_expand "cmphi"
635 [(set (reg:CC FLAGS_REG)
636 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
637 (match_operand:HI 1 "general_operand" "")))]
640 if (MEM_P (operands[0]) && MEM_P (operands[1]))
641 operands[0] = force_reg (HImode, operands[0]);
642 ix86_compare_op0 = operands[0];
643 ix86_compare_op1 = operands[1];
647 (define_expand "cmpqi"
648 [(set (reg:CC FLAGS_REG)
649 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
650 (match_operand:QI 1 "general_operand" "")))]
653 if (MEM_P (operands[0]) && MEM_P (operands[1]))
654 operands[0] = force_reg (QImode, operands[0]);
655 ix86_compare_op0 = operands[0];
656 ix86_compare_op1 = operands[1];
660 (define_insn "cmpdi_ccno_1_rex64"
661 [(set (reg FLAGS_REG)
662 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
663 (match_operand:DI 1 "const0_operand" "n,n")))]
664 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
667 cmp{q}\t{%1, %0|%0, %1}"
668 [(set_attr "type" "test,icmp")
669 (set_attr "length_immediate" "0,1")
670 (set_attr "mode" "DI")])
672 (define_insn "*cmpdi_minus_1_rex64"
673 [(set (reg FLAGS_REG)
674 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
675 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
677 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
678 "cmp{q}\t{%1, %0|%0, %1}"
679 [(set_attr "type" "icmp")
680 (set_attr "mode" "DI")])
682 (define_expand "cmpdi_1_rex64"
683 [(set (reg:CC FLAGS_REG)
684 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
685 (match_operand:DI 1 "general_operand" "")))]
689 (define_insn "cmpdi_1_insn_rex64"
690 [(set (reg FLAGS_REG)
691 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
692 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
693 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
694 "cmp{q}\t{%1, %0|%0, %1}"
695 [(set_attr "type" "icmp")
696 (set_attr "mode" "DI")])
699 (define_insn "*cmpsi_ccno_1"
700 [(set (reg FLAGS_REG)
701 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
702 (match_operand:SI 1 "const0_operand" "n,n")))]
703 "ix86_match_ccmode (insn, CCNOmode)"
706 cmp{l}\t{%1, %0|%0, %1}"
707 [(set_attr "type" "test,icmp")
708 (set_attr "length_immediate" "0,1")
709 (set_attr "mode" "SI")])
711 (define_insn "*cmpsi_minus_1"
712 [(set (reg FLAGS_REG)
713 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
714 (match_operand:SI 1 "general_operand" "ri,mr"))
716 "ix86_match_ccmode (insn, CCGOCmode)"
717 "cmp{l}\t{%1, %0|%0, %1}"
718 [(set_attr "type" "icmp")
719 (set_attr "mode" "SI")])
721 (define_expand "cmpsi_1"
722 [(set (reg:CC FLAGS_REG)
723 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
724 (match_operand:SI 1 "general_operand" "")))]
728 (define_insn "*cmpsi_1_insn"
729 [(set (reg FLAGS_REG)
730 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
731 (match_operand:SI 1 "general_operand" "ri,mr")))]
732 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
733 && ix86_match_ccmode (insn, CCmode)"
734 "cmp{l}\t{%1, %0|%0, %1}"
735 [(set_attr "type" "icmp")
736 (set_attr "mode" "SI")])
738 (define_insn "*cmphi_ccno_1"
739 [(set (reg FLAGS_REG)
740 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
741 (match_operand:HI 1 "const0_operand" "n,n")))]
742 "ix86_match_ccmode (insn, CCNOmode)"
745 cmp{w}\t{%1, %0|%0, %1}"
746 [(set_attr "type" "test,icmp")
747 (set_attr "length_immediate" "0,1")
748 (set_attr "mode" "HI")])
750 (define_insn "*cmphi_minus_1"
751 [(set (reg FLAGS_REG)
752 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
753 (match_operand:HI 1 "general_operand" "ri,mr"))
755 "ix86_match_ccmode (insn, CCGOCmode)"
756 "cmp{w}\t{%1, %0|%0, %1}"
757 [(set_attr "type" "icmp")
758 (set_attr "mode" "HI")])
760 (define_insn "*cmphi_1"
761 [(set (reg FLAGS_REG)
762 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
763 (match_operand:HI 1 "general_operand" "ri,mr")))]
764 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
765 && ix86_match_ccmode (insn, CCmode)"
766 "cmp{w}\t{%1, %0|%0, %1}"
767 [(set_attr "type" "icmp")
768 (set_attr "mode" "HI")])
770 (define_insn "*cmpqi_ccno_1"
771 [(set (reg FLAGS_REG)
772 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
773 (match_operand:QI 1 "const0_operand" "n,n")))]
774 "ix86_match_ccmode (insn, CCNOmode)"
777 cmp{b}\t{$0, %0|%0, 0}"
778 [(set_attr "type" "test,icmp")
779 (set_attr "length_immediate" "0,1")
780 (set_attr "mode" "QI")])
782 (define_insn "*cmpqi_1"
783 [(set (reg FLAGS_REG)
784 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
785 (match_operand:QI 1 "general_operand" "qi,mq")))]
786 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
787 && ix86_match_ccmode (insn, CCmode)"
788 "cmp{b}\t{%1, %0|%0, %1}"
789 [(set_attr "type" "icmp")
790 (set_attr "mode" "QI")])
792 (define_insn "*cmpqi_minus_1"
793 [(set (reg FLAGS_REG)
794 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
795 (match_operand:QI 1 "general_operand" "qi,mq"))
797 "ix86_match_ccmode (insn, CCGOCmode)"
798 "cmp{b}\t{%1, %0|%0, %1}"
799 [(set_attr "type" "icmp")
800 (set_attr "mode" "QI")])
802 (define_insn "*cmpqi_ext_1"
803 [(set (reg FLAGS_REG)
805 (match_operand:QI 0 "general_operand" "Qm")
808 (match_operand 1 "ext_register_operand" "Q")
811 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
812 "cmp{b}\t{%h1, %0|%0, %h1}"
813 [(set_attr "type" "icmp")
814 (set_attr "mode" "QI")])
816 (define_insn "*cmpqi_ext_1_rex64"
817 [(set (reg FLAGS_REG)
819 (match_operand:QI 0 "register_operand" "Q")
822 (match_operand 1 "ext_register_operand" "Q")
825 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
826 "cmp{b}\t{%h1, %0|%0, %h1}"
827 [(set_attr "type" "icmp")
828 (set_attr "mode" "QI")])
830 (define_insn "*cmpqi_ext_2"
831 [(set (reg FLAGS_REG)
835 (match_operand 0 "ext_register_operand" "Q")
838 (match_operand:QI 1 "const0_operand" "n")))]
839 "ix86_match_ccmode (insn, CCNOmode)"
841 [(set_attr "type" "test")
842 (set_attr "length_immediate" "0")
843 (set_attr "mode" "QI")])
845 (define_expand "cmpqi_ext_3"
846 [(set (reg:CC FLAGS_REG)
850 (match_operand 0 "ext_register_operand" "")
853 (match_operand:QI 1 "general_operand" "")))]
857 (define_insn "cmpqi_ext_3_insn"
858 [(set (reg FLAGS_REG)
862 (match_operand 0 "ext_register_operand" "Q")
865 (match_operand:QI 1 "general_operand" "Qmn")))]
866 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
867 "cmp{b}\t{%1, %h0|%h0, %1}"
868 [(set_attr "type" "icmp")
869 (set_attr "mode" "QI")])
871 (define_insn "cmpqi_ext_3_insn_rex64"
872 [(set (reg FLAGS_REG)
876 (match_operand 0 "ext_register_operand" "Q")
879 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
880 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
881 "cmp{b}\t{%1, %h0|%h0, %1}"
882 [(set_attr "type" "icmp")
883 (set_attr "mode" "QI")])
885 (define_insn "*cmpqi_ext_4"
886 [(set (reg FLAGS_REG)
890 (match_operand 0 "ext_register_operand" "Q")
895 (match_operand 1 "ext_register_operand" "Q")
898 "ix86_match_ccmode (insn, CCmode)"
899 "cmp{b}\t{%h1, %h0|%h0, %h1}"
900 [(set_attr "type" "icmp")
901 (set_attr "mode" "QI")])
903 ;; These implement float point compares.
904 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
905 ;; which would allow mix and match FP modes on the compares. Which is what
906 ;; the old patterns did, but with many more of them.
908 (define_expand "cmpxf"
909 [(set (reg:CC FLAGS_REG)
910 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
911 (match_operand:XF 1 "nonmemory_operand" "")))]
914 ix86_compare_op0 = operands[0];
915 ix86_compare_op1 = operands[1];
919 (define_expand "cmp<mode>"
920 [(set (reg:CC FLAGS_REG)
921 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
922 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
923 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
925 ix86_compare_op0 = operands[0];
926 ix86_compare_op1 = operands[1];
930 ;; FP compares, step 1:
931 ;; Set the FP condition codes.
933 ;; CCFPmode compare with exceptions
934 ;; CCFPUmode compare with no exceptions
936 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
937 ;; used to manage the reg stack popping would not be preserved.
939 (define_insn "*cmpfp_0"
940 [(set (match_operand:HI 0 "register_operand" "=a")
943 (match_operand 1 "register_operand" "f")
944 (match_operand 2 "const0_operand" "X"))]
946 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
947 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
948 "* return output_fp_compare (insn, operands, 0, 0);"
949 [(set_attr "type" "multi")
950 (set_attr "unit" "i387")
952 (cond [(match_operand:SF 1 "" "")
954 (match_operand:DF 1 "" "")
957 (const_string "XF")))])
959 (define_insn_and_split "*cmpfp_0_cc"
960 [(set (reg:CCFP FLAGS_REG)
962 (match_operand 1 "register_operand" "f")
963 (match_operand 2 "const0_operand" "X")))
964 (clobber (match_operand:HI 0 "register_operand" "=a"))]
965 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
966 && TARGET_SAHF && !TARGET_CMOVE
967 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
969 "&& reload_completed"
972 [(compare:CCFP (match_dup 1)(match_dup 2))]
974 (set (reg:CC FLAGS_REG)
975 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
977 [(set_attr "type" "multi")
978 (set_attr "unit" "i387")
980 (cond [(match_operand:SF 1 "" "")
982 (match_operand:DF 1 "" "")
985 (const_string "XF")))])
987 (define_insn "*cmpfp_xf"
988 [(set (match_operand:HI 0 "register_operand" "=a")
991 (match_operand:XF 1 "register_operand" "f")
992 (match_operand:XF 2 "register_operand" "f"))]
995 "* return output_fp_compare (insn, operands, 0, 0);"
996 [(set_attr "type" "multi")
997 (set_attr "unit" "i387")
998 (set_attr "mode" "XF")])
1000 (define_insn_and_split "*cmpfp_xf_cc"
1001 [(set (reg:CCFP FLAGS_REG)
1003 (match_operand:XF 1 "register_operand" "f")
1004 (match_operand:XF 2 "register_operand" "f")))
1005 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1007 && TARGET_SAHF && !TARGET_CMOVE"
1009 "&& reload_completed"
1012 [(compare:CCFP (match_dup 1)(match_dup 2))]
1014 (set (reg:CC FLAGS_REG)
1015 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1017 [(set_attr "type" "multi")
1018 (set_attr "unit" "i387")
1019 (set_attr "mode" "XF")])
1021 (define_insn "*cmpfp_<mode>"
1022 [(set (match_operand:HI 0 "register_operand" "=a")
1025 (match_operand:MODEF 1 "register_operand" "f")
1026 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1029 "* return output_fp_compare (insn, operands, 0, 0);"
1030 [(set_attr "type" "multi")
1031 (set_attr "unit" "i387")
1032 (set_attr "mode" "<MODE>")])
1034 (define_insn_and_split "*cmpfp_<mode>_cc"
1035 [(set (reg:CCFP FLAGS_REG)
1037 (match_operand:MODEF 1 "register_operand" "f")
1038 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1039 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1041 && TARGET_SAHF && !TARGET_CMOVE"
1043 "&& reload_completed"
1046 [(compare:CCFP (match_dup 1)(match_dup 2))]
1048 (set (reg:CC FLAGS_REG)
1049 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1051 [(set_attr "type" "multi")
1052 (set_attr "unit" "i387")
1053 (set_attr "mode" "<MODE>")])
1055 (define_insn "*cmpfp_u"
1056 [(set (match_operand:HI 0 "register_operand" "=a")
1059 (match_operand 1 "register_operand" "f")
1060 (match_operand 2 "register_operand" "f"))]
1062 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1063 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1064 "* return output_fp_compare (insn, operands, 0, 1);"
1065 [(set_attr "type" "multi")
1066 (set_attr "unit" "i387")
1068 (cond [(match_operand:SF 1 "" "")
1070 (match_operand:DF 1 "" "")
1073 (const_string "XF")))])
1075 (define_insn_and_split "*cmpfp_u_cc"
1076 [(set (reg:CCFPU FLAGS_REG)
1078 (match_operand 1 "register_operand" "f")
1079 (match_operand 2 "register_operand" "f")))
1080 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1081 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1082 && TARGET_SAHF && !TARGET_CMOVE
1083 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1085 "&& reload_completed"
1088 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1090 (set (reg:CC FLAGS_REG)
1091 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1093 [(set_attr "type" "multi")
1094 (set_attr "unit" "i387")
1096 (cond [(match_operand:SF 1 "" "")
1098 (match_operand:DF 1 "" "")
1101 (const_string "XF")))])
1103 (define_insn "*cmpfp_<mode>"
1104 [(set (match_operand:HI 0 "register_operand" "=a")
1107 (match_operand 1 "register_operand" "f")
1108 (match_operator 3 "float_operator"
1109 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1111 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1112 && TARGET_USE_<MODE>MODE_FIOP
1113 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1114 "* return output_fp_compare (insn, operands, 0, 0);"
1115 [(set_attr "type" "multi")
1116 (set_attr "unit" "i387")
1117 (set_attr "fp_int_src" "true")
1118 (set_attr "mode" "<MODE>")])
1120 (define_insn_and_split "*cmpfp_<mode>_cc"
1121 [(set (reg:CCFP FLAGS_REG)
1123 (match_operand 1 "register_operand" "f")
1124 (match_operator 3 "float_operator"
1125 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1126 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1127 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1128 && TARGET_SAHF && !TARGET_CMOVE
1129 && TARGET_USE_<MODE>MODE_FIOP
1130 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1132 "&& reload_completed"
1137 (match_op_dup 3 [(match_dup 2)]))]
1139 (set (reg:CC FLAGS_REG)
1140 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1142 [(set_attr "type" "multi")
1143 (set_attr "unit" "i387")
1144 (set_attr "fp_int_src" "true")
1145 (set_attr "mode" "<MODE>")])
1147 ;; FP compares, step 2
1148 ;; Move the fpsw to ax.
1150 (define_insn "x86_fnstsw_1"
1151 [(set (match_operand:HI 0 "register_operand" "=a")
1152 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1155 [(set_attr "length" "2")
1156 (set_attr "mode" "SI")
1157 (set_attr "unit" "i387")])
1159 ;; FP compares, step 3
1160 ;; Get ax into flags, general case.
1162 (define_insn "x86_sahf_1"
1163 [(set (reg:CC FLAGS_REG)
1164 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1168 #ifdef HAVE_AS_IX86_SAHF
1171 return ".byte\t0x9e";
1174 [(set_attr "length" "1")
1175 (set_attr "athlon_decode" "vector")
1176 (set_attr "amdfam10_decode" "direct")
1177 (set_attr "mode" "SI")])
1179 ;; Pentium Pro can do steps 1 through 3 in one go.
1180 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1181 (define_insn "*cmpfp_i_mixed"
1182 [(set (reg:CCFP FLAGS_REG)
1183 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1184 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1185 "TARGET_MIX_SSE_I387
1186 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1187 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1188 "* return output_fp_compare (insn, operands, 1, 0);"
1189 [(set_attr "type" "fcmp,ssecomi")
1191 (if_then_else (match_operand:SF 1 "" "")
1193 (const_string "DF")))
1194 (set_attr "athlon_decode" "vector")
1195 (set_attr "amdfam10_decode" "direct")])
1197 (define_insn "*cmpfp_i_sse"
1198 [(set (reg:CCFP FLAGS_REG)
1199 (compare:CCFP (match_operand 0 "register_operand" "x")
1200 (match_operand 1 "nonimmediate_operand" "xm")))]
1202 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1203 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1204 "* return output_fp_compare (insn, operands, 1, 0);"
1205 [(set_attr "type" "ssecomi")
1207 (if_then_else (match_operand:SF 1 "" "")
1209 (const_string "DF")))
1210 (set_attr "athlon_decode" "vector")
1211 (set_attr "amdfam10_decode" "direct")])
1213 (define_insn "*cmpfp_i_i387"
1214 [(set (reg:CCFP FLAGS_REG)
1215 (compare:CCFP (match_operand 0 "register_operand" "f")
1216 (match_operand 1 "register_operand" "f")))]
1217 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1219 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1220 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1221 "* return output_fp_compare (insn, operands, 1, 0);"
1222 [(set_attr "type" "fcmp")
1224 (cond [(match_operand:SF 1 "" "")
1226 (match_operand:DF 1 "" "")
1229 (const_string "XF")))
1230 (set_attr "athlon_decode" "vector")
1231 (set_attr "amdfam10_decode" "direct")])
1233 (define_insn "*cmpfp_iu_mixed"
1234 [(set (reg:CCFPU FLAGS_REG)
1235 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1236 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1237 "TARGET_MIX_SSE_I387
1238 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1239 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1240 "* return output_fp_compare (insn, operands, 1, 1);"
1241 [(set_attr "type" "fcmp,ssecomi")
1243 (if_then_else (match_operand:SF 1 "" "")
1245 (const_string "DF")))
1246 (set_attr "athlon_decode" "vector")
1247 (set_attr "amdfam10_decode" "direct")])
1249 (define_insn "*cmpfp_iu_sse"
1250 [(set (reg:CCFPU FLAGS_REG)
1251 (compare:CCFPU (match_operand 0 "register_operand" "x")
1252 (match_operand 1 "nonimmediate_operand" "xm")))]
1254 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1255 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1256 "* return output_fp_compare (insn, operands, 1, 1);"
1257 [(set_attr "type" "ssecomi")
1259 (if_then_else (match_operand:SF 1 "" "")
1261 (const_string "DF")))
1262 (set_attr "athlon_decode" "vector")
1263 (set_attr "amdfam10_decode" "direct")])
1265 (define_insn "*cmpfp_iu_387"
1266 [(set (reg:CCFPU FLAGS_REG)
1267 (compare:CCFPU (match_operand 0 "register_operand" "f")
1268 (match_operand 1 "register_operand" "f")))]
1269 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1271 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1272 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1273 "* return output_fp_compare (insn, operands, 1, 1);"
1274 [(set_attr "type" "fcmp")
1276 (cond [(match_operand:SF 1 "" "")
1278 (match_operand:DF 1 "" "")
1281 (const_string "XF")))
1282 (set_attr "athlon_decode" "vector")
1283 (set_attr "amdfam10_decode" "direct")])
1285 ;; Move instructions.
1287 ;; General case of fullword move.
1289 (define_expand "movsi"
1290 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1291 (match_operand:SI 1 "general_operand" ""))]
1293 "ix86_expand_move (SImode, operands); DONE;")
1295 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1298 ;; %%% We don't use a post-inc memory reference because x86 is not a
1299 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1300 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1301 ;; targets without our curiosities, and it is just as easy to represent
1302 ;; this differently.
1304 (define_insn "*pushsi2"
1305 [(set (match_operand:SI 0 "push_operand" "=<")
1306 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1309 [(set_attr "type" "push")
1310 (set_attr "mode" "SI")])
1312 ;; For 64BIT abi we always round up to 8 bytes.
1313 (define_insn "*pushsi2_rex64"
1314 [(set (match_operand:SI 0 "push_operand" "=X")
1315 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1318 [(set_attr "type" "push")
1319 (set_attr "mode" "SI")])
1321 (define_insn "*pushsi2_prologue"
1322 [(set (match_operand:SI 0 "push_operand" "=<")
1323 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1324 (clobber (mem:BLK (scratch)))]
1327 [(set_attr "type" "push")
1328 (set_attr "mode" "SI")])
1330 (define_insn "*popsi1_epilogue"
1331 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1332 (mem:SI (reg:SI SP_REG)))
1333 (set (reg:SI SP_REG)
1334 (plus:SI (reg:SI SP_REG) (const_int 4)))
1335 (clobber (mem:BLK (scratch)))]
1338 [(set_attr "type" "pop")
1339 (set_attr "mode" "SI")])
1341 (define_insn "popsi1"
1342 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1343 (mem:SI (reg:SI SP_REG)))
1344 (set (reg:SI SP_REG)
1345 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1348 [(set_attr "type" "pop")
1349 (set_attr "mode" "SI")])
1351 (define_insn "*movsi_xor"
1352 [(set (match_operand:SI 0 "register_operand" "=r")
1353 (match_operand:SI 1 "const0_operand" "i"))
1354 (clobber (reg:CC FLAGS_REG))]
1355 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1357 [(set_attr "type" "alu1")
1358 (set_attr "mode" "SI")
1359 (set_attr "length_immediate" "0")])
1361 (define_insn "*movsi_or"
1362 [(set (match_operand:SI 0 "register_operand" "=r")
1363 (match_operand:SI 1 "immediate_operand" "i"))
1364 (clobber (reg:CC FLAGS_REG))]
1366 && operands[1] == constm1_rtx
1367 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1369 operands[1] = constm1_rtx;
1370 return "or{l}\t{%1, %0|%0, %1}";
1372 [(set_attr "type" "alu1")
1373 (set_attr "mode" "SI")
1374 (set_attr "length_immediate" "1")])
1376 (define_insn "*movsi_1"
1377 [(set (match_operand:SI 0 "nonimmediate_operand"
1378 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1379 (match_operand:SI 1 "general_operand"
1380 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1381 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1383 switch (get_attr_type (insn))
1386 if (get_attr_mode (insn) == MODE_TI)
1387 return "pxor\t%0, %0";
1388 return "xorps\t%0, %0";
1391 switch (get_attr_mode (insn))
1394 return "movdqa\t{%1, %0|%0, %1}";
1396 return "movaps\t{%1, %0|%0, %1}";
1398 return "movd\t{%1, %0|%0, %1}";
1400 return "movss\t{%1, %0|%0, %1}";
1406 return "pxor\t%0, %0";
1409 if (get_attr_mode (insn) == MODE_DI)
1410 return "movq\t{%1, %0|%0, %1}";
1411 return "movd\t{%1, %0|%0, %1}";
1414 return "lea{l}\t{%1, %0|%0, %1}";
1417 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1418 return "mov{l}\t{%1, %0|%0, %1}";
1422 (cond [(eq_attr "alternative" "2")
1423 (const_string "mmxadd")
1424 (eq_attr "alternative" "3,4,5")
1425 (const_string "mmxmov")
1426 (eq_attr "alternative" "6")
1427 (const_string "sselog1")
1428 (eq_attr "alternative" "7,8,9,10,11")
1429 (const_string "ssemov")
1430 (match_operand:DI 1 "pic_32bit_operand" "")
1431 (const_string "lea")
1433 (const_string "imov")))
1435 (cond [(eq_attr "alternative" "2,3")
1437 (eq_attr "alternative" "6,7")
1439 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1440 (const_string "V4SF")
1441 (const_string "TI"))
1442 (and (eq_attr "alternative" "8,9,10,11")
1443 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1446 (const_string "SI")))])
1448 ;; Stores and loads of ax to arbitrary constant address.
1449 ;; We fake an second form of instruction to force reload to load address
1450 ;; into register when rax is not available
1451 (define_insn "*movabssi_1_rex64"
1452 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1453 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1454 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1456 movabs{l}\t{%1, %P0|%P0, %1}
1457 mov{l}\t{%1, %a0|%a0, %1}"
1458 [(set_attr "type" "imov")
1459 (set_attr "modrm" "0,*")
1460 (set_attr "length_address" "8,0")
1461 (set_attr "length_immediate" "0,*")
1462 (set_attr "memory" "store")
1463 (set_attr "mode" "SI")])
1465 (define_insn "*movabssi_2_rex64"
1466 [(set (match_operand:SI 0 "register_operand" "=a,r")
1467 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1468 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1470 movabs{l}\t{%P1, %0|%0, %P1}
1471 mov{l}\t{%a1, %0|%0, %a1}"
1472 [(set_attr "type" "imov")
1473 (set_attr "modrm" "0,*")
1474 (set_attr "length_address" "8,0")
1475 (set_attr "length_immediate" "0")
1476 (set_attr "memory" "load")
1477 (set_attr "mode" "SI")])
1479 (define_insn "*swapsi"
1480 [(set (match_operand:SI 0 "register_operand" "+r")
1481 (match_operand:SI 1 "register_operand" "+r"))
1486 [(set_attr "type" "imov")
1487 (set_attr "mode" "SI")
1488 (set_attr "pent_pair" "np")
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "double")])
1492 (define_expand "movhi"
1493 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1494 (match_operand:HI 1 "general_operand" ""))]
1496 "ix86_expand_move (HImode, operands); DONE;")
1498 (define_insn "*pushhi2"
1499 [(set (match_operand:HI 0 "push_operand" "=X")
1500 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1503 [(set_attr "type" "push")
1504 (set_attr "mode" "SI")])
1506 ;; For 64BIT abi we always round up to 8 bytes.
1507 (define_insn "*pushhi2_rex64"
1508 [(set (match_operand:HI 0 "push_operand" "=X")
1509 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1512 [(set_attr "type" "push")
1513 (set_attr "mode" "DI")])
1515 (define_insn "*movhi_1"
1516 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1517 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1518 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1520 switch (get_attr_type (insn))
1523 /* movzwl is faster than movw on p2 due to partial word stalls,
1524 though not as fast as an aligned movl. */
1525 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1527 if (get_attr_mode (insn) == MODE_SI)
1528 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1530 return "mov{w}\t{%1, %0|%0, %1}";
1534 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1535 (const_string "imov")
1536 (and (eq_attr "alternative" "0")
1537 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1539 (eq (symbol_ref "TARGET_HIMODE_MATH")
1541 (const_string "imov")
1542 (and (eq_attr "alternative" "1,2")
1543 (match_operand:HI 1 "aligned_operand" ""))
1544 (const_string "imov")
1545 (and (ne (symbol_ref "TARGET_MOVX")
1547 (eq_attr "alternative" "0,2"))
1548 (const_string "imovx")
1550 (const_string "imov")))
1552 (cond [(eq_attr "type" "imovx")
1554 (and (eq_attr "alternative" "1,2")
1555 (match_operand:HI 1 "aligned_operand" ""))
1557 (and (eq_attr "alternative" "0")
1558 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560 (eq (symbol_ref "TARGET_HIMODE_MATH")
1564 (const_string "HI")))])
1566 ;; Stores and loads of ax to arbitrary constant address.
1567 ;; We fake an second form of instruction to force reload to load address
1568 ;; into register when rax is not available
1569 (define_insn "*movabshi_1_rex64"
1570 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1571 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1572 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1574 movabs{w}\t{%1, %P0|%P0, %1}
1575 mov{w}\t{%1, %a0|%a0, %1}"
1576 [(set_attr "type" "imov")
1577 (set_attr "modrm" "0,*")
1578 (set_attr "length_address" "8,0")
1579 (set_attr "length_immediate" "0,*")
1580 (set_attr "memory" "store")
1581 (set_attr "mode" "HI")])
1583 (define_insn "*movabshi_2_rex64"
1584 [(set (match_operand:HI 0 "register_operand" "=a,r")
1585 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1586 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1588 movabs{w}\t{%P1, %0|%0, %P1}
1589 mov{w}\t{%a1, %0|%0, %a1}"
1590 [(set_attr "type" "imov")
1591 (set_attr "modrm" "0,*")
1592 (set_attr "length_address" "8,0")
1593 (set_attr "length_immediate" "0")
1594 (set_attr "memory" "load")
1595 (set_attr "mode" "HI")])
1597 (define_insn "*swaphi_1"
1598 [(set (match_operand:HI 0 "register_operand" "+r")
1599 (match_operand:HI 1 "register_operand" "+r"))
1602 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1604 [(set_attr "type" "imov")
1605 (set_attr "mode" "SI")
1606 (set_attr "pent_pair" "np")
1607 (set_attr "athlon_decode" "vector")
1608 (set_attr "amdfam10_decode" "double")])
1610 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1611 (define_insn "*swaphi_2"
1612 [(set (match_operand:HI 0 "register_operand" "+r")
1613 (match_operand:HI 1 "register_operand" "+r"))
1616 "TARGET_PARTIAL_REG_STALL"
1618 [(set_attr "type" "imov")
1619 (set_attr "mode" "HI")
1620 (set_attr "pent_pair" "np")
1621 (set_attr "athlon_decode" "vector")])
1623 (define_expand "movstricthi"
1624 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1625 (match_operand:HI 1 "general_operand" ""))]
1626 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1628 /* Don't generate memory->memory moves, go through a register */
1629 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1630 operands[1] = force_reg (HImode, operands[1]);
1633 (define_insn "*movstricthi_1"
1634 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1635 (match_operand:HI 1 "general_operand" "rn,m"))]
1636 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1637 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1638 "mov{w}\t{%1, %0|%0, %1}"
1639 [(set_attr "type" "imov")
1640 (set_attr "mode" "HI")])
1642 (define_insn "*movstricthi_xor"
1643 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1644 (match_operand:HI 1 "const0_operand" "i"))
1645 (clobber (reg:CC FLAGS_REG))]
1647 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1649 [(set_attr "type" "alu1")
1650 (set_attr "mode" "HI")
1651 (set_attr "length_immediate" "0")])
1653 (define_expand "movqi"
1654 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1655 (match_operand:QI 1 "general_operand" ""))]
1657 "ix86_expand_move (QImode, operands); DONE;")
1659 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1660 ;; "push a byte". But actually we use pushl, which has the effect
1661 ;; of rounding the amount pushed up to a word.
1663 (define_insn "*pushqi2"
1664 [(set (match_operand:QI 0 "push_operand" "=X")
1665 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1668 [(set_attr "type" "push")
1669 (set_attr "mode" "SI")])
1671 ;; For 64BIT abi we always round up to 8 bytes.
1672 (define_insn "*pushqi2_rex64"
1673 [(set (match_operand:QI 0 "push_operand" "=X")
1674 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1677 [(set_attr "type" "push")
1678 (set_attr "mode" "DI")])
1680 ;; Situation is quite tricky about when to choose full sized (SImode) move
1681 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1682 ;; partial register dependency machines (such as AMD Athlon), where QImode
1683 ;; moves issue extra dependency and for partial register stalls machines
1684 ;; that don't use QImode patterns (and QImode move cause stall on the next
1687 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1688 ;; register stall machines with, where we use QImode instructions, since
1689 ;; partial register stall can be caused there. Then we use movzx.
1690 (define_insn "*movqi_1"
1691 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1692 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1693 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1695 switch (get_attr_type (insn))
1698 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1699 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1701 if (get_attr_mode (insn) == MODE_SI)
1702 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1704 return "mov{b}\t{%1, %0|%0, %1}";
1708 (cond [(and (eq_attr "alternative" "5")
1709 (not (match_operand:QI 1 "aligned_operand" "")))
1710 (const_string "imovx")
1711 (ne (symbol_ref "optimize_size") (const_int 0))
1712 (const_string "imov")
1713 (and (eq_attr "alternative" "3")
1714 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1716 (eq (symbol_ref "TARGET_QIMODE_MATH")
1718 (const_string "imov")
1719 (eq_attr "alternative" "3,5")
1720 (const_string "imovx")
1721 (and (ne (symbol_ref "TARGET_MOVX")
1723 (eq_attr "alternative" "2"))
1724 (const_string "imovx")
1726 (const_string "imov")))
1728 (cond [(eq_attr "alternative" "3,4,5")
1730 (eq_attr "alternative" "6")
1732 (eq_attr "type" "imovx")
1734 (and (eq_attr "type" "imov")
1735 (and (eq_attr "alternative" "0,1")
1736 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1738 (and (eq (symbol_ref "optimize_size")
1740 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1743 ;; Avoid partial register stalls when not using QImode arithmetic
1744 (and (eq_attr "type" "imov")
1745 (and (eq_attr "alternative" "0,1")
1746 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1748 (eq (symbol_ref "TARGET_QIMODE_MATH")
1752 (const_string "QI")))])
1754 (define_expand "reload_outqi"
1755 [(parallel [(match_operand:QI 0 "" "=m")
1756 (match_operand:QI 1 "register_operand" "r")
1757 (match_operand:QI 2 "register_operand" "=&q")])]
1761 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1763 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1764 if (! q_regs_operand (op1, QImode))
1766 emit_insn (gen_movqi (op2, op1));
1769 emit_insn (gen_movqi (op0, op1));
1773 (define_insn "*swapqi_1"
1774 [(set (match_operand:QI 0 "register_operand" "+r")
1775 (match_operand:QI 1 "register_operand" "+r"))
1778 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1780 [(set_attr "type" "imov")
1781 (set_attr "mode" "SI")
1782 (set_attr "pent_pair" "np")
1783 (set_attr "athlon_decode" "vector")
1784 (set_attr "amdfam10_decode" "vector")])
1786 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1787 (define_insn "*swapqi_2"
1788 [(set (match_operand:QI 0 "register_operand" "+q")
1789 (match_operand:QI 1 "register_operand" "+q"))
1792 "TARGET_PARTIAL_REG_STALL"
1794 [(set_attr "type" "imov")
1795 (set_attr "mode" "QI")
1796 (set_attr "pent_pair" "np")
1797 (set_attr "athlon_decode" "vector")])
1799 (define_expand "movstrictqi"
1800 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1801 (match_operand:QI 1 "general_operand" ""))]
1802 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1804 /* Don't generate memory->memory moves, go through a register. */
1805 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1806 operands[1] = force_reg (QImode, operands[1]);
1809 (define_insn "*movstrictqi_1"
1810 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1811 (match_operand:QI 1 "general_operand" "*qn,m"))]
1812 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1813 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1814 "mov{b}\t{%1, %0|%0, %1}"
1815 [(set_attr "type" "imov")
1816 (set_attr "mode" "QI")])
1818 (define_insn "*movstrictqi_xor"
1819 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1820 (match_operand:QI 1 "const0_operand" "i"))
1821 (clobber (reg:CC FLAGS_REG))]
1822 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1824 [(set_attr "type" "alu1")
1825 (set_attr "mode" "QI")
1826 (set_attr "length_immediate" "0")])
1828 (define_insn "*movsi_extv_1"
1829 [(set (match_operand:SI 0 "register_operand" "=R")
1830 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1834 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1835 [(set_attr "type" "imovx")
1836 (set_attr "mode" "SI")])
1838 (define_insn "*movhi_extv_1"
1839 [(set (match_operand:HI 0 "register_operand" "=R")
1840 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1844 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1845 [(set_attr "type" "imovx")
1846 (set_attr "mode" "SI")])
1848 (define_insn "*movqi_extv_1"
1849 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1850 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1855 switch (get_attr_type (insn))
1858 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1860 return "mov{b}\t{%h1, %0|%0, %h1}";
1864 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1865 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1866 (ne (symbol_ref "TARGET_MOVX")
1868 (const_string "imovx")
1869 (const_string "imov")))
1871 (if_then_else (eq_attr "type" "imovx")
1873 (const_string "QI")))])
1875 (define_insn "*movqi_extv_1_rex64"
1876 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1877 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1882 switch (get_attr_type (insn))
1885 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1887 return "mov{b}\t{%h1, %0|%0, %h1}";
1891 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1892 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1893 (ne (symbol_ref "TARGET_MOVX")
1895 (const_string "imovx")
1896 (const_string "imov")))
1898 (if_then_else (eq_attr "type" "imovx")
1900 (const_string "QI")))])
1902 ;; Stores and loads of ax to arbitrary constant address.
1903 ;; We fake an second form of instruction to force reload to load address
1904 ;; into register when rax is not available
1905 (define_insn "*movabsqi_1_rex64"
1906 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1907 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1908 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1910 movabs{b}\t{%1, %P0|%P0, %1}
1911 mov{b}\t{%1, %a0|%a0, %1}"
1912 [(set_attr "type" "imov")
1913 (set_attr "modrm" "0,*")
1914 (set_attr "length_address" "8,0")
1915 (set_attr "length_immediate" "0,*")
1916 (set_attr "memory" "store")
1917 (set_attr "mode" "QI")])
1919 (define_insn "*movabsqi_2_rex64"
1920 [(set (match_operand:QI 0 "register_operand" "=a,r")
1921 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1922 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1924 movabs{b}\t{%P1, %0|%0, %P1}
1925 mov{b}\t{%a1, %0|%0, %a1}"
1926 [(set_attr "type" "imov")
1927 (set_attr "modrm" "0,*")
1928 (set_attr "length_address" "8,0")
1929 (set_attr "length_immediate" "0")
1930 (set_attr "memory" "load")
1931 (set_attr "mode" "QI")])
1933 (define_insn "*movdi_extzv_1"
1934 [(set (match_operand:DI 0 "register_operand" "=R")
1935 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1939 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1940 [(set_attr "type" "imovx")
1941 (set_attr "mode" "DI")])
1943 (define_insn "*movsi_extzv_1"
1944 [(set (match_operand:SI 0 "register_operand" "=R")
1945 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1949 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1950 [(set_attr "type" "imovx")
1951 (set_attr "mode" "SI")])
1953 (define_insn "*movqi_extzv_2"
1954 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1955 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1960 switch (get_attr_type (insn))
1963 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1965 return "mov{b}\t{%h1, %0|%0, %h1}";
1969 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1970 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1971 (ne (symbol_ref "TARGET_MOVX")
1973 (const_string "imovx")
1974 (const_string "imov")))
1976 (if_then_else (eq_attr "type" "imovx")
1978 (const_string "QI")))])
1980 (define_insn "*movqi_extzv_2_rex64"
1981 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1982 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1987 switch (get_attr_type (insn))
1990 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1992 return "mov{b}\t{%h1, %0|%0, %h1}";
1996 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1997 (ne (symbol_ref "TARGET_MOVX")
1999 (const_string "imovx")
2000 (const_string "imov")))
2002 (if_then_else (eq_attr "type" "imovx")
2004 (const_string "QI")))])
2006 (define_insn "movsi_insv_1"
2007 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2010 (match_operand:SI 1 "general_operand" "Qmn"))]
2012 "mov{b}\t{%b1, %h0|%h0, %b1}"
2013 [(set_attr "type" "imov")
2014 (set_attr "mode" "QI")])
2016 (define_insn "*movsi_insv_1_rex64"
2017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2020 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2022 "mov{b}\t{%b1, %h0|%h0, %b1}"
2023 [(set_attr "type" "imov")
2024 (set_attr "mode" "QI")])
2026 (define_insn "movdi_insv_1_rex64"
2027 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2030 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2032 "mov{b}\t{%b1, %h0|%h0, %b1}"
2033 [(set_attr "type" "imov")
2034 (set_attr "mode" "QI")])
2036 (define_insn "*movqi_insv_2"
2037 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2040 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2043 "mov{b}\t{%h1, %h0|%h0, %h1}"
2044 [(set_attr "type" "imov")
2045 (set_attr "mode" "QI")])
2047 (define_expand "movdi"
2048 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2049 (match_operand:DI 1 "general_operand" ""))]
2051 "ix86_expand_move (DImode, operands); DONE;")
2053 (define_insn "*pushdi"
2054 [(set (match_operand:DI 0 "push_operand" "=<")
2055 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2059 (define_insn "*pushdi2_rex64"
2060 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2061 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2066 [(set_attr "type" "push,multi")
2067 (set_attr "mode" "DI")])
2069 ;; Convert impossible pushes of immediate to existing instructions.
2070 ;; First try to get scratch register and go through it. In case this
2071 ;; fails, push sign extended lower part first and then overwrite
2072 ;; upper part by 32bit move.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "push_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))]
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 [(set (match_operand:DI 0 "push_operand" "")
2088 (match_operand:DI 1 "immediate_operand" ""))]
2089 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091 [(set (match_dup 0) (match_dup 1))
2092 (set (match_dup 2) (match_dup 3))]
2093 "split_di (operands + 1, 1, operands + 2, operands + 3);
2094 operands[1] = gen_lowpart (DImode, operands[2]);
2095 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2100 [(set (match_operand:DI 0 "push_operand" "")
2101 (match_operand:DI 1 "immediate_operand" ""))]
2102 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2103 ? epilogue_completed : reload_completed)
2104 && !symbolic_operand (operands[1], DImode)
2105 && !x86_64_immediate_operand (operands[1], DImode)"
2106 [(set (match_dup 0) (match_dup 1))
2107 (set (match_dup 2) (match_dup 3))]
2108 "split_di (operands + 1, 1, operands + 2, operands + 3);
2109 operands[1] = gen_lowpart (DImode, operands[2]);
2110 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2114 (define_insn "*pushdi2_prologue_rex64"
2115 [(set (match_operand:DI 0 "push_operand" "=<")
2116 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2117 (clobber (mem:BLK (scratch)))]
2120 [(set_attr "type" "push")
2121 (set_attr "mode" "DI")])
2123 (define_insn "*popdi1_epilogue_rex64"
2124 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2125 (mem:DI (reg:DI SP_REG)))
2126 (set (reg:DI SP_REG)
2127 (plus:DI (reg:DI SP_REG) (const_int 8)))
2128 (clobber (mem:BLK (scratch)))]
2131 [(set_attr "type" "pop")
2132 (set_attr "mode" "DI")])
2134 (define_insn "popdi1"
2135 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2136 (mem:DI (reg:DI SP_REG)))
2137 (set (reg:DI SP_REG)
2138 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2141 [(set_attr "type" "pop")
2142 (set_attr "mode" "DI")])
2144 (define_insn "*movdi_xor_rex64"
2145 [(set (match_operand:DI 0 "register_operand" "=r")
2146 (match_operand:DI 1 "const0_operand" "i"))
2147 (clobber (reg:CC FLAGS_REG))]
2148 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2149 && reload_completed"
2151 [(set_attr "type" "alu1")
2152 (set_attr "mode" "SI")
2153 (set_attr "length_immediate" "0")])
2155 (define_insn "*movdi_or_rex64"
2156 [(set (match_operand:DI 0 "register_operand" "=r")
2157 (match_operand:DI 1 "const_int_operand" "i"))
2158 (clobber (reg:CC FLAGS_REG))]
2159 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2161 && operands[1] == constm1_rtx"
2163 operands[1] = constm1_rtx;
2164 return "or{q}\t{%1, %0|%0, %1}";
2166 [(set_attr "type" "alu1")
2167 (set_attr "mode" "DI")
2168 (set_attr "length_immediate" "1")])
2170 (define_insn "*movdi_2"
2171 [(set (match_operand:DI 0 "nonimmediate_operand"
2172 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2173 (match_operand:DI 1 "general_operand"
2174 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2175 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2180 movq\t{%1, %0|%0, %1}
2181 movq\t{%1, %0|%0, %1}
2183 movq\t{%1, %0|%0, %1}
2184 movdqa\t{%1, %0|%0, %1}
2185 movq\t{%1, %0|%0, %1}
2187 movlps\t{%1, %0|%0, %1}
2188 movaps\t{%1, %0|%0, %1}
2189 movlps\t{%1, %0|%0, %1}"
2190 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2191 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2194 [(set (match_operand:DI 0 "push_operand" "")
2195 (match_operand:DI 1 "general_operand" ""))]
2196 "!TARGET_64BIT && reload_completed
2197 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2199 "ix86_split_long_move (operands); DONE;")
2201 ;; %%% This multiword shite has got to go.
2203 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2204 (match_operand:DI 1 "general_operand" ""))]
2205 "!TARGET_64BIT && reload_completed
2206 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2207 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2209 "ix86_split_long_move (operands); DONE;")
2211 (define_insn "*movdi_1_rex64"
2212 [(set (match_operand:DI 0 "nonimmediate_operand"
2213 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2214 (match_operand:DI 1 "general_operand"
2215 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2216 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2218 switch (get_attr_type (insn))
2221 if (SSE_REG_P (operands[0]))
2222 return "movq2dq\t{%1, %0|%0, %1}";
2224 return "movdq2q\t{%1, %0|%0, %1}";
2227 if (get_attr_mode (insn) == MODE_TI)
2228 return "movdqa\t{%1, %0|%0, %1}";
2232 /* Moves from and into integer register is done using movd
2233 opcode with REX prefix. */
2234 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2235 return "movd\t{%1, %0|%0, %1}";
2236 return "movq\t{%1, %0|%0, %1}";
2240 return "pxor\t%0, %0";
2246 return "lea{q}\t{%a1, %0|%0, %a1}";
2249 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2250 if (get_attr_mode (insn) == MODE_SI)
2251 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2252 else if (which_alternative == 2)
2253 return "movabs{q}\t{%1, %0|%0, %1}";
2255 return "mov{q}\t{%1, %0|%0, %1}";
2259 (cond [(eq_attr "alternative" "5")
2260 (const_string "mmxadd")
2261 (eq_attr "alternative" "6,7,8,9,10")
2262 (const_string "mmxmov")
2263 (eq_attr "alternative" "11")
2264 (const_string "sselog1")
2265 (eq_attr "alternative" "12,13,14,15,16")
2266 (const_string "ssemov")
2267 (eq_attr "alternative" "17,18")
2268 (const_string "ssecvt")
2269 (eq_attr "alternative" "4")
2270 (const_string "multi")
2271 (match_operand:DI 1 "pic_32bit_operand" "")
2272 (const_string "lea")
2274 (const_string "imov")))
2275 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2276 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2277 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2279 ;; Stores and loads of ax to arbitrary constant address.
2280 ;; We fake an second form of instruction to force reload to load address
2281 ;; into register when rax is not available
2282 (define_insn "*movabsdi_1_rex64"
2283 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2284 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2285 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2287 movabs{q}\t{%1, %P0|%P0, %1}
2288 mov{q}\t{%1, %a0|%a0, %1}"
2289 [(set_attr "type" "imov")
2290 (set_attr "modrm" "0,*")
2291 (set_attr "length_address" "8,0")
2292 (set_attr "length_immediate" "0,*")
2293 (set_attr "memory" "store")
2294 (set_attr "mode" "DI")])
2296 (define_insn "*movabsdi_2_rex64"
2297 [(set (match_operand:DI 0 "register_operand" "=a,r")
2298 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2299 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2301 movabs{q}\t{%P1, %0|%0, %P1}
2302 mov{q}\t{%a1, %0|%0, %a1}"
2303 [(set_attr "type" "imov")
2304 (set_attr "modrm" "0,*")
2305 (set_attr "length_address" "8,0")
2306 (set_attr "length_immediate" "0")
2307 (set_attr "memory" "load")
2308 (set_attr "mode" "DI")])
2310 ;; Convert impossible stores of immediate to existing instructions.
2311 ;; First try to get scratch register and go through it. In case this
2312 ;; fails, move by 32bit parts.
2314 [(match_scratch:DI 2 "r")
2315 (set (match_operand:DI 0 "memory_operand" "")
2316 (match_operand:DI 1 "immediate_operand" ""))]
2317 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2318 && !x86_64_immediate_operand (operands[1], DImode)"
2319 [(set (match_dup 2) (match_dup 1))
2320 (set (match_dup 0) (match_dup 2))]
2323 ;; We need to define this as both peepholer and splitter for case
2324 ;; peephole2 pass is not run.
2325 ;; "&& 1" is needed to keep it from matching the previous pattern.
2327 [(set (match_operand:DI 0 "memory_operand" "")
2328 (match_operand:DI 1 "immediate_operand" ""))]
2329 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2330 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2331 [(set (match_dup 2) (match_dup 3))
2332 (set (match_dup 4) (match_dup 5))]
2333 "split_di (operands, 2, operands + 2, operands + 4);")
2336 [(set (match_operand:DI 0 "memory_operand" "")
2337 (match_operand:DI 1 "immediate_operand" ""))]
2338 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2339 ? epilogue_completed : reload_completed)
2340 && !symbolic_operand (operands[1], DImode)
2341 && !x86_64_immediate_operand (operands[1], DImode)"
2342 [(set (match_dup 2) (match_dup 3))
2343 (set (match_dup 4) (match_dup 5))]
2344 "split_di (operands, 2, operands + 2, operands + 4);")
2346 (define_insn "*swapdi_rex64"
2347 [(set (match_operand:DI 0 "register_operand" "+r")
2348 (match_operand:DI 1 "register_operand" "+r"))
2353 [(set_attr "type" "imov")
2354 (set_attr "mode" "DI")
2355 (set_attr "pent_pair" "np")
2356 (set_attr "athlon_decode" "vector")
2357 (set_attr "amdfam10_decode" "double")])
2359 (define_expand "movti"
2360 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2361 (match_operand:TI 1 "nonimmediate_operand" ""))]
2362 "TARGET_SSE || TARGET_64BIT"
2365 ix86_expand_move (TImode, operands);
2366 else if (push_operand (operands[0], TImode))
2367 ix86_expand_push (TImode, operands[1]);
2369 ix86_expand_vector_move (TImode, operands);
2373 (define_insn "*movti_internal"
2374 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2375 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2376 "TARGET_SSE && !TARGET_64BIT
2377 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2379 switch (which_alternative)
2382 if (get_attr_mode (insn) == MODE_V4SF)
2383 return "xorps\t%0, %0";
2385 return "pxor\t%0, %0";
2388 if (get_attr_mode (insn) == MODE_V4SF)
2389 return "movaps\t{%1, %0|%0, %1}";
2391 return "movdqa\t{%1, %0|%0, %1}";
2396 [(set_attr "type" "sselog1,ssemov,ssemov")
2398 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2399 (ne (symbol_ref "optimize_size") (const_int 0)))
2400 (const_string "V4SF")
2401 (and (eq_attr "alternative" "2")
2402 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2404 (const_string "V4SF")]
2405 (const_string "TI")))])
2407 (define_insn "*movti_rex64"
2408 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2409 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2411 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2413 switch (which_alternative)
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "xorps\t%0, %0";
2422 return "pxor\t%0, %0";
2425 if (get_attr_mode (insn) == MODE_V4SF)
2426 return "movaps\t{%1, %0|%0, %1}";
2428 return "movdqa\t{%1, %0|%0, %1}";
2433 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2435 (cond [(eq_attr "alternative" "2,3")
2437 (ne (symbol_ref "optimize_size")
2439 (const_string "V4SF")
2440 (const_string "TI"))
2441 (eq_attr "alternative" "4")
2443 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2445 (ne (symbol_ref "optimize_size")
2447 (const_string "V4SF")
2448 (const_string "TI"))]
2449 (const_string "DI")))])
2452 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2453 (match_operand:TI 1 "general_operand" ""))]
2454 "reload_completed && !SSE_REG_P (operands[0])
2455 && !SSE_REG_P (operands[1])"
2457 "ix86_split_long_move (operands); DONE;")
2459 ;; This expands to what emit_move_complex would generate if we didn't
2460 ;; have a movti pattern. Having this avoids problems with reload on
2461 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2462 ;; to have around all the time.
2463 (define_expand "movcdi"
2464 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2465 (match_operand:CDI 1 "general_operand" ""))]
2468 if (push_operand (operands[0], CDImode))
2469 emit_move_complex_push (CDImode, operands[0], operands[1]);
2471 emit_move_complex_parts (operands[0], operands[1]);
2475 (define_expand "movsf"
2476 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2477 (match_operand:SF 1 "general_operand" ""))]
2479 "ix86_expand_move (SFmode, operands); DONE;")
2481 (define_insn "*pushsf"
2482 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2483 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2486 /* Anything else should be already split before reg-stack. */
2487 gcc_assert (which_alternative == 1);
2488 return "push{l}\t%1";
2490 [(set_attr "type" "multi,push,multi")
2491 (set_attr "unit" "i387,*,*")
2492 (set_attr "mode" "SF,SI,SF")])
2494 (define_insn "*pushsf_rex64"
2495 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2496 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2499 /* Anything else should be already split before reg-stack. */
2500 gcc_assert (which_alternative == 1);
2501 return "push{q}\t%q1";
2503 [(set_attr "type" "multi,push,multi")
2504 (set_attr "unit" "i387,*,*")
2505 (set_attr "mode" "SF,DI,SF")])
2508 [(set (match_operand:SF 0 "push_operand" "")
2509 (match_operand:SF 1 "memory_operand" ""))]
2511 && MEM_P (operands[1])
2512 && (operands[2] = find_constant_src (insn))"
2517 ;; %%% Kill this when call knows how to work this out.
2519 [(set (match_operand:SF 0 "push_operand" "")
2520 (match_operand:SF 1 "any_fp_register_operand" ""))]
2522 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2523 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2526 [(set (match_operand:SF 0 "push_operand" "")
2527 (match_operand:SF 1 "any_fp_register_operand" ""))]
2529 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2530 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2532 (define_insn "*movsf_1"
2533 [(set (match_operand:SF 0 "nonimmediate_operand"
2534 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2535 (match_operand:SF 1 "general_operand"
2536 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2537 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2538 && (reload_in_progress || reload_completed
2539 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2540 || (!TARGET_SSE_MATH && optimize_size
2541 && standard_80387_constant_p (operands[1]))
2542 || GET_CODE (operands[1]) != CONST_DOUBLE
2543 || memory_operand (operands[0], SFmode))"
2545 switch (which_alternative)
2549 return output_387_reg_move (insn, operands);
2552 return standard_80387_constant_opcode (operands[1]);
2556 return "mov{l}\t{%1, %0|%0, %1}";
2558 if (get_attr_mode (insn) == MODE_TI)
2559 return "pxor\t%0, %0";
2561 return "xorps\t%0, %0";
2563 if (get_attr_mode (insn) == MODE_V4SF)
2564 return "movaps\t{%1, %0|%0, %1}";
2566 return "movss\t{%1, %0|%0, %1}";
2568 return "movss\t{%1, %0|%0, %1}";
2571 case 12: case 13: case 14: case 15:
2572 return "movd\t{%1, %0|%0, %1}";
2575 return "movq\t{%1, %0|%0, %1}";
2581 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2583 (cond [(eq_attr "alternative" "3,4,9,10")
2585 (eq_attr "alternative" "5")
2587 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2589 (ne (symbol_ref "TARGET_SSE2")
2591 (eq (symbol_ref "optimize_size")
2594 (const_string "V4SF"))
2595 /* For architectures resolving dependencies on
2596 whole SSE registers use APS move to break dependency
2597 chains, otherwise use short move to avoid extra work.
2599 Do the same for architectures resolving dependencies on
2600 the parts. While in DF mode it is better to always handle
2601 just register parts, the SF mode is different due to lack
2602 of instructions to load just part of the register. It is
2603 better to maintain the whole registers in single format
2604 to avoid problems on using packed logical operations. */
2605 (eq_attr "alternative" "6")
2607 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2609 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2611 (const_string "V4SF")
2612 (const_string "SF"))
2613 (eq_attr "alternative" "11")
2614 (const_string "DI")]
2615 (const_string "SF")))])
2617 (define_insn "*swapsf"
2618 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2619 (match_operand:SF 1 "fp_register_operand" "+f"))
2622 "reload_completed || TARGET_80387"
2624 if (STACK_TOP_P (operands[0]))
2629 [(set_attr "type" "fxch")
2630 (set_attr "mode" "SF")])
2632 (define_expand "movdf"
2633 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2634 (match_operand:DF 1 "general_operand" ""))]
2636 "ix86_expand_move (DFmode, operands); DONE;")
2638 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2639 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2640 ;; On the average, pushdf using integers can be still shorter. Allow this
2641 ;; pattern for optimize_size too.
2643 (define_insn "*pushdf_nointeger"
2644 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2645 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2646 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2648 /* This insn should be already split before reg-stack. */
2651 [(set_attr "type" "multi")
2652 (set_attr "unit" "i387,*,*,*")
2653 (set_attr "mode" "DF,SI,SI,DF")])
2655 (define_insn "*pushdf_integer"
2656 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2657 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2658 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2660 /* This insn should be already split before reg-stack. */
2663 [(set_attr "type" "multi")
2664 (set_attr "unit" "i387,*,*")
2665 (set_attr "mode" "DF,SI,DF")])
2667 ;; %%% Kill this when call knows how to work this out.
2669 [(set (match_operand:DF 0 "push_operand" "")
2670 (match_operand:DF 1 "any_fp_register_operand" ""))]
2671 "!TARGET_64BIT && reload_completed"
2672 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2673 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2677 [(set (match_operand:DF 0 "push_operand" "")
2678 (match_operand:DF 1 "any_fp_register_operand" ""))]
2679 "TARGET_64BIT && reload_completed"
2680 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2681 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2685 [(set (match_operand:DF 0 "push_operand" "")
2686 (match_operand:DF 1 "general_operand" ""))]
2689 "ix86_split_long_move (operands); DONE;")
2691 ;; Moving is usually shorter when only FP registers are used. This separate
2692 ;; movdf pattern avoids the use of integer registers for FP operations
2693 ;; when optimizing for size.
2695 (define_insn "*movdf_nointeger"
2696 [(set (match_operand:DF 0 "nonimmediate_operand"
2697 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2698 (match_operand:DF 1 "general_operand"
2699 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2700 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2701 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2702 && (reload_in_progress || reload_completed
2703 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2704 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2705 && !memory_operand (operands[0], DFmode)
2706 && standard_80387_constant_p (operands[1]))
2707 || GET_CODE (operands[1]) != CONST_DOUBLE
2709 || !TARGET_MEMORY_MISMATCH_STALL
2710 || reload_in_progress || reload_completed)
2711 && memory_operand (operands[0], DFmode)))"
2713 switch (which_alternative)
2717 return output_387_reg_move (insn, operands);
2720 return standard_80387_constant_opcode (operands[1]);
2726 switch (get_attr_mode (insn))
2729 return "xorps\t%0, %0";
2731 return "xorpd\t%0, %0";
2733 return "pxor\t%0, %0";
2740 switch (get_attr_mode (insn))
2743 return "movaps\t{%1, %0|%0, %1}";
2745 return "movapd\t{%1, %0|%0, %1}";
2747 return "movdqa\t{%1, %0|%0, %1}";
2749 return "movq\t{%1, %0|%0, %1}";
2751 return "movsd\t{%1, %0|%0, %1}";
2753 return "movlpd\t{%1, %0|%0, %1}";
2755 return "movlps\t{%1, %0|%0, %1}";
2764 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2766 (cond [(eq_attr "alternative" "0,1,2")
2768 (eq_attr "alternative" "3,4")
2771 /* For SSE1, we have many fewer alternatives. */
2772 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2773 (cond [(eq_attr "alternative" "5,6")
2774 (const_string "V4SF")
2776 (const_string "V2SF"))
2778 /* xorps is one byte shorter. */
2779 (eq_attr "alternative" "5")
2780 (cond [(ne (symbol_ref "optimize_size")
2782 (const_string "V4SF")
2783 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2787 (const_string "V2DF"))
2789 /* For architectures resolving dependencies on
2790 whole SSE registers use APD move to break dependency
2791 chains, otherwise use short move to avoid extra work.
2793 movaps encodes one byte shorter. */
2794 (eq_attr "alternative" "6")
2796 [(ne (symbol_ref "optimize_size")
2798 (const_string "V4SF")
2799 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2801 (const_string "V2DF")
2803 (const_string "DF"))
2804 /* For architectures resolving dependencies on register
2805 parts we may avoid extra work to zero out upper part
2807 (eq_attr "alternative" "7")
2809 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2811 (const_string "V1DF")
2812 (const_string "DF"))
2814 (const_string "DF")))])
2816 (define_insn "*movdf_integer_rex64"
2817 [(set (match_operand:DF 0 "nonimmediate_operand"
2818 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2819 (match_operand:DF 1 "general_operand"
2820 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2821 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2822 && (reload_in_progress || reload_completed
2823 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2824 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2825 && standard_80387_constant_p (operands[1]))
2826 || GET_CODE (operands[1]) != CONST_DOUBLE
2827 || memory_operand (operands[0], DFmode))"
2829 switch (which_alternative)
2833 return output_387_reg_move (insn, operands);
2836 return standard_80387_constant_opcode (operands[1]);
2843 switch (get_attr_mode (insn))
2846 return "xorps\t%0, %0";
2848 return "xorpd\t%0, %0";
2850 return "pxor\t%0, %0";
2857 switch (get_attr_mode (insn))
2860 return "movaps\t{%1, %0|%0, %1}";
2862 return "movapd\t{%1, %0|%0, %1}";
2864 return "movdqa\t{%1, %0|%0, %1}";
2866 return "movq\t{%1, %0|%0, %1}";
2868 return "movsd\t{%1, %0|%0, %1}";
2870 return "movlpd\t{%1, %0|%0, %1}";
2872 return "movlps\t{%1, %0|%0, %1}";
2879 return "movd\t{%1, %0|%0, %1}";
2885 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2887 (cond [(eq_attr "alternative" "0,1,2")
2889 (eq_attr "alternative" "3,4,9,10")
2892 /* For SSE1, we have many fewer alternatives. */
2893 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2894 (cond [(eq_attr "alternative" "5,6")
2895 (const_string "V4SF")
2897 (const_string "V2SF"))
2899 /* xorps is one byte shorter. */
2900 (eq_attr "alternative" "5")
2901 (cond [(ne (symbol_ref "optimize_size")
2903 (const_string "V4SF")
2904 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2908 (const_string "V2DF"))
2910 /* For architectures resolving dependencies on
2911 whole SSE registers use APD move to break dependency
2912 chains, otherwise use short move to avoid extra work.
2914 movaps encodes one byte shorter. */
2915 (eq_attr "alternative" "6")
2917 [(ne (symbol_ref "optimize_size")
2919 (const_string "V4SF")
2920 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2922 (const_string "V2DF")
2924 (const_string "DF"))
2925 /* For architectures resolving dependencies on register
2926 parts we may avoid extra work to zero out upper part
2928 (eq_attr "alternative" "7")
2930 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2932 (const_string "V1DF")
2933 (const_string "DF"))
2935 (const_string "DF")))])
2937 (define_insn "*movdf_integer"
2938 [(set (match_operand:DF 0 "nonimmediate_operand"
2939 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2940 (match_operand:DF 1 "general_operand"
2941 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2942 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2943 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2944 && (reload_in_progress || reload_completed
2945 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2946 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2947 && standard_80387_constant_p (operands[1]))
2948 || GET_CODE (operands[1]) != CONST_DOUBLE
2949 || memory_operand (operands[0], DFmode))"
2951 switch (which_alternative)
2955 return output_387_reg_move (insn, operands);
2958 return standard_80387_constant_opcode (operands[1]);
2965 switch (get_attr_mode (insn))
2968 return "xorps\t%0, %0";
2970 return "xorpd\t%0, %0";
2972 return "pxor\t%0, %0";
2979 switch (get_attr_mode (insn))
2982 return "movaps\t{%1, %0|%0, %1}";
2984 return "movapd\t{%1, %0|%0, %1}";
2986 return "movdqa\t{%1, %0|%0, %1}";
2988 return "movq\t{%1, %0|%0, %1}";
2990 return "movsd\t{%1, %0|%0, %1}";
2992 return "movlpd\t{%1, %0|%0, %1}";
2994 return "movlps\t{%1, %0|%0, %1}";
3003 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3005 (cond [(eq_attr "alternative" "0,1,2")
3007 (eq_attr "alternative" "3,4")
3010 /* For SSE1, we have many fewer alternatives. */
3011 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3012 (cond [(eq_attr "alternative" "5,6")
3013 (const_string "V4SF")
3015 (const_string "V2SF"))
3017 /* xorps is one byte shorter. */
3018 (eq_attr "alternative" "5")
3019 (cond [(ne (symbol_ref "optimize_size")
3021 (const_string "V4SF")
3022 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3026 (const_string "V2DF"))
3028 /* For architectures resolving dependencies on
3029 whole SSE registers use APD move to break dependency
3030 chains, otherwise use short move to avoid extra work.
3032 movaps encodes one byte shorter. */
3033 (eq_attr "alternative" "6")
3035 [(ne (symbol_ref "optimize_size")
3037 (const_string "V4SF")
3038 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3040 (const_string "V2DF")
3042 (const_string "DF"))
3043 /* For architectures resolving dependencies on register
3044 parts we may avoid extra work to zero out upper part
3046 (eq_attr "alternative" "7")
3048 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3050 (const_string "V1DF")
3051 (const_string "DF"))
3053 (const_string "DF")))])
3056 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3057 (match_operand:DF 1 "general_operand" ""))]
3059 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3060 && ! (ANY_FP_REG_P (operands[0]) ||
3061 (GET_CODE (operands[0]) == SUBREG
3062 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3063 && ! (ANY_FP_REG_P (operands[1]) ||
3064 (GET_CODE (operands[1]) == SUBREG
3065 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3067 "ix86_split_long_move (operands); DONE;")
3069 (define_insn "*swapdf"
3070 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3071 (match_operand:DF 1 "fp_register_operand" "+f"))
3074 "reload_completed || TARGET_80387"
3076 if (STACK_TOP_P (operands[0]))
3081 [(set_attr "type" "fxch")
3082 (set_attr "mode" "DF")])
3084 (define_expand "movxf"
3085 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3086 (match_operand:XF 1 "general_operand" ""))]
3088 "ix86_expand_move (XFmode, operands); DONE;")
3090 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3091 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3092 ;; Pushing using integer instructions is longer except for constants
3093 ;; and direct memory references.
3094 ;; (assuming that any given constant is pushed only once, but this ought to be
3095 ;; handled elsewhere).
3097 (define_insn "*pushxf_nointeger"
3098 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3099 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3102 /* This insn should be already split before reg-stack. */
3105 [(set_attr "type" "multi")
3106 (set_attr "unit" "i387,*,*")
3107 (set_attr "mode" "XF,SI,SI")])
3109 (define_insn "*pushxf_integer"
3110 [(set (match_operand:XF 0 "push_operand" "=<,<")
3111 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3114 /* This insn should be already split before reg-stack. */
3117 [(set_attr "type" "multi")
3118 (set_attr "unit" "i387,*")
3119 (set_attr "mode" "XF,SI")])
3122 [(set (match_operand 0 "push_operand" "")
3123 (match_operand 1 "general_operand" ""))]
3125 && (GET_MODE (operands[0]) == XFmode
3126 || GET_MODE (operands[0]) == DFmode)
3127 && !ANY_FP_REG_P (operands[1])"
3129 "ix86_split_long_move (operands); DONE;")
3132 [(set (match_operand:XF 0 "push_operand" "")
3133 (match_operand:XF 1 "any_fp_register_operand" ""))]
3135 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3136 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3137 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3140 [(set (match_operand:XF 0 "push_operand" "")
3141 (match_operand:XF 1 "any_fp_register_operand" ""))]
3143 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3144 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3145 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3147 ;; Do not use integer registers when optimizing for size
3148 (define_insn "*movxf_nointeger"
3149 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3150 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3152 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3153 && (reload_in_progress || reload_completed
3154 || (optimize_size && standard_80387_constant_p (operands[1]))
3155 || GET_CODE (operands[1]) != CONST_DOUBLE
3156 || memory_operand (operands[0], XFmode))"
3158 switch (which_alternative)
3162 return output_387_reg_move (insn, operands);
3165 return standard_80387_constant_opcode (operands[1]);
3173 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3174 (set_attr "mode" "XF,XF,XF,SI,SI")])
3176 (define_insn "*movxf_integer"
3177 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3178 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3180 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (reload_in_progress || reload_completed
3182 || (optimize_size && standard_80387_constant_p (operands[1]))
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || memory_operand (operands[0], XFmode))"
3186 switch (which_alternative)
3190 return output_387_reg_move (insn, operands);
3193 return standard_80387_constant_opcode (operands[1]);
3202 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3203 (set_attr "mode" "XF,XF,XF,SI,SI")])
3205 (define_expand "movtf"
3206 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3207 (match_operand:TF 1 "nonimmediate_operand" ""))]
3210 ix86_expand_move (TFmode, operands);
3214 (define_insn "*movtf_internal"
3215 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3216 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3218 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3220 switch (which_alternative)
3224 if (get_attr_mode (insn) == MODE_V4SF)
3225 return "movaps\t{%1, %0|%0, %1}";
3227 return "movdqa\t{%1, %0|%0, %1}";
3229 if (get_attr_mode (insn) == MODE_V4SF)
3230 return "xorps\t%0, %0";
3232 return "pxor\t%0, %0";
3240 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3242 (cond [(eq_attr "alternative" "0,2")
3244 (ne (symbol_ref "optimize_size")
3246 (const_string "V4SF")
3247 (const_string "TI"))
3248 (eq_attr "alternative" "1")
3250 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3252 (ne (symbol_ref "optimize_size")
3254 (const_string "V4SF")
3255 (const_string "TI"))]
3256 (const_string "DI")))])
3259 [(set (match_operand 0 "nonimmediate_operand" "")
3260 (match_operand 1 "general_operand" ""))]
3262 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3263 && GET_MODE (operands[0]) == XFmode
3264 && ! (ANY_FP_REG_P (operands[0]) ||
3265 (GET_CODE (operands[0]) == SUBREG
3266 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3267 && ! (ANY_FP_REG_P (operands[1]) ||
3268 (GET_CODE (operands[1]) == SUBREG
3269 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3271 "ix86_split_long_move (operands); DONE;")
3274 [(set (match_operand 0 "register_operand" "")
3275 (match_operand 1 "memory_operand" ""))]
3277 && MEM_P (operands[1])
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == SFmode
3281 || GET_MODE (operands[0]) == DFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3285 rtx c = operands[2];
3286 rtx r = operands[0];
3288 if (GET_CODE (r) == SUBREG)
3293 if (!standard_sse_constant_p (c))
3296 else if (FP_REG_P (r))
3298 if (!standard_80387_constant_p (c))
3301 else if (MMX_REG_P (r))
3306 [(set (match_operand 0 "register_operand" "")
3307 (float_extend (match_operand 1 "memory_operand" "")))]
3309 && MEM_P (operands[1])
3310 && (GET_MODE (operands[0]) == TFmode
3311 || GET_MODE (operands[0]) == XFmode
3312 || GET_MODE (operands[0]) == SFmode
3313 || GET_MODE (operands[0]) == DFmode)
3314 && (operands[2] = find_constant_src (insn))"
3315 [(set (match_dup 0) (match_dup 2))]
3317 rtx c = operands[2];
3318 rtx r = operands[0];
3320 if (GET_CODE (r) == SUBREG)
3325 if (!standard_sse_constant_p (c))
3328 else if (FP_REG_P (r))
3330 if (!standard_80387_constant_p (c))
3333 else if (MMX_REG_P (r))
3337 (define_insn "swapxf"
3338 [(set (match_operand:XF 0 "register_operand" "+f")
3339 (match_operand:XF 1 "register_operand" "+f"))
3344 if (STACK_TOP_P (operands[0]))
3349 [(set_attr "type" "fxch")
3350 (set_attr "mode" "XF")])
3352 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3354 [(set (match_operand:X87MODEF 0 "register_operand" "")
3355 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3356 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3357 && (standard_80387_constant_p (operands[1]) == 8
3358 || standard_80387_constant_p (operands[1]) == 9)"
3359 [(set (match_dup 0)(match_dup 1))
3361 (neg:X87MODEF (match_dup 0)))]
3365 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3366 if (real_isnegzero (&r))
3367 operands[1] = CONST0_RTX (<MODE>mode);
3369 operands[1] = CONST1_RTX (<MODE>mode);
3373 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3374 (match_operand:TF 1 "general_operand" ""))]
3376 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3378 "ix86_split_long_move (operands); DONE;")
3380 ;; Zero extension instructions
3382 (define_expand "zero_extendhisi2"
3383 [(set (match_operand:SI 0 "register_operand" "")
3384 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3387 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3389 operands[1] = force_reg (HImode, operands[1]);
3390 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3395 (define_insn "zero_extendhisi2_and"
3396 [(set (match_operand:SI 0 "register_operand" "=r")
3397 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3398 (clobber (reg:CC FLAGS_REG))]
3399 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3401 [(set_attr "type" "alu1")
3402 (set_attr "mode" "SI")])
3405 [(set (match_operand:SI 0 "register_operand" "")
3406 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3407 (clobber (reg:CC FLAGS_REG))]
3408 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3409 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3410 (clobber (reg:CC FLAGS_REG))])]
3413 (define_insn "*zero_extendhisi2_movzwl"
3414 [(set (match_operand:SI 0 "register_operand" "=r")
3415 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3416 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3417 "movz{wl|x}\t{%1, %0|%0, %1}"
3418 [(set_attr "type" "imovx")
3419 (set_attr "mode" "SI")])
3421 (define_expand "zero_extendqihi2"
3423 [(set (match_operand:HI 0 "register_operand" "")
3424 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3425 (clobber (reg:CC FLAGS_REG))])]
3429 (define_insn "*zero_extendqihi2_and"
3430 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3431 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3432 (clobber (reg:CC FLAGS_REG))]
3433 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3435 [(set_attr "type" "alu1")
3436 (set_attr "mode" "HI")])
3438 (define_insn "*zero_extendqihi2_movzbw_and"
3439 [(set (match_operand:HI 0 "register_operand" "=r,r")
3440 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3441 (clobber (reg:CC FLAGS_REG))]
3442 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3444 [(set_attr "type" "imovx,alu1")
3445 (set_attr "mode" "HI")])
3447 ; zero extend to SImode here to avoid partial register stalls
3448 (define_insn "*zero_extendqihi2_movzbl"
3449 [(set (match_operand:HI 0 "register_operand" "=r")
3450 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3451 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3452 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "SI")])
3456 ;; For the movzbw case strip only the clobber
3458 [(set (match_operand:HI 0 "register_operand" "")
3459 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3460 (clobber (reg:CC FLAGS_REG))]
3462 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3463 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3464 [(set (match_operand:HI 0 "register_operand" "")
3465 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3467 ;; When source and destination does not overlap, clear destination
3468 ;; first and then do the movb
3470 [(set (match_operand:HI 0 "register_operand" "")
3471 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3472 (clobber (reg:CC FLAGS_REG))]
3474 && ANY_QI_REG_P (operands[0])
3475 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3476 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3477 [(set (match_dup 0) (const_int 0))
3478 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3479 "operands[2] = gen_lowpart (QImode, operands[0]);")
3481 ;; Rest is handled by single and.
3483 [(set (match_operand:HI 0 "register_operand" "")
3484 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3485 (clobber (reg:CC FLAGS_REG))]
3487 && true_regnum (operands[0]) == true_regnum (operands[1])"
3488 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3489 (clobber (reg:CC FLAGS_REG))])]
3492 (define_expand "zero_extendqisi2"
3494 [(set (match_operand:SI 0 "register_operand" "")
3495 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3496 (clobber (reg:CC FLAGS_REG))])]
3500 (define_insn "*zero_extendqisi2_and"
3501 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3502 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3503 (clobber (reg:CC FLAGS_REG))]
3504 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3506 [(set_attr "type" "alu1")
3507 (set_attr "mode" "SI")])
3509 (define_insn "*zero_extendqisi2_movzbw_and"
3510 [(set (match_operand:SI 0 "register_operand" "=r,r")
3511 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3512 (clobber (reg:CC FLAGS_REG))]
3513 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3515 [(set_attr "type" "imovx,alu1")
3516 (set_attr "mode" "SI")])
3518 (define_insn "*zero_extendqisi2_movzbw"
3519 [(set (match_operand:SI 0 "register_operand" "=r")
3520 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3521 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3522 "movz{bl|x}\t{%1, %0|%0, %1}"
3523 [(set_attr "type" "imovx")
3524 (set_attr "mode" "SI")])
3526 ;; For the movzbl case strip only the clobber
3528 [(set (match_operand:SI 0 "register_operand" "")
3529 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3530 (clobber (reg:CC FLAGS_REG))]
3532 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3533 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3535 (zero_extend:SI (match_dup 1)))])
3537 ;; When source and destination does not overlap, clear destination
3538 ;; first and then do the movb
3540 [(set (match_operand:SI 0 "register_operand" "")
3541 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3542 (clobber (reg:CC FLAGS_REG))]
3544 && ANY_QI_REG_P (operands[0])
3545 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3546 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3547 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3548 [(set (match_dup 0) (const_int 0))
3549 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3550 "operands[2] = gen_lowpart (QImode, operands[0]);")
3552 ;; Rest is handled by single and.
3554 [(set (match_operand:SI 0 "register_operand" "")
3555 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3556 (clobber (reg:CC FLAGS_REG))]
3558 && true_regnum (operands[0]) == true_regnum (operands[1])"
3559 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3560 (clobber (reg:CC FLAGS_REG))])]
3563 ;; %%% Kill me once multi-word ops are sane.
3564 (define_expand "zero_extendsidi2"
3565 [(set (match_operand:DI 0 "register_operand" "")
3566 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3571 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3576 (define_insn "zero_extendsidi2_32"
3577 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3579 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3580 (clobber (reg:CC FLAGS_REG))]
3586 movd\t{%1, %0|%0, %1}
3587 movd\t{%1, %0|%0, %1}
3588 movd\t{%1, %0|%0, %1}
3589 movd\t{%1, %0|%0, %1}"
3590 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3591 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3593 (define_insn "zero_extendsidi2_rex64"
3594 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3596 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3599 mov\t{%k1, %k0|%k0, %k1}
3601 movd\t{%1, %0|%0, %1}
3602 movd\t{%1, %0|%0, %1}
3603 movd\t{%1, %0|%0, %1}
3604 movd\t{%1, %0|%0, %1}"
3605 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3606 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3609 [(set (match_operand:DI 0 "memory_operand" "")
3610 (zero_extend:DI (match_dup 0)))]
3612 [(set (match_dup 4) (const_int 0))]
3613 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3616 [(set (match_operand:DI 0 "register_operand" "")
3617 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3618 (clobber (reg:CC FLAGS_REG))]
3619 "!TARGET_64BIT && reload_completed
3620 && true_regnum (operands[0]) == true_regnum (operands[1])"
3621 [(set (match_dup 4) (const_int 0))]
3622 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3625 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3626 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3627 (clobber (reg:CC FLAGS_REG))]
3628 "!TARGET_64BIT && reload_completed
3629 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3630 [(set (match_dup 3) (match_dup 1))
3631 (set (match_dup 4) (const_int 0))]
3632 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3634 (define_insn "zero_extendhidi2"
3635 [(set (match_operand:DI 0 "register_operand" "=r")
3636 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3638 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3639 [(set_attr "type" "imovx")
3640 (set_attr "mode" "DI")])
3642 (define_insn "zero_extendqidi2"
3643 [(set (match_operand:DI 0 "register_operand" "=r")
3644 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3646 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3647 [(set_attr "type" "imovx")
3648 (set_attr "mode" "DI")])
3650 ;; Sign extension instructions
3652 (define_expand "extendsidi2"
3653 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3654 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3655 (clobber (reg:CC FLAGS_REG))
3656 (clobber (match_scratch:SI 2 ""))])]
3661 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3666 (define_insn "*extendsidi2_1"
3667 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3668 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3669 (clobber (reg:CC FLAGS_REG))
3670 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3674 (define_insn "extendsidi2_rex64"
3675 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3676 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3680 movs{lq|x}\t{%1,%0|%0, %1}"
3681 [(set_attr "type" "imovx")
3682 (set_attr "mode" "DI")
3683 (set_attr "prefix_0f" "0")
3684 (set_attr "modrm" "0,1")])
3686 (define_insn "extendhidi2"
3687 [(set (match_operand:DI 0 "register_operand" "=r")
3688 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3690 "movs{wq|x}\t{%1,%0|%0, %1}"
3691 [(set_attr "type" "imovx")
3692 (set_attr "mode" "DI")])
3694 (define_insn "extendqidi2"
3695 [(set (match_operand:DI 0 "register_operand" "=r")
3696 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3698 "movs{bq|x}\t{%1,%0|%0, %1}"
3699 [(set_attr "type" "imovx")
3700 (set_attr "mode" "DI")])
3702 ;; Extend to memory case when source register does die.
3704 [(set (match_operand:DI 0 "memory_operand" "")
3705 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3706 (clobber (reg:CC FLAGS_REG))
3707 (clobber (match_operand:SI 2 "register_operand" ""))]
3709 && dead_or_set_p (insn, operands[1])
3710 && !reg_mentioned_p (operands[1], operands[0]))"
3711 [(set (match_dup 3) (match_dup 1))
3712 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3713 (clobber (reg:CC FLAGS_REG))])
3714 (set (match_dup 4) (match_dup 1))]
3715 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3717 ;; Extend to memory case when source register does not die.
3719 [(set (match_operand:DI 0 "memory_operand" "")
3720 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3721 (clobber (reg:CC FLAGS_REG))
3722 (clobber (match_operand:SI 2 "register_operand" ""))]
3726 split_di (&operands[0], 1, &operands[3], &operands[4]);
3728 emit_move_insn (operands[3], operands[1]);
3730 /* Generate a cltd if possible and doing so it profitable. */
3731 if ((optimize_size || TARGET_USE_CLTD)
3732 && true_regnum (operands[1]) == AX_REG
3733 && true_regnum (operands[2]) == DX_REG)
3735 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3739 emit_move_insn (operands[2], operands[1]);
3740 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3742 emit_move_insn (operands[4], operands[2]);
3746 ;; Extend to register case. Optimize case where source and destination
3747 ;; registers match and cases where we can use cltd.
3749 [(set (match_operand:DI 0 "register_operand" "")
3750 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3751 (clobber (reg:CC FLAGS_REG))
3752 (clobber (match_scratch:SI 2 ""))]
3756 split_di (&operands[0], 1, &operands[3], &operands[4]);
3758 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3759 emit_move_insn (operands[3], operands[1]);
3761 /* Generate a cltd if possible and doing so it profitable. */
3762 if ((optimize_size || TARGET_USE_CLTD)
3763 && true_regnum (operands[3]) == AX_REG)
3765 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3769 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3770 emit_move_insn (operands[4], operands[1]);
3772 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3776 (define_insn "extendhisi2"
3777 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3778 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3781 switch (get_attr_prefix_0f (insn))
3784 return "{cwtl|cwde}";
3786 return "movs{wl|x}\t{%1,%0|%0, %1}";
3789 [(set_attr "type" "imovx")
3790 (set_attr "mode" "SI")
3791 (set (attr "prefix_0f")
3792 ;; movsx is short decodable while cwtl is vector decoded.
3793 (if_then_else (and (eq_attr "cpu" "!k6")
3794 (eq_attr "alternative" "0"))
3796 (const_string "1")))
3798 (if_then_else (eq_attr "prefix_0f" "0")
3800 (const_string "1")))])
3802 (define_insn "*extendhisi2_zext"
3803 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3805 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3808 switch (get_attr_prefix_0f (insn))
3811 return "{cwtl|cwde}";
3813 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3816 [(set_attr "type" "imovx")
3817 (set_attr "mode" "SI")
3818 (set (attr "prefix_0f")
3819 ;; movsx is short decodable while cwtl is vector decoded.
3820 (if_then_else (and (eq_attr "cpu" "!k6")
3821 (eq_attr "alternative" "0"))
3823 (const_string "1")))
3825 (if_then_else (eq_attr "prefix_0f" "0")
3827 (const_string "1")))])
3829 (define_insn "extendqihi2"
3830 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3831 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3834 switch (get_attr_prefix_0f (insn))
3837 return "{cbtw|cbw}";
3839 return "movs{bw|x}\t{%1,%0|%0, %1}";
3842 [(set_attr "type" "imovx")
3843 (set_attr "mode" "HI")
3844 (set (attr "prefix_0f")
3845 ;; movsx is short decodable while cwtl is vector decoded.
3846 (if_then_else (and (eq_attr "cpu" "!k6")
3847 (eq_attr "alternative" "0"))
3849 (const_string "1")))
3851 (if_then_else (eq_attr "prefix_0f" "0")
3853 (const_string "1")))])
3855 (define_insn "extendqisi2"
3856 [(set (match_operand:SI 0 "register_operand" "=r")
3857 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3859 "movs{bl|x}\t{%1,%0|%0, %1}"
3860 [(set_attr "type" "imovx")
3861 (set_attr "mode" "SI")])
3863 (define_insn "*extendqisi2_zext"
3864 [(set (match_operand:DI 0 "register_operand" "=r")
3866 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3868 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3869 [(set_attr "type" "imovx")
3870 (set_attr "mode" "SI")])
3872 ;; Conversions between float and double.
3874 ;; These are all no-ops in the model used for the 80387. So just
3877 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3878 (define_insn "*dummy_extendsfdf2"
3879 [(set (match_operand:DF 0 "push_operand" "=<")
3880 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3885 [(set (match_operand:DF 0 "push_operand" "")
3886 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3888 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3889 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3892 [(set (match_operand:DF 0 "push_operand" "")
3893 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3895 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3896 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3898 (define_insn "*dummy_extendsfxf2"
3899 [(set (match_operand:XF 0 "push_operand" "=<")
3900 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3905 [(set (match_operand:XF 0 "push_operand" "")
3906 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3908 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3909 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3910 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3913 [(set (match_operand:XF 0 "push_operand" "")
3914 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3916 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3917 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3918 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3921 [(set (match_operand:XF 0 "push_operand" "")
3922 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3924 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3925 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3926 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3929 [(set (match_operand:XF 0 "push_operand" "")
3930 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3932 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3933 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3934 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3936 (define_expand "extendsfdf2"
3937 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3938 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3939 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3941 /* ??? Needed for compress_float_constant since all fp constants
3942 are LEGITIMATE_CONSTANT_P. */
3943 if (GET_CODE (operands[1]) == CONST_DOUBLE)