Merge -r 127928:132243 from trunk
[official-gcc.git] / gcc / config / i386 / i386.md
blob1724c0df7f5bdec515da55d5747b7500f63afd02
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
7 ;;
8 ;; This file is part of GCC.
9 ;;
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)
13 ;; any later version.
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
31 ;;     operands[1].
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.
47 ;; UNSPEC usage:
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_NOP                  48)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                49)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDDQU                47)
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123    (UNSPEC_TAN                  68)
124    (UNSPEC_FXAM                 69)
126    ; x87 Rounding
127    (UNSPEC_FRNDINT_FLOOR        70)
128    (UNSPEC_FRNDINT_CEIL         71)
129    (UNSPEC_FRNDINT_TRUNC        72)
130    (UNSPEC_FRNDINT_MASK_PM      73)
131    (UNSPEC_FIST_FLOOR           74)
132    (UNSPEC_FIST_CEIL            75)
134    ; x87 Double output FP
135    (UNSPEC_SINCOS_COS           80)
136    (UNSPEC_SINCOS_SIN           81)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
146    (UNSPEC_C2_FLAG              95)
148    ; SSP patterns
149    (UNSPEC_SP_SET               100)
150    (UNSPEC_SP_TEST              101)
151    (UNSPEC_SP_TLS_SET           102)
152    (UNSPEC_SP_TLS_TEST          103)
154    ; SSSE3
155    (UNSPEC_PSHUFB               120)
156    (UNSPEC_PSIGN                121)
157    (UNSPEC_PALIGNR              122)
159    ; For SSE4A support
160    (UNSPEC_EXTRQI               130)
161    (UNSPEC_EXTRQ                131)
162    (UNSPEC_INSERTQI             132)
163    (UNSPEC_INSERTQ              133)
165    ; For SSE4.1 support
166    (UNSPEC_BLENDV               134)
167    (UNSPEC_INSERTPS             135)
168    (UNSPEC_DP                   136)
169    (UNSPEC_MOVNTDQA             137)
170    (UNSPEC_MPSADBW              138)
171    (UNSPEC_PHMINPOSUW           139)
172    (UNSPEC_PTEST                140)
173    (UNSPEC_ROUND                141)
175    ; For SSE4.2 support
176    (UNSPEC_CRC32                143)
177    (UNSPEC_PCMPESTR             144)
178    (UNSPEC_PCMPISTR             145)
180    ;; For SSE5
181    (UNSPEC_SSE5_INTRINSIC       150)
182    (UNSPEC_SSE5_UNSIGNED_CMP    151)
183    (UNSPEC_SSE5_TRUEFALSE       152)
184    (UNSPEC_SSE5_PERMUTE         153)
185    (UNSPEC_SSE5_ASHIFT          154)
186    (UNSPEC_SSE5_LSHIFT          155)
187    (UNSPEC_FRCZ                 156)
188    (UNSPEC_CVTPH2PS             157)
189    (UNSPEC_CVTPS2PH             158)
190   ])
192 (define_constants
193   [(UNSPECV_BLOCKAGE            0)
194    (UNSPECV_STACK_PROBE         1)
195    (UNSPECV_EMMS                2)
196    (UNSPECV_LDMXCSR             3)
197    (UNSPECV_STMXCSR             4)
198    (UNSPECV_FEMMS               5)
199    (UNSPECV_CLFLUSH             6)
200    (UNSPECV_ALIGN               7)
201    (UNSPECV_MONITOR             8)
202    (UNSPECV_MWAIT               9)
203    (UNSPECV_CMPXCHG_1           10)
204    (UNSPECV_CMPXCHG_2           11)
205    (UNSPECV_XCHG                12)
206    (UNSPECV_LOCK                13)
207    (UNSPECV_PROLOGUE_USE        14)
208   ])
210 ;; Constants to represent pcomtrue/pcomfalse variants
211 (define_constants
212   [(PCOM_FALSE                  0)
213    (PCOM_TRUE                   1)
214    (COM_FALSE_S                 2)
215    (COM_FALSE_P                 3)
216    (COM_TRUE_S                  4)
217    (COM_TRUE_P                  5)
218   ])
220 ;; Registers by name.
221 (define_constants
222   [(AX_REG                       0)
223    (DX_REG                       1)
224    (CX_REG                       2)
225    (SI_REG                       4)
226    (DI_REG                       5)
227    (BP_REG                       6)
228    (SP_REG                       7)
229    (FLAGS_REG                   17)
230    (FPSR_REG                    18)
231    (FPCR_REG                    19)
232    (R10_REG                     39)
233    (R11_REG                     40)
234   ])
236 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
237 ;; from i386.c.
239 ;; In C guard expressions, put expressions which may be compile-time
240 ;; constants first.  This allows for better optimization.  For
241 ;; example, write "TARGET_64BIT && reload_completed", not
242 ;; "reload_completed && TARGET_64BIT".
245 ;; Processor type.  This attribute must exactly match the processor_type
246 ;; enumeration in i386.h.
247 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
248                     nocona,core2,generic32,generic64,amdfam10"
249   (const (symbol_ref "ix86_tune")))
251 ;; A basic instruction type.  Refinements due to arguments to be
252 ;; provided in other attributes.
253 (define_attr "type"
254   "other,multi,
255    alu,alu1,negnot,imov,imovx,lea,
256    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
257    icmp,test,ibr,setcc,icmov,
258    push,pop,call,callv,leave,
259    str,bitmanip,
260    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
261    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
262    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
263    ssemuladd,sse4arg,
264    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
265   (const_string "other"))
267 ;; Main data type used by the insn
268 (define_attr "mode"
269   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
270   (const_string "unknown"))
272 ;; The CPU unit operations uses.
273 (define_attr "unit" "integer,i387,sse,mmx,unknown"
274   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
275            (const_string "i387")
276          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
277                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
278                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
279            (const_string "sse")
280          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
281            (const_string "mmx")
282          (eq_attr "type" "other")
283            (const_string "unknown")]
284          (const_string "integer")))
286 ;; The (bounding maximum) length of an instruction immediate.
287 (define_attr "length_immediate" ""
288   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
289                           bitmanip")
290            (const_int 0)
291          (eq_attr "unit" "i387,sse,mmx")
292            (const_int 0)
293          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
294                           imul,icmp,push,pop")
295            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
296          (eq_attr "type" "imov,test")
297            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
298          (eq_attr "type" "call")
299            (if_then_else (match_operand 0 "constant_call_address_operand" "")
300              (const_int 4)
301              (const_int 0))
302          (eq_attr "type" "callv")
303            (if_then_else (match_operand 1 "constant_call_address_operand" "")
304              (const_int 4)
305              (const_int 0))
306          ;; We don't know the size before shorten_branches.  Expect
307          ;; the instruction to fit for better scheduling.
308          (eq_attr "type" "ibr")
309            (const_int 1)
310          ]
311          (symbol_ref "/* Update immediate_length and other attributes! */
312                       gcc_unreachable (),1")))
314 ;; The (bounding maximum) length of an instruction address.
315 (define_attr "length_address" ""
316   (cond [(eq_attr "type" "str,other,multi,fxch")
317            (const_int 0)
318          (and (eq_attr "type" "call")
319               (match_operand 0 "constant_call_address_operand" ""))
320              (const_int 0)
321          (and (eq_attr "type" "callv")
322               (match_operand 1 "constant_call_address_operand" ""))
323              (const_int 0)
324          ]
325          (symbol_ref "ix86_attr_length_address_default (insn)")))
327 ;; Set when length prefix is used.
328 (define_attr "prefix_data16" ""
329   (if_then_else (ior (eq_attr "mode" "HI")
330                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
331     (const_int 1)
332     (const_int 0)))
334 ;; Set when string REP prefix is used.
335 (define_attr "prefix_rep" ""
336   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
337     (const_int 1)
338     (const_int 0)))
340 ;; Set when 0f opcode prefix is used.
341 (define_attr "prefix_0f" ""
342   (if_then_else
343     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
344          (eq_attr "unit" "sse,mmx"))
345     (const_int 1)
346     (const_int 0)))
348 ;; Set when REX opcode prefix is used.
349 (define_attr "prefix_rex" ""
350   (cond [(and (eq_attr "mode" "DI")
351               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
352            (const_int 1)
353          (and (eq_attr "mode" "QI")
354               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
355                   (const_int 0)))
356            (const_int 1)
357          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
358              (const_int 0))
359            (const_int 1)
360         ]
361         (const_int 0)))
363 ;; There are also additional prefixes in SSSE3.
364 (define_attr "prefix_extra" "" (const_int 0))
366 ;; Set when modrm byte is used.
367 (define_attr "modrm" ""
368   (cond [(eq_attr "type" "str,leave")
369            (const_int 0)
370          (eq_attr "unit" "i387")
371            (const_int 0)
372          (and (eq_attr "type" "incdec")
373               (ior (match_operand:SI 1 "register_operand" "")
374                    (match_operand:HI 1 "register_operand" "")))
375            (const_int 0)
376          (and (eq_attr "type" "push")
377               (not (match_operand 1 "memory_operand" "")))
378            (const_int 0)
379          (and (eq_attr "type" "pop")
380               (not (match_operand 0 "memory_operand" "")))
381            (const_int 0)
382          (and (eq_attr "type" "imov")
383               (ior (and (match_operand 0 "register_operand" "")
384                         (match_operand 1 "immediate_operand" ""))
385                    (ior (and (match_operand 0 "ax_reg_operand" "")
386                              (match_operand 1 "memory_displacement_only_operand" ""))
387                         (and (match_operand 0 "memory_displacement_only_operand" "")
388                              (match_operand 1 "ax_reg_operand" "")))))
389            (const_int 0)
390          (and (eq_attr "type" "call")
391               (match_operand 0 "constant_call_address_operand" ""))
392              (const_int 0)
393          (and (eq_attr "type" "callv")
394               (match_operand 1 "constant_call_address_operand" ""))
395              (const_int 0)
396          ]
397          (const_int 1)))
399 ;; The (bounding maximum) length of an instruction in bytes.
400 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
401 ;; Later we may want to split them and compute proper length as for
402 ;; other insns.
403 (define_attr "length" ""
404   (cond [(eq_attr "type" "other,multi,fistp,frndint")
405            (const_int 16)
406          (eq_attr "type" "fcmp")
407            (const_int 4)
408          (eq_attr "unit" "i387")
409            (plus (const_int 2)
410                  (plus (attr "prefix_data16")
411                        (attr "length_address")))]
412          (plus (plus (attr "modrm")
413                      (plus (attr "prefix_0f")
414                            (plus (attr "prefix_rex")
415                                  (plus (attr "prefix_extra")
416                                        (const_int 1)))))
417                (plus (attr "prefix_rep")
418                      (plus (attr "prefix_data16")
419                            (plus (attr "length_immediate")
420                                  (attr "length_address")))))))
422 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
423 ;; `store' if there is a simple memory reference therein, or `unknown'
424 ;; if the instruction is complex.
426 (define_attr "memory" "none,load,store,both,unknown"
427   (cond [(eq_attr "type" "other,multi,str")
428            (const_string "unknown")
429          (eq_attr "type" "lea,fcmov,fpspc")
430            (const_string "none")
431          (eq_attr "type" "fistp,leave")
432            (const_string "both")
433          (eq_attr "type" "frndint")
434            (const_string "load")
435          (eq_attr "type" "push")
436            (if_then_else (match_operand 1 "memory_operand" "")
437              (const_string "both")
438              (const_string "store"))
439          (eq_attr "type" "pop")
440            (if_then_else (match_operand 0 "memory_operand" "")
441              (const_string "both")
442              (const_string "load"))
443          (eq_attr "type" "setcc")
444            (if_then_else (match_operand 0 "memory_operand" "")
445              (const_string "store")
446              (const_string "none"))
447          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
448            (if_then_else (ior (match_operand 0 "memory_operand" "")
449                               (match_operand 1 "memory_operand" ""))
450              (const_string "load")
451              (const_string "none"))
452          (eq_attr "type" "ibr")
453            (if_then_else (match_operand 0 "memory_operand" "")
454              (const_string "load")
455              (const_string "none"))
456          (eq_attr "type" "call")
457            (if_then_else (match_operand 0 "constant_call_address_operand" "")
458              (const_string "none")
459              (const_string "load"))
460          (eq_attr "type" "callv")
461            (if_then_else (match_operand 1 "constant_call_address_operand" "")
462              (const_string "none")
463              (const_string "load"))
464          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
465               (match_operand 1 "memory_operand" ""))
466            (const_string "both")
467          (and (match_operand 0 "memory_operand" "")
468               (match_operand 1 "memory_operand" ""))
469            (const_string "both")
470          (match_operand 0 "memory_operand" "")
471            (const_string "store")
472          (match_operand 1 "memory_operand" "")
473            (const_string "load")
474          (and (eq_attr "type"
475                  "!alu1,negnot,ishift1,
476                    imov,imovx,icmp,test,bitmanip,
477                    fmov,fcmp,fsgn,
478                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
479                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
480               (match_operand 2 "memory_operand" ""))
481            (const_string "load")
482          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
483               (match_operand 3 "memory_operand" ""))
484            (const_string "load")
485         ]
486         (const_string "none")))
488 ;; Indicates if an instruction has both an immediate and a displacement.
490 (define_attr "imm_disp" "false,true,unknown"
491   (cond [(eq_attr "type" "other,multi")
492            (const_string "unknown")
493          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
494               (and (match_operand 0 "memory_displacement_operand" "")
495                    (match_operand 1 "immediate_operand" "")))
496            (const_string "true")
497          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
498               (and (match_operand 0 "memory_displacement_operand" "")
499                    (match_operand 2 "immediate_operand" "")))
500            (const_string "true")
501         ]
502         (const_string "false")))
504 ;; Indicates if an FP operation has an integer source.
506 (define_attr "fp_int_src" "false,true"
507   (const_string "false"))
509 ;; Defines rounding mode of an FP operation.
511 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
512   (const_string "any"))
514 ;; Describe a user's asm statement.
515 (define_asm_attributes
516   [(set_attr "length" "128")
517    (set_attr "type" "multi")])
519 (define_code_iterator plusminus [plus minus])
521 ;; Base name for define_insn and insn mnemonic.
522 (define_code_attr addsub [(plus "add") (minus "sub")])
524 ;; Mark commutative operators as such in constraints.
525 (define_code_attr comm [(plus "%") (minus "")])
527 ;; All single word integer modes.
528 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
530 ;; Instruction suffix for integer modes.
531 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
533 ;; Register class for integer modes.
534 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
536 ;; Immediate operand constraint for integer modes.
537 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
539 ;; General operand predicate for integer modes.
540 (define_mode_attr general_operand
541         [(QI "general_operand")
542          (HI "general_operand")
543          (SI "general_operand")
544          (DI "x86_64_general_operand")])
546 ;; SSE and x87 SFmode and DFmode floating point modes
547 (define_mode_iterator MODEF [SF DF])
549 ;; All x87 floating point modes
550 (define_mode_iterator X87MODEF [SF DF XF])
552 ;; All integer modes handled by x87 fisttp operator.
553 (define_mode_iterator X87MODEI [HI SI DI])
555 ;; All integer modes handled by integer x87 operators.
556 (define_mode_iterator X87MODEI12 [HI SI])
558 ;; All integer modes handled by SSE cvtts?2si* operators.
559 (define_mode_iterator SSEMODEI24 [SI DI])
561 ;; SSE asm suffix for floating point modes
562 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
564 ;; SSE vector mode corresponding to a scalar mode
565 (define_mode_attr ssevecmode
566   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
568 ;; Scheduling descriptions
570 (include "pentium.md")
571 (include "ppro.md")
572 (include "k6.md")
573 (include "athlon.md")
574 (include "geode.md")
577 ;; Operand and operator predicates and constraints
579 (include "predicates.md")
580 (include "constraints.md")
583 ;; Compare instructions.
585 ;; All compare insns have expanders that save the operands away without
586 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
587 ;; after the cmp) will actually emit the cmpM.
589 (define_expand "cmpti"
590   [(set (reg:CC FLAGS_REG)
591         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
592                     (match_operand:TI 1 "x86_64_general_operand" "")))]
593   "TARGET_64BIT"
595   if (MEM_P (operands[0]) && MEM_P (operands[1]))
596     operands[0] = force_reg (TImode, operands[0]);
597   ix86_compare_op0 = operands[0];
598   ix86_compare_op1 = operands[1];
599   DONE;
602 (define_expand "cmpdi"
603   [(set (reg:CC FLAGS_REG)
604         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
605                     (match_operand:DI 1 "x86_64_general_operand" "")))]
606   ""
608   if (MEM_P (operands[0]) && MEM_P (operands[1]))
609     operands[0] = force_reg (DImode, operands[0]);
610   ix86_compare_op0 = operands[0];
611   ix86_compare_op1 = operands[1];
612   DONE;
615 (define_expand "cmpsi"
616   [(set (reg:CC FLAGS_REG)
617         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
618                     (match_operand:SI 1 "general_operand" "")))]
619   ""
621   if (MEM_P (operands[0]) && MEM_P (operands[1]))
622     operands[0] = force_reg (SImode, operands[0]);
623   ix86_compare_op0 = operands[0];
624   ix86_compare_op1 = operands[1];
625   DONE;
628 (define_expand "cmphi"
629   [(set (reg:CC FLAGS_REG)
630         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
631                     (match_operand:HI 1 "general_operand" "")))]
632   ""
634   if (MEM_P (operands[0]) && MEM_P (operands[1]))
635     operands[0] = force_reg (HImode, operands[0]);
636   ix86_compare_op0 = operands[0];
637   ix86_compare_op1 = operands[1];
638   DONE;
641 (define_expand "cmpqi"
642   [(set (reg:CC FLAGS_REG)
643         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
644                     (match_operand:QI 1 "general_operand" "")))]
645   "TARGET_QIMODE_MATH"
647   if (MEM_P (operands[0]) && MEM_P (operands[1]))
648     operands[0] = force_reg (QImode, operands[0]);
649   ix86_compare_op0 = operands[0];
650   ix86_compare_op1 = operands[1];
651   DONE;
654 (define_insn "cmpdi_ccno_1_rex64"
655   [(set (reg FLAGS_REG)
656         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
657                  (match_operand:DI 1 "const0_operand" "n,n")))]
658   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
659   "@
660    test{q}\t%0, %0
661    cmp{q}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "test,icmp")
663    (set_attr "length_immediate" "0,1")
664    (set_attr "mode" "DI")])
666 (define_insn "*cmpdi_minus_1_rex64"
667   [(set (reg FLAGS_REG)
668         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
669                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
670                  (const_int 0)))]
671   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
672   "cmp{q}\t{%1, %0|%0, %1}"
673   [(set_attr "type" "icmp")
674    (set_attr "mode" "DI")])
676 (define_expand "cmpdi_1_rex64"
677   [(set (reg:CC FLAGS_REG)
678         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
679                     (match_operand:DI 1 "general_operand" "")))]
680   "TARGET_64BIT"
681   "")
683 (define_insn "cmpdi_1_insn_rex64"
684   [(set (reg FLAGS_REG)
685         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
686                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
687   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688   "cmp{q}\t{%1, %0|%0, %1}"
689   [(set_attr "type" "icmp")
690    (set_attr "mode" "DI")])
693 (define_insn "*cmpsi_ccno_1"
694   [(set (reg FLAGS_REG)
695         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
696                  (match_operand:SI 1 "const0_operand" "n,n")))]
697   "ix86_match_ccmode (insn, CCNOmode)"
698   "@
699    test{l}\t%0, %0
700    cmp{l}\t{%1, %0|%0, %1}"
701   [(set_attr "type" "test,icmp")
702    (set_attr "length_immediate" "0,1")
703    (set_attr "mode" "SI")])
705 (define_insn "*cmpsi_minus_1"
706   [(set (reg FLAGS_REG)
707         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
708                            (match_operand:SI 1 "general_operand" "ri,mr"))
709                  (const_int 0)))]
710   "ix86_match_ccmode (insn, CCGOCmode)"
711   "cmp{l}\t{%1, %0|%0, %1}"
712   [(set_attr "type" "icmp")
713    (set_attr "mode" "SI")])
715 (define_expand "cmpsi_1"
716   [(set (reg:CC FLAGS_REG)
717         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
718                     (match_operand:SI 1 "general_operand" "")))]
719   ""
720   "")
722 (define_insn "*cmpsi_1_insn"
723   [(set (reg FLAGS_REG)
724         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
725                  (match_operand:SI 1 "general_operand" "ri,mr")))]
726   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
727     && ix86_match_ccmode (insn, CCmode)"
728   "cmp{l}\t{%1, %0|%0, %1}"
729   [(set_attr "type" "icmp")
730    (set_attr "mode" "SI")])
732 (define_insn "*cmphi_ccno_1"
733   [(set (reg FLAGS_REG)
734         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
735                  (match_operand:HI 1 "const0_operand" "n,n")))]
736   "ix86_match_ccmode (insn, CCNOmode)"
737   "@
738    test{w}\t%0, %0
739    cmp{w}\t{%1, %0|%0, %1}"
740   [(set_attr "type" "test,icmp")
741    (set_attr "length_immediate" "0,1")
742    (set_attr "mode" "HI")])
744 (define_insn "*cmphi_minus_1"
745   [(set (reg FLAGS_REG)
746         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
747                            (match_operand:HI 1 "general_operand" "ri,mr"))
748                  (const_int 0)))]
749   "ix86_match_ccmode (insn, CCGOCmode)"
750   "cmp{w}\t{%1, %0|%0, %1}"
751   [(set_attr "type" "icmp")
752    (set_attr "mode" "HI")])
754 (define_insn "*cmphi_1"
755   [(set (reg FLAGS_REG)
756         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
757                  (match_operand:HI 1 "general_operand" "ri,mr")))]
758   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
759    && ix86_match_ccmode (insn, CCmode)"
760   "cmp{w}\t{%1, %0|%0, %1}"
761   [(set_attr "type" "icmp")
762    (set_attr "mode" "HI")])
764 (define_insn "*cmpqi_ccno_1"
765   [(set (reg FLAGS_REG)
766         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
767                  (match_operand:QI 1 "const0_operand" "n,n")))]
768   "ix86_match_ccmode (insn, CCNOmode)"
769   "@
770    test{b}\t%0, %0
771    cmp{b}\t{$0, %0|%0, 0}"
772   [(set_attr "type" "test,icmp")
773    (set_attr "length_immediate" "0,1")
774    (set_attr "mode" "QI")])
776 (define_insn "*cmpqi_1"
777   [(set (reg FLAGS_REG)
778         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
779                  (match_operand:QI 1 "general_operand" "qi,mq")))]
780   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
781     && ix86_match_ccmode (insn, CCmode)"
782   "cmp{b}\t{%1, %0|%0, %1}"
783   [(set_attr "type" "icmp")
784    (set_attr "mode" "QI")])
786 (define_insn "*cmpqi_minus_1"
787   [(set (reg FLAGS_REG)
788         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
789                            (match_operand:QI 1 "general_operand" "qi,mq"))
790                  (const_int 0)))]
791   "ix86_match_ccmode (insn, CCGOCmode)"
792   "cmp{b}\t{%1, %0|%0, %1}"
793   [(set_attr "type" "icmp")
794    (set_attr "mode" "QI")])
796 (define_insn "*cmpqi_ext_1"
797   [(set (reg FLAGS_REG)
798         (compare
799           (match_operand:QI 0 "general_operand" "Qm")
800           (subreg:QI
801             (zero_extract:SI
802               (match_operand 1 "ext_register_operand" "Q")
803               (const_int 8)
804               (const_int 8)) 0)))]
805   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
806   "cmp{b}\t{%h1, %0|%0, %h1}"
807   [(set_attr "type" "icmp")
808    (set_attr "mode" "QI")])
810 (define_insn "*cmpqi_ext_1_rex64"
811   [(set (reg FLAGS_REG)
812         (compare
813           (match_operand:QI 0 "register_operand" "Q")
814           (subreg:QI
815             (zero_extract:SI
816               (match_operand 1 "ext_register_operand" "Q")
817               (const_int 8)
818               (const_int 8)) 0)))]
819   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
820   "cmp{b}\t{%h1, %0|%0, %h1}"
821   [(set_attr "type" "icmp")
822    (set_attr "mode" "QI")])
824 (define_insn "*cmpqi_ext_2"
825   [(set (reg FLAGS_REG)
826         (compare
827           (subreg:QI
828             (zero_extract:SI
829               (match_operand 0 "ext_register_operand" "Q")
830               (const_int 8)
831               (const_int 8)) 0)
832           (match_operand:QI 1 "const0_operand" "n")))]
833   "ix86_match_ccmode (insn, CCNOmode)"
834   "test{b}\t%h0, %h0"
835   [(set_attr "type" "test")
836    (set_attr "length_immediate" "0")
837    (set_attr "mode" "QI")])
839 (define_expand "cmpqi_ext_3"
840   [(set (reg:CC FLAGS_REG)
841         (compare:CC
842           (subreg:QI
843             (zero_extract:SI
844               (match_operand 0 "ext_register_operand" "")
845               (const_int 8)
846               (const_int 8)) 0)
847           (match_operand:QI 1 "general_operand" "")))]
848   ""
849   "")
851 (define_insn "cmpqi_ext_3_insn"
852   [(set (reg FLAGS_REG)
853         (compare
854           (subreg:QI
855             (zero_extract:SI
856               (match_operand 0 "ext_register_operand" "Q")
857               (const_int 8)
858               (const_int 8)) 0)
859           (match_operand:QI 1 "general_operand" "Qmn")))]
860   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
861   "cmp{b}\t{%1, %h0|%h0, %1}"
862   [(set_attr "type" "icmp")
863    (set_attr "mode" "QI")])
865 (define_insn "cmpqi_ext_3_insn_rex64"
866   [(set (reg FLAGS_REG)
867         (compare
868           (subreg:QI
869             (zero_extract:SI
870               (match_operand 0 "ext_register_operand" "Q")
871               (const_int 8)
872               (const_int 8)) 0)
873           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
874   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
875   "cmp{b}\t{%1, %h0|%h0, %1}"
876   [(set_attr "type" "icmp")
877    (set_attr "mode" "QI")])
879 (define_insn "*cmpqi_ext_4"
880   [(set (reg FLAGS_REG)
881         (compare
882           (subreg:QI
883             (zero_extract:SI
884               (match_operand 0 "ext_register_operand" "Q")
885               (const_int 8)
886               (const_int 8)) 0)
887           (subreg:QI
888             (zero_extract:SI
889               (match_operand 1 "ext_register_operand" "Q")
890               (const_int 8)
891               (const_int 8)) 0)))]
892   "ix86_match_ccmode (insn, CCmode)"
893   "cmp{b}\t{%h1, %h0|%h0, %h1}"
894   [(set_attr "type" "icmp")
895    (set_attr "mode" "QI")])
897 ;; These implement float point compares.
898 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
899 ;; which would allow mix and match FP modes on the compares.  Which is what
900 ;; the old patterns did, but with many more of them.
902 (define_expand "cmpxf"
903   [(set (reg:CC FLAGS_REG)
904         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
905                     (match_operand:XF 1 "nonmemory_operand" "")))]
906   "TARGET_80387"
908   ix86_compare_op0 = operands[0];
909   ix86_compare_op1 = operands[1];
910   DONE;
913 (define_expand "cmp<mode>"
914   [(set (reg:CC FLAGS_REG)
915         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
916                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
917   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
919   ix86_compare_op0 = operands[0];
920   ix86_compare_op1 = operands[1];
921   DONE;
924 ;; FP compares, step 1:
925 ;; Set the FP condition codes.
927 ;; CCFPmode     compare with exceptions
928 ;; CCFPUmode    compare with no exceptions
930 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
931 ;; used to manage the reg stack popping would not be preserved.
933 (define_insn "*cmpfp_0"
934   [(set (match_operand:HI 0 "register_operand" "=a")
935         (unspec:HI
936           [(compare:CCFP
937              (match_operand 1 "register_operand" "f")
938              (match_operand 2 "const0_operand" "X"))]
939         UNSPEC_FNSTSW))]
940   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
941    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
942   "* return output_fp_compare (insn, operands, 0, 0);"
943   [(set_attr "type" "multi")
944    (set_attr "unit" "i387")
945    (set (attr "mode")
946      (cond [(match_operand:SF 1 "" "")
947               (const_string "SF")
948             (match_operand:DF 1 "" "")
949               (const_string "DF")
950            ]
951            (const_string "XF")))])
953 (define_insn_and_split "*cmpfp_0_cc"
954   [(set (reg:CCFP FLAGS_REG)
955         (compare:CCFP
956           (match_operand 1 "register_operand" "f")
957           (match_operand 2 "const0_operand" "X")))
958    (clobber (match_operand:HI 0 "register_operand" "=a"))]
959   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
960    && TARGET_SAHF && !TARGET_CMOVE
961    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
962   "#"
963   "&& reload_completed"
964   [(set (match_dup 0)
965         (unspec:HI
966           [(compare:CCFP (match_dup 1)(match_dup 2))]
967         UNSPEC_FNSTSW))
968    (set (reg:CC FLAGS_REG)
969         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
970   ""
971   [(set_attr "type" "multi")
972    (set_attr "unit" "i387")
973    (set (attr "mode")
974      (cond [(match_operand:SF 1 "" "")
975               (const_string "SF")
976             (match_operand:DF 1 "" "")
977               (const_string "DF")
978            ]
979            (const_string "XF")))])
981 (define_insn "*cmpfp_xf"
982   [(set (match_operand:HI 0 "register_operand" "=a")
983         (unspec:HI
984           [(compare:CCFP
985              (match_operand:XF 1 "register_operand" "f")
986              (match_operand:XF 2 "register_operand" "f"))]
987           UNSPEC_FNSTSW))]
988   "TARGET_80387"
989   "* return output_fp_compare (insn, operands, 0, 0);"
990   [(set_attr "type" "multi")
991    (set_attr "unit" "i387")
992    (set_attr "mode" "XF")])
994 (define_insn_and_split "*cmpfp_xf_cc"
995   [(set (reg:CCFP FLAGS_REG)
996         (compare:CCFP
997           (match_operand:XF 1 "register_operand" "f")
998           (match_operand:XF 2 "register_operand" "f")))
999    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1000   "TARGET_80387
1001    && TARGET_SAHF && !TARGET_CMOVE"
1002   "#"
1003   "&& reload_completed"
1004   [(set (match_dup 0)
1005         (unspec:HI
1006           [(compare:CCFP (match_dup 1)(match_dup 2))]
1007         UNSPEC_FNSTSW))
1008    (set (reg:CC FLAGS_REG)
1009         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1010   ""
1011   [(set_attr "type" "multi")
1012    (set_attr "unit" "i387")
1013    (set_attr "mode" "XF")])
1015 (define_insn "*cmpfp_<mode>"
1016   [(set (match_operand:HI 0 "register_operand" "=a")
1017         (unspec:HI
1018           [(compare:CCFP
1019              (match_operand:MODEF 1 "register_operand" "f")
1020              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1021           UNSPEC_FNSTSW))]
1022   "TARGET_80387"
1023   "* return output_fp_compare (insn, operands, 0, 0);"
1024   [(set_attr "type" "multi")
1025    (set_attr "unit" "i387")
1026    (set_attr "mode" "<MODE>")])
1028 (define_insn_and_split "*cmpfp_<mode>_cc"
1029   [(set (reg:CCFP FLAGS_REG)
1030         (compare:CCFP
1031           (match_operand:MODEF 1 "register_operand" "f")
1032           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1033    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1034   "TARGET_80387
1035    && TARGET_SAHF && !TARGET_CMOVE"
1036   "#"
1037   "&& reload_completed"
1038   [(set (match_dup 0)
1039         (unspec:HI
1040           [(compare:CCFP (match_dup 1)(match_dup 2))]
1041         UNSPEC_FNSTSW))
1042    (set (reg:CC FLAGS_REG)
1043         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1044   ""
1045   [(set_attr "type" "multi")
1046    (set_attr "unit" "i387")
1047    (set_attr "mode" "<MODE>")])
1049 (define_insn "*cmpfp_u"
1050   [(set (match_operand:HI 0 "register_operand" "=a")
1051         (unspec:HI
1052           [(compare:CCFPU
1053              (match_operand 1 "register_operand" "f")
1054              (match_operand 2 "register_operand" "f"))]
1055           UNSPEC_FNSTSW))]
1056   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1057    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1058   "* return output_fp_compare (insn, operands, 0, 1);"
1059   [(set_attr "type" "multi")
1060    (set_attr "unit" "i387")
1061    (set (attr "mode")
1062      (cond [(match_operand:SF 1 "" "")
1063               (const_string "SF")
1064             (match_operand:DF 1 "" "")
1065               (const_string "DF")
1066            ]
1067            (const_string "XF")))])
1069 (define_insn_and_split "*cmpfp_u_cc"
1070   [(set (reg:CCFPU FLAGS_REG)
1071         (compare:CCFPU
1072           (match_operand 1 "register_operand" "f")
1073           (match_operand 2 "register_operand" "f")))
1074    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1075   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076    && TARGET_SAHF && !TARGET_CMOVE
1077    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078   "#"
1079   "&& reload_completed"
1080   [(set (match_dup 0)
1081         (unspec:HI
1082           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1083         UNSPEC_FNSTSW))
1084    (set (reg:CC FLAGS_REG)
1085         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1086   ""
1087   [(set_attr "type" "multi")
1088    (set_attr "unit" "i387")
1089    (set (attr "mode")
1090      (cond [(match_operand:SF 1 "" "")
1091               (const_string "SF")
1092             (match_operand:DF 1 "" "")
1093               (const_string "DF")
1094            ]
1095            (const_string "XF")))])
1097 (define_insn "*cmpfp_<mode>"
1098   [(set (match_operand:HI 0 "register_operand" "=a")
1099         (unspec:HI
1100           [(compare:CCFP
1101              (match_operand 1 "register_operand" "f")
1102              (match_operator 3 "float_operator"
1103                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1104           UNSPEC_FNSTSW))]
1105   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1106    && TARGET_USE_<MODE>MODE_FIOP
1107    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1108   "* return output_fp_compare (insn, operands, 0, 0);"
1109   [(set_attr "type" "multi")
1110    (set_attr "unit" "i387")
1111    (set_attr "fp_int_src" "true")
1112    (set_attr "mode" "<MODE>")])
1114 (define_insn_and_split "*cmpfp_<mode>_cc"
1115   [(set (reg:CCFP FLAGS_REG)
1116         (compare:CCFP
1117           (match_operand 1 "register_operand" "f")
1118           (match_operator 3 "float_operator"
1119             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1120    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1121   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122    && TARGET_SAHF && !TARGET_CMOVE
1123    && TARGET_USE_<MODE>MODE_FIOP
1124    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1125   "#"
1126   "&& reload_completed"
1127   [(set (match_dup 0)
1128         (unspec:HI
1129           [(compare:CCFP
1130              (match_dup 1)
1131              (match_op_dup 3 [(match_dup 2)]))]
1132         UNSPEC_FNSTSW))
1133    (set (reg:CC FLAGS_REG)
1134         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1135   ""
1136   [(set_attr "type" "multi")
1137    (set_attr "unit" "i387")
1138    (set_attr "fp_int_src" "true")
1139    (set_attr "mode" "<MODE>")])
1141 ;; FP compares, step 2
1142 ;; Move the fpsw to ax.
1144 (define_insn "x86_fnstsw_1"
1145   [(set (match_operand:HI 0 "register_operand" "=a")
1146         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1147   "TARGET_80387"
1148   "fnstsw\t%0"
1149   [(set_attr "length" "2")
1150    (set_attr "mode" "SI")
1151    (set_attr "unit" "i387")])
1153 ;; FP compares, step 3
1154 ;; Get ax into flags, general case.
1156 (define_insn "x86_sahf_1"
1157   [(set (reg:CC FLAGS_REG)
1158         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1159                    UNSPEC_SAHF))]
1160   "TARGET_SAHF"
1162 #ifdef HAVE_AS_IX86_SAHF
1163   return "sahf";
1164 #else
1165   return ".byte\t0x9e";
1166 #endif
1168   [(set_attr "length" "1")
1169    (set_attr "athlon_decode" "vector")
1170    (set_attr "amdfam10_decode" "direct")
1171    (set_attr "mode" "SI")])
1173 ;; Pentium Pro can do steps 1 through 3 in one go.
1174 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1175 (define_insn "*cmpfp_i_mixed"
1176   [(set (reg:CCFP FLAGS_REG)
1177         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1178                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1179   "TARGET_MIX_SSE_I387
1180    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1181    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1182   "* return output_fp_compare (insn, operands, 1, 0);"
1183   [(set_attr "type" "fcmp,ssecomi")
1184    (set (attr "mode")
1185      (if_then_else (match_operand:SF 1 "" "")
1186         (const_string "SF")
1187         (const_string "DF")))
1188    (set_attr "athlon_decode" "vector")
1189    (set_attr "amdfam10_decode" "direct")])
1191 (define_insn "*cmpfp_i_sse"
1192   [(set (reg:CCFP FLAGS_REG)
1193         (compare:CCFP (match_operand 0 "register_operand" "x")
1194                       (match_operand 1 "nonimmediate_operand" "xm")))]
1195   "TARGET_SSE_MATH
1196    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1197    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1198   "* return output_fp_compare (insn, operands, 1, 0);"
1199   [(set_attr "type" "ssecomi")
1200    (set (attr "mode")
1201      (if_then_else (match_operand:SF 1 "" "")
1202         (const_string "SF")
1203         (const_string "DF")))
1204    (set_attr "athlon_decode" "vector")
1205    (set_attr "amdfam10_decode" "direct")])
1207 (define_insn "*cmpfp_i_i387"
1208   [(set (reg:CCFP FLAGS_REG)
1209         (compare:CCFP (match_operand 0 "register_operand" "f")
1210                       (match_operand 1 "register_operand" "f")))]
1211   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1212    && TARGET_CMOVE
1213    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1214    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1215   "* return output_fp_compare (insn, operands, 1, 0);"
1216   [(set_attr "type" "fcmp")
1217    (set (attr "mode")
1218      (cond [(match_operand:SF 1 "" "")
1219               (const_string "SF")
1220             (match_operand:DF 1 "" "")
1221               (const_string "DF")
1222            ]
1223            (const_string "XF")))
1224    (set_attr "athlon_decode" "vector")
1225    (set_attr "amdfam10_decode" "direct")])
1227 (define_insn "*cmpfp_iu_mixed"
1228   [(set (reg:CCFPU FLAGS_REG)
1229         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1230                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1231   "TARGET_MIX_SSE_I387
1232    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1233    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234   "* return output_fp_compare (insn, operands, 1, 1);"
1235   [(set_attr "type" "fcmp,ssecomi")
1236    (set (attr "mode")
1237      (if_then_else (match_operand:SF 1 "" "")
1238         (const_string "SF")
1239         (const_string "DF")))
1240    (set_attr "athlon_decode" "vector")
1241    (set_attr "amdfam10_decode" "direct")])
1243 (define_insn "*cmpfp_iu_sse"
1244   [(set (reg:CCFPU FLAGS_REG)
1245         (compare:CCFPU (match_operand 0 "register_operand" "x")
1246                        (match_operand 1 "nonimmediate_operand" "xm")))]
1247   "TARGET_SSE_MATH
1248    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1249    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1250   "* return output_fp_compare (insn, operands, 1, 1);"
1251   [(set_attr "type" "ssecomi")
1252    (set (attr "mode")
1253      (if_then_else (match_operand:SF 1 "" "")
1254         (const_string "SF")
1255         (const_string "DF")))
1256    (set_attr "athlon_decode" "vector")
1257    (set_attr "amdfam10_decode" "direct")])
1259 (define_insn "*cmpfp_iu_387"
1260   [(set (reg:CCFPU FLAGS_REG)
1261         (compare:CCFPU (match_operand 0 "register_operand" "f")
1262                        (match_operand 1 "register_operand" "f")))]
1263   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1264    && TARGET_CMOVE
1265    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1266    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1267   "* return output_fp_compare (insn, operands, 1, 1);"
1268   [(set_attr "type" "fcmp")
1269    (set (attr "mode")
1270      (cond [(match_operand:SF 1 "" "")
1271               (const_string "SF")
1272             (match_operand:DF 1 "" "")
1273               (const_string "DF")
1274            ]
1275            (const_string "XF")))
1276    (set_attr "athlon_decode" "vector")
1277    (set_attr "amdfam10_decode" "direct")])
1279 ;; Move instructions.
1281 ;; General case of fullword move.
1283 (define_expand "movsi"
1284   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1285         (match_operand:SI 1 "general_operand" ""))]
1286   ""
1287   "ix86_expand_move (SImode, operands); DONE;")
1289 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1290 ;; general_operand.
1292 ;; %%% We don't use a post-inc memory reference because x86 is not a
1293 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1294 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1295 ;; targets without our curiosities, and it is just as easy to represent
1296 ;; this differently.
1298 (define_insn "*pushsi2"
1299   [(set (match_operand:SI 0 "push_operand" "=<")
1300         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1301   "!TARGET_64BIT"
1302   "push{l}\t%1"
1303   [(set_attr "type" "push")
1304    (set_attr "mode" "SI")])
1306 ;; For 64BIT abi we always round up to 8 bytes.
1307 (define_insn "*pushsi2_rex64"
1308   [(set (match_operand:SI 0 "push_operand" "=X")
1309         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1310   "TARGET_64BIT"
1311   "push{q}\t%q1"
1312   [(set_attr "type" "push")
1313    (set_attr "mode" "SI")])
1315 (define_insn "*pushsi2_prologue"
1316   [(set (match_operand:SI 0 "push_operand" "=<")
1317         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1318    (clobber (mem:BLK (scratch)))]
1319   "!TARGET_64BIT"
1320   "push{l}\t%1"
1321   [(set_attr "type" "push")
1322    (set_attr "mode" "SI")])
1324 (define_insn "*popsi1_epilogue"
1325   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1326         (mem:SI (reg:SI SP_REG)))
1327    (set (reg:SI SP_REG)
1328         (plus:SI (reg:SI SP_REG) (const_int 4)))
1329    (clobber (mem:BLK (scratch)))]
1330   "!TARGET_64BIT"
1331   "pop{l}\t%0"
1332   [(set_attr "type" "pop")
1333    (set_attr "mode" "SI")])
1335 (define_insn "popsi1"
1336   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1337         (mem:SI (reg:SI SP_REG)))
1338    (set (reg:SI SP_REG)
1339         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1340   "!TARGET_64BIT"
1341   "pop{l}\t%0"
1342   [(set_attr "type" "pop")
1343    (set_attr "mode" "SI")])
1345 (define_insn "*movsi_xor"
1346   [(set (match_operand:SI 0 "register_operand" "=r")
1347         (match_operand:SI 1 "const0_operand" "i"))
1348    (clobber (reg:CC FLAGS_REG))]
1349   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1350   "xor{l}\t%0, %0"
1351   [(set_attr "type" "alu1")
1352    (set_attr "mode" "SI")
1353    (set_attr "length_immediate" "0")])
1355 (define_insn "*movsi_or"
1356   [(set (match_operand:SI 0 "register_operand" "=r")
1357         (match_operand:SI 1 "immediate_operand" "i"))
1358    (clobber (reg:CC FLAGS_REG))]
1359   "reload_completed
1360    && operands[1] == constm1_rtx
1361    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1363   operands[1] = constm1_rtx;
1364   return "or{l}\t{%1, %0|%0, %1}";
1366   [(set_attr "type" "alu1")
1367    (set_attr "mode" "SI")
1368    (set_attr "length_immediate" "1")])
1370 (define_insn "*movsi_1"
1371   [(set (match_operand:SI 0 "nonimmediate_operand"
1372                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1373         (match_operand:SI 1 "general_operand"
1374                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1375   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1377   switch (get_attr_type (insn))
1378     {
1379     case TYPE_SSELOG1:
1380       if (get_attr_mode (insn) == MODE_TI)
1381         return "pxor\t%0, %0";
1382       return "xorps\t%0, %0";
1384     case TYPE_SSEMOV:
1385       switch (get_attr_mode (insn))
1386         {
1387         case MODE_TI:
1388           return "movdqa\t{%1, %0|%0, %1}";
1389         case MODE_V4SF:
1390           return "movaps\t{%1, %0|%0, %1}";
1391         case MODE_SI:
1392           return "movd\t{%1, %0|%0, %1}";
1393         case MODE_SF:
1394           return "movss\t{%1, %0|%0, %1}";
1395         default:
1396           gcc_unreachable ();
1397         }
1399     case TYPE_MMXADD:
1400       return "pxor\t%0, %0";
1402     case TYPE_MMXMOV:
1403       if (get_attr_mode (insn) == MODE_DI)
1404         return "movq\t{%1, %0|%0, %1}";
1405       return "movd\t{%1, %0|%0, %1}";
1407     case TYPE_LEA:
1408       return "lea{l}\t{%1, %0|%0, %1}";
1410     default:
1411       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1412       return "mov{l}\t{%1, %0|%0, %1}";
1413     }
1415   [(set (attr "type")
1416      (cond [(eq_attr "alternative" "2")
1417               (const_string "mmxadd")
1418             (eq_attr "alternative" "3,4,5")
1419               (const_string "mmxmov")
1420             (eq_attr "alternative" "6")
1421               (const_string "sselog1")
1422             (eq_attr "alternative" "7,8,9,10,11")
1423               (const_string "ssemov")
1424             (match_operand:DI 1 "pic_32bit_operand" "")
1425               (const_string "lea")
1426            ]
1427            (const_string "imov")))
1428    (set (attr "mode")
1429      (cond [(eq_attr "alternative" "2,3")
1430               (const_string "DI")
1431             (eq_attr "alternative" "6,7")
1432               (if_then_else
1433                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1434                 (const_string "V4SF")
1435                 (const_string "TI"))
1436             (and (eq_attr "alternative" "8,9,10,11")
1437                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1438               (const_string "SF")
1439            ]
1440            (const_string "SI")))])
1442 ;; Stores and loads of ax to arbitrary constant address.
1443 ;; We fake an second form of instruction to force reload to load address
1444 ;; into register when rax is not available
1445 (define_insn "*movabssi_1_rex64"
1446   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1447         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1448   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1449   "@
1450    movabs{l}\t{%1, %P0|%P0, %1}
1451    mov{l}\t{%1, %a0|%a0, %1}"
1452   [(set_attr "type" "imov")
1453    (set_attr "modrm" "0,*")
1454    (set_attr "length_address" "8,0")
1455    (set_attr "length_immediate" "0,*")
1456    (set_attr "memory" "store")
1457    (set_attr "mode" "SI")])
1459 (define_insn "*movabssi_2_rex64"
1460   [(set (match_operand:SI 0 "register_operand" "=a,r")
1461         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1462   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1463   "@
1464    movabs{l}\t{%P1, %0|%0, %P1}
1465    mov{l}\t{%a1, %0|%0, %a1}"
1466   [(set_attr "type" "imov")
1467    (set_attr "modrm" "0,*")
1468    (set_attr "length_address" "8,0")
1469    (set_attr "length_immediate" "0")
1470    (set_attr "memory" "load")
1471    (set_attr "mode" "SI")])
1473 (define_insn "*swapsi"
1474   [(set (match_operand:SI 0 "register_operand" "+r")
1475         (match_operand:SI 1 "register_operand" "+r"))
1476    (set (match_dup 1)
1477         (match_dup 0))]
1478   ""
1479   "xchg{l}\t%1, %0"
1480   [(set_attr "type" "imov")
1481    (set_attr "mode" "SI")
1482    (set_attr "pent_pair" "np")
1483    (set_attr "athlon_decode" "vector")
1484    (set_attr "amdfam10_decode" "double")])
1486 (define_expand "movhi"
1487   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1488         (match_operand:HI 1 "general_operand" ""))]
1489   ""
1490   "ix86_expand_move (HImode, operands); DONE;")
1492 (define_insn "*pushhi2"
1493   [(set (match_operand:HI 0 "push_operand" "=X")
1494         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1495   "!TARGET_64BIT"
1496   "push{l}\t%k1"
1497   [(set_attr "type" "push")
1498    (set_attr "mode" "SI")])
1500 ;; For 64BIT abi we always round up to 8 bytes.
1501 (define_insn "*pushhi2_rex64"
1502   [(set (match_operand:HI 0 "push_operand" "=X")
1503         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1504   "TARGET_64BIT"
1505   "push{q}\t%q1"
1506   [(set_attr "type" "push")
1507    (set_attr "mode" "DI")])
1509 (define_insn "*movhi_1"
1510   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1511         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1512   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1514   switch (get_attr_type (insn))
1515     {
1516     case TYPE_IMOVX:
1517       /* movzwl is faster than movw on p2 due to partial word stalls,
1518          though not as fast as an aligned movl.  */
1519       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1520     default:
1521       if (get_attr_mode (insn) == MODE_SI)
1522         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1523       else
1524         return "mov{w}\t{%1, %0|%0, %1}";
1525     }
1527   [(set (attr "type")
1528      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1529               (const_string "imov")
1530             (and (eq_attr "alternative" "0")
1531                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532                           (const_int 0))
1533                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1534                           (const_int 0))))
1535               (const_string "imov")
1536             (and (eq_attr "alternative" "1,2")
1537                  (match_operand:HI 1 "aligned_operand" ""))
1538               (const_string "imov")
1539             (and (ne (symbol_ref "TARGET_MOVX")
1540                      (const_int 0))
1541                  (eq_attr "alternative" "0,2"))
1542               (const_string "imovx")
1543            ]
1544            (const_string "imov")))
1545     (set (attr "mode")
1546       (cond [(eq_attr "type" "imovx")
1547                (const_string "SI")
1548              (and (eq_attr "alternative" "1,2")
1549                   (match_operand:HI 1 "aligned_operand" ""))
1550                (const_string "SI")
1551              (and (eq_attr "alternative" "0")
1552                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553                            (const_int 0))
1554                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1555                            (const_int 0))))
1556                (const_string "SI")
1557             ]
1558             (const_string "HI")))])
1560 ;; Stores and loads of ax to arbitrary constant address.
1561 ;; We fake an second form of instruction to force reload to load address
1562 ;; into register when rax is not available
1563 (define_insn "*movabshi_1_rex64"
1564   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1565         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1566   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1567   "@
1568    movabs{w}\t{%1, %P0|%P0, %1}
1569    mov{w}\t{%1, %a0|%a0, %1}"
1570   [(set_attr "type" "imov")
1571    (set_attr "modrm" "0,*")
1572    (set_attr "length_address" "8,0")
1573    (set_attr "length_immediate" "0,*")
1574    (set_attr "memory" "store")
1575    (set_attr "mode" "HI")])
1577 (define_insn "*movabshi_2_rex64"
1578   [(set (match_operand:HI 0 "register_operand" "=a,r")
1579         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1580   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1581   "@
1582    movabs{w}\t{%P1, %0|%0, %P1}
1583    mov{w}\t{%a1, %0|%0, %a1}"
1584   [(set_attr "type" "imov")
1585    (set_attr "modrm" "0,*")
1586    (set_attr "length_address" "8,0")
1587    (set_attr "length_immediate" "0")
1588    (set_attr "memory" "load")
1589    (set_attr "mode" "HI")])
1591 (define_insn "*swaphi_1"
1592   [(set (match_operand:HI 0 "register_operand" "+r")
1593         (match_operand:HI 1 "register_operand" "+r"))
1594    (set (match_dup 1)
1595         (match_dup 0))]
1596   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1597   "xchg{l}\t%k1, %k0"
1598   [(set_attr "type" "imov")
1599    (set_attr "mode" "SI")
1600    (set_attr "pent_pair" "np")
1601    (set_attr "athlon_decode" "vector")
1602    (set_attr "amdfam10_decode" "double")])
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swaphi_2"
1606   [(set (match_operand:HI 0 "register_operand" "+r")
1607         (match_operand:HI 1 "register_operand" "+r"))
1608    (set (match_dup 1)
1609         (match_dup 0))]
1610   "TARGET_PARTIAL_REG_STALL"
1611   "xchg{w}\t%1, %0"
1612   [(set_attr "type" "imov")
1613    (set_attr "mode" "HI")
1614    (set_attr "pent_pair" "np")
1615    (set_attr "athlon_decode" "vector")])
1617 (define_expand "movstricthi"
1618   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1619         (match_operand:HI 1 "general_operand" ""))]
1620   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1622   /* Don't generate memory->memory moves, go through a register */
1623   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1624     operands[1] = force_reg (HImode, operands[1]);
1627 (define_insn "*movstricthi_1"
1628   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1629         (match_operand:HI 1 "general_operand" "rn,m"))]
1630   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632   "mov{w}\t{%1, %0|%0, %1}"
1633   [(set_attr "type" "imov")
1634    (set_attr "mode" "HI")])
1636 (define_insn "*movstricthi_xor"
1637   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1638         (match_operand:HI 1 "const0_operand" "i"))
1639    (clobber (reg:CC FLAGS_REG))]
1640   "reload_completed
1641    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1642   "xor{w}\t%0, %0"
1643   [(set_attr "type" "alu1")
1644    (set_attr "mode" "HI")
1645    (set_attr "length_immediate" "0")])
1647 (define_expand "movqi"
1648   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1649         (match_operand:QI 1 "general_operand" ""))]
1650   ""
1651   "ix86_expand_move (QImode, operands); DONE;")
1653 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1654 ;; "push a byte".  But actually we use pushl, which has the effect
1655 ;; of rounding the amount pushed up to a word.
1657 (define_insn "*pushqi2"
1658   [(set (match_operand:QI 0 "push_operand" "=X")
1659         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1660   "!TARGET_64BIT"
1661   "push{l}\t%k1"
1662   [(set_attr "type" "push")
1663    (set_attr "mode" "SI")])
1665 ;; For 64BIT abi we always round up to 8 bytes.
1666 (define_insn "*pushqi2_rex64"
1667   [(set (match_operand:QI 0 "push_operand" "=X")
1668         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1669   "TARGET_64BIT"
1670   "push{q}\t%q1"
1671   [(set_attr "type" "push")
1672    (set_attr "mode" "DI")])
1674 ;; Situation is quite tricky about when to choose full sized (SImode) move
1675 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1676 ;; partial register dependency machines (such as AMD Athlon), where QImode
1677 ;; moves issue extra dependency and for partial register stalls machines
1678 ;; that don't use QImode patterns (and QImode move cause stall on the next
1679 ;; instruction).
1681 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1682 ;; register stall machines with, where we use QImode instructions, since
1683 ;; partial register stall can be caused there.  Then we use movzx.
1684 (define_insn "*movqi_1"
1685   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1686         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1687   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1689   switch (get_attr_type (insn))
1690     {
1691     case TYPE_IMOVX:
1692       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1693       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1694     default:
1695       if (get_attr_mode (insn) == MODE_SI)
1696         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1697       else
1698         return "mov{b}\t{%1, %0|%0, %1}";
1699     }
1701   [(set (attr "type")
1702      (cond [(and (eq_attr "alternative" "5")
1703                  (not (match_operand:QI 1 "aligned_operand" "")))
1704               (const_string "imovx")
1705             (ne (symbol_ref "optimize_size") (const_int 0))
1706               (const_string "imov")
1707             (and (eq_attr "alternative" "3")
1708                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1709                           (const_int 0))
1710                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1711                           (const_int 0))))
1712               (const_string "imov")
1713             (eq_attr "alternative" "3,5")
1714               (const_string "imovx")
1715             (and (ne (symbol_ref "TARGET_MOVX")
1716                      (const_int 0))
1717                  (eq_attr "alternative" "2"))
1718               (const_string "imovx")
1719            ]
1720            (const_string "imov")))
1721    (set (attr "mode")
1722       (cond [(eq_attr "alternative" "3,4,5")
1723                (const_string "SI")
1724              (eq_attr "alternative" "6")
1725                (const_string "QI")
1726              (eq_attr "type" "imovx")
1727                (const_string "SI")
1728              (and (eq_attr "type" "imov")
1729                   (and (eq_attr "alternative" "0,1")
1730                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1731                                 (const_int 0))
1732                             (and (eq (symbol_ref "optimize_size")
1733                                      (const_int 0))
1734                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1735                                      (const_int 0))))))
1736                (const_string "SI")
1737              ;; Avoid partial register stalls when not using QImode arithmetic
1738              (and (eq_attr "type" "imov")
1739                   (and (eq_attr "alternative" "0,1")
1740                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1741                                 (const_int 0))
1742                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1743                                 (const_int 0)))))
1744                (const_string "SI")
1745            ]
1746            (const_string "QI")))])
1748 (define_expand "reload_outqi"
1749   [(parallel [(match_operand:QI 0 "" "=m")
1750               (match_operand:QI 1 "register_operand" "r")
1751               (match_operand:QI 2 "register_operand" "=&q")])]
1752   ""
1754   rtx op0, op1, op2;
1755   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1757   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1758   if (! q_regs_operand (op1, QImode))
1759     {
1760       emit_insn (gen_movqi (op2, op1));
1761       op1 = op2;
1762     }
1763   emit_insn (gen_movqi (op0, op1));
1764   DONE;
1767 (define_insn "*swapqi_1"
1768   [(set (match_operand:QI 0 "register_operand" "+r")
1769         (match_operand:QI 1 "register_operand" "+r"))
1770    (set (match_dup 1)
1771         (match_dup 0))]
1772   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1773   "xchg{l}\t%k1, %k0"
1774   [(set_attr "type" "imov")
1775    (set_attr "mode" "SI")
1776    (set_attr "pent_pair" "np")
1777    (set_attr "athlon_decode" "vector")
1778    (set_attr "amdfam10_decode" "vector")])
1780 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1781 (define_insn "*swapqi_2"
1782   [(set (match_operand:QI 0 "register_operand" "+q")
1783         (match_operand:QI 1 "register_operand" "+q"))
1784    (set (match_dup 1)
1785         (match_dup 0))]
1786   "TARGET_PARTIAL_REG_STALL"
1787   "xchg{b}\t%1, %0"
1788   [(set_attr "type" "imov")
1789    (set_attr "mode" "QI")
1790    (set_attr "pent_pair" "np")
1791    (set_attr "athlon_decode" "vector")])
1793 (define_expand "movstrictqi"
1794   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1795         (match_operand:QI 1 "general_operand" ""))]
1796   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1798   /* Don't generate memory->memory moves, go through a register.  */
1799   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1800     operands[1] = force_reg (QImode, operands[1]);
1803 (define_insn "*movstrictqi_1"
1804   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1805         (match_operand:QI 1 "general_operand" "*qn,m"))]
1806   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1807    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1808   "mov{b}\t{%1, %0|%0, %1}"
1809   [(set_attr "type" "imov")
1810    (set_attr "mode" "QI")])
1812 (define_insn "*movstrictqi_xor"
1813   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1814         (match_operand:QI 1 "const0_operand" "i"))
1815    (clobber (reg:CC FLAGS_REG))]
1816   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1817   "xor{b}\t%0, %0"
1818   [(set_attr "type" "alu1")
1819    (set_attr "mode" "QI")
1820    (set_attr "length_immediate" "0")])
1822 (define_insn "*movsi_extv_1"
1823   [(set (match_operand:SI 0 "register_operand" "=R")
1824         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1825                          (const_int 8)
1826                          (const_int 8)))]
1827   ""
1828   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1829   [(set_attr "type" "imovx")
1830    (set_attr "mode" "SI")])
1832 (define_insn "*movhi_extv_1"
1833   [(set (match_operand:HI 0 "register_operand" "=R")
1834         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1835                          (const_int 8)
1836                          (const_int 8)))]
1837   ""
1838   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1839   [(set_attr "type" "imovx")
1840    (set_attr "mode" "SI")])
1842 (define_insn "*movqi_extv_1"
1843   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1844         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1845                          (const_int 8)
1846                          (const_int 8)))]
1847   "!TARGET_64BIT"
1849   switch (get_attr_type (insn))
1850     {
1851     case TYPE_IMOVX:
1852       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1853     default:
1854       return "mov{b}\t{%h1, %0|%0, %h1}";
1855     }
1857   [(set (attr "type")
1858      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1859                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1860                              (ne (symbol_ref "TARGET_MOVX")
1861                                  (const_int 0))))
1862         (const_string "imovx")
1863         (const_string "imov")))
1864    (set (attr "mode")
1865      (if_then_else (eq_attr "type" "imovx")
1866         (const_string "SI")
1867         (const_string "QI")))])
1869 (define_insn "*movqi_extv_1_rex64"
1870   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1871         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1872                          (const_int 8)
1873                          (const_int 8)))]
1874   "TARGET_64BIT"
1876   switch (get_attr_type (insn))
1877     {
1878     case TYPE_IMOVX:
1879       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1880     default:
1881       return "mov{b}\t{%h1, %0|%0, %h1}";
1882     }
1884   [(set (attr "type")
1885      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1886                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1887                              (ne (symbol_ref "TARGET_MOVX")
1888                                  (const_int 0))))
1889         (const_string "imovx")
1890         (const_string "imov")))
1891    (set (attr "mode")
1892      (if_then_else (eq_attr "type" "imovx")
1893         (const_string "SI")
1894         (const_string "QI")))])
1896 ;; Stores and loads of ax to arbitrary constant address.
1897 ;; We fake an second form of instruction to force reload to load address
1898 ;; into register when rax is not available
1899 (define_insn "*movabsqi_1_rex64"
1900   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1901         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1902   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1903   "@
1904    movabs{b}\t{%1, %P0|%P0, %1}
1905    mov{b}\t{%1, %a0|%a0, %1}"
1906   [(set_attr "type" "imov")
1907    (set_attr "modrm" "0,*")
1908    (set_attr "length_address" "8,0")
1909    (set_attr "length_immediate" "0,*")
1910    (set_attr "memory" "store")
1911    (set_attr "mode" "QI")])
1913 (define_insn "*movabsqi_2_rex64"
1914   [(set (match_operand:QI 0 "register_operand" "=a,r")
1915         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1916   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1917   "@
1918    movabs{b}\t{%P1, %0|%0, %P1}
1919    mov{b}\t{%a1, %0|%0, %a1}"
1920   [(set_attr "type" "imov")
1921    (set_attr "modrm" "0,*")
1922    (set_attr "length_address" "8,0")
1923    (set_attr "length_immediate" "0")
1924    (set_attr "memory" "load")
1925    (set_attr "mode" "QI")])
1927 (define_insn "*movdi_extzv_1"
1928   [(set (match_operand:DI 0 "register_operand" "=R")
1929         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1930                          (const_int 8)
1931                          (const_int 8)))]
1932   "TARGET_64BIT"
1933   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1934   [(set_attr "type" "imovx")
1935    (set_attr "mode" "DI")])
1937 (define_insn "*movsi_extzv_1"
1938   [(set (match_operand:SI 0 "register_operand" "=R")
1939         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1940                          (const_int 8)
1941                          (const_int 8)))]
1942   ""
1943   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1944   [(set_attr "type" "imovx")
1945    (set_attr "mode" "SI")])
1947 (define_insn "*movqi_extzv_2"
1948   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1949         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1950                                     (const_int 8)
1951                                     (const_int 8)) 0))]
1952   "!TARGET_64BIT"
1954   switch (get_attr_type (insn))
1955     {
1956     case TYPE_IMOVX:
1957       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1958     default:
1959       return "mov{b}\t{%h1, %0|%0, %h1}";
1960     }
1962   [(set (attr "type")
1963      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1964                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1965                              (ne (symbol_ref "TARGET_MOVX")
1966                                  (const_int 0))))
1967         (const_string "imovx")
1968         (const_string "imov")))
1969    (set (attr "mode")
1970      (if_then_else (eq_attr "type" "imovx")
1971         (const_string "SI")
1972         (const_string "QI")))])
1974 (define_insn "*movqi_extzv_2_rex64"
1975   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1976         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1977                                     (const_int 8)
1978                                     (const_int 8)) 0))]
1979   "TARGET_64BIT"
1981   switch (get_attr_type (insn))
1982     {
1983     case TYPE_IMOVX:
1984       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1985     default:
1986       return "mov{b}\t{%h1, %0|%0, %h1}";
1987     }
1989   [(set (attr "type")
1990      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1991                         (ne (symbol_ref "TARGET_MOVX")
1992                             (const_int 0)))
1993         (const_string "imovx")
1994         (const_string "imov")))
1995    (set (attr "mode")
1996      (if_then_else (eq_attr "type" "imovx")
1997         (const_string "SI")
1998         (const_string "QI")))])
2000 (define_insn "movsi_insv_1"
2001   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2002                          (const_int 8)
2003                          (const_int 8))
2004         (match_operand:SI 1 "general_operand" "Qmn"))]
2005   "!TARGET_64BIT"
2006   "mov{b}\t{%b1, %h0|%h0, %b1}"
2007   [(set_attr "type" "imov")
2008    (set_attr "mode" "QI")])
2010 (define_insn "*movsi_insv_1_rex64"
2011   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2012                          (const_int 8)
2013                          (const_int 8))
2014         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2015   "TARGET_64BIT"
2016   "mov{b}\t{%b1, %h0|%h0, %b1}"
2017   [(set_attr "type" "imov")
2018    (set_attr "mode" "QI")])
2020 (define_insn "movdi_insv_1_rex64"
2021   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2022                          (const_int 8)
2023                          (const_int 8))
2024         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2025   "TARGET_64BIT"
2026   "mov{b}\t{%b1, %h0|%h0, %b1}"
2027   [(set_attr "type" "imov")
2028    (set_attr "mode" "QI")])
2030 (define_insn "*movqi_insv_2"
2031   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2032                          (const_int 8)
2033                          (const_int 8))
2034         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2035                      (const_int 8)))]
2036   ""
2037   "mov{b}\t{%h1, %h0|%h0, %h1}"
2038   [(set_attr "type" "imov")
2039    (set_attr "mode" "QI")])
2041 (define_expand "movdi"
2042   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2043         (match_operand:DI 1 "general_operand" ""))]
2044   ""
2045   "ix86_expand_move (DImode, operands); DONE;")
2047 (define_insn "*pushdi"
2048   [(set (match_operand:DI 0 "push_operand" "=<")
2049         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2050   "!TARGET_64BIT"
2051   "#")
2053 (define_insn "*pushdi2_rex64"
2054   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2055         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2056   "TARGET_64BIT"
2057   "@
2058    push{q}\t%1
2059    #"
2060   [(set_attr "type" "push,multi")
2061    (set_attr "mode" "DI")])
2063 ;; Convert impossible pushes of immediate to existing instructions.
2064 ;; First try to get scratch register and go through it.  In case this
2065 ;; fails, push sign extended lower part first and then overwrite
2066 ;; upper part by 32bit move.
2067 (define_peephole2
2068   [(match_scratch:DI 2 "r")
2069    (set (match_operand:DI 0 "push_operand" "")
2070         (match_operand:DI 1 "immediate_operand" ""))]
2071   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072    && !x86_64_immediate_operand (operands[1], DImode)"
2073   [(set (match_dup 2) (match_dup 1))
2074    (set (match_dup 0) (match_dup 2))]
2075   "")
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2080 (define_peephole2
2081   [(set (match_operand:DI 0 "push_operand" "")
2082         (match_operand:DI 1 "immediate_operand" ""))]
2083   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085   [(set (match_dup 0) (match_dup 1))
2086    (set (match_dup 2) (match_dup 3))]
2087   "split_di (operands + 1, 1, operands + 2, operands + 3);
2088    operands[1] = gen_lowpart (DImode, operands[2]);
2089    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2090                                                     GEN_INT (4)));
2091   ")
2093 (define_split
2094   [(set (match_operand:DI 0 "push_operand" "")
2095         (match_operand:DI 1 "immediate_operand" ""))]
2096   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097                     ? epilogue_completed : reload_completed)
2098    && !symbolic_operand (operands[1], DImode)
2099    && !x86_64_immediate_operand (operands[1], DImode)"
2100   [(set (match_dup 0) (match_dup 1))
2101    (set (match_dup 2) (match_dup 3))]
2102   "split_di (operands + 1, 1, operands + 2, operands + 3);
2103    operands[1] = gen_lowpart (DImode, operands[2]);
2104    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2105                                                     GEN_INT (4)));
2106   ")
2108 (define_insn "*pushdi2_prologue_rex64"
2109   [(set (match_operand:DI 0 "push_operand" "=<")
2110         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2111    (clobber (mem:BLK (scratch)))]
2112   "TARGET_64BIT"
2113   "push{q}\t%1"
2114   [(set_attr "type" "push")
2115    (set_attr "mode" "DI")])
2117 (define_insn "*popdi1_epilogue_rex64"
2118   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2119         (mem:DI (reg:DI SP_REG)))
2120    (set (reg:DI SP_REG)
2121         (plus:DI (reg:DI SP_REG) (const_int 8)))
2122    (clobber (mem:BLK (scratch)))]
2123   "TARGET_64BIT"
2124   "pop{q}\t%0"
2125   [(set_attr "type" "pop")
2126    (set_attr "mode" "DI")])
2128 (define_insn "popdi1"
2129   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2130         (mem:DI (reg:DI SP_REG)))
2131    (set (reg:DI SP_REG)
2132         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2133   "TARGET_64BIT"
2134   "pop{q}\t%0"
2135   [(set_attr "type" "pop")
2136    (set_attr "mode" "DI")])
2138 (define_insn "*movdi_xor_rex64"
2139   [(set (match_operand:DI 0 "register_operand" "=r")
2140         (match_operand:DI 1 "const0_operand" "i"))
2141    (clobber (reg:CC FLAGS_REG))]
2142   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2143    && reload_completed"
2144   "xor{l}\t%k0, %k0";
2145   [(set_attr "type" "alu1")
2146    (set_attr "mode" "SI")
2147    (set_attr "length_immediate" "0")])
2149 (define_insn "*movdi_or_rex64"
2150   [(set (match_operand:DI 0 "register_operand" "=r")
2151         (match_operand:DI 1 "const_int_operand" "i"))
2152    (clobber (reg:CC FLAGS_REG))]
2153   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2154    && reload_completed
2155    && operands[1] == constm1_rtx"
2157   operands[1] = constm1_rtx;
2158   return "or{q}\t{%1, %0|%0, %1}";
2160   [(set_attr "type" "alu1")
2161    (set_attr "mode" "DI")
2162    (set_attr "length_immediate" "1")])
2164 (define_insn "*movdi_2"
2165   [(set (match_operand:DI 0 "nonimmediate_operand"
2166                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2167         (match_operand:DI 1 "general_operand"
2168                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2169   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2170   "@
2171    #
2172    #
2173    pxor\t%0, %0
2174    movq\t{%1, %0|%0, %1}
2175    movq\t{%1, %0|%0, %1}
2176    pxor\t%0, %0
2177    movq\t{%1, %0|%0, %1}
2178    movdqa\t{%1, %0|%0, %1}
2179    movq\t{%1, %0|%0, %1}
2180    xorps\t%0, %0
2181    movlps\t{%1, %0|%0, %1}
2182    movaps\t{%1, %0|%0, %1}
2183    movlps\t{%1, %0|%0, %1}"
2184   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2185    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2187 (define_split
2188   [(set (match_operand:DI 0 "push_operand" "")
2189         (match_operand:DI 1 "general_operand" ""))]
2190   "!TARGET_64BIT && reload_completed
2191    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2192   [(const_int 0)]
2193   "ix86_split_long_move (operands); DONE;")
2195 ;; %%% This multiword shite has got to go.
2196 (define_split
2197   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2198         (match_operand:DI 1 "general_operand" ""))]
2199   "!TARGET_64BIT && reload_completed
2200    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2201    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2202   [(const_int 0)]
2203   "ix86_split_long_move (operands); DONE;")
2205 (define_insn "*movdi_1_rex64"
2206   [(set (match_operand:DI 0 "nonimmediate_operand"
2207           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2208         (match_operand:DI 1 "general_operand"
2209           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2210   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2212   switch (get_attr_type (insn))
2213     {
2214     case TYPE_SSECVT:
2215       if (SSE_REG_P (operands[0]))
2216         return "movq2dq\t{%1, %0|%0, %1}";
2217       else
2218         return "movdq2q\t{%1, %0|%0, %1}";
2220     case TYPE_SSEMOV:
2221       if (get_attr_mode (insn) == MODE_TI)
2222         return "movdqa\t{%1, %0|%0, %1}";
2223       /* FALLTHRU */
2225     case TYPE_MMXMOV:
2226       /* Moves from and into integer register is done using movd
2227          opcode with REX prefix.  */
2228       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2229         return "movd\t{%1, %0|%0, %1}";
2230       return "movq\t{%1, %0|%0, %1}";
2232     case TYPE_SSELOG1:
2233     case TYPE_MMXADD:
2234       return "pxor\t%0, %0";
2236     case TYPE_MULTI:
2237       return "#";
2239     case TYPE_LEA:
2240       return "lea{q}\t{%a1, %0|%0, %a1}";
2242     default:
2243       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2244       if (get_attr_mode (insn) == MODE_SI)
2245         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2246       else if (which_alternative == 2)
2247         return "movabs{q}\t{%1, %0|%0, %1}";
2248       else
2249         return "mov{q}\t{%1, %0|%0, %1}";
2250     }
2252   [(set (attr "type")
2253      (cond [(eq_attr "alternative" "5")
2254               (const_string "mmxadd")
2255             (eq_attr "alternative" "6,7,8,9,10")
2256               (const_string "mmxmov")
2257             (eq_attr "alternative" "11")
2258               (const_string "sselog1")
2259             (eq_attr "alternative" "12,13,14,15,16")
2260               (const_string "ssemov")
2261             (eq_attr "alternative" "17,18")
2262               (const_string "ssecvt")
2263             (eq_attr "alternative" "4")
2264               (const_string "multi")
2265             (match_operand:DI 1 "pic_32bit_operand" "")
2266               (const_string "lea")
2267            ]
2268            (const_string "imov")))
2269    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2271    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2273 ;; Stores and loads of ax to arbitrary constant address.
2274 ;; We fake an second form of instruction to force reload to load address
2275 ;; into register when rax is not available
2276 (define_insn "*movabsdi_1_rex64"
2277   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2278         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2279   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2280   "@
2281    movabs{q}\t{%1, %P0|%P0, %1}
2282    mov{q}\t{%1, %a0|%a0, %1}"
2283   [(set_attr "type" "imov")
2284    (set_attr "modrm" "0,*")
2285    (set_attr "length_address" "8,0")
2286    (set_attr "length_immediate" "0,*")
2287    (set_attr "memory" "store")
2288    (set_attr "mode" "DI")])
2290 (define_insn "*movabsdi_2_rex64"
2291   [(set (match_operand:DI 0 "register_operand" "=a,r")
2292         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2293   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2294   "@
2295    movabs{q}\t{%P1, %0|%0, %P1}
2296    mov{q}\t{%a1, %0|%0, %a1}"
2297   [(set_attr "type" "imov")
2298    (set_attr "modrm" "0,*")
2299    (set_attr "length_address" "8,0")
2300    (set_attr "length_immediate" "0")
2301    (set_attr "memory" "load")
2302    (set_attr "mode" "DI")])
2304 ;; Convert impossible stores of immediate to existing instructions.
2305 ;; First try to get scratch register and go through it.  In case this
2306 ;; fails, move by 32bit parts.
2307 (define_peephole2
2308   [(match_scratch:DI 2 "r")
2309    (set (match_operand:DI 0 "memory_operand" "")
2310         (match_operand:DI 1 "immediate_operand" ""))]
2311   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2312    && !x86_64_immediate_operand (operands[1], DImode)"
2313   [(set (match_dup 2) (match_dup 1))
2314    (set (match_dup 0) (match_dup 2))]
2315   "")
2317 ;; We need to define this as both peepholer and splitter for case
2318 ;; peephole2 pass is not run.
2319 ;; "&& 1" is needed to keep it from matching the previous pattern.
2320 (define_peephole2
2321   [(set (match_operand:DI 0 "memory_operand" "")
2322         (match_operand:DI 1 "immediate_operand" ""))]
2323   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2324    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2325   [(set (match_dup 2) (match_dup 3))
2326    (set (match_dup 4) (match_dup 5))]
2327   "split_di (operands, 2, operands + 2, operands + 4);")
2329 (define_split
2330   [(set (match_operand:DI 0 "memory_operand" "")
2331         (match_operand:DI 1 "immediate_operand" ""))]
2332   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2333                     ? epilogue_completed : reload_completed)
2334    && !symbolic_operand (operands[1], DImode)
2335    && !x86_64_immediate_operand (operands[1], DImode)"
2336   [(set (match_dup 2) (match_dup 3))
2337    (set (match_dup 4) (match_dup 5))]
2338   "split_di (operands, 2, operands + 2, operands + 4);")
2340 (define_insn "*swapdi_rex64"
2341   [(set (match_operand:DI 0 "register_operand" "+r")
2342         (match_operand:DI 1 "register_operand" "+r"))
2343    (set (match_dup 1)
2344         (match_dup 0))]
2345   "TARGET_64BIT"
2346   "xchg{q}\t%1, %0"
2347   [(set_attr "type" "imov")
2348    (set_attr "mode" "DI")
2349    (set_attr "pent_pair" "np")
2350    (set_attr "athlon_decode" "vector")
2351    (set_attr "amdfam10_decode" "double")])
2353 (define_expand "movti"
2354   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2355         (match_operand:TI 1 "nonimmediate_operand" ""))]
2356   "TARGET_SSE || TARGET_64BIT"
2358   if (TARGET_64BIT)
2359     ix86_expand_move (TImode, operands);
2360   else if (push_operand (operands[0], TImode))
2361     ix86_expand_push (TImode, operands[1]);
2362   else
2363     ix86_expand_vector_move (TImode, operands);
2364   DONE;
2367 (define_insn "*movti_internal"
2368   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2369         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2370   "TARGET_SSE && !TARGET_64BIT
2371    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2373   switch (which_alternative)
2374     {
2375     case 0:
2376       if (get_attr_mode (insn) == MODE_V4SF)
2377         return "xorps\t%0, %0";
2378       else
2379         return "pxor\t%0, %0";
2380     case 1:
2381     case 2:
2382       if (get_attr_mode (insn) == MODE_V4SF)
2383         return "movaps\t{%1, %0|%0, %1}";
2384       else
2385         return "movdqa\t{%1, %0|%0, %1}";
2386     default:
2387       gcc_unreachable ();
2388     }
2390   [(set_attr "type" "sselog1,ssemov,ssemov")
2391    (set (attr "mode")
2392         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2393                     (ne (symbol_ref "optimize_size") (const_int 0)))
2394                  (const_string "V4SF")
2395                (and (eq_attr "alternative" "2")
2396                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2397                         (const_int 0)))
2398                  (const_string "V4SF")]
2399               (const_string "TI")))])
2401 (define_insn "*movti_rex64"
2402   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2403         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2404   "TARGET_64BIT
2405    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2407   switch (which_alternative)
2408     {
2409     case 0:
2410     case 1:
2411       return "#";
2412     case 2:
2413       if (get_attr_mode (insn) == MODE_V4SF)
2414         return "xorps\t%0, %0";
2415       else
2416         return "pxor\t%0, %0";
2417     case 3:
2418     case 4:
2419       if (get_attr_mode (insn) == MODE_V4SF)
2420         return "movaps\t{%1, %0|%0, %1}";
2421       else
2422         return "movdqa\t{%1, %0|%0, %1}";
2423     default:
2424       gcc_unreachable ();
2425     }
2427   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2428    (set (attr "mode")
2429         (cond [(eq_attr "alternative" "2,3")
2430                  (if_then_else
2431                    (ne (symbol_ref "optimize_size")
2432                        (const_int 0))
2433                    (const_string "V4SF")
2434                    (const_string "TI"))
2435                (eq_attr "alternative" "4")
2436                  (if_then_else
2437                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2438                             (const_int 0))
2439                         (ne (symbol_ref "optimize_size")
2440                             (const_int 0)))
2441                    (const_string "V4SF")
2442                    (const_string "TI"))]
2443                (const_string "DI")))])
2445 (define_split
2446   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2447         (match_operand:TI 1 "general_operand" ""))]
2448   "reload_completed && !SSE_REG_P (operands[0])
2449    && !SSE_REG_P (operands[1])"
2450   [(const_int 0)]
2451   "ix86_split_long_move (operands); DONE;")
2453 ;; This expands to what emit_move_complex would generate if we didn't
2454 ;; have a movti pattern.  Having this avoids problems with reload on
2455 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2456 ;; to have around all the time.
2457 (define_expand "movcdi"
2458   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2459         (match_operand:CDI 1 "general_operand" ""))]
2460   ""
2462   if (push_operand (operands[0], CDImode))
2463     emit_move_complex_push (CDImode, operands[0], operands[1]);
2464   else
2465     emit_move_complex_parts (operands[0], operands[1]);
2466   DONE;
2469 (define_expand "movsf"
2470   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2471         (match_operand:SF 1 "general_operand" ""))]
2472   ""
2473   "ix86_expand_move (SFmode, operands); DONE;")
2475 (define_insn "*pushsf"
2476   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2477         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2478   "!TARGET_64BIT"
2480   /* Anything else should be already split before reg-stack.  */
2481   gcc_assert (which_alternative == 1);
2482   return "push{l}\t%1";
2484   [(set_attr "type" "multi,push,multi")
2485    (set_attr "unit" "i387,*,*")
2486    (set_attr "mode" "SF,SI,SF")])
2488 (define_insn "*pushsf_rex64"
2489   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2490         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2491   "TARGET_64BIT"
2493   /* Anything else should be already split before reg-stack.  */
2494   gcc_assert (which_alternative == 1);
2495   return "push{q}\t%q1";
2497   [(set_attr "type" "multi,push,multi")
2498    (set_attr "unit" "i387,*,*")
2499    (set_attr "mode" "SF,DI,SF")])
2501 (define_split
2502   [(set (match_operand:SF 0 "push_operand" "")
2503         (match_operand:SF 1 "memory_operand" ""))]
2504   "reload_completed
2505    && MEM_P (operands[1])
2506    && (operands[2] = find_constant_src (insn))"
2507   [(set (match_dup 0)
2508         (match_dup 2))])
2511 ;; %%% Kill this when call knows how to work this out.
2512 (define_split
2513   [(set (match_operand:SF 0 "push_operand" "")
2514         (match_operand:SF 1 "any_fp_register_operand" ""))]
2515   "!TARGET_64BIT"
2516   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2517    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2519 (define_split
2520   [(set (match_operand:SF 0 "push_operand" "")
2521         (match_operand:SF 1 "any_fp_register_operand" ""))]
2522   "TARGET_64BIT"
2523   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2524    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2526 (define_insn "*movsf_1"
2527   [(set (match_operand:SF 0 "nonimmediate_operand"
2528           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2529         (match_operand:SF 1 "general_operand"
2530           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2531   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2532    && (reload_in_progress || reload_completed
2533        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2534        || (!TARGET_SSE_MATH && optimize_size
2535            && standard_80387_constant_p (operands[1]))
2536        || GET_CODE (operands[1]) != CONST_DOUBLE
2537        || memory_operand (operands[0], SFmode))"
2539   switch (which_alternative)
2540     {
2541     case 0:
2542     case 1:
2543       return output_387_reg_move (insn, operands);
2545     case 2:
2546       return standard_80387_constant_opcode (operands[1]);
2548     case 3:
2549     case 4:
2550       return "mov{l}\t{%1, %0|%0, %1}";
2551     case 5:
2552       if (get_attr_mode (insn) == MODE_TI)
2553         return "pxor\t%0, %0";
2554       else
2555         return "xorps\t%0, %0";
2556     case 6:
2557       if (get_attr_mode (insn) == MODE_V4SF)
2558         return "movaps\t{%1, %0|%0, %1}";
2559       else
2560         return "movss\t{%1, %0|%0, %1}";
2561     case 7: case 8:
2562       return "movss\t{%1, %0|%0, %1}";
2564     case 9: case 10:
2565     case 12: case 13: case 14: case 15:
2566       return "movd\t{%1, %0|%0, %1}";
2568     case 11:
2569       return "movq\t{%1, %0|%0, %1}";
2571     default:
2572       gcc_unreachable ();
2573     }
2575   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2576    (set (attr "mode")
2577         (cond [(eq_attr "alternative" "3,4,9,10")
2578                  (const_string "SI")
2579                (eq_attr "alternative" "5")
2580                  (if_then_else
2581                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2582                                  (const_int 0))
2583                              (ne (symbol_ref "TARGET_SSE2")
2584                                  (const_int 0)))
2585                         (eq (symbol_ref "optimize_size")
2586                             (const_int 0)))
2587                    (const_string "TI")
2588                    (const_string "V4SF"))
2589                /* For architectures resolving dependencies on
2590                   whole SSE registers use APS move to break dependency
2591                   chains, otherwise use short move to avoid extra work.
2593                   Do the same for architectures resolving dependencies on
2594                   the parts.  While in DF mode it is better to always handle
2595                   just register parts, the SF mode is different due to lack
2596                   of instructions to load just part of the register.  It is
2597                   better to maintain the whole registers in single format
2598                   to avoid problems on using packed logical operations.  */
2599                (eq_attr "alternative" "6")
2600                  (if_then_else
2601                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602                             (const_int 0))
2603                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2604                             (const_int 0)))
2605                    (const_string "V4SF")
2606                    (const_string "SF"))
2607                (eq_attr "alternative" "11")
2608                  (const_string "DI")]
2609                (const_string "SF")))])
2611 (define_insn "*swapsf"
2612   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2613         (match_operand:SF 1 "fp_register_operand" "+f"))
2614    (set (match_dup 1)
2615         (match_dup 0))]
2616   "reload_completed || TARGET_80387"
2618   if (STACK_TOP_P (operands[0]))
2619     return "fxch\t%1";
2620   else
2621     return "fxch\t%0";
2623   [(set_attr "type" "fxch")
2624    (set_attr "mode" "SF")])
2626 (define_expand "movdf"
2627   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2628         (match_operand:DF 1 "general_operand" ""))]
2629   ""
2630   "ix86_expand_move (DFmode, operands); DONE;")
2632 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2633 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2634 ;; On the average, pushdf using integers can be still shorter.  Allow this
2635 ;; pattern for optimize_size too.
2637 (define_insn "*pushdf_nointeger"
2638   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2639         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2640   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2642   /* This insn should be already split before reg-stack.  */
2643   gcc_unreachable ();
2645   [(set_attr "type" "multi")
2646    (set_attr "unit" "i387,*,*,*")
2647    (set_attr "mode" "DF,SI,SI,DF")])
2649 (define_insn "*pushdf_integer"
2650   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2651         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2652   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2654   /* This insn should be already split before reg-stack.  */
2655   gcc_unreachable ();
2657   [(set_attr "type" "multi")
2658    (set_attr "unit" "i387,*,*")
2659    (set_attr "mode" "DF,SI,DF")])
2661 ;; %%% Kill this when call knows how to work this out.
2662 (define_split
2663   [(set (match_operand:DF 0 "push_operand" "")
2664         (match_operand:DF 1 "any_fp_register_operand" ""))]
2665   "!TARGET_64BIT && reload_completed"
2666   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2667    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2668   "")
2670 (define_split
2671   [(set (match_operand:DF 0 "push_operand" "")
2672         (match_operand:DF 1 "any_fp_register_operand" ""))]
2673   "TARGET_64BIT && reload_completed"
2674   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2675    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2676   "")
2678 (define_split
2679   [(set (match_operand:DF 0 "push_operand" "")
2680         (match_operand:DF 1 "general_operand" ""))]
2681   "reload_completed"
2682   [(const_int 0)]
2683   "ix86_split_long_move (operands); DONE;")
2685 ;; Moving is usually shorter when only FP registers are used. This separate
2686 ;; movdf pattern avoids the use of integer registers for FP operations
2687 ;; when optimizing for size.
2689 (define_insn "*movdf_nointeger"
2690   [(set (match_operand:DF 0 "nonimmediate_operand"
2691                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2692         (match_operand:DF 1 "general_operand"
2693                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2694   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2695    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2696    && (reload_in_progress || reload_completed
2697        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2698        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2699            && !memory_operand (operands[0], DFmode)
2700            && standard_80387_constant_p (operands[1]))
2701        || GET_CODE (operands[1]) != CONST_DOUBLE
2702        || ((optimize_size
2703             || !TARGET_MEMORY_MISMATCH_STALL
2704             || reload_in_progress || reload_completed)
2705            && memory_operand (operands[0], DFmode)))"
2707   switch (which_alternative)
2708     {
2709     case 0:
2710     case 1:
2711       return output_387_reg_move (insn, operands);
2713     case 2:
2714       return standard_80387_constant_opcode (operands[1]);
2716     case 3:
2717     case 4:
2718       return "#";
2719     case 5:
2720       switch (get_attr_mode (insn))
2721         {
2722         case MODE_V4SF:
2723           return "xorps\t%0, %0";
2724         case MODE_V2DF:
2725           return "xorpd\t%0, %0";
2726         case MODE_TI:
2727           return "pxor\t%0, %0";
2728         default:
2729           gcc_unreachable ();
2730         }
2731     case 6:
2732     case 7:
2733     case 8:
2734       switch (get_attr_mode (insn))
2735         {
2736         case MODE_V4SF:
2737           return "movaps\t{%1, %0|%0, %1}";
2738         case MODE_V2DF:
2739           return "movapd\t{%1, %0|%0, %1}";
2740         case MODE_TI:
2741           return "movdqa\t{%1, %0|%0, %1}";
2742         case MODE_DI:
2743           return "movq\t{%1, %0|%0, %1}";
2744         case MODE_DF:
2745           return "movsd\t{%1, %0|%0, %1}";
2746         case MODE_V1DF:
2747           return "movlpd\t{%1, %0|%0, %1}";
2748         case MODE_V2SF:
2749           return "movlps\t{%1, %0|%0, %1}";
2750         default:
2751           gcc_unreachable ();
2752         }
2754     default:
2755       gcc_unreachable ();
2756     }
2758   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2759    (set (attr "mode")
2760         (cond [(eq_attr "alternative" "0,1,2")
2761                  (const_string "DF")
2762                (eq_attr "alternative" "3,4")
2763                  (const_string "SI")
2765                /* For SSE1, we have many fewer alternatives.  */
2766                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2767                  (cond [(eq_attr "alternative" "5,6")
2768                           (const_string "V4SF")
2769                        ]
2770                    (const_string "V2SF"))
2772                /* xorps is one byte shorter.  */
2773                (eq_attr "alternative" "5")
2774                  (cond [(ne (symbol_ref "optimize_size")
2775                             (const_int 0))
2776                           (const_string "V4SF")
2777                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2778                             (const_int 0))
2779                           (const_string "TI")
2780                        ]
2781                        (const_string "V2DF"))
2783                /* For architectures resolving dependencies on
2784                   whole SSE registers use APD move to break dependency
2785                   chains, otherwise use short move to avoid extra work.
2787                   movaps encodes one byte shorter.  */
2788                (eq_attr "alternative" "6")
2789                  (cond
2790                    [(ne (symbol_ref "optimize_size")
2791                         (const_int 0))
2792                       (const_string "V4SF")
2793                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2794                         (const_int 0))
2795                       (const_string "V2DF")
2796                    ]
2797                    (const_string "DF"))
2798                /* For architectures resolving dependencies on register
2799                   parts we may avoid extra work to zero out upper part
2800                   of register.  */
2801                (eq_attr "alternative" "7")
2802                  (if_then_else
2803                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2804                        (const_int 0))
2805                    (const_string "V1DF")
2806                    (const_string "DF"))
2807               ]
2808               (const_string "DF")))])
2810 (define_insn "*movdf_integer_rex64"
2811   [(set (match_operand:DF 0 "nonimmediate_operand"
2812                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2813         (match_operand:DF 1 "general_operand"
2814                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2815   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2816    && (reload_in_progress || reload_completed
2817        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2818        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2819            && standard_80387_constant_p (operands[1]))
2820        || GET_CODE (operands[1]) != CONST_DOUBLE
2821        || memory_operand (operands[0], DFmode))"
2823   switch (which_alternative)
2824     {
2825     case 0:
2826     case 1:
2827       return output_387_reg_move (insn, operands);
2829     case 2:
2830       return standard_80387_constant_opcode (operands[1]);
2832     case 3:
2833     case 4:
2834       return "#";
2836     case 5:
2837       switch (get_attr_mode (insn))
2838         {
2839         case MODE_V4SF:
2840           return "xorps\t%0, %0";
2841         case MODE_V2DF:
2842           return "xorpd\t%0, %0";
2843         case MODE_TI:
2844           return "pxor\t%0, %0";
2845         default:
2846           gcc_unreachable ();
2847         }
2848     case 6:
2849     case 7:
2850     case 8:
2851       switch (get_attr_mode (insn))
2852         {
2853         case MODE_V4SF:
2854           return "movaps\t{%1, %0|%0, %1}";
2855         case MODE_V2DF:
2856           return "movapd\t{%1, %0|%0, %1}";
2857         case MODE_TI:
2858           return "movdqa\t{%1, %0|%0, %1}";
2859         case MODE_DI:
2860           return "movq\t{%1, %0|%0, %1}";
2861         case MODE_DF:
2862           return "movsd\t{%1, %0|%0, %1}";
2863         case MODE_V1DF:
2864           return "movlpd\t{%1, %0|%0, %1}";
2865         case MODE_V2SF:
2866           return "movlps\t{%1, %0|%0, %1}";
2867         default:
2868           gcc_unreachable ();
2869         }
2871     case 9:
2872     case 10:
2873       return "movd\t{%1, %0|%0, %1}";
2875     default:
2876       gcc_unreachable();
2877     }
2879   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2880    (set (attr "mode")
2881         (cond [(eq_attr "alternative" "0,1,2")
2882                  (const_string "DF")
2883                (eq_attr "alternative" "3,4,9,10")
2884                  (const_string "DI")
2886                /* For SSE1, we have many fewer alternatives.  */
2887                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2888                  (cond [(eq_attr "alternative" "5,6")
2889                           (const_string "V4SF")
2890                        ]
2891                    (const_string "V2SF"))
2893                /* xorps is one byte shorter.  */
2894                (eq_attr "alternative" "5")
2895                  (cond [(ne (symbol_ref "optimize_size")
2896                             (const_int 0))
2897                           (const_string "V4SF")
2898                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2899                             (const_int 0))
2900                           (const_string "TI")
2901                        ]
2902                        (const_string "V2DF"))
2904                /* For architectures resolving dependencies on
2905                   whole SSE registers use APD move to break dependency
2906                   chains, otherwise use short move to avoid extra work.
2908                   movaps encodes one byte shorter.  */
2909                (eq_attr "alternative" "6")
2910                  (cond
2911                    [(ne (symbol_ref "optimize_size")
2912                         (const_int 0))
2913                       (const_string "V4SF")
2914                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2915                         (const_int 0))
2916                       (const_string "V2DF")
2917                    ]
2918                    (const_string "DF"))
2919                /* For architectures resolving dependencies on register
2920                   parts we may avoid extra work to zero out upper part
2921                   of register.  */
2922                (eq_attr "alternative" "7")
2923                  (if_then_else
2924                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2925                        (const_int 0))
2926                    (const_string "V1DF")
2927                    (const_string "DF"))
2928               ]
2929               (const_string "DF")))])
2931 (define_insn "*movdf_integer"
2932   [(set (match_operand:DF 0 "nonimmediate_operand"
2933                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2934         (match_operand:DF 1 "general_operand"
2935                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2936   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2937    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2938    && (reload_in_progress || reload_completed
2939        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2940        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2941            && standard_80387_constant_p (operands[1]))
2942        || GET_CODE (operands[1]) != CONST_DOUBLE
2943        || memory_operand (operands[0], DFmode))"
2945   switch (which_alternative)
2946     {
2947     case 0:
2948     case 1:
2949       return output_387_reg_move (insn, operands);
2951     case 2:
2952       return standard_80387_constant_opcode (operands[1]);
2954     case 3:
2955     case 4:
2956       return "#";
2958     case 5:
2959       switch (get_attr_mode (insn))
2960         {
2961         case MODE_V4SF:
2962           return "xorps\t%0, %0";
2963         case MODE_V2DF:
2964           return "xorpd\t%0, %0";
2965         case MODE_TI:
2966           return "pxor\t%0, %0";
2967         default:
2968           gcc_unreachable ();
2969         }
2970     case 6:
2971     case 7:
2972     case 8:
2973       switch (get_attr_mode (insn))
2974         {
2975         case MODE_V4SF:
2976           return "movaps\t{%1, %0|%0, %1}";
2977         case MODE_V2DF:
2978           return "movapd\t{%1, %0|%0, %1}";
2979         case MODE_TI:
2980           return "movdqa\t{%1, %0|%0, %1}";
2981         case MODE_DI:
2982           return "movq\t{%1, %0|%0, %1}";
2983         case MODE_DF:
2984           return "movsd\t{%1, %0|%0, %1}";
2985         case MODE_V1DF:
2986           return "movlpd\t{%1, %0|%0, %1}";
2987         case MODE_V2SF:
2988           return "movlps\t{%1, %0|%0, %1}";
2989         default:
2990           gcc_unreachable ();
2991         }
2993     default:
2994       gcc_unreachable();
2995     }
2997   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2998    (set (attr "mode")
2999         (cond [(eq_attr "alternative" "0,1,2")
3000                  (const_string "DF")
3001                (eq_attr "alternative" "3,4")
3002                  (const_string "SI")
3004                /* For SSE1, we have many fewer alternatives.  */
3005                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3006                  (cond [(eq_attr "alternative" "5,6")
3007                           (const_string "V4SF")
3008                        ]
3009                    (const_string "V2SF"))
3011                /* xorps is one byte shorter.  */
3012                (eq_attr "alternative" "5")
3013                  (cond [(ne (symbol_ref "optimize_size")
3014                             (const_int 0))
3015                           (const_string "V4SF")
3016                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3017                             (const_int 0))
3018                           (const_string "TI")
3019                        ]
3020                        (const_string "V2DF"))
3022                /* For architectures resolving dependencies on
3023                   whole SSE registers use APD move to break dependency
3024                   chains, otherwise use short move to avoid extra work.
3026                   movaps encodes one byte shorter.  */
3027                (eq_attr "alternative" "6")
3028                  (cond
3029                    [(ne (symbol_ref "optimize_size")
3030                         (const_int 0))
3031                       (const_string "V4SF")
3032                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3033                         (const_int 0))
3034                       (const_string "V2DF")
3035                    ]
3036                    (const_string "DF"))
3037                /* For architectures resolving dependencies on register
3038                   parts we may avoid extra work to zero out upper part
3039                   of register.  */
3040                (eq_attr "alternative" "7")
3041                  (if_then_else
3042                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3043                        (const_int 0))
3044                    (const_string "V1DF")
3045                    (const_string "DF"))
3046               ]
3047               (const_string "DF")))])
3049 (define_split
3050   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3051         (match_operand:DF 1 "general_operand" ""))]
3052   "reload_completed
3053    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3054    && ! (ANY_FP_REG_P (operands[0]) ||
3055          (GET_CODE (operands[0]) == SUBREG
3056           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3057    && ! (ANY_FP_REG_P (operands[1]) ||
3058          (GET_CODE (operands[1]) == SUBREG
3059           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3060   [(const_int 0)]
3061   "ix86_split_long_move (operands); DONE;")
3063 (define_insn "*swapdf"
3064   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3065         (match_operand:DF 1 "fp_register_operand" "+f"))
3066    (set (match_dup 1)
3067         (match_dup 0))]
3068   "reload_completed || TARGET_80387"
3070   if (STACK_TOP_P (operands[0]))
3071     return "fxch\t%1";
3072   else
3073     return "fxch\t%0";
3075   [(set_attr "type" "fxch")
3076    (set_attr "mode" "DF")])
3078 (define_expand "movxf"
3079   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3080         (match_operand:XF 1 "general_operand" ""))]
3081   ""
3082   "ix86_expand_move (XFmode, operands); DONE;")
3084 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3085 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3086 ;; Pushing using integer instructions is longer except for constants
3087 ;; and direct memory references.
3088 ;; (assuming that any given constant is pushed only once, but this ought to be
3089 ;;  handled elsewhere).
3091 (define_insn "*pushxf_nointeger"
3092   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3093         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3094   "optimize_size"
3096   /* This insn should be already split before reg-stack.  */
3097   gcc_unreachable ();
3099   [(set_attr "type" "multi")
3100    (set_attr "unit" "i387,*,*")
3101    (set_attr "mode" "XF,SI,SI")])
3103 (define_insn "*pushxf_integer"
3104   [(set (match_operand:XF 0 "push_operand" "=<,<")
3105         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3106   "!optimize_size"
3108   /* This insn should be already split before reg-stack.  */
3109   gcc_unreachable ();
3111   [(set_attr "type" "multi")
3112    (set_attr "unit" "i387,*")
3113    (set_attr "mode" "XF,SI")])
3115 (define_split
3116   [(set (match_operand 0 "push_operand" "")
3117         (match_operand 1 "general_operand" ""))]
3118   "reload_completed
3119    && (GET_MODE (operands[0]) == XFmode
3120        || GET_MODE (operands[0]) == DFmode)
3121    && !ANY_FP_REG_P (operands[1])"
3122   [(const_int 0)]
3123   "ix86_split_long_move (operands); DONE;")
3125 (define_split
3126   [(set (match_operand:XF 0 "push_operand" "")
3127         (match_operand:XF 1 "any_fp_register_operand" ""))]
3128   "!TARGET_64BIT"
3129   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3130    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3131   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3133 (define_split
3134   [(set (match_operand:XF 0 "push_operand" "")
3135         (match_operand:XF 1 "any_fp_register_operand" ""))]
3136   "TARGET_64BIT"
3137   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3138    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3139   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3141 ;; Do not use integer registers when optimizing for size
3142 (define_insn "*movxf_nointeger"
3143   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3144         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3145   "optimize_size
3146    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3147    && (reload_in_progress || reload_completed
3148        || (optimize_size && standard_80387_constant_p (operands[1]))
3149        || GET_CODE (operands[1]) != CONST_DOUBLE
3150        || memory_operand (operands[0], XFmode))"
3152   switch (which_alternative)
3153     {
3154     case 0:
3155     case 1:
3156       return output_387_reg_move (insn, operands);
3158     case 2:
3159       return standard_80387_constant_opcode (operands[1]);
3161     case 3: case 4:
3162       return "#";
3163     default:
3164       gcc_unreachable ();
3165     }
3167   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3168    (set_attr "mode" "XF,XF,XF,SI,SI")])
3170 (define_insn "*movxf_integer"
3171   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3172         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3173   "!optimize_size
3174    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3175    && (reload_in_progress || reload_completed
3176        || (optimize_size && standard_80387_constant_p (operands[1]))
3177        || GET_CODE (operands[1]) != CONST_DOUBLE
3178        || memory_operand (operands[0], XFmode))"
3180   switch (which_alternative)
3181     {
3182     case 0:
3183     case 1:
3184       return output_387_reg_move (insn, operands);
3186     case 2:
3187       return standard_80387_constant_opcode (operands[1]);
3189     case 3: case 4:
3190       return "#";
3192     default:
3193       gcc_unreachable ();
3194     }
3196   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3197    (set_attr "mode" "XF,XF,XF,SI,SI")])
3199 (define_expand "movtf"
3200   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201         (match_operand:TF 1 "nonimmediate_operand" ""))]
3202   "TARGET_64BIT"
3204   ix86_expand_move (TFmode, operands);
3205   DONE;
3208 (define_insn "*movtf_internal"
3209   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3210         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3211   "TARGET_64BIT
3212    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3214   switch (which_alternative)
3215     {
3216     case 0:
3217     case 1:
3218       if (get_attr_mode (insn) == MODE_V4SF)
3219         return "movaps\t{%1, %0|%0, %1}";
3220       else
3221         return "movdqa\t{%1, %0|%0, %1}";
3222     case 2:
3223       if (get_attr_mode (insn) == MODE_V4SF)
3224         return "xorps\t%0, %0";
3225       else
3226         return "pxor\t%0, %0";
3227     case 3:
3228     case 4:
3229         return "#";
3230     default:
3231       gcc_unreachable ();
3232     }
3234   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3235    (set (attr "mode")
3236         (cond [(eq_attr "alternative" "0,2")
3237                  (if_then_else
3238                    (ne (symbol_ref "optimize_size")
3239                        (const_int 0))
3240                    (const_string "V4SF")
3241                    (const_string "TI"))
3242                (eq_attr "alternative" "1")
3243                  (if_then_else
3244                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3245                             (const_int 0))
3246                         (ne (symbol_ref "optimize_size")
3247                             (const_int 0)))
3248                    (const_string "V4SF")
3249                    (const_string "TI"))]
3250                (const_string "DI")))])
3252 (define_split
3253   [(set (match_operand 0 "nonimmediate_operand" "")
3254         (match_operand 1 "general_operand" ""))]
3255   "reload_completed
3256    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3257    && GET_MODE (operands[0]) == XFmode
3258    && ! (ANY_FP_REG_P (operands[0]) ||
3259          (GET_CODE (operands[0]) == SUBREG
3260           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3261    && ! (ANY_FP_REG_P (operands[1]) ||
3262          (GET_CODE (operands[1]) == SUBREG
3263           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3264   [(const_int 0)]
3265   "ix86_split_long_move (operands); DONE;")
3267 (define_split
3268   [(set (match_operand 0 "register_operand" "")
3269         (match_operand 1 "memory_operand" ""))]
3270   "reload_completed
3271    && MEM_P (operands[1])
3272    && (GET_MODE (operands[0]) == TFmode
3273        || GET_MODE (operands[0]) == XFmode
3274        || GET_MODE (operands[0]) == SFmode
3275        || GET_MODE (operands[0]) == DFmode)
3276    && (operands[2] = find_constant_src (insn))"
3277   [(set (match_dup 0) (match_dup 2))]
3279   rtx c = operands[2];
3280   rtx r = operands[0];
3282   if (GET_CODE (r) == SUBREG)
3283     r = SUBREG_REG (r);
3285   if (SSE_REG_P (r))
3286     {
3287       if (!standard_sse_constant_p (c))
3288         FAIL;
3289     }
3290   else if (FP_REG_P (r))
3291     {
3292       if (!standard_80387_constant_p (c))
3293         FAIL;
3294     }
3295   else if (MMX_REG_P (r))
3296     FAIL;
3299 (define_split
3300   [(set (match_operand 0 "register_operand" "")
3301         (float_extend (match_operand 1 "memory_operand" "")))]
3302   "reload_completed
3303    && MEM_P (operands[1])
3304    && (GET_MODE (operands[0]) == TFmode
3305        || GET_MODE (operands[0]) == XFmode
3306        || GET_MODE (operands[0]) == SFmode
3307        || GET_MODE (operands[0]) == DFmode)
3308    && (operands[2] = find_constant_src (insn))"
3309   [(set (match_dup 0) (match_dup 2))]
3311   rtx c = operands[2];
3312   rtx r = operands[0];
3314   if (GET_CODE (r) == SUBREG)
3315     r = SUBREG_REG (r);
3317   if (SSE_REG_P (r))
3318     {
3319       if (!standard_sse_constant_p (c))
3320         FAIL;
3321     }
3322   else if (FP_REG_P (r))
3323     {
3324       if (!standard_80387_constant_p (c))
3325         FAIL;
3326     }
3327   else if (MMX_REG_P (r))
3328     FAIL;
3331 (define_insn "swapxf"
3332   [(set (match_operand:XF 0 "register_operand" "+f")
3333         (match_operand:XF 1 "register_operand" "+f"))
3334    (set (match_dup 1)
3335         (match_dup 0))]
3336   "TARGET_80387"
3338   if (STACK_TOP_P (operands[0]))
3339     return "fxch\t%1";
3340   else
3341     return "fxch\t%0";
3343   [(set_attr "type" "fxch")
3344    (set_attr "mode" "XF")])
3346 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3347 (define_split
3348   [(set (match_operand:X87MODEF 0 "register_operand" "")
3349         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3350   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3351    && (standard_80387_constant_p (operands[1]) == 8
3352        || standard_80387_constant_p (operands[1]) == 9)"
3353   [(set (match_dup 0)(match_dup 1))
3354    (set (match_dup 0)
3355         (neg:X87MODEF (match_dup 0)))]
3357   REAL_VALUE_TYPE r;
3359   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3360   if (real_isnegzero (&r))
3361     operands[1] = CONST0_RTX (<MODE>mode);
3362   else
3363     operands[1] = CONST1_RTX (<MODE>mode);
3366 (define_split
3367   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3368         (match_operand:TF 1 "general_operand" ""))]
3369   "reload_completed
3370    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3371   [(const_int 0)]
3372   "ix86_split_long_move (operands); DONE;")
3374 ;; Zero extension instructions
3376 (define_expand "zero_extendhisi2"
3377   [(set (match_operand:SI 0 "register_operand" "")
3378      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3379   ""
3381   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3382     {
3383       operands[1] = force_reg (HImode, operands[1]);
3384       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3385       DONE;
3386     }
3389 (define_insn "zero_extendhisi2_and"
3390   [(set (match_operand:SI 0 "register_operand" "=r")
3391      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3392    (clobber (reg:CC FLAGS_REG))]
3393   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3394   "#"
3395   [(set_attr "type" "alu1")
3396    (set_attr "mode" "SI")])
3398 (define_split
3399   [(set (match_operand:SI 0 "register_operand" "")
3400         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3401    (clobber (reg:CC FLAGS_REG))]
3402   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3403   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3404               (clobber (reg:CC FLAGS_REG))])]
3405   "")
3407 (define_insn "*zero_extendhisi2_movzwl"
3408   [(set (match_operand:SI 0 "register_operand" "=r")
3409      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3410   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3411   "movz{wl|x}\t{%1, %0|%0, %1}"
3412   [(set_attr "type" "imovx")
3413    (set_attr "mode" "SI")])
3415 (define_expand "zero_extendqihi2"
3416   [(parallel
3417     [(set (match_operand:HI 0 "register_operand" "")
3418        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3419      (clobber (reg:CC FLAGS_REG))])]
3420   ""
3421   "")
3423 (define_insn "*zero_extendqihi2_and"
3424   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3425      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3426    (clobber (reg:CC FLAGS_REG))]
3427   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3428   "#"
3429   [(set_attr "type" "alu1")
3430    (set_attr "mode" "HI")])
3432 (define_insn "*zero_extendqihi2_movzbw_and"
3433   [(set (match_operand:HI 0 "register_operand" "=r,r")
3434      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3435    (clobber (reg:CC FLAGS_REG))]
3436   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3437   "#"
3438   [(set_attr "type" "imovx,alu1")
3439    (set_attr "mode" "HI")])
3441 ; zero extend to SImode here to avoid partial register stalls
3442 (define_insn "*zero_extendqihi2_movzbl"
3443   [(set (match_operand:HI 0 "register_operand" "=r")
3444      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3445   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3446   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3447   [(set_attr "type" "imovx")
3448    (set_attr "mode" "SI")])
3450 ;; For the movzbw case strip only the clobber
3451 (define_split
3452   [(set (match_operand:HI 0 "register_operand" "")
3453         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3454    (clobber (reg:CC FLAGS_REG))]
3455   "reload_completed
3456    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3457    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3458   [(set (match_operand:HI 0 "register_operand" "")
3459         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3461 ;; When source and destination does not overlap, clear destination
3462 ;; first and then do the movb
3463 (define_split
3464   [(set (match_operand:HI 0 "register_operand" "")
3465         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3466    (clobber (reg:CC FLAGS_REG))]
3467   "reload_completed
3468    && ANY_QI_REG_P (operands[0])
3469    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3470    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3471   [(set (match_dup 0) (const_int 0))
3472    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3473   "operands[2] = gen_lowpart (QImode, operands[0]);")
3475 ;; Rest is handled by single and.
3476 (define_split
3477   [(set (match_operand:HI 0 "register_operand" "")
3478         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3479    (clobber (reg:CC FLAGS_REG))]
3480   "reload_completed
3481    && true_regnum (operands[0]) == true_regnum (operands[1])"
3482   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3483               (clobber (reg:CC FLAGS_REG))])]
3484   "")
3486 (define_expand "zero_extendqisi2"
3487   [(parallel
3488     [(set (match_operand:SI 0 "register_operand" "")
3489        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3490      (clobber (reg:CC FLAGS_REG))])]
3491   ""
3492   "")
3494 (define_insn "*zero_extendqisi2_and"
3495   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3496      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3497    (clobber (reg:CC FLAGS_REG))]
3498   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3499   "#"
3500   [(set_attr "type" "alu1")
3501    (set_attr "mode" "SI")])
3503 (define_insn "*zero_extendqisi2_movzbw_and"
3504   [(set (match_operand:SI 0 "register_operand" "=r,r")
3505      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3506    (clobber (reg:CC FLAGS_REG))]
3507   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3508   "#"
3509   [(set_attr "type" "imovx,alu1")
3510    (set_attr "mode" "SI")])
3512 (define_insn "*zero_extendqisi2_movzbw"
3513   [(set (match_operand:SI 0 "register_operand" "=r")
3514      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3515   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3516   "movz{bl|x}\t{%1, %0|%0, %1}"
3517   [(set_attr "type" "imovx")
3518    (set_attr "mode" "SI")])
3520 ;; For the movzbl case strip only the clobber
3521 (define_split
3522   [(set (match_operand:SI 0 "register_operand" "")
3523         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3524    (clobber (reg:CC FLAGS_REG))]
3525   "reload_completed
3526    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3527    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3528   [(set (match_dup 0)
3529         (zero_extend:SI (match_dup 1)))])
3531 ;; When source and destination does not overlap, clear destination
3532 ;; first and then do the movb
3533 (define_split
3534   [(set (match_operand:SI 0 "register_operand" "")
3535         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3536    (clobber (reg:CC FLAGS_REG))]
3537   "reload_completed
3538    && ANY_QI_REG_P (operands[0])
3539    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3540    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3541    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3542   [(set (match_dup 0) (const_int 0))
3543    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3544   "operands[2] = gen_lowpart (QImode, operands[0]);")
3546 ;; Rest is handled by single and.
3547 (define_split
3548   [(set (match_operand:SI 0 "register_operand" "")
3549         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3550    (clobber (reg:CC FLAGS_REG))]
3551   "reload_completed
3552    && true_regnum (operands[0]) == true_regnum (operands[1])"
3553   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3554               (clobber (reg:CC FLAGS_REG))])]
3555   "")
3557 ;; %%% Kill me once multi-word ops are sane.
3558 (define_expand "zero_extendsidi2"
3559   [(set (match_operand:DI 0 "register_operand" "")
3560      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3561   ""
3563   if (!TARGET_64BIT)
3564     {
3565       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3566       DONE;
3567     }
3570 (define_insn "zero_extendsidi2_32"
3571   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3572         (zero_extend:DI
3573          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3574    (clobber (reg:CC FLAGS_REG))]
3575   "!TARGET_64BIT"
3576   "@
3577    #
3578    #
3579    #
3580    movd\t{%1, %0|%0, %1}
3581    movd\t{%1, %0|%0, %1}
3582    movd\t{%1, %0|%0, %1}
3583    movd\t{%1, %0|%0, %1}"
3584   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3585    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3587 (define_insn "zero_extendsidi2_rex64"
3588   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3589      (zero_extend:DI
3590        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3591   "TARGET_64BIT"
3592   "@
3593    mov\t{%k1, %k0|%k0, %k1}
3594    #
3595    movd\t{%1, %0|%0, %1}
3596    movd\t{%1, %0|%0, %1}
3597    movd\t{%1, %0|%0, %1}
3598    movd\t{%1, %0|%0, %1}"
3599   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3600    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3602 (define_split
3603   [(set (match_operand:DI 0 "memory_operand" "")
3604      (zero_extend:DI (match_dup 0)))]
3605   "TARGET_64BIT"
3606   [(set (match_dup 4) (const_int 0))]
3607   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3609 (define_split
3610   [(set (match_operand:DI 0 "register_operand" "")
3611         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3612    (clobber (reg:CC FLAGS_REG))]
3613   "!TARGET_64BIT && reload_completed
3614    && true_regnum (operands[0]) == true_regnum (operands[1])"
3615   [(set (match_dup 4) (const_int 0))]
3616   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3618 (define_split
3619   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3620         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3621    (clobber (reg:CC FLAGS_REG))]
3622   "!TARGET_64BIT && reload_completed
3623    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3624   [(set (match_dup 3) (match_dup 1))
3625    (set (match_dup 4) (const_int 0))]
3626   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3628 (define_insn "zero_extendhidi2"
3629   [(set (match_operand:DI 0 "register_operand" "=r")
3630      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3631   "TARGET_64BIT"
3632   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3633   [(set_attr "type" "imovx")
3634    (set_attr "mode" "DI")])
3636 (define_insn "zero_extendqidi2"
3637   [(set (match_operand:DI 0 "register_operand" "=r")
3638      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3639   "TARGET_64BIT"
3640   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3641   [(set_attr "type" "imovx")
3642    (set_attr "mode" "DI")])
3644 ;; Sign extension instructions
3646 (define_expand "extendsidi2"
3647   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3648                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3649               (clobber (reg:CC FLAGS_REG))
3650               (clobber (match_scratch:SI 2 ""))])]
3651   ""
3653   if (TARGET_64BIT)
3654     {
3655       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3656       DONE;
3657     }
3660 (define_insn "*extendsidi2_1"
3661   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3662         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3663    (clobber (reg:CC FLAGS_REG))
3664    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3665   "!TARGET_64BIT"
3666   "#")
3668 (define_insn "extendsidi2_rex64"
3669   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3670         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3671   "TARGET_64BIT"
3672   "@
3673    {cltq|cdqe}
3674    movs{lq|x}\t{%1,%0|%0, %1}"
3675   [(set_attr "type" "imovx")
3676    (set_attr "mode" "DI")
3677    (set_attr "prefix_0f" "0")
3678    (set_attr "modrm" "0,1")])
3680 (define_insn "extendhidi2"
3681   [(set (match_operand:DI 0 "register_operand" "=r")
3682         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683   "TARGET_64BIT"
3684   "movs{wq|x}\t{%1,%0|%0, %1}"
3685   [(set_attr "type" "imovx")
3686    (set_attr "mode" "DI")])
3688 (define_insn "extendqidi2"
3689   [(set (match_operand:DI 0 "register_operand" "=r")
3690         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3691   "TARGET_64BIT"
3692   "movs{bq|x}\t{%1,%0|%0, %1}"
3693    [(set_attr "type" "imovx")
3694     (set_attr "mode" "DI")])
3696 ;; Extend to memory case when source register does die.
3697 (define_split
3698   [(set (match_operand:DI 0 "memory_operand" "")
3699         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3700    (clobber (reg:CC FLAGS_REG))
3701    (clobber (match_operand:SI 2 "register_operand" ""))]
3702   "(reload_completed
3703     && dead_or_set_p (insn, operands[1])
3704     && !reg_mentioned_p (operands[1], operands[0]))"
3705   [(set (match_dup 3) (match_dup 1))
3706    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3707               (clobber (reg:CC FLAGS_REG))])
3708    (set (match_dup 4) (match_dup 1))]
3709   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3711 ;; Extend to memory case when source register does not die.
3712 (define_split
3713   [(set (match_operand:DI 0 "memory_operand" "")
3714         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3715    (clobber (reg:CC FLAGS_REG))
3716    (clobber (match_operand:SI 2 "register_operand" ""))]
3717   "reload_completed"
3718   [(const_int 0)]
3720   split_di (&operands[0], 1, &operands[3], &operands[4]);
3722   emit_move_insn (operands[3], operands[1]);
3724   /* Generate a cltd if possible and doing so it profitable.  */
3725   if ((optimize_size || TARGET_USE_CLTD)
3726       && true_regnum (operands[1]) == AX_REG
3727       && true_regnum (operands[2]) == DX_REG)
3728     {
3729       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3730     }
3731   else
3732     {
3733       emit_move_insn (operands[2], operands[1]);
3734       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3735     }
3736   emit_move_insn (operands[4], operands[2]);
3737   DONE;
3740 ;; Extend to register case.  Optimize case where source and destination
3741 ;; registers match and cases where we can use cltd.
3742 (define_split
3743   [(set (match_operand:DI 0 "register_operand" "")
3744         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3745    (clobber (reg:CC FLAGS_REG))
3746    (clobber (match_scratch:SI 2 ""))]
3747   "reload_completed"
3748   [(const_int 0)]
3750   split_di (&operands[0], 1, &operands[3], &operands[4]);
3752   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3753     emit_move_insn (operands[3], operands[1]);
3755   /* Generate a cltd if possible and doing so it profitable.  */
3756   if ((optimize_size || TARGET_USE_CLTD)
3757       && true_regnum (operands[3]) == AX_REG)
3758     {
3759       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3760       DONE;
3761     }
3763   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3764     emit_move_insn (operands[4], operands[1]);
3766   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3767   DONE;
3770 (define_insn "extendhisi2"
3771   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3772         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3773   ""
3775   switch (get_attr_prefix_0f (insn))
3776     {
3777     case 0:
3778       return "{cwtl|cwde}";
3779     default:
3780       return "movs{wl|x}\t{%1,%0|%0, %1}";
3781     }
3783   [(set_attr "type" "imovx")
3784    (set_attr "mode" "SI")
3785    (set (attr "prefix_0f")
3786      ;; movsx is short decodable while cwtl is vector decoded.
3787      (if_then_else (and (eq_attr "cpu" "!k6")
3788                         (eq_attr "alternative" "0"))
3789         (const_string "0")
3790         (const_string "1")))
3791    (set (attr "modrm")
3792      (if_then_else (eq_attr "prefix_0f" "0")
3793         (const_string "0")
3794         (const_string "1")))])
3796 (define_insn "*extendhisi2_zext"
3797   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3798         (zero_extend:DI
3799           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3800   "TARGET_64BIT"
3802   switch (get_attr_prefix_0f (insn))
3803     {
3804     case 0:
3805       return "{cwtl|cwde}";
3806     default:
3807       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3808     }
3810   [(set_attr "type" "imovx")
3811    (set_attr "mode" "SI")
3812    (set (attr "prefix_0f")
3813      ;; movsx is short decodable while cwtl is vector decoded.
3814      (if_then_else (and (eq_attr "cpu" "!k6")
3815                         (eq_attr "alternative" "0"))
3816         (const_string "0")
3817         (const_string "1")))
3818    (set (attr "modrm")
3819      (if_then_else (eq_attr "prefix_0f" "0")
3820         (const_string "0")
3821         (const_string "1")))])
3823 (define_insn "extendqihi2"
3824   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3825         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3826   ""
3828   switch (get_attr_prefix_0f (insn))
3829     {
3830     case 0:
3831       return "{cbtw|cbw}";
3832     default:
3833       return "movs{bw|x}\t{%1,%0|%0, %1}";
3834     }
3836   [(set_attr "type" "imovx")
3837    (set_attr "mode" "HI")
3838    (set (attr "prefix_0f")
3839      ;; movsx is short decodable while cwtl is vector decoded.
3840      (if_then_else (and (eq_attr "cpu" "!k6")
3841                         (eq_attr "alternative" "0"))
3842         (const_string "0")
3843         (const_string "1")))
3844    (set (attr "modrm")
3845      (if_then_else (eq_attr "prefix_0f" "0")
3846         (const_string "0")
3847         (const_string "1")))])
3849 (define_insn "extendqisi2"
3850   [(set (match_operand:SI 0 "register_operand" "=r")
3851         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3852   ""
3853   "movs{bl|x}\t{%1,%0|%0, %1}"
3854    [(set_attr "type" "imovx")
3855     (set_attr "mode" "SI")])
3857 (define_insn "*extendqisi2_zext"
3858   [(set (match_operand:DI 0 "register_operand" "=r")
3859         (zero_extend:DI
3860           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3861   "TARGET_64BIT"
3862   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3863    [(set_attr "type" "imovx")
3864     (set_attr "mode" "SI")])
3866 ;; Conversions between float and double.
3868 ;; These are all no-ops in the model used for the 80387.  So just
3869 ;; emit moves.
3871 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3872 (define_insn "*dummy_extendsfdf2"
3873   [(set (match_operand:DF 0 "push_operand" "=<")
3874         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3875   "0"
3876   "#")
3878 (define_split
3879   [(set (match_operand:DF 0 "push_operand" "")
3880         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3881   "!TARGET_64BIT"
3882   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3883    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3885 (define_split
3886   [(set (match_operand:DF 0 "push_operand" "")
3887         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3888   "TARGET_64BIT"
3889   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3890    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3892 (define_insn "*dummy_extendsfxf2"
3893   [(set (match_operand:XF 0 "push_operand" "=<")
3894         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3895   "0"
3896   "#")
3898 (define_split
3899   [(set (match_operand:XF 0 "push_operand" "")
3900         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3901   ""
3902   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3903    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3904   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3906 (define_split
3907   [(set (match_operand:XF 0 "push_operand" "")
3908         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3909   "TARGET_64BIT"
3910   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3911    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3912   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3914 (define_split
3915   [(set (match_operand:XF 0 "push_operand" "")
3916         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3917   ""
3918   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3919    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3920   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3922 (define_split
3923   [(set (match_operand:XF 0 "push_operand" "")
3924         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3925   "TARGET_64BIT"
3926   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3927    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3928   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3930 (define_expand "extendsfdf2"
3931   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3932         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3933   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3935   /* ??? Needed for compress_float_constant since all fp constants
3936      are LEGITIMATE_CONSTANT_P.  */
3937   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3938     {
3939       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3940           && standard_80387_constant_p (operands[1]) > 0)
3941         {
3942           operands[1] = simplify_const_unary_operation
3943             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3944           emit_move_insn_1 (operands[0], operands[1]);
3945           DONE;
3946         }
3947       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3948     }
3951 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3952    cvtss2sd:
3953       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3954       cvtps2pd xmm2,xmm1
3955    We do the conversion post reload to avoid producing of 128bit spills
3956    that might lead to ICE on 32bit target.  The sequence unlikely combine
3957    anyway.  */
3958 (define_split
3959   [(set (match_operand:DF 0 "register_operand" "")
3960         (float_extend:DF
3961           (match_operand:SF 1 "nonimmediate_operand" "")))]
3962   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3963    && reload_completed && SSE_REG_P (operands[0])"
3964    [(set (match_dup 2)
3965          (float_extend:V2DF
3966            (vec_select:V2SF
3967              (match_dup 3)
3968              (parallel [(const_int 0) (const_int 1)]))))]
3970   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3971   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3972   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3973      Try to avoid move when unpacking can be done in source.  */
3974   if (REG_P (operands[1]))
3975     {
3976       /* If it is unsafe to overwrite upper half of source, we need
3977          to move to destination and unpack there.  */
3978       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3979            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3980           && true_regnum (operands[0]) != true_regnum (operands[1]))
3981         {
3982           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3983           emit_move_insn (tmp, operands[1]);
3984         }
3985       else
3986         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3987       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3988     }
3989   else
3990     emit_insn (gen_vec_setv4sf_0 (operands[3],
3991                                   CONST0_RTX (V4SFmode), operands[1]));
3994 (define_insn "*extendsfdf2_mixed"
3995   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3996         (float_extend:DF
3997           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3998   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4000   switch (which_alternative)
4001     {
4002     case 0:
4003     case 1:
4004       return output_387_reg_move (insn, operands);
4006     case 2:
4007       return "cvtss2sd\t{%1, %0|%0, %1}";
4009     default:
4010       gcc_unreachable ();
4011     }
4013   [(set_attr "type" "fmov,fmov,ssecvt")
4014    (set_attr "mode" "SF,XF,DF")])
4016 (define_insn "*extendsfdf2_sse"
4017   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4018         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4019   "TARGET_SSE2 && TARGET_SSE_MATH"
4020   "cvtss2sd\t{%1, %0|%0, %1}"
4021   [(set_attr "type" "ssecvt")
4022    (set_attr "mode" "DF")])
4024 (define_insn "*extendsfdf2_i387"
4025   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4026         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4027   "TARGET_80387"
4028   "* return output_387_reg_move (insn, operands);"
4029   [(set_attr "type" "fmov")
4030    (set_attr "mode" "SF,XF")])
4032 (define_expand "extend<mode>xf2"
4033   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4034         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4035   "TARGET_80387"
4037   /* ??? Needed for compress_float_constant since all fp constants
4038      are LEGITIMATE_CONSTANT_P.  */
4039   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4040     {
4041       if (standard_80387_constant_p (operands[1]) > 0)
4042         {
4043           operands[1] = simplify_const_unary_operation
4044             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4045           emit_move_insn_1 (operands[0], operands[1]);
4046           DONE;
4047         }
4048       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4049     }
4052 (define_insn "*extend<mode>xf2_i387"
4053   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4054         (float_extend:XF
4055           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4056   "TARGET_80387"
4057   "* return output_387_reg_move (insn, operands);"
4058   [(set_attr "type" "fmov")
4059    (set_attr "mode" "<MODE>,XF")])
4061 ;; %%% This seems bad bad news.
4062 ;; This cannot output into an f-reg because there is no way to be sure
4063 ;; of truncating in that case.  Otherwise this is just like a simple move
4064 ;; insn.  So we pretend we can output to a reg in order to get better
4065 ;; register preferencing, but we really use a stack slot.
4067 ;; Conversion from DFmode to SFmode.
4069 (define_expand "truncdfsf2"
4070   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4071         (float_truncate:SF
4072           (match_operand:DF 1 "nonimmediate_operand" "")))]
4073   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4075   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4076     ;
4077   else if (flag_unsafe_math_optimizations)
4078     ;
4079   else
4080     {
4081       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4082       rtx temp = assign_386_stack_local (SFmode, slot);
4083       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4084       DONE;
4085     }
4088 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4089    cvtsd2ss:
4090       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4091       cvtpd2ps xmm2,xmm1
4092    We do the conversion post reload to avoid producing of 128bit spills
4093    that might lead to ICE on 32bit target.  The sequence unlikely combine
4094    anyway.  */
4095 (define_split
4096   [(set (match_operand:SF 0 "register_operand" "")
4097         (float_truncate:SF
4098           (match_operand:DF 1 "nonimmediate_operand" "")))]
4099   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4100    && reload_completed && SSE_REG_P (operands[0])"
4101    [(set (match_dup 2)
4102          (vec_concat:V4SF
4103            (float_truncate:V2SF
4104              (match_dup 4))
4105            (match_dup 3)))]
4107   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4108   operands[3] = CONST0_RTX (V2SFmode);
4109   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4110   /* Use movsd for loading from memory, unpcklpd for registers.
4111      Try to avoid move when unpacking can be done in source, or SSE3
4112      movddup is available.  */
4113   if (REG_P (operands[1]))
4114     {
4115       if (!TARGET_SSE3
4116           && true_regnum (operands[0]) != true_regnum (operands[1])
4117           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4118               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4119         {
4120           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4121           emit_move_insn (tmp, operands[1]);
4122           operands[1] = tmp;
4123         }
4124       else if (!TARGET_SSE3)
4125         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4126       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4127     }
4128   else
4129     emit_insn (gen_sse2_loadlpd (operands[4],
4130                                  CONST0_RTX (V2DFmode), operands[1]));
4133 (define_expand "truncdfsf2_with_temp"
4134   [(parallel [(set (match_operand:SF 0 "" "")
4135                    (float_truncate:SF (match_operand:DF 1 "" "")))
4136               (clobber (match_operand:SF 2 "" ""))])]
4137   "")
4139 (define_insn "*truncdfsf_fast_mixed"
4140   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4141         (float_truncate:SF
4142           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4143   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4145   switch (which_alternative)
4146     {
4147     case 0:
4148     case 1:
4149       return output_387_reg_move (insn, operands);
4150     case 2:
4151       return "cvtsd2ss\t{%1, %0|%0, %1}";
4152     default:
4153       gcc_unreachable ();
4154     }
4156   [(set_attr "type" "fmov,fmov,ssecvt")
4157    (set_attr "mode" "SF")])
4159 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4160 ;; because nothing we do here is unsafe.
4161 (define_insn "*truncdfsf_fast_sse"
4162   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4163         (float_truncate:SF
4164           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4165   "TARGET_SSE2 && TARGET_SSE_MATH"
4166   "cvtsd2ss\t{%1, %0|%0, %1}"
4167   [(set_attr "type" "ssecvt")
4168    (set_attr "mode" "SF")])
4170 (define_insn "*truncdfsf_fast_i387"
4171   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4172         (float_truncate:SF
4173           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4174   "TARGET_80387 && flag_unsafe_math_optimizations"
4175   "* return output_387_reg_move (insn, operands);"
4176   [(set_attr "type" "fmov")
4177    (set_attr "mode" "SF")])
4179 (define_insn "*truncdfsf_mixed"
4180   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4181         (float_truncate:SF
4182           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4183    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4184   "TARGET_MIX_SSE_I387"
4186   switch (which_alternative)
4187     {
4188     case 0:
4189       return output_387_reg_move (insn, operands);
4191     case 1:
4192       return "#";
4193     case 2:
4194       return "cvtsd2ss\t{%1, %0|%0, %1}";
4195     default:
4196       gcc_unreachable ();
4197     }
4199   [(set_attr "type" "fmov,multi,ssecvt")
4200    (set_attr "unit" "*,i387,*")
4201    (set_attr "mode" "SF")])
4203 (define_insn "*truncdfsf_i387"
4204   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4205         (float_truncate:SF
4206           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4207    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4208   "TARGET_80387"
4210   switch (which_alternative)
4211     {
4212     case 0:
4213       return output_387_reg_move (insn, operands);
4215     case 1:
4216       return "#";
4217     default:
4218       gcc_unreachable ();
4219     }
4221   [(set_attr "type" "fmov,multi")
4222    (set_attr "unit" "*,i387")
4223    (set_attr "mode" "SF")])
4225 (define_insn "*truncdfsf2_i387_1"
4226   [(set (match_operand:SF 0 "memory_operand" "=m")
4227         (float_truncate:SF
4228           (match_operand:DF 1 "register_operand" "f")))]
4229   "TARGET_80387
4230    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4231    && !TARGET_MIX_SSE_I387"
4232   "* return output_387_reg_move (insn, operands);"
4233   [(set_attr "type" "fmov")
4234    (set_attr "mode" "SF")])
4236 (define_split
4237   [(set (match_operand:SF 0 "register_operand" "")
4238         (float_truncate:SF
4239          (match_operand:DF 1 "fp_register_operand" "")))
4240    (clobber (match_operand 2 "" ""))]
4241   "reload_completed"
4242   [(set (match_dup 2) (match_dup 1))
4243    (set (match_dup 0) (match_dup 2))]
4245   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4248 ;; Conversion from XFmode to {SF,DF}mode
4250 (define_expand "truncxf<mode>2"
4251   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4252                    (float_truncate:MODEF
4253                      (match_operand:XF 1 "register_operand" "")))
4254               (clobber (match_dup 2))])]
4255   "TARGET_80387"
4257   if (flag_unsafe_math_optimizations)
4258     {
4259       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4260       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4261       if (reg != operands[0])
4262         emit_move_insn (operands[0], reg);
4263       DONE;
4264     }
4265   else
4266     {
4267       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4268       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4269     }
4272 (define_insn "*truncxfsf2_mixed"
4273   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4274         (float_truncate:SF
4275           (match_operand:XF 1 "register_operand" "f,f")))
4276    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4277   "TARGET_80387"
4279   gcc_assert (!which_alternative);
4280   return output_387_reg_move (insn, operands);
4282   [(set_attr "type" "fmov,multi")
4283    (set_attr "unit" "*,i387")
4284    (set_attr "mode" "SF")])
4286 (define_insn "*truncxfdf2_mixed"
4287   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4288         (float_truncate:DF
4289           (match_operand:XF 1 "register_operand" "f,f")))
4290    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4291   "TARGET_80387"
4293   gcc_assert (!which_alternative);
4294   return output_387_reg_move (insn, operands);
4296   [(set_attr "type" "fmov,multi")
4297    (set_attr "unit" "*,i387")
4298    (set_attr "mode" "DF")])
4300 (define_insn "truncxf<mode>2_i387_noop"
4301   [(set (match_operand:MODEF 0 "register_operand" "=f")
4302         (float_truncate:MODEF
4303           (match_operand:XF 1 "register_operand" "f")))]
4304   "TARGET_80387 && flag_unsafe_math_optimizations"
4305   "* return output_387_reg_move (insn, operands);"
4306   [(set_attr "type" "fmov")
4307    (set_attr "mode" "<MODE>")])
4309 (define_insn "*truncxf<mode>2_i387"
4310   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4311         (float_truncate:MODEF
4312           (match_operand:XF 1 "register_operand" "f")))]
4313   "TARGET_80387"
4314   "* return output_387_reg_move (insn, operands);"
4315   [(set_attr "type" "fmov")
4316    (set_attr "mode" "<MODE>")])
4318 (define_split
4319   [(set (match_operand:MODEF 0 "register_operand" "")
4320         (float_truncate:MODEF
4321           (match_operand:XF 1 "register_operand" "")))
4322    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4323   "TARGET_80387 && reload_completed"
4324   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4325    (set (match_dup 0) (match_dup 2))]
4326   "")
4328 (define_split
4329   [(set (match_operand:MODEF 0 "memory_operand" "")
4330         (float_truncate:MODEF
4331           (match_operand:XF 1 "register_operand" "")))
4332    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4333   "TARGET_80387"
4334   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4335   "")
4337 ;; Signed conversion to DImode.
4339 (define_expand "fix_truncxfdi2"
4340   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4341                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4342               (clobber (reg:CC FLAGS_REG))])]
4343   "TARGET_80387"
4345   if (TARGET_FISTTP)
4346    {
4347      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4348      DONE;
4349    }
4352 (define_expand "fix_trunc<mode>di2"
4353   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4354                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4355               (clobber (reg:CC FLAGS_REG))])]
4356   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4358   if (TARGET_FISTTP
4359       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4360    {
4361      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4362      DONE;
4363    }
4364   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4365    {
4366      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4367      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4368      if (out != operands[0])
4369         emit_move_insn (operands[0], out);
4370      DONE;
4371    }
4374 ;; Signed conversion to SImode.
4376 (define_expand "fix_truncxfsi2"
4377   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4378                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4379               (clobber (reg:CC FLAGS_REG))])]
4380   "TARGET_80387"
4382   if (TARGET_FISTTP)
4383    {
4384      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4385      DONE;
4386    }
4389 (define_expand "fix_trunc<mode>si2"
4390   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4391                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4392               (clobber (reg:CC FLAGS_REG))])]
4393   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4395   if (TARGET_FISTTP
4396       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4397    {
4398      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4399      DONE;
4400    }
4401   if (SSE_FLOAT_MODE_P (<MODE>mode))
4402    {
4403      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4404      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4405      if (out != operands[0])
4406         emit_move_insn (operands[0], out);
4407      DONE;
4408    }
4411 ;; Signed conversion to HImode.
4413 (define_expand "fix_trunc<mode>hi2"
4414   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4415                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4416               (clobber (reg:CC FLAGS_REG))])]
4417   "TARGET_80387
4418    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4420   if (TARGET_FISTTP)
4421    {
4422      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4423      DONE;
4424    }
4427 ;; Unsigned conversion to SImode.
4429 (define_expand "fixuns_trunc<mode>si2"
4430   [(parallel
4431     [(set (match_operand:SI 0 "register_operand" "")
4432           (unsigned_fix:SI
4433             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4434      (use (match_dup 2))
4435      (clobber (match_scratch:<ssevecmode> 3 ""))
4436      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4437   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4439   enum machine_mode mode = <MODE>mode;
4440   enum machine_mode vecmode = <ssevecmode>mode;
4441   REAL_VALUE_TYPE TWO31r;
4442   rtx two31;
4444   real_ldexp (&TWO31r, &dconst1, 31);
4445   two31 = const_double_from_real_value (TWO31r, mode);
4446   two31 = ix86_build_const_vector (mode, true, two31);
4447   operands[2] = force_reg (vecmode, two31);
4450 (define_insn_and_split "*fixuns_trunc<mode>_1"
4451   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4452         (unsigned_fix:SI
4453           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4454    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4455    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4456    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4457   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4458   "#"
4459   "&& reload_completed"
4460   [(const_int 0)]
4462   ix86_split_convert_uns_si_sse (operands);
4463   DONE;
4466 ;; Unsigned conversion to HImode.
4467 ;; Without these patterns, we'll try the unsigned SI conversion which
4468 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4470 (define_expand "fixuns_trunc<mode>hi2"
4471   [(set (match_dup 2)
4472         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4473    (set (match_operand:HI 0 "nonimmediate_operand" "")
4474         (subreg:HI (match_dup 2) 0))]
4475   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4476   "operands[2] = gen_reg_rtx (SImode);")
4478 ;; When SSE is available, it is always faster to use it!
4479 (define_insn "fix_trunc<mode>di_sse"
4480   [(set (match_operand:DI 0 "register_operand" "=r,r")
4481         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4482   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4483    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4484   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4485   [(set_attr "type" "sseicvt")
4486    (set_attr "mode" "<MODE>")
4487    (set_attr "athlon_decode" "double,vector")
4488    (set_attr "amdfam10_decode" "double,double")])
4490 (define_insn "fix_trunc<mode>si_sse"
4491   [(set (match_operand:SI 0 "register_operand" "=r,r")
4492         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4493   "SSE_FLOAT_MODE_P (<MODE>mode)
4494    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4495   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4496   [(set_attr "type" "sseicvt")
4497    (set_attr "mode" "<MODE>")
4498    (set_attr "athlon_decode" "double,vector")
4499    (set_attr "amdfam10_decode" "double,double")])
4501 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4502 (define_peephole2
4503   [(set (match_operand:MODEF 0 "register_operand" "")
4504         (match_operand:MODEF 1 "memory_operand" ""))
4505    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4506         (fix:SSEMODEI24 (match_dup 0)))]
4507   "TARGET_SHORTEN_X87_SSE
4508    && peep2_reg_dead_p (2, operands[0])"
4509   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4510   "")
4512 ;; Avoid vector decoded forms of the instruction.
4513 (define_peephole2
4514   [(match_scratch:DF 2 "Y2")
4515    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4516         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4517   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4518   [(set (match_dup 2) (match_dup 1))
4519    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4520   "")
4522 (define_peephole2
4523   [(match_scratch:SF 2 "x")
4524    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4525         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4526   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4527   [(set (match_dup 2) (match_dup 1))
4528    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4529   "")
4531 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4532   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4533         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4534   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4535    && TARGET_FISTTP
4536    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4537          && (TARGET_64BIT || <MODE>mode != DImode))
4538         && TARGET_SSE_MATH)
4539    && !(reload_completed || reload_in_progress)"
4540   "#"
4541   "&& 1"
4542   [(const_int 0)]
4544   if (memory_operand (operands[0], VOIDmode))
4545     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4546   else
4547     {
4548       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4549       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4550                                                             operands[1],
4551                                                             operands[2]));
4552     }
4553   DONE;
4555   [(set_attr "type" "fisttp")
4556    (set_attr "mode" "<MODE>")])
4558 (define_insn "fix_trunc<mode>_i387_fisttp"
4559   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4560         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4561    (clobber (match_scratch:XF 2 "=&1f"))]
4562   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563    && TARGET_FISTTP
4564    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4565          && (TARGET_64BIT || <MODE>mode != DImode))
4566         && TARGET_SSE_MATH)"
4567   "* return output_fix_trunc (insn, operands, 1);"
4568   [(set_attr "type" "fisttp")
4569    (set_attr "mode" "<MODE>")])
4571 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4572   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4573         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4574    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4575    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4576   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4577    && TARGET_FISTTP
4578    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4579         && (TARGET_64BIT || <MODE>mode != DImode))
4580         && TARGET_SSE_MATH)"
4581   "#"
4582   [(set_attr "type" "fisttp")
4583    (set_attr "mode" "<MODE>")])
4585 (define_split
4586   [(set (match_operand:X87MODEI 0 "register_operand" "")
4587         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4588    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4589    (clobber (match_scratch 3 ""))]
4590   "reload_completed"
4591   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4592               (clobber (match_dup 3))])
4593    (set (match_dup 0) (match_dup 2))]
4594   "")
4596 (define_split
4597   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4598         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4599    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4600    (clobber (match_scratch 3 ""))]
4601   "reload_completed"
4602   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4603               (clobber (match_dup 3))])]
4604   "")
4606 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4607 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4608 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4609 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4610 ;; function in i386.c.
4611 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4612   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4613         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4614    (clobber (reg:CC FLAGS_REG))]
4615   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616    && !TARGET_FISTTP
4617    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4618          && (TARGET_64BIT || <MODE>mode != DImode))
4619    && !(reload_completed || reload_in_progress)"
4620   "#"
4621   "&& 1"
4622   [(const_int 0)]
4624   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4626   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4627   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4628   if (memory_operand (operands[0], VOIDmode))
4629     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4630                                          operands[2], operands[3]));
4631   else
4632     {
4633       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4634       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4635                                                      operands[2], operands[3],
4636                                                      operands[4]));
4637     }
4638   DONE;
4640   [(set_attr "type" "fistp")
4641    (set_attr "i387_cw" "trunc")
4642    (set_attr "mode" "<MODE>")])
4644 (define_insn "fix_truncdi_i387"
4645   [(set (match_operand:DI 0 "memory_operand" "=m")
4646         (fix:DI (match_operand 1 "register_operand" "f")))
4647    (use (match_operand:HI 2 "memory_operand" "m"))
4648    (use (match_operand:HI 3 "memory_operand" "m"))
4649    (clobber (match_scratch:XF 4 "=&1f"))]
4650   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4651    && !TARGET_FISTTP
4652    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4653   "* return output_fix_trunc (insn, operands, 0);"
4654   [(set_attr "type" "fistp")
4655    (set_attr "i387_cw" "trunc")
4656    (set_attr "mode" "DI")])
4658 (define_insn "fix_truncdi_i387_with_temp"
4659   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4660         (fix:DI (match_operand 1 "register_operand" "f,f")))
4661    (use (match_operand:HI 2 "memory_operand" "m,m"))
4662    (use (match_operand:HI 3 "memory_operand" "m,m"))
4663    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4664    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4665   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4666    && !TARGET_FISTTP
4667    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4668   "#"
4669   [(set_attr "type" "fistp")
4670    (set_attr "i387_cw" "trunc")
4671    (set_attr "mode" "DI")])
4673 (define_split
4674   [(set (match_operand:DI 0 "register_operand" "")
4675         (fix:DI (match_operand 1 "register_operand" "")))
4676    (use (match_operand:HI 2 "memory_operand" ""))
4677    (use (match_operand:HI 3 "memory_operand" ""))
4678    (clobber (match_operand:DI 4 "memory_operand" ""))
4679    (clobber (match_scratch 5 ""))]
4680   "reload_completed"
4681   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4682               (use (match_dup 2))
4683               (use (match_dup 3))
4684               (clobber (match_dup 5))])
4685    (set (match_dup 0) (match_dup 4))]
4686   "")
4688 (define_split
4689   [(set (match_operand:DI 0 "memory_operand" "")
4690         (fix:DI (match_operand 1 "register_operand" "")))
4691    (use (match_operand:HI 2 "memory_operand" ""))
4692    (use (match_operand:HI 3 "memory_operand" ""))
4693    (clobber (match_operand:DI 4 "memory_operand" ""))
4694    (clobber (match_scratch 5 ""))]
4695   "reload_completed"
4696   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4697               (use (match_dup 2))
4698               (use (match_dup 3))
4699               (clobber (match_dup 5))])]
4700   "")
4702 (define_insn "fix_trunc<mode>_i387"
4703   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4704         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4705    (use (match_operand:HI 2 "memory_operand" "m"))
4706    (use (match_operand:HI 3 "memory_operand" "m"))]
4707   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4708    && !TARGET_FISTTP
4709    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4710   "* return output_fix_trunc (insn, operands, 0);"
4711   [(set_attr "type" "fistp")
4712    (set_attr "i387_cw" "trunc")
4713    (set_attr "mode" "<MODE>")])
4715 (define_insn "fix_trunc<mode>_i387_with_temp"
4716   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4717         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4718    (use (match_operand:HI 2 "memory_operand" "m,m"))
4719    (use (match_operand:HI 3 "memory_operand" "m,m"))
4720    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4721   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4722    && !TARGET_FISTTP
4723    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4724   "#"
4725   [(set_attr "type" "fistp")
4726    (set_attr "i387_cw" "trunc")
4727    (set_attr "mode" "<MODE>")])
4729 (define_split
4730   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4731         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4732    (use (match_operand:HI 2 "memory_operand" ""))
4733    (use (match_operand:HI 3 "memory_operand" ""))
4734    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4735   "reload_completed"
4736   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4737               (use (match_dup 2))
4738               (use (match_dup 3))])
4739    (set (match_dup 0) (match_dup 4))]
4740   "")
4742 (define_split
4743   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4744         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4745    (use (match_operand:HI 2 "memory_operand" ""))
4746    (use (match_operand:HI 3 "memory_operand" ""))
4747    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4748   "reload_completed"
4749   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4750               (use (match_dup 2))
4751               (use (match_dup 3))])]
4752   "")
4754 (define_insn "x86_fnstcw_1"
4755   [(set (match_operand:HI 0 "memory_operand" "=m")
4756         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4757   "TARGET_80387"
4758   "fnstcw\t%0"
4759   [(set_attr "length" "2")
4760    (set_attr "mode" "HI")
4761    (set_attr "unit" "i387")])
4763 (define_insn "x86_fldcw_1"
4764   [(set (reg:HI FPCR_REG)
4765         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4766   "TARGET_80387"
4767   "fldcw\t%0"
4768   [(set_attr "length" "2")
4769    (set_attr "mode" "HI")
4770    (set_attr "unit" "i387")
4771    (set_attr "athlon_decode" "vector")
4772    (set_attr "amdfam10_decode" "vector")])
4774 ;; Conversion between fixed point and floating point.
4776 ;; Even though we only accept memory inputs, the backend _really_
4777 ;; wants to be able to do this between registers.
4779 (define_expand "floathi<mode>2"
4780   [(set (match_operand:MODEF 0 "register_operand" "")
4781         (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4782   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4784   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4785     {
4786       emit_insn
4787         (gen_floatsi<mode>2 (operands[0],
4788                              convert_to_mode (SImode, operands[1], 0)));
4789       DONE;
4790     }
4793 (define_insn "*floathi<mode>2_i387"
4794   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4795         (float:MODEF
4796           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4797   "TARGET_80387
4798    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4799        || TARGET_MIX_SSE_I387)"
4800   "@
4801    fild%z1\t%1
4802    #"
4803   [(set_attr "type" "fmov,multi")
4804    (set_attr "mode" "<MODE>")
4805    (set_attr "unit" "*,i387")
4806    (set_attr "fp_int_src" "true")])
4808 (define_expand "floatsi<mode>2"
4809   [(set (match_operand:MODEF 0 "register_operand" "")
4810         (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4811   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4812   "
4813    /* When we use vector converts, we can't have input in memory.  */
4814    if (GET_MODE (operands[0]) == DFmode
4815        && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4816        && SSE_FLOAT_MODE_P (DFmode))
4817      operands[1] = force_reg (SImode, operands[1]);
4818    else if (GET_MODE (operands[0]) == SFmode
4819             && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4820             && SSE_FLOAT_MODE_P (SFmode))
4821      {
4822        /* When !flag_trapping_math, we handle SImode->SFmode vector
4823           conversions same way as SImode->DFmode.
4825           For flat_trapping_math we can't safely use vector conversion without
4826           clearing upper half, otherwise precision exception might occur.
4827           However we can still generate the common sequence converting value
4828           from general register to XMM register as:
4830             mov         reg32, mem32
4831             movd        mem32, xmm
4832             cvtdq2pd xmm,xmm
4834           because we know that movd clears the upper half.
4836           Sadly in this case we can't rely on reload moving the value to XMM
4837           register, since we need to know if upper half is OK, so we need
4838           to do reloading by hand.  We force operand to memory unless target
4839           supports inter unit moves.  */
4840        if (!flag_trapping_math)
4841          operands[1] = force_reg (SImode, operands[1]);
4842        else if (!MEM_P (operands[1]))
4843          {
4844            int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4845            rtx tmp = assign_386_stack_local (SImode, slot);
4846            emit_move_insn (tmp, operands[1]);
4847            operands[1] = tmp;
4848          }
4849      }
4850    /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4851       !TARGET_INTER_UNIT_CONVERSIONS
4852       It is necessary for the patterns to not accept nonmemory operands
4853       as we would optimize out later.  */
4854    else if (!TARGET_INTER_UNIT_CONVERSIONS
4855             && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4856             && !optimize_size
4857             && !MEM_P (operands[1]))
4858      {
4859        int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4860        rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4861        emit_move_insn (tmp, operands[1]);
4862        operands[1] = tmp;
4863      }
4864   ")
4866 (define_insn "*floatsisf2_mixed_vector"
4867   [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4868         (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4869   "TARGET_MIX_SSE_I387 && !flag_trapping_math
4870    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4871   "@
4872    cvtdq2ps\t{%1, %0|%0, %1}
4873    fild%z1\t%1
4874    #"
4875   [(set_attr "type" "sseicvt,fmov,multi")
4876    (set_attr "mode" "SF")
4877    (set_attr "unit" "*,i387,*")
4878    (set_attr "athlon_decode" "double,*,*")
4879    (set_attr "amdfam10_decode" "double,*,*")
4880    (set_attr "fp_int_src" "false,true,true")])
4882 (define_insn "*floatsisf2_mixed"
4883   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4884         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4885   "TARGET_MIX_SSE_I387
4886    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4887        || optimize_size)"
4888   "@
4889    fild%z1\t%1
4890    #
4891    cvtsi2ss\t{%1, %0|%0, %1}
4892    cvtsi2ss\t{%1, %0|%0, %1}"
4893   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4894    (set_attr "mode" "SF")
4895    (set_attr "unit" "*,i387,*,*")
4896    (set_attr "athlon_decode" "*,*,vector,double")
4897    (set_attr "amdfam10_decode" "*,*,vector,double")
4898    (set_attr "fp_int_src" "true")])
4900 (define_insn "*floatsisf2_mixed_memory"
4901   [(set (match_operand:SF 0 "register_operand" "=f,x")
4902         (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4903   "TARGET_MIX_SSE_I387
4904    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4905   "@
4906    fild%z1\t%1
4907    cvtsi2ss\t{%1, %0|%0, %1}"
4908   [(set_attr "type" "fmov,sseicvt")
4909    (set_attr "mode" "SF")
4910    (set_attr "athlon_decode" "*,double")
4911    (set_attr "amdfam10_decode" "*,double")
4912    (set_attr "fp_int_src" "true")])
4914 (define_insn "*floatsisf2_sse_vector_nointernunit"
4915   [(set (match_operand:SF 0 "register_operand" "=x")
4916         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4917   "TARGET_SSE_MATH && flag_trapping_math
4918    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4919    && !TARGET_INTER_UNIT_MOVES"
4920   "#"
4921   [(set_attr "type" "multi")])
4923 (define_insn "*floatsisf2_sse_vector_internunit"
4924   [(set (match_operand:SF 0 "register_operand" "=x,x")
4925         (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4926   "TARGET_SSE_MATH && flag_trapping_math
4927    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4928    && TARGET_INTER_UNIT_MOVES"
4929   "#"
4930   [(set_attr "type" "multi")])
4932 (define_split
4933   [(set (match_operand:SF 0 "register_operand" "")
4934         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4935   "flag_trapping_math
4936    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4937    && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4938    && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4939   [(set (match_dup 0)
4940         (float:V4SF (match_dup 2)))]
4942   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4943   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4944   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4947 (define_split
4948   [(set (match_operand:SF 0 "register_operand" "")
4949         (float:SF (match_operand:SI 1 "register_operand" "")))]
4950   "flag_trapping_math
4951    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4952    && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4953   [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4954    (set (match_dup 0)
4955         (float:V4SF (match_dup 2)))]
4957   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4958   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4961 (define_insn "*floatsisf2_sse_vector"
4962   [(set (match_operand:SF 0 "register_operand" "=x")
4963         (float:SF (match_operand:SI 1 "register_operand" "x")))]
4964   "TARGET_SSE_MATH && !flag_trapping_math
4965    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4966    && !TARGET_INTER_UNIT_MOVES"
4967   "cvtdq2ps\t{%1, %0|%0, %1}"
4968   [(set_attr "type" "sseicvt")
4969    (set_attr "mode" "SF")
4970    (set_attr "athlon_decode" "double")
4971    (set_attr "amdfam10_decode" "double")
4972    (set_attr "fp_int_src" "true")])
4974 (define_insn "*floatsisf2_sse"
4975   [(set (match_operand:SF 0 "register_operand" "=x,x")
4976         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4977   "TARGET_SSE_MATH
4978    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4979        || optimize_size)"
4980   "cvtsi2ss\t{%1, %0|%0, %1}"
4981   [(set_attr "type" "sseicvt")
4982    (set_attr "mode" "SF")
4983    (set_attr "athlon_decode" "vector,double")
4984    (set_attr "amdfam10_decode" "vector,double")
4985    (set_attr "fp_int_src" "true")])
4987 (define_insn "*floatsisf2_sse_memory"
4988   [(set (match_operand:SF 0 "register_operand" "=x")
4989         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4990   "TARGET_SSE_MATH
4991    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4992   "cvtsi2ss\t{%1, %0|%0, %1}"
4993   [(set_attr "type" "sseicvt")
4994    (set_attr "mode" "SF")
4995    (set_attr "athlon_decode" "double")
4996    (set_attr "amdfam10_decode" "double")
4997    (set_attr "fp_int_src" "true")])
4999 (define_insn "*floatsidf2_mixed_vector"
5000   [(set (match_operand:DF 0 "register_operand" "=x,f,f")
5001         (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
5002   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5003    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5004   "@
5005    cvtdq2pd\t{%1, %0|%0, %1}
5006    fild%z1\t%1
5007    #"
5008   [(set_attr "type" "sseicvt,fmov,multi")
5009    (set_attr "mode" "V2DF,DF,DF")
5010    (set_attr "unit" "*,*,i387")
5011    (set_attr "athlon_decode" "double,*,*")
5012    (set_attr "amdfam10_decode" "double,*,*")
5013    (set_attr "fp_int_src" "false,true,true")])
5015 (define_insn "*floatsidf2_mixed"
5016   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5017         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5018   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5019    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5020        || optimize_size)"
5021   "@
5022    fild%z1\t%1
5023    #
5024    cvtsi2sd\t{%1, %0|%0, %1}
5025    cvtsi2sd\t{%1, %0|%0, %1}
5026    cvtdq2pd\t{%1, %0|%0, %1}"
5027   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5028    (set_attr "mode" "DF,DF,DF,DF,V2DF")
5029    (set_attr "unit" "*,i387,*,*,*")
5030    (set_attr "athlon_decode" "*,*,double,direct,double")
5031    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5032    (set_attr "fp_int_src" "true,true,true,true,false")])
5034 (define_insn "*floatsidf2_mixed_memory"
5035   [(set (match_operand:DF 0 "register_operand" "=f,x")
5036         (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5037   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5038    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5039   "@
5040    fild%z1\t%1
5041    cvtsi2sd\t{%1, %0|%0, %1}"
5042   [(set_attr "type" "fmov,sseicvt")
5043    (set_attr "mode" "DF")
5044    (set_attr "athlon_decode" "*,direct")
5045    (set_attr "amdfam10_decode" "*,double")
5046    (set_attr "fp_int_src" "true")])
5048 (define_insn "*floatsidf2_sse_vector"
5049   [(set (match_operand:DF 0 "register_operand" "=x")
5050         (float:DF (match_operand:SI 1 "register_operand" "x")))]
5051   "TARGET_SSE2 && TARGET_SSE_MATH
5052    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5053   "cvtdq2pd\t{%1, %0|%0, %1}"
5054   [(set_attr "type" "sseicvt")
5055    (set_attr "mode" "V2DF")
5056    (set_attr "athlon_decode" "double")
5057    (set_attr "amdfam10_decode" "double")
5058    (set_attr "fp_int_src" "true")])
5060 (define_split
5061   [(set (match_operand:DF 0 "register_operand" "")
5062         (float:DF (match_operand:SI 1 "memory_operand" "")))]
5063   "TARGET_USE_VECTOR_CONVERTS && reload_completed
5064    && SSE_REG_P (operands[0])"
5065   [(set (match_dup 0)
5066         (float:V2DF
5067           (vec_select:V2SI
5068             (match_dup 2)
5069             (parallel [(const_int 0) (const_int 1)]))))]
5071   operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5072   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5073   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5076 (define_insn "*floatsidf2_sse"
5077   [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5078         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5079   "TARGET_SSE2 && TARGET_SSE_MATH
5080    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5081        || optimize_size)"
5082   "@
5083    cvtsi2sd\t{%1, %0|%0, %1}
5084    cvtsi2sd\t{%1, %0|%0, %1}
5085    cvtdq2pd\t{%1, %0|%0, %1}"
5086   [(set_attr "type" "sseicvt")
5087    (set_attr "mode" "DF,DF,V2DF")
5088    (set_attr "athlon_decode" "double,direct,double")
5089    (set_attr "amdfam10_decode" "vector,double,double")
5090    (set_attr "fp_int_src" "true")])
5092 (define_insn "*floatsidf2_memory"
5093   [(set (match_operand:DF 0 "register_operand" "=x")
5094         (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5095   "TARGET_SSE2 && TARGET_SSE_MATH
5096    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5097        || optimize_size)"
5098   "cvtsi2sd\t{%1, %0|%0, %1}"
5099   [(set_attr "type" "sseicvt")
5100    (set_attr "mode" "DF")
5101    (set_attr "athlon_decode" "direct")
5102    (set_attr "amdfam10_decode" "double")
5103    (set_attr "fp_int_src" "true")])
5105 (define_insn "*floatsi<mode>2_i387"
5106   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5107         (float:MODEF
5108           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5109   "TARGET_80387
5110    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5111   "@
5112    fild%z1\t%1
5113    #"
5114   [(set_attr "type" "fmov,multi")
5115    (set_attr "mode" "<MODE>")
5116    (set_attr "unit" "*,i387")
5117    (set_attr "fp_int_src" "true")])
5119 (define_expand "floatdisf2"
5120   [(set (match_operand:SF 0 "register_operand" "")
5121         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5122   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5124   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5125       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5126       && !optimize_size
5127       && !MEM_P (operands[1]))
5128     {
5129       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5130       rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5131       emit_move_insn (tmp, operands[1]);
5132       operands[1] = tmp;
5133     }
5136 (define_insn "*floatdisf2_mixed"
5137   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5138         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5139   "TARGET_64BIT && TARGET_MIX_SSE_I387
5140    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5141   "@
5142    fild%z1\t%1
5143    #
5144    cvtsi2ss{q}\t{%1, %0|%0, %1}
5145    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5146   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5147    (set_attr "mode" "SF")
5148    (set_attr "unit" "*,i387,*,*")
5149    (set_attr "athlon_decode" "*,*,vector,double")
5150    (set_attr "amdfam10_decode" "*,*,vector,double")
5151    (set_attr "fp_int_src" "true")])
5153 (define_insn "*floatdisf2_mixed"
5154   [(set (match_operand:SF 0 "register_operand" "=f,x")
5155         (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5156   "TARGET_64BIT && TARGET_MIX_SSE_I387
5157    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5158   "@
5159    fild%z1\t%1
5160    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5161   [(set_attr "type" "fmov,sseicvt")
5162    (set_attr "mode" "SF")
5163    (set_attr "athlon_decode" "*,double")
5164    (set_attr "amdfam10_decode" "*,double")
5165    (set_attr "fp_int_src" "true")])
5167 (define_insn "*floatdisf2_sse"
5168   [(set (match_operand:SF 0 "register_operand" "=x,x")
5169         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5170   "TARGET_64BIT && TARGET_SSE_MATH
5171    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5172   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5173   [(set_attr "type" "sseicvt")
5174    (set_attr "mode" "SF")
5175    (set_attr "athlon_decode" "vector,double")
5176    (set_attr "amdfam10_decode" "vector,double")
5177    (set_attr "fp_int_src" "true")])
5179 (define_insn "*floatdisf2_memory"
5180   [(set (match_operand:SF 0 "register_operand" "=x")
5181         (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5182   "TARGET_64BIT && TARGET_SSE_MATH
5183    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5184   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5185   [(set_attr "type" "sseicvt")
5186    (set_attr "mode" "SF")
5187    (set_attr "athlon_decode" "double")
5188    (set_attr "amdfam10_decode" "double")
5189    (set_attr "fp_int_src" "true")])
5191 (define_expand "floatdidf2"
5192   [(set (match_operand:DF 0 "register_operand" "")
5193         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5194   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5196   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5197     {
5198       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5199       DONE;
5200     }
5201   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5202       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5203       && !optimize_size
5204       && !MEM_P (operands[1]))
5205     {
5206       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5207       rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5208       emit_move_insn (tmp, operands[1]);
5209       operands[1] = tmp;
5210     }
5213 (define_insn "*floatdidf2_mixed"
5214   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5215         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5216   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5217    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5218   "@
5219    fild%z1\t%1
5220    #
5221    cvtsi2sd{q}\t{%1, %0|%0, %1}
5222    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5223   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5224    (set_attr "mode" "DF")
5225    (set_attr "unit" "*,i387,*,*")
5226    (set_attr "athlon_decode" "*,*,double,direct")
5227    (set_attr "amdfam10_decode" "*,*,vector,double")
5228    (set_attr "fp_int_src" "true")])
5230 (define_insn "*floatdidf2_mixed_memory"
5231   [(set (match_operand:DF 0 "register_operand" "=f,x")
5232         (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5233   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5234    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5235   "@
5236    fild%z1\t%1
5237    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5238   [(set_attr "type" "fmov,sseicvt")
5239    (set_attr "mode" "DF")
5240    (set_attr "athlon_decode" "*,direct")
5241    (set_attr "amdfam10_decode" "*,double")
5242    (set_attr "fp_int_src" "true")])
5244 (define_insn "*floatdidf2_sse"
5245   [(set (match_operand:DF 0 "register_operand" "=x,x")
5246         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5247   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5248    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5249   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5250   [(set_attr "type" "sseicvt")
5251    (set_attr "mode" "DF")
5252    (set_attr "athlon_decode" "double,direct")
5253    (set_attr "amdfam10_decode" "vector,double")
5254    (set_attr "fp_int_src" "true")])
5256 (define_insn "*floatdidf2_sse_memory"
5257   [(set (match_operand:DF 0 "register_operand" "=x")
5258         (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5259   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5260    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5261   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5262   [(set_attr "type" "sseicvt")
5263    (set_attr "mode" "DF")
5264    (set_attr "athlon_decode" "direct")
5265    (set_attr "amdfam10_decode" "double")
5266    (set_attr "fp_int_src" "true")])
5268 (define_insn "*floatdi<mode>2_i387"
5269   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5270         (float:MODEF
5271           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5272   "TARGET_80387
5273    && (!TARGET_SSE_MATH || !TARGET_64BIT
5274        || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5275   "@
5276    fild%z1\t%1
5277    #"
5278   [(set_attr "type" "fmov,multi")
5279    (set_attr "mode" "<MODE>")
5280    (set_attr "unit" "*,i387")
5281    (set_attr "fp_int_src" "true")])
5283 (define_insn "float<mode>xf2"
5284   [(set (match_operand:XF 0 "register_operand" "=f,f")
5285         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5286   "TARGET_80387"
5287   "@
5288    fild%z1\t%1
5289    #"
5290   [(set_attr "type" "fmov,multi")
5291    (set_attr "mode" "XF")
5292    (set_attr "unit" "*,i387")
5293    (set_attr "fp_int_src" "true")])
5295 ;; %%% Kill these when reload knows how to do it.
5296 (define_split
5297   [(set (match_operand 0 "fp_register_operand" "")
5298         (float (match_operand 1 "register_operand" "")))]
5299   "reload_completed
5300    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5301   [(const_int 0)]
5303   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5304   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5305   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5306   ix86_free_from_memory (GET_MODE (operands[1]));
5307   DONE;
5310 (define_expand "floatunssi<mode>2"
5311   [(use (match_operand:MODEF 0 "register_operand" ""))
5312    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5313   "!TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5315   ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5316   DONE;
5319 (define_expand "floatunsdisf2"
5320   [(use (match_operand:SF 0 "register_operand" ""))
5321    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5322   "TARGET_64BIT && TARGET_SSE_MATH"
5323   "x86_emit_floatuns (operands); DONE;")
5325 (define_expand "floatunsdidf2"
5326   [(use (match_operand:DF 0 "register_operand" ""))
5327    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5328   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5329    && TARGET_SSE2 && TARGET_SSE_MATH"
5331   if (TARGET_64BIT)
5332     x86_emit_floatuns (operands);
5333   else
5334     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5335   DONE;
5338 ;; Add instructions
5340 ;; %%% splits for addditi3
5342 (define_expand "addti3"
5343   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5344         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5345                  (match_operand:TI 2 "x86_64_general_operand" "")))
5346    (clobber (reg:CC FLAGS_REG))]
5347   "TARGET_64BIT"
5348   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5350 (define_insn "*addti3_1"
5351   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5352         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5353                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5354    (clobber (reg:CC FLAGS_REG))]
5355   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5356   "#")
5358 (define_split
5359   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5360         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5361                  (match_operand:TI 2 "x86_64_general_operand" "")))
5362    (clobber (reg:CC FLAGS_REG))]
5363   "TARGET_64BIT && reload_completed"
5364   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5365                                           UNSPEC_ADD_CARRY))
5366               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5367    (parallel [(set (match_dup 3)
5368                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5369                                      (match_dup 4))
5370                             (match_dup 5)))
5371               (clobber (reg:CC FLAGS_REG))])]
5372   "split_ti (operands+0, 1, operands+0, operands+3);
5373    split_ti (operands+1, 1, operands+1, operands+4);
5374    split_ti (operands+2, 1, operands+2, operands+5);")
5376 ;; %%% splits for addsidi3
5377 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5378 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5379 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5381 (define_expand "adddi3"
5382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5383         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5384                  (match_operand:DI 2 "x86_64_general_operand" "")))
5385    (clobber (reg:CC FLAGS_REG))]
5386   ""
5387   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5389 (define_insn "*adddi3_1"
5390   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5391         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5392                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5393    (clobber (reg:CC FLAGS_REG))]
5394   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5395   "#")
5397 (define_split
5398   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5399         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5400                  (match_operand:DI 2 "general_operand" "")))
5401    (clobber (reg:CC FLAGS_REG))]
5402   "!TARGET_64BIT && reload_completed"
5403   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5404                                           UNSPEC_ADD_CARRY))
5405               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5406    (parallel [(set (match_dup 3)
5407                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5408                                      (match_dup 4))
5409                             (match_dup 5)))
5410               (clobber (reg:CC FLAGS_REG))])]
5411   "split_di (operands+0, 1, operands+0, operands+3);
5412    split_di (operands+1, 1, operands+1, operands+4);
5413    split_di (operands+2, 1, operands+2, operands+5);")
5415 (define_insn "adddi3_carry_rex64"
5416   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5417           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5418                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5419                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5420    (clobber (reg:CC FLAGS_REG))]
5421   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5422   "adc{q}\t{%2, %0|%0, %2}"
5423   [(set_attr "type" "alu")
5424    (set_attr "pent_pair" "pu")
5425    (set_attr "mode" "DI")])
5427 (define_insn "*adddi3_cc_rex64"
5428   [(set (reg:CC FLAGS_REG)
5429         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5430                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5431                    UNSPEC_ADD_CARRY))
5432    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5433         (plus:DI (match_dup 1) (match_dup 2)))]
5434   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5435   "add{q}\t{%2, %0|%0, %2}"
5436   [(set_attr "type" "alu")
5437    (set_attr "mode" "DI")])
5439 (define_insn "*<addsub><mode>3_cc_overflow"
5440   [(set (reg:CCC FLAGS_REG)
5441         (compare:CCC
5442             (plusminus:SWI
5443                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5444                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5445             (match_dup 1)))
5446    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5447         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5448   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5449   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5450   [(set_attr "type" "alu")
5451    (set_attr "mode" "<MODE>")])
5453 (define_insn "*add<mode>3_cconly_overflow"
5454   [(set (reg:CCC FLAGS_REG)
5455         (compare:CCC
5456                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5457                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5458                 (match_dup 1)))
5459    (clobber (match_scratch:SWI 0 "=<r>"))]
5460   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5461   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5462   [(set_attr "type" "alu")
5463    (set_attr "mode" "<MODE>")])
5465 (define_insn "*sub<mode>3_cconly_overflow"
5466   [(set (reg:CCC FLAGS_REG)
5467         (compare:CCC
5468              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5469                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5470              (match_dup 0)))]
5471   ""
5472   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5473   [(set_attr "type" "icmp")
5474    (set_attr "mode" "<MODE>")])
5476 (define_insn "*<addsub>si3_zext_cc_overflow"
5477   [(set (reg:CCC FLAGS_REG)
5478         (compare:CCC
5479             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5480                           (match_operand:SI 2 "general_operand" "g"))
5481             (match_dup 1)))
5482    (set (match_operand:DI 0 "register_operand" "=r")
5483         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5484   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5485   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5486   [(set_attr "type" "alu")
5487    (set_attr "mode" "SI")])
5489 (define_insn "addqi3_carry"
5490   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5491           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5492                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5493                    (match_operand:QI 2 "general_operand" "qi,qm")))
5494    (clobber (reg:CC FLAGS_REG))]
5495   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5496   "adc{b}\t{%2, %0|%0, %2}"
5497   [(set_attr "type" "alu")
5498    (set_attr "pent_pair" "pu")
5499    (set_attr "mode" "QI")])
5501 (define_insn "addhi3_carry"
5502   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5503           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5504                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5505                    (match_operand:HI 2 "general_operand" "ri,rm")))
5506    (clobber (reg:CC FLAGS_REG))]
5507   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5508   "adc{w}\t{%2, %0|%0, %2}"
5509   [(set_attr "type" "alu")
5510    (set_attr "pent_pair" "pu")
5511    (set_attr "mode" "HI")])
5513 (define_insn "addsi3_carry"
5514   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5515           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5516                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5517                    (match_operand:SI 2 "general_operand" "ri,rm")))
5518    (clobber (reg:CC FLAGS_REG))]
5519   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5520   "adc{l}\t{%2, %0|%0, %2}"
5521   [(set_attr "type" "alu")
5522    (set_attr "pent_pair" "pu")
5523    (set_attr "mode" "SI")])
5525 (define_insn "*addsi3_carry_zext"
5526   [(set (match_operand:DI 0 "register_operand" "=r")
5527           (zero_extend:DI
5528             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5529                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5530                      (match_operand:SI 2 "general_operand" "g"))))
5531    (clobber (reg:CC FLAGS_REG))]
5532   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5533   "adc{l}\t{%2, %k0|%k0, %2}"
5534   [(set_attr "type" "alu")
5535    (set_attr "pent_pair" "pu")
5536    (set_attr "mode" "SI")])
5538 (define_insn "*addsi3_cc"
5539   [(set (reg:CC FLAGS_REG)
5540         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5541                     (match_operand:SI 2 "general_operand" "ri,rm")]
5542                    UNSPEC_ADD_CARRY))
5543    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5544         (plus:SI (match_dup 1) (match_dup 2)))]
5545   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5546   "add{l}\t{%2, %0|%0, %2}"
5547   [(set_attr "type" "alu")
5548    (set_attr "mode" "SI")])
5550 (define_insn "addqi3_cc"
5551   [(set (reg:CC FLAGS_REG)
5552         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5553                     (match_operand:QI 2 "general_operand" "qi,qm")]
5554                    UNSPEC_ADD_CARRY))
5555    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5556         (plus:QI (match_dup 1) (match_dup 2)))]
5557   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5558   "add{b}\t{%2, %0|%0, %2}"
5559   [(set_attr "type" "alu")
5560    (set_attr "mode" "QI")])
5562 (define_expand "addsi3"
5563   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5564                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5565                             (match_operand:SI 2 "general_operand" "")))
5566               (clobber (reg:CC FLAGS_REG))])]
5567   ""
5568   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5570 (define_insn "*lea_1"
5571   [(set (match_operand:SI 0 "register_operand" "=r")
5572         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5573   "!TARGET_64BIT"
5574   "lea{l}\t{%a1, %0|%0, %a1}"
5575   [(set_attr "type" "lea")
5576    (set_attr "mode" "SI")])
5578 (define_insn "*lea_1_rex64"
5579   [(set (match_operand:SI 0 "register_operand" "=r")
5580         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5581   "TARGET_64BIT"
5582   "lea{l}\t{%a1, %0|%0, %a1}"
5583   [(set_attr "type" "lea")
5584    (set_attr "mode" "SI")])
5586 (define_insn "*lea_1_zext"
5587   [(set (match_operand:DI 0 "register_operand" "=r")
5588         (zero_extend:DI
5589          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5590   "TARGET_64BIT"
5591   "lea{l}\t{%a1, %k0|%k0, %a1}"
5592   [(set_attr "type" "lea")
5593    (set_attr "mode" "SI")])
5595 (define_insn "*lea_2_rex64"
5596   [(set (match_operand:DI 0 "register_operand" "=r")
5597         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5598   "TARGET_64BIT"
5599   "lea{q}\t{%a1, %0|%0, %a1}"
5600   [(set_attr "type" "lea")
5601    (set_attr "mode" "DI")])
5603 ;; The lea patterns for non-Pmodes needs to be matched by several
5604 ;; insns converted to real lea by splitters.
5606 (define_insn_and_split "*lea_general_1"
5607   [(set (match_operand 0 "register_operand" "=r")
5608         (plus (plus (match_operand 1 "index_register_operand" "l")
5609                     (match_operand 2 "register_operand" "r"))
5610               (match_operand 3 "immediate_operand" "i")))]
5611   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5612     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5613    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5614    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5615    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5616    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5617        || GET_MODE (operands[3]) == VOIDmode)"
5618   "#"
5619   "&& reload_completed"
5620   [(const_int 0)]
5622   rtx pat;
5623   operands[0] = gen_lowpart (SImode, operands[0]);
5624   operands[1] = gen_lowpart (Pmode, operands[1]);
5625   operands[2] = gen_lowpart (Pmode, operands[2]);
5626   operands[3] = gen_lowpart (Pmode, operands[3]);
5627   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5628                       operands[3]);
5629   if (Pmode != SImode)
5630     pat = gen_rtx_SUBREG (SImode, pat, 0);
5631   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5632   DONE;
5634   [(set_attr "type" "lea")
5635    (set_attr "mode" "SI")])
5637 (define_insn_and_split "*lea_general_1_zext"
5638   [(set (match_operand:DI 0 "register_operand" "=r")
5639         (zero_extend:DI
5640           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5641                             (match_operand:SI 2 "register_operand" "r"))
5642                    (match_operand:SI 3 "immediate_operand" "i"))))]
5643   "TARGET_64BIT"
5644   "#"
5645   "&& reload_completed"
5646   [(set (match_dup 0)
5647         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5648                                                      (match_dup 2))
5649                                             (match_dup 3)) 0)))]
5651   operands[1] = gen_lowpart (Pmode, operands[1]);
5652   operands[2] = gen_lowpart (Pmode, operands[2]);
5653   operands[3] = gen_lowpart (Pmode, operands[3]);
5655   [(set_attr "type" "lea")
5656    (set_attr "mode" "SI")])
5658 (define_insn_and_split "*lea_general_2"
5659   [(set (match_operand 0 "register_operand" "=r")
5660         (plus (mult (match_operand 1 "index_register_operand" "l")
5661                     (match_operand 2 "const248_operand" "i"))
5662               (match_operand 3 "nonmemory_operand" "ri")))]
5663   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5664     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5665    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5666    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5667    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5668        || GET_MODE (operands[3]) == VOIDmode)"
5669   "#"
5670   "&& reload_completed"
5671   [(const_int 0)]
5673   rtx pat;
5674   operands[0] = gen_lowpart (SImode, operands[0]);
5675   operands[1] = gen_lowpart (Pmode, operands[1]);
5676   operands[3] = gen_lowpart (Pmode, operands[3]);
5677   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5678                       operands[3]);
5679   if (Pmode != SImode)
5680     pat = gen_rtx_SUBREG (SImode, pat, 0);
5681   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5682   DONE;
5684   [(set_attr "type" "lea")
5685    (set_attr "mode" "SI")])
5687 (define_insn_and_split "*lea_general_2_zext"
5688   [(set (match_operand:DI 0 "register_operand" "=r")
5689         (zero_extend:DI
5690           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5691                             (match_operand:SI 2 "const248_operand" "n"))
5692                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5693   "TARGET_64BIT"
5694   "#"
5695   "&& reload_completed"
5696   [(set (match_dup 0)
5697         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5698                                                      (match_dup 2))
5699                                             (match_dup 3)) 0)))]
5701   operands[1] = gen_lowpart (Pmode, operands[1]);
5702   operands[3] = gen_lowpart (Pmode, operands[3]);
5704   [(set_attr "type" "lea")
5705    (set_attr "mode" "SI")])
5707 (define_insn_and_split "*lea_general_3"
5708   [(set (match_operand 0 "register_operand" "=r")
5709         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5710                           (match_operand 2 "const248_operand" "i"))
5711                     (match_operand 3 "register_operand" "r"))
5712               (match_operand 4 "immediate_operand" "i")))]
5713   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5714     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5715    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5716    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5717    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5718   "#"
5719   "&& reload_completed"
5720   [(const_int 0)]
5722   rtx pat;
5723   operands[0] = gen_lowpart (SImode, operands[0]);
5724   operands[1] = gen_lowpart (Pmode, operands[1]);
5725   operands[3] = gen_lowpart (Pmode, operands[3]);
5726   operands[4] = gen_lowpart (Pmode, operands[4]);
5727   pat = gen_rtx_PLUS (Pmode,
5728                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5729                                                          operands[2]),
5730                                     operands[3]),
5731                       operands[4]);
5732   if (Pmode != SImode)
5733     pat = gen_rtx_SUBREG (SImode, pat, 0);
5734   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5735   DONE;
5737   [(set_attr "type" "lea")
5738    (set_attr "mode" "SI")])
5740 (define_insn_and_split "*lea_general_3_zext"
5741   [(set (match_operand:DI 0 "register_operand" "=r")
5742         (zero_extend:DI
5743           (plus:SI (plus:SI (mult:SI
5744                               (match_operand:SI 1 "index_register_operand" "l")
5745                               (match_operand:SI 2 "const248_operand" "n"))
5746                             (match_operand:SI 3 "register_operand" "r"))
5747                    (match_operand:SI 4 "immediate_operand" "i"))))]
5748   "TARGET_64BIT"
5749   "#"
5750   "&& reload_completed"
5751   [(set (match_dup 0)
5752         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5753                                                               (match_dup 2))
5754                                                      (match_dup 3))
5755                                             (match_dup 4)) 0)))]
5757   operands[1] = gen_lowpart (Pmode, operands[1]);
5758   operands[3] = gen_lowpart (Pmode, operands[3]);
5759   operands[4] = gen_lowpart (Pmode, operands[4]);
5761   [(set_attr "type" "lea")
5762    (set_attr "mode" "SI")])
5764 (define_insn "*adddi_1_rex64"
5765   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5766         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5767                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5768    (clobber (reg:CC FLAGS_REG))]
5769   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5771   switch (get_attr_type (insn))
5772     {
5773     case TYPE_LEA:
5774       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5775       return "lea{q}\t{%a2, %0|%0, %a2}";
5777     case TYPE_INCDEC:
5778       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779       if (operands[2] == const1_rtx)
5780         return "inc{q}\t%0";
5781       else
5782         {
5783           gcc_assert (operands[2] == constm1_rtx);
5784           return "dec{q}\t%0";
5785         }
5787     default:
5788       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5790       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5791          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5792       if (CONST_INT_P (operands[2])
5793           /* Avoid overflows.  */
5794           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5795           && (INTVAL (operands[2]) == 128
5796               || (INTVAL (operands[2]) < 0
5797                   && INTVAL (operands[2]) != -128)))
5798         {
5799           operands[2] = GEN_INT (-INTVAL (operands[2]));
5800           return "sub{q}\t{%2, %0|%0, %2}";
5801         }
5802       return "add{q}\t{%2, %0|%0, %2}";
5803     }
5805   [(set (attr "type")
5806      (cond [(eq_attr "alternative" "2")
5807               (const_string "lea")
5808             ; Current assemblers are broken and do not allow @GOTOFF in
5809             ; ought but a memory context.
5810             (match_operand:DI 2 "pic_symbolic_operand" "")
5811               (const_string "lea")
5812             (match_operand:DI 2 "incdec_operand" "")
5813               (const_string "incdec")
5814            ]
5815            (const_string "alu")))
5816    (set_attr "mode" "DI")])
5818 ;; Convert lea to the lea pattern to avoid flags dependency.
5819 (define_split
5820   [(set (match_operand:DI 0 "register_operand" "")
5821         (plus:DI (match_operand:DI 1 "register_operand" "")
5822                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5823    (clobber (reg:CC FLAGS_REG))]
5824   "TARGET_64BIT && reload_completed
5825    && true_regnum (operands[0]) != true_regnum (operands[1])"
5826   [(set (match_dup 0)
5827         (plus:DI (match_dup 1)
5828                  (match_dup 2)))]
5829   "")
5831 (define_insn "*adddi_2_rex64"
5832   [(set (reg FLAGS_REG)
5833         (compare
5834           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5835                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5836           (const_int 0)))
5837    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5838         (plus:DI (match_dup 1) (match_dup 2)))]
5839   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5840    && ix86_binary_operator_ok (PLUS, DImode, operands)
5841    /* Current assemblers are broken and do not allow @GOTOFF in
5842       ought but a memory context.  */
5843    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5845   switch (get_attr_type (insn))
5846     {
5847     case TYPE_INCDEC:
5848       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5849       if (operands[2] == const1_rtx)
5850         return "inc{q}\t%0";
5851       else
5852         {
5853           gcc_assert (operands[2] == constm1_rtx);
5854           return "dec{q}\t%0";
5855         }
5857     default:
5858       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5859       /* ???? We ought to handle there the 32bit case too
5860          - do we need new constraint?  */
5861       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5862          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5863       if (CONST_INT_P (operands[2])
5864           /* Avoid overflows.  */
5865           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5866           && (INTVAL (operands[2]) == 128
5867               || (INTVAL (operands[2]) < 0
5868                   && INTVAL (operands[2]) != -128)))
5869         {
5870           operands[2] = GEN_INT (-INTVAL (operands[2]));
5871           return "sub{q}\t{%2, %0|%0, %2}";
5872         }
5873       return "add{q}\t{%2, %0|%0, %2}";
5874     }
5876   [(set (attr "type")
5877      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5878         (const_string "incdec")
5879         (const_string "alu")))
5880    (set_attr "mode" "DI")])
5882 (define_insn "*adddi_3_rex64"
5883   [(set (reg FLAGS_REG)
5884         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5885                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5886    (clobber (match_scratch:DI 0 "=r"))]
5887   "TARGET_64BIT
5888    && ix86_match_ccmode (insn, CCZmode)
5889    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5890    /* Current assemblers are broken and do not allow @GOTOFF in
5891       ought but a memory context.  */
5892    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5894   switch (get_attr_type (insn))
5895     {
5896     case TYPE_INCDEC:
5897       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5898       if (operands[2] == const1_rtx)
5899         return "inc{q}\t%0";
5900       else
5901         {
5902           gcc_assert (operands[2] == constm1_rtx);
5903           return "dec{q}\t%0";
5904         }
5906     default:
5907       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5908       /* ???? We ought to handle there the 32bit case too
5909          - do we need new constraint?  */
5910       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5912       if (CONST_INT_P (operands[2])
5913           /* Avoid overflows.  */
5914           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5915           && (INTVAL (operands[2]) == 128
5916               || (INTVAL (operands[2]) < 0
5917                   && INTVAL (operands[2]) != -128)))
5918         {
5919           operands[2] = GEN_INT (-INTVAL (operands[2]));
5920           return "sub{q}\t{%2, %0|%0, %2}";
5921         }
5922       return "add{q}\t{%2, %0|%0, %2}";
5923     }
5925   [(set (attr "type")
5926      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5927         (const_string "incdec")
5928         (const_string "alu")))
5929    (set_attr "mode" "DI")])
5931 ; For comparisons against 1, -1 and 128, we may generate better code
5932 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5933 ; is matched then.  We can't accept general immediate, because for
5934 ; case of overflows,  the result is messed up.
5935 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5936 ; when negated.
5937 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5938 ; only for comparisons not depending on it.
5939 (define_insn "*adddi_4_rex64"
5940   [(set (reg FLAGS_REG)
5941         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5942                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5943    (clobber (match_scratch:DI 0 "=rm"))]
5944   "TARGET_64BIT
5945    &&  ix86_match_ccmode (insn, CCGCmode)"
5947   switch (get_attr_type (insn))
5948     {
5949     case TYPE_INCDEC:
5950       if (operands[2] == constm1_rtx)
5951         return "inc{q}\t%0";
5952       else
5953         {
5954           gcc_assert (operands[2] == const1_rtx);
5955           return "dec{q}\t%0";
5956         }
5958     default:
5959       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5962       if ((INTVAL (operands[2]) == -128
5963            || (INTVAL (operands[2]) > 0
5964                && INTVAL (operands[2]) != 128))
5965           /* Avoid overflows.  */
5966           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5967         return "sub{q}\t{%2, %0|%0, %2}";
5968       operands[2] = GEN_INT (-INTVAL (operands[2]));
5969       return "add{q}\t{%2, %0|%0, %2}";
5970     }
5972   [(set (attr "type")
5973      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5974         (const_string "incdec")
5975         (const_string "alu")))
5976    (set_attr "mode" "DI")])
5978 (define_insn "*adddi_5_rex64"
5979   [(set (reg FLAGS_REG)
5980         (compare
5981           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5982                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5983           (const_int 0)))
5984    (clobber (match_scratch:DI 0 "=r"))]
5985   "TARGET_64BIT
5986    && ix86_match_ccmode (insn, CCGOCmode)
5987    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5988    /* Current assemblers are broken and do not allow @GOTOFF in
5989       ought but a memory context.  */
5990    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5992   switch (get_attr_type (insn))
5993     {
5994     case TYPE_INCDEC:
5995       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5996       if (operands[2] == const1_rtx)
5997         return "inc{q}\t%0";
5998       else
5999         {
6000           gcc_assert (operands[2] == constm1_rtx);
6001           return "dec{q}\t%0";
6002         }
6004     default:
6005       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6006       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6007          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6008       if (CONST_INT_P (operands[2])
6009           /* Avoid overflows.  */
6010           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6011           && (INTVAL (operands[2]) == 128
6012               || (INTVAL (operands[2]) < 0
6013                   && INTVAL (operands[2]) != -128)))
6014         {
6015           operands[2] = GEN_INT (-INTVAL (operands[2]));
6016           return "sub{q}\t{%2, %0|%0, %2}";
6017         }
6018       return "add{q}\t{%2, %0|%0, %2}";
6019     }
6021   [(set (attr "type")
6022      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6023         (const_string "incdec")
6024         (const_string "alu")))
6025    (set_attr "mode" "DI")])
6028 (define_insn "*addsi_1"
6029   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6030         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6031                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6032    (clobber (reg:CC FLAGS_REG))]
6033   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6035   switch (get_attr_type (insn))
6036     {
6037     case TYPE_LEA:
6038       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6039       return "lea{l}\t{%a2, %0|%0, %a2}";
6041     case TYPE_INCDEC:
6042       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6043       if (operands[2] == const1_rtx)
6044         return "inc{l}\t%0";
6045       else
6046         {
6047           gcc_assert (operands[2] == constm1_rtx);
6048           return "dec{l}\t%0";
6049         }
6051     default:
6052       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6054       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6055          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6056       if (CONST_INT_P (operands[2])
6057           && (INTVAL (operands[2]) == 128
6058               || (INTVAL (operands[2]) < 0
6059                   && INTVAL (operands[2]) != -128)))
6060         {
6061           operands[2] = GEN_INT (-INTVAL (operands[2]));
6062           return "sub{l}\t{%2, %0|%0, %2}";
6063         }
6064       return "add{l}\t{%2, %0|%0, %2}";
6065     }
6067   [(set (attr "type")
6068      (cond [(eq_attr "alternative" "2")
6069               (const_string "lea")
6070             ; Current assemblers are broken and do not allow @GOTOFF in
6071             ; ought but a memory context.
6072             (match_operand:SI 2 "pic_symbolic_operand" "")
6073               (const_string "lea")
6074             (match_operand:SI 2 "incdec_operand" "")
6075               (const_string "incdec")
6076            ]
6077            (const_string "alu")))
6078    (set_attr "mode" "SI")])
6080 ;; Convert lea to the lea pattern to avoid flags dependency.
6081 (define_split
6082   [(set (match_operand 0 "register_operand" "")
6083         (plus (match_operand 1 "register_operand" "")
6084               (match_operand 2 "nonmemory_operand" "")))
6085    (clobber (reg:CC FLAGS_REG))]
6086   "reload_completed
6087    && true_regnum (operands[0]) != true_regnum (operands[1])"
6088   [(const_int 0)]
6090   rtx pat;
6091   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6092      may confuse gen_lowpart.  */
6093   if (GET_MODE (operands[0]) != Pmode)
6094     {
6095       operands[1] = gen_lowpart (Pmode, operands[1]);
6096       operands[2] = gen_lowpart (Pmode, operands[2]);
6097     }
6098   operands[0] = gen_lowpart (SImode, operands[0]);
6099   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6100   if (Pmode != SImode)
6101     pat = gen_rtx_SUBREG (SImode, pat, 0);
6102   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6103   DONE;
6106 ;; It may seem that nonimmediate operand is proper one for operand 1.
6107 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6108 ;; we take care in ix86_binary_operator_ok to not allow two memory
6109 ;; operands so proper swapping will be done in reload.  This allow
6110 ;; patterns constructed from addsi_1 to match.
6111 (define_insn "addsi_1_zext"
6112   [(set (match_operand:DI 0 "register_operand" "=r,r")
6113         (zero_extend:DI
6114           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6115                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6116    (clobber (reg:CC FLAGS_REG))]
6117   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6119   switch (get_attr_type (insn))
6120     {
6121     case TYPE_LEA:
6122       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6123       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6125     case TYPE_INCDEC:
6126       if (operands[2] == const1_rtx)
6127         return "inc{l}\t%k0";
6128       else
6129         {
6130           gcc_assert (operands[2] == constm1_rtx);
6131           return "dec{l}\t%k0";
6132         }
6134     default:
6135       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6136          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6137       if (CONST_INT_P (operands[2])
6138           && (INTVAL (operands[2]) == 128
6139               || (INTVAL (operands[2]) < 0
6140                   && INTVAL (operands[2]) != -128)))
6141         {
6142           operands[2] = GEN_INT (-INTVAL (operands[2]));
6143           return "sub{l}\t{%2, %k0|%k0, %2}";
6144         }
6145       return "add{l}\t{%2, %k0|%k0, %2}";
6146     }
6148   [(set (attr "type")
6149      (cond [(eq_attr "alternative" "1")
6150               (const_string "lea")
6151             ; Current assemblers are broken and do not allow @GOTOFF in
6152             ; ought but a memory context.
6153             (match_operand:SI 2 "pic_symbolic_operand" "")
6154               (const_string "lea")
6155             (match_operand:SI 2 "incdec_operand" "")
6156               (const_string "incdec")
6157            ]
6158            (const_string "alu")))
6159    (set_attr "mode" "SI")])
6161 ;; Convert lea to the lea pattern to avoid flags dependency.
6162 (define_split
6163   [(set (match_operand:DI 0 "register_operand" "")
6164         (zero_extend:DI
6165           (plus:SI (match_operand:SI 1 "register_operand" "")
6166                    (match_operand:SI 2 "nonmemory_operand" ""))))
6167    (clobber (reg:CC FLAGS_REG))]
6168   "TARGET_64BIT && reload_completed
6169    && true_regnum (operands[0]) != true_regnum (operands[1])"
6170   [(set (match_dup 0)
6171         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6173   operands[1] = gen_lowpart (Pmode, operands[1]);
6174   operands[2] = gen_lowpart (Pmode, operands[2]);
6177 (define_insn "*addsi_2"
6178   [(set (reg FLAGS_REG)
6179         (compare
6180           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6181                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6182           (const_int 0)))
6183    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6184         (plus:SI (match_dup 1) (match_dup 2)))]
6185   "ix86_match_ccmode (insn, CCGOCmode)
6186    && ix86_binary_operator_ok (PLUS, SImode, operands)
6187    /* Current assemblers are broken and do not allow @GOTOFF in
6188       ought but a memory context.  */
6189    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6191   switch (get_attr_type (insn))
6192     {
6193     case TYPE_INCDEC:
6194       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6195       if (operands[2] == const1_rtx)
6196         return "inc{l}\t%0";
6197       else
6198         {
6199           gcc_assert (operands[2] == constm1_rtx);
6200           return "dec{l}\t%0";
6201         }
6203     default:
6204       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6205       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6206          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6207       if (CONST_INT_P (operands[2])
6208           && (INTVAL (operands[2]) == 128
6209               || (INTVAL (operands[2]) < 0
6210                   && INTVAL (operands[2]) != -128)))
6211         {
6212           operands[2] = GEN_INT (-INTVAL (operands[2]));
6213           return "sub{l}\t{%2, %0|%0, %2}";
6214         }
6215       return "add{l}\t{%2, %0|%0, %2}";
6216     }
6218   [(set (attr "type")
6219      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6220         (const_string "incdec")
6221         (const_string "alu")))
6222    (set_attr "mode" "SI")])
6224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6225 (define_insn "*addsi_2_zext"
6226   [(set (reg FLAGS_REG)
6227         (compare
6228           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6229                    (match_operand:SI 2 "general_operand" "rmni"))
6230           (const_int 0)))
6231    (set (match_operand:DI 0 "register_operand" "=r")
6232         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6233   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6234    && ix86_binary_operator_ok (PLUS, SImode, operands)
6235    /* Current assemblers are broken and do not allow @GOTOFF in
6236       ought but a memory context.  */
6237    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6239   switch (get_attr_type (insn))
6240     {
6241     case TYPE_INCDEC:
6242       if (operands[2] == const1_rtx)
6243         return "inc{l}\t%k0";
6244       else
6245         {
6246           gcc_assert (operands[2] == constm1_rtx);
6247           return "dec{l}\t%k0";
6248         }
6250     default:
6251       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6252          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6253       if (CONST_INT_P (operands[2])
6254           && (INTVAL (operands[2]) == 128
6255               || (INTVAL (operands[2]) < 0
6256                   && INTVAL (operands[2]) != -128)))
6257         {
6258           operands[2] = GEN_INT (-INTVAL (operands[2]));
6259           return "sub{l}\t{%2, %k0|%k0, %2}";
6260         }
6261       return "add{l}\t{%2, %k0|%k0, %2}";
6262     }
6264   [(set (attr "type")
6265      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6266         (const_string "incdec")
6267         (const_string "alu")))
6268    (set_attr "mode" "SI")])
6270 (define_insn "*addsi_3"
6271   [(set (reg FLAGS_REG)
6272         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6273                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6274    (clobber (match_scratch:SI 0 "=r"))]
6275   "ix86_match_ccmode (insn, CCZmode)
6276    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6277    /* Current assemblers are broken and do not allow @GOTOFF in
6278       ought but a memory context.  */
6279    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6281   switch (get_attr_type (insn))
6282     {
6283     case TYPE_INCDEC:
6284       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6285       if (operands[2] == const1_rtx)
6286         return "inc{l}\t%0";
6287       else
6288         {
6289           gcc_assert (operands[2] == constm1_rtx);
6290           return "dec{l}\t%0";
6291         }
6293     default:
6294       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6295       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6296          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6297       if (CONST_INT_P (operands[2])
6298           && (INTVAL (operands[2]) == 128
6299               || (INTVAL (operands[2]) < 0
6300                   && INTVAL (operands[2]) != -128)))
6301         {
6302           operands[2] = GEN_INT (-INTVAL (operands[2]));
6303           return "sub{l}\t{%2, %0|%0, %2}";
6304         }
6305       return "add{l}\t{%2, %0|%0, %2}";
6306     }
6308   [(set (attr "type")
6309      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6310         (const_string "incdec")
6311         (const_string "alu")))
6312    (set_attr "mode" "SI")])
6314 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6315 (define_insn "*addsi_3_zext"
6316   [(set (reg FLAGS_REG)
6317         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6318                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6319    (set (match_operand:DI 0 "register_operand" "=r")
6320         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6321   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6322    && ix86_binary_operator_ok (PLUS, SImode, operands)
6323    /* Current assemblers are broken and do not allow @GOTOFF in
6324       ought but a memory context.  */
6325    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6327   switch (get_attr_type (insn))
6328     {
6329     case TYPE_INCDEC:
6330       if (operands[2] == const1_rtx)
6331         return "inc{l}\t%k0";
6332       else
6333         {
6334           gcc_assert (operands[2] == constm1_rtx);
6335           return "dec{l}\t%k0";
6336         }
6338     default:
6339       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6340          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6341       if (CONST_INT_P (operands[2])
6342           && (INTVAL (operands[2]) == 128
6343               || (INTVAL (operands[2]) < 0
6344                   && INTVAL (operands[2]) != -128)))
6345         {
6346           operands[2] = GEN_INT (-INTVAL (operands[2]));
6347           return "sub{l}\t{%2, %k0|%k0, %2}";
6348         }
6349       return "add{l}\t{%2, %k0|%k0, %2}";
6350     }
6352   [(set (attr "type")
6353      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6354         (const_string "incdec")
6355         (const_string "alu")))
6356    (set_attr "mode" "SI")])
6358 ; For comparisons against 1, -1 and 128, we may generate better code
6359 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6360 ; is matched then.  We can't accept general immediate, because for
6361 ; case of overflows,  the result is messed up.
6362 ; This pattern also don't hold of 0x80000000, since the value overflows
6363 ; when negated.
6364 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6365 ; only for comparisons not depending on it.
6366 (define_insn "*addsi_4"
6367   [(set (reg FLAGS_REG)
6368         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6369                  (match_operand:SI 2 "const_int_operand" "n")))
6370    (clobber (match_scratch:SI 0 "=rm"))]
6371   "ix86_match_ccmode (insn, CCGCmode)
6372    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6374   switch (get_attr_type (insn))
6375     {
6376     case TYPE_INCDEC:
6377       if (operands[2] == constm1_rtx)
6378         return "inc{l}\t%0";
6379       else
6380         {
6381           gcc_assert (operands[2] == const1_rtx);
6382           return "dec{l}\t%0";
6383         }
6385     default:
6386       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6387       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6388          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6389       if ((INTVAL (operands[2]) == -128
6390            || (INTVAL (operands[2]) > 0
6391                && INTVAL (operands[2]) != 128)))
6392         return "sub{l}\t{%2, %0|%0, %2}";
6393       operands[2] = GEN_INT (-INTVAL (operands[2]));
6394       return "add{l}\t{%2, %0|%0, %2}";
6395     }
6397   [(set (attr "type")
6398      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6399         (const_string "incdec")
6400         (const_string "alu")))
6401    (set_attr "mode" "SI")])
6403 (define_insn "*addsi_5"
6404   [(set (reg FLAGS_REG)
6405         (compare
6406           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6407                    (match_operand:SI 2 "general_operand" "rmni"))
6408           (const_int 0)))
6409    (clobber (match_scratch:SI 0 "=r"))]
6410   "ix86_match_ccmode (insn, CCGOCmode)
6411    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6412    /* Current assemblers are broken and do not allow @GOTOFF in
6413       ought but a memory context.  */
6414    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6416   switch (get_attr_type (insn))
6417     {
6418     case TYPE_INCDEC:
6419       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6420       if (operands[2] == const1_rtx)
6421         return "inc{l}\t%0";
6422       else
6423         {
6424           gcc_assert (operands[2] == constm1_rtx);
6425           return "dec{l}\t%0";
6426         }
6428     default:
6429       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6430       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6431          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6432       if (CONST_INT_P (operands[2])
6433           && (INTVAL (operands[2]) == 128
6434               || (INTVAL (operands[2]) < 0
6435                   && INTVAL (operands[2]) != -128)))
6436         {
6437           operands[2] = GEN_INT (-INTVAL (operands[2]));
6438           return "sub{l}\t{%2, %0|%0, %2}";
6439         }
6440       return "add{l}\t{%2, %0|%0, %2}";
6441     }
6443   [(set (attr "type")
6444      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6445         (const_string "incdec")
6446         (const_string "alu")))
6447    (set_attr "mode" "SI")])
6449 (define_expand "addhi3"
6450   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6451                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6452                             (match_operand:HI 2 "general_operand" "")))
6453               (clobber (reg:CC FLAGS_REG))])]
6454   "TARGET_HIMODE_MATH"
6455   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6457 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6458 ;; type optimizations enabled by define-splits.  This is not important
6459 ;; for PII, and in fact harmful because of partial register stalls.
6461 (define_insn "*addhi_1_lea"
6462   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6463         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6464                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6465    (clobber (reg:CC FLAGS_REG))]
6466   "!TARGET_PARTIAL_REG_STALL
6467    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6469   switch (get_attr_type (insn))
6470     {
6471     case TYPE_LEA:
6472       return "#";
6473     case TYPE_INCDEC:
6474       if (operands[2] == const1_rtx)
6475         return "inc{w}\t%0";
6476       else
6477         {
6478           gcc_assert (operands[2] == constm1_rtx);
6479           return "dec{w}\t%0";
6480         }
6482     default:
6483       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6484          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6485       if (CONST_INT_P (operands[2])
6486           && (INTVAL (operands[2]) == 128
6487               || (INTVAL (operands[2]) < 0
6488                   && INTVAL (operands[2]) != -128)))
6489         {
6490           operands[2] = GEN_INT (-INTVAL (operands[2]));
6491           return "sub{w}\t{%2, %0|%0, %2}";
6492         }
6493       return "add{w}\t{%2, %0|%0, %2}";
6494     }
6496   [(set (attr "type")
6497      (if_then_else (eq_attr "alternative" "2")
6498         (const_string "lea")
6499         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6500            (const_string "incdec")
6501            (const_string "alu"))))
6502    (set_attr "mode" "HI,HI,SI")])
6504 (define_insn "*addhi_1"
6505   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6506         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6507                  (match_operand:HI 2 "general_operand" "ri,rm")))
6508    (clobber (reg:CC FLAGS_REG))]
6509   "TARGET_PARTIAL_REG_STALL
6510    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6512   switch (get_attr_type (insn))
6513     {
6514     case TYPE_INCDEC:
6515       if (operands[2] == const1_rtx)
6516         return "inc{w}\t%0";
6517       else
6518         {
6519           gcc_assert (operands[2] == constm1_rtx);
6520           return "dec{w}\t%0";
6521         }
6523     default:
6524       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6525          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6526       if (CONST_INT_P (operands[2])
6527           && (INTVAL (operands[2]) == 128
6528               || (INTVAL (operands[2]) < 0
6529                   && INTVAL (operands[2]) != -128)))
6530         {
6531           operands[2] = GEN_INT (-INTVAL (operands[2]));
6532           return "sub{w}\t{%2, %0|%0, %2}";
6533         }
6534       return "add{w}\t{%2, %0|%0, %2}";
6535     }
6537   [(set (attr "type")
6538      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6539         (const_string "incdec")
6540         (const_string "alu")))
6541    (set_attr "mode" "HI")])
6543 (define_insn "*addhi_2"
6544   [(set (reg FLAGS_REG)
6545         (compare
6546           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6547                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6548           (const_int 0)))
6549    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6550         (plus:HI (match_dup 1) (match_dup 2)))]
6551   "ix86_match_ccmode (insn, CCGOCmode)
6552    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6554   switch (get_attr_type (insn))
6555     {
6556     case TYPE_INCDEC:
6557       if (operands[2] == const1_rtx)
6558         return "inc{w}\t%0";
6559       else
6560         {
6561           gcc_assert (operands[2] == constm1_rtx);
6562           return "dec{w}\t%0";
6563         }
6565     default:
6566       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6567          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6568       if (CONST_INT_P (operands[2])
6569           && (INTVAL (operands[2]) == 128
6570               || (INTVAL (operands[2]) < 0
6571                   && INTVAL (operands[2]) != -128)))
6572         {
6573           operands[2] = GEN_INT (-INTVAL (operands[2]));
6574           return "sub{w}\t{%2, %0|%0, %2}";
6575         }
6576       return "add{w}\t{%2, %0|%0, %2}";
6577     }
6579   [(set (attr "type")
6580      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6581         (const_string "incdec")
6582         (const_string "alu")))
6583    (set_attr "mode" "HI")])
6585 (define_insn "*addhi_3"
6586   [(set (reg FLAGS_REG)
6587         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6588                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6589    (clobber (match_scratch:HI 0 "=r"))]
6590   "ix86_match_ccmode (insn, CCZmode)
6591    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6593   switch (get_attr_type (insn))
6594     {
6595     case TYPE_INCDEC:
6596       if (operands[2] == const1_rtx)
6597         return "inc{w}\t%0";
6598       else
6599         {
6600           gcc_assert (operands[2] == constm1_rtx);
6601           return "dec{w}\t%0";
6602         }
6604     default:
6605       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6606          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6607       if (CONST_INT_P (operands[2])
6608           && (INTVAL (operands[2]) == 128
6609               || (INTVAL (operands[2]) < 0
6610                   && INTVAL (operands[2]) != -128)))
6611         {
6612           operands[2] = GEN_INT (-INTVAL (operands[2]));
6613           return "sub{w}\t{%2, %0|%0, %2}";
6614         }
6615       return "add{w}\t{%2, %0|%0, %2}";
6616     }
6618   [(set (attr "type")
6619      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6620         (const_string "incdec")
6621         (const_string "alu")))
6622    (set_attr "mode" "HI")])
6624 ; See comments above addsi_4 for details.
6625 (define_insn "*addhi_4"
6626   [(set (reg FLAGS_REG)
6627         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6628                  (match_operand:HI 2 "const_int_operand" "n")))
6629    (clobber (match_scratch:HI 0 "=rm"))]
6630   "ix86_match_ccmode (insn, CCGCmode)
6631    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6633   switch (get_attr_type (insn))
6634     {
6635     case TYPE_INCDEC:
6636       if (operands[2] == constm1_rtx)
6637         return "inc{w}\t%0";
6638       else
6639         {
6640           gcc_assert (operands[2] == const1_rtx);
6641           return "dec{w}\t%0";
6642         }
6644     default:
6645       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6646       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6647          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6648       if ((INTVAL (operands[2]) == -128
6649            || (INTVAL (operands[2]) > 0
6650                && INTVAL (operands[2]) != 128)))
6651         return "sub{w}\t{%2, %0|%0, %2}";
6652       operands[2] = GEN_INT (-INTVAL (operands[2]));
6653       return "add{w}\t{%2, %0|%0, %2}";
6654     }
6656   [(set (attr "type")
6657      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6658         (const_string "incdec")
6659         (const_string "alu")))
6660    (set_attr "mode" "SI")])
6663 (define_insn "*addhi_5"
6664   [(set (reg FLAGS_REG)
6665         (compare
6666           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6667                    (match_operand:HI 2 "general_operand" "rmni"))
6668           (const_int 0)))
6669    (clobber (match_scratch:HI 0 "=r"))]
6670   "ix86_match_ccmode (insn, CCGOCmode)
6671    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6673   switch (get_attr_type (insn))
6674     {
6675     case TYPE_INCDEC:
6676       if (operands[2] == const1_rtx)
6677         return "inc{w}\t%0";
6678       else
6679         {
6680           gcc_assert (operands[2] == constm1_rtx);
6681           return "dec{w}\t%0";
6682         }
6684     default:
6685       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6686          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6687       if (CONST_INT_P (operands[2])
6688           && (INTVAL (operands[2]) == 128
6689               || (INTVAL (operands[2]) < 0
6690                   && INTVAL (operands[2]) != -128)))
6691         {
6692           operands[2] = GEN_INT (-INTVAL (operands[2]));
6693           return "sub{w}\t{%2, %0|%0, %2}";
6694         }
6695       return "add{w}\t{%2, %0|%0, %2}";
6696     }
6698   [(set (attr "type")
6699      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6700         (const_string "incdec")
6701         (const_string "alu")))
6702    (set_attr "mode" "HI")])
6704 (define_expand "addqi3"
6705   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6706                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6707                             (match_operand:QI 2 "general_operand" "")))
6708               (clobber (reg:CC FLAGS_REG))])]
6709   "TARGET_QIMODE_MATH"
6710   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6712 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6713 (define_insn "*addqi_1_lea"
6714   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6715         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6716                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6717    (clobber (reg:CC FLAGS_REG))]
6718   "!TARGET_PARTIAL_REG_STALL
6719    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6721   int widen = (which_alternative == 2);
6722   switch (get_attr_type (insn))
6723     {
6724     case TYPE_LEA:
6725       return "#";
6726     case TYPE_INCDEC:
6727       if (operands[2] == const1_rtx)
6728         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6729       else
6730         {
6731           gcc_assert (operands[2] == constm1_rtx);
6732           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6733         }
6735     default:
6736       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6737          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6738       if (CONST_INT_P (operands[2])
6739           && (INTVAL (operands[2]) == 128
6740               || (INTVAL (operands[2]) < 0
6741                   && INTVAL (operands[2]) != -128)))
6742         {
6743           operands[2] = GEN_INT (-INTVAL (operands[2]));
6744           if (widen)
6745             return "sub{l}\t{%2, %k0|%k0, %2}";
6746           else
6747             return "sub{b}\t{%2, %0|%0, %2}";
6748         }
6749       if (widen)
6750         return "add{l}\t{%k2, %k0|%k0, %k2}";
6751       else
6752         return "add{b}\t{%2, %0|%0, %2}";
6753     }
6755   [(set (attr "type")
6756      (if_then_else (eq_attr "alternative" "3")
6757         (const_string "lea")
6758         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6759            (const_string "incdec")
6760            (const_string "alu"))))
6761    (set_attr "mode" "QI,QI,SI,SI")])
6763 (define_insn "*addqi_1"
6764   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6765         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6766                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6767    (clobber (reg:CC FLAGS_REG))]
6768   "TARGET_PARTIAL_REG_STALL
6769    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6771   int widen = (which_alternative == 2);
6772   switch (get_attr_type (insn))
6773     {
6774     case TYPE_INCDEC:
6775       if (operands[2] == const1_rtx)
6776         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6777       else
6778         {
6779           gcc_assert (operands[2] == constm1_rtx);
6780           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6781         }
6783     default:
6784       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6785          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6786       if (CONST_INT_P (operands[2])
6787           && (INTVAL (operands[2]) == 128
6788               || (INTVAL (operands[2]) < 0
6789                   && INTVAL (operands[2]) != -128)))
6790         {
6791           operands[2] = GEN_INT (-INTVAL (operands[2]));
6792           if (widen)
6793             return "sub{l}\t{%2, %k0|%k0, %2}";
6794           else
6795             return "sub{b}\t{%2, %0|%0, %2}";
6796         }
6797       if (widen)
6798         return "add{l}\t{%k2, %k0|%k0, %k2}";
6799       else
6800         return "add{b}\t{%2, %0|%0, %2}";
6801     }
6803   [(set (attr "type")
6804      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6805         (const_string "incdec")
6806         (const_string "alu")))
6807    (set_attr "mode" "QI,QI,SI")])
6809 (define_insn "*addqi_1_slp"
6810   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6811         (plus:QI (match_dup 0)
6812                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6813    (clobber (reg:CC FLAGS_REG))]
6814   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6815    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6817   switch (get_attr_type (insn))
6818     {
6819     case TYPE_INCDEC:
6820       if (operands[1] == const1_rtx)
6821         return "inc{b}\t%0";
6822       else
6823         {
6824           gcc_assert (operands[1] == constm1_rtx);
6825           return "dec{b}\t%0";
6826         }
6828     default:
6829       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6830       if (CONST_INT_P (operands[1])
6831           && INTVAL (operands[1]) < 0)
6832         {
6833           operands[1] = GEN_INT (-INTVAL (operands[1]));
6834           return "sub{b}\t{%1, %0|%0, %1}";
6835         }
6836       return "add{b}\t{%1, %0|%0, %1}";
6837     }
6839   [(set (attr "type")
6840      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6841         (const_string "incdec")
6842         (const_string "alu1")))
6843    (set (attr "memory")
6844      (if_then_else (match_operand 1 "memory_operand" "")
6845         (const_string "load")
6846         (const_string "none")))
6847    (set_attr "mode" "QI")])
6849 (define_insn "*addqi_2"
6850   [(set (reg FLAGS_REG)
6851         (compare
6852           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6853                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6854           (const_int 0)))
6855    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6856         (plus:QI (match_dup 1) (match_dup 2)))]
6857   "ix86_match_ccmode (insn, CCGOCmode)
6858    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6860   switch (get_attr_type (insn))
6861     {
6862     case TYPE_INCDEC:
6863       if (operands[2] == const1_rtx)
6864         return "inc{b}\t%0";
6865       else
6866         {
6867           gcc_assert (operands[2] == constm1_rtx
6868                       || (CONST_INT_P (operands[2])
6869                           && INTVAL (operands[2]) == 255));
6870           return "dec{b}\t%0";
6871         }
6873     default:
6874       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6875       if (CONST_INT_P (operands[2])
6876           && INTVAL (operands[2]) < 0)
6877         {
6878           operands[2] = GEN_INT (-INTVAL (operands[2]));
6879           return "sub{b}\t{%2, %0|%0, %2}";
6880         }
6881       return "add{b}\t{%2, %0|%0, %2}";
6882     }
6884   [(set (attr "type")
6885      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6886         (const_string "incdec")
6887         (const_string "alu")))
6888    (set_attr "mode" "QI")])
6890 (define_insn "*addqi_3"
6891   [(set (reg FLAGS_REG)
6892         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6893                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6894    (clobber (match_scratch:QI 0 "=q"))]
6895   "ix86_match_ccmode (insn, CCZmode)
6896    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898   switch (get_attr_type (insn))
6899     {
6900     case TYPE_INCDEC:
6901       if (operands[2] == const1_rtx)
6902         return "inc{b}\t%0";
6903       else
6904         {
6905           gcc_assert (operands[2] == constm1_rtx
6906                       || (CONST_INT_P (operands[2])
6907                           && INTVAL (operands[2]) == 255));
6908           return "dec{b}\t%0";
6909         }
6911     default:
6912       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6913       if (CONST_INT_P (operands[2])
6914           && INTVAL (operands[2]) < 0)
6915         {
6916           operands[2] = GEN_INT (-INTVAL (operands[2]));
6917           return "sub{b}\t{%2, %0|%0, %2}";
6918         }
6919       return "add{b}\t{%2, %0|%0, %2}";
6920     }
6922   [(set (attr "type")
6923      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6924         (const_string "incdec")
6925         (const_string "alu")))
6926    (set_attr "mode" "QI")])
6928 ; See comments above addsi_4 for details.
6929 (define_insn "*addqi_4"
6930   [(set (reg FLAGS_REG)
6931         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6932                  (match_operand:QI 2 "const_int_operand" "n")))
6933    (clobber (match_scratch:QI 0 "=qm"))]
6934   "ix86_match_ccmode (insn, CCGCmode)
6935    && (INTVAL (operands[2]) & 0xff) != 0x80"
6937   switch (get_attr_type (insn))
6938     {
6939     case TYPE_INCDEC:
6940       if (operands[2] == constm1_rtx
6941           || (CONST_INT_P (operands[2])
6942               && INTVAL (operands[2]) == 255))
6943         return "inc{b}\t%0";
6944       else
6945         {
6946           gcc_assert (operands[2] == const1_rtx);
6947           return "dec{b}\t%0";
6948         }
6950     default:
6951       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6952       if (INTVAL (operands[2]) < 0)
6953         {
6954           operands[2] = GEN_INT (-INTVAL (operands[2]));
6955           return "add{b}\t{%2, %0|%0, %2}";
6956         }
6957       return "sub{b}\t{%2, %0|%0, %2}";
6958     }
6960   [(set (attr "type")
6961      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6962         (const_string "incdec")
6963         (const_string "alu")))
6964    (set_attr "mode" "QI")])
6967 (define_insn "*addqi_5"
6968   [(set (reg FLAGS_REG)
6969         (compare
6970           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6971                    (match_operand:QI 2 "general_operand" "qmni"))
6972           (const_int 0)))
6973    (clobber (match_scratch:QI 0 "=q"))]
6974   "ix86_match_ccmode (insn, CCGOCmode)
6975    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6977   switch (get_attr_type (insn))
6978     {
6979     case TYPE_INCDEC:
6980       if (operands[2] == const1_rtx)
6981         return "inc{b}\t%0";
6982       else
6983         {
6984           gcc_assert (operands[2] == constm1_rtx
6985                       || (CONST_INT_P (operands[2])
6986                           && INTVAL (operands[2]) == 255));
6987           return "dec{b}\t%0";
6988         }
6990     default:
6991       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6992       if (CONST_INT_P (operands[2])
6993           && INTVAL (operands[2]) < 0)
6994         {
6995           operands[2] = GEN_INT (-INTVAL (operands[2]));
6996           return "sub{b}\t{%2, %0|%0, %2}";
6997         }
6998       return "add{b}\t{%2, %0|%0, %2}";
6999     }
7001   [(set (attr "type")
7002      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7003         (const_string "incdec")
7004         (const_string "alu")))
7005    (set_attr "mode" "QI")])
7008 (define_insn "addqi_ext_1"
7009   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7010                          (const_int 8)
7011                          (const_int 8))
7012         (plus:SI
7013           (zero_extract:SI
7014             (match_operand 1 "ext_register_operand" "0")
7015             (const_int 8)
7016             (const_int 8))
7017           (match_operand:QI 2 "general_operand" "Qmn")))
7018    (clobber (reg:CC FLAGS_REG))]
7019   "!TARGET_64BIT"
7021   switch (get_attr_type (insn))
7022     {
7023     case TYPE_INCDEC:
7024       if (operands[2] == const1_rtx)
7025         return "inc{b}\t%h0";
7026       else
7027         {
7028           gcc_assert (operands[2] == constm1_rtx
7029                       || (CONST_INT_P (operands[2])
7030                           && INTVAL (operands[2]) == 255));
7031           return "dec{b}\t%h0";
7032         }
7034     default:
7035       return "add{b}\t{%2, %h0|%h0, %2}";
7036     }
7038   [(set (attr "type")
7039      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7040         (const_string "incdec")
7041         (const_string "alu")))
7042    (set_attr "mode" "QI")])
7044 (define_insn "*addqi_ext_1_rex64"
7045   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7046                          (const_int 8)
7047                          (const_int 8))
7048         (plus:SI
7049           (zero_extract:SI
7050             (match_operand 1 "ext_register_operand" "0")
7051             (const_int 8)
7052             (const_int 8))
7053           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7054    (clobber (reg:CC FLAGS_REG))]
7055   "TARGET_64BIT"
7057   switch (get_attr_type (insn))
7058     {
7059     case TYPE_INCDEC:
7060       if (operands[2] == const1_rtx)
7061         return "inc{b}\t%h0";
7062       else
7063         {
7064           gcc_assert (operands[2] == constm1_rtx
7065                       || (CONST_INT_P (operands[2])
7066                           && INTVAL (operands[2]) == 255));
7067           return "dec{b}\t%h0";
7068         }
7070     default:
7071       return "add{b}\t{%2, %h0|%h0, %2}";
7072     }
7074   [(set (attr "type")
7075      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7076         (const_string "incdec")
7077         (const_string "alu")))
7078    (set_attr "mode" "QI")])
7080 (define_insn "*addqi_ext_2"
7081   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7082                          (const_int 8)
7083                          (const_int 8))
7084         (plus:SI
7085           (zero_extract:SI
7086             (match_operand 1 "ext_register_operand" "%0")
7087             (const_int 8)
7088             (const_int 8))
7089           (zero_extract:SI
7090             (match_operand 2 "ext_register_operand" "Q")
7091             (const_int 8)
7092             (const_int 8))))
7093    (clobber (reg:CC FLAGS_REG))]
7094   ""
7095   "add{b}\t{%h2, %h0|%h0, %h2}"
7096   [(set_attr "type" "alu")
7097    (set_attr "mode" "QI")])
7099 ;; The patterns that match these are at the end of this file.
7101 (define_expand "addxf3"
7102   [(set (match_operand:XF 0 "register_operand" "")
7103         (plus:XF (match_operand:XF 1 "register_operand" "")
7104                  (match_operand:XF 2 "register_operand" "")))]
7105   "TARGET_80387"
7106   "")
7108 (define_expand "add<mode>3"
7109   [(set (match_operand:MODEF 0 "register_operand" "")
7110         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7111                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7112   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7113   "")
7115 ;; Subtract instructions
7117 ;; %%% splits for subditi3
7119 (define_expand "subti3"
7120   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7121                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7122                              (match_operand:TI 2 "x86_64_general_operand" "")))
7123               (clobber (reg:CC FLAGS_REG))])]
7124   "TARGET_64BIT"
7125   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7127 (define_insn "*subti3_1"
7128   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7129         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7130                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7131    (clobber (reg:CC FLAGS_REG))]
7132   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7133   "#")
7135 (define_split
7136   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7137         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7138                   (match_operand:TI 2 "x86_64_general_operand" "")))
7139    (clobber (reg:CC FLAGS_REG))]
7140   "TARGET_64BIT && reload_completed"
7141   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7142               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7143    (parallel [(set (match_dup 3)
7144                    (minus:DI (match_dup 4)
7145                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7146                                       (match_dup 5))))
7147               (clobber (reg:CC FLAGS_REG))])]
7148   "split_ti (operands+0, 1, operands+0, operands+3);
7149    split_ti (operands+1, 1, operands+1, operands+4);
7150    split_ti (operands+2, 1, operands+2, operands+5);")
7152 ;; %%% splits for subsidi3
7154 (define_expand "subdi3"
7155   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7156                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7157                              (match_operand:DI 2 "x86_64_general_operand" "")))
7158               (clobber (reg:CC FLAGS_REG))])]
7159   ""
7160   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7162 (define_insn "*subdi3_1"
7163   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7164         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7165                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7166    (clobber (reg:CC FLAGS_REG))]
7167   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7168   "#")
7170 (define_split
7171   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7172         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7173                   (match_operand:DI 2 "general_operand" "")))
7174    (clobber (reg:CC FLAGS_REG))]
7175   "!TARGET_64BIT && reload_completed"
7176   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7177               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7178    (parallel [(set (match_dup 3)
7179                    (minus:SI (match_dup 4)
7180                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7181                                       (match_dup 5))))
7182               (clobber (reg:CC FLAGS_REG))])]
7183   "split_di (operands+0, 1, operands+0, operands+3);
7184    split_di (operands+1, 1, operands+1, operands+4);
7185    split_di (operands+2, 1, operands+2, operands+5);")
7187 (define_insn "subdi3_carry_rex64"
7188   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7189           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7190             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7191                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7192    (clobber (reg:CC FLAGS_REG))]
7193   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7194   "sbb{q}\t{%2, %0|%0, %2}"
7195   [(set_attr "type" "alu")
7196    (set_attr "pent_pair" "pu")
7197    (set_attr "mode" "DI")])
7199 (define_insn "*subdi_1_rex64"
7200   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7201         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7202                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7203    (clobber (reg:CC FLAGS_REG))]
7204   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7205   "sub{q}\t{%2, %0|%0, %2}"
7206   [(set_attr "type" "alu")
7207    (set_attr "mode" "DI")])
7209 (define_insn "*subdi_2_rex64"
7210   [(set (reg FLAGS_REG)
7211         (compare
7212           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7213                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7214           (const_int 0)))
7215    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7216         (minus:DI (match_dup 1) (match_dup 2)))]
7217   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7218    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7219   "sub{q}\t{%2, %0|%0, %2}"
7220   [(set_attr "type" "alu")
7221    (set_attr "mode" "DI")])
7223 (define_insn "*subdi_3_rex63"
7224   [(set (reg FLAGS_REG)
7225         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7226                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7227    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7228         (minus:DI (match_dup 1) (match_dup 2)))]
7229   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7230    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7231   "sub{q}\t{%2, %0|%0, %2}"
7232   [(set_attr "type" "alu")
7233    (set_attr "mode" "DI")])
7235 (define_insn "subqi3_carry"
7236   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7237           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7238             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7239                (match_operand:QI 2 "general_operand" "qi,qm"))))
7240    (clobber (reg:CC FLAGS_REG))]
7241   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7242   "sbb{b}\t{%2, %0|%0, %2}"
7243   [(set_attr "type" "alu")
7244    (set_attr "pent_pair" "pu")
7245    (set_attr "mode" "QI")])
7247 (define_insn "subhi3_carry"
7248   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7249           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7250             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7251                (match_operand:HI 2 "general_operand" "ri,rm"))))
7252    (clobber (reg:CC FLAGS_REG))]
7253   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7254   "sbb{w}\t{%2, %0|%0, %2}"
7255   [(set_attr "type" "alu")
7256    (set_attr "pent_pair" "pu")
7257    (set_attr "mode" "HI")])
7259 (define_insn "subsi3_carry"
7260   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7261           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7262             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7263                (match_operand:SI 2 "general_operand" "ri,rm"))))
7264    (clobber (reg:CC FLAGS_REG))]
7265   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7266   "sbb{l}\t{%2, %0|%0, %2}"
7267   [(set_attr "type" "alu")
7268    (set_attr "pent_pair" "pu")
7269    (set_attr "mode" "SI")])
7271 (define_insn "subsi3_carry_zext"
7272   [(set (match_operand:DI 0 "register_operand" "=r")
7273           (zero_extend:DI
7274             (minus:SI (match_operand:SI 1 "register_operand" "0")
7275               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7276                  (match_operand:SI 2 "general_operand" "g")))))
7277    (clobber (reg:CC FLAGS_REG))]
7278   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7279   "sbb{l}\t{%2, %k0|%k0, %2}"
7280   [(set_attr "type" "alu")
7281    (set_attr "pent_pair" "pu")
7282    (set_attr "mode" "SI")])
7284 (define_expand "subsi3"
7285   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7286                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7287                              (match_operand:SI 2 "general_operand" "")))
7288               (clobber (reg:CC FLAGS_REG))])]
7289   ""
7290   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7292 (define_insn "*subsi_1"
7293   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7294         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7295                   (match_operand:SI 2 "general_operand" "ri,rm")))
7296    (clobber (reg:CC FLAGS_REG))]
7297   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7298   "sub{l}\t{%2, %0|%0, %2}"
7299   [(set_attr "type" "alu")
7300    (set_attr "mode" "SI")])
7302 (define_insn "*subsi_1_zext"
7303   [(set (match_operand:DI 0 "register_operand" "=r")
7304         (zero_extend:DI
7305           (minus:SI (match_operand:SI 1 "register_operand" "0")
7306                     (match_operand:SI 2 "general_operand" "g"))))
7307    (clobber (reg:CC FLAGS_REG))]
7308   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7309   "sub{l}\t{%2, %k0|%k0, %2}"
7310   [(set_attr "type" "alu")
7311    (set_attr "mode" "SI")])
7313 (define_insn "*subsi_2"
7314   [(set (reg FLAGS_REG)
7315         (compare
7316           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7317                     (match_operand:SI 2 "general_operand" "ri,rm"))
7318           (const_int 0)))
7319    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7320         (minus:SI (match_dup 1) (match_dup 2)))]
7321   "ix86_match_ccmode (insn, CCGOCmode)
7322    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7323   "sub{l}\t{%2, %0|%0, %2}"
7324   [(set_attr "type" "alu")
7325    (set_attr "mode" "SI")])
7327 (define_insn "*subsi_2_zext"
7328   [(set (reg FLAGS_REG)
7329         (compare
7330           (minus:SI (match_operand:SI 1 "register_operand" "0")
7331                     (match_operand:SI 2 "general_operand" "g"))
7332           (const_int 0)))
7333    (set (match_operand:DI 0 "register_operand" "=r")
7334         (zero_extend:DI
7335           (minus:SI (match_dup 1)
7336                     (match_dup 2))))]
7337   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7338    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339   "sub{l}\t{%2, %k0|%k0, %2}"
7340   [(set_attr "type" "alu")
7341    (set_attr "mode" "SI")])
7343 (define_insn "*subsi_3"
7344   [(set (reg FLAGS_REG)
7345         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7346                  (match_operand:SI 2 "general_operand" "ri,rm")))
7347    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7348         (minus:SI (match_dup 1) (match_dup 2)))]
7349   "ix86_match_ccmode (insn, CCmode)
7350    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7351   "sub{l}\t{%2, %0|%0, %2}"
7352   [(set_attr "type" "alu")
7353    (set_attr "mode" "SI")])
7355 (define_insn "*subsi_3_zext"
7356   [(set (reg FLAGS_REG)
7357         (compare (match_operand:SI 1 "register_operand" "0")
7358                  (match_operand:SI 2 "general_operand" "g")))
7359    (set (match_operand:DI 0 "register_operand" "=r")
7360         (zero_extend:DI
7361           (minus:SI (match_dup 1)
7362                     (match_dup 2))))]
7363   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7364    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7365   "sub{l}\t{%2, %1|%1, %2}"
7366   [(set_attr "type" "alu")
7367    (set_attr "mode" "DI")])
7369 (define_expand "subhi3"
7370   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7371                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7372                              (match_operand:HI 2 "general_operand" "")))
7373               (clobber (reg:CC FLAGS_REG))])]
7374   "TARGET_HIMODE_MATH"
7375   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7377 (define_insn "*subhi_1"
7378   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7379         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7380                   (match_operand:HI 2 "general_operand" "ri,rm")))
7381    (clobber (reg:CC FLAGS_REG))]
7382   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7383   "sub{w}\t{%2, %0|%0, %2}"
7384   [(set_attr "type" "alu")
7385    (set_attr "mode" "HI")])
7387 (define_insn "*subhi_2"
7388   [(set (reg FLAGS_REG)
7389         (compare
7390           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7391                     (match_operand:HI 2 "general_operand" "ri,rm"))
7392           (const_int 0)))
7393    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7394         (minus:HI (match_dup 1) (match_dup 2)))]
7395   "ix86_match_ccmode (insn, CCGOCmode)
7396    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7397   "sub{w}\t{%2, %0|%0, %2}"
7398   [(set_attr "type" "alu")
7399    (set_attr "mode" "HI")])
7401 (define_insn "*subhi_3"
7402   [(set (reg FLAGS_REG)
7403         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7404                  (match_operand:HI 2 "general_operand" "ri,rm")))
7405    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7406         (minus:HI (match_dup 1) (match_dup 2)))]
7407   "ix86_match_ccmode (insn, CCmode)
7408    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7409   "sub{w}\t{%2, %0|%0, %2}"
7410   [(set_attr "type" "alu")
7411    (set_attr "mode" "HI")])
7413 (define_expand "subqi3"
7414   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7415                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7416                              (match_operand:QI 2 "general_operand" "")))
7417               (clobber (reg:CC FLAGS_REG))])]
7418   "TARGET_QIMODE_MATH"
7419   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7421 (define_insn "*subqi_1"
7422   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7423         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7424                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7425    (clobber (reg:CC FLAGS_REG))]
7426   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7427   "sub{b}\t{%2, %0|%0, %2}"
7428   [(set_attr "type" "alu")
7429    (set_attr "mode" "QI")])
7431 (define_insn "*subqi_1_slp"
7432   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7433         (minus:QI (match_dup 0)
7434                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7435    (clobber (reg:CC FLAGS_REG))]
7436   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7437    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7438   "sub{b}\t{%1, %0|%0, %1}"
7439   [(set_attr "type" "alu1")
7440    (set_attr "mode" "QI")])
7442 (define_insn "*subqi_2"
7443   [(set (reg FLAGS_REG)
7444         (compare
7445           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7446                     (match_operand:QI 2 "general_operand" "qi,qm"))
7447           (const_int 0)))
7448    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7449         (minus:HI (match_dup 1) (match_dup 2)))]
7450   "ix86_match_ccmode (insn, CCGOCmode)
7451    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7452   "sub{b}\t{%2, %0|%0, %2}"
7453   [(set_attr "type" "alu")
7454    (set_attr "mode" "QI")])
7456 (define_insn "*subqi_3"
7457   [(set (reg FLAGS_REG)
7458         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7459                  (match_operand:QI 2 "general_operand" "qi,qm")))
7460    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7461         (minus:HI (match_dup 1) (match_dup 2)))]
7462   "ix86_match_ccmode (insn, CCmode)
7463    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7464   "sub{b}\t{%2, %0|%0, %2}"
7465   [(set_attr "type" "alu")
7466    (set_attr "mode" "QI")])
7468 ;; The patterns that match these are at the end of this file.
7470 (define_expand "subxf3"
7471   [(set (match_operand:XF 0 "register_operand" "")
7472         (minus:XF (match_operand:XF 1 "register_operand" "")
7473                   (match_operand:XF 2 "register_operand" "")))]
7474   "TARGET_80387"
7475   "")
7477 (define_expand "sub<mode>3"
7478   [(set (match_operand:MODEF 0 "register_operand" "")
7479         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7480                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7481   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7482   "")
7484 ;; Multiply instructions
7486 (define_expand "muldi3"
7487   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488                    (mult:DI (match_operand:DI 1 "register_operand" "")
7489                             (match_operand:DI 2 "x86_64_general_operand" "")))
7490               (clobber (reg:CC FLAGS_REG))])]
7491   "TARGET_64BIT"
7492   "")
7494 ;; On AMDFAM10
7495 ;; IMUL reg64, reg64, imm8      Direct
7496 ;; IMUL reg64, mem64, imm8      VectorPath
7497 ;; IMUL reg64, reg64, imm32     Direct
7498 ;; IMUL reg64, mem64, imm32     VectorPath
7499 ;; IMUL reg64, reg64            Direct
7500 ;; IMUL reg64, mem64            Direct
7502 (define_insn "*muldi3_1_rex64"
7503   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7504         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7505                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7506    (clobber (reg:CC FLAGS_REG))]
7507   "TARGET_64BIT
7508    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7509   "@
7510    imul{q}\t{%2, %1, %0|%0, %1, %2}
7511    imul{q}\t{%2, %1, %0|%0, %1, %2}
7512    imul{q}\t{%2, %0|%0, %2}"
7513   [(set_attr "type" "imul")
7514    (set_attr "prefix_0f" "0,0,1")
7515    (set (attr "athlon_decode")
7516         (cond [(eq_attr "cpu" "athlon")
7517                   (const_string "vector")
7518                (eq_attr "alternative" "1")
7519                   (const_string "vector")
7520                (and (eq_attr "alternative" "2")
7521                     (match_operand 1 "memory_operand" ""))
7522                   (const_string "vector")]
7523               (const_string "direct")))
7524    (set (attr "amdfam10_decode")
7525         (cond [(and (eq_attr "alternative" "0,1")
7526                     (match_operand 1 "memory_operand" ""))
7527                   (const_string "vector")]
7528               (const_string "direct")))
7529    (set_attr "mode" "DI")])
7531 (define_expand "mulsi3"
7532   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7533                    (mult:SI (match_operand:SI 1 "register_operand" "")
7534                             (match_operand:SI 2 "general_operand" "")))
7535               (clobber (reg:CC FLAGS_REG))])]
7536   ""
7537   "")
7539 ;; On AMDFAM10
7540 ;; IMUL reg32, reg32, imm8      Direct
7541 ;; IMUL reg32, mem32, imm8      VectorPath
7542 ;; IMUL reg32, reg32, imm32     Direct
7543 ;; IMUL reg32, mem32, imm32     VectorPath
7544 ;; IMUL reg32, reg32            Direct
7545 ;; IMUL reg32, mem32            Direct
7547 (define_insn "*mulsi3_1"
7548   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7549         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7550                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7551    (clobber (reg:CC FLAGS_REG))]
7552   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7553   "@
7554    imul{l}\t{%2, %1, %0|%0, %1, %2}
7555    imul{l}\t{%2, %1, %0|%0, %1, %2}
7556    imul{l}\t{%2, %0|%0, %2}"
7557   [(set_attr "type" "imul")
7558    (set_attr "prefix_0f" "0,0,1")
7559    (set (attr "athlon_decode")
7560         (cond [(eq_attr "cpu" "athlon")
7561                   (const_string "vector")
7562                (eq_attr "alternative" "1")
7563                   (const_string "vector")
7564                (and (eq_attr "alternative" "2")
7565                     (match_operand 1 "memory_operand" ""))
7566                   (const_string "vector")]
7567               (const_string "direct")))
7568    (set (attr "amdfam10_decode")
7569         (cond [(and (eq_attr "alternative" "0,1")
7570                     (match_operand 1 "memory_operand" ""))
7571                   (const_string "vector")]
7572               (const_string "direct")))
7573    (set_attr "mode" "SI")])
7575 (define_insn "*mulsi3_1_zext"
7576   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7577         (zero_extend:DI
7578           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7579                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7580    (clobber (reg:CC FLAGS_REG))]
7581   "TARGET_64BIT
7582    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7583   "@
7584    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7585    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7586    imul{l}\t{%2, %k0|%k0, %2}"
7587   [(set_attr "type" "imul")
7588    (set_attr "prefix_0f" "0,0,1")
7589    (set (attr "athlon_decode")
7590         (cond [(eq_attr "cpu" "athlon")
7591                   (const_string "vector")
7592                (eq_attr "alternative" "1")
7593                   (const_string "vector")
7594                (and (eq_attr "alternative" "2")
7595                     (match_operand 1 "memory_operand" ""))
7596                   (const_string "vector")]
7597               (const_string "direct")))
7598    (set (attr "amdfam10_decode")
7599         (cond [(and (eq_attr "alternative" "0,1")
7600                     (match_operand 1 "memory_operand" ""))
7601                   (const_string "vector")]
7602               (const_string "direct")))
7603    (set_attr "mode" "SI")])
7605 (define_expand "mulhi3"
7606   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7607                    (mult:HI (match_operand:HI 1 "register_operand" "")
7608                             (match_operand:HI 2 "general_operand" "")))
7609               (clobber (reg:CC FLAGS_REG))])]
7610   "TARGET_HIMODE_MATH"
7611   "")
7613 ;; On AMDFAM10
7614 ;; IMUL reg16, reg16, imm8      VectorPath
7615 ;; IMUL reg16, mem16, imm8      VectorPath
7616 ;; IMUL reg16, reg16, imm16     VectorPath
7617 ;; IMUL reg16, mem16, imm16     VectorPath
7618 ;; IMUL reg16, reg16            Direct
7619 ;; IMUL reg16, mem16            Direct
7620 (define_insn "*mulhi3_1"
7621   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7622         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7623                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7624    (clobber (reg:CC FLAGS_REG))]
7625   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7626   "@
7627    imul{w}\t{%2, %1, %0|%0, %1, %2}
7628    imul{w}\t{%2, %1, %0|%0, %1, %2}
7629    imul{w}\t{%2, %0|%0, %2}"
7630   [(set_attr "type" "imul")
7631    (set_attr "prefix_0f" "0,0,1")
7632    (set (attr "athlon_decode")
7633         (cond [(eq_attr "cpu" "athlon")
7634                   (const_string "vector")
7635                (eq_attr "alternative" "1,2")
7636                   (const_string "vector")]
7637               (const_string "direct")))
7638    (set (attr "amdfam10_decode")
7639         (cond [(eq_attr "alternative" "0,1")
7640                   (const_string "vector")]
7641               (const_string "direct")))
7642    (set_attr "mode" "HI")])
7644 (define_expand "mulqi3"
7645   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7646                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7647                             (match_operand:QI 2 "register_operand" "")))
7648               (clobber (reg:CC FLAGS_REG))])]
7649   "TARGET_QIMODE_MATH"
7650   "")
7652 ;;On AMDFAM10
7653 ;; MUL reg8     Direct
7654 ;; MUL mem8     Direct
7656 (define_insn "*mulqi3_1"
7657   [(set (match_operand:QI 0 "register_operand" "=a")
7658         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7659                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7660    (clobber (reg:CC FLAGS_REG))]
7661   "TARGET_QIMODE_MATH
7662    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663   "mul{b}\t%2"
7664   [(set_attr "type" "imul")
7665    (set_attr "length_immediate" "0")
7666    (set (attr "athlon_decode")
7667      (if_then_else (eq_attr "cpu" "athlon")
7668         (const_string "vector")
7669         (const_string "direct")))
7670    (set_attr "amdfam10_decode" "direct")
7671    (set_attr "mode" "QI")])
7673 (define_expand "umulqihi3"
7674   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7675                    (mult:HI (zero_extend:HI
7676                               (match_operand:QI 1 "nonimmediate_operand" ""))
7677                             (zero_extend:HI
7678                               (match_operand:QI 2 "register_operand" ""))))
7679               (clobber (reg:CC FLAGS_REG))])]
7680   "TARGET_QIMODE_MATH"
7681   "")
7683 (define_insn "*umulqihi3_1"
7684   [(set (match_operand:HI 0 "register_operand" "=a")
7685         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7686                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7687    (clobber (reg:CC FLAGS_REG))]
7688   "TARGET_QIMODE_MATH
7689    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7690   "mul{b}\t%2"
7691   [(set_attr "type" "imul")
7692    (set_attr "length_immediate" "0")
7693    (set (attr "athlon_decode")
7694      (if_then_else (eq_attr "cpu" "athlon")
7695         (const_string "vector")
7696         (const_string "direct")))
7697    (set_attr "amdfam10_decode" "direct")
7698    (set_attr "mode" "QI")])
7700 (define_expand "mulqihi3"
7701   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7702                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7703                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7704               (clobber (reg:CC FLAGS_REG))])]
7705   "TARGET_QIMODE_MATH"
7706   "")
7708 (define_insn "*mulqihi3_insn"
7709   [(set (match_operand:HI 0 "register_operand" "=a")
7710         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7711                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7712    (clobber (reg:CC FLAGS_REG))]
7713   "TARGET_QIMODE_MATH
7714    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7715   "imul{b}\t%2"
7716   [(set_attr "type" "imul")
7717    (set_attr "length_immediate" "0")
7718    (set (attr "athlon_decode")
7719      (if_then_else (eq_attr "cpu" "athlon")
7720         (const_string "vector")
7721         (const_string "direct")))
7722    (set_attr "amdfam10_decode" "direct")
7723    (set_attr "mode" "QI")])
7725 (define_expand "umulditi3"
7726   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7727                    (mult:TI (zero_extend:TI
7728                               (match_operand:DI 1 "nonimmediate_operand" ""))
7729                             (zero_extend:TI
7730                               (match_operand:DI 2 "register_operand" ""))))
7731               (clobber (reg:CC FLAGS_REG))])]
7732   "TARGET_64BIT"
7733   "")
7735 (define_insn "*umulditi3_insn"
7736   [(set (match_operand:TI 0 "register_operand" "=A")
7737         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7738                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7739    (clobber (reg:CC FLAGS_REG))]
7740   "TARGET_64BIT
7741    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7742   "mul{q}\t%2"
7743   [(set_attr "type" "imul")
7744    (set_attr "length_immediate" "0")
7745    (set (attr "athlon_decode")
7746      (if_then_else (eq_attr "cpu" "athlon")
7747         (const_string "vector")
7748         (const_string "double")))
7749    (set_attr "amdfam10_decode" "double")
7750    (set_attr "mode" "DI")])
7752 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7753 (define_expand "umulsidi3"
7754   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7755                    (mult:DI (zero_extend:DI
7756                               (match_operand:SI 1 "nonimmediate_operand" ""))
7757                             (zero_extend:DI
7758                               (match_operand:SI 2 "register_operand" ""))))
7759               (clobber (reg:CC FLAGS_REG))])]
7760   "!TARGET_64BIT"
7761   "")
7763 (define_insn "*umulsidi3_insn"
7764   [(set (match_operand:DI 0 "register_operand" "=A")
7765         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7766                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7767    (clobber (reg:CC FLAGS_REG))]
7768   "!TARGET_64BIT
7769    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7770   "mul{l}\t%2"
7771   [(set_attr "type" "imul")
7772    (set_attr "length_immediate" "0")
7773    (set (attr "athlon_decode")
7774      (if_then_else (eq_attr "cpu" "athlon")
7775         (const_string "vector")
7776         (const_string "double")))
7777    (set_attr "amdfam10_decode" "double")
7778    (set_attr "mode" "SI")])
7780 (define_expand "mulditi3"
7781   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7782                    (mult:TI (sign_extend:TI
7783                               (match_operand:DI 1 "nonimmediate_operand" ""))
7784                             (sign_extend:TI
7785                               (match_operand:DI 2 "register_operand" ""))))
7786               (clobber (reg:CC FLAGS_REG))])]
7787   "TARGET_64BIT"
7788   "")
7790 (define_insn "*mulditi3_insn"
7791   [(set (match_operand:TI 0 "register_operand" "=A")
7792         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7793                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7794    (clobber (reg:CC FLAGS_REG))]
7795   "TARGET_64BIT
7796    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7797   "imul{q}\t%2"
7798   [(set_attr "type" "imul")
7799    (set_attr "length_immediate" "0")
7800    (set (attr "athlon_decode")
7801      (if_then_else (eq_attr "cpu" "athlon")
7802         (const_string "vector")
7803         (const_string "double")))
7804    (set_attr "amdfam10_decode" "double")
7805    (set_attr "mode" "DI")])
7807 (define_expand "mulsidi3"
7808   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7809                    (mult:DI (sign_extend:DI
7810                               (match_operand:SI 1 "nonimmediate_operand" ""))
7811                             (sign_extend:DI
7812                               (match_operand:SI 2 "register_operand" ""))))
7813               (clobber (reg:CC FLAGS_REG))])]
7814   "!TARGET_64BIT"
7815   "")
7817 (define_insn "*mulsidi3_insn"
7818   [(set (match_operand:DI 0 "register_operand" "=A")
7819         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7820                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7821    (clobber (reg:CC FLAGS_REG))]
7822   "!TARGET_64BIT
7823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7824   "imul{l}\t%2"
7825   [(set_attr "type" "imul")
7826    (set_attr "length_immediate" "0")
7827    (set (attr "athlon_decode")
7828      (if_then_else (eq_attr "cpu" "athlon")
7829         (const_string "vector")
7830         (const_string "double")))
7831    (set_attr "amdfam10_decode" "double")
7832    (set_attr "mode" "SI")])
7834 (define_expand "umuldi3_highpart"
7835   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7836                    (truncate:DI
7837                      (lshiftrt:TI
7838                        (mult:TI (zero_extend:TI
7839                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7840                                 (zero_extend:TI
7841                                   (match_operand:DI 2 "register_operand" "")))
7842                        (const_int 64))))
7843               (clobber (match_scratch:DI 3 ""))
7844               (clobber (reg:CC FLAGS_REG))])]
7845   "TARGET_64BIT"
7846   "")
7848 (define_insn "*umuldi3_highpart_rex64"
7849   [(set (match_operand:DI 0 "register_operand" "=d")
7850         (truncate:DI
7851           (lshiftrt:TI
7852             (mult:TI (zero_extend:TI
7853                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7854                      (zero_extend:TI
7855                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7856             (const_int 64))))
7857    (clobber (match_scratch:DI 3 "=1"))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "TARGET_64BIT
7860    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7861   "mul{q}\t%2"
7862   [(set_attr "type" "imul")
7863    (set_attr "length_immediate" "0")
7864    (set (attr "athlon_decode")
7865      (if_then_else (eq_attr "cpu" "athlon")
7866         (const_string "vector")
7867         (const_string "double")))
7868    (set_attr "amdfam10_decode" "double")
7869    (set_attr "mode" "DI")])
7871 (define_expand "umulsi3_highpart"
7872   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7873                    (truncate:SI
7874                      (lshiftrt:DI
7875                        (mult:DI (zero_extend:DI
7876                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7877                                 (zero_extend:DI
7878                                   (match_operand:SI 2 "register_operand" "")))
7879                        (const_int 32))))
7880               (clobber (match_scratch:SI 3 ""))
7881               (clobber (reg:CC FLAGS_REG))])]
7882   ""
7883   "")
7885 (define_insn "*umulsi3_highpart_insn"
7886   [(set (match_operand:SI 0 "register_operand" "=d")
7887         (truncate:SI
7888           (lshiftrt:DI
7889             (mult:DI (zero_extend:DI
7890                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7891                      (zero_extend:DI
7892                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7893             (const_int 32))))
7894    (clobber (match_scratch:SI 3 "=1"))
7895    (clobber (reg:CC FLAGS_REG))]
7896   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7897   "mul{l}\t%2"
7898   [(set_attr "type" "imul")
7899    (set_attr "length_immediate" "0")
7900    (set (attr "athlon_decode")
7901      (if_then_else (eq_attr "cpu" "athlon")
7902         (const_string "vector")
7903         (const_string "double")))
7904    (set_attr "amdfam10_decode" "double")
7905    (set_attr "mode" "SI")])
7907 (define_insn "*umulsi3_highpart_zext"
7908   [(set (match_operand:DI 0 "register_operand" "=d")
7909         (zero_extend:DI (truncate:SI
7910           (lshiftrt:DI
7911             (mult:DI (zero_extend:DI
7912                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7913                      (zero_extend:DI
7914                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7915             (const_int 32)))))
7916    (clobber (match_scratch:SI 3 "=1"))
7917    (clobber (reg:CC FLAGS_REG))]
7918   "TARGET_64BIT
7919    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7920   "mul{l}\t%2"
7921   [(set_attr "type" "imul")
7922    (set_attr "length_immediate" "0")
7923    (set (attr "athlon_decode")
7924      (if_then_else (eq_attr "cpu" "athlon")
7925         (const_string "vector")
7926         (const_string "double")))
7927    (set_attr "amdfam10_decode" "double")
7928    (set_attr "mode" "SI")])
7930 (define_expand "smuldi3_highpart"
7931   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7932                    (truncate:DI
7933                      (lshiftrt:TI
7934                        (mult:TI (sign_extend:TI
7935                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7936                                 (sign_extend:TI
7937                                   (match_operand:DI 2 "register_operand" "")))
7938                        (const_int 64))))
7939               (clobber (match_scratch:DI 3 ""))
7940               (clobber (reg:CC FLAGS_REG))])]
7941   "TARGET_64BIT"
7942   "")
7944 (define_insn "*smuldi3_highpart_rex64"
7945   [(set (match_operand:DI 0 "register_operand" "=d")
7946         (truncate:DI
7947           (lshiftrt:TI
7948             (mult:TI (sign_extend:TI
7949                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7950                      (sign_extend:TI
7951                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7952             (const_int 64))))
7953    (clobber (match_scratch:DI 3 "=1"))
7954    (clobber (reg:CC FLAGS_REG))]
7955   "TARGET_64BIT
7956    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7957   "imul{q}\t%2"
7958   [(set_attr "type" "imul")
7959    (set (attr "athlon_decode")
7960      (if_then_else (eq_attr "cpu" "athlon")
7961         (const_string "vector")
7962         (const_string "double")))
7963    (set_attr "amdfam10_decode" "double")
7964    (set_attr "mode" "DI")])
7966 (define_expand "smulsi3_highpart"
7967   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7968                    (truncate:SI
7969                      (lshiftrt:DI
7970                        (mult:DI (sign_extend:DI
7971                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7972                                 (sign_extend:DI
7973                                   (match_operand:SI 2 "register_operand" "")))
7974                        (const_int 32))))
7975               (clobber (match_scratch:SI 3 ""))
7976               (clobber (reg:CC FLAGS_REG))])]
7977   ""
7978   "")
7980 (define_insn "*smulsi3_highpart_insn"
7981   [(set (match_operand:SI 0 "register_operand" "=d")
7982         (truncate:SI
7983           (lshiftrt:DI
7984             (mult:DI (sign_extend:DI
7985                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7986                      (sign_extend:DI
7987                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7988             (const_int 32))))
7989    (clobber (match_scratch:SI 3 "=1"))
7990    (clobber (reg:CC FLAGS_REG))]
7991   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7992   "imul{l}\t%2"
7993   [(set_attr "type" "imul")
7994    (set (attr "athlon_decode")
7995      (if_then_else (eq_attr "cpu" "athlon")
7996         (const_string "vector")
7997         (const_string "double")))
7998    (set_attr "amdfam10_decode" "double")
7999    (set_attr "mode" "SI")])
8001 (define_insn "*smulsi3_highpart_zext"
8002   [(set (match_operand:DI 0 "register_operand" "=d")
8003         (zero_extend:DI (truncate:SI
8004           (lshiftrt:DI
8005             (mult:DI (sign_extend:DI
8006                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8007                      (sign_extend:DI
8008                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8009             (const_int 32)))))
8010    (clobber (match_scratch:SI 3 "=1"))
8011    (clobber (reg:CC FLAGS_REG))]
8012   "TARGET_64BIT
8013    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8014   "imul{l}\t%2"
8015   [(set_attr "type" "imul")
8016    (set (attr "athlon_decode")
8017      (if_then_else (eq_attr "cpu" "athlon")
8018         (const_string "vector")
8019         (const_string "double")))
8020    (set_attr "amdfam10_decode" "double")
8021    (set_attr "mode" "SI")])
8023 ;; The patterns that match these are at the end of this file.
8025 (define_expand "mulxf3"
8026   [(set (match_operand:XF 0 "register_operand" "")
8027         (mult:XF (match_operand:XF 1 "register_operand" "")
8028                  (match_operand:XF 2 "register_operand" "")))]
8029   "TARGET_80387"
8030   "")
8032 (define_expand "mul<mode>3"
8033   [(set (match_operand:MODEF 0 "register_operand" "")
8034         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8035                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8036   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8037   "")
8039 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8042 ;; Divide instructions
8044 (define_insn "divqi3"
8045   [(set (match_operand:QI 0 "register_operand" "=a")
8046         (div:QI (match_operand:HI 1 "register_operand" "0")
8047                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8048    (clobber (reg:CC FLAGS_REG))]
8049   "TARGET_QIMODE_MATH"
8050   "idiv{b}\t%2"
8051   [(set_attr "type" "idiv")
8052    (set_attr "mode" "QI")])
8054 (define_insn "udivqi3"
8055   [(set (match_operand:QI 0 "register_operand" "=a")
8056         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8057                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8058    (clobber (reg:CC FLAGS_REG))]
8059   "TARGET_QIMODE_MATH"
8060   "div{b}\t%2"
8061   [(set_attr "type" "idiv")
8062    (set_attr "mode" "QI")])
8064 ;; The patterns that match these are at the end of this file.
8066 (define_expand "divxf3"
8067   [(set (match_operand:XF 0 "register_operand" "")
8068         (div:XF (match_operand:XF 1 "register_operand" "")
8069                 (match_operand:XF 2 "register_operand" "")))]
8070   "TARGET_80387"
8071   "")
8073 (define_expand "divdf3"
8074   [(set (match_operand:DF 0 "register_operand" "")
8075         (div:DF (match_operand:DF 1 "register_operand" "")
8076                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8077    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8078    "")
8080 (define_expand "divsf3"
8081   [(set (match_operand:SF 0 "register_operand" "")
8082         (div:SF (match_operand:SF 1 "register_operand" "")
8083                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8084   "TARGET_80387 || TARGET_SSE_MATH"
8086   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8087       && flag_finite_math_only && !flag_trapping_math
8088       && flag_unsafe_math_optimizations)
8089     {
8090       ix86_emit_swdivsf (operands[0], operands[1],
8091                          operands[2], SFmode);
8092       DONE;
8093     }
8096 ;; Remainder instructions.
8098 (define_expand "divmoddi4"
8099   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8100                    (div:DI (match_operand:DI 1 "register_operand" "")
8101                            (match_operand:DI 2 "nonimmediate_operand" "")))
8102               (set (match_operand:DI 3 "register_operand" "")
8103                    (mod:DI (match_dup 1) (match_dup 2)))
8104               (clobber (reg:CC FLAGS_REG))])]
8105   "TARGET_64BIT"
8106   "")
8108 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8109 ;; Penalize eax case slightly because it results in worse scheduling
8110 ;; of code.
8111 (define_insn "*divmoddi4_nocltd_rex64"
8112   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8113         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8114                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8115    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8116         (mod:DI (match_dup 2) (match_dup 3)))
8117    (clobber (reg:CC FLAGS_REG))]
8118   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8119   "#"
8120   [(set_attr "type" "multi")])
8122 (define_insn "*divmoddi4_cltd_rex64"
8123   [(set (match_operand:DI 0 "register_operand" "=a")
8124         (div:DI (match_operand:DI 2 "register_operand" "a")
8125                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8126    (set (match_operand:DI 1 "register_operand" "=&d")
8127         (mod:DI (match_dup 2) (match_dup 3)))
8128    (clobber (reg:CC FLAGS_REG))]
8129   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8130   "#"
8131   [(set_attr "type" "multi")])
8133 (define_insn "*divmoddi_noext_rex64"
8134   [(set (match_operand:DI 0 "register_operand" "=a")
8135         (div:DI (match_operand:DI 1 "register_operand" "0")
8136                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8137    (set (match_operand:DI 3 "register_operand" "=d")
8138         (mod:DI (match_dup 1) (match_dup 2)))
8139    (use (match_operand:DI 4 "register_operand" "3"))
8140    (clobber (reg:CC FLAGS_REG))]
8141   "TARGET_64BIT"
8142   "idiv{q}\t%2"
8143   [(set_attr "type" "idiv")
8144    (set_attr "mode" "DI")])
8146 (define_split
8147   [(set (match_operand:DI 0 "register_operand" "")
8148         (div:DI (match_operand:DI 1 "register_operand" "")
8149                 (match_operand:DI 2 "nonimmediate_operand" "")))
8150    (set (match_operand:DI 3 "register_operand" "")
8151         (mod:DI (match_dup 1) (match_dup 2)))
8152    (clobber (reg:CC FLAGS_REG))]
8153   "TARGET_64BIT && reload_completed"
8154   [(parallel [(set (match_dup 3)
8155                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8156               (clobber (reg:CC FLAGS_REG))])
8157    (parallel [(set (match_dup 0)
8158                    (div:DI (reg:DI 0) (match_dup 2)))
8159               (set (match_dup 3)
8160                    (mod:DI (reg:DI 0) (match_dup 2)))
8161               (use (match_dup 3))
8162               (clobber (reg:CC FLAGS_REG))])]
8164   /* Avoid use of cltd in favor of a mov+shift.  */
8165   if (!TARGET_USE_CLTD && !optimize_size)
8166     {
8167       if (true_regnum (operands[1]))
8168         emit_move_insn (operands[0], operands[1]);
8169       else
8170         emit_move_insn (operands[3], operands[1]);
8171       operands[4] = operands[3];
8172     }
8173   else
8174     {
8175       gcc_assert (!true_regnum (operands[1]));
8176       operands[4] = operands[1];
8177     }
8181 (define_expand "divmodsi4"
8182   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8183                    (div:SI (match_operand:SI 1 "register_operand" "")
8184                            (match_operand:SI 2 "nonimmediate_operand" "")))
8185               (set (match_operand:SI 3 "register_operand" "")
8186                    (mod:SI (match_dup 1) (match_dup 2)))
8187               (clobber (reg:CC FLAGS_REG))])]
8188   ""
8189   "")
8191 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8192 ;; Penalize eax case slightly because it results in worse scheduling
8193 ;; of code.
8194 (define_insn "*divmodsi4_nocltd"
8195   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8196         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8197                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8198    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8199         (mod:SI (match_dup 2) (match_dup 3)))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "!optimize_size && !TARGET_USE_CLTD"
8202   "#"
8203   [(set_attr "type" "multi")])
8205 (define_insn "*divmodsi4_cltd"
8206   [(set (match_operand:SI 0 "register_operand" "=a")
8207         (div:SI (match_operand:SI 2 "register_operand" "a")
8208                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8209    (set (match_operand:SI 1 "register_operand" "=&d")
8210         (mod:SI (match_dup 2) (match_dup 3)))
8211    (clobber (reg:CC FLAGS_REG))]
8212   "optimize_size || TARGET_USE_CLTD"
8213   "#"
8214   [(set_attr "type" "multi")])
8216 (define_insn "*divmodsi_noext"
8217   [(set (match_operand:SI 0 "register_operand" "=a")
8218         (div:SI (match_operand:SI 1 "register_operand" "0")
8219                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8220    (set (match_operand:SI 3 "register_operand" "=d")
8221         (mod:SI (match_dup 1) (match_dup 2)))
8222    (use (match_operand:SI 4 "register_operand" "3"))
8223    (clobber (reg:CC FLAGS_REG))]
8224   ""
8225   "idiv{l}\t%2"
8226   [(set_attr "type" "idiv")
8227    (set_attr "mode" "SI")])
8229 (define_split
8230   [(set (match_operand:SI 0 "register_operand" "")
8231         (div:SI (match_operand:SI 1 "register_operand" "")
8232                 (match_operand:SI 2 "nonimmediate_operand" "")))
8233    (set (match_operand:SI 3 "register_operand" "")
8234         (mod:SI (match_dup 1) (match_dup 2)))
8235    (clobber (reg:CC FLAGS_REG))]
8236   "reload_completed"
8237   [(parallel [(set (match_dup 3)
8238                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8239               (clobber (reg:CC FLAGS_REG))])
8240    (parallel [(set (match_dup 0)
8241                    (div:SI (reg:SI 0) (match_dup 2)))
8242               (set (match_dup 3)
8243                    (mod:SI (reg:SI 0) (match_dup 2)))
8244               (use (match_dup 3))
8245               (clobber (reg:CC FLAGS_REG))])]
8247   /* Avoid use of cltd in favor of a mov+shift.  */
8248   if (!TARGET_USE_CLTD && !optimize_size)
8249     {
8250       if (true_regnum (operands[1]))
8251         emit_move_insn (operands[0], operands[1]);
8252       else
8253         emit_move_insn (operands[3], operands[1]);
8254       operands[4] = operands[3];
8255     }
8256   else
8257     {
8258       gcc_assert (!true_regnum (operands[1]));
8259       operands[4] = operands[1];
8260     }
8262 ;; %%% Split me.
8263 (define_insn "divmodhi4"
8264   [(set (match_operand:HI 0 "register_operand" "=a")
8265         (div:HI (match_operand:HI 1 "register_operand" "0")
8266                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8267    (set (match_operand:HI 3 "register_operand" "=&d")
8268         (mod:HI (match_dup 1) (match_dup 2)))
8269    (clobber (reg:CC FLAGS_REG))]
8270   "TARGET_HIMODE_MATH"
8271   "cwtd\;idiv{w}\t%2"
8272   [(set_attr "type" "multi")
8273    (set_attr "length_immediate" "0")
8274    (set_attr "mode" "SI")])
8276 (define_insn "udivmoddi4"
8277   [(set (match_operand:DI 0 "register_operand" "=a")
8278         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8279                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8280    (set (match_operand:DI 3 "register_operand" "=&d")
8281         (umod:DI (match_dup 1) (match_dup 2)))
8282    (clobber (reg:CC FLAGS_REG))]
8283   "TARGET_64BIT"
8284   "xor{q}\t%3, %3\;div{q}\t%2"
8285   [(set_attr "type" "multi")
8286    (set_attr "length_immediate" "0")
8287    (set_attr "mode" "DI")])
8289 (define_insn "*udivmoddi4_noext"
8290   [(set (match_operand:DI 0 "register_operand" "=a")
8291         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8292                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8293    (set (match_operand:DI 3 "register_operand" "=d")
8294         (umod:DI (match_dup 1) (match_dup 2)))
8295    (use (match_dup 3))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "TARGET_64BIT"
8298   "div{q}\t%2"
8299   [(set_attr "type" "idiv")
8300    (set_attr "mode" "DI")])
8302 (define_split
8303   [(set (match_operand:DI 0 "register_operand" "")
8304         (udiv:DI (match_operand:DI 1 "register_operand" "")
8305                  (match_operand:DI 2 "nonimmediate_operand" "")))
8306    (set (match_operand:DI 3 "register_operand" "")
8307         (umod:DI (match_dup 1) (match_dup 2)))
8308    (clobber (reg:CC FLAGS_REG))]
8309   "TARGET_64BIT && reload_completed"
8310   [(set (match_dup 3) (const_int 0))
8311    (parallel [(set (match_dup 0)
8312                    (udiv:DI (match_dup 1) (match_dup 2)))
8313               (set (match_dup 3)
8314                    (umod:DI (match_dup 1) (match_dup 2)))
8315               (use (match_dup 3))
8316               (clobber (reg:CC FLAGS_REG))])]
8317   "")
8319 (define_insn "udivmodsi4"
8320   [(set (match_operand:SI 0 "register_operand" "=a")
8321         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8322                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8323    (set (match_operand:SI 3 "register_operand" "=&d")
8324         (umod:SI (match_dup 1) (match_dup 2)))
8325    (clobber (reg:CC FLAGS_REG))]
8326   ""
8327   "xor{l}\t%3, %3\;div{l}\t%2"
8328   [(set_attr "type" "multi")
8329    (set_attr "length_immediate" "0")
8330    (set_attr "mode" "SI")])
8332 (define_insn "*udivmodsi4_noext"
8333   [(set (match_operand:SI 0 "register_operand" "=a")
8334         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8335                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8336    (set (match_operand:SI 3 "register_operand" "=d")
8337         (umod:SI (match_dup 1) (match_dup 2)))
8338    (use (match_dup 3))
8339    (clobber (reg:CC FLAGS_REG))]
8340   ""
8341   "div{l}\t%2"
8342   [(set_attr "type" "idiv")
8343    (set_attr "mode" "SI")])
8345 (define_split
8346   [(set (match_operand:SI 0 "register_operand" "")
8347         (udiv:SI (match_operand:SI 1 "register_operand" "")
8348                  (match_operand:SI 2 "nonimmediate_operand" "")))
8349    (set (match_operand:SI 3 "register_operand" "")
8350         (umod:SI (match_dup 1) (match_dup 2)))
8351    (clobber (reg:CC FLAGS_REG))]
8352   "reload_completed"
8353   [(set (match_dup 3) (const_int 0))
8354    (parallel [(set (match_dup 0)
8355                    (udiv:SI (match_dup 1) (match_dup 2)))
8356               (set (match_dup 3)
8357                    (umod:SI (match_dup 1) (match_dup 2)))
8358               (use (match_dup 3))
8359               (clobber (reg:CC FLAGS_REG))])]
8360   "")
8362 (define_expand "udivmodhi4"
8363   [(set (match_dup 4) (const_int 0))
8364    (parallel [(set (match_operand:HI 0 "register_operand" "")
8365                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8366                             (match_operand:HI 2 "nonimmediate_operand" "")))
8367               (set (match_operand:HI 3 "register_operand" "")
8368                    (umod:HI (match_dup 1) (match_dup 2)))
8369               (use (match_dup 4))
8370               (clobber (reg:CC FLAGS_REG))])]
8371   "TARGET_HIMODE_MATH"
8372   "operands[4] = gen_reg_rtx (HImode);")
8374 (define_insn "*udivmodhi_noext"
8375   [(set (match_operand:HI 0 "register_operand" "=a")
8376         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8377                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8378    (set (match_operand:HI 3 "register_operand" "=d")
8379         (umod:HI (match_dup 1) (match_dup 2)))
8380    (use (match_operand:HI 4 "register_operand" "3"))
8381    (clobber (reg:CC FLAGS_REG))]
8382   ""
8383   "div{w}\t%2"
8384   [(set_attr "type" "idiv")
8385    (set_attr "mode" "HI")])
8387 ;; We cannot use div/idiv for double division, because it causes
8388 ;; "division by zero" on the overflow and that's not what we expect
8389 ;; from truncate.  Because true (non truncating) double division is
8390 ;; never generated, we can't create this insn anyway.
8392 ;(define_insn ""
8393 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8394 ;       (truncate:SI
8395 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8396 ;                  (zero_extend:DI
8397 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8398 ;   (set (match_operand:SI 3 "register_operand" "=d")
8399 ;       (truncate:SI
8400 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8401 ;   (clobber (reg:CC FLAGS_REG))]
8402 ;  ""
8403 ;  "div{l}\t{%2, %0|%0, %2}"
8404 ;  [(set_attr "type" "idiv")])
8406 ;;- Logical AND instructions
8408 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8409 ;; Note that this excludes ah.
8411 (define_insn "*testdi_1_rex64"
8412   [(set (reg FLAGS_REG)
8413         (compare
8414           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8415                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8416           (const_int 0)))]
8417   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8418    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8419   "@
8420    test{l}\t{%k1, %k0|%k0, %k1}
8421    test{l}\t{%k1, %k0|%k0, %k1}
8422    test{q}\t{%1, %0|%0, %1}
8423    test{q}\t{%1, %0|%0, %1}
8424    test{q}\t{%1, %0|%0, %1}"
8425   [(set_attr "type" "test")
8426    (set_attr "modrm" "0,1,0,1,1")
8427    (set_attr "mode" "SI,SI,DI,DI,DI")
8428    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8430 (define_insn "testsi_1"
8431   [(set (reg FLAGS_REG)
8432         (compare
8433           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8434                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8435           (const_int 0)))]
8436   "ix86_match_ccmode (insn, CCNOmode)
8437    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8438   "test{l}\t{%1, %0|%0, %1}"
8439   [(set_attr "type" "test")
8440    (set_attr "modrm" "0,1,1")
8441    (set_attr "mode" "SI")
8442    (set_attr "pent_pair" "uv,np,uv")])
8444 (define_expand "testsi_ccno_1"
8445   [(set (reg:CCNO FLAGS_REG)
8446         (compare:CCNO
8447           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8448                   (match_operand:SI 1 "nonmemory_operand" ""))
8449           (const_int 0)))]
8450   ""
8451   "")
8453 (define_insn "*testhi_1"
8454   [(set (reg FLAGS_REG)
8455         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8456                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8457                  (const_int 0)))]
8458   "ix86_match_ccmode (insn, CCNOmode)
8459    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8460   "test{w}\t{%1, %0|%0, %1}"
8461   [(set_attr "type" "test")
8462    (set_attr "modrm" "0,1,1")
8463    (set_attr "mode" "HI")
8464    (set_attr "pent_pair" "uv,np,uv")])
8466 (define_expand "testqi_ccz_1"
8467   [(set (reg:CCZ FLAGS_REG)
8468         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8469                              (match_operand:QI 1 "nonmemory_operand" ""))
8470                  (const_int 0)))]
8471   ""
8472   "")
8474 (define_insn "*testqi_1_maybe_si"
8475   [(set (reg FLAGS_REG)
8476         (compare
8477           (and:QI
8478             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8479             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8480           (const_int 0)))]
8481    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8482     && ix86_match_ccmode (insn,
8483                          CONST_INT_P (operands[1])
8484                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8486   if (which_alternative == 3)
8487     {
8488       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8489         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8490       return "test{l}\t{%1, %k0|%k0, %1}";
8491     }
8492   return "test{b}\t{%1, %0|%0, %1}";
8494   [(set_attr "type" "test")
8495    (set_attr "modrm" "0,1,1,1")
8496    (set_attr "mode" "QI,QI,QI,SI")
8497    (set_attr "pent_pair" "uv,np,uv,np")])
8499 (define_insn "*testqi_1"
8500   [(set (reg FLAGS_REG)
8501         (compare
8502           (and:QI
8503             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8504             (match_operand:QI 1 "general_operand" "n,n,qn"))
8505           (const_int 0)))]
8506   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8507    && ix86_match_ccmode (insn, CCNOmode)"
8508   "test{b}\t{%1, %0|%0, %1}"
8509   [(set_attr "type" "test")
8510    (set_attr "modrm" "0,1,1")
8511    (set_attr "mode" "QI")
8512    (set_attr "pent_pair" "uv,np,uv")])
8514 (define_expand "testqi_ext_ccno_0"
8515   [(set (reg:CCNO FLAGS_REG)
8516         (compare:CCNO
8517           (and:SI
8518             (zero_extract:SI
8519               (match_operand 0 "ext_register_operand" "")
8520               (const_int 8)
8521               (const_int 8))
8522             (match_operand 1 "const_int_operand" ""))
8523           (const_int 0)))]
8524   ""
8525   "")
8527 (define_insn "*testqi_ext_0"
8528   [(set (reg FLAGS_REG)
8529         (compare
8530           (and:SI
8531             (zero_extract:SI
8532               (match_operand 0 "ext_register_operand" "Q")
8533               (const_int 8)
8534               (const_int 8))
8535             (match_operand 1 "const_int_operand" "n"))
8536           (const_int 0)))]
8537   "ix86_match_ccmode (insn, CCNOmode)"
8538   "test{b}\t{%1, %h0|%h0, %1}"
8539   [(set_attr "type" "test")
8540    (set_attr "mode" "QI")
8541    (set_attr "length_immediate" "1")
8542    (set_attr "pent_pair" "np")])
8544 (define_insn "*testqi_ext_1"
8545   [(set (reg FLAGS_REG)
8546         (compare
8547           (and:SI
8548             (zero_extract:SI
8549               (match_operand 0 "ext_register_operand" "Q")
8550               (const_int 8)
8551               (const_int 8))
8552             (zero_extend:SI
8553               (match_operand:QI 1 "general_operand" "Qm")))
8554           (const_int 0)))]
8555   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8556    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8557   "test{b}\t{%1, %h0|%h0, %1}"
8558   [(set_attr "type" "test")
8559    (set_attr "mode" "QI")])
8561 (define_insn "*testqi_ext_1_rex64"
8562   [(set (reg FLAGS_REG)
8563         (compare
8564           (and:SI
8565             (zero_extract:SI
8566               (match_operand 0 "ext_register_operand" "Q")
8567               (const_int 8)
8568               (const_int 8))
8569             (zero_extend:SI
8570               (match_operand:QI 1 "register_operand" "Q")))
8571           (const_int 0)))]
8572   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8573   "test{b}\t{%1, %h0|%h0, %1}"
8574   [(set_attr "type" "test")
8575    (set_attr "mode" "QI")])
8577 (define_insn "*testqi_ext_2"
8578   [(set (reg FLAGS_REG)
8579         (compare
8580           (and:SI
8581             (zero_extract:SI
8582               (match_operand 0 "ext_register_operand" "Q")
8583               (const_int 8)
8584               (const_int 8))
8585             (zero_extract:SI
8586               (match_operand 1 "ext_register_operand" "Q")
8587               (const_int 8)
8588               (const_int 8)))
8589           (const_int 0)))]
8590   "ix86_match_ccmode (insn, CCNOmode)"
8591   "test{b}\t{%h1, %h0|%h0, %h1}"
8592   [(set_attr "type" "test")
8593    (set_attr "mode" "QI")])
8595 ;; Combine likes to form bit extractions for some tests.  Humor it.
8596 (define_insn "*testqi_ext_3"
8597   [(set (reg FLAGS_REG)
8598         (compare (zero_extract:SI
8599                    (match_operand 0 "nonimmediate_operand" "rm")
8600                    (match_operand:SI 1 "const_int_operand" "")
8601                    (match_operand:SI 2 "const_int_operand" ""))
8602                  (const_int 0)))]
8603   "ix86_match_ccmode (insn, CCNOmode)
8604    && INTVAL (operands[1]) > 0
8605    && INTVAL (operands[2]) >= 0
8606    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8607    && (GET_MODE (operands[0]) == SImode
8608        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8609        || GET_MODE (operands[0]) == HImode
8610        || GET_MODE (operands[0]) == QImode)"
8611   "#")
8613 (define_insn "*testqi_ext_3_rex64"
8614   [(set (reg FLAGS_REG)
8615         (compare (zero_extract:DI
8616                    (match_operand 0 "nonimmediate_operand" "rm")
8617                    (match_operand:DI 1 "const_int_operand" "")
8618                    (match_operand:DI 2 "const_int_operand" ""))
8619                  (const_int 0)))]
8620   "TARGET_64BIT
8621    && ix86_match_ccmode (insn, CCNOmode)
8622    && INTVAL (operands[1]) > 0
8623    && INTVAL (operands[2]) >= 0
8624    /* Ensure that resulting mask is zero or sign extended operand.  */
8625    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8626        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8627            && INTVAL (operands[1]) > 32))
8628    && (GET_MODE (operands[0]) == SImode
8629        || GET_MODE (operands[0]) == DImode
8630        || GET_MODE (operands[0]) == HImode
8631        || GET_MODE (operands[0]) == QImode)"
8632   "#")
8634 (define_split
8635   [(set (match_operand 0 "flags_reg_operand" "")
8636         (match_operator 1 "compare_operator"
8637           [(zero_extract
8638              (match_operand 2 "nonimmediate_operand" "")
8639              (match_operand 3 "const_int_operand" "")
8640              (match_operand 4 "const_int_operand" ""))
8641            (const_int 0)]))]
8642   "ix86_match_ccmode (insn, CCNOmode)"
8643   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8645   rtx val = operands[2];
8646   HOST_WIDE_INT len = INTVAL (operands[3]);
8647   HOST_WIDE_INT pos = INTVAL (operands[4]);
8648   HOST_WIDE_INT mask;
8649   enum machine_mode mode, submode;
8651   mode = GET_MODE (val);
8652   if (MEM_P (val))
8653     {
8654       /* ??? Combine likes to put non-volatile mem extractions in QImode
8655          no matter the size of the test.  So find a mode that works.  */
8656       if (! MEM_VOLATILE_P (val))
8657         {
8658           mode = smallest_mode_for_size (pos + len, MODE_INT);
8659           val = adjust_address (val, mode, 0);
8660         }
8661     }
8662   else if (GET_CODE (val) == SUBREG
8663            && (submode = GET_MODE (SUBREG_REG (val)),
8664                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8665            && pos + len <= GET_MODE_BITSIZE (submode))
8666     {
8667       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8668       mode = submode;
8669       val = SUBREG_REG (val);
8670     }
8671   else if (mode == HImode && pos + len <= 8)
8672     {
8673       /* Small HImode tests can be converted to QImode.  */
8674       mode = QImode;
8675       val = gen_lowpart (QImode, val);
8676     }
8678   if (len == HOST_BITS_PER_WIDE_INT)
8679     mask = -1;
8680   else
8681     mask = ((HOST_WIDE_INT)1 << len) - 1;
8682   mask <<= pos;
8684   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8687 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8688 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8689 ;; this is relatively important trick.
8690 ;; Do the conversion only post-reload to avoid limiting of the register class
8691 ;; to QI regs.
8692 (define_split
8693   [(set (match_operand 0 "flags_reg_operand" "")
8694         (match_operator 1 "compare_operator"
8695           [(and (match_operand 2 "register_operand" "")
8696                 (match_operand 3 "const_int_operand" ""))
8697            (const_int 0)]))]
8698    "reload_completed
8699     && QI_REG_P (operands[2])
8700     && GET_MODE (operands[2]) != QImode
8701     && ((ix86_match_ccmode (insn, CCZmode)
8702          && !(INTVAL (operands[3]) & ~(255 << 8)))
8703         || (ix86_match_ccmode (insn, CCNOmode)
8704             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8705   [(set (match_dup 0)
8706         (match_op_dup 1
8707           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8708                    (match_dup 3))
8709            (const_int 0)]))]
8710   "operands[2] = gen_lowpart (SImode, operands[2]);
8711    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8713 (define_split
8714   [(set (match_operand 0 "flags_reg_operand" "")
8715         (match_operator 1 "compare_operator"
8716           [(and (match_operand 2 "nonimmediate_operand" "")
8717                 (match_operand 3 "const_int_operand" ""))
8718            (const_int 0)]))]
8719    "reload_completed
8720     && GET_MODE (operands[2]) != QImode
8721     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8722     && ((ix86_match_ccmode (insn, CCZmode)
8723          && !(INTVAL (operands[3]) & ~255))
8724         || (ix86_match_ccmode (insn, CCNOmode)
8725             && !(INTVAL (operands[3]) & ~127)))"
8726   [(set (match_dup 0)
8727         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8728                          (const_int 0)]))]
8729   "operands[2] = gen_lowpart (QImode, operands[2]);
8730    operands[3] = gen_lowpart (QImode, operands[3]);")
8733 ;; %%% This used to optimize known byte-wide and operations to memory,
8734 ;; and sometimes to QImode registers.  If this is considered useful,
8735 ;; it should be done with splitters.
8737 (define_expand "anddi3"
8738   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8739         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8740                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8741    (clobber (reg:CC FLAGS_REG))]
8742   "TARGET_64BIT"
8743   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8745 (define_insn "*anddi_1_rex64"
8746   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8747         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8748                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8749    (clobber (reg:CC FLAGS_REG))]
8750   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8752   switch (get_attr_type (insn))
8753     {
8754     case TYPE_IMOVX:
8755       {
8756         enum machine_mode mode;
8758         gcc_assert (CONST_INT_P (operands[2]));
8759         if (INTVAL (operands[2]) == 0xff)
8760           mode = QImode;
8761         else
8762           {
8763             gcc_assert (INTVAL (operands[2]) == 0xffff);
8764             mode = HImode;
8765           }
8767         operands[1] = gen_lowpart (mode, operands[1]);
8768         if (mode == QImode)
8769           return "movz{bq|x}\t{%1,%0|%0, %1}";
8770         else
8771           return "movz{wq|x}\t{%1,%0|%0, %1}";
8772       }
8774     default:
8775       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8776       if (get_attr_mode (insn) == MODE_SI)
8777         return "and{l}\t{%k2, %k0|%k0, %k2}";
8778       else
8779         return "and{q}\t{%2, %0|%0, %2}";
8780     }
8782   [(set_attr "type" "alu,alu,alu,imovx")
8783    (set_attr "length_immediate" "*,*,*,0")
8784    (set_attr "mode" "SI,DI,DI,DI")])
8786 (define_insn "*anddi_2"
8787   [(set (reg FLAGS_REG)
8788         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8789                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8790                  (const_int 0)))
8791    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8792         (and:DI (match_dup 1) (match_dup 2)))]
8793   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8794    && ix86_binary_operator_ok (AND, DImode, operands)"
8795   "@
8796    and{l}\t{%k2, %k0|%k0, %k2}
8797    and{q}\t{%2, %0|%0, %2}
8798    and{q}\t{%2, %0|%0, %2}"
8799   [(set_attr "type" "alu")
8800    (set_attr "mode" "SI,DI,DI")])
8802 (define_expand "andsi3"
8803   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8804         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8805                 (match_operand:SI 2 "general_operand" "")))
8806    (clobber (reg:CC FLAGS_REG))]
8807   ""
8808   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8810 (define_insn "*andsi_1"
8811   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8812         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8813                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8814    (clobber (reg:CC FLAGS_REG))]
8815   "ix86_binary_operator_ok (AND, SImode, operands)"
8817   switch (get_attr_type (insn))
8818     {
8819     case TYPE_IMOVX:
8820       {
8821         enum machine_mode mode;
8823         gcc_assert (CONST_INT_P (operands[2]));
8824         if (INTVAL (operands[2]) == 0xff)
8825           mode = QImode;
8826         else
8827           {
8828             gcc_assert (INTVAL (operands[2]) == 0xffff);
8829             mode = HImode;
8830           }
8832         operands[1] = gen_lowpart (mode, operands[1]);
8833         if (mode == QImode)
8834           return "movz{bl|x}\t{%1,%0|%0, %1}";
8835         else
8836           return "movz{wl|x}\t{%1,%0|%0, %1}";
8837       }
8839     default:
8840       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8841       return "and{l}\t{%2, %0|%0, %2}";
8842     }
8844   [(set_attr "type" "alu,alu,imovx")
8845    (set_attr "length_immediate" "*,*,0")
8846    (set_attr "mode" "SI")])
8848 (define_split
8849   [(set (match_operand 0 "register_operand" "")
8850         (and (match_dup 0)
8851              (const_int -65536)))
8852    (clobber (reg:CC FLAGS_REG))]
8853   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8854   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8855   "operands[1] = gen_lowpart (HImode, operands[0]);")
8857 (define_split
8858   [(set (match_operand 0 "ext_register_operand" "")
8859         (and (match_dup 0)
8860              (const_int -256)))
8861    (clobber (reg:CC FLAGS_REG))]
8862   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8863   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8864   "operands[1] = gen_lowpart (QImode, operands[0]);")
8866 (define_split
8867   [(set (match_operand 0 "ext_register_operand" "")
8868         (and (match_dup 0)
8869              (const_int -65281)))
8870    (clobber (reg:CC FLAGS_REG))]
8871   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8872   [(parallel [(set (zero_extract:SI (match_dup 0)
8873                                     (const_int 8)
8874                                     (const_int 8))
8875                    (xor:SI
8876                      (zero_extract:SI (match_dup 0)
8877                                       (const_int 8)
8878                                       (const_int 8))
8879                      (zero_extract:SI (match_dup 0)
8880                                       (const_int 8)
8881                                       (const_int 8))))
8882               (clobber (reg:CC FLAGS_REG))])]
8883   "operands[0] = gen_lowpart (SImode, operands[0]);")
8885 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8886 (define_insn "*andsi_1_zext"
8887   [(set (match_operand:DI 0 "register_operand" "=r")
8888         (zero_extend:DI
8889           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8890                   (match_operand:SI 2 "general_operand" "g"))))
8891    (clobber (reg:CC FLAGS_REG))]
8892   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8893   "and{l}\t{%2, %k0|%k0, %2}"
8894   [(set_attr "type" "alu")
8895    (set_attr "mode" "SI")])
8897 (define_insn "*andsi_2"
8898   [(set (reg FLAGS_REG)
8899         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8900                          (match_operand:SI 2 "general_operand" "g,ri"))
8901                  (const_int 0)))
8902    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8903         (and:SI (match_dup 1) (match_dup 2)))]
8904   "ix86_match_ccmode (insn, CCNOmode)
8905    && ix86_binary_operator_ok (AND, SImode, operands)"
8906   "and{l}\t{%2, %0|%0, %2}"
8907   [(set_attr "type" "alu")
8908    (set_attr "mode" "SI")])
8910 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8911 (define_insn "*andsi_2_zext"
8912   [(set (reg FLAGS_REG)
8913         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8914                          (match_operand:SI 2 "general_operand" "g"))
8915                  (const_int 0)))
8916    (set (match_operand:DI 0 "register_operand" "=r")
8917         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8918   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8919    && ix86_binary_operator_ok (AND, SImode, operands)"
8920   "and{l}\t{%2, %k0|%k0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "SI")])
8924 (define_expand "andhi3"
8925   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8926         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8927                 (match_operand:HI 2 "general_operand" "")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "TARGET_HIMODE_MATH"
8930   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8932 (define_insn "*andhi_1"
8933   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8934         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8935                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8936    (clobber (reg:CC FLAGS_REG))]
8937   "ix86_binary_operator_ok (AND, HImode, operands)"
8939   switch (get_attr_type (insn))
8940     {
8941     case TYPE_IMOVX:
8942       gcc_assert (CONST_INT_P (operands[2]));
8943       gcc_assert (INTVAL (operands[2]) == 0xff);
8944       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8946     default:
8947       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8949       return "and{w}\t{%2, %0|%0, %2}";
8950     }
8952   [(set_attr "type" "alu,alu,imovx")
8953    (set_attr "length_immediate" "*,*,0")
8954    (set_attr "mode" "HI,HI,SI")])
8956 (define_insn "*andhi_2"
8957   [(set (reg FLAGS_REG)
8958         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8959                          (match_operand:HI 2 "general_operand" "g,ri"))
8960                  (const_int 0)))
8961    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8962         (and:HI (match_dup 1) (match_dup 2)))]
8963   "ix86_match_ccmode (insn, CCNOmode)
8964    && ix86_binary_operator_ok (AND, HImode, operands)"
8965   "and{w}\t{%2, %0|%0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "HI")])
8969 (define_expand "andqi3"
8970   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8971         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8972                 (match_operand:QI 2 "general_operand" "")))
8973    (clobber (reg:CC FLAGS_REG))]
8974   "TARGET_QIMODE_MATH"
8975   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8977 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8978 (define_insn "*andqi_1"
8979   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8980         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8981                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "ix86_binary_operator_ok (AND, QImode, operands)"
8984   "@
8985    and{b}\t{%2, %0|%0, %2}
8986    and{b}\t{%2, %0|%0, %2}
8987    and{l}\t{%k2, %k0|%k0, %k2}"
8988   [(set_attr "type" "alu")
8989    (set_attr "mode" "QI,QI,SI")])
8991 (define_insn "*andqi_1_slp"
8992   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8993         (and:QI (match_dup 0)
8994                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8995    (clobber (reg:CC FLAGS_REG))]
8996   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8997    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8998   "and{b}\t{%1, %0|%0, %1}"
8999   [(set_attr "type" "alu1")
9000    (set_attr "mode" "QI")])
9002 (define_insn "*andqi_2_maybe_si"
9003   [(set (reg FLAGS_REG)
9004         (compare (and:QI
9005                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9006                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9007                  (const_int 0)))
9008    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9009         (and:QI (match_dup 1) (match_dup 2)))]
9010   "ix86_binary_operator_ok (AND, QImode, operands)
9011    && ix86_match_ccmode (insn,
9012                          CONST_INT_P (operands[2])
9013                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9015   if (which_alternative == 2)
9016     {
9017       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9018         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9019       return "and{l}\t{%2, %k0|%k0, %2}";
9020     }
9021   return "and{b}\t{%2, %0|%0, %2}";
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "QI,QI,SI")])
9026 (define_insn "*andqi_2"
9027   [(set (reg FLAGS_REG)
9028         (compare (and:QI
9029                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9030                    (match_operand:QI 2 "general_operand" "qim,qi"))
9031                  (const_int 0)))
9032    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9033         (and:QI (match_dup 1) (match_dup 2)))]
9034   "ix86_match_ccmode (insn, CCNOmode)
9035    && ix86_binary_operator_ok (AND, QImode, operands)"
9036   "and{b}\t{%2, %0|%0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "mode" "QI")])
9040 (define_insn "*andqi_2_slp"
9041   [(set (reg FLAGS_REG)
9042         (compare (and:QI
9043                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9044                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9045                  (const_int 0)))
9046    (set (strict_low_part (match_dup 0))
9047         (and:QI (match_dup 0) (match_dup 1)))]
9048   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9049    && ix86_match_ccmode (insn, CCNOmode)
9050    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9051   "and{b}\t{%1, %0|%0, %1}"
9052   [(set_attr "type" "alu1")
9053    (set_attr "mode" "QI")])
9055 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9056 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9057 ;; for a QImode operand, which of course failed.
9059 (define_insn "andqi_ext_0"
9060   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9061                          (const_int 8)
9062                          (const_int 8))
9063         (and:SI
9064           (zero_extract:SI
9065             (match_operand 1 "ext_register_operand" "0")
9066             (const_int 8)
9067             (const_int 8))
9068           (match_operand 2 "const_int_operand" "n")))
9069    (clobber (reg:CC FLAGS_REG))]
9070   ""
9071   "and{b}\t{%2, %h0|%h0, %2}"
9072   [(set_attr "type" "alu")
9073    (set_attr "length_immediate" "1")
9074    (set_attr "mode" "QI")])
9076 ;; Generated by peephole translating test to and.  This shows up
9077 ;; often in fp comparisons.
9079 (define_insn "*andqi_ext_0_cc"
9080   [(set (reg FLAGS_REG)
9081         (compare
9082           (and:SI
9083             (zero_extract:SI
9084               (match_operand 1 "ext_register_operand" "0")
9085               (const_int 8)
9086               (const_int 8))
9087             (match_operand 2 "const_int_operand" "n"))
9088           (const_int 0)))
9089    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9090                          (const_int 8)
9091                          (const_int 8))
9092         (and:SI
9093           (zero_extract:SI
9094             (match_dup 1)
9095             (const_int 8)
9096             (const_int 8))
9097           (match_dup 2)))]
9098   "ix86_match_ccmode (insn, CCNOmode)"
9099   "and{b}\t{%2, %h0|%h0, %2}"
9100   [(set_attr "type" "alu")
9101    (set_attr "length_immediate" "1")
9102    (set_attr "mode" "QI")])
9104 (define_insn "*andqi_ext_1"
9105   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9106                          (const_int 8)
9107                          (const_int 8))
9108         (and:SI
9109           (zero_extract:SI
9110             (match_operand 1 "ext_register_operand" "0")
9111             (const_int 8)
9112             (const_int 8))
9113           (zero_extend:SI
9114             (match_operand:QI 2 "general_operand" "Qm"))))
9115    (clobber (reg:CC FLAGS_REG))]
9116   "!TARGET_64BIT"
9117   "and{b}\t{%2, %h0|%h0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "length_immediate" "0")
9120    (set_attr "mode" "QI")])
9122 (define_insn "*andqi_ext_1_rex64"
9123   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9124                          (const_int 8)
9125                          (const_int 8))
9126         (and:SI
9127           (zero_extract:SI
9128             (match_operand 1 "ext_register_operand" "0")
9129             (const_int 8)
9130             (const_int 8))
9131           (zero_extend:SI
9132             (match_operand 2 "ext_register_operand" "Q"))))
9133    (clobber (reg:CC FLAGS_REG))]
9134   "TARGET_64BIT"
9135   "and{b}\t{%2, %h0|%h0, %2}"
9136   [(set_attr "type" "alu")
9137    (set_attr "length_immediate" "0")
9138    (set_attr "mode" "QI")])
9140 (define_insn "*andqi_ext_2"
9141   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9142                          (const_int 8)
9143                          (const_int 8))
9144         (and:SI
9145           (zero_extract:SI
9146             (match_operand 1 "ext_register_operand" "%0")
9147             (const_int 8)
9148             (const_int 8))
9149           (zero_extract:SI
9150             (match_operand 2 "ext_register_operand" "Q")
9151             (const_int 8)
9152             (const_int 8))))
9153    (clobber (reg:CC FLAGS_REG))]
9154   ""
9155   "and{b}\t{%h2, %h0|%h0, %h2}"
9156   [(set_attr "type" "alu")
9157    (set_attr "length_immediate" "0")
9158    (set_attr "mode" "QI")])
9160 ;; Convert wide AND instructions with immediate operand to shorter QImode
9161 ;; equivalents when possible.
9162 ;; Don't do the splitting with memory operands, since it introduces risk
9163 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9164 ;; for size, but that can (should?) be handled by generic code instead.
9165 (define_split
9166   [(set (match_operand 0 "register_operand" "")
9167         (and (match_operand 1 "register_operand" "")
9168              (match_operand 2 "const_int_operand" "")))
9169    (clobber (reg:CC FLAGS_REG))]
9170    "reload_completed
9171     && QI_REG_P (operands[0])
9172     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9173     && !(~INTVAL (operands[2]) & ~(255 << 8))
9174     && GET_MODE (operands[0]) != QImode"
9175   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9176                    (and:SI (zero_extract:SI (match_dup 1)
9177                                             (const_int 8) (const_int 8))
9178                            (match_dup 2)))
9179               (clobber (reg:CC FLAGS_REG))])]
9180   "operands[0] = gen_lowpart (SImode, operands[0]);
9181    operands[1] = gen_lowpart (SImode, operands[1]);
9182    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9184 ;; Since AND can be encoded with sign extended immediate, this is only
9185 ;; profitable when 7th bit is not set.
9186 (define_split
9187   [(set (match_operand 0 "register_operand" "")
9188         (and (match_operand 1 "general_operand" "")
9189              (match_operand 2 "const_int_operand" "")))
9190    (clobber (reg:CC FLAGS_REG))]
9191    "reload_completed
9192     && ANY_QI_REG_P (operands[0])
9193     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9194     && !(~INTVAL (operands[2]) & ~255)
9195     && !(INTVAL (operands[2]) & 128)
9196     && GET_MODE (operands[0]) != QImode"
9197   [(parallel [(set (strict_low_part (match_dup 0))
9198                    (and:QI (match_dup 1)
9199                            (match_dup 2)))
9200               (clobber (reg:CC FLAGS_REG))])]
9201   "operands[0] = gen_lowpart (QImode, operands[0]);
9202    operands[1] = gen_lowpart (QImode, operands[1]);
9203    operands[2] = gen_lowpart (QImode, operands[2]);")
9205 ;; Logical inclusive OR instructions
9207 ;; %%% This used to optimize known byte-wide and operations to memory.
9208 ;; If this is considered useful, it should be done with splitters.
9210 (define_expand "iordi3"
9211   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9212         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9213                 (match_operand:DI 2 "x86_64_general_operand" "")))
9214    (clobber (reg:CC FLAGS_REG))]
9215   "TARGET_64BIT"
9216   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9218 (define_insn "*iordi_1_rex64"
9219   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9220         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9221                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9222    (clobber (reg:CC FLAGS_REG))]
9223   "TARGET_64BIT
9224    && ix86_binary_operator_ok (IOR, DImode, operands)"
9225   "or{q}\t{%2, %0|%0, %2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "mode" "DI")])
9229 (define_insn "*iordi_2_rex64"
9230   [(set (reg FLAGS_REG)
9231         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9232                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9233                  (const_int 0)))
9234    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9235         (ior:DI (match_dup 1) (match_dup 2)))]
9236   "TARGET_64BIT
9237    && ix86_match_ccmode (insn, CCNOmode)
9238    && ix86_binary_operator_ok (IOR, DImode, operands)"
9239   "or{q}\t{%2, %0|%0, %2}"
9240   [(set_attr "type" "alu")
9241    (set_attr "mode" "DI")])
9243 (define_insn "*iordi_3_rex64"
9244   [(set (reg FLAGS_REG)
9245         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9246                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9247                  (const_int 0)))
9248    (clobber (match_scratch:DI 0 "=r"))]
9249   "TARGET_64BIT
9250    && ix86_match_ccmode (insn, CCNOmode)
9251    && ix86_binary_operator_ok (IOR, DImode, operands)"
9252   "or{q}\t{%2, %0|%0, %2}"
9253   [(set_attr "type" "alu")
9254    (set_attr "mode" "DI")])
9257 (define_expand "iorsi3"
9258   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9259         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9260                 (match_operand:SI 2 "general_operand" "")))
9261    (clobber (reg:CC FLAGS_REG))]
9262   ""
9263   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9265 (define_insn "*iorsi_1"
9266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9267         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9268                 (match_operand:SI 2 "general_operand" "ri,g")))
9269    (clobber (reg:CC FLAGS_REG))]
9270   "ix86_binary_operator_ok (IOR, SImode, operands)"
9271   "or{l}\t{%2, %0|%0, %2}"
9272   [(set_attr "type" "alu")
9273    (set_attr "mode" "SI")])
9275 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9276 (define_insn "*iorsi_1_zext"
9277   [(set (match_operand:DI 0 "register_operand" "=r")
9278         (zero_extend:DI
9279           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9280                   (match_operand:SI 2 "general_operand" "g"))))
9281    (clobber (reg:CC FLAGS_REG))]
9282   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9283   "or{l}\t{%2, %k0|%k0, %2}"
9284   [(set_attr "type" "alu")
9285    (set_attr "mode" "SI")])
9287 (define_insn "*iorsi_1_zext_imm"
9288   [(set (match_operand:DI 0 "register_operand" "=r")
9289         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9290                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9291    (clobber (reg:CC FLAGS_REG))]
9292   "TARGET_64BIT"
9293   "or{l}\t{%2, %k0|%k0, %2}"
9294   [(set_attr "type" "alu")
9295    (set_attr "mode" "SI")])
9297 (define_insn "*iorsi_2"
9298   [(set (reg FLAGS_REG)
9299         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9300                          (match_operand:SI 2 "general_operand" "g,ri"))
9301                  (const_int 0)))
9302    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9303         (ior:SI (match_dup 1) (match_dup 2)))]
9304   "ix86_match_ccmode (insn, CCNOmode)
9305    && ix86_binary_operator_ok (IOR, SImode, operands)"
9306   "or{l}\t{%2, %0|%0, %2}"
9307   [(set_attr "type" "alu")
9308    (set_attr "mode" "SI")])
9310 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9311 ;; ??? Special case for immediate operand is missing - it is tricky.
9312 (define_insn "*iorsi_2_zext"
9313   [(set (reg FLAGS_REG)
9314         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9315                          (match_operand:SI 2 "general_operand" "g"))
9316                  (const_int 0)))
9317    (set (match_operand:DI 0 "register_operand" "=r")
9318         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9319   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9320    && ix86_binary_operator_ok (IOR, SImode, operands)"
9321   "or{l}\t{%2, %k0|%k0, %2}"
9322   [(set_attr "type" "alu")
9323    (set_attr "mode" "SI")])
9325 (define_insn "*iorsi_2_zext_imm"
9326   [(set (reg FLAGS_REG)
9327         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9328                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9329                  (const_int 0)))
9330    (set (match_operand:DI 0 "register_operand" "=r")
9331         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9332   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9333    && ix86_binary_operator_ok (IOR, SImode, operands)"
9334   "or{l}\t{%2, %k0|%k0, %2}"
9335   [(set_attr "type" "alu")
9336    (set_attr "mode" "SI")])
9338 (define_insn "*iorsi_3"
9339   [(set (reg FLAGS_REG)
9340         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9341                          (match_operand:SI 2 "general_operand" "g"))
9342                  (const_int 0)))
9343    (clobber (match_scratch:SI 0 "=r"))]
9344   "ix86_match_ccmode (insn, CCNOmode)
9345    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9346   "or{l}\t{%2, %0|%0, %2}"
9347   [(set_attr "type" "alu")
9348    (set_attr "mode" "SI")])
9350 (define_expand "iorhi3"
9351   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9352         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9353                 (match_operand:HI 2 "general_operand" "")))
9354    (clobber (reg:CC FLAGS_REG))]
9355   "TARGET_HIMODE_MATH"
9356   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9358 (define_insn "*iorhi_1"
9359   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9360         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9361                 (match_operand:HI 2 "general_operand" "g,ri")))
9362    (clobber (reg:CC FLAGS_REG))]
9363   "ix86_binary_operator_ok (IOR, HImode, operands)"
9364   "or{w}\t{%2, %0|%0, %2}"
9365   [(set_attr "type" "alu")
9366    (set_attr "mode" "HI")])
9368 (define_insn "*iorhi_2"
9369   [(set (reg FLAGS_REG)
9370         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9371                          (match_operand:HI 2 "general_operand" "g,ri"))
9372                  (const_int 0)))
9373    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9374         (ior:HI (match_dup 1) (match_dup 2)))]
9375   "ix86_match_ccmode (insn, CCNOmode)
9376    && ix86_binary_operator_ok (IOR, HImode, operands)"
9377   "or{w}\t{%2, %0|%0, %2}"
9378   [(set_attr "type" "alu")
9379    (set_attr "mode" "HI")])
9381 (define_insn "*iorhi_3"
9382   [(set (reg FLAGS_REG)
9383         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9384                          (match_operand:HI 2 "general_operand" "g"))
9385                  (const_int 0)))
9386    (clobber (match_scratch:HI 0 "=r"))]
9387   "ix86_match_ccmode (insn, CCNOmode)
9388    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9389   "or{w}\t{%2, %0|%0, %2}"
9390   [(set_attr "type" "alu")
9391    (set_attr "mode" "HI")])
9393 (define_expand "iorqi3"
9394   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9395         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9396                 (match_operand:QI 2 "general_operand" "")))
9397    (clobber (reg:CC FLAGS_REG))]
9398   "TARGET_QIMODE_MATH"
9399   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9401 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9402 (define_insn "*iorqi_1"
9403   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9404         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9405                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9406    (clobber (reg:CC FLAGS_REG))]
9407   "ix86_binary_operator_ok (IOR, QImode, operands)"
9408   "@
9409    or{b}\t{%2, %0|%0, %2}
9410    or{b}\t{%2, %0|%0, %2}
9411    or{l}\t{%k2, %k0|%k0, %k2}"
9412   [(set_attr "type" "alu")
9413    (set_attr "mode" "QI,QI,SI")])
9415 (define_insn "*iorqi_1_slp"
9416   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9417         (ior:QI (match_dup 0)
9418                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9419    (clobber (reg:CC FLAGS_REG))]
9420   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9421    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9422   "or{b}\t{%1, %0|%0, %1}"
9423   [(set_attr "type" "alu1")
9424    (set_attr "mode" "QI")])
9426 (define_insn "*iorqi_2"
9427   [(set (reg FLAGS_REG)
9428         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9429                          (match_operand:QI 2 "general_operand" "qim,qi"))
9430                  (const_int 0)))
9431    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9432         (ior:QI (match_dup 1) (match_dup 2)))]
9433   "ix86_match_ccmode (insn, CCNOmode)
9434    && ix86_binary_operator_ok (IOR, QImode, operands)"
9435   "or{b}\t{%2, %0|%0, %2}"
9436   [(set_attr "type" "alu")
9437    (set_attr "mode" "QI")])
9439 (define_insn "*iorqi_2_slp"
9440   [(set (reg FLAGS_REG)
9441         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9442                          (match_operand:QI 1 "general_operand" "qim,qi"))
9443                  (const_int 0)))
9444    (set (strict_low_part (match_dup 0))
9445         (ior:QI (match_dup 0) (match_dup 1)))]
9446   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9447    && ix86_match_ccmode (insn, CCNOmode)
9448    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9449   "or{b}\t{%1, %0|%0, %1}"
9450   [(set_attr "type" "alu1")
9451    (set_attr "mode" "QI")])
9453 (define_insn "*iorqi_3"
9454   [(set (reg FLAGS_REG)
9455         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9456                          (match_operand:QI 2 "general_operand" "qim"))
9457                  (const_int 0)))
9458    (clobber (match_scratch:QI 0 "=q"))]
9459   "ix86_match_ccmode (insn, CCNOmode)
9460    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9461   "or{b}\t{%2, %0|%0, %2}"
9462   [(set_attr "type" "alu")
9463    (set_attr "mode" "QI")])
9465 (define_insn "iorqi_ext_0"
9466   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9467                          (const_int 8)
9468                          (const_int 8))
9469         (ior:SI
9470           (zero_extract:SI
9471             (match_operand 1 "ext_register_operand" "0")
9472             (const_int 8)
9473             (const_int 8))
9474           (match_operand 2 "const_int_operand" "n")))
9475    (clobber (reg:CC FLAGS_REG))]
9476   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9477   "or{b}\t{%2, %h0|%h0, %2}"
9478   [(set_attr "type" "alu")
9479    (set_attr "length_immediate" "1")
9480    (set_attr "mode" "QI")])
9482 (define_insn "*iorqi_ext_1"
9483   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9484                          (const_int 8)
9485                          (const_int 8))
9486         (ior:SI
9487           (zero_extract:SI
9488             (match_operand 1 "ext_register_operand" "0")
9489             (const_int 8)
9490             (const_int 8))
9491           (zero_extend:SI
9492             (match_operand:QI 2 "general_operand" "Qm"))))
9493    (clobber (reg:CC FLAGS_REG))]
9494   "!TARGET_64BIT
9495    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9496   "or{b}\t{%2, %h0|%h0, %2}"
9497   [(set_attr "type" "alu")
9498    (set_attr "length_immediate" "0")
9499    (set_attr "mode" "QI")])
9501 (define_insn "*iorqi_ext_1_rex64"
9502   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9503                          (const_int 8)
9504                          (const_int 8))
9505         (ior:SI
9506           (zero_extract:SI
9507             (match_operand 1 "ext_register_operand" "0")
9508             (const_int 8)
9509             (const_int 8))
9510           (zero_extend:SI
9511             (match_operand 2 "ext_register_operand" "Q"))))
9512    (clobber (reg:CC FLAGS_REG))]
9513   "TARGET_64BIT
9514    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515   "or{b}\t{%2, %h0|%h0, %2}"
9516   [(set_attr "type" "alu")
9517    (set_attr "length_immediate" "0")
9518    (set_attr "mode" "QI")])
9520 (define_insn "*iorqi_ext_2"
9521   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9522                          (const_int 8)
9523                          (const_int 8))
9524         (ior:SI
9525           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9526                            (const_int 8)
9527                            (const_int 8))
9528           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9529                            (const_int 8)
9530                            (const_int 8))))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9533   "ior{b}\t{%h2, %h0|%h0, %h2}"
9534   [(set_attr "type" "alu")
9535    (set_attr "length_immediate" "0")
9536    (set_attr "mode" "QI")])
9538 (define_split
9539   [(set (match_operand 0 "register_operand" "")
9540         (ior (match_operand 1 "register_operand" "")
9541              (match_operand 2 "const_int_operand" "")))
9542    (clobber (reg:CC FLAGS_REG))]
9543    "reload_completed
9544     && QI_REG_P (operands[0])
9545     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9546     && !(INTVAL (operands[2]) & ~(255 << 8))
9547     && GET_MODE (operands[0]) != QImode"
9548   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9549                    (ior:SI (zero_extract:SI (match_dup 1)
9550                                             (const_int 8) (const_int 8))
9551                            (match_dup 2)))
9552               (clobber (reg:CC FLAGS_REG))])]
9553   "operands[0] = gen_lowpart (SImode, operands[0]);
9554    operands[1] = gen_lowpart (SImode, operands[1]);
9555    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9557 ;; Since OR can be encoded with sign extended immediate, this is only
9558 ;; profitable when 7th bit is set.
9559 (define_split
9560   [(set (match_operand 0 "register_operand" "")
9561         (ior (match_operand 1 "general_operand" "")
9562              (match_operand 2 "const_int_operand" "")))
9563    (clobber (reg:CC FLAGS_REG))]
9564    "reload_completed
9565     && ANY_QI_REG_P (operands[0])
9566     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9567     && !(INTVAL (operands[2]) & ~255)
9568     && (INTVAL (operands[2]) & 128)
9569     && GET_MODE (operands[0]) != QImode"
9570   [(parallel [(set (strict_low_part (match_dup 0))
9571                    (ior:QI (match_dup 1)
9572                            (match_dup 2)))
9573               (clobber (reg:CC FLAGS_REG))])]
9574   "operands[0] = gen_lowpart (QImode, operands[0]);
9575    operands[1] = gen_lowpart (QImode, operands[1]);
9576    operands[2] = gen_lowpart (QImode, operands[2]);")
9578 ;; Logical XOR instructions
9580 ;; %%% This used to optimize known byte-wide and operations to memory.
9581 ;; If this is considered useful, it should be done with splitters.
9583 (define_expand "xordi3"
9584   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9585         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9586                 (match_operand:DI 2 "x86_64_general_operand" "")))
9587    (clobber (reg:CC FLAGS_REG))]
9588   "TARGET_64BIT"
9589   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9591 (define_insn "*xordi_1_rex64"
9592   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9593         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9594                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9595    (clobber (reg:CC FLAGS_REG))]
9596   "TARGET_64BIT
9597    && ix86_binary_operator_ok (XOR, DImode, operands)"
9598   "@
9599    xor{q}\t{%2, %0|%0, %2}
9600    xor{q}\t{%2, %0|%0, %2}"
9601   [(set_attr "type" "alu")
9602    (set_attr "mode" "DI,DI")])
9604 (define_insn "*xordi_2_rex64"
9605   [(set (reg FLAGS_REG)
9606         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9607                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9608                  (const_int 0)))
9609    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9610         (xor:DI (match_dup 1) (match_dup 2)))]
9611   "TARGET_64BIT
9612    && ix86_match_ccmode (insn, CCNOmode)
9613    && ix86_binary_operator_ok (XOR, DImode, operands)"
9614   "@
9615    xor{q}\t{%2, %0|%0, %2}
9616    xor{q}\t{%2, %0|%0, %2}"
9617   [(set_attr "type" "alu")
9618    (set_attr "mode" "DI,DI")])
9620 (define_insn "*xordi_3_rex64"
9621   [(set (reg FLAGS_REG)
9622         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9623                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9624                  (const_int 0)))
9625    (clobber (match_scratch:DI 0 "=r"))]
9626   "TARGET_64BIT
9627    && ix86_match_ccmode (insn, CCNOmode)
9628    && ix86_binary_operator_ok (XOR, DImode, operands)"
9629   "xor{q}\t{%2, %0|%0, %2}"
9630   [(set_attr "type" "alu")
9631    (set_attr "mode" "DI")])
9633 (define_expand "xorsi3"
9634   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9635         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9636                 (match_operand:SI 2 "general_operand" "")))
9637    (clobber (reg:CC FLAGS_REG))]
9638   ""
9639   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9641 (define_insn "*xorsi_1"
9642   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9643         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9644                 (match_operand:SI 2 "general_operand" "ri,rm")))
9645    (clobber (reg:CC FLAGS_REG))]
9646   "ix86_binary_operator_ok (XOR, SImode, operands)"
9647   "xor{l}\t{%2, %0|%0, %2}"
9648   [(set_attr "type" "alu")
9649    (set_attr "mode" "SI")])
9651 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9652 ;; Add speccase for immediates
9653 (define_insn "*xorsi_1_zext"
9654   [(set (match_operand:DI 0 "register_operand" "=r")
9655         (zero_extend:DI
9656           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9657                   (match_operand:SI 2 "general_operand" "g"))))
9658    (clobber (reg:CC FLAGS_REG))]
9659   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9660   "xor{l}\t{%2, %k0|%k0, %2}"
9661   [(set_attr "type" "alu")
9662    (set_attr "mode" "SI")])
9664 (define_insn "*xorsi_1_zext_imm"
9665   [(set (match_operand:DI 0 "register_operand" "=r")
9666         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9667                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9668    (clobber (reg:CC FLAGS_REG))]
9669   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9670   "xor{l}\t{%2, %k0|%k0, %2}"
9671   [(set_attr "type" "alu")
9672    (set_attr "mode" "SI")])
9674 (define_insn "*xorsi_2"
9675   [(set (reg FLAGS_REG)
9676         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9677                          (match_operand:SI 2 "general_operand" "g,ri"))
9678                  (const_int 0)))
9679    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9680         (xor:SI (match_dup 1) (match_dup 2)))]
9681   "ix86_match_ccmode (insn, CCNOmode)
9682    && ix86_binary_operator_ok (XOR, SImode, operands)"
9683   "xor{l}\t{%2, %0|%0, %2}"
9684   [(set_attr "type" "alu")
9685    (set_attr "mode" "SI")])
9687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9688 ;; ??? Special case for immediate operand is missing - it is tricky.
9689 (define_insn "*xorsi_2_zext"
9690   [(set (reg FLAGS_REG)
9691         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9692                          (match_operand:SI 2 "general_operand" "g"))
9693                  (const_int 0)))
9694    (set (match_operand:DI 0 "register_operand" "=r")
9695         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9696   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9697    && ix86_binary_operator_ok (XOR, SImode, operands)"
9698   "xor{l}\t{%2, %k0|%k0, %2}"
9699   [(set_attr "type" "alu")
9700    (set_attr "mode" "SI")])
9702 (define_insn "*xorsi_2_zext_imm"
9703   [(set (reg FLAGS_REG)
9704         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9705                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9706                  (const_int 0)))
9707    (set (match_operand:DI 0 "register_operand" "=r")
9708         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9709   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9710    && ix86_binary_operator_ok (XOR, SImode, operands)"
9711   "xor{l}\t{%2, %k0|%k0, %2}"
9712   [(set_attr "type" "alu")
9713    (set_attr "mode" "SI")])
9715 (define_insn "*xorsi_3"
9716   [(set (reg FLAGS_REG)
9717         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9718                          (match_operand:SI 2 "general_operand" "g"))
9719                  (const_int 0)))
9720    (clobber (match_scratch:SI 0 "=r"))]
9721   "ix86_match_ccmode (insn, CCNOmode)
9722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9723   "xor{l}\t{%2, %0|%0, %2}"
9724   [(set_attr "type" "alu")
9725    (set_attr "mode" "SI")])
9727 (define_expand "xorhi3"
9728   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9729         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9730                 (match_operand:HI 2 "general_operand" "")))
9731    (clobber (reg:CC FLAGS_REG))]
9732   "TARGET_HIMODE_MATH"
9733   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9735 (define_insn "*xorhi_1"
9736   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9737         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9738                 (match_operand:HI 2 "general_operand" "g,ri")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "ix86_binary_operator_ok (XOR, HImode, operands)"
9741   "xor{w}\t{%2, %0|%0, %2}"
9742   [(set_attr "type" "alu")
9743    (set_attr "mode" "HI")])
9745 (define_insn "*xorhi_2"
9746   [(set (reg FLAGS_REG)
9747         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9748                          (match_operand:HI 2 "general_operand" "g,ri"))
9749                  (const_int 0)))
9750    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9751         (xor:HI (match_dup 1) (match_dup 2)))]
9752   "ix86_match_ccmode (insn, CCNOmode)
9753    && ix86_binary_operator_ok (XOR, HImode, operands)"
9754   "xor{w}\t{%2, %0|%0, %2}"
9755   [(set_attr "type" "alu")
9756    (set_attr "mode" "HI")])
9758 (define_insn "*xorhi_3"
9759   [(set (reg FLAGS_REG)
9760         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9761                          (match_operand:HI 2 "general_operand" "g"))
9762                  (const_int 0)))
9763    (clobber (match_scratch:HI 0 "=r"))]
9764   "ix86_match_ccmode (insn, CCNOmode)
9765    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9766   "xor{w}\t{%2, %0|%0, %2}"
9767   [(set_attr "type" "alu")
9768    (set_attr "mode" "HI")])
9770 (define_expand "xorqi3"
9771   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9772         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9773                 (match_operand:QI 2 "general_operand" "")))
9774    (clobber (reg:CC FLAGS_REG))]
9775   "TARGET_QIMODE_MATH"
9776   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9778 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9779 (define_insn "*xorqi_1"
9780   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9781         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9782                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9783    (clobber (reg:CC FLAGS_REG))]
9784   "ix86_binary_operator_ok (XOR, QImode, operands)"
9785   "@
9786    xor{b}\t{%2, %0|%0, %2}
9787    xor{b}\t{%2, %0|%0, %2}
9788    xor{l}\t{%k2, %k0|%k0, %k2}"
9789   [(set_attr "type" "alu")
9790    (set_attr "mode" "QI,QI,SI")])
9792 (define_insn "*xorqi_1_slp"
9793   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9794         (xor:QI (match_dup 0)
9795                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9796    (clobber (reg:CC FLAGS_REG))]
9797   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9798    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9799   "xor{b}\t{%1, %0|%0, %1}"
9800   [(set_attr "type" "alu1")
9801    (set_attr "mode" "QI")])
9803 (define_insn "xorqi_ext_0"
9804   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9805                          (const_int 8)
9806                          (const_int 8))
9807         (xor:SI
9808           (zero_extract:SI
9809             (match_operand 1 "ext_register_operand" "0")
9810             (const_int 8)
9811             (const_int 8))
9812           (match_operand 2 "const_int_operand" "n")))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9815   "xor{b}\t{%2, %h0|%h0, %2}"
9816   [(set_attr "type" "alu")
9817    (set_attr "length_immediate" "1")
9818    (set_attr "mode" "QI")])
9820 (define_insn "*xorqi_ext_1"
9821   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9822                          (const_int 8)
9823                          (const_int 8))
9824         (xor:SI
9825           (zero_extract:SI
9826             (match_operand 1 "ext_register_operand" "0")
9827             (const_int 8)
9828             (const_int 8))
9829           (zero_extend:SI
9830             (match_operand:QI 2 "general_operand" "Qm"))))
9831    (clobber (reg:CC FLAGS_REG))]
9832   "!TARGET_64BIT
9833    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9834   "xor{b}\t{%2, %h0|%h0, %2}"
9835   [(set_attr "type" "alu")
9836    (set_attr "length_immediate" "0")
9837    (set_attr "mode" "QI")])
9839 (define_insn "*xorqi_ext_1_rex64"
9840   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9841                          (const_int 8)
9842                          (const_int 8))
9843         (xor:SI
9844           (zero_extract:SI
9845             (match_operand 1 "ext_register_operand" "0")
9846             (const_int 8)
9847             (const_int 8))
9848           (zero_extend:SI
9849             (match_operand 2 "ext_register_operand" "Q"))))
9850    (clobber (reg:CC FLAGS_REG))]
9851   "TARGET_64BIT
9852    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9853   "xor{b}\t{%2, %h0|%h0, %2}"
9854   [(set_attr "type" "alu")
9855    (set_attr "length_immediate" "0")
9856    (set_attr "mode" "QI")])
9858 (define_insn "*xorqi_ext_2"
9859   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9860                          (const_int 8)
9861                          (const_int 8))
9862         (xor:SI
9863           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9864                            (const_int 8)
9865                            (const_int 8))
9866           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9867                            (const_int 8)
9868                            (const_int 8))))
9869    (clobber (reg:CC FLAGS_REG))]
9870   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9871   "xor{b}\t{%h2, %h0|%h0, %h2}"
9872   [(set_attr "type" "alu")
9873    (set_attr "length_immediate" "0")
9874    (set_attr "mode" "QI")])
9876 (define_insn "*xorqi_cc_1"
9877   [(set (reg FLAGS_REG)
9878         (compare
9879           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9880                   (match_operand:QI 2 "general_operand" "qim,qi"))
9881           (const_int 0)))
9882    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9883         (xor:QI (match_dup 1) (match_dup 2)))]
9884   "ix86_match_ccmode (insn, CCNOmode)
9885    && ix86_binary_operator_ok (XOR, QImode, operands)"
9886   "xor{b}\t{%2, %0|%0, %2}"
9887   [(set_attr "type" "alu")
9888    (set_attr "mode" "QI")])
9890 (define_insn "*xorqi_2_slp"
9891   [(set (reg FLAGS_REG)
9892         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9893                          (match_operand:QI 1 "general_operand" "qim,qi"))
9894                  (const_int 0)))
9895    (set (strict_low_part (match_dup 0))
9896         (xor:QI (match_dup 0) (match_dup 1)))]
9897   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9898    && ix86_match_ccmode (insn, CCNOmode)
9899    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9900   "xor{b}\t{%1, %0|%0, %1}"
9901   [(set_attr "type" "alu1")
9902    (set_attr "mode" "QI")])
9904 (define_insn "*xorqi_cc_2"
9905   [(set (reg FLAGS_REG)
9906         (compare
9907           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9908                   (match_operand:QI 2 "general_operand" "qim"))
9909           (const_int 0)))
9910    (clobber (match_scratch:QI 0 "=q"))]
9911   "ix86_match_ccmode (insn, CCNOmode)
9912    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9913   "xor{b}\t{%2, %0|%0, %2}"
9914   [(set_attr "type" "alu")
9915    (set_attr "mode" "QI")])
9917 (define_insn "*xorqi_cc_ext_1"
9918   [(set (reg FLAGS_REG)
9919         (compare
9920           (xor:SI
9921             (zero_extract:SI
9922               (match_operand 1 "ext_register_operand" "0")
9923               (const_int 8)
9924               (const_int 8))
9925             (match_operand:QI 2 "general_operand" "qmn"))
9926           (const_int 0)))
9927    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9928                          (const_int 8)
9929                          (const_int 8))
9930         (xor:SI
9931           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9932           (match_dup 2)))]
9933   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9934   "xor{b}\t{%2, %h0|%h0, %2}"
9935   [(set_attr "type" "alu")
9936    (set_attr "mode" "QI")])
9938 (define_insn "*xorqi_cc_ext_1_rex64"
9939   [(set (reg FLAGS_REG)
9940         (compare
9941           (xor:SI
9942             (zero_extract:SI
9943               (match_operand 1 "ext_register_operand" "0")
9944               (const_int 8)
9945               (const_int 8))
9946             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9947           (const_int 0)))
9948    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9949                          (const_int 8)
9950                          (const_int 8))
9951         (xor:SI
9952           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9953           (match_dup 2)))]
9954   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9955   "xor{b}\t{%2, %h0|%h0, %2}"
9956   [(set_attr "type" "alu")
9957    (set_attr "mode" "QI")])
9959 (define_expand "xorqi_cc_ext_1"
9960   [(parallel [
9961      (set (reg:CCNO FLAGS_REG)
9962           (compare:CCNO
9963             (xor:SI
9964               (zero_extract:SI
9965                 (match_operand 1 "ext_register_operand" "")
9966                 (const_int 8)
9967                 (const_int 8))
9968               (match_operand:QI 2 "general_operand" ""))
9969             (const_int 0)))
9970      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9971                            (const_int 8)
9972                            (const_int 8))
9973           (xor:SI
9974             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9975             (match_dup 2)))])]
9976   ""
9977   "")
9979 (define_split
9980   [(set (match_operand 0 "register_operand" "")
9981         (xor (match_operand 1 "register_operand" "")
9982              (match_operand 2 "const_int_operand" "")))
9983    (clobber (reg:CC FLAGS_REG))]
9984    "reload_completed
9985     && QI_REG_P (operands[0])
9986     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9987     && !(INTVAL (operands[2]) & ~(255 << 8))
9988     && GET_MODE (operands[0]) != QImode"
9989   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9990                    (xor:SI (zero_extract:SI (match_dup 1)
9991                                             (const_int 8) (const_int 8))
9992                            (match_dup 2)))
9993               (clobber (reg:CC FLAGS_REG))])]
9994   "operands[0] = gen_lowpart (SImode, operands[0]);
9995    operands[1] = gen_lowpart (SImode, operands[1]);
9996    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9998 ;; Since XOR can be encoded with sign extended immediate, this is only
9999 ;; profitable when 7th bit is set.
10000 (define_split
10001   [(set (match_operand 0 "register_operand" "")
10002         (xor (match_operand 1 "general_operand" "")
10003              (match_operand 2 "const_int_operand" "")))
10004    (clobber (reg:CC FLAGS_REG))]
10005    "reload_completed
10006     && ANY_QI_REG_P (operands[0])
10007     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10008     && !(INTVAL (operands[2]) & ~255)
10009     && (INTVAL (operands[2]) & 128)
10010     && GET_MODE (operands[0]) != QImode"
10011   [(parallel [(set (strict_low_part (match_dup 0))
10012                    (xor:QI (match_dup 1)
10013                            (match_dup 2)))
10014               (clobber (reg:CC FLAGS_REG))])]
10015   "operands[0] = gen_lowpart (QImode, operands[0]);
10016    operands[1] = gen_lowpart (QImode, operands[1]);
10017    operands[2] = gen_lowpart (QImode, operands[2]);")
10019 ;; Negation instructions
10021 (define_expand "negti2"
10022   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10023                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10024               (clobber (reg:CC FLAGS_REG))])]
10025   "TARGET_64BIT"
10026   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10028 (define_insn "*negti2_1"
10029   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10030         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10031    (clobber (reg:CC FLAGS_REG))]
10032   "TARGET_64BIT
10033    && ix86_unary_operator_ok (NEG, TImode, operands)"
10034   "#")
10036 (define_split
10037   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10038         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10039    (clobber (reg:CC FLAGS_REG))]
10040   "TARGET_64BIT && reload_completed"
10041   [(parallel
10042     [(set (reg:CCZ FLAGS_REG)
10043           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10044      (set (match_dup 0) (neg:DI (match_dup 2)))])
10045    (parallel
10046     [(set (match_dup 1)
10047           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10048                             (match_dup 3))
10049                    (const_int 0)))
10050      (clobber (reg:CC FLAGS_REG))])
10051    (parallel
10052     [(set (match_dup 1)
10053           (neg:DI (match_dup 1)))
10054      (clobber (reg:CC FLAGS_REG))])]
10055   "split_ti (operands+1, 1, operands+2, operands+3);
10056    split_ti (operands+0, 1, operands+0, operands+1);")
10058 (define_expand "negdi2"
10059   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10060                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10061               (clobber (reg:CC FLAGS_REG))])]
10062   ""
10063   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10065 (define_insn "*negdi2_1"
10066   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10067         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10068    (clobber (reg:CC FLAGS_REG))]
10069   "!TARGET_64BIT
10070    && ix86_unary_operator_ok (NEG, DImode, operands)"
10071   "#")
10073 (define_split
10074   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10075         (neg:DI (match_operand:DI 1 "general_operand" "")))
10076    (clobber (reg:CC FLAGS_REG))]
10077   "!TARGET_64BIT && reload_completed"
10078   [(parallel
10079     [(set (reg:CCZ FLAGS_REG)
10080           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10081      (set (match_dup 0) (neg:SI (match_dup 2)))])
10082    (parallel
10083     [(set (match_dup 1)
10084           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10085                             (match_dup 3))
10086                    (const_int 0)))
10087      (clobber (reg:CC FLAGS_REG))])
10088    (parallel
10089     [(set (match_dup 1)
10090           (neg:SI (match_dup 1)))
10091      (clobber (reg:CC FLAGS_REG))])]
10092   "split_di (operands+1, 1, operands+2, operands+3);
10093    split_di (operands+0, 1, operands+0, operands+1);")
10095 (define_insn "*negdi2_1_rex64"
10096   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10097         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10098    (clobber (reg:CC FLAGS_REG))]
10099   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10100   "neg{q}\t%0"
10101   [(set_attr "type" "negnot")
10102    (set_attr "mode" "DI")])
10104 ;; The problem with neg is that it does not perform (compare x 0),
10105 ;; it really performs (compare 0 x), which leaves us with the zero
10106 ;; flag being the only useful item.
10108 (define_insn "*negdi2_cmpz_rex64"
10109   [(set (reg:CCZ FLAGS_REG)
10110         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10111                      (const_int 0)))
10112    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10113         (neg:DI (match_dup 1)))]
10114   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10115   "neg{q}\t%0"
10116   [(set_attr "type" "negnot")
10117    (set_attr "mode" "DI")])
10120 (define_expand "negsi2"
10121   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10122                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10123               (clobber (reg:CC FLAGS_REG))])]
10124   ""
10125   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10127 (define_insn "*negsi2_1"
10128   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10129         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10130    (clobber (reg:CC FLAGS_REG))]
10131   "ix86_unary_operator_ok (NEG, SImode, operands)"
10132   "neg{l}\t%0"
10133   [(set_attr "type" "negnot")
10134    (set_attr "mode" "SI")])
10136 ;; Combine is quite creative about this pattern.
10137 (define_insn "*negsi2_1_zext"
10138   [(set (match_operand:DI 0 "register_operand" "=r")
10139         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10140                                         (const_int 32)))
10141                      (const_int 32)))
10142    (clobber (reg:CC FLAGS_REG))]
10143   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10144   "neg{l}\t%k0"
10145   [(set_attr "type" "negnot")
10146    (set_attr "mode" "SI")])
10148 ;; The problem with neg is that it does not perform (compare x 0),
10149 ;; it really performs (compare 0 x), which leaves us with the zero
10150 ;; flag being the only useful item.
10152 (define_insn "*negsi2_cmpz"
10153   [(set (reg:CCZ FLAGS_REG)
10154         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10155                      (const_int 0)))
10156    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10157         (neg:SI (match_dup 1)))]
10158   "ix86_unary_operator_ok (NEG, SImode, operands)"
10159   "neg{l}\t%0"
10160   [(set_attr "type" "negnot")
10161    (set_attr "mode" "SI")])
10163 (define_insn "*negsi2_cmpz_zext"
10164   [(set (reg:CCZ FLAGS_REG)
10165         (compare:CCZ (lshiftrt:DI
10166                        (neg:DI (ashift:DI
10167                                  (match_operand:DI 1 "register_operand" "0")
10168                                  (const_int 32)))
10169                        (const_int 32))
10170                      (const_int 0)))
10171    (set (match_operand:DI 0 "register_operand" "=r")
10172         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10173                                         (const_int 32)))
10174                      (const_int 32)))]
10175   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10176   "neg{l}\t%k0"
10177   [(set_attr "type" "negnot")
10178    (set_attr "mode" "SI")])
10180 (define_expand "neghi2"
10181   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10182                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10183               (clobber (reg:CC FLAGS_REG))])]
10184   "TARGET_HIMODE_MATH"
10185   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10187 (define_insn "*neghi2_1"
10188   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10189         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10190    (clobber (reg:CC FLAGS_REG))]
10191   "ix86_unary_operator_ok (NEG, HImode, operands)"
10192   "neg{w}\t%0"
10193   [(set_attr "type" "negnot")
10194    (set_attr "mode" "HI")])
10196 (define_insn "*neghi2_cmpz"
10197   [(set (reg:CCZ FLAGS_REG)
10198         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10199                      (const_int 0)))
10200    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10201         (neg:HI (match_dup 1)))]
10202   "ix86_unary_operator_ok (NEG, HImode, operands)"
10203   "neg{w}\t%0"
10204   [(set_attr "type" "negnot")
10205    (set_attr "mode" "HI")])
10207 (define_expand "negqi2"
10208   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10209                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10210               (clobber (reg:CC FLAGS_REG))])]
10211   "TARGET_QIMODE_MATH"
10212   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10214 (define_insn "*negqi2_1"
10215   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10216         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10217    (clobber (reg:CC FLAGS_REG))]
10218   "ix86_unary_operator_ok (NEG, QImode, operands)"
10219   "neg{b}\t%0"
10220   [(set_attr "type" "negnot")
10221    (set_attr "mode" "QI")])
10223 (define_insn "*negqi2_cmpz"
10224   [(set (reg:CCZ FLAGS_REG)
10225         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10226                      (const_int 0)))
10227    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10228         (neg:QI (match_dup 1)))]
10229   "ix86_unary_operator_ok (NEG, QImode, operands)"
10230   "neg{b}\t%0"
10231   [(set_attr "type" "negnot")
10232    (set_attr "mode" "QI")])
10234 ;; Changing of sign for FP values is doable using integer unit too.
10236 (define_expand "neg<mode>2"
10237   [(set (match_operand:X87MODEF 0 "register_operand" "")
10238         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10239   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10240   "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10242 (define_expand "abs<mode>2"
10243   [(set (match_operand:X87MODEF 0 "register_operand" "")
10244         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10245   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10246   "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10248 (define_insn "*absneg<mode>2_mixed"
10249   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10250         (match_operator:MODEF 3 "absneg_operator"
10251           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10252    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10253    (clobber (reg:CC FLAGS_REG))]
10254   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10255   "#")
10257 (define_insn "*absneg<mode>2_sse"
10258   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10259         (match_operator:MODEF 3 "absneg_operator"
10260           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10261    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10262    (clobber (reg:CC FLAGS_REG))]
10263   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10264   "#")
10266 (define_insn "*absneg<mode>2_i387"
10267   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10268         (match_operator:X87MODEF 3 "absneg_operator"
10269           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10270    (use (match_operand 2 "" ""))
10271    (clobber (reg:CC FLAGS_REG))]
10272   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10273   "#")
10275 (define_expand "negtf2"
10276   [(set (match_operand:TF 0 "register_operand" "")
10277         (neg:TF (match_operand:TF 1 "register_operand" "")))]
10278   "TARGET_64BIT"
10279   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10281 (define_expand "abstf2"
10282   [(set (match_operand:TF 0 "register_operand" "")
10283         (abs:TF (match_operand:TF 1 "register_operand" "")))]
10284   "TARGET_64BIT"
10285   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10287 (define_insn "*absnegtf2_sse"
10288   [(set (match_operand:TF 0 "register_operand" "=x,x")
10289         (match_operator:TF 3 "absneg_operator"
10290           [(match_operand:TF 1 "register_operand" "0,x")]))
10291    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10292    (clobber (reg:CC FLAGS_REG))]
10293   "TARGET_64BIT"
10294   "#")
10296 ;; Splitters for fp abs and neg.
10298 (define_split
10299   [(set (match_operand 0 "fp_register_operand" "")
10300         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10301    (use (match_operand 2 "" ""))
10302    (clobber (reg:CC FLAGS_REG))]
10303   "reload_completed"
10304   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10306 (define_split
10307   [(set (match_operand 0 "register_operand" "")
10308         (match_operator 3 "absneg_operator"
10309           [(match_operand 1 "register_operand" "")]))
10310    (use (match_operand 2 "nonimmediate_operand" ""))
10311    (clobber (reg:CC FLAGS_REG))]
10312   "reload_completed && SSE_REG_P (operands[0])"
10313   [(set (match_dup 0) (match_dup 3))]
10315   enum machine_mode mode = GET_MODE (operands[0]);
10316   enum machine_mode vmode = GET_MODE (operands[2]);
10317   rtx tmp;
10319   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10320   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10321   if (operands_match_p (operands[0], operands[2]))
10322     {
10323       tmp = operands[1];
10324       operands[1] = operands[2];
10325       operands[2] = tmp;
10326     }
10327   if (GET_CODE (operands[3]) == ABS)
10328     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10329   else
10330     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10331   operands[3] = tmp;
10334 (define_split
10335   [(set (match_operand:SF 0 "register_operand" "")
10336         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10337    (use (match_operand:V4SF 2 "" ""))
10338    (clobber (reg:CC FLAGS_REG))]
10339   "reload_completed"
10340   [(parallel [(set (match_dup 0) (match_dup 1))
10341               (clobber (reg:CC FLAGS_REG))])]
10343   rtx tmp;
10344   operands[0] = gen_lowpart (SImode, operands[0]);
10345   if (GET_CODE (operands[1]) == ABS)
10346     {
10347       tmp = gen_int_mode (0x7fffffff, SImode);
10348       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10349     }
10350   else
10351     {
10352       tmp = gen_int_mode (0x80000000, SImode);
10353       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10354     }
10355   operands[1] = tmp;
10358 (define_split
10359   [(set (match_operand:DF 0 "register_operand" "")
10360         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10361    (use (match_operand 2 "" ""))
10362    (clobber (reg:CC FLAGS_REG))]
10363   "reload_completed"
10364   [(parallel [(set (match_dup 0) (match_dup 1))
10365               (clobber (reg:CC FLAGS_REG))])]
10367   rtx tmp;
10368   if (TARGET_64BIT)
10369     {
10370       tmp = gen_lowpart (DImode, operands[0]);
10371       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10372       operands[0] = tmp;
10374       if (GET_CODE (operands[1]) == ABS)
10375         tmp = const0_rtx;
10376       else
10377         tmp = gen_rtx_NOT (DImode, tmp);
10378     }
10379   else
10380     {
10381       operands[0] = gen_highpart (SImode, operands[0]);
10382       if (GET_CODE (operands[1]) == ABS)
10383         {
10384           tmp = gen_int_mode (0x7fffffff, SImode);
10385           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10386         }
10387       else
10388         {
10389           tmp = gen_int_mode (0x80000000, SImode);
10390           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10391         }
10392     }
10393   operands[1] = tmp;
10396 (define_split
10397   [(set (match_operand:XF 0 "register_operand" "")
10398         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10399    (use (match_operand 2 "" ""))
10400    (clobber (reg:CC FLAGS_REG))]
10401   "reload_completed"
10402   [(parallel [(set (match_dup 0) (match_dup 1))
10403               (clobber (reg:CC FLAGS_REG))])]
10405   rtx tmp;
10406   operands[0] = gen_rtx_REG (SImode,
10407                              true_regnum (operands[0])
10408                              + (TARGET_64BIT ? 1 : 2));
10409   if (GET_CODE (operands[1]) == ABS)
10410     {
10411       tmp = GEN_INT (0x7fff);
10412       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10413     }
10414   else
10415     {
10416       tmp = GEN_INT (0x8000);
10417       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10418     }
10419   operands[1] = tmp;
10422 ;; Conditionalize these after reload. If they match before reload, we
10423 ;; lose the clobber and ability to use integer instructions.
10425 (define_insn "*neg<mode>2_1"
10426   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10427         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10428   "TARGET_80387
10429    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10430   "fchs"
10431   [(set_attr "type" "fsgn")
10432    (set_attr "mode" "<MODE>")])
10434 (define_insn "*abs<mode>2_1"
10435   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10436         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10437   "TARGET_80387
10438    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10439   "fabs"
10440   [(set_attr "type" "fsgn")
10441    (set_attr "mode" "<MODE>")])
10443 (define_insn "*negextendsfdf2"
10444   [(set (match_operand:DF 0 "register_operand" "=f")
10445         (neg:DF (float_extend:DF
10446                   (match_operand:SF 1 "register_operand" "0"))))]
10447   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10448   "fchs"
10449   [(set_attr "type" "fsgn")
10450    (set_attr "mode" "DF")])
10452 (define_insn "*negextenddfxf2"
10453   [(set (match_operand:XF 0 "register_operand" "=f")
10454         (neg:XF (float_extend:XF
10455                   (match_operand:DF 1 "register_operand" "0"))))]
10456   "TARGET_80387"
10457   "fchs"
10458   [(set_attr "type" "fsgn")
10459    (set_attr "mode" "XF")])
10461 (define_insn "*negextendsfxf2"
10462   [(set (match_operand:XF 0 "register_operand" "=f")
10463         (neg:XF (float_extend:XF
10464                   (match_operand:SF 1 "register_operand" "0"))))]
10465   "TARGET_80387"
10466   "fchs"
10467   [(set_attr "type" "fsgn")
10468    (set_attr "mode" "XF")])
10470 (define_insn "*absextendsfdf2"
10471   [(set (match_operand:DF 0 "register_operand" "=f")
10472         (abs:DF (float_extend:DF
10473                   (match_operand:SF 1 "register_operand" "0"))))]
10474   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10475   "fabs"
10476   [(set_attr "type" "fsgn")
10477    (set_attr "mode" "DF")])
10479 (define_insn "*absextenddfxf2"
10480   [(set (match_operand:XF 0 "register_operand" "=f")
10481         (abs:XF (float_extend:XF
10482           (match_operand:DF 1 "register_operand" "0"))))]
10483   "TARGET_80387"
10484   "fabs"
10485   [(set_attr "type" "fsgn")
10486    (set_attr "mode" "XF")])
10488 (define_insn "*absextendsfxf2"
10489   [(set (match_operand:XF 0 "register_operand" "=f")
10490         (abs:XF (float_extend:XF
10491           (match_operand:SF 1 "register_operand" "0"))))]
10492   "TARGET_80387"
10493   "fabs"
10494   [(set_attr "type" "fsgn")
10495    (set_attr "mode" "XF")])
10497 ;; Copysign instructions
10499 (define_mode_iterator CSGNMODE [SF DF TF])
10500 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10502 (define_expand "copysign<mode>3"
10503   [(match_operand:CSGNMODE 0 "register_operand" "")
10504    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10505    (match_operand:CSGNMODE 2 "register_operand" "")]
10506   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10507    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10509   ix86_expand_copysign (operands);
10510   DONE;
10513 (define_insn_and_split "copysign<mode>3_const"
10514   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10515         (unspec:CSGNMODE
10516           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10517            (match_operand:CSGNMODE 2 "register_operand" "0")
10518            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10519           UNSPEC_COPYSIGN))]
10520   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10521    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10522   "#"
10523   "&& reload_completed"
10524   [(const_int 0)]
10526   ix86_split_copysign_const (operands);
10527   DONE;
10530 (define_insn "copysign<mode>3_var"
10531   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10532         (unspec:CSGNMODE
10533           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10534            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10535            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10536            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10537           UNSPEC_COPYSIGN))
10538    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10539   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10540    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10541   "#")
10543 (define_split
10544   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10545         (unspec:CSGNMODE
10546           [(match_operand:CSGNMODE 2 "register_operand" "")
10547            (match_operand:CSGNMODE 3 "register_operand" "")
10548            (match_operand:<CSGNVMODE> 4 "" "")
10549            (match_operand:<CSGNVMODE> 5 "" "")]
10550           UNSPEC_COPYSIGN))
10551    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10552   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10553     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10554    && reload_completed"
10555   [(const_int 0)]
10557   ix86_split_copysign_var (operands);
10558   DONE;
10561 ;; One complement instructions
10563 (define_expand "one_cmpldi2"
10564   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10565         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10566   "TARGET_64BIT"
10567   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10569 (define_insn "*one_cmpldi2_1_rex64"
10570   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10571         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10572   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10573   "not{q}\t%0"
10574   [(set_attr "type" "negnot")
10575    (set_attr "mode" "DI")])
10577 (define_insn "*one_cmpldi2_2_rex64"
10578   [(set (reg FLAGS_REG)
10579         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10580                  (const_int 0)))
10581    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10582         (not:DI (match_dup 1)))]
10583   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10584    && ix86_unary_operator_ok (NOT, DImode, operands)"
10585   "#"
10586   [(set_attr "type" "alu1")
10587    (set_attr "mode" "DI")])
10589 (define_split
10590   [(set (match_operand 0 "flags_reg_operand" "")
10591         (match_operator 2 "compare_operator"
10592           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10593            (const_int 0)]))
10594    (set (match_operand:DI 1 "nonimmediate_operand" "")
10595         (not:DI (match_dup 3)))]
10596   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10597   [(parallel [(set (match_dup 0)
10598                    (match_op_dup 2
10599                      [(xor:DI (match_dup 3) (const_int -1))
10600                       (const_int 0)]))
10601               (set (match_dup 1)
10602                    (xor:DI (match_dup 3) (const_int -1)))])]
10603   "")
10605 (define_expand "one_cmplsi2"
10606   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10607         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10608   ""
10609   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10611 (define_insn "*one_cmplsi2_1"
10612   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10613         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10614   "ix86_unary_operator_ok (NOT, SImode, operands)"
10615   "not{l}\t%0"
10616   [(set_attr "type" "negnot")
10617    (set_attr "mode" "SI")])
10619 ;; ??? Currently never generated - xor is used instead.
10620 (define_insn "*one_cmplsi2_1_zext"
10621   [(set (match_operand:DI 0 "register_operand" "=r")
10622         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10623   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10624   "not{l}\t%k0"
10625   [(set_attr "type" "negnot")
10626    (set_attr "mode" "SI")])
10628 (define_insn "*one_cmplsi2_2"
10629   [(set (reg FLAGS_REG)
10630         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10631                  (const_int 0)))
10632    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10633         (not:SI (match_dup 1)))]
10634   "ix86_match_ccmode (insn, CCNOmode)
10635    && ix86_unary_operator_ok (NOT, SImode, operands)"
10636   "#"
10637   [(set_attr "type" "alu1")
10638    (set_attr "mode" "SI")])
10640 (define_split
10641   [(set (match_operand 0 "flags_reg_operand" "")
10642         (match_operator 2 "compare_operator"
10643           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10644            (const_int 0)]))
10645    (set (match_operand:SI 1 "nonimmediate_operand" "")
10646         (not:SI (match_dup 3)))]
10647   "ix86_match_ccmode (insn, CCNOmode)"
10648   [(parallel [(set (match_dup 0)
10649                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10650                                     (const_int 0)]))
10651               (set (match_dup 1)
10652                    (xor:SI (match_dup 3) (const_int -1)))])]
10653   "")
10655 ;; ??? Currently never generated - xor is used instead.
10656 (define_insn "*one_cmplsi2_2_zext"
10657   [(set (reg FLAGS_REG)
10658         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10659                  (const_int 0)))
10660    (set (match_operand:DI 0 "register_operand" "=r")
10661         (zero_extend:DI (not:SI (match_dup 1))))]
10662   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10663    && ix86_unary_operator_ok (NOT, SImode, operands)"
10664   "#"
10665   [(set_attr "type" "alu1")
10666    (set_attr "mode" "SI")])
10668 (define_split
10669   [(set (match_operand 0 "flags_reg_operand" "")
10670         (match_operator 2 "compare_operator"
10671           [(not:SI (match_operand:SI 3 "register_operand" ""))
10672            (const_int 0)]))
10673    (set (match_operand:DI 1 "register_operand" "")
10674         (zero_extend:DI (not:SI (match_dup 3))))]
10675   "ix86_match_ccmode (insn, CCNOmode)"
10676   [(parallel [(set (match_dup 0)
10677                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10678                                     (const_int 0)]))
10679               (set (match_dup 1)
10680                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10681   "")
10683 (define_expand "one_cmplhi2"
10684   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10685         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10686   "TARGET_HIMODE_MATH"
10687   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10689 (define_insn "*one_cmplhi2_1"
10690   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10691         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10692   "ix86_unary_operator_ok (NOT, HImode, operands)"
10693   "not{w}\t%0"
10694   [(set_attr "type" "negnot")
10695    (set_attr "mode" "HI")])
10697 (define_insn "*one_cmplhi2_2"
10698   [(set (reg FLAGS_REG)
10699         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10700                  (const_int 0)))
10701    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10702         (not:HI (match_dup 1)))]
10703   "ix86_match_ccmode (insn, CCNOmode)
10704    && ix86_unary_operator_ok (NEG, HImode, operands)"
10705   "#"
10706   [(set_attr "type" "alu1")
10707    (set_attr "mode" "HI")])
10709 (define_split
10710   [(set (match_operand 0 "flags_reg_operand" "")
10711         (match_operator 2 "compare_operator"
10712           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10713            (const_int 0)]))
10714    (set (match_operand:HI 1 "nonimmediate_operand" "")
10715         (not:HI (match_dup 3)))]
10716   "ix86_match_ccmode (insn, CCNOmode)"
10717   [(parallel [(set (match_dup 0)
10718                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10719                                     (const_int 0)]))
10720               (set (match_dup 1)
10721                    (xor:HI (match_dup 3) (const_int -1)))])]
10722   "")
10724 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10725 (define_expand "one_cmplqi2"
10726   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10727         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10728   "TARGET_QIMODE_MATH"
10729   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10731 (define_insn "*one_cmplqi2_1"
10732   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10733         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10734   "ix86_unary_operator_ok (NOT, QImode, operands)"
10735   "@
10736    not{b}\t%0
10737    not{l}\t%k0"
10738   [(set_attr "type" "negnot")
10739    (set_attr "mode" "QI,SI")])
10741 (define_insn "*one_cmplqi2_2"
10742   [(set (reg FLAGS_REG)
10743         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10744                  (const_int 0)))
10745    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10746         (not:QI (match_dup 1)))]
10747   "ix86_match_ccmode (insn, CCNOmode)
10748    && ix86_unary_operator_ok (NOT, QImode, operands)"
10749   "#"
10750   [(set_attr "type" "alu1")
10751    (set_attr "mode" "QI")])
10753 (define_split
10754   [(set (match_operand 0 "flags_reg_operand" "")
10755         (match_operator 2 "compare_operator"
10756           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10757            (const_int 0)]))
10758    (set (match_operand:QI 1 "nonimmediate_operand" "")
10759         (not:QI (match_dup 3)))]
10760   "ix86_match_ccmode (insn, CCNOmode)"
10761   [(parallel [(set (match_dup 0)
10762                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10763                                     (const_int 0)]))
10764               (set (match_dup 1)
10765                    (xor:QI (match_dup 3) (const_int -1)))])]
10766   "")
10768 ;; Arithmetic shift instructions
10770 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10771 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10772 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10773 ;; from the assembler input.
10775 ;; This instruction shifts the target reg/mem as usual, but instead of
10776 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10777 ;; is a left shift double, bits are taken from the high order bits of
10778 ;; reg, else if the insn is a shift right double, bits are taken from the
10779 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10780 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10782 ;; Since sh[lr]d does not change the `reg' operand, that is done
10783 ;; separately, making all shifts emit pairs of shift double and normal
10784 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10785 ;; support a 63 bit shift, each shift where the count is in a reg expands
10786 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10788 ;; If the shift count is a constant, we need never emit more than one
10789 ;; shift pair, instead using moves and sign extension for counts greater
10790 ;; than 31.
10792 (define_expand "ashlti3"
10793   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10794                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10795                               (match_operand:QI 2 "nonmemory_operand" "")))
10796               (clobber (reg:CC FLAGS_REG))])]
10797   "TARGET_64BIT"
10799   if (! immediate_operand (operands[2], QImode))
10800     {
10801       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10802       DONE;
10803     }
10804   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10805   DONE;
10808 (define_insn "ashlti3_1"
10809   [(set (match_operand:TI 0 "register_operand" "=r")
10810         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10811                    (match_operand:QI 2 "register_operand" "c")))
10812    (clobber (match_scratch:DI 3 "=&r"))
10813    (clobber (reg:CC FLAGS_REG))]
10814   "TARGET_64BIT"
10815   "#"
10816   [(set_attr "type" "multi")])
10818 ;; This pattern must be defined before *ashlti3_2 to prevent
10819 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10821 (define_insn "sse2_ashlti3"
10822   [(set (match_operand:TI 0 "register_operand" "=x")
10823         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10824                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10825   "TARGET_SSE2"
10827   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10828   return "pslldq\t{%2, %0|%0, %2}";
10830   [(set_attr "type" "sseishft")
10831    (set_attr "prefix_data16" "1")
10832    (set_attr "mode" "TI")])
10834 (define_insn "*ashlti3_2"
10835   [(set (match_operand:TI 0 "register_operand" "=r")
10836         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10837                    (match_operand:QI 2 "immediate_operand" "O")))
10838    (clobber (reg:CC FLAGS_REG))]
10839   "TARGET_64BIT"
10840   "#"
10841   [(set_attr "type" "multi")])
10843 (define_split
10844   [(set (match_operand:TI 0 "register_operand" "")
10845         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10846                    (match_operand:QI 2 "register_operand" "")))
10847    (clobber (match_scratch:DI 3 ""))
10848    (clobber (reg:CC FLAGS_REG))]
10849   "TARGET_64BIT && reload_completed"
10850   [(const_int 0)]
10851   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10853 (define_split
10854   [(set (match_operand:TI 0 "register_operand" "")
10855         (ashift:TI (match_operand:TI 1 "register_operand" "")
10856                    (match_operand:QI 2 "immediate_operand" "")))
10857    (clobber (reg:CC FLAGS_REG))]
10858   "TARGET_64BIT && reload_completed"
10859   [(const_int 0)]
10860   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10862 (define_insn "x86_64_shld"
10863   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10864         (ior:DI (ashift:DI (match_dup 0)
10865                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10866                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10867                   (minus:QI (const_int 64) (match_dup 2)))))
10868    (clobber (reg:CC FLAGS_REG))]
10869   "TARGET_64BIT"
10870   "@
10871    shld{q}\t{%2, %1, %0|%0, %1, %2}
10872    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10873   [(set_attr "type" "ishift")
10874    (set_attr "prefix_0f" "1")
10875    (set_attr "mode" "DI")
10876    (set_attr "athlon_decode" "vector")
10877    (set_attr "amdfam10_decode" "vector")])
10879 (define_expand "x86_64_shift_adj"
10880   [(set (reg:CCZ FLAGS_REG)
10881         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10882                              (const_int 64))
10883                      (const_int 0)))
10884    (set (match_operand:DI 0 "register_operand" "")
10885         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10886                          (match_operand:DI 1 "register_operand" "")
10887                          (match_dup 0)))
10888    (set (match_dup 1)
10889         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10890                          (match_operand:DI 3 "register_operand" "r")
10891                          (match_dup 1)))]
10892   "TARGET_64BIT"
10893   "")
10895 (define_expand "ashldi3"
10896   [(set (match_operand:DI 0 "shiftdi_operand" "")
10897         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10898                    (match_operand:QI 2 "nonmemory_operand" "")))]
10899   ""
10900   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10902 (define_insn "*ashldi3_1_rex64"
10903   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10904         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10905                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10906    (clobber (reg:CC FLAGS_REG))]
10907   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10909   switch (get_attr_type (insn))
10910     {
10911     case TYPE_ALU:
10912       gcc_assert (operands[2] == const1_rtx);
10913       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10914       return "add{q}\t%0, %0";
10916     case TYPE_LEA:
10917       gcc_assert (CONST_INT_P (operands[2]));
10918       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10919       operands[1] = gen_rtx_MULT (DImode, operands[1],
10920                                   GEN_INT (1 << INTVAL (operands[2])));
10921       return "lea{q}\t{%a1, %0|%0, %a1}";
10923     default:
10924       if (REG_P (operands[2]))
10925         return "sal{q}\t{%b2, %0|%0, %b2}";
10926       else if (operands[2] == const1_rtx
10927                && (TARGET_SHIFT1 || optimize_size))
10928         return "sal{q}\t%0";
10929       else
10930         return "sal{q}\t{%2, %0|%0, %2}";
10931     }
10933   [(set (attr "type")
10934      (cond [(eq_attr "alternative" "1")
10935               (const_string "lea")
10936             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10937                           (const_int 0))
10938                       (match_operand 0 "register_operand" ""))
10939                  (match_operand 2 "const1_operand" ""))
10940               (const_string "alu")
10941            ]
10942            (const_string "ishift")))
10943    (set_attr "mode" "DI")])
10945 ;; Convert lea to the lea pattern to avoid flags dependency.
10946 (define_split
10947   [(set (match_operand:DI 0 "register_operand" "")
10948         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10949                    (match_operand:QI 2 "immediate_operand" "")))
10950    (clobber (reg:CC FLAGS_REG))]
10951   "TARGET_64BIT && reload_completed
10952    && true_regnum (operands[0]) != true_regnum (operands[1])"
10953   [(set (match_dup 0)
10954         (mult:DI (match_dup 1)
10955                  (match_dup 2)))]
10956   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10958 ;; This pattern can't accept a variable shift count, since shifts by
10959 ;; zero don't affect the flags.  We assume that shifts by constant
10960 ;; zero are optimized away.
10961 (define_insn "*ashldi3_cmp_rex64"
10962   [(set (reg FLAGS_REG)
10963         (compare
10964           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10965                      (match_operand:QI 2 "immediate_operand" "e"))
10966           (const_int 0)))
10967    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10968         (ashift:DI (match_dup 1) (match_dup 2)))]
10969   "TARGET_64BIT
10970    && (optimize_size
10971        || !TARGET_PARTIAL_FLAG_REG_STALL
10972        || (operands[2] == const1_rtx
10973            && (TARGET_SHIFT1
10974                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10975    && ix86_match_ccmode (insn, CCGOCmode)
10976    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10978   switch (get_attr_type (insn))
10979     {
10980     case TYPE_ALU:
10981       gcc_assert (operands[2] == const1_rtx);
10982       return "add{q}\t%0, %0";
10984     default:
10985       if (REG_P (operands[2]))
10986         return "sal{q}\t{%b2, %0|%0, %b2}";
10987       else if (operands[2] == const1_rtx
10988                && (TARGET_SHIFT1 || optimize_size))
10989         return "sal{q}\t%0";
10990       else
10991         return "sal{q}\t{%2, %0|%0, %2}";
10992     }
10994   [(set (attr "type")
10995      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10996                           (const_int 0))
10997                       (match_operand 0 "register_operand" ""))
10998                  (match_operand 2 "const1_operand" ""))
10999               (const_string "alu")
11000            ]
11001            (const_string "ishift")))
11002    (set_attr "mode" "DI")])
11004 (define_insn "*ashldi3_cconly_rex64"
11005   [(set (reg FLAGS_REG)
11006         (compare
11007           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11008                      (match_operand:QI 2 "immediate_operand" "e"))
11009           (const_int 0)))
11010    (clobber (match_scratch:DI 0 "=r"))]
11011   "TARGET_64BIT
11012    && (optimize_size
11013        || !TARGET_PARTIAL_FLAG_REG_STALL
11014        || (operands[2] == const1_rtx
11015            && (TARGET_SHIFT1
11016                || TARGET_DOUBLE_WITH_ADD)))
11017    && ix86_match_ccmode (insn, CCGOCmode)
11018    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11020   switch (get_attr_type (insn))
11021     {
11022     case TYPE_ALU:
11023       gcc_assert (operands[2] == const1_rtx);
11024       return "add{q}\t%0, %0";
11026     default:
11027       if (REG_P (operands[2]))
11028         return "sal{q}\t{%b2, %0|%0, %b2}";
11029       else if (operands[2] == const1_rtx
11030                && (TARGET_SHIFT1 || optimize_size))
11031         return "sal{q}\t%0";
11032       else
11033         return "sal{q}\t{%2, %0|%0, %2}";
11034     }
11036   [(set (attr "type")
11037      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11038                           (const_int 0))
11039                       (match_operand 0 "register_operand" ""))
11040                  (match_operand 2 "const1_operand" ""))
11041               (const_string "alu")
11042            ]
11043            (const_string "ishift")))
11044    (set_attr "mode" "DI")])
11046 (define_insn "*ashldi3_1"
11047   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11048         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11049                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11050    (clobber (reg:CC FLAGS_REG))]
11051   "!TARGET_64BIT"
11052   "#"
11053   [(set_attr "type" "multi")])
11055 ;; By default we don't ask for a scratch register, because when DImode
11056 ;; values are manipulated, registers are already at a premium.  But if
11057 ;; we have one handy, we won't turn it away.
11058 (define_peephole2
11059   [(match_scratch:SI 3 "r")
11060    (parallel [(set (match_operand:DI 0 "register_operand" "")
11061                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11062                               (match_operand:QI 2 "nonmemory_operand" "")))
11063               (clobber (reg:CC FLAGS_REG))])
11064    (match_dup 3)]
11065   "!TARGET_64BIT && TARGET_CMOVE"
11066   [(const_int 0)]
11067   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11069 (define_split
11070   [(set (match_operand:DI 0 "register_operand" "")
11071         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11072                    (match_operand:QI 2 "nonmemory_operand" "")))
11073    (clobber (reg:CC FLAGS_REG))]
11074   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11075                      ? epilogue_completed : reload_completed)"
11076   [(const_int 0)]
11077   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11079 (define_insn "x86_shld_1"
11080   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11081         (ior:SI (ashift:SI (match_dup 0)
11082                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11083                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11084                   (minus:QI (const_int 32) (match_dup 2)))))
11085    (clobber (reg:CC FLAGS_REG))]
11086   ""
11087   "@
11088    shld{l}\t{%2, %1, %0|%0, %1, %2}
11089    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11090   [(set_attr "type" "ishift")
11091    (set_attr "prefix_0f" "1")
11092    (set_attr "mode" "SI")
11093    (set_attr "pent_pair" "np")
11094    (set_attr "athlon_decode" "vector")
11095    (set_attr "amdfam10_decode" "vector")])
11097 (define_expand "x86_shift_adj_1"
11098   [(set (reg:CCZ FLAGS_REG)
11099         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11100                              (const_int 32))
11101                      (const_int 0)))
11102    (set (match_operand:SI 0 "register_operand" "")
11103         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11104                          (match_operand:SI 1 "register_operand" "")
11105                          (match_dup 0)))
11106    (set (match_dup 1)
11107         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11108                          (match_operand:SI 3 "register_operand" "r")
11109                          (match_dup 1)))]
11110   "TARGET_CMOVE"
11111   "")
11113 (define_expand "x86_shift_adj_2"
11114   [(use (match_operand:SI 0 "register_operand" ""))
11115    (use (match_operand:SI 1 "register_operand" ""))
11116    (use (match_operand:QI 2 "register_operand" ""))]
11117   ""
11119   rtx label = gen_label_rtx ();
11120   rtx tmp;
11122   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11124   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11125   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11126   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11127                               gen_rtx_LABEL_REF (VOIDmode, label),
11128                               pc_rtx);
11129   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11130   JUMP_LABEL (tmp) = label;
11132   emit_move_insn (operands[0], operands[1]);
11133   ix86_expand_clear (operands[1]);
11135   emit_label (label);
11136   LABEL_NUSES (label) = 1;
11138   DONE;
11141 (define_expand "ashlsi3"
11142   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11143         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11144                    (match_operand:QI 2 "nonmemory_operand" "")))
11145    (clobber (reg:CC FLAGS_REG))]
11146   ""
11147   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11149 (define_insn "*ashlsi3_1"
11150   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11151         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11152                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11153    (clobber (reg:CC FLAGS_REG))]
11154   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11156   switch (get_attr_type (insn))
11157     {
11158     case TYPE_ALU:
11159       gcc_assert (operands[2] == const1_rtx);
11160       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11161       return "add{l}\t%0, %0";
11163     case TYPE_LEA:
11164       return "#";
11166     default:
11167       if (REG_P (operands[2]))
11168         return "sal{l}\t{%b2, %0|%0, %b2}";
11169       else if (operands[2] == const1_rtx
11170                && (TARGET_SHIFT1 || optimize_size))
11171         return "sal{l}\t%0";
11172       else
11173         return "sal{l}\t{%2, %0|%0, %2}";
11174     }
11176   [(set (attr "type")
11177      (cond [(eq_attr "alternative" "1")
11178               (const_string "lea")
11179             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11180                           (const_int 0))
11181                       (match_operand 0 "register_operand" ""))
11182                  (match_operand 2 "const1_operand" ""))
11183               (const_string "alu")
11184            ]
11185            (const_string "ishift")))
11186    (set_attr "mode" "SI")])
11188 ;; Convert lea to the lea pattern to avoid flags dependency.
11189 (define_split
11190   [(set (match_operand 0 "register_operand" "")
11191         (ashift (match_operand 1 "index_register_operand" "")
11192                 (match_operand:QI 2 "const_int_operand" "")))
11193    (clobber (reg:CC FLAGS_REG))]
11194   "reload_completed
11195    && true_regnum (operands[0]) != true_regnum (operands[1])
11196    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11197   [(const_int 0)]
11199   rtx pat;
11200   enum machine_mode mode = GET_MODE (operands[0]);
11202   if (GET_MODE_SIZE (mode) < 4)
11203     operands[0] = gen_lowpart (SImode, operands[0]);
11204   if (mode != Pmode)
11205     operands[1] = gen_lowpart (Pmode, operands[1]);
11206   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11208   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11209   if (Pmode != SImode)
11210     pat = gen_rtx_SUBREG (SImode, pat, 0);
11211   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11212   DONE;
11215 ;; Rare case of shifting RSP is handled by generating move and shift
11216 (define_split
11217   [(set (match_operand 0 "register_operand" "")
11218         (ashift (match_operand 1 "register_operand" "")
11219                 (match_operand:QI 2 "const_int_operand" "")))
11220    (clobber (reg:CC FLAGS_REG))]
11221   "reload_completed
11222    && true_regnum (operands[0]) != true_regnum (operands[1])"
11223   [(const_int 0)]
11225   rtx pat, clob;
11226   emit_move_insn (operands[0], operands[1]);
11227   pat = gen_rtx_SET (VOIDmode, operands[0],
11228                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11229                                      operands[0], operands[2]));
11230   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11231   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11232   DONE;
11235 (define_insn "*ashlsi3_1_zext"
11236   [(set (match_operand:DI 0 "register_operand" "=r,r")
11237         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11238                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11239    (clobber (reg:CC FLAGS_REG))]
11240   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11242   switch (get_attr_type (insn))
11243     {
11244     case TYPE_ALU:
11245       gcc_assert (operands[2] == const1_rtx);
11246       return "add{l}\t%k0, %k0";
11248     case TYPE_LEA:
11249       return "#";
11251     default:
11252       if (REG_P (operands[2]))
11253         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11254       else if (operands[2] == const1_rtx
11255                && (TARGET_SHIFT1 || optimize_size))
11256         return "sal{l}\t%k0";
11257       else
11258         return "sal{l}\t{%2, %k0|%k0, %2}";
11259     }
11261   [(set (attr "type")
11262      (cond [(eq_attr "alternative" "1")
11263               (const_string "lea")
11264             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11265                      (const_int 0))
11266                  (match_operand 2 "const1_operand" ""))
11267               (const_string "alu")
11268            ]
11269            (const_string "ishift")))
11270    (set_attr "mode" "SI")])
11272 ;; Convert lea to the lea pattern to avoid flags dependency.
11273 (define_split
11274   [(set (match_operand:DI 0 "register_operand" "")
11275         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11276                                 (match_operand:QI 2 "const_int_operand" ""))))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && reload_completed
11279    && true_regnum (operands[0]) != true_regnum (operands[1])"
11280   [(set (match_dup 0) (zero_extend:DI
11281                         (subreg:SI (mult:SI (match_dup 1)
11282                                             (match_dup 2)) 0)))]
11284   operands[1] = gen_lowpart (Pmode, operands[1]);
11285   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11288 ;; This pattern can't accept a variable shift count, since shifts by
11289 ;; zero don't affect the flags.  We assume that shifts by constant
11290 ;; zero are optimized away.
11291 (define_insn "*ashlsi3_cmp"
11292   [(set (reg FLAGS_REG)
11293         (compare
11294           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11295                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11296           (const_int 0)))
11297    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11298         (ashift:SI (match_dup 1) (match_dup 2)))]
11299    "(optimize_size
11300      || !TARGET_PARTIAL_FLAG_REG_STALL
11301      || (operands[2] == const1_rtx
11302          && (TARGET_SHIFT1
11303              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11304    && ix86_match_ccmode (insn, CCGOCmode)
11305    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11307   switch (get_attr_type (insn))
11308     {
11309     case TYPE_ALU:
11310       gcc_assert (operands[2] == const1_rtx);
11311       return "add{l}\t%0, %0";
11313     default:
11314       if (REG_P (operands[2]))
11315         return "sal{l}\t{%b2, %0|%0, %b2}";
11316       else if (operands[2] == const1_rtx
11317                && (TARGET_SHIFT1 || optimize_size))
11318         return "sal{l}\t%0";
11319       else
11320         return "sal{l}\t{%2, %0|%0, %2}";
11321     }
11323   [(set (attr "type")
11324      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11325                           (const_int 0))
11326                       (match_operand 0 "register_operand" ""))
11327                  (match_operand 2 "const1_operand" ""))
11328               (const_string "alu")
11329            ]
11330            (const_string "ishift")))
11331    (set_attr "mode" "SI")])
11333 (define_insn "*ashlsi3_cconly"
11334   [(set (reg FLAGS_REG)
11335         (compare
11336           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11337                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11338           (const_int 0)))
11339    (clobber (match_scratch:SI 0 "=r"))]
11340   "(optimize_size
11341     || !TARGET_PARTIAL_FLAG_REG_STALL
11342     || (operands[2] == const1_rtx
11343         && (TARGET_SHIFT1
11344             || TARGET_DOUBLE_WITH_ADD)))
11345    && ix86_match_ccmode (insn, CCGOCmode)
11346    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11348   switch (get_attr_type (insn))
11349     {
11350     case TYPE_ALU:
11351       gcc_assert (operands[2] == const1_rtx);
11352       return "add{l}\t%0, %0";
11354     default:
11355       if (REG_P (operands[2]))
11356         return "sal{l}\t{%b2, %0|%0, %b2}";
11357       else if (operands[2] == const1_rtx
11358                && (TARGET_SHIFT1 || optimize_size))
11359         return "sal{l}\t%0";
11360       else
11361         return "sal{l}\t{%2, %0|%0, %2}";
11362     }
11364   [(set (attr "type")
11365      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11366                           (const_int 0))
11367                       (match_operand 0 "register_operand" ""))
11368                  (match_operand 2 "const1_operand" ""))
11369               (const_string "alu")
11370            ]
11371            (const_string "ishift")))
11372    (set_attr "mode" "SI")])
11374 (define_insn "*ashlsi3_cmp_zext"
11375   [(set (reg FLAGS_REG)
11376         (compare
11377           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11378                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11379           (const_int 0)))
11380    (set (match_operand:DI 0 "register_operand" "=r")
11381         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11382   "TARGET_64BIT
11383    && (optimize_size
11384        || !TARGET_PARTIAL_FLAG_REG_STALL
11385        || (operands[2] == const1_rtx
11386            && (TARGET_SHIFT1
11387                || TARGET_DOUBLE_WITH_ADD)))
11388    && ix86_match_ccmode (insn, CCGOCmode)
11389    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11391   switch (get_attr_type (insn))
11392     {
11393     case TYPE_ALU:
11394       gcc_assert (operands[2] == const1_rtx);
11395       return "add{l}\t%k0, %k0";
11397     default:
11398       if (REG_P (operands[2]))
11399         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11400       else if (operands[2] == const1_rtx
11401                && (TARGET_SHIFT1 || optimize_size))
11402         return "sal{l}\t%k0";
11403       else
11404         return "sal{l}\t{%2, %k0|%k0, %2}";
11405     }
11407   [(set (attr "type")
11408      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11409                      (const_int 0))
11410                  (match_operand 2 "const1_operand" ""))
11411               (const_string "alu")
11412            ]
11413            (const_string "ishift")))
11414    (set_attr "mode" "SI")])
11416 (define_expand "ashlhi3"
11417   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11418         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11419                    (match_operand:QI 2 "nonmemory_operand" "")))
11420    (clobber (reg:CC FLAGS_REG))]
11421   "TARGET_HIMODE_MATH"
11422   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11424 (define_insn "*ashlhi3_1_lea"
11425   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11426         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11427                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11428    (clobber (reg:CC FLAGS_REG))]
11429   "!TARGET_PARTIAL_REG_STALL
11430    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11432   switch (get_attr_type (insn))
11433     {
11434     case TYPE_LEA:
11435       return "#";
11436     case TYPE_ALU:
11437       gcc_assert (operands[2] == const1_rtx);
11438       return "add{w}\t%0, %0";
11440     default:
11441       if (REG_P (operands[2]))
11442         return "sal{w}\t{%b2, %0|%0, %b2}";
11443       else if (operands[2] == const1_rtx
11444                && (TARGET_SHIFT1 || optimize_size))
11445         return "sal{w}\t%0";
11446       else
11447         return "sal{w}\t{%2, %0|%0, %2}";
11448     }
11450   [(set (attr "type")
11451      (cond [(eq_attr "alternative" "1")
11452               (const_string "lea")
11453             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11454                           (const_int 0))
11455                       (match_operand 0 "register_operand" ""))
11456                  (match_operand 2 "const1_operand" ""))
11457               (const_string "alu")
11458            ]
11459            (const_string "ishift")))
11460    (set_attr "mode" "HI,SI")])
11462 (define_insn "*ashlhi3_1"
11463   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11464         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11465                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11466    (clobber (reg:CC FLAGS_REG))]
11467   "TARGET_PARTIAL_REG_STALL
11468    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11470   switch (get_attr_type (insn))
11471     {
11472     case TYPE_ALU:
11473       gcc_assert (operands[2] == const1_rtx);
11474       return "add{w}\t%0, %0";
11476     default:
11477       if (REG_P (operands[2]))
11478         return "sal{w}\t{%b2, %0|%0, %b2}";
11479       else if (operands[2] == const1_rtx
11480                && (TARGET_SHIFT1 || optimize_size))
11481         return "sal{w}\t%0";
11482       else
11483         return "sal{w}\t{%2, %0|%0, %2}";
11484     }
11486   [(set (attr "type")
11487      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11488                           (const_int 0))
11489                       (match_operand 0 "register_operand" ""))
11490                  (match_operand 2 "const1_operand" ""))
11491               (const_string "alu")
11492            ]
11493            (const_string "ishift")))
11494    (set_attr "mode" "HI")])
11496 ;; This pattern can't accept a variable shift count, since shifts by
11497 ;; zero don't affect the flags.  We assume that shifts by constant
11498 ;; zero are optimized away.
11499 (define_insn "*ashlhi3_cmp"
11500   [(set (reg FLAGS_REG)
11501         (compare
11502           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11503                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11504           (const_int 0)))
11505    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11506         (ashift:HI (match_dup 1) (match_dup 2)))]
11507   "(optimize_size
11508     || !TARGET_PARTIAL_FLAG_REG_STALL
11509     || (operands[2] == const1_rtx
11510         && (TARGET_SHIFT1
11511             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11512    && ix86_match_ccmode (insn, CCGOCmode)
11513    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11515   switch (get_attr_type (insn))
11516     {
11517     case TYPE_ALU:
11518       gcc_assert (operands[2] == const1_rtx);
11519       return "add{w}\t%0, %0";
11521     default:
11522       if (REG_P (operands[2]))
11523         return "sal{w}\t{%b2, %0|%0, %b2}";
11524       else if (operands[2] == const1_rtx
11525                && (TARGET_SHIFT1 || optimize_size))
11526         return "sal{w}\t%0";
11527       else
11528         return "sal{w}\t{%2, %0|%0, %2}";
11529     }
11531   [(set (attr "type")
11532      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11533                           (const_int 0))
11534                       (match_operand 0 "register_operand" ""))
11535                  (match_operand 2 "const1_operand" ""))
11536               (const_string "alu")
11537            ]
11538            (const_string "ishift")))
11539    (set_attr "mode" "HI")])
11541 (define_insn "*ashlhi3_cconly"
11542   [(set (reg FLAGS_REG)
11543         (compare
11544           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11545                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11546           (const_int 0)))
11547    (clobber (match_scratch:HI 0 "=r"))]
11548   "(optimize_size
11549     || !TARGET_PARTIAL_FLAG_REG_STALL
11550     || (operands[2] == const1_rtx
11551         && (TARGET_SHIFT1
11552             || TARGET_DOUBLE_WITH_ADD)))
11553    && ix86_match_ccmode (insn, CCGOCmode)
11554    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11556   switch (get_attr_type (insn))
11557     {
11558     case TYPE_ALU:
11559       gcc_assert (operands[2] == const1_rtx);
11560       return "add{w}\t%0, %0";
11562     default:
11563       if (REG_P (operands[2]))
11564         return "sal{w}\t{%b2, %0|%0, %b2}";
11565       else if (operands[2] == const1_rtx
11566                && (TARGET_SHIFT1 || optimize_size))
11567         return "sal{w}\t%0";
11568       else
11569         return "sal{w}\t{%2, %0|%0, %2}";
11570     }
11572   [(set (attr "type")
11573      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11574                           (const_int 0))
11575                       (match_operand 0 "register_operand" ""))
11576                  (match_operand 2 "const1_operand" ""))
11577               (const_string "alu")
11578            ]
11579            (const_string "ishift")))
11580    (set_attr "mode" "HI")])
11582 (define_expand "ashlqi3"
11583   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11584         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11585                    (match_operand:QI 2 "nonmemory_operand" "")))
11586    (clobber (reg:CC FLAGS_REG))]
11587   "TARGET_QIMODE_MATH"
11588   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11590 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11592 (define_insn "*ashlqi3_1_lea"
11593   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11594         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11595                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11596    (clobber (reg:CC FLAGS_REG))]
11597   "!TARGET_PARTIAL_REG_STALL
11598    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11600   switch (get_attr_type (insn))
11601     {
11602     case TYPE_LEA:
11603       return "#";
11604     case TYPE_ALU:
11605       gcc_assert (operands[2] == const1_rtx);
11606       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11607         return "add{l}\t%k0, %k0";
11608       else
11609         return "add{b}\t%0, %0";
11611     default:
11612       if (REG_P (operands[2]))
11613         {
11614           if (get_attr_mode (insn) == MODE_SI)
11615             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11616           else
11617             return "sal{b}\t{%b2, %0|%0, %b2}";
11618         }
11619       else if (operands[2] == const1_rtx
11620                && (TARGET_SHIFT1 || optimize_size))
11621         {
11622           if (get_attr_mode (insn) == MODE_SI)
11623             return "sal{l}\t%0";
11624           else
11625             return "sal{b}\t%0";
11626         }
11627       else
11628         {
11629           if (get_attr_mode (insn) == MODE_SI)
11630             return "sal{l}\t{%2, %k0|%k0, %2}";
11631           else
11632             return "sal{b}\t{%2, %0|%0, %2}";
11633         }
11634     }
11636   [(set (attr "type")
11637      (cond [(eq_attr "alternative" "2")
11638               (const_string "lea")
11639             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11640                           (const_int 0))
11641                       (match_operand 0 "register_operand" ""))
11642                  (match_operand 2 "const1_operand" ""))
11643               (const_string "alu")
11644            ]
11645            (const_string "ishift")))
11646    (set_attr "mode" "QI,SI,SI")])
11648 (define_insn "*ashlqi3_1"
11649   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11650         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11651                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11652    (clobber (reg:CC FLAGS_REG))]
11653   "TARGET_PARTIAL_REG_STALL
11654    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11656   switch (get_attr_type (insn))
11657     {
11658     case TYPE_ALU:
11659       gcc_assert (operands[2] == const1_rtx);
11660       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11661         return "add{l}\t%k0, %k0";
11662       else
11663         return "add{b}\t%0, %0";
11665     default:
11666       if (REG_P (operands[2]))
11667         {
11668           if (get_attr_mode (insn) == MODE_SI)
11669             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11670           else
11671             return "sal{b}\t{%b2, %0|%0, %b2}";
11672         }
11673       else if (operands[2] == const1_rtx
11674                && (TARGET_SHIFT1 || optimize_size))
11675         {
11676           if (get_attr_mode (insn) == MODE_SI)
11677             return "sal{l}\t%0";
11678           else
11679             return "sal{b}\t%0";
11680         }
11681       else
11682         {
11683           if (get_attr_mode (insn) == MODE_SI)
11684             return "sal{l}\t{%2, %k0|%k0, %2}";
11685           else
11686             return "sal{b}\t{%2, %0|%0, %2}";
11687         }
11688     }
11690   [(set (attr "type")
11691      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11692                           (const_int 0))
11693                       (match_operand 0 "register_operand" ""))
11694                  (match_operand 2 "const1_operand" ""))
11695               (const_string "alu")
11696            ]
11697            (const_string "ishift")))
11698    (set_attr "mode" "QI,SI")])
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags.  We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*ashlqi3_cmp"
11704   [(set (reg FLAGS_REG)
11705         (compare
11706           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11707                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11708           (const_int 0)))
11709    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11710         (ashift:QI (match_dup 1) (match_dup 2)))]
11711   "(optimize_size
11712     || !TARGET_PARTIAL_FLAG_REG_STALL
11713     || (operands[2] == const1_rtx
11714         && (TARGET_SHIFT1
11715             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11716    && ix86_match_ccmode (insn, CCGOCmode)
11717    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11719   switch (get_attr_type (insn))
11720     {
11721     case TYPE_ALU:
11722       gcc_assert (operands[2] == const1_rtx);
11723       return "add{b}\t%0, %0";
11725     default:
11726       if (REG_P (operands[2]))
11727         return "sal{b}\t{%b2, %0|%0, %b2}";
11728       else if (operands[2] == const1_rtx
11729                && (TARGET_SHIFT1 || optimize_size))
11730         return "sal{b}\t%0";
11731       else
11732         return "sal{b}\t{%2, %0|%0, %2}";
11733     }
11735   [(set (attr "type")
11736      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11737                           (const_int 0))
11738                       (match_operand 0 "register_operand" ""))
11739                  (match_operand 2 "const1_operand" ""))
11740               (const_string "alu")
11741            ]
11742            (const_string "ishift")))
11743    (set_attr "mode" "QI")])
11745 (define_insn "*ashlqi3_cconly"
11746   [(set (reg FLAGS_REG)
11747         (compare
11748           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11749                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11750           (const_int 0)))
11751    (clobber (match_scratch:QI 0 "=q"))]
11752   "(optimize_size
11753     || !TARGET_PARTIAL_FLAG_REG_STALL
11754     || (operands[2] == const1_rtx
11755         && (TARGET_SHIFT1
11756             || TARGET_DOUBLE_WITH_ADD)))
11757    && ix86_match_ccmode (insn, CCGOCmode)
11758    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11760   switch (get_attr_type (insn))
11761     {
11762     case TYPE_ALU:
11763       gcc_assert (operands[2] == const1_rtx);
11764       return "add{b}\t%0, %0";
11766     default:
11767       if (REG_P (operands[2]))
11768         return "sal{b}\t{%b2, %0|%0, %b2}";
11769       else if (operands[2] == const1_rtx
11770                && (TARGET_SHIFT1 || optimize_size))
11771         return "sal{b}\t%0";
11772       else
11773         return "sal{b}\t{%2, %0|%0, %2}";
11774     }
11776   [(set (attr "type")
11777      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778                           (const_int 0))
11779                       (match_operand 0 "register_operand" ""))
11780                  (match_operand 2 "const1_operand" ""))
11781               (const_string "alu")
11782            ]
11783            (const_string "ishift")))
11784    (set_attr "mode" "QI")])
11786 ;; See comment above `ashldi3' about how this works.
11788 (define_expand "ashrti3"
11789   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11790                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11791                                 (match_operand:QI 2 "nonmemory_operand" "")))
11792               (clobber (reg:CC FLAGS_REG))])]
11793   "TARGET_64BIT"
11795   if (! immediate_operand (operands[2], QImode))
11796     {
11797       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11798       DONE;
11799     }
11800   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11801   DONE;
11804 (define_insn "ashrti3_1"
11805   [(set (match_operand:TI 0 "register_operand" "=r")
11806         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11807                      (match_operand:QI 2 "register_operand" "c")))
11808    (clobber (match_scratch:DI 3 "=&r"))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "TARGET_64BIT"
11811   "#"
11812   [(set_attr "type" "multi")])
11814 (define_insn "*ashrti3_2"
11815   [(set (match_operand:TI 0 "register_operand" "=r")
11816         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11817                      (match_operand:QI 2 "immediate_operand" "O")))
11818    (clobber (reg:CC FLAGS_REG))]
11819   "TARGET_64BIT"
11820   "#"
11821   [(set_attr "type" "multi")])
11823 (define_split
11824   [(set (match_operand:TI 0 "register_operand" "")
11825         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11826                      (match_operand:QI 2 "register_operand" "")))
11827    (clobber (match_scratch:DI 3 ""))
11828    (clobber (reg:CC FLAGS_REG))]
11829   "TARGET_64BIT && reload_completed"
11830   [(const_int 0)]
11831   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11833 (define_split
11834   [(set (match_operand:TI 0 "register_operand" "")
11835         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11836                      (match_operand:QI 2 "immediate_operand" "")))
11837    (clobber (reg:CC FLAGS_REG))]
11838   "TARGET_64BIT && reload_completed"
11839   [(const_int 0)]
11840   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11842 (define_insn "x86_64_shrd"
11843   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11844         (ior:DI (ashiftrt:DI (match_dup 0)
11845                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11846                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11847                   (minus:QI (const_int 64) (match_dup 2)))))
11848    (clobber (reg:CC FLAGS_REG))]
11849   "TARGET_64BIT"
11850   "@
11851    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11852    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11853   [(set_attr "type" "ishift")
11854    (set_attr "prefix_0f" "1")
11855    (set_attr "mode" "DI")
11856    (set_attr "athlon_decode" "vector")
11857    (set_attr "amdfam10_decode" "vector")])
11859 (define_expand "ashrdi3"
11860   [(set (match_operand:DI 0 "shiftdi_operand" "")
11861         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11862                      (match_operand:QI 2 "nonmemory_operand" "")))]
11863   ""
11864   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11866 (define_insn "*ashrdi3_63_rex64"
11867   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11868         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11869                      (match_operand:DI 2 "const_int_operand" "i,i")))
11870    (clobber (reg:CC FLAGS_REG))]
11871   "TARGET_64BIT && INTVAL (operands[2]) == 63
11872    && (TARGET_USE_CLTD || optimize_size)
11873    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11874   "@
11875    {cqto|cqo}
11876    sar{q}\t{%2, %0|%0, %2}"
11877   [(set_attr "type" "imovx,ishift")
11878    (set_attr "prefix_0f" "0,*")
11879    (set_attr "length_immediate" "0,*")
11880    (set_attr "modrm" "0,1")
11881    (set_attr "mode" "DI")])
11883 (define_insn "*ashrdi3_1_one_bit_rex64"
11884   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11885         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11886                      (match_operand:QI 2 "const1_operand" "")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "TARGET_64BIT
11889    && (TARGET_SHIFT1 || optimize_size)
11890    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11891   "sar{q}\t%0"
11892   [(set_attr "type" "ishift")
11893    (set (attr "length")
11894      (if_then_else (match_operand:DI 0 "register_operand" "")
11895         (const_string "2")
11896         (const_string "*")))])
11898 (define_insn "*ashrdi3_1_rex64"
11899   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11900         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11901                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11902    (clobber (reg:CC FLAGS_REG))]
11903   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11904   "@
11905    sar{q}\t{%2, %0|%0, %2}
11906    sar{q}\t{%b2, %0|%0, %b2}"
11907   [(set_attr "type" "ishift")
11908    (set_attr "mode" "DI")])
11910 ;; This pattern can't accept a variable shift count, since shifts by
11911 ;; zero don't affect the flags.  We assume that shifts by constant
11912 ;; zero are optimized away.
11913 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11914   [(set (reg FLAGS_REG)
11915         (compare
11916           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11917                        (match_operand:QI 2 "const1_operand" ""))
11918           (const_int 0)))
11919    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11920         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11921   "TARGET_64BIT
11922    && (TARGET_SHIFT1 || optimize_size)
11923    && ix86_match_ccmode (insn, CCGOCmode)
11924    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11925   "sar{q}\t%0"
11926   [(set_attr "type" "ishift")
11927    (set (attr "length")
11928      (if_then_else (match_operand:DI 0 "register_operand" "")
11929         (const_string "2")
11930         (const_string "*")))])
11932 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11933   [(set (reg FLAGS_REG)
11934         (compare
11935           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11936                        (match_operand:QI 2 "const1_operand" ""))
11937           (const_int 0)))
11938    (clobber (match_scratch:DI 0 "=r"))]
11939   "TARGET_64BIT
11940    && (TARGET_SHIFT1 || optimize_size)
11941    && ix86_match_ccmode (insn, CCGOCmode)
11942    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11943   "sar{q}\t%0"
11944   [(set_attr "type" "ishift")
11945    (set_attr "length" "2")])
11947 ;; This pattern can't accept a variable shift count, since shifts by
11948 ;; zero don't affect the flags.  We assume that shifts by constant
11949 ;; zero are optimized away.
11950 (define_insn "*ashrdi3_cmp_rex64"
11951   [(set (reg FLAGS_REG)
11952         (compare
11953           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11954                        (match_operand:QI 2 "const_int_operand" "n"))
11955           (const_int 0)))
11956    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11957         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11958   "TARGET_64BIT
11959    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11960    && ix86_match_ccmode (insn, CCGOCmode)
11961    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11962   "sar{q}\t{%2, %0|%0, %2}"
11963   [(set_attr "type" "ishift")
11964    (set_attr "mode" "DI")])
11966 (define_insn "*ashrdi3_cconly_rex64"
11967   [(set (reg FLAGS_REG)
11968         (compare
11969           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11970                        (match_operand:QI 2 "const_int_operand" "n"))
11971           (const_int 0)))
11972    (clobber (match_scratch:DI 0 "=r"))]
11973   "TARGET_64BIT
11974    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11975    && ix86_match_ccmode (insn, CCGOCmode)
11976    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11977   "sar{q}\t{%2, %0|%0, %2}"
11978   [(set_attr "type" "ishift")
11979    (set_attr "mode" "DI")])
11981 (define_insn "*ashrdi3_1"
11982   [(set (match_operand:DI 0 "register_operand" "=r")
11983         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11984                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11985    (clobber (reg:CC FLAGS_REG))]
11986   "!TARGET_64BIT"
11987   "#"
11988   [(set_attr "type" "multi")])
11990 ;; By default we don't ask for a scratch register, because when DImode
11991 ;; values are manipulated, registers are already at a premium.  But if
11992 ;; we have one handy, we won't turn it away.
11993 (define_peephole2
11994   [(match_scratch:SI 3 "r")
11995    (parallel [(set (match_operand:DI 0 "register_operand" "")
11996                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11997                                 (match_operand:QI 2 "nonmemory_operand" "")))
11998               (clobber (reg:CC FLAGS_REG))])
11999    (match_dup 3)]
12000   "!TARGET_64BIT && TARGET_CMOVE"
12001   [(const_int 0)]
12002   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12004 (define_split
12005   [(set (match_operand:DI 0 "register_operand" "")
12006         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12007                      (match_operand:QI 2 "nonmemory_operand" "")))
12008    (clobber (reg:CC FLAGS_REG))]
12009   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12010                      ? epilogue_completed : reload_completed)"
12011   [(const_int 0)]
12012   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12014 (define_insn "x86_shrd_1"
12015   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12016         (ior:SI (ashiftrt:SI (match_dup 0)
12017                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12018                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12019                   (minus:QI (const_int 32) (match_dup 2)))))
12020    (clobber (reg:CC FLAGS_REG))]
12021   ""
12022   "@
12023    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12024    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12025   [(set_attr "type" "ishift")
12026    (set_attr "prefix_0f" "1")
12027    (set_attr "pent_pair" "np")
12028    (set_attr "mode" "SI")])
12030 (define_expand "x86_shift_adj_3"
12031   [(use (match_operand:SI 0 "register_operand" ""))
12032    (use (match_operand:SI 1 "register_operand" ""))
12033    (use (match_operand:QI 2 "register_operand" ""))]
12034   ""
12036   rtx label = gen_label_rtx ();
12037   rtx tmp;
12039   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12041   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12042   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12043   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12044                               gen_rtx_LABEL_REF (VOIDmode, label),
12045                               pc_rtx);
12046   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12047   JUMP_LABEL (tmp) = label;
12049   emit_move_insn (operands[0], operands[1]);
12050   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12052   emit_label (label);
12053   LABEL_NUSES (label) = 1;
12055   DONE;
12058 (define_insn "ashrsi3_31"
12059   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12060         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12061                      (match_operand:SI 2 "const_int_operand" "i,i")))
12062    (clobber (reg:CC FLAGS_REG))]
12063   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12064    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12065   "@
12066    {cltd|cdq}
12067    sar{l}\t{%2, %0|%0, %2}"
12068   [(set_attr "type" "imovx,ishift")
12069    (set_attr "prefix_0f" "0,*")
12070    (set_attr "length_immediate" "0,*")
12071    (set_attr "modrm" "0,1")
12072    (set_attr "mode" "SI")])
12074 (define_insn "*ashrsi3_31_zext"
12075   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12076         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12077                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12080    && INTVAL (operands[2]) == 31
12081    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12082   "@
12083    {cltd|cdq}
12084    sar{l}\t{%2, %k0|%k0, %2}"
12085   [(set_attr "type" "imovx,ishift")
12086    (set_attr "prefix_0f" "0,*")
12087    (set_attr "length_immediate" "0,*")
12088    (set_attr "modrm" "0,1")
12089    (set_attr "mode" "SI")])
12091 (define_expand "ashrsi3"
12092   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12093         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12094                      (match_operand:QI 2 "nonmemory_operand" "")))
12095    (clobber (reg:CC FLAGS_REG))]
12096   ""
12097   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12099 (define_insn "*ashrsi3_1_one_bit"
12100   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12101         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12102                      (match_operand:QI 2 "const1_operand" "")))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "(TARGET_SHIFT1 || optimize_size)
12105    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12106   "sar{l}\t%0"
12107   [(set_attr "type" "ishift")
12108    (set (attr "length")
12109      (if_then_else (match_operand:SI 0 "register_operand" "")
12110         (const_string "2")
12111         (const_string "*")))])
12113 (define_insn "*ashrsi3_1_one_bit_zext"
12114   [(set (match_operand:DI 0 "register_operand" "=r")
12115         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12116                                      (match_operand:QI 2 "const1_operand" ""))))
12117    (clobber (reg:CC FLAGS_REG))]
12118   "TARGET_64BIT
12119    && (TARGET_SHIFT1 || optimize_size)
12120    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12121   "sar{l}\t%k0"
12122   [(set_attr "type" "ishift")
12123    (set_attr "length" "2")])
12125 (define_insn "*ashrsi3_1"
12126   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12127         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12128                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12131   "@
12132    sar{l}\t{%2, %0|%0, %2}
12133    sar{l}\t{%b2, %0|%0, %b2}"
12134   [(set_attr "type" "ishift")
12135    (set_attr "mode" "SI")])
12137 (define_insn "*ashrsi3_1_zext"
12138   [(set (match_operand:DI 0 "register_operand" "=r,r")
12139         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12140                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12141    (clobber (reg:CC FLAGS_REG))]
12142   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12143   "@
12144    sar{l}\t{%2, %k0|%k0, %2}
12145    sar{l}\t{%b2, %k0|%k0, %b2}"
12146   [(set_attr "type" "ishift")
12147    (set_attr "mode" "SI")])
12149 ;; This pattern can't accept a variable shift count, since shifts by
12150 ;; zero don't affect the flags.  We assume that shifts by constant
12151 ;; zero are optimized away.
12152 (define_insn "*ashrsi3_one_bit_cmp"
12153   [(set (reg FLAGS_REG)
12154         (compare
12155           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12156                        (match_operand:QI 2 "const1_operand" ""))
12157           (const_int 0)))
12158    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12159         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12160   "(TARGET_SHIFT1 || optimize_size)
12161    && ix86_match_ccmode (insn, CCGOCmode)
12162    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12163   "sar{l}\t%0"
12164   [(set_attr "type" "ishift")
12165    (set (attr "length")
12166      (if_then_else (match_operand:SI 0 "register_operand" "")
12167         (const_string "2")
12168         (const_string "*")))])
12170 (define_insn "*ashrsi3_one_bit_cconly"
12171   [(set (reg FLAGS_REG)
12172         (compare
12173           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12174                        (match_operand:QI 2 "const1_operand" ""))
12175           (const_int 0)))
12176    (clobber (match_scratch:SI 0 "=r"))]
12177   "(TARGET_SHIFT1 || optimize_size)
12178    && ix86_match_ccmode (insn, CCGOCmode)
12179    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12180   "sar{l}\t%0"
12181   [(set_attr "type" "ishift")
12182    (set_attr "length" "2")])
12184 (define_insn "*ashrsi3_one_bit_cmp_zext"
12185   [(set (reg FLAGS_REG)
12186         (compare
12187           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12188                        (match_operand:QI 2 "const1_operand" ""))
12189           (const_int 0)))
12190    (set (match_operand:DI 0 "register_operand" "=r")
12191         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12192   "TARGET_64BIT
12193    && (TARGET_SHIFT1 || optimize_size)
12194    && ix86_match_ccmode (insn, CCmode)
12195    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12196   "sar{l}\t%k0"
12197   [(set_attr "type" "ishift")
12198    (set_attr "length" "2")])
12200 ;; This pattern can't accept a variable shift count, since shifts by
12201 ;; zero don't affect the flags.  We assume that shifts by constant
12202 ;; zero are optimized away.
12203 (define_insn "*ashrsi3_cmp"
12204   [(set (reg FLAGS_REG)
12205         (compare
12206           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12207                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12208           (const_int 0)))
12209    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12210         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12211   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12212    && ix86_match_ccmode (insn, CCGOCmode)
12213    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12214   "sar{l}\t{%2, %0|%0, %2}"
12215   [(set_attr "type" "ishift")
12216    (set_attr "mode" "SI")])
12218 (define_insn "*ashrsi3_cconly"
12219   [(set (reg FLAGS_REG)
12220         (compare
12221           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12222                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12223           (const_int 0)))
12224    (clobber (match_scratch:SI 0 "=r"))]
12225   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12226    && ix86_match_ccmode (insn, CCGOCmode)
12227    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12228   "sar{l}\t{%2, %0|%0, %2}"
12229   [(set_attr "type" "ishift")
12230    (set_attr "mode" "SI")])
12232 (define_insn "*ashrsi3_cmp_zext"
12233   [(set (reg FLAGS_REG)
12234         (compare
12235           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12236                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12237           (const_int 0)))
12238    (set (match_operand:DI 0 "register_operand" "=r")
12239         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12240   "TARGET_64BIT
12241    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12242    && ix86_match_ccmode (insn, CCGOCmode)
12243    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12244   "sar{l}\t{%2, %k0|%k0, %2}"
12245   [(set_attr "type" "ishift")
12246    (set_attr "mode" "SI")])
12248 (define_expand "ashrhi3"
12249   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12250         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12251                      (match_operand:QI 2 "nonmemory_operand" "")))
12252    (clobber (reg:CC FLAGS_REG))]
12253   "TARGET_HIMODE_MATH"
12254   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12256 (define_insn "*ashrhi3_1_one_bit"
12257   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12258         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12259                      (match_operand:QI 2 "const1_operand" "")))
12260    (clobber (reg:CC FLAGS_REG))]
12261   "(TARGET_SHIFT1 || optimize_size)
12262    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12263   "sar{w}\t%0"
12264   [(set_attr "type" "ishift")
12265    (set (attr "length")
12266      (if_then_else (match_operand 0 "register_operand" "")
12267         (const_string "2")
12268         (const_string "*")))])
12270 (define_insn "*ashrhi3_1"
12271   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12272         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12273                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12274    (clobber (reg:CC FLAGS_REG))]
12275   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12276   "@
12277    sar{w}\t{%2, %0|%0, %2}
12278    sar{w}\t{%b2, %0|%0, %b2}"
12279   [(set_attr "type" "ishift")
12280    (set_attr "mode" "HI")])
12282 ;; This pattern can't accept a variable shift count, since shifts by
12283 ;; zero don't affect the flags.  We assume that shifts by constant
12284 ;; zero are optimized away.
12285 (define_insn "*ashrhi3_one_bit_cmp"
12286   [(set (reg FLAGS_REG)
12287         (compare
12288           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12289                        (match_operand:QI 2 "const1_operand" ""))
12290           (const_int 0)))
12291    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12292         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12293   "(TARGET_SHIFT1 || optimize_size)
12294    && ix86_match_ccmode (insn, CCGOCmode)
12295    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12296   "sar{w}\t%0"
12297   [(set_attr "type" "ishift")
12298    (set (attr "length")
12299      (if_then_else (match_operand 0 "register_operand" "")
12300         (const_string "2")
12301         (const_string "*")))])
12303 (define_insn "*ashrhi3_one_bit_cconly"
12304   [(set (reg FLAGS_REG)
12305         (compare
12306           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12307                        (match_operand:QI 2 "const1_operand" ""))
12308           (const_int 0)))
12309    (clobber (match_scratch:HI 0 "=r"))]
12310   "(TARGET_SHIFT1 || optimize_size)
12311    && ix86_match_ccmode (insn, CCGOCmode)
12312    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12313   "sar{w}\t%0"
12314   [(set_attr "type" "ishift")
12315    (set_attr "length" "2")])
12317 ;; This pattern can't accept a variable shift count, since shifts by
12318 ;; zero don't affect the flags.  We assume that shifts by constant
12319 ;; zero are optimized away.
12320 (define_insn "*ashrhi3_cmp"
12321   [(set (reg FLAGS_REG)
12322         (compare
12323           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12324                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12325           (const_int 0)))
12326    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12327         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12328   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12329    && ix86_match_ccmode (insn, CCGOCmode)
12330    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12331   "sar{w}\t{%2, %0|%0, %2}"
12332   [(set_attr "type" "ishift")
12333    (set_attr "mode" "HI")])
12335 (define_insn "*ashrhi3_cconly"
12336   [(set (reg FLAGS_REG)
12337         (compare
12338           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12339                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12340           (const_int 0)))
12341    (clobber (match_scratch:HI 0 "=r"))]
12342   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12343    && ix86_match_ccmode (insn, CCGOCmode)
12344    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12345   "sar{w}\t{%2, %0|%0, %2}"
12346   [(set_attr "type" "ishift")
12347    (set_attr "mode" "HI")])
12349 (define_expand "ashrqi3"
12350   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12351         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12352                      (match_operand:QI 2 "nonmemory_operand" "")))
12353    (clobber (reg:CC FLAGS_REG))]
12354   "TARGET_QIMODE_MATH"
12355   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12357 (define_insn "*ashrqi3_1_one_bit"
12358   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12359         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12360                      (match_operand:QI 2 "const1_operand" "")))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "(TARGET_SHIFT1 || optimize_size)
12363    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12364   "sar{b}\t%0"
12365   [(set_attr "type" "ishift")
12366    (set (attr "length")
12367      (if_then_else (match_operand 0 "register_operand" "")
12368         (const_string "2")
12369         (const_string "*")))])
12371 (define_insn "*ashrqi3_1_one_bit_slp"
12372   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12373         (ashiftrt:QI (match_dup 0)
12374                      (match_operand:QI 1 "const1_operand" "")))
12375    (clobber (reg:CC FLAGS_REG))]
12376   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12377    && (TARGET_SHIFT1 || optimize_size)
12378    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12379   "sar{b}\t%0"
12380   [(set_attr "type" "ishift1")
12381    (set (attr "length")
12382      (if_then_else (match_operand 0 "register_operand" "")
12383         (const_string "2")
12384         (const_string "*")))])
12386 (define_insn "*ashrqi3_1"
12387   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12388         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12389                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12390    (clobber (reg:CC FLAGS_REG))]
12391   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12392   "@
12393    sar{b}\t{%2, %0|%0, %2}
12394    sar{b}\t{%b2, %0|%0, %b2}"
12395   [(set_attr "type" "ishift")
12396    (set_attr "mode" "QI")])
12398 (define_insn "*ashrqi3_1_slp"
12399   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12400         (ashiftrt:QI (match_dup 0)
12401                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12402    (clobber (reg:CC FLAGS_REG))]
12403   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12404    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12405   "@
12406    sar{b}\t{%1, %0|%0, %1}
12407    sar{b}\t{%b1, %0|%0, %b1}"
12408   [(set_attr "type" "ishift1")
12409    (set_attr "mode" "QI")])
12411 ;; This pattern can't accept a variable shift count, since shifts by
12412 ;; zero don't affect the flags.  We assume that shifts by constant
12413 ;; zero are optimized away.
12414 (define_insn "*ashrqi3_one_bit_cmp"
12415   [(set (reg FLAGS_REG)
12416         (compare
12417           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12418                        (match_operand:QI 2 "const1_operand" "I"))
12419           (const_int 0)))
12420    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12421         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12422   "(TARGET_SHIFT1 || optimize_size)
12423    && ix86_match_ccmode (insn, CCGOCmode)
12424    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12425   "sar{b}\t%0"
12426   [(set_attr "type" "ishift")
12427    (set (attr "length")
12428      (if_then_else (match_operand 0 "register_operand" "")
12429         (const_string "2")
12430         (const_string "*")))])
12432 (define_insn "*ashrqi3_one_bit_cconly"
12433   [(set (reg FLAGS_REG)
12434         (compare
12435           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12436                        (match_operand:QI 2 "const1_operand" "I"))
12437           (const_int 0)))
12438    (clobber (match_scratch:QI 0 "=q"))]
12439   "(TARGET_SHIFT1 || optimize_size)
12440    && ix86_match_ccmode (insn, CCGOCmode)
12441    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12442   "sar{b}\t%0"
12443   [(set_attr "type" "ishift")
12444    (set_attr "length" "2")])
12446 ;; This pattern can't accept a variable shift count, since shifts by
12447 ;; zero don't affect the flags.  We assume that shifts by constant
12448 ;; zero are optimized away.
12449 (define_insn "*ashrqi3_cmp"
12450   [(set (reg FLAGS_REG)
12451         (compare
12452           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12453                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12454           (const_int 0)))
12455    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12456         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12457   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12458    && ix86_match_ccmode (insn, CCGOCmode)
12459    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12460   "sar{b}\t{%2, %0|%0, %2}"
12461   [(set_attr "type" "ishift")
12462    (set_attr "mode" "QI")])
12464 (define_insn "*ashrqi3_cconly"
12465   [(set (reg FLAGS_REG)
12466         (compare
12467           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12468                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12469           (const_int 0)))
12470    (clobber (match_scratch:QI 0 "=q"))]
12471   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12472    && ix86_match_ccmode (insn, CCGOCmode)
12473    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12474   "sar{b}\t{%2, %0|%0, %2}"
12475   [(set_attr "type" "ishift")
12476    (set_attr "mode" "QI")])
12479 ;; Logical shift instructions
12481 ;; See comment above `ashldi3' about how this works.
12483 (define_expand "lshrti3"
12484   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12485                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12486                                 (match_operand:QI 2 "nonmemory_operand" "")))
12487               (clobber (reg:CC FLAGS_REG))])]
12488   "TARGET_64BIT"
12490   if (! immediate_operand (operands[2], QImode))
12491     {
12492       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12493       DONE;
12494     }
12495   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12496   DONE;
12499 (define_insn "lshrti3_1"
12500   [(set (match_operand:TI 0 "register_operand" "=r")
12501         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12502                      (match_operand:QI 2 "register_operand" "c")))
12503    (clobber (match_scratch:DI 3 "=&r"))
12504    (clobber (reg:CC FLAGS_REG))]
12505   "TARGET_64BIT"
12506   "#"
12507   [(set_attr "type" "multi")])
12509 ;; This pattern must be defined before *lshrti3_2 to prevent
12510 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12512 (define_insn "sse2_lshrti3"
12513   [(set (match_operand:TI 0 "register_operand" "=x")
12514         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12515                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12516   "TARGET_SSE2"
12518   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12519   return "psrldq\t{%2, %0|%0, %2}";
12521   [(set_attr "type" "sseishft")
12522    (set_attr "prefix_data16" "1")
12523    (set_attr "mode" "TI")])
12525 (define_insn "*lshrti3_2"
12526   [(set (match_operand:TI 0 "register_operand" "=r")
12527         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12528                      (match_operand:QI 2 "immediate_operand" "O")))
12529    (clobber (reg:CC FLAGS_REG))]
12530   "TARGET_64BIT"
12531   "#"
12532   [(set_attr "type" "multi")])
12534 (define_split
12535   [(set (match_operand:TI 0 "register_operand" "")
12536         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12537                      (match_operand:QI 2 "register_operand" "")))
12538    (clobber (match_scratch:DI 3 ""))
12539    (clobber (reg:CC FLAGS_REG))]
12540   "TARGET_64BIT && reload_completed"
12541   [(const_int 0)]
12542   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12544 (define_split
12545   [(set (match_operand:TI 0 "register_operand" "")
12546         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12547                      (match_operand:QI 2 "immediate_operand" "")))
12548    (clobber (reg:CC FLAGS_REG))]
12549   "TARGET_64BIT && reload_completed"
12550   [(const_int 0)]
12551   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12553 (define_expand "lshrdi3"
12554   [(set (match_operand:DI 0 "shiftdi_operand" "")
12555         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12556                      (match_operand:QI 2 "nonmemory_operand" "")))]
12557   ""
12558   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12560 (define_insn "*lshrdi3_1_one_bit_rex64"
12561   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12562         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12563                      (match_operand:QI 2 "const1_operand" "")))
12564    (clobber (reg:CC FLAGS_REG))]
12565   "TARGET_64BIT
12566    && (TARGET_SHIFT1 || optimize_size)
12567    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12568   "shr{q}\t%0"
12569   [(set_attr "type" "ishift")
12570    (set (attr "length")
12571      (if_then_else (match_operand:DI 0 "register_operand" "")
12572         (const_string "2")
12573         (const_string "*")))])
12575 (define_insn "*lshrdi3_1_rex64"
12576   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12577         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12578                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12579    (clobber (reg:CC FLAGS_REG))]
12580   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12581   "@
12582    shr{q}\t{%2, %0|%0, %2}
12583    shr{q}\t{%b2, %0|%0, %b2}"
12584   [(set_attr "type" "ishift")
12585    (set_attr "mode" "DI")])
12587 ;; This pattern can't accept a variable shift count, since shifts by
12588 ;; zero don't affect the flags.  We assume that shifts by constant
12589 ;; zero are optimized away.
12590 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12591   [(set (reg FLAGS_REG)
12592         (compare
12593           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12594                        (match_operand:QI 2 "const1_operand" ""))
12595           (const_int 0)))
12596    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12597         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12598   "TARGET_64BIT
12599    && (TARGET_SHIFT1 || optimize_size)
12600    && ix86_match_ccmode (insn, CCGOCmode)
12601    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12602   "shr{q}\t%0"
12603   [(set_attr "type" "ishift")
12604    (set (attr "length")
12605      (if_then_else (match_operand:DI 0 "register_operand" "")
12606         (const_string "2")
12607         (const_string "*")))])
12609 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12610   [(set (reg FLAGS_REG)
12611         (compare
12612           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12613                        (match_operand:QI 2 "const1_operand" ""))
12614           (const_int 0)))
12615    (clobber (match_scratch:DI 0 "=r"))]
12616   "TARGET_64BIT
12617    && (TARGET_SHIFT1 || optimize_size)
12618    && ix86_match_ccmode (insn, CCGOCmode)
12619    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12620   "shr{q}\t%0"
12621   [(set_attr "type" "ishift")
12622    (set_attr "length" "2")])
12624 ;; This pattern can't accept a variable shift count, since shifts by
12625 ;; zero don't affect the flags.  We assume that shifts by constant
12626 ;; zero are optimized away.
12627 (define_insn "*lshrdi3_cmp_rex64"
12628   [(set (reg FLAGS_REG)
12629         (compare
12630           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12631                        (match_operand:QI 2 "const_int_operand" "e"))
12632           (const_int 0)))
12633    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12634         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12635   "TARGET_64BIT
12636    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12637    && ix86_match_ccmode (insn, CCGOCmode)
12638    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12639   "shr{q}\t{%2, %0|%0, %2}"
12640   [(set_attr "type" "ishift")
12641    (set_attr "mode" "DI")])
12643 (define_insn "*lshrdi3_cconly_rex64"
12644   [(set (reg FLAGS_REG)
12645         (compare
12646           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12647                        (match_operand:QI 2 "const_int_operand" "e"))
12648           (const_int 0)))
12649    (clobber (match_scratch:DI 0 "=r"))]
12650   "TARGET_64BIT
12651    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12652    && ix86_match_ccmode (insn, CCGOCmode)
12653    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12654   "shr{q}\t{%2, %0|%0, %2}"
12655   [(set_attr "type" "ishift")
12656    (set_attr "mode" "DI")])
12658 (define_insn "*lshrdi3_1"
12659   [(set (match_operand:DI 0 "register_operand" "=r")
12660         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12661                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12662    (clobber (reg:CC FLAGS_REG))]
12663   "!TARGET_64BIT"
12664   "#"
12665   [(set_attr "type" "multi")])
12667 ;; By default we don't ask for a scratch register, because when DImode
12668 ;; values are manipulated, registers are already at a premium.  But if
12669 ;; we have one handy, we won't turn it away.
12670 (define_peephole2
12671   [(match_scratch:SI 3 "r")
12672    (parallel [(set (match_operand:DI 0 "register_operand" "")
12673                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12674                                 (match_operand:QI 2 "nonmemory_operand" "")))
12675               (clobber (reg:CC FLAGS_REG))])
12676    (match_dup 3)]
12677   "!TARGET_64BIT && TARGET_CMOVE"
12678   [(const_int 0)]
12679   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12681 (define_split
12682   [(set (match_operand:DI 0 "register_operand" "")
12683         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12684                      (match_operand:QI 2 "nonmemory_operand" "")))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12687                      ? epilogue_completed : reload_completed)"
12688   [(const_int 0)]
12689   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12691 (define_expand "lshrsi3"
12692   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12693         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12694                      (match_operand:QI 2 "nonmemory_operand" "")))
12695    (clobber (reg:CC FLAGS_REG))]
12696   ""
12697   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12699 (define_insn "*lshrsi3_1_one_bit"
12700   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12701         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12702                      (match_operand:QI 2 "const1_operand" "")))
12703    (clobber (reg:CC FLAGS_REG))]
12704   "(TARGET_SHIFT1 || optimize_size)
12705    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12706   "shr{l}\t%0"
12707   [(set_attr "type" "ishift")
12708    (set (attr "length")
12709      (if_then_else (match_operand:SI 0 "register_operand" "")
12710         (const_string "2")
12711         (const_string "*")))])
12713 (define_insn "*lshrsi3_1_one_bit_zext"
12714   [(set (match_operand:DI 0 "register_operand" "=r")
12715         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12716                      (match_operand:QI 2 "const1_operand" "")))
12717    (clobber (reg:CC FLAGS_REG))]
12718   "TARGET_64BIT
12719    && (TARGET_SHIFT1 || optimize_size)
12720    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12721   "shr{l}\t%k0"
12722   [(set_attr "type" "ishift")
12723    (set_attr "length" "2")])
12725 (define_insn "*lshrsi3_1"
12726   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12727         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12728                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12729    (clobber (reg:CC FLAGS_REG))]
12730   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12731   "@
12732    shr{l}\t{%2, %0|%0, %2}
12733    shr{l}\t{%b2, %0|%0, %b2}"
12734   [(set_attr "type" "ishift")
12735    (set_attr "mode" "SI")])
12737 (define_insn "*lshrsi3_1_zext"
12738   [(set (match_operand:DI 0 "register_operand" "=r,r")
12739         (zero_extend:DI
12740           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12741                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12742    (clobber (reg:CC FLAGS_REG))]
12743   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12744   "@
12745    shr{l}\t{%2, %k0|%k0, %2}
12746    shr{l}\t{%b2, %k0|%k0, %b2}"
12747   [(set_attr "type" "ishift")
12748    (set_attr "mode" "SI")])
12750 ;; This pattern can't accept a variable shift count, since shifts by
12751 ;; zero don't affect the flags.  We assume that shifts by constant
12752 ;; zero are optimized away.
12753 (define_insn "*lshrsi3_one_bit_cmp"
12754   [(set (reg FLAGS_REG)
12755         (compare
12756           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12757                        (match_operand:QI 2 "const1_operand" ""))
12758           (const_int 0)))
12759    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12760         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12761   "(TARGET_SHIFT1 || optimize_size)
12762    && ix86_match_ccmode (insn, CCGOCmode)
12763    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12764   "shr{l}\t%0"
12765   [(set_attr "type" "ishift")
12766    (set (attr "length")
12767      (if_then_else (match_operand:SI 0 "register_operand" "")
12768         (const_string "2")
12769         (const_string "*")))])
12771 (define_insn "*lshrsi3_one_bit_cconly"
12772   [(set (reg FLAGS_REG)
12773         (compare
12774           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12775                        (match_operand:QI 2 "const1_operand" ""))
12776           (const_int 0)))
12777    (clobber (match_scratch:SI 0 "=r"))]
12778   "(TARGET_SHIFT1 || optimize_size)
12779    && ix86_match_ccmode (insn, CCGOCmode)
12780    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781   "shr{l}\t%0"
12782   [(set_attr "type" "ishift")
12783    (set_attr "length" "2")])
12785 (define_insn "*lshrsi3_cmp_one_bit_zext"
12786   [(set (reg FLAGS_REG)
12787         (compare
12788           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12789                        (match_operand:QI 2 "const1_operand" ""))
12790           (const_int 0)))
12791    (set (match_operand:DI 0 "register_operand" "=r")
12792         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12793   "TARGET_64BIT
12794    && (TARGET_SHIFT1 || optimize_size)
12795    && ix86_match_ccmode (insn, CCGOCmode)
12796    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12797   "shr{l}\t%k0"
12798   [(set_attr "type" "ishift")
12799    (set_attr "length" "2")])
12801 ;; This pattern can't accept a variable shift count, since shifts by
12802 ;; zero don't affect the flags.  We assume that shifts by constant
12803 ;; zero are optimized away.
12804 (define_insn "*lshrsi3_cmp"
12805   [(set (reg FLAGS_REG)
12806         (compare
12807           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12808                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12809           (const_int 0)))
12810    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12811         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12812   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12813    && ix86_match_ccmode (insn, CCGOCmode)
12814    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12815   "shr{l}\t{%2, %0|%0, %2}"
12816   [(set_attr "type" "ishift")
12817    (set_attr "mode" "SI")])
12819 (define_insn "*lshrsi3_cconly"
12820   [(set (reg FLAGS_REG)
12821       (compare
12822         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12823                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12824         (const_int 0)))
12825    (clobber (match_scratch:SI 0 "=r"))]
12826   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12827    && ix86_match_ccmode (insn, CCGOCmode)
12828    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12829   "shr{l}\t{%2, %0|%0, %2}"
12830   [(set_attr "type" "ishift")
12831    (set_attr "mode" "SI")])
12833 (define_insn "*lshrsi3_cmp_zext"
12834   [(set (reg FLAGS_REG)
12835         (compare
12836           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12837                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12838           (const_int 0)))
12839    (set (match_operand:DI 0 "register_operand" "=r")
12840         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12841   "TARGET_64BIT
12842    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12843    && ix86_match_ccmode (insn, CCGOCmode)
12844    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12845   "shr{l}\t{%2, %k0|%k0, %2}"
12846   [(set_attr "type" "ishift")
12847    (set_attr "mode" "SI")])
12849 (define_expand "lshrhi3"
12850   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12851         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12852                      (match_operand:QI 2 "nonmemory_operand" "")))
12853    (clobber (reg:CC FLAGS_REG))]
12854   "TARGET_HIMODE_MATH"
12855   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12857 (define_insn "*lshrhi3_1_one_bit"
12858   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12859         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12860                      (match_operand:QI 2 "const1_operand" "")))
12861    (clobber (reg:CC FLAGS_REG))]
12862   "(TARGET_SHIFT1 || optimize_size)
12863    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12864   "shr{w}\t%0"
12865   [(set_attr "type" "ishift")
12866    (set (attr "length")
12867      (if_then_else (match_operand 0 "register_operand" "")
12868         (const_string "2")
12869         (const_string "*")))])
12871 (define_insn "*lshrhi3_1"
12872   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12873         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12874                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12875    (clobber (reg:CC FLAGS_REG))]
12876   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12877   "@
12878    shr{w}\t{%2, %0|%0, %2}
12879    shr{w}\t{%b2, %0|%0, %b2}"
12880   [(set_attr "type" "ishift")
12881    (set_attr "mode" "HI")])
12883 ;; This pattern can't accept a variable shift count, since shifts by
12884 ;; zero don't affect the flags.  We assume that shifts by constant
12885 ;; zero are optimized away.
12886 (define_insn "*lshrhi3_one_bit_cmp"
12887   [(set (reg FLAGS_REG)
12888         (compare
12889           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12890                        (match_operand:QI 2 "const1_operand" ""))
12891           (const_int 0)))
12892    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12894   "(TARGET_SHIFT1 || optimize_size)
12895    && ix86_match_ccmode (insn, CCGOCmode)
12896    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897   "shr{w}\t%0"
12898   [(set_attr "type" "ishift")
12899    (set (attr "length")
12900      (if_then_else (match_operand:SI 0 "register_operand" "")
12901         (const_string "2")
12902         (const_string "*")))])
12904 (define_insn "*lshrhi3_one_bit_cconly"
12905   [(set (reg FLAGS_REG)
12906         (compare
12907           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12908                        (match_operand:QI 2 "const1_operand" ""))
12909           (const_int 0)))
12910    (clobber (match_scratch:HI 0 "=r"))]
12911   "(TARGET_SHIFT1 || optimize_size)
12912    && ix86_match_ccmode (insn, CCGOCmode)
12913    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12914   "shr{w}\t%0"
12915   [(set_attr "type" "ishift")
12916    (set_attr "length" "2")])
12918 ;; This pattern can't accept a variable shift count, since shifts by
12919 ;; zero don't affect the flags.  We assume that shifts by constant
12920 ;; zero are optimized away.
12921 (define_insn "*lshrhi3_cmp"
12922   [(set (reg FLAGS_REG)
12923         (compare
12924           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12925                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12926           (const_int 0)))
12927    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12928         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12929   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12930    && ix86_match_ccmode (insn, CCGOCmode)
12931    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12932   "shr{w}\t{%2, %0|%0, %2}"
12933   [(set_attr "type" "ishift")
12934    (set_attr "mode" "HI")])
12936 (define_insn "*lshrhi3_cconly"
12937   [(set (reg FLAGS_REG)
12938         (compare
12939           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12940                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12941           (const_int 0)))
12942    (clobber (match_scratch:HI 0 "=r"))]
12943   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12944    && ix86_match_ccmode (insn, CCGOCmode)
12945    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12946   "shr{w}\t{%2, %0|%0, %2}"
12947   [(set_attr "type" "ishift")
12948    (set_attr "mode" "HI")])
12950 (define_expand "lshrqi3"
12951   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12952         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12953                      (match_operand:QI 2 "nonmemory_operand" "")))
12954    (clobber (reg:CC FLAGS_REG))]
12955   "TARGET_QIMODE_MATH"
12956   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12958 (define_insn "*lshrqi3_1_one_bit"
12959   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12960         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12961                      (match_operand:QI 2 "const1_operand" "")))
12962    (clobber (reg:CC FLAGS_REG))]
12963   "(TARGET_SHIFT1 || optimize_size)
12964    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12965   "shr{b}\t%0"
12966   [(set_attr "type" "ishift")
12967    (set (attr "length")
12968      (if_then_else (match_operand 0 "register_operand" "")
12969         (const_string "2")
12970         (const_string "*")))])
12972 (define_insn "*lshrqi3_1_one_bit_slp"
12973   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12974         (lshiftrt:QI (match_dup 0)
12975                      (match_operand:QI 1 "const1_operand" "")))
12976    (clobber (reg:CC FLAGS_REG))]
12977   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12978    && (TARGET_SHIFT1 || optimize_size)"
12979   "shr{b}\t%0"
12980   [(set_attr "type" "ishift1")
12981    (set (attr "length")
12982      (if_then_else (match_operand 0 "register_operand" "")
12983         (const_string "2")
12984         (const_string "*")))])
12986 (define_insn "*lshrqi3_1"
12987   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12988         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12989                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12990    (clobber (reg:CC FLAGS_REG))]
12991   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12992   "@
12993    shr{b}\t{%2, %0|%0, %2}
12994    shr{b}\t{%b2, %0|%0, %b2}"
12995   [(set_attr "type" "ishift")
12996    (set_attr "mode" "QI")])
12998 (define_insn "*lshrqi3_1_slp"
12999   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13000         (lshiftrt:QI (match_dup 0)
13001                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13002    (clobber (reg:CC FLAGS_REG))]
13003   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13004    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13005   "@
13006    shr{b}\t{%1, %0|%0, %1}
13007    shr{b}\t{%b1, %0|%0, %b1}"
13008   [(set_attr "type" "ishift1")
13009    (set_attr "mode" "QI")])
13011 ;; This pattern can't accept a variable shift count, since shifts by
13012 ;; zero don't affect the flags.  We assume that shifts by constant
13013 ;; zero are optimized away.
13014 (define_insn "*lshrqi2_one_bit_cmp"
13015   [(set (reg FLAGS_REG)
13016         (compare
13017           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13018                        (match_operand:QI 2 "const1_operand" ""))
13019           (const_int 0)))
13020    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13021         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13022   "(TARGET_SHIFT1 || optimize_size)
13023    && ix86_match_ccmode (insn, CCGOCmode)
13024    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13025   "shr{b}\t%0"
13026   [(set_attr "type" "ishift")
13027    (set (attr "length")
13028      (if_then_else (match_operand:SI 0 "register_operand" "")
13029         (const_string "2")
13030         (const_string "*")))])
13032 (define_insn "*lshrqi2_one_bit_cconly"
13033   [(set (reg FLAGS_REG)
13034         (compare
13035           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13036                        (match_operand:QI 2 "const1_operand" ""))
13037           (const_int 0)))
13038    (clobber (match_scratch:QI 0 "=q"))]
13039   "(TARGET_SHIFT1 || optimize_size)
13040    && ix86_match_ccmode (insn, CCGOCmode)
13041    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13042   "shr{b}\t%0"
13043   [(set_attr "type" "ishift")
13044    (set_attr "length" "2")])
13046 ;; This pattern can't accept a variable shift count, since shifts by
13047 ;; zero don't affect the flags.  We assume that shifts by constant
13048 ;; zero are optimized away.
13049 (define_insn "*lshrqi2_cmp"
13050   [(set (reg FLAGS_REG)
13051         (compare
13052           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13053                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13054           (const_int 0)))
13055    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13056         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13057   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13058    && ix86_match_ccmode (insn, CCGOCmode)
13059    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13060   "shr{b}\t{%2, %0|%0, %2}"
13061   [(set_attr "type" "ishift")
13062    (set_attr "mode" "QI")])
13064 (define_insn "*lshrqi2_cconly"
13065   [(set (reg FLAGS_REG)
13066         (compare
13067           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13068                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13069           (const_int 0)))
13070    (clobber (match_scratch:QI 0 "=q"))]
13071   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13072    && ix86_match_ccmode (insn, CCGOCmode)
13073    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13074   "shr{b}\t{%2, %0|%0, %2}"
13075   [(set_attr "type" "ishift")
13076    (set_attr "mode" "QI")])
13078 ;; Rotate instructions
13080 (define_expand "rotldi3"
13081   [(set (match_operand:DI 0 "shiftdi_operand" "")
13082         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13083                    (match_operand:QI 2 "nonmemory_operand" "")))
13084    (clobber (reg:CC FLAGS_REG))]
13085  ""
13087   if (TARGET_64BIT)
13088     {
13089       ix86_expand_binary_operator (ROTATE, DImode, operands);
13090       DONE;
13091     }
13092   if (!const_1_to_31_operand (operands[2], VOIDmode))
13093     FAIL;
13094   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13095   DONE;
13098 ;; Implement rotation using two double-precision shift instructions
13099 ;; and a scratch register.
13100 (define_insn_and_split "ix86_rotldi3"
13101  [(set (match_operand:DI 0 "register_operand" "=r")
13102        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13103                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13104   (clobber (reg:CC FLAGS_REG))
13105   (clobber (match_scratch:SI 3 "=&r"))]
13106  "!TARGET_64BIT"
13107  ""
13108  "&& reload_completed"
13109  [(set (match_dup 3) (match_dup 4))
13110   (parallel
13111    [(set (match_dup 4)
13112          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13113                  (lshiftrt:SI (match_dup 5)
13114                               (minus:QI (const_int 32) (match_dup 2)))))
13115     (clobber (reg:CC FLAGS_REG))])
13116   (parallel
13117    [(set (match_dup 5)
13118          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13119                  (lshiftrt:SI (match_dup 3)
13120                               (minus:QI (const_int 32) (match_dup 2)))))
13121     (clobber (reg:CC FLAGS_REG))])]
13122  "split_di (operands, 1, operands + 4, operands + 5);")
13124 (define_insn "*rotlsi3_1_one_bit_rex64"
13125   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13126         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13127                    (match_operand:QI 2 "const1_operand" "")))
13128    (clobber (reg:CC FLAGS_REG))]
13129   "TARGET_64BIT
13130    && (TARGET_SHIFT1 || optimize_size)
13131    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13132   "rol{q}\t%0"
13133   [(set_attr "type" "rotate")
13134    (set (attr "length")
13135      (if_then_else (match_operand:DI 0 "register_operand" "")
13136         (const_string "2")
13137         (const_string "*")))])
13139 (define_insn "*rotldi3_1_rex64"
13140   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13141         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13142                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13143    (clobber (reg:CC FLAGS_REG))]
13144   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13145   "@
13146    rol{q}\t{%2, %0|%0, %2}
13147    rol{q}\t{%b2, %0|%0, %b2}"
13148   [(set_attr "type" "rotate")
13149    (set_attr "mode" "DI")])
13151 (define_expand "rotlsi3"
13152   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13153         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13154                    (match_operand:QI 2 "nonmemory_operand" "")))
13155    (clobber (reg:CC FLAGS_REG))]
13156   ""
13157   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13159 (define_insn "*rotlsi3_1_one_bit"
13160   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13161         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13162                    (match_operand:QI 2 "const1_operand" "")))
13163    (clobber (reg:CC FLAGS_REG))]
13164   "(TARGET_SHIFT1 || optimize_size)
13165    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13166   "rol{l}\t%0"
13167   [(set_attr "type" "rotate")
13168    (set (attr "length")
13169      (if_then_else (match_operand:SI 0 "register_operand" "")
13170         (const_string "2")
13171         (const_string "*")))])
13173 (define_insn "*rotlsi3_1_one_bit_zext"
13174   [(set (match_operand:DI 0 "register_operand" "=r")
13175         (zero_extend:DI
13176           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13177                      (match_operand:QI 2 "const1_operand" ""))))
13178    (clobber (reg:CC FLAGS_REG))]
13179   "TARGET_64BIT
13180    && (TARGET_SHIFT1 || optimize_size)
13181    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13182   "rol{l}\t%k0"
13183   [(set_attr "type" "rotate")
13184    (set_attr "length" "2")])
13186 (define_insn "*rotlsi3_1"
13187   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13188         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13189                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13190    (clobber (reg:CC FLAGS_REG))]
13191   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13192   "@
13193    rol{l}\t{%2, %0|%0, %2}
13194    rol{l}\t{%b2, %0|%0, %b2}"
13195   [(set_attr "type" "rotate")
13196    (set_attr "mode" "SI")])
13198 (define_insn "*rotlsi3_1_zext"
13199   [(set (match_operand:DI 0 "register_operand" "=r,r")
13200         (zero_extend:DI
13201           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13202                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13203    (clobber (reg:CC FLAGS_REG))]
13204   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13205   "@
13206    rol{l}\t{%2, %k0|%k0, %2}
13207    rol{l}\t{%b2, %k0|%k0, %b2}"
13208   [(set_attr "type" "rotate")
13209    (set_attr "mode" "SI")])
13211 (define_expand "rotlhi3"
13212   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13213         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13214                    (match_operand:QI 2 "nonmemory_operand" "")))
13215    (clobber (reg:CC FLAGS_REG))]
13216   "TARGET_HIMODE_MATH"
13217   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13219 (define_insn "*rotlhi3_1_one_bit"
13220   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13221         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13222                    (match_operand:QI 2 "const1_operand" "")))
13223    (clobber (reg:CC FLAGS_REG))]
13224   "(TARGET_SHIFT1 || optimize_size)
13225    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13226   "rol{w}\t%0"
13227   [(set_attr "type" "rotate")
13228    (set (attr "length")
13229      (if_then_else (match_operand 0 "register_operand" "")
13230         (const_string "2")
13231         (const_string "*")))])
13233 (define_insn "*rotlhi3_1"
13234   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13235         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13236                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13237    (clobber (reg:CC FLAGS_REG))]
13238   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13239   "@
13240    rol{w}\t{%2, %0|%0, %2}
13241    rol{w}\t{%b2, %0|%0, %b2}"
13242   [(set_attr "type" "rotate")
13243    (set_attr "mode" "HI")])
13245 (define_split
13246  [(set (match_operand:HI 0 "register_operand" "")
13247        (rotate:HI (match_dup 0) (const_int 8)))
13248   (clobber (reg:CC FLAGS_REG))]
13249  "reload_completed"
13250  [(parallel [(set (strict_low_part (match_dup 0))
13251                   (bswap:HI (match_dup 0)))
13252              (clobber (reg:CC FLAGS_REG))])]
13253  "")
13255 (define_expand "rotlqi3"
13256   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13257         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13258                    (match_operand:QI 2 "nonmemory_operand" "")))
13259    (clobber (reg:CC FLAGS_REG))]
13260   "TARGET_QIMODE_MATH"
13261   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13263 (define_insn "*rotlqi3_1_one_bit_slp"
13264   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13265         (rotate:QI (match_dup 0)
13266                    (match_operand:QI 1 "const1_operand" "")))
13267    (clobber (reg:CC FLAGS_REG))]
13268   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13269    && (TARGET_SHIFT1 || optimize_size)"
13270   "rol{b}\t%0"
13271   [(set_attr "type" "rotate1")
13272    (set (attr "length")
13273      (if_then_else (match_operand 0 "register_operand" "")
13274         (const_string "2")
13275         (const_string "*")))])
13277 (define_insn "*rotlqi3_1_one_bit"
13278   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13279         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13280                    (match_operand:QI 2 "const1_operand" "")))
13281    (clobber (reg:CC FLAGS_REG))]
13282   "(TARGET_SHIFT1 || optimize_size)
13283    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13284   "rol{b}\t%0"
13285   [(set_attr "type" "rotate")
13286    (set (attr "length")
13287      (if_then_else (match_operand 0 "register_operand" "")
13288         (const_string "2")
13289         (const_string "*")))])
13291 (define_insn "*rotlqi3_1_slp"
13292   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13293         (rotate:QI (match_dup 0)
13294                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13295    (clobber (reg:CC FLAGS_REG))]
13296   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13297    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13298   "@
13299    rol{b}\t{%1, %0|%0, %1}
13300    rol{b}\t{%b1, %0|%0, %b1}"
13301   [(set_attr "type" "rotate1")
13302    (set_attr "mode" "QI")])
13304 (define_insn "*rotlqi3_1"
13305   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13306         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13307                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13308    (clobber (reg:CC FLAGS_REG))]
13309   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13310   "@
13311    rol{b}\t{%2, %0|%0, %2}
13312    rol{b}\t{%b2, %0|%0, %b2}"
13313   [(set_attr "type" "rotate")
13314    (set_attr "mode" "QI")])
13316 (define_expand "rotrdi3"
13317   [(set (match_operand:DI 0 "shiftdi_operand" "")
13318         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13319                    (match_operand:QI 2 "nonmemory_operand" "")))
13320    (clobber (reg:CC FLAGS_REG))]
13321  ""
13323   if (TARGET_64BIT)
13324     {
13325       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13326       DONE;
13327     }
13328   if (!const_1_to_31_operand (operands[2], VOIDmode))
13329     FAIL;
13330   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13331   DONE;
13334 ;; Implement rotation using two double-precision shift instructions
13335 ;; and a scratch register.
13336 (define_insn_and_split "ix86_rotrdi3"
13337  [(set (match_operand:DI 0 "register_operand" "=r")
13338        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13339                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13340   (clobber (reg:CC FLAGS_REG))
13341   (clobber (match_scratch:SI 3 "=&r"))]
13342  "!TARGET_64BIT"
13343  ""
13344  "&& reload_completed"
13345  [(set (match_dup 3) (match_dup 4))
13346   (parallel
13347    [(set (match_dup 4)
13348          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13349                  (ashift:SI (match_dup 5)
13350                             (minus:QI (const_int 32) (match_dup 2)))))
13351     (clobber (reg:CC FLAGS_REG))])
13352   (parallel
13353    [(set (match_dup 5)
13354          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13355                  (ashift:SI (match_dup 3)
13356                             (minus:QI (const_int 32) (match_dup 2)))))
13357     (clobber (reg:CC FLAGS_REG))])]
13358  "split_di (operands, 1, operands + 4, operands + 5);")
13360 (define_insn "*rotrdi3_1_one_bit_rex64"
13361   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13362         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13363                      (match_operand:QI 2 "const1_operand" "")))
13364    (clobber (reg:CC FLAGS_REG))]
13365   "TARGET_64BIT
13366    && (TARGET_SHIFT1 || optimize_size)
13367    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13368   "ror{q}\t%0"
13369   [(set_attr "type" "rotate")
13370    (set (attr "length")
13371      (if_then_else (match_operand:DI 0 "register_operand" "")
13372         (const_string "2")
13373         (const_string "*")))])
13375 (define_insn "*rotrdi3_1_rex64"
13376   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13377         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13378                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13379    (clobber (reg:CC FLAGS_REG))]
13380   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13381   "@
13382    ror{q}\t{%2, %0|%0, %2}
13383    ror{q}\t{%b2, %0|%0, %b2}"
13384   [(set_attr "type" "rotate")
13385    (set_attr "mode" "DI")])
13387 (define_expand "rotrsi3"
13388   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13389         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13390                      (match_operand:QI 2 "nonmemory_operand" "")))
13391    (clobber (reg:CC FLAGS_REG))]
13392   ""
13393   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13395 (define_insn "*rotrsi3_1_one_bit"
13396   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13397         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13398                      (match_operand:QI 2 "const1_operand" "")))
13399    (clobber (reg:CC FLAGS_REG))]
13400   "(TARGET_SHIFT1 || optimize_size)
13401    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13402   "ror{l}\t%0"
13403   [(set_attr "type" "rotate")
13404    (set (attr "length")
13405      (if_then_else (match_operand:SI 0 "register_operand" "")
13406         (const_string "2")
13407         (const_string "*")))])
13409 (define_insn "*rotrsi3_1_one_bit_zext"
13410   [(set (match_operand:DI 0 "register_operand" "=r")
13411         (zero_extend:DI
13412           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13413                        (match_operand:QI 2 "const1_operand" ""))))
13414    (clobber (reg:CC FLAGS_REG))]
13415   "TARGET_64BIT
13416    && (TARGET_SHIFT1 || optimize_size)
13417    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13418   "ror{l}\t%k0"
13419   [(set_attr "type" "rotate")
13420    (set (attr "length")
13421      (if_then_else (match_operand:SI 0 "register_operand" "")
13422         (const_string "2")
13423         (const_string "*")))])
13425 (define_insn "*rotrsi3_1"
13426   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13427         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13428                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13429    (clobber (reg:CC FLAGS_REG))]
13430   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13431   "@
13432    ror{l}\t{%2, %0|%0, %2}
13433    ror{l}\t{%b2, %0|%0, %b2}"
13434   [(set_attr "type" "rotate")
13435    (set_attr "mode" "SI")])
13437 (define_insn "*rotrsi3_1_zext"
13438   [(set (match_operand:DI 0 "register_operand" "=r,r")
13439         (zero_extend:DI
13440           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13441                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13442    (clobber (reg:CC FLAGS_REG))]
13443   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13444   "@
13445    ror{l}\t{%2, %k0|%k0, %2}
13446    ror{l}\t{%b2, %k0|%k0, %b2}"
13447   [(set_attr "type" "rotate")
13448    (set_attr "mode" "SI")])
13450 (define_expand "rotrhi3"
13451   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13452         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13453                      (match_operand:QI 2 "nonmemory_operand" "")))
13454    (clobber (reg:CC FLAGS_REG))]
13455   "TARGET_HIMODE_MATH"
13456   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13458 (define_insn "*rotrhi3_one_bit"
13459   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13460         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13461                      (match_operand:QI 2 "const1_operand" "")))
13462    (clobber (reg:CC FLAGS_REG))]
13463   "(TARGET_SHIFT1 || optimize_size)
13464    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13465   "ror{w}\t%0"
13466   [(set_attr "type" "rotate")
13467    (set (attr "length")
13468      (if_then_else (match_operand 0 "register_operand" "")
13469         (const_string "2")
13470         (const_string "*")))])
13472 (define_insn "*rotrhi3_1"
13473   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13474         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13475                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13476    (clobber (reg:CC FLAGS_REG))]
13477   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13478   "@
13479    ror{w}\t{%2, %0|%0, %2}
13480    ror{w}\t{%b2, %0|%0, %b2}"
13481   [(set_attr "type" "rotate")
13482    (set_attr "mode" "HI")])
13484 (define_split
13485  [(set (match_operand:HI 0 "register_operand" "")
13486        (rotatert:HI (match_dup 0) (const_int 8)))
13487   (clobber (reg:CC FLAGS_REG))]
13488  "reload_completed"
13489  [(parallel [(set (strict_low_part (match_dup 0))
13490                   (bswap:HI (match_dup 0)))
13491              (clobber (reg:CC FLAGS_REG))])]
13492  "")
13494 (define_expand "rotrqi3"
13495   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13496         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13497                      (match_operand:QI 2 "nonmemory_operand" "")))
13498    (clobber (reg:CC FLAGS_REG))]
13499   "TARGET_QIMODE_MATH"
13500   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13502 (define_insn "*rotrqi3_1_one_bit"
13503   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13504         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13505                      (match_operand:QI 2 "const1_operand" "")))
13506    (clobber (reg:CC FLAGS_REG))]
13507   "(TARGET_SHIFT1 || optimize_size)
13508    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13509   "ror{b}\t%0"
13510   [(set_attr "type" "rotate")
13511    (set (attr "length")
13512      (if_then_else (match_operand 0 "register_operand" "")
13513         (const_string "2")
13514         (const_string "*")))])
13516 (define_insn "*rotrqi3_1_one_bit_slp"
13517   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13518         (rotatert:QI (match_dup 0)
13519                      (match_operand:QI 1 "const1_operand" "")))
13520    (clobber (reg:CC FLAGS_REG))]
13521   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13522    && (TARGET_SHIFT1 || optimize_size)"
13523   "ror{b}\t%0"
13524   [(set_attr "type" "rotate1")
13525    (set (attr "length")
13526      (if_then_else (match_operand 0 "register_operand" "")
13527         (const_string "2")
13528         (const_string "*")))])
13530 (define_insn "*rotrqi3_1"
13531   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13532         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13533                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13534    (clobber (reg:CC FLAGS_REG))]
13535   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13536   "@
13537    ror{b}\t{%2, %0|%0, %2}
13538    ror{b}\t{%b2, %0|%0, %b2}"
13539   [(set_attr "type" "rotate")
13540    (set_attr "mode" "QI")])
13542 (define_insn "*rotrqi3_1_slp"
13543   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13544         (rotatert:QI (match_dup 0)
13545                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13546    (clobber (reg:CC FLAGS_REG))]
13547   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13548    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13549   "@
13550    ror{b}\t{%1, %0|%0, %1}
13551    ror{b}\t{%b1, %0|%0, %b1}"
13552   [(set_attr "type" "rotate1")
13553    (set_attr "mode" "QI")])
13555 ;; Bit set / bit test instructions
13557 (define_expand "extv"
13558   [(set (match_operand:SI 0 "register_operand" "")
13559         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13560                          (match_operand:SI 2 "const8_operand" "")
13561                          (match_operand:SI 3 "const8_operand" "")))]
13562   ""
13564   /* Handle extractions from %ah et al.  */
13565   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13566     FAIL;
13568   /* From mips.md: extract_bit_field doesn't verify that our source
13569      matches the predicate, so check it again here.  */
13570   if (! ext_register_operand (operands[1], VOIDmode))
13571     FAIL;
13574 (define_expand "extzv"
13575   [(set (match_operand:SI 0 "register_operand" "")
13576         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13577                          (match_operand:SI 2 "const8_operand" "")
13578                          (match_operand:SI 3 "const8_operand" "")))]
13579   ""
13581   /* Handle extractions from %ah et al.  */
13582   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13583     FAIL;
13585   /* From mips.md: extract_bit_field doesn't verify that our source
13586      matches the predicate, so check it again here.  */
13587   if (! ext_register_operand (operands[1], VOIDmode))
13588     FAIL;
13591 (define_expand "insv"
13592   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13593                       (match_operand 1 "const8_operand" "")
13594                       (match_operand 2 "const8_operand" ""))
13595         (match_operand 3 "register_operand" ""))]
13596   ""
13598   /* Handle insertions to %ah et al.  */
13599   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13600     FAIL;
13602   /* From mips.md: insert_bit_field doesn't verify that our source
13603      matches the predicate, so check it again here.  */
13604   if (! ext_register_operand (operands[0], VOIDmode))
13605     FAIL;
13607   if (TARGET_64BIT)
13608     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13609   else
13610     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13612   DONE;
13615 ;; %%% bts, btr, btc, bt.
13616 ;; In general these instructions are *slow* when applied to memory,
13617 ;; since they enforce atomic operation.  When applied to registers,
13618 ;; it depends on the cpu implementation.  They're never faster than
13619 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13620 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13621 ;; within the instruction itself, so operating on bits in the high
13622 ;; 32-bits of a register becomes easier.
13624 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13625 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13626 ;; negdf respectively, so they can never be disabled entirely.
13628 (define_insn "*btsq"
13629   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13630                          (const_int 1)
13631                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13632         (const_int 1))
13633    (clobber (reg:CC FLAGS_REG))]
13634   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13635   "bts{q} %1,%0"
13636   [(set_attr "type" "alu1")])
13638 (define_insn "*btrq"
13639   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13640                          (const_int 1)
13641                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13642         (const_int 0))
13643    (clobber (reg:CC FLAGS_REG))]
13644   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13645   "btr{q} %1,%0"
13646   [(set_attr "type" "alu1")])
13648 (define_insn "*btcq"
13649   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13650                          (const_int 1)
13651                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13652         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13653    (clobber (reg:CC FLAGS_REG))]
13654   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13655   "btc{q} %1,%0"
13656   [(set_attr "type" "alu1")])
13658 ;; Allow Nocona to avoid these instructions if a register is available.
13660 (define_peephole2
13661   [(match_scratch:DI 2 "r")
13662    (parallel [(set (zero_extract:DI
13663                      (match_operand:DI 0 "register_operand" "")
13664                      (const_int 1)
13665                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13666                    (const_int 1))
13667               (clobber (reg:CC FLAGS_REG))])]
13668   "TARGET_64BIT && !TARGET_USE_BT"
13669   [(const_int 0)]
13671   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13672   rtx op1;
13674   if (HOST_BITS_PER_WIDE_INT >= 64)
13675     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13676   else if (i < HOST_BITS_PER_WIDE_INT)
13677     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13678   else
13679     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13681   op1 = immed_double_const (lo, hi, DImode);
13682   if (i >= 31)
13683     {
13684       emit_move_insn (operands[2], op1);
13685       op1 = operands[2];
13686     }
13688   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13689   DONE;
13692 (define_peephole2
13693   [(match_scratch:DI 2 "r")
13694    (parallel [(set (zero_extract:DI
13695                      (match_operand:DI 0 "register_operand" "")
13696                      (const_int 1)
13697                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13698                    (const_int 0))
13699               (clobber (reg:CC FLAGS_REG))])]
13700   "TARGET_64BIT && !TARGET_USE_BT"
13701   [(const_int 0)]
13703   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13704   rtx op1;
13706   if (HOST_BITS_PER_WIDE_INT >= 64)
13707     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13708   else if (i < HOST_BITS_PER_WIDE_INT)
13709     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13710   else
13711     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13713   op1 = immed_double_const (~lo, ~hi, DImode);
13714   if (i >= 32)
13715     {
13716       emit_move_insn (operands[2], op1);
13717       op1 = operands[2];
13718     }
13720   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13721   DONE;
13724 (define_peephole2
13725   [(match_scratch:DI 2 "r")
13726    (parallel [(set (zero_extract:DI
13727                      (match_operand:DI 0 "register_operand" "")
13728                      (const_int 1)
13729                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13730               (not:DI (zero_extract:DI
13731                         (match_dup 0) (const_int 1) (match_dup 1))))
13732               (clobber (reg:CC FLAGS_REG))])]
13733   "TARGET_64BIT && !TARGET_USE_BT"
13734   [(const_int 0)]
13736   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13737   rtx op1;
13739   if (HOST_BITS_PER_WIDE_INT >= 64)
13740     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13741   else if (i < HOST_BITS_PER_WIDE_INT)
13742     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13743   else
13744     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13746   op1 = immed_double_const (lo, hi, DImode);
13747   if (i >= 31)
13748     {
13749       emit_move_insn (operands[2], op1);
13750       op1 = operands[2];
13751     }
13753   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13754   DONE;
13757 ;; Store-flag instructions.
13759 ;; For all sCOND expanders, also expand the compare or test insn that
13760 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13762 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13763 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13764 ;; way, which can later delete the movzx if only QImode is needed.
13766 (define_expand "seq"
13767   [(set (match_operand:QI 0 "register_operand" "")
13768         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13769   ""
13770   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13772 (define_expand "sne"
13773   [(set (match_operand:QI 0 "register_operand" "")
13774         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13775   ""
13776   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13778 (define_expand "sgt"
13779   [(set (match_operand:QI 0 "register_operand" "")
13780         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13781   ""
13782   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13784 (define_expand "sgtu"
13785   [(set (match_operand:QI 0 "register_operand" "")
13786         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13787   ""
13788   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13790 (define_expand "slt"
13791   [(set (match_operand:QI 0 "register_operand" "")
13792         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13793   ""
13794   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13796 (define_expand "sltu"
13797   [(set (match_operand:QI 0 "register_operand" "")
13798         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13799   ""
13800   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13802 (define_expand "sge"
13803   [(set (match_operand:QI 0 "register_operand" "")
13804         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13805   ""
13806   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13808 (define_expand "sgeu"
13809   [(set (match_operand:QI 0 "register_operand" "")
13810         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13811   ""
13812   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13814 (define_expand "sle"
13815   [(set (match_operand:QI 0 "register_operand" "")
13816         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13817   ""
13818   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13820 (define_expand "sleu"
13821   [(set (match_operand:QI 0 "register_operand" "")
13822         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13823   ""
13824   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13826 (define_expand "sunordered"
13827   [(set (match_operand:QI 0 "register_operand" "")
13828         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13829   "TARGET_80387 || TARGET_SSE"
13830   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13832 (define_expand "sordered"
13833   [(set (match_operand:QI 0 "register_operand" "")
13834         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13835   "TARGET_80387"
13836   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13838 (define_expand "suneq"
13839   [(set (match_operand:QI 0 "register_operand" "")
13840         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13841   "TARGET_80387 || TARGET_SSE"
13842   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13844 (define_expand "sunge"
13845   [(set (match_operand:QI 0 "register_operand" "")
13846         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13847   "TARGET_80387 || TARGET_SSE"
13848   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13850 (define_expand "sungt"
13851   [(set (match_operand:QI 0 "register_operand" "")
13852         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13853   "TARGET_80387 || TARGET_SSE"
13854   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13856 (define_expand "sunle"
13857   [(set (match_operand:QI 0 "register_operand" "")
13858         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13859   "TARGET_80387 || TARGET_SSE"
13860   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13862 (define_expand "sunlt"
13863   [(set (match_operand:QI 0 "register_operand" "")
13864         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13865   "TARGET_80387 || TARGET_SSE"
13866   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13868 (define_expand "sltgt"
13869   [(set (match_operand:QI 0 "register_operand" "")
13870         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13871   "TARGET_80387 || TARGET_SSE"
13872   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13874 (define_insn "*setcc_1"
13875   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13876         (match_operator:QI 1 "ix86_comparison_operator"
13877           [(reg FLAGS_REG) (const_int 0)]))]
13878   ""
13879   "set%C1\t%0"
13880   [(set_attr "type" "setcc")
13881    (set_attr "mode" "QI")])
13883 (define_insn "*setcc_2"
13884   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13885         (match_operator:QI 1 "ix86_comparison_operator"
13886           [(reg FLAGS_REG) (const_int 0)]))]
13887   ""
13888   "set%C1\t%0"
13889   [(set_attr "type" "setcc")
13890    (set_attr "mode" "QI")])
13892 ;; In general it is not safe to assume too much about CCmode registers,
13893 ;; so simplify-rtx stops when it sees a second one.  Under certain
13894 ;; conditions this is safe on x86, so help combine not create
13896 ;;      seta    %al
13897 ;;      testb   %al, %al
13898 ;;      sete    %al
13900 (define_split
13901   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13902         (ne:QI (match_operator 1 "ix86_comparison_operator"
13903                  [(reg FLAGS_REG) (const_int 0)])
13904             (const_int 0)))]
13905   ""
13906   [(set (match_dup 0) (match_dup 1))]
13908   PUT_MODE (operands[1], QImode);
13911 (define_split
13912   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13913         (ne:QI (match_operator 1 "ix86_comparison_operator"
13914                  [(reg FLAGS_REG) (const_int 0)])
13915             (const_int 0)))]
13916   ""
13917   [(set (match_dup 0) (match_dup 1))]
13919   PUT_MODE (operands[1], QImode);
13922 (define_split
13923   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13924         (eq:QI (match_operator 1 "ix86_comparison_operator"
13925                  [(reg FLAGS_REG) (const_int 0)])
13926             (const_int 0)))]
13927   ""
13928   [(set (match_dup 0) (match_dup 1))]
13930   rtx new_op1 = copy_rtx (operands[1]);
13931   operands[1] = new_op1;
13932   PUT_MODE (new_op1, QImode);
13933   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13934                                              GET_MODE (XEXP (new_op1, 0))));
13936   /* Make sure that (a) the CCmode we have for the flags is strong
13937      enough for the reversed compare or (b) we have a valid FP compare.  */
13938   if (! ix86_comparison_operator (new_op1, VOIDmode))
13939     FAIL;
13942 (define_split
13943   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13944         (eq:QI (match_operator 1 "ix86_comparison_operator"
13945                  [(reg FLAGS_REG) (const_int 0)])
13946             (const_int 0)))]
13947   ""
13948   [(set (match_dup 0) (match_dup 1))]
13950   rtx new_op1 = copy_rtx (operands[1]);
13951   operands[1] = new_op1;
13952   PUT_MODE (new_op1, QImode);
13953   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13954                                              GET_MODE (XEXP (new_op1, 0))));
13956   /* Make sure that (a) the CCmode we have for the flags is strong
13957      enough for the reversed compare or (b) we have a valid FP compare.  */
13958   if (! ix86_comparison_operator (new_op1, VOIDmode))
13959     FAIL;
13962 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13963 ;; subsequent logical operations are used to imitate conditional moves.
13964 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13965 ;; it directly.
13967 (define_insn "*sse_setccsf"
13968   [(set (match_operand:SF 0 "register_operand" "=x")
13969         (match_operator:SF 1 "sse_comparison_operator"
13970           [(match_operand:SF 2 "register_operand" "0")
13971            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13972   "TARGET_SSE && !TARGET_SSE5"
13973   "cmp%D1ss\t{%3, %0|%0, %3}"
13974   [(set_attr "type" "ssecmp")
13975    (set_attr "mode" "SF")])
13977 (define_insn "*sse_setccdf"
13978   [(set (match_operand:DF 0 "register_operand" "=x")
13979         (match_operator:DF 1 "sse_comparison_operator"
13980           [(match_operand:DF 2 "register_operand" "0")
13981            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13982   "TARGET_SSE2 && !TARGET_SSE5"
13983   "cmp%D1sd\t{%3, %0|%0, %3}"
13984   [(set_attr "type" "ssecmp")
13985    (set_attr "mode" "DF")])
13987 (define_insn "*sse5_setcc<mode>"
13988   [(set (match_operand:MODEF 0 "register_operand" "=x")
13989         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13990           [(match_operand:MODEF 2 "register_operand" "x")
13991            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13992   "TARGET_SSE5"
13993   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13994   [(set_attr "type" "sse4arg")
13995    (set_attr "mode" "<MODE>")])
13998 ;; Basic conditional jump instructions.
13999 ;; We ignore the overflow flag for signed branch instructions.
14001 ;; For all bCOND expanders, also expand the compare or test insn that
14002 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14004 (define_expand "beq"
14005   [(set (pc)
14006         (if_then_else (match_dup 1)
14007                       (label_ref (match_operand 0 "" ""))
14008                       (pc)))]
14009   ""
14010   "ix86_expand_branch (EQ, operands[0]); DONE;")
14012 (define_expand "bne"
14013   [(set (pc)
14014         (if_then_else (match_dup 1)
14015                       (label_ref (match_operand 0 "" ""))
14016                       (pc)))]
14017   ""
14018   "ix86_expand_branch (NE, operands[0]); DONE;")
14020 (define_expand "bgt"
14021   [(set (pc)
14022         (if_then_else (match_dup 1)
14023                       (label_ref (match_operand 0 "" ""))
14024                       (pc)))]
14025   ""
14026   "ix86_expand_branch (GT, operands[0]); DONE;")
14028 (define_expand "bgtu"
14029   [(set (pc)
14030         (if_then_else (match_dup 1)
14031                       (label_ref (match_operand 0 "" ""))
14032                       (pc)))]
14033   ""
14034   "ix86_expand_branch (GTU, operands[0]); DONE;")
14036 (define_expand "blt"
14037   [(set (pc)
14038         (if_then_else (match_dup 1)
14039                       (label_ref (match_operand 0 "" ""))
14040                       (pc)))]
14041   ""
14042   "ix86_expand_branch (LT, operands[0]); DONE;")
14044 (define_expand "bltu"
14045   [(set (pc)
14046         (if_then_else (match_dup 1)
14047                       (label_ref (match_operand 0 "" ""))
14048                       (pc)))]
14049   ""
14050   "ix86_expand_branch (LTU, operands[0]); DONE;")
14052 (define_expand "bge"
14053   [(set (pc)
14054         (if_then_else (match_dup 1)
14055                       (label_ref (match_operand 0 "" ""))
14056                       (pc)))]
14057   ""
14058   "ix86_expand_branch (GE, operands[0]); DONE;")
14060 (define_expand "bgeu"
14061   [(set (pc)
14062         (if_then_else (match_dup 1)
14063                       (label_ref (match_operand 0 "" ""))
14064                       (pc)))]
14065   ""
14066   "ix86_expand_branch (GEU, operands[0]); DONE;")
14068 (define_expand "ble"
14069   [(set (pc)
14070         (if_then_else (match_dup 1)
14071                       (label_ref (match_operand 0 "" ""))
14072                       (pc)))]
14073   ""
14074   "ix86_expand_branch (LE, operands[0]); DONE;")
14076 (define_expand "bleu"
14077   [(set (pc)
14078         (if_then_else (match_dup 1)
14079                       (label_ref (match_operand 0 "" ""))
14080                       (pc)))]
14081   ""
14082   "ix86_expand_branch (LEU, operands[0]); DONE;")
14084 (define_expand "bunordered"
14085   [(set (pc)
14086         (if_then_else (match_dup 1)
14087                       (label_ref (match_operand 0 "" ""))
14088                       (pc)))]
14089   "TARGET_80387 || TARGET_SSE_MATH"
14090   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14092 (define_expand "bordered"
14093   [(set (pc)
14094         (if_then_else (match_dup 1)
14095                       (label_ref (match_operand 0 "" ""))
14096                       (pc)))]
14097   "TARGET_80387 || TARGET_SSE_MATH"
14098   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14100 (define_expand "buneq"
14101   [(set (pc)
14102         (if_then_else (match_dup 1)
14103                       (label_ref (match_operand 0 "" ""))
14104                       (pc)))]
14105   "TARGET_80387 || TARGET_SSE_MATH"
14106   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14108 (define_expand "bunge"
14109   [(set (pc)
14110         (if_then_else (match_dup 1)
14111                       (label_ref (match_operand 0 "" ""))
14112                       (pc)))]
14113   "TARGET_80387 || TARGET_SSE_MATH"
14114   "ix86_expand_branch (UNGE, operands[0]); DONE;")
14116 (define_expand "bungt"
14117   [(set (pc)
14118         (if_then_else (match_dup 1)
14119                       (label_ref (match_operand 0 "" ""))
14120                       (pc)))]
14121   "TARGET_80387 || TARGET_SSE_MATH"
14122   "ix86_expand_branch (UNGT, operands[0]); DONE;")
14124 (define_expand "bunle"
14125   [(set (pc)
14126         (if_then_else (match_dup 1)
14127                       (label_ref (match_operand 0 "" ""))
14128                       (pc)))]
14129   "TARGET_80387 || TARGET_SSE_MATH"
14130   "ix86_expand_branch (UNLE, operands[0]); DONE;")
14132 (define_expand "bunlt"
14133   [(set (pc)
14134         (if_then_else (match_dup 1)
14135                       (label_ref (match_operand 0 "" ""))
14136                       (pc)))]
14137   "TARGET_80387 || TARGET_SSE_MATH"
14138   "ix86_expand_branch (UNLT, operands[0]); DONE;")
14140 (define_expand "bltgt"
14141   [(set (pc)
14142         (if_then_else (match_dup 1)
14143                       (label_ref (match_operand 0 "" ""))
14144                       (pc)))]
14145   "TARGET_80387 || TARGET_SSE_MATH"
14146   "ix86_expand_branch (LTGT, operands[0]); DONE;")
14148 (define_insn "*jcc_1"
14149   [(set (pc)
14150         (if_then_else (match_operator 1 "ix86_comparison_operator"
14151                                       [(reg FLAGS_REG) (const_int 0)])
14152                       (label_ref (match_operand 0 "" ""))
14153                       (pc)))]
14154   ""
14155   "%+j%C1\t%l0"
14156   [(set_attr "type" "ibr")
14157    (set_attr "modrm" "0")
14158    (set (attr "length")
14159            (if_then_else (and (ge (minus (match_dup 0) (pc))
14160                                   (const_int -126))
14161                               (lt (minus (match_dup 0) (pc))
14162                                   (const_int 128)))
14163              (const_int 2)
14164              (const_int 6)))])
14166 (define_insn "*jcc_2"
14167   [(set (pc)
14168         (if_then_else (match_operator 1 "ix86_comparison_operator"
14169                                       [(reg FLAGS_REG) (const_int 0)])
14170                       (pc)
14171                       (label_ref (match_operand 0 "" ""))))]
14172   ""
14173   "%+j%c1\t%l0"
14174   [(set_attr "type" "ibr")
14175    (set_attr "modrm" "0")
14176    (set (attr "length")
14177            (if_then_else (and (ge (minus (match_dup 0) (pc))
14178                                   (const_int -126))
14179                               (lt (minus (match_dup 0) (pc))
14180                                   (const_int 128)))
14181              (const_int 2)
14182              (const_int 6)))])
14184 ;; In general it is not safe to assume too much about CCmode registers,
14185 ;; so simplify-rtx stops when it sees a second one.  Under certain
14186 ;; conditions this is safe on x86, so help combine not create
14188 ;;      seta    %al
14189 ;;      testb   %al, %al
14190 ;;      je      Lfoo
14192 (define_split
14193   [(set (pc)
14194         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14195                                       [(reg FLAGS_REG) (const_int 0)])
14196                           (const_int 0))
14197                       (label_ref (match_operand 1 "" ""))
14198                       (pc)))]
14199   ""
14200   [(set (pc)
14201         (if_then_else (match_dup 0)
14202                       (label_ref (match_dup 1))
14203                       (pc)))]
14205   PUT_MODE (operands[0], VOIDmode);
14208 (define_split
14209   [(set (pc)
14210         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14211                                       [(reg FLAGS_REG) (const_int 0)])
14212                           (const_int 0))
14213                       (label_ref (match_operand 1 "" ""))
14214                       (pc)))]
14215   ""
14216   [(set (pc)
14217         (if_then_else (match_dup 0)
14218                       (label_ref (match_dup 1))
14219                       (pc)))]
14221   rtx new_op0 = copy_rtx (operands[0]);
14222   operands[0] = new_op0;
14223   PUT_MODE (new_op0, VOIDmode);
14224   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14225                                              GET_MODE (XEXP (new_op0, 0))));
14227   /* Make sure that (a) the CCmode we have for the flags is strong
14228      enough for the reversed compare or (b) we have a valid FP compare.  */
14229   if (! ix86_comparison_operator (new_op0, VOIDmode))
14230     FAIL;
14233 ;; Define combination compare-and-branch fp compare instructions to use
14234 ;; during early optimization.  Splitting the operation apart early makes
14235 ;; for bad code when we want to reverse the operation.
14237 (define_insn "*fp_jcc_1_mixed"
14238   [(set (pc)
14239         (if_then_else (match_operator 0 "comparison_operator"
14240                         [(match_operand 1 "register_operand" "f,x")
14241                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14242           (label_ref (match_operand 3 "" ""))
14243           (pc)))
14244    (clobber (reg:CCFP FPSR_REG))
14245    (clobber (reg:CCFP FLAGS_REG))]
14246   "TARGET_MIX_SSE_I387
14247    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14248    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14249    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14250   "#")
14252 (define_insn "*fp_jcc_1_sse"
14253   [(set (pc)
14254         (if_then_else (match_operator 0 "comparison_operator"
14255                         [(match_operand 1 "register_operand" "x")
14256                          (match_operand 2 "nonimmediate_operand" "xm")])
14257           (label_ref (match_operand 3 "" ""))
14258           (pc)))
14259    (clobber (reg:CCFP FPSR_REG))
14260    (clobber (reg:CCFP FLAGS_REG))]
14261   "TARGET_SSE_MATH
14262    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14263    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14264    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14265   "#")
14267 (define_insn "*fp_jcc_1_387"
14268   [(set (pc)
14269         (if_then_else (match_operator 0 "comparison_operator"
14270                         [(match_operand 1 "register_operand" "f")
14271                          (match_operand 2 "register_operand" "f")])
14272           (label_ref (match_operand 3 "" ""))
14273           (pc)))
14274    (clobber (reg:CCFP FPSR_REG))
14275    (clobber (reg:CCFP FLAGS_REG))]
14276   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14277    && TARGET_CMOVE
14278    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14279    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14280   "#")
14282 (define_insn "*fp_jcc_2_mixed"
14283   [(set (pc)
14284         (if_then_else (match_operator 0 "comparison_operator"
14285                         [(match_operand 1 "register_operand" "f,x")
14286                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14287           (pc)
14288           (label_ref (match_operand 3 "" ""))))
14289    (clobber (reg:CCFP FPSR_REG))
14290    (clobber (reg:CCFP FLAGS_REG))]
14291   "TARGET_MIX_SSE_I387
14292    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14293    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14294    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14295   "#")
14297 (define_insn "*fp_jcc_2_sse"
14298   [(set (pc)
14299         (if_then_else (match_operator 0 "comparison_operator"
14300                         [(match_operand 1 "register_operand" "x")
14301                          (match_operand 2 "nonimmediate_operand" "xm")])
14302           (pc)
14303           (label_ref (match_operand 3 "" ""))))
14304    (clobber (reg:CCFP FPSR_REG))
14305    (clobber (reg:CCFP FLAGS_REG))]
14306   "TARGET_SSE_MATH
14307    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14308    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14309    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14310   "#")
14312 (define_insn "*fp_jcc_2_387"
14313   [(set (pc)
14314         (if_then_else (match_operator 0 "comparison_operator"
14315                         [(match_operand 1 "register_operand" "f")
14316                          (match_operand 2 "register_operand" "f")])
14317           (pc)
14318           (label_ref (match_operand 3 "" ""))))
14319    (clobber (reg:CCFP FPSR_REG))
14320    (clobber (reg:CCFP FLAGS_REG))]
14321   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14322    && TARGET_CMOVE
14323    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14324    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14325   "#")
14327 (define_insn "*fp_jcc_3_387"
14328   [(set (pc)
14329         (if_then_else (match_operator 0 "comparison_operator"
14330                         [(match_operand 1 "register_operand" "f")
14331                          (match_operand 2 "nonimmediate_operand" "fm")])
14332           (label_ref (match_operand 3 "" ""))
14333           (pc)))
14334    (clobber (reg:CCFP FPSR_REG))
14335    (clobber (reg:CCFP FLAGS_REG))
14336    (clobber (match_scratch:HI 4 "=a"))]
14337   "TARGET_80387
14338    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14339    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14340    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14341    && SELECT_CC_MODE (GET_CODE (operands[0]),
14342                       operands[1], operands[2]) == CCFPmode
14343    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14344   "#")
14346 (define_insn "*fp_jcc_4_387"
14347   [(set (pc)
14348         (if_then_else (match_operator 0 "comparison_operator"
14349                         [(match_operand 1 "register_operand" "f")
14350                          (match_operand 2 "nonimmediate_operand" "fm")])
14351           (pc)
14352           (label_ref (match_operand 3 "" ""))))
14353    (clobber (reg:CCFP FPSR_REG))
14354    (clobber (reg:CCFP FLAGS_REG))
14355    (clobber (match_scratch:HI 4 "=a"))]
14356   "TARGET_80387
14357    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14358    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14359    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14360    && SELECT_CC_MODE (GET_CODE (operands[0]),
14361                       operands[1], operands[2]) == CCFPmode
14362    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14363   "#")
14365 (define_insn "*fp_jcc_5_387"
14366   [(set (pc)
14367         (if_then_else (match_operator 0 "comparison_operator"
14368                         [(match_operand 1 "register_operand" "f")
14369                          (match_operand 2 "register_operand" "f")])
14370           (label_ref (match_operand 3 "" ""))
14371           (pc)))
14372    (clobber (reg:CCFP FPSR_REG))
14373    (clobber (reg:CCFP FLAGS_REG))
14374    (clobber (match_scratch:HI 4 "=a"))]
14375   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14376    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14377    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14378   "#")
14380 (define_insn "*fp_jcc_6_387"
14381   [(set (pc)
14382         (if_then_else (match_operator 0 "comparison_operator"
14383                         [(match_operand 1 "register_operand" "f")
14384                          (match_operand 2 "register_operand" "f")])
14385           (pc)
14386           (label_ref (match_operand 3 "" ""))))
14387    (clobber (reg:CCFP FPSR_REG))
14388    (clobber (reg:CCFP FLAGS_REG))
14389    (clobber (match_scratch:HI 4 "=a"))]
14390   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14391    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14392    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14393   "#")
14395 (define_insn "*fp_jcc_7_387"
14396   [(set (pc)
14397         (if_then_else (match_operator 0 "comparison_operator"
14398                         [(match_operand 1 "register_operand" "f")
14399                          (match_operand 2 "const0_operand" "X")])
14400           (label_ref (match_operand 3 "" ""))
14401           (pc)))
14402    (clobber (reg:CCFP FPSR_REG))
14403    (clobber (reg:CCFP FLAGS_REG))
14404    (clobber (match_scratch:HI 4 "=a"))]
14405   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14406    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14407    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14408    && SELECT_CC_MODE (GET_CODE (operands[0]),
14409                       operands[1], operands[2]) == CCFPmode
14410    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14411   "#")
14413 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14414 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14415 ;; with a precedence over other operators and is always put in the first
14416 ;; place. Swap condition and operands to match ficom instruction.
14418 (define_insn "*fp_jcc_8<mode>_387"
14419   [(set (pc)
14420         (if_then_else (match_operator 0 "comparison_operator"
14421                         [(match_operator 1 "float_operator"
14422                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14423                            (match_operand 3 "register_operand" "f,f")])
14424           (label_ref (match_operand 4 "" ""))
14425           (pc)))
14426    (clobber (reg:CCFP FPSR_REG))
14427    (clobber (reg:CCFP FLAGS_REG))
14428    (clobber (match_scratch:HI 5 "=a,a"))]
14429   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14430    && TARGET_USE_<MODE>MODE_FIOP
14431    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14432    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14433    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14434    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14435   "#")
14437 (define_split
14438   [(set (pc)
14439         (if_then_else (match_operator 0 "comparison_operator"
14440                         [(match_operand 1 "register_operand" "")
14441                          (match_operand 2 "nonimmediate_operand" "")])
14442           (match_operand 3 "" "")
14443           (match_operand 4 "" "")))
14444    (clobber (reg:CCFP FPSR_REG))
14445    (clobber (reg:CCFP FLAGS_REG))]
14446   "reload_completed"
14447   [(const_int 0)]
14449   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14450                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14451   DONE;
14454 (define_split
14455   [(set (pc)
14456         (if_then_else (match_operator 0 "comparison_operator"
14457                         [(match_operand 1 "register_operand" "")
14458                          (match_operand 2 "general_operand" "")])
14459           (match_operand 3 "" "")
14460           (match_operand 4 "" "")))
14461    (clobber (reg:CCFP FPSR_REG))
14462    (clobber (reg:CCFP FLAGS_REG))
14463    (clobber (match_scratch:HI 5 "=a"))]
14464   "reload_completed"
14465   [(const_int 0)]
14467   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14468                         operands[3], operands[4], operands[5], NULL_RTX);
14469   DONE;
14472 (define_split
14473   [(set (pc)
14474         (if_then_else (match_operator 0 "comparison_operator"
14475                         [(match_operator 1 "float_operator"
14476                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14477                            (match_operand 3 "register_operand" "")])
14478           (match_operand 4 "" "")
14479           (match_operand 5 "" "")))
14480    (clobber (reg:CCFP FPSR_REG))
14481    (clobber (reg:CCFP FLAGS_REG))
14482    (clobber (match_scratch:HI 6 "=a"))]
14483   "reload_completed"
14484   [(const_int 0)]
14486   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14487   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14488                         operands[3], operands[7],
14489                         operands[4], operands[5], operands[6], NULL_RTX);
14490   DONE;
14493 ;; %%% Kill this when reload knows how to do it.
14494 (define_split
14495   [(set (pc)
14496         (if_then_else (match_operator 0 "comparison_operator"
14497                         [(match_operator 1 "float_operator"
14498                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14499                            (match_operand 3 "register_operand" "")])
14500           (match_operand 4 "" "")
14501           (match_operand 5 "" "")))
14502    (clobber (reg:CCFP FPSR_REG))
14503    (clobber (reg:CCFP FLAGS_REG))
14504    (clobber (match_scratch:HI 6 "=a"))]
14505   "reload_completed"
14506   [(const_int 0)]
14508   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14509   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14510   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14511                         operands[3], operands[7],
14512                         operands[4], operands[5], operands[6], operands[2]);
14513   DONE;
14516 ;; Unconditional and other jump instructions
14518 (define_insn "jump"
14519   [(set (pc)
14520         (label_ref (match_operand 0 "" "")))]
14521   ""
14522   "jmp\t%l0"
14523   [(set_attr "type" "ibr")
14524    (set (attr "length")
14525            (if_then_else (and (ge (minus (match_dup 0) (pc))
14526                                   (const_int -126))
14527                               (lt (minus (match_dup 0) (pc))
14528                                   (const_int 128)))
14529              (const_int 2)
14530              (const_int 5)))
14531    (set_attr "modrm" "0")])
14533 (define_expand "indirect_jump"
14534   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14535   ""
14536   "")
14538 (define_insn "*indirect_jump"
14539   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14540   "!TARGET_64BIT"
14541   "jmp\t%A0"
14542   [(set_attr "type" "ibr")
14543    (set_attr "length_immediate" "0")])
14545 (define_insn "*indirect_jump_rtx64"
14546   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14547   "TARGET_64BIT"
14548   "jmp\t%A0"
14549   [(set_attr "type" "ibr")
14550    (set_attr "length_immediate" "0")])
14552 (define_expand "tablejump"
14553   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14554               (use (label_ref (match_operand 1 "" "")))])]
14555   ""
14557   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14558      relative.  Convert the relative address to an absolute address.  */
14559   if (flag_pic)
14560     {
14561       rtx op0, op1;
14562       enum rtx_code code;
14564       /* We can't use @GOTOFF for text labels on VxWorks;
14565          see gotoff_operand.  */
14566       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14567         {
14568           code = PLUS;
14569           op0 = operands[0];
14570           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14571         }
14572       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14573         {
14574           code = PLUS;
14575           op0 = operands[0];
14576           op1 = pic_offset_table_rtx;
14577         }
14578       else
14579         {
14580           code = MINUS;
14581           op0 = pic_offset_table_rtx;
14582           op1 = operands[0];
14583         }
14585       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14586                                          OPTAB_DIRECT);
14587     }
14590 (define_insn "*tablejump_1"
14591   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14592    (use (label_ref (match_operand 1 "" "")))]
14593   "!TARGET_64BIT"
14594   "jmp\t%A0"
14595   [(set_attr "type" "ibr")
14596    (set_attr "length_immediate" "0")])
14598 (define_insn "*tablejump_1_rtx64"
14599   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14600    (use (label_ref (match_operand 1 "" "")))]
14601   "TARGET_64BIT"
14602   "jmp\t%A0"
14603   [(set_attr "type" "ibr")
14604    (set_attr "length_immediate" "0")])
14606 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14608 (define_peephole2
14609   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14610    (set (match_operand:QI 1 "register_operand" "")
14611         (match_operator:QI 2 "ix86_comparison_operator"
14612           [(reg FLAGS_REG) (const_int 0)]))
14613    (set (match_operand 3 "q_regs_operand" "")
14614         (zero_extend (match_dup 1)))]
14615   "(peep2_reg_dead_p (3, operands[1])
14616     || operands_match_p (operands[1], operands[3]))
14617    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14618   [(set (match_dup 4) (match_dup 0))
14619    (set (strict_low_part (match_dup 5))
14620         (match_dup 2))]
14622   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14623   operands[5] = gen_lowpart (QImode, operands[3]);
14624   ix86_expand_clear (operands[3]);
14627 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14629 (define_peephole2
14630   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14631    (set (match_operand:QI 1 "register_operand" "")
14632         (match_operator:QI 2 "ix86_comparison_operator"
14633           [(reg FLAGS_REG) (const_int 0)]))
14634    (parallel [(set (match_operand 3 "q_regs_operand" "")
14635                    (zero_extend (match_dup 1)))
14636               (clobber (reg:CC FLAGS_REG))])]
14637   "(peep2_reg_dead_p (3, operands[1])
14638     || operands_match_p (operands[1], operands[3]))
14639    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14640   [(set (match_dup 4) (match_dup 0))
14641    (set (strict_low_part (match_dup 5))
14642         (match_dup 2))]
14644   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14645   operands[5] = gen_lowpart (QImode, operands[3]);
14646   ix86_expand_clear (operands[3]);
14649 ;; Call instructions.
14651 ;; The predicates normally associated with named expanders are not properly
14652 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14653 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14655 ;; Call subroutine returning no value.
14657 (define_expand "call_pop"
14658   [(parallel [(call (match_operand:QI 0 "" "")
14659                     (match_operand:SI 1 "" ""))
14660               (set (reg:SI SP_REG)
14661                    (plus:SI (reg:SI SP_REG)
14662                             (match_operand:SI 3 "" "")))])]
14663   "!TARGET_64BIT"
14665   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14666   DONE;
14669 (define_insn "*call_pop_0"
14670   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14671          (match_operand:SI 1 "" ""))
14672    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14673                             (match_operand:SI 2 "immediate_operand" "")))]
14674   "!TARGET_64BIT"
14676   if (SIBLING_CALL_P (insn))
14677     return "jmp\t%P0";
14678   else
14679     return "call\t%P0";
14681   [(set_attr "type" "call")])
14683 (define_insn "*call_pop_1"
14684   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14685          (match_operand:SI 1 "" ""))
14686    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14687                             (match_operand:SI 2 "immediate_operand" "i")))]
14688   "!TARGET_64BIT"
14690   if (constant_call_address_operand (operands[0], Pmode))
14691     {
14692       if (SIBLING_CALL_P (insn))
14693         return "jmp\t%P0";
14694       else
14695         return "call\t%P0";
14696     }
14697   if (SIBLING_CALL_P (insn))
14698     return "jmp\t%A0";
14699   else
14700     return "call\t%A0";
14702   [(set_attr "type" "call")])
14704 (define_expand "call"
14705   [(call (match_operand:QI 0 "" "")
14706          (match_operand 1 "" ""))
14707    (use (match_operand 2 "" ""))]
14708   ""
14710   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14711   DONE;
14714 (define_expand "sibcall"
14715   [(call (match_operand:QI 0 "" "")
14716          (match_operand 1 "" ""))
14717    (use (match_operand 2 "" ""))]
14718   ""
14720   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14721   DONE;
14724 (define_insn "*call_0"
14725   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14726          (match_operand 1 "" ""))]
14727   ""
14729   if (SIBLING_CALL_P (insn))
14730     return "jmp\t%P0";
14731   else
14732     return "call\t%P0";
14734   [(set_attr "type" "call")])
14736 (define_insn "*call_1"
14737   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14738          (match_operand 1 "" ""))]
14739   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14741   if (constant_call_address_operand (operands[0], Pmode))
14742     return "call\t%P0";
14743   return "call\t%A0";
14745   [(set_attr "type" "call")])
14747 (define_insn "*sibcall_1"
14748   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14749          (match_operand 1 "" ""))]
14750   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14752   if (constant_call_address_operand (operands[0], Pmode))
14753     return "jmp\t%P0";
14754   return "jmp\t%A0";
14756   [(set_attr "type" "call")])
14758 (define_insn "*call_1_rex64"
14759   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14760          (match_operand 1 "" ""))]
14761   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14762    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14764   if (constant_call_address_operand (operands[0], Pmode))
14765     return "call\t%P0";
14766   return "call\t%A0";
14768   [(set_attr "type" "call")])
14770 (define_insn "*call_1_rex64_large"
14771   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14772          (match_operand 1 "" ""))]
14773   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14774   "call\t%A0"
14775   [(set_attr "type" "call")])
14777 (define_insn "*sibcall_1_rex64"
14778   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14779          (match_operand 1 "" ""))]
14780   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14781   "jmp\t%P0"
14782   [(set_attr "type" "call")])
14784 (define_insn "*sibcall_1_rex64_v"
14785   [(call (mem:QI (reg:DI R11_REG))
14786          (match_operand 0 "" ""))]
14787   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14788   "jmp\t{*%%}r11"
14789   [(set_attr "type" "call")])
14792 ;; Call subroutine, returning value in operand 0
14794 (define_expand "call_value_pop"
14795   [(parallel [(set (match_operand 0 "" "")
14796                    (call (match_operand:QI 1 "" "")
14797                          (match_operand:SI 2 "" "")))
14798               (set (reg:SI SP_REG)
14799                    (plus:SI (reg:SI SP_REG)
14800                             (match_operand:SI 4 "" "")))])]
14801   "!TARGET_64BIT"
14803   ix86_expand_call (operands[0], operands[1], operands[2],
14804                     operands[3], operands[4], 0);
14805   DONE;
14808 (define_expand "call_value"
14809   [(set (match_operand 0 "" "")
14810         (call (match_operand:QI 1 "" "")
14811               (match_operand:SI 2 "" "")))
14812    (use (match_operand:SI 3 "" ""))]
14813   ;; Operand 2 not used on the i386.
14814   ""
14816   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14817   DONE;
14820 (define_expand "sibcall_value"
14821   [(set (match_operand 0 "" "")
14822         (call (match_operand:QI 1 "" "")
14823               (match_operand:SI 2 "" "")))
14824    (use (match_operand:SI 3 "" ""))]
14825   ;; Operand 2 not used on the i386.
14826   ""
14828   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14829   DONE;
14832 ;; Call subroutine returning any type.
14834 (define_expand "untyped_call"
14835   [(parallel [(call (match_operand 0 "" "")
14836                     (const_int 0))
14837               (match_operand 1 "" "")
14838               (match_operand 2 "" "")])]
14839   ""
14841   int i;
14843   /* In order to give reg-stack an easier job in validating two
14844      coprocessor registers as containing a possible return value,
14845      simply pretend the untyped call returns a complex long double
14846      value.  */
14848   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14849                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14850                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14851                     NULL, 0);
14853   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14854     {
14855       rtx set = XVECEXP (operands[2], 0, i);
14856       emit_move_insn (SET_DEST (set), SET_SRC (set));
14857     }
14859   /* The optimizer does not know that the call sets the function value
14860      registers we stored in the result block.  We avoid problems by
14861      claiming that all hard registers are used and clobbered at this
14862      point.  */
14863   emit_insn (gen_blockage ());
14865   DONE;
14868 ;; Prologue and epilogue instructions
14870 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14871 ;; all of memory.  This blocks insns from being moved across this point.
14873 (define_insn "blockage"
14874   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14875   ""
14876   ""
14877   [(set_attr "length" "0")])
14879 ;; As USE insns aren't meaningful after reload, this is used instead
14880 ;; to prevent deleting instructions setting registers for PIC code
14881 (define_insn "prologue_use"
14882   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14883   ""
14884   ""
14885   [(set_attr "length" "0")])
14887 ;; Insn emitted into the body of a function to return from a function.
14888 ;; This is only done if the function's epilogue is known to be simple.
14889 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14891 (define_expand "return"
14892   [(return)]
14893   "ix86_can_use_return_insn_p ()"
14895   if (current_function_pops_args)
14896     {
14897       rtx popc = GEN_INT (current_function_pops_args);
14898       emit_jump_insn (gen_return_pop_internal (popc));
14899       DONE;
14900     }
14903 (define_insn "return_internal"
14904   [(return)]
14905   "reload_completed"
14906   "ret"
14907   [(set_attr "length" "1")
14908    (set_attr "length_immediate" "0")
14909    (set_attr "modrm" "0")])
14911 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14912 ;; instruction Athlon and K8 have.
14914 (define_insn "return_internal_long"
14915   [(return)
14916    (unspec [(const_int 0)] UNSPEC_REP)]
14917   "reload_completed"
14918   "rep\;ret"
14919   [(set_attr "length" "1")
14920    (set_attr "length_immediate" "0")
14921    (set_attr "prefix_rep" "1")
14922    (set_attr "modrm" "0")])
14924 (define_insn "return_pop_internal"
14925   [(return)
14926    (use (match_operand:SI 0 "const_int_operand" ""))]
14927   "reload_completed"
14928   "ret\t%0"
14929   [(set_attr "length" "3")
14930    (set_attr "length_immediate" "2")
14931    (set_attr "modrm" "0")])
14933 (define_insn "return_indirect_internal"
14934   [(return)
14935    (use (match_operand:SI 0 "register_operand" "r"))]
14936   "reload_completed"
14937   "jmp\t%A0"
14938   [(set_attr "type" "ibr")
14939    (set_attr "length_immediate" "0")])
14941 (define_insn "nop"
14942   [(const_int 0)]
14943   ""
14944   "nop"
14945   [(set_attr "length" "1")
14946    (set_attr "length_immediate" "0")
14947    (set_attr "modrm" "0")])
14949 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14950 ;; branch prediction penalty for the third jump in a 16-byte
14951 ;; block on K8.
14953 (define_insn "align"
14954   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14955   ""
14957 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14958   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14959 #else
14960   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14961      The align insn is used to avoid 3 jump instructions in the row to improve
14962      branch prediction and the benefits hardly outweigh the cost of extra 8
14963      nops on the average inserted by full alignment pseudo operation.  */
14964 #endif
14965   return "";
14967   [(set_attr "length" "16")])
14969 (define_expand "prologue"
14970   [(const_int 0)]
14971   ""
14972   "ix86_expand_prologue (); DONE;")
14974 (define_insn "set_got"
14975   [(set (match_operand:SI 0 "register_operand" "=r")
14976         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14977    (clobber (reg:CC FLAGS_REG))]
14978   "!TARGET_64BIT"
14979   { return output_set_got (operands[0], NULL_RTX); }
14980   [(set_attr "type" "multi")
14981    (set_attr "length" "12")])
14983 (define_insn "set_got_labelled"
14984   [(set (match_operand:SI 0 "register_operand" "=r")
14985         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14986          UNSPEC_SET_GOT))
14987    (clobber (reg:CC FLAGS_REG))]
14988   "!TARGET_64BIT"
14989   { return output_set_got (operands[0], operands[1]); }
14990   [(set_attr "type" "multi")
14991    (set_attr "length" "12")])
14993 (define_insn "set_got_rex64"
14994   [(set (match_operand:DI 0 "register_operand" "=r")
14995         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14996   "TARGET_64BIT"
14997   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14998   [(set_attr "type" "lea")
14999    (set_attr "length" "6")])
15001 (define_insn "set_rip_rex64"
15002   [(set (match_operand:DI 0 "register_operand" "=r")
15003         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15004   "TARGET_64BIT"
15005   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15006   [(set_attr "type" "lea")
15007    (set_attr "length" "6")])
15009 (define_insn "set_got_offset_rex64"
15010   [(set (match_operand:DI 0 "register_operand" "=r")
15011         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15012   "TARGET_64BIT"
15013   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15014   [(set_attr "type" "imov")
15015    (set_attr "length" "11")])
15017 (define_expand "epilogue"
15018   [(const_int 0)]
15019   ""
15020   "ix86_expand_epilogue (1); DONE;")
15022 (define_expand "sibcall_epilogue"
15023   [(const_int 0)]
15024   ""
15025   "ix86_expand_epilogue (0); DONE;")
15027 (define_expand "eh_return"
15028   [(use (match_operand 0 "register_operand" ""))]
15029   ""
15031   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15033   /* Tricky bit: we write the address of the handler to which we will
15034      be returning into someone else's stack frame, one word below the
15035      stack address we wish to restore.  */
15036   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15037   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15038   tmp = gen_rtx_MEM (Pmode, tmp);
15039   emit_move_insn (tmp, ra);
15041   if (Pmode == SImode)
15042     emit_jump_insn (gen_eh_return_si (sa));
15043   else
15044     emit_jump_insn (gen_eh_return_di (sa));
15045   emit_barrier ();
15046   DONE;
15049 (define_insn_and_split "eh_return_si"
15050   [(set (pc)
15051         (unspec [(match_operand:SI 0 "register_operand" "c")]
15052                  UNSPEC_EH_RETURN))]
15053   "!TARGET_64BIT"
15054   "#"
15055   "reload_completed"
15056   [(const_int 0)]
15057   "ix86_expand_epilogue (2); DONE;")
15059 (define_insn_and_split "eh_return_di"
15060   [(set (pc)
15061         (unspec [(match_operand:DI 0 "register_operand" "c")]
15062                  UNSPEC_EH_RETURN))]
15063   "TARGET_64BIT"
15064   "#"
15065   "reload_completed"
15066   [(const_int 0)]
15067   "ix86_expand_epilogue (2); DONE;")
15069 (define_insn "leave"
15070   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15071    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15072    (clobber (mem:BLK (scratch)))]
15073   "!TARGET_64BIT"
15074   "leave"
15075   [(set_attr "type" "leave")])
15077 (define_insn "leave_rex64"
15078   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15079    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15080    (clobber (mem:BLK (scratch)))]
15081   "TARGET_64BIT"
15082   "leave"
15083   [(set_attr "type" "leave")])
15085 (define_expand "ffssi2"
15086   [(parallel
15087      [(set (match_operand:SI 0 "register_operand" "")
15088            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15089       (clobber (match_scratch:SI 2 ""))
15090       (clobber (reg:CC FLAGS_REG))])]
15091   ""
15093   if (TARGET_CMOVE)
15094     {
15095       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15096       DONE;
15097     }
15100 (define_expand "ffs_cmove"
15101   [(set (match_dup 2) (const_int -1))
15102    (parallel [(set (reg:CCZ FLAGS_REG)
15103                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15104                                 (const_int 0)))
15105               (set (match_operand:SI 0 "nonimmediate_operand" "")
15106                    (ctz:SI (match_dup 1)))])
15107    (set (match_dup 0) (if_then_else:SI
15108                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15109                         (match_dup 2)
15110                         (match_dup 0)))
15111    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15112               (clobber (reg:CC FLAGS_REG))])]
15113   "TARGET_CMOVE"
15114   "operands[2] = gen_reg_rtx (SImode);")
15116 (define_insn_and_split "*ffs_no_cmove"
15117   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15118         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15119    (clobber (match_scratch:SI 2 "=&q"))
15120    (clobber (reg:CC FLAGS_REG))]
15121   "!TARGET_CMOVE"
15122   "#"
15123   "&& reload_completed"
15124   [(parallel [(set (reg:CCZ FLAGS_REG)
15125                    (compare:CCZ (match_dup 1) (const_int 0)))
15126               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15127    (set (strict_low_part (match_dup 3))
15128         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15129    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15130               (clobber (reg:CC FLAGS_REG))])
15131    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15132               (clobber (reg:CC FLAGS_REG))])
15133    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15134               (clobber (reg:CC FLAGS_REG))])]
15136   operands[3] = gen_lowpart (QImode, operands[2]);
15137   ix86_expand_clear (operands[2]);
15140 (define_insn "*ffssi_1"
15141   [(set (reg:CCZ FLAGS_REG)
15142         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15143                      (const_int 0)))
15144    (set (match_operand:SI 0 "register_operand" "=r")
15145         (ctz:SI (match_dup 1)))]
15146   ""
15147   "bsf{l}\t{%1, %0|%0, %1}"
15148   [(set_attr "prefix_0f" "1")])
15150 (define_expand "ffsdi2"
15151   [(set (match_dup 2) (const_int -1))
15152    (parallel [(set (reg:CCZ FLAGS_REG)
15153                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15154                                 (const_int 0)))
15155               (set (match_operand:DI 0 "nonimmediate_operand" "")
15156                    (ctz:DI (match_dup 1)))])
15157    (set (match_dup 0) (if_then_else:DI
15158                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15159                         (match_dup 2)
15160                         (match_dup 0)))
15161    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15162               (clobber (reg:CC FLAGS_REG))])]
15163   "TARGET_64BIT"
15164   "operands[2] = gen_reg_rtx (DImode);")
15166 (define_insn "*ffsdi_1"
15167   [(set (reg:CCZ FLAGS_REG)
15168         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15169                      (const_int 0)))
15170    (set (match_operand:DI 0 "register_operand" "=r")
15171         (ctz:DI (match_dup 1)))]
15172   "TARGET_64BIT"
15173   "bsf{q}\t{%1, %0|%0, %1}"
15174   [(set_attr "prefix_0f" "1")])
15176 (define_insn "ctzsi2"
15177   [(set (match_operand:SI 0 "register_operand" "=r")
15178         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15179    (clobber (reg:CC FLAGS_REG))]
15180   ""
15181   "bsf{l}\t{%1, %0|%0, %1}"
15182   [(set_attr "prefix_0f" "1")])
15184 (define_insn "ctzdi2"
15185   [(set (match_operand:DI 0 "register_operand" "=r")
15186         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15187    (clobber (reg:CC FLAGS_REG))]
15188   "TARGET_64BIT"
15189   "bsf{q}\t{%1, %0|%0, %1}"
15190   [(set_attr "prefix_0f" "1")])
15192 (define_expand "clzsi2"
15193   [(parallel
15194      [(set (match_operand:SI 0 "register_operand" "")
15195            (minus:SI (const_int 31)
15196                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15197       (clobber (reg:CC FLAGS_REG))])
15198    (parallel
15199      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15200       (clobber (reg:CC FLAGS_REG))])]
15201   ""
15203   if (TARGET_ABM)
15204     {
15205       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15206       DONE;
15207     }
15210 (define_insn "clzsi2_abm"
15211   [(set (match_operand:SI 0 "register_operand" "=r")
15212         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15213    (clobber (reg:CC FLAGS_REG))]
15214   "TARGET_ABM"
15215   "lzcnt{l}\t{%1, %0|%0, %1}"
15216   [(set_attr "prefix_rep" "1")
15217    (set_attr "type" "bitmanip")
15218    (set_attr "mode" "SI")])
15220 (define_insn "*bsr"
15221   [(set (match_operand:SI 0 "register_operand" "=r")
15222         (minus:SI (const_int 31)
15223                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15224    (clobber (reg:CC FLAGS_REG))]
15225   ""
15226   "bsr{l}\t{%1, %0|%0, %1}"
15227   [(set_attr "prefix_0f" "1")
15228    (set_attr "mode" "SI")])
15230 (define_insn "popcountsi2"
15231   [(set (match_operand:SI 0 "register_operand" "=r")
15232         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15233    (clobber (reg:CC FLAGS_REG))]
15234   "TARGET_POPCNT"
15235   "popcnt{l}\t{%1, %0|%0, %1}"
15236   [(set_attr "prefix_rep" "1")
15237    (set_attr "type" "bitmanip")
15238    (set_attr "mode" "SI")])
15240 (define_insn "*popcountsi2_cmp"
15241   [(set (reg FLAGS_REG)
15242         (compare
15243           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15244           (const_int 0)))
15245    (set (match_operand:SI 0 "register_operand" "=r")
15246         (popcount:SI (match_dup 1)))]
15247   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15248   "popcnt{l}\t{%1, %0|%0, %1}"
15249   [(set_attr "prefix_rep" "1")
15250    (set_attr "type" "bitmanip")
15251    (set_attr "mode" "SI")])
15253 (define_insn "*popcountsi2_cmp_zext"
15254   [(set (reg FLAGS_REG)
15255         (compare
15256           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15257           (const_int 0)))
15258    (set (match_operand:DI 0 "register_operand" "=r")
15259         (zero_extend:DI(popcount:SI (match_dup 1))))]
15260   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15261   "popcnt{l}\t{%1, %0|%0, %1}"
15262   [(set_attr "prefix_rep" "1")
15263    (set_attr "type" "bitmanip")
15264    (set_attr "mode" "SI")])
15266 (define_expand "bswapsi2"
15267   [(set (match_operand:SI 0 "register_operand" "")
15268         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15269   ""
15271   if (!TARGET_BSWAP)
15272     {
15273       rtx x = operands[0];
15275       emit_move_insn (x, operands[1]);
15276       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15277       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15278       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15279       DONE;
15280     }
15283 (define_insn "*bswapsi_1"
15284   [(set (match_operand:SI 0 "register_operand" "=r")
15285         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15286   "TARGET_BSWAP"
15287   "bswap\t%0"
15288   [(set_attr "prefix_0f" "1")
15289    (set_attr "length" "2")])
15291 (define_insn "*bswaphi_lowpart_1"
15292   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15293         (bswap:HI (match_dup 0)))
15294    (clobber (reg:CC FLAGS_REG))]
15295   "TARGET_USE_XCHGB || optimize_size"
15296   "@
15297     xchg{b}\t{%h0, %b0|%b0, %h0}
15298     rol{w}\t{$8, %0|%0, 8}"
15299   [(set_attr "length" "2,4")
15300    (set_attr "mode" "QI,HI")])
15302 (define_insn "bswaphi_lowpart"
15303   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15304         (bswap:HI (match_dup 0)))
15305    (clobber (reg:CC FLAGS_REG))]
15306   ""
15307   "rol{w}\t{$8, %0|%0, 8}"
15308   [(set_attr "length" "4")
15309    (set_attr "mode" "HI")])
15311 (define_insn "bswapdi2"
15312   [(set (match_operand:DI 0 "register_operand" "=r")
15313         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15314   "TARGET_64BIT"
15315   "bswap\t%0"
15316   [(set_attr "prefix_0f" "1")
15317    (set_attr "length" "3")])
15319 (define_expand "clzdi2"
15320   [(parallel
15321      [(set (match_operand:DI 0 "register_operand" "")
15322            (minus:DI (const_int 63)
15323                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15324       (clobber (reg:CC FLAGS_REG))])
15325    (parallel
15326      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15327       (clobber (reg:CC FLAGS_REG))])]
15328   "TARGET_64BIT"
15330   if (TARGET_ABM)
15331     {
15332       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15333       DONE;
15334     }
15337 (define_insn "clzdi2_abm"
15338   [(set (match_operand:DI 0 "register_operand" "=r")
15339         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15340    (clobber (reg:CC FLAGS_REG))]
15341   "TARGET_64BIT && TARGET_ABM"
15342   "lzcnt{q}\t{%1, %0|%0, %1}"
15343   [(set_attr "prefix_rep" "1")
15344    (set_attr "type" "bitmanip")
15345    (set_attr "mode" "DI")])
15347 (define_insn "*bsr_rex64"
15348   [(set (match_operand:DI 0 "register_operand" "=r")
15349         (minus:DI (const_int 63)
15350                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15351    (clobber (reg:CC FLAGS_REG))]
15352   "TARGET_64BIT"
15353   "bsr{q}\t{%1, %0|%0, %1}"
15354   [(set_attr "prefix_0f" "1")
15355    (set_attr "mode" "DI")])
15357 (define_insn "popcountdi2"
15358   [(set (match_operand:DI 0 "register_operand" "=r")
15359         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15360    (clobber (reg:CC FLAGS_REG))]
15361   "TARGET_64BIT && TARGET_POPCNT"
15362   "popcnt{q}\t{%1, %0|%0, %1}"
15363   [(set_attr "prefix_rep" "1")
15364    (set_attr "type" "bitmanip")
15365    (set_attr "mode" "DI")])
15367 (define_insn "*popcountdi2_cmp"
15368   [(set (reg FLAGS_REG)
15369         (compare
15370           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15371           (const_int 0)))
15372    (set (match_operand:DI 0 "register_operand" "=r")
15373         (popcount:DI (match_dup 1)))]
15374   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15375   "popcnt{q}\t{%1, %0|%0, %1}"
15376   [(set_attr "prefix_rep" "1")
15377    (set_attr "type" "bitmanip")
15378    (set_attr "mode" "DI")])
15380 (define_expand "clzhi2"
15381   [(parallel
15382      [(set (match_operand:HI 0 "register_operand" "")
15383            (minus:HI (const_int 15)
15384                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15385       (clobber (reg:CC FLAGS_REG))])
15386    (parallel
15387      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15388       (clobber (reg:CC FLAGS_REG))])]
15389   ""
15391   if (TARGET_ABM)
15392     {
15393       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15394       DONE;
15395     }
15398 (define_insn "clzhi2_abm"
15399   [(set (match_operand:HI 0 "register_operand" "=r")
15400         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15401    (clobber (reg:CC FLAGS_REG))]
15402   "TARGET_ABM"
15403   "lzcnt{w}\t{%1, %0|%0, %1}"
15404   [(set_attr "prefix_rep" "1")
15405    (set_attr "type" "bitmanip")
15406    (set_attr "mode" "HI")])
15408 (define_insn "*bsrhi"
15409   [(set (match_operand:HI 0 "register_operand" "=r")
15410         (minus:HI (const_int 15)
15411                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15412    (clobber (reg:CC FLAGS_REG))]
15413   ""
15414   "bsr{w}\t{%1, %0|%0, %1}"
15415   [(set_attr "prefix_0f" "1")
15416    (set_attr "mode" "HI")])
15418 (define_insn "popcounthi2"
15419   [(set (match_operand:HI 0 "register_operand" "=r")
15420         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15421    (clobber (reg:CC FLAGS_REG))]
15422   "TARGET_POPCNT"
15423   "popcnt{w}\t{%1, %0|%0, %1}"
15424   [(set_attr "prefix_rep" "1")
15425    (set_attr "type" "bitmanip")
15426    (set_attr "mode" "HI")])
15428 (define_insn "*popcounthi2_cmp"
15429   [(set (reg FLAGS_REG)
15430         (compare
15431           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15432           (const_int 0)))
15433    (set (match_operand:HI 0 "register_operand" "=r")
15434         (popcount:HI (match_dup 1)))]
15435   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15436   "popcnt{w}\t{%1, %0|%0, %1}"
15437   [(set_attr "prefix_rep" "1")
15438    (set_attr "type" "bitmanip")
15439    (set_attr "mode" "HI")])
15441 (define_expand "paritydi2"
15442   [(set (match_operand:DI 0 "register_operand" "")
15443         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15444   "! TARGET_POPCNT"
15446   rtx scratch = gen_reg_rtx (QImode);
15447   rtx cond;
15449   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15450                                 NULL_RTX, operands[1]));
15452   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15453                          gen_rtx_REG (CCmode, FLAGS_REG),
15454                          const0_rtx);
15455   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15457   if (TARGET_64BIT)
15458     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15459   else
15460     {
15461       rtx tmp = gen_reg_rtx (SImode);
15463       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15464       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15465     }
15466   DONE;
15469 (define_insn_and_split "paritydi2_cmp"
15470   [(set (reg:CC FLAGS_REG)
15471         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15472    (clobber (match_scratch:DI 0 "=r,X"))
15473    (clobber (match_scratch:SI 1 "=r,r"))
15474    (clobber (match_scratch:HI 2 "=Q,Q"))]
15475   "! TARGET_POPCNT"
15476   "#"
15477   "&& reload_completed"
15478   [(parallel
15479      [(set (match_dup 1)
15480            (xor:SI (match_dup 1) (match_dup 4)))
15481       (clobber (reg:CC FLAGS_REG))])
15482    (parallel
15483      [(set (reg:CC FLAGS_REG)
15484            (parity:CC (match_dup 1)))
15485       (clobber (match_dup 1))
15486       (clobber (match_dup 2))])]
15488   operands[4] = gen_lowpart (SImode, operands[3]);
15490   if (MEM_P (operands[3]))
15491     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15492   else if (! TARGET_64BIT)
15493     operands[1] = gen_highpart (SImode, operands[3]);
15494   else
15495     {
15496       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15497       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15498     }
15501 (define_expand "paritysi2"
15502   [(set (match_operand:SI 0 "register_operand" "")
15503         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15504   "! TARGET_POPCNT"
15506   rtx scratch = gen_reg_rtx (QImode);
15507   rtx cond;
15509   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15511   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15512                          gen_rtx_REG (CCmode, FLAGS_REG),
15513                          const0_rtx);
15514   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15516   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15517   DONE;
15520 (define_insn_and_split "paritysi2_cmp"
15521   [(set (reg:CC FLAGS_REG)
15522         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15523    (clobber (match_scratch:SI 0 "=r,X"))
15524    (clobber (match_scratch:HI 1 "=Q,Q"))]
15525   "! TARGET_POPCNT"
15526   "#"
15527   "&& reload_completed"
15528   [(parallel
15529      [(set (match_dup 1)
15530            (xor:HI (match_dup 1) (match_dup 3)))
15531       (clobber (reg:CC FLAGS_REG))])
15532    (parallel
15533      [(set (reg:CC FLAGS_REG)
15534            (parity:CC (match_dup 1)))
15535       (clobber (match_dup 1))])]
15537   operands[3] = gen_lowpart (HImode, operands[2]);
15539   if (MEM_P (operands[2]))
15540     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15541   else
15542     {
15543       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15544       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15545     }
15548 (define_insn "*parityhi2_cmp"
15549   [(set (reg:CC FLAGS_REG)
15550         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15551    (clobber (match_scratch:HI 0 "=Q"))]
15552   "! TARGET_POPCNT"
15553   "xor{b}\t{%h0, %b0|%b0, %h0}"
15554   [(set_attr "length" "2")
15555    (set_attr "mode" "HI")])
15557 (define_insn "*parityqi2_cmp"
15558   [(set (reg:CC FLAGS_REG)
15559         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15560   "! TARGET_POPCNT"
15561   "test{b}\t%0, %0"
15562   [(set_attr "length" "2")
15563    (set_attr "mode" "QI")])
15565 ;; Thread-local storage patterns for ELF.
15567 ;; Note that these code sequences must appear exactly as shown
15568 ;; in order to allow linker relaxation.
15570 (define_insn "*tls_global_dynamic_32_gnu"
15571   [(set (match_operand:SI 0 "register_operand" "=a")
15572         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15573                     (match_operand:SI 2 "tls_symbolic_operand" "")
15574                     (match_operand:SI 3 "call_insn_operand" "")]
15575                     UNSPEC_TLS_GD))
15576    (clobber (match_scratch:SI 4 "=d"))
15577    (clobber (match_scratch:SI 5 "=c"))
15578    (clobber (reg:CC FLAGS_REG))]
15579   "!TARGET_64BIT && TARGET_GNU_TLS"
15580   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15581   [(set_attr "type" "multi")
15582    (set_attr "length" "12")])
15584 (define_insn "*tls_global_dynamic_32_sun"
15585   [(set (match_operand:SI 0 "register_operand" "=a")
15586         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15587                     (match_operand:SI 2 "tls_symbolic_operand" "")
15588                     (match_operand:SI 3 "call_insn_operand" "")]
15589                     UNSPEC_TLS_GD))
15590    (clobber (match_scratch:SI 4 "=d"))
15591    (clobber (match_scratch:SI 5 "=c"))
15592    (clobber (reg:CC FLAGS_REG))]
15593   "!TARGET_64BIT && TARGET_SUN_TLS"
15594   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15595         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15596   [(set_attr "type" "multi")
15597    (set_attr "length" "14")])
15599 (define_expand "tls_global_dynamic_32"
15600   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15601                    (unspec:SI
15602                     [(match_dup 2)
15603                      (match_operand:SI 1 "tls_symbolic_operand" "")
15604                      (match_dup 3)]
15605                     UNSPEC_TLS_GD))
15606               (clobber (match_scratch:SI 4 ""))
15607               (clobber (match_scratch:SI 5 ""))
15608               (clobber (reg:CC FLAGS_REG))])]
15609   ""
15611   if (flag_pic)
15612     operands[2] = pic_offset_table_rtx;
15613   else
15614     {
15615       operands[2] = gen_reg_rtx (Pmode);
15616       emit_insn (gen_set_got (operands[2]));
15617     }
15618   if (TARGET_GNU2_TLS)
15619     {
15620        emit_insn (gen_tls_dynamic_gnu2_32
15621                   (operands[0], operands[1], operands[2]));
15622        DONE;
15623     }
15624   operands[3] = ix86_tls_get_addr ();
15627 (define_insn "*tls_global_dynamic_64"
15628   [(set (match_operand:DI 0 "register_operand" "=a")
15629         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15630                  (match_operand:DI 3 "" "")))
15631    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15632               UNSPEC_TLS_GD)]
15633   "TARGET_64BIT"
15634   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15635   [(set_attr "type" "multi")
15636    (set_attr "length" "16")])
15638 (define_expand "tls_global_dynamic_64"
15639   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15640                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15641               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15642                          UNSPEC_TLS_GD)])]
15643   ""
15645   if (TARGET_GNU2_TLS)
15646     {
15647        emit_insn (gen_tls_dynamic_gnu2_64
15648                   (operands[0], operands[1]));
15649        DONE;
15650     }
15651   operands[2] = ix86_tls_get_addr ();
15654 (define_insn "*tls_local_dynamic_base_32_gnu"
15655   [(set (match_operand:SI 0 "register_operand" "=a")
15656         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15657                     (match_operand:SI 2 "call_insn_operand" "")]
15658                    UNSPEC_TLS_LD_BASE))
15659    (clobber (match_scratch:SI 3 "=d"))
15660    (clobber (match_scratch:SI 4 "=c"))
15661    (clobber (reg:CC FLAGS_REG))]
15662   "!TARGET_64BIT && TARGET_GNU_TLS"
15663   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15664   [(set_attr "type" "multi")
15665    (set_attr "length" "11")])
15667 (define_insn "*tls_local_dynamic_base_32_sun"
15668   [(set (match_operand:SI 0 "register_operand" "=a")
15669         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15670                     (match_operand:SI 2 "call_insn_operand" "")]
15671                    UNSPEC_TLS_LD_BASE))
15672    (clobber (match_scratch:SI 3 "=d"))
15673    (clobber (match_scratch:SI 4 "=c"))
15674    (clobber (reg:CC FLAGS_REG))]
15675   "!TARGET_64BIT && TARGET_SUN_TLS"
15676   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15677         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15678   [(set_attr "type" "multi")
15679    (set_attr "length" "13")])
15681 (define_expand "tls_local_dynamic_base_32"
15682   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15683                    (unspec:SI [(match_dup 1) (match_dup 2)]
15684                               UNSPEC_TLS_LD_BASE))
15685               (clobber (match_scratch:SI 3 ""))
15686               (clobber (match_scratch:SI 4 ""))
15687               (clobber (reg:CC FLAGS_REG))])]
15688   ""
15690   if (flag_pic)
15691     operands[1] = pic_offset_table_rtx;
15692   else
15693     {
15694       operands[1] = gen_reg_rtx (Pmode);
15695       emit_insn (gen_set_got (operands[1]));
15696     }
15697   if (TARGET_GNU2_TLS)
15698     {
15699        emit_insn (gen_tls_dynamic_gnu2_32
15700                   (operands[0], ix86_tls_module_base (), operands[1]));
15701        DONE;
15702     }
15703   operands[2] = ix86_tls_get_addr ();
15706 (define_insn "*tls_local_dynamic_base_64"
15707   [(set (match_operand:DI 0 "register_operand" "=a")
15708         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15709                  (match_operand:DI 2 "" "")))
15710    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15711   "TARGET_64BIT"
15712   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15713   [(set_attr "type" "multi")
15714    (set_attr "length" "12")])
15716 (define_expand "tls_local_dynamic_base_64"
15717   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15718                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15719               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15720   ""
15722   if (TARGET_GNU2_TLS)
15723     {
15724        emit_insn (gen_tls_dynamic_gnu2_64
15725                   (operands[0], ix86_tls_module_base ()));
15726        DONE;
15727     }
15728   operands[1] = ix86_tls_get_addr ();
15731 ;; Local dynamic of a single variable is a lose.  Show combine how
15732 ;; to convert that back to global dynamic.
15734 (define_insn_and_split "*tls_local_dynamic_32_once"
15735   [(set (match_operand:SI 0 "register_operand" "=a")
15736         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15737                              (match_operand:SI 2 "call_insn_operand" "")]
15738                             UNSPEC_TLS_LD_BASE)
15739                  (const:SI (unspec:SI
15740                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15741                             UNSPEC_DTPOFF))))
15742    (clobber (match_scratch:SI 4 "=d"))
15743    (clobber (match_scratch:SI 5 "=c"))
15744    (clobber (reg:CC FLAGS_REG))]
15745   ""
15746   "#"
15747   ""
15748   [(parallel [(set (match_dup 0)
15749                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15750                               UNSPEC_TLS_GD))
15751               (clobber (match_dup 4))
15752               (clobber (match_dup 5))
15753               (clobber (reg:CC FLAGS_REG))])]
15754   "")
15756 ;; Load and add the thread base pointer from %gs:0.
15758 (define_insn "*load_tp_si"
15759   [(set (match_operand:SI 0 "register_operand" "=r")
15760         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15761   "!TARGET_64BIT"
15762   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15763   [(set_attr "type" "imov")
15764    (set_attr "modrm" "0")
15765    (set_attr "length" "7")
15766    (set_attr "memory" "load")
15767    (set_attr "imm_disp" "false")])
15769 (define_insn "*add_tp_si"
15770   [(set (match_operand:SI 0 "register_operand" "=r")
15771         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15772                  (match_operand:SI 1 "register_operand" "0")))
15773    (clobber (reg:CC FLAGS_REG))]
15774   "!TARGET_64BIT"
15775   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15776   [(set_attr "type" "alu")
15777    (set_attr "modrm" "0")
15778    (set_attr "length" "7")
15779    (set_attr "memory" "load")
15780    (set_attr "imm_disp" "false")])
15782 (define_insn "*load_tp_di"
15783   [(set (match_operand:DI 0 "register_operand" "=r")
15784         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15785   "TARGET_64BIT"
15786   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15787   [(set_attr "type" "imov")
15788    (set_attr "modrm" "0")
15789    (set_attr "length" "7")
15790    (set_attr "memory" "load")
15791    (set_attr "imm_disp" "false")])
15793 (define_insn "*add_tp_di"
15794   [(set (match_operand:DI 0 "register_operand" "=r")
15795         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15796                  (match_operand:DI 1 "register_operand" "0")))
15797    (clobber (reg:CC FLAGS_REG))]
15798   "TARGET_64BIT"
15799   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15800   [(set_attr "type" "alu")
15801    (set_attr "modrm" "0")
15802    (set_attr "length" "7")
15803    (set_attr "memory" "load")
15804    (set_attr "imm_disp" "false")])
15806 ;; GNU2 TLS patterns can be split.
15808 (define_expand "tls_dynamic_gnu2_32"
15809   [(set (match_dup 3)
15810         (plus:SI (match_operand:SI 2 "register_operand" "")
15811                  (const:SI
15812                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15813                              UNSPEC_TLSDESC))))
15814    (parallel
15815     [(set (match_operand:SI 0 "register_operand" "")
15816           (unspec:SI [(match_dup 1) (match_dup 3)
15817                       (match_dup 2) (reg:SI SP_REG)]
15818                       UNSPEC_TLSDESC))
15819      (clobber (reg:CC FLAGS_REG))])]
15820   "!TARGET_64BIT && TARGET_GNU2_TLS"
15822   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15823   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15826 (define_insn "*tls_dynamic_lea_32"
15827   [(set (match_operand:SI 0 "register_operand" "=r")
15828         (plus:SI (match_operand:SI 1 "register_operand" "b")
15829                  (const:SI
15830                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15831                               UNSPEC_TLSDESC))))]
15832   "!TARGET_64BIT && TARGET_GNU2_TLS"
15833   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15834   [(set_attr "type" "lea")
15835    (set_attr "mode" "SI")
15836    (set_attr "length" "6")
15837    (set_attr "length_address" "4")])
15839 (define_insn "*tls_dynamic_call_32"
15840   [(set (match_operand:SI 0 "register_operand" "=a")
15841         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15842                     (match_operand:SI 2 "register_operand" "0")
15843                     ;; we have to make sure %ebx still points to the GOT
15844                     (match_operand:SI 3 "register_operand" "b")
15845                     (reg:SI SP_REG)]
15846                    UNSPEC_TLSDESC))
15847    (clobber (reg:CC FLAGS_REG))]
15848   "!TARGET_64BIT && TARGET_GNU2_TLS"
15849   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15850   [(set_attr "type" "call")
15851    (set_attr "length" "2")
15852    (set_attr "length_address" "0")])
15854 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15855   [(set (match_operand:SI 0 "register_operand" "=&a")
15856         (plus:SI
15857          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15858                      (match_operand:SI 4 "" "")
15859                      (match_operand:SI 2 "register_operand" "b")
15860                      (reg:SI SP_REG)]
15861                     UNSPEC_TLSDESC)
15862          (const:SI (unspec:SI
15863                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15864                     UNSPEC_DTPOFF))))
15865    (clobber (reg:CC FLAGS_REG))]
15866   "!TARGET_64BIT && TARGET_GNU2_TLS"
15867   "#"
15868   ""
15869   [(set (match_dup 0) (match_dup 5))]
15871   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15872   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15875 (define_expand "tls_dynamic_gnu2_64"
15876   [(set (match_dup 2)
15877         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15878                    UNSPEC_TLSDESC))
15879    (parallel
15880     [(set (match_operand:DI 0 "register_operand" "")
15881           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15882                      UNSPEC_TLSDESC))
15883      (clobber (reg:CC FLAGS_REG))])]
15884   "TARGET_64BIT && TARGET_GNU2_TLS"
15886   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15887   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15890 (define_insn "*tls_dynamic_lea_64"
15891   [(set (match_operand:DI 0 "register_operand" "=r")
15892         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15893                    UNSPEC_TLSDESC))]
15894   "TARGET_64BIT && TARGET_GNU2_TLS"
15895   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15896   [(set_attr "type" "lea")
15897    (set_attr "mode" "DI")
15898    (set_attr "length" "7")
15899    (set_attr "length_address" "4")])
15901 (define_insn "*tls_dynamic_call_64"
15902   [(set (match_operand:DI 0 "register_operand" "=a")
15903         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15904                     (match_operand:DI 2 "register_operand" "0")
15905                     (reg:DI SP_REG)]
15906                    UNSPEC_TLSDESC))
15907    (clobber (reg:CC FLAGS_REG))]
15908   "TARGET_64BIT && TARGET_GNU2_TLS"
15909   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15910   [(set_attr "type" "call")
15911    (set_attr "length" "2")
15912    (set_attr "length_address" "0")])
15914 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15915   [(set (match_operand:DI 0 "register_operand" "=&a")
15916         (plus:DI
15917          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15918                      (match_operand:DI 3 "" "")
15919                      (reg:DI SP_REG)]
15920                     UNSPEC_TLSDESC)
15921          (const:DI (unspec:DI
15922                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15923                     UNSPEC_DTPOFF))))
15924    (clobber (reg:CC FLAGS_REG))]
15925   "TARGET_64BIT && TARGET_GNU2_TLS"
15926   "#"
15927   ""
15928   [(set (match_dup 0) (match_dup 4))]
15930   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15931   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15936 ;; These patterns match the binary 387 instructions for addM3, subM3,
15937 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15938 ;; SFmode.  The first is the normal insn, the second the same insn but
15939 ;; with one operand a conversion, and the third the same insn but with
15940 ;; the other operand a conversion.  The conversion may be SFmode or
15941 ;; SImode if the target mode DFmode, but only SImode if the target mode
15942 ;; is SFmode.
15944 ;; Gcc is slightly more smart about handling normal two address instructions
15945 ;; so use special patterns for add and mull.
15947 (define_insn "*fop_sf_comm_mixed"
15948   [(set (match_operand:SF 0 "register_operand" "=f,x")
15949         (match_operator:SF 3 "binary_fp_operator"
15950                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15951                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15952   "TARGET_MIX_SSE_I387
15953    && COMMUTATIVE_ARITH_P (operands[3])
15954    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15955   "* return output_387_binary_op (insn, operands);"
15956   [(set (attr "type")
15957         (if_then_else (eq_attr "alternative" "1")
15958            (if_then_else (match_operand:SF 3 "mult_operator" "")
15959               (const_string "ssemul")
15960               (const_string "sseadd"))
15961            (if_then_else (match_operand:SF 3 "mult_operator" "")
15962               (const_string "fmul")
15963               (const_string "fop"))))
15964    (set_attr "mode" "SF")])
15966 (define_insn "*fop_sf_comm_sse"
15967   [(set (match_operand:SF 0 "register_operand" "=x")
15968         (match_operator:SF 3 "binary_fp_operator"
15969                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15970                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15971   "TARGET_SSE_MATH
15972    && COMMUTATIVE_ARITH_P (operands[3])
15973    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15974   "* return output_387_binary_op (insn, operands);"
15975   [(set (attr "type")
15976         (if_then_else (match_operand:SF 3 "mult_operator" "")
15977            (const_string "ssemul")
15978            (const_string "sseadd")))
15979    (set_attr "mode" "SF")])
15981 (define_insn "*fop_sf_comm_i387"
15982   [(set (match_operand:SF 0 "register_operand" "=f")
15983         (match_operator:SF 3 "binary_fp_operator"
15984                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15985                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15986   "TARGET_80387
15987    && COMMUTATIVE_ARITH_P (operands[3])
15988    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15989   "* return output_387_binary_op (insn, operands);"
15990   [(set (attr "type")
15991         (if_then_else (match_operand:SF 3 "mult_operator" "")
15992            (const_string "fmul")
15993            (const_string "fop")))
15994    (set_attr "mode" "SF")])
15996 (define_insn "*fop_sf_1_mixed"
15997   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15998         (match_operator:SF 3 "binary_fp_operator"
15999                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16000                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16001   "TARGET_MIX_SSE_I387
16002    && !COMMUTATIVE_ARITH_P (operands[3])
16003    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16004   "* return output_387_binary_op (insn, operands);"
16005   [(set (attr "type")
16006         (cond [(and (eq_attr "alternative" "2")
16007                     (match_operand:SF 3 "mult_operator" ""))
16008                  (const_string "ssemul")
16009                (and (eq_attr "alternative" "2")
16010                     (match_operand:SF 3 "div_operator" ""))
16011                  (const_string "ssediv")
16012                (eq_attr "alternative" "2")
16013                  (const_string "sseadd")
16014                (match_operand:SF 3 "mult_operator" "")
16015                  (const_string "fmul")
16016                (match_operand:SF 3 "div_operator" "")
16017                  (const_string "fdiv")
16018               ]
16019               (const_string "fop")))
16020    (set_attr "mode" "SF")])
16022 (define_insn "*rcpsf2_sse"
16023   [(set (match_operand:SF 0 "register_operand" "=x")
16024         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16025                    UNSPEC_RCP))]
16026   "TARGET_SSE_MATH"
16027   "rcpss\t{%1, %0|%0, %1}"
16028   [(set_attr "type" "sse")
16029    (set_attr "mode" "SF")])
16031 (define_insn "*fop_sf_1_sse"
16032   [(set (match_operand:SF 0 "register_operand" "=x")
16033         (match_operator:SF 3 "binary_fp_operator"
16034                         [(match_operand:SF 1 "register_operand" "0")
16035                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16036   "TARGET_SSE_MATH
16037    && !COMMUTATIVE_ARITH_P (operands[3])"
16038   "* return output_387_binary_op (insn, operands);"
16039   [(set (attr "type")
16040         (cond [(match_operand:SF 3 "mult_operator" "")
16041                  (const_string "ssemul")
16042                (match_operand:SF 3 "div_operator" "")
16043                  (const_string "ssediv")
16044               ]
16045               (const_string "sseadd")))
16046    (set_attr "mode" "SF")])
16048 ;; This pattern is not fully shadowed by the pattern above.
16049 (define_insn "*fop_sf_1_i387"
16050   [(set (match_operand:SF 0 "register_operand" "=f,f")
16051         (match_operator:SF 3 "binary_fp_operator"
16052                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16053                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16054   "TARGET_80387 && !TARGET_SSE_MATH
16055    && !COMMUTATIVE_ARITH_P (operands[3])
16056    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16057   "* return output_387_binary_op (insn, operands);"
16058   [(set (attr "type")
16059         (cond [(match_operand:SF 3 "mult_operator" "")
16060                  (const_string "fmul")
16061                (match_operand:SF 3 "div_operator" "")
16062                  (const_string "fdiv")
16063               ]
16064               (const_string "fop")))
16065    (set_attr "mode" "SF")])
16067 ;; ??? Add SSE splitters for these!
16068 (define_insn "*fop_sf_2<mode>_i387"
16069   [(set (match_operand:SF 0 "register_operand" "=f,f")
16070         (match_operator:SF 3 "binary_fp_operator"
16071           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16072            (match_operand:SF 2 "register_operand" "0,0")]))]
16073   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16074   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16075   [(set (attr "type")
16076         (cond [(match_operand:SF 3 "mult_operator" "")
16077                  (const_string "fmul")
16078                (match_operand:SF 3 "div_operator" "")
16079                  (const_string "fdiv")
16080               ]
16081               (const_string "fop")))
16082    (set_attr "fp_int_src" "true")
16083    (set_attr "mode" "<MODE>")])
16085 (define_insn "*fop_sf_3<mode>_i387"
16086   [(set (match_operand:SF 0 "register_operand" "=f,f")
16087         (match_operator:SF 3 "binary_fp_operator"
16088           [(match_operand:SF 1 "register_operand" "0,0")
16089            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16090   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16091   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16092   [(set (attr "type")
16093         (cond [(match_operand:SF 3 "mult_operator" "")
16094                  (const_string "fmul")
16095                (match_operand:SF 3 "div_operator" "")
16096                  (const_string "fdiv")
16097               ]
16098               (const_string "fop")))
16099    (set_attr "fp_int_src" "true")
16100    (set_attr "mode" "<MODE>")])
16102 (define_insn "*fop_df_comm_mixed"
16103   [(set (match_operand:DF 0 "register_operand" "=f,x")
16104         (match_operator:DF 3 "binary_fp_operator"
16105           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16106            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16107   "TARGET_SSE2 && TARGET_MIX_SSE_I387
16108    && COMMUTATIVE_ARITH_P (operands[3])
16109    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16110   "* return output_387_binary_op (insn, operands);"
16111   [(set (attr "type")
16112         (if_then_else (eq_attr "alternative" "1")
16113            (if_then_else (match_operand:DF 3 "mult_operator" "")
16114               (const_string "ssemul")
16115               (const_string "sseadd"))
16116            (if_then_else (match_operand:DF 3 "mult_operator" "")
16117               (const_string "fmul")
16118               (const_string "fop"))))
16119    (set_attr "mode" "DF")])
16121 (define_insn "*fop_df_comm_sse"
16122   [(set (match_operand:DF 0 "register_operand" "=x")
16123         (match_operator:DF 3 "binary_fp_operator"
16124           [(match_operand:DF 1 "nonimmediate_operand" "%0")
16125            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16126   "TARGET_SSE2 && TARGET_SSE_MATH
16127    && COMMUTATIVE_ARITH_P (operands[3])
16128    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16129   "* return output_387_binary_op (insn, operands);"
16130   [(set (attr "type")
16131         (if_then_else (match_operand:DF 3 "mult_operator" "")
16132            (const_string "ssemul")
16133            (const_string "sseadd")))
16134    (set_attr "mode" "DF")])
16136 (define_insn "*fop_df_comm_i387"
16137   [(set (match_operand:DF 0 "register_operand" "=f")
16138         (match_operator:DF 3 "binary_fp_operator"
16139                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
16140                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16141   "TARGET_80387
16142    && COMMUTATIVE_ARITH_P (operands[3])
16143    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16144   "* return output_387_binary_op (insn, operands);"
16145   [(set (attr "type")
16146         (if_then_else (match_operand:DF 3 "mult_operator" "")
16147            (const_string "fmul")
16148            (const_string "fop")))
16149    (set_attr "mode" "DF")])
16151 (define_insn "*fop_df_1_mixed"
16152   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16153         (match_operator:DF 3 "binary_fp_operator"
16154           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16155            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16156   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16157    && !COMMUTATIVE_ARITH_P (operands[3])
16158    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16159   "* return output_387_binary_op (insn, operands);"
16160   [(set (attr "type")
16161         (cond [(and (eq_attr "alternative" "2")
16162                     (match_operand:DF 3 "mult_operator" ""))
16163                  (const_string "ssemul")
16164                (and (eq_attr "alternative" "2")
16165                     (match_operand:DF 3 "div_operator" ""))
16166                  (const_string "ssediv")
16167                (eq_attr "alternative" "2")
16168                  (const_string "sseadd")
16169                (match_operand:DF 3 "mult_operator" "")
16170                  (const_string "fmul")
16171                (match_operand:DF 3 "div_operator" "")
16172                  (const_string "fdiv")
16173               ]
16174               (const_string "fop")))
16175    (set_attr "mode" "DF")])
16177 (define_insn "*fop_df_1_sse"
16178   [(set (match_operand:DF 0 "register_operand" "=x")
16179         (match_operator:DF 3 "binary_fp_operator"
16180           [(match_operand:DF 1 "register_operand" "0")
16181            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16182   "TARGET_SSE2 && TARGET_SSE_MATH
16183    && !COMMUTATIVE_ARITH_P (operands[3])"
16184   "* return output_387_binary_op (insn, operands);"
16185   [(set_attr "mode" "DF")
16186    (set (attr "type")
16187         (cond [(match_operand:DF 3 "mult_operator" "")
16188                  (const_string "ssemul")
16189                (match_operand:DF 3 "div_operator" "")
16190                  (const_string "ssediv")
16191               ]
16192               (const_string "sseadd")))])
16194 ;; This pattern is not fully shadowed by the pattern above.
16195 (define_insn "*fop_df_1_i387"
16196   [(set (match_operand:DF 0 "register_operand" "=f,f")
16197         (match_operator:DF 3 "binary_fp_operator"
16198                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16199                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16200   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16201    && !COMMUTATIVE_ARITH_P (operands[3])
16202    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16203   "* return output_387_binary_op (insn, operands);"
16204   [(set (attr "type")
16205         (cond [(match_operand:DF 3 "mult_operator" "")
16206                  (const_string "fmul")
16207                (match_operand:DF 3 "div_operator" "")
16208                  (const_string "fdiv")
16209               ]
16210               (const_string "fop")))
16211    (set_attr "mode" "DF")])
16213 ;; ??? Add SSE splitters for these!
16214 (define_insn "*fop_df_2<mode>_i387"
16215   [(set (match_operand:DF 0 "register_operand" "=f,f")
16216         (match_operator:DF 3 "binary_fp_operator"
16217            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16218             (match_operand:DF 2 "register_operand" "0,0")]))]
16219   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16220    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16221   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16222   [(set (attr "type")
16223         (cond [(match_operand:DF 3 "mult_operator" "")
16224                  (const_string "fmul")
16225                (match_operand:DF 3 "div_operator" "")
16226                  (const_string "fdiv")
16227               ]
16228               (const_string "fop")))
16229    (set_attr "fp_int_src" "true")
16230    (set_attr "mode" "<MODE>")])
16232 (define_insn "*fop_df_3<mode>_i387"
16233   [(set (match_operand:DF 0 "register_operand" "=f,f")
16234         (match_operator:DF 3 "binary_fp_operator"
16235            [(match_operand:DF 1 "register_operand" "0,0")
16236             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16237   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16238    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16239   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16240   [(set (attr "type")
16241         (cond [(match_operand:DF 3 "mult_operator" "")
16242                  (const_string "fmul")
16243                (match_operand:DF 3 "div_operator" "")
16244                  (const_string "fdiv")
16245               ]
16246               (const_string "fop")))
16247    (set_attr "fp_int_src" "true")
16248    (set_attr "mode" "<MODE>")])
16250 (define_insn "*fop_df_4_i387"
16251   [(set (match_operand:DF 0 "register_operand" "=f,f")
16252         (match_operator:DF 3 "binary_fp_operator"
16253            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16254             (match_operand:DF 2 "register_operand" "0,f")]))]
16255   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16256    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16257   "* return output_387_binary_op (insn, operands);"
16258   [(set (attr "type")
16259         (cond [(match_operand:DF 3 "mult_operator" "")
16260                  (const_string "fmul")
16261                (match_operand:DF 3 "div_operator" "")
16262                  (const_string "fdiv")
16263               ]
16264               (const_string "fop")))
16265    (set_attr "mode" "SF")])
16267 (define_insn "*fop_df_5_i387"
16268   [(set (match_operand:DF 0 "register_operand" "=f,f")
16269         (match_operator:DF 3 "binary_fp_operator"
16270           [(match_operand:DF 1 "register_operand" "0,f")
16271            (float_extend:DF
16272             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16273   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16274   "* return output_387_binary_op (insn, operands);"
16275   [(set (attr "type")
16276         (cond [(match_operand:DF 3 "mult_operator" "")
16277                  (const_string "fmul")
16278                (match_operand:DF 3 "div_operator" "")
16279                  (const_string "fdiv")
16280               ]
16281               (const_string "fop")))
16282    (set_attr "mode" "SF")])
16284 (define_insn "*fop_df_6_i387"
16285   [(set (match_operand:DF 0 "register_operand" "=f,f")
16286         (match_operator:DF 3 "binary_fp_operator"
16287           [(float_extend:DF
16288             (match_operand:SF 1 "register_operand" "0,f"))
16289            (float_extend:DF
16290             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16291   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16292   "* return output_387_binary_op (insn, operands);"
16293   [(set (attr "type")
16294         (cond [(match_operand:DF 3 "mult_operator" "")
16295                  (const_string "fmul")
16296                (match_operand:DF 3 "div_operator" "")
16297                  (const_string "fdiv")
16298               ]
16299               (const_string "fop")))
16300    (set_attr "mode" "SF")])
16302 (define_insn "*fop_xf_comm_i387"
16303   [(set (match_operand:XF 0 "register_operand" "=f")
16304         (match_operator:XF 3 "binary_fp_operator"
16305                         [(match_operand:XF 1 "register_operand" "%0")
16306                          (match_operand:XF 2 "register_operand" "f")]))]
16307   "TARGET_80387
16308    && COMMUTATIVE_ARITH_P (operands[3])"
16309   "* return output_387_binary_op (insn, operands);"
16310   [(set (attr "type")
16311         (if_then_else (match_operand:XF 3 "mult_operator" "")
16312            (const_string "fmul")
16313            (const_string "fop")))
16314    (set_attr "mode" "XF")])
16316 (define_insn "*fop_xf_1_i387"
16317   [(set (match_operand:XF 0 "register_operand" "=f,f")
16318         (match_operator:XF 3 "binary_fp_operator"
16319                         [(match_operand:XF 1 "register_operand" "0,f")
16320                          (match_operand:XF 2 "register_operand" "f,0")]))]
16321   "TARGET_80387
16322    && !COMMUTATIVE_ARITH_P (operands[3])"
16323   "* return output_387_binary_op (insn, operands);"
16324   [(set (attr "type")
16325         (cond [(match_operand:XF 3 "mult_operator" "")
16326                  (const_string "fmul")
16327                (match_operand:XF 3 "div_operator" "")
16328                  (const_string "fdiv")
16329               ]
16330               (const_string "fop")))
16331    (set_attr "mode" "XF")])
16333 (define_insn "*fop_xf_2<mode>_i387"
16334   [(set (match_operand:XF 0 "register_operand" "=f,f")
16335         (match_operator:XF 3 "binary_fp_operator"
16336            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16337             (match_operand:XF 2 "register_operand" "0,0")]))]
16338   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16339   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16340   [(set (attr "type")
16341         (cond [(match_operand:XF 3 "mult_operator" "")
16342                  (const_string "fmul")
16343                (match_operand:XF 3 "div_operator" "")
16344                  (const_string "fdiv")
16345               ]
16346               (const_string "fop")))
16347    (set_attr "fp_int_src" "true")
16348    (set_attr "mode" "<MODE>")])
16350 (define_insn "*fop_xf_3<mode>_i387"
16351   [(set (match_operand:XF 0 "register_operand" "=f,f")
16352         (match_operator:XF 3 "binary_fp_operator"
16353           [(match_operand:XF 1 "register_operand" "0,0")
16354            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16355   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16356   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16357   [(set (attr "type")
16358         (cond [(match_operand:XF 3 "mult_operator" "")
16359                  (const_string "fmul")
16360                (match_operand:XF 3 "div_operator" "")
16361                  (const_string "fdiv")
16362               ]
16363               (const_string "fop")))
16364    (set_attr "fp_int_src" "true")
16365    (set_attr "mode" "<MODE>")])
16367 (define_insn "*fop_xf_4_i387"
16368   [(set (match_operand:XF 0 "register_operand" "=f,f")
16369         (match_operator:XF 3 "binary_fp_operator"
16370            [(float_extend:XF
16371               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16372             (match_operand:XF 2 "register_operand" "0,f")]))]
16373   "TARGET_80387"
16374   "* return output_387_binary_op (insn, operands);"
16375   [(set (attr "type")
16376         (cond [(match_operand:XF 3 "mult_operator" "")
16377                  (const_string "fmul")
16378                (match_operand:XF 3 "div_operator" "")
16379                  (const_string "fdiv")
16380               ]
16381               (const_string "fop")))
16382    (set_attr "mode" "SF")])
16384 (define_insn "*fop_xf_5_i387"
16385   [(set (match_operand:XF 0 "register_operand" "=f,f")
16386         (match_operator:XF 3 "binary_fp_operator"
16387           [(match_operand:XF 1 "register_operand" "0,f")
16388            (float_extend:XF
16389              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16390   "TARGET_80387"
16391   "* return output_387_binary_op (insn, operands);"
16392   [(set (attr "type")
16393         (cond [(match_operand:XF 3 "mult_operator" "")
16394                  (const_string "fmul")
16395                (match_operand:XF 3 "div_operator" "")
16396                  (const_string "fdiv")
16397               ]
16398               (const_string "fop")))
16399    (set_attr "mode" "SF")])
16401 (define_insn "*fop_xf_6_i387"
16402   [(set (match_operand:XF 0 "register_operand" "=f,f")
16403         (match_operator:XF 3 "binary_fp_operator"
16404           [(float_extend:XF
16405              (match_operand:MODEF 1 "register_operand" "0,f"))
16406            (float_extend:XF
16407              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16408   "TARGET_80387"
16409   "* return output_387_binary_op (insn, operands);"
16410   [(set (attr "type")
16411         (cond [(match_operand:XF 3 "mult_operator" "")
16412                  (const_string "fmul")
16413                (match_operand:XF 3 "div_operator" "")
16414                  (const_string "fdiv")
16415               ]
16416               (const_string "fop")))
16417    (set_attr "mode" "SF")])
16419 (define_split
16420   [(set (match_operand 0 "register_operand" "")
16421         (match_operator 3 "binary_fp_operator"
16422            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16423             (match_operand 2 "register_operand" "")]))]
16424   "reload_completed
16425    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16426   [(const_int 0)]
16428   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16429   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16430   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16431                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16432                                           GET_MODE (operands[3]),
16433                                           operands[4],
16434                                           operands[2])));
16435   ix86_free_from_memory (GET_MODE (operands[1]));
16436   DONE;
16439 (define_split
16440   [(set (match_operand 0 "register_operand" "")
16441         (match_operator 3 "binary_fp_operator"
16442            [(match_operand 1 "register_operand" "")
16443             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16444   "reload_completed
16445    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16446   [(const_int 0)]
16448   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16449   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16450   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16451                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16452                                           GET_MODE (operands[3]),
16453                                           operands[1],
16454                                           operands[4])));
16455   ix86_free_from_memory (GET_MODE (operands[2]));
16456   DONE;
16459 ;; FPU special functions.
16461 ;; This pattern implements a no-op XFmode truncation for
16462 ;; all fancy i386 XFmode math functions.
16464 (define_insn "truncxf<mode>2_i387_noop_unspec"
16465   [(set (match_operand:MODEF 0 "register_operand" "=f")
16466         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16467         UNSPEC_TRUNC_NOOP))]
16468   "TARGET_USE_FANCY_MATH_387"
16469   "* return output_387_reg_move (insn, operands);"
16470   [(set_attr "type" "fmov")
16471    (set_attr "mode" "<MODE>")])
16473 (define_insn "sqrtxf2"
16474   [(set (match_operand:XF 0 "register_operand" "=f")
16475         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16476   "TARGET_USE_FANCY_MATH_387"
16477   "fsqrt"
16478   [(set_attr "type" "fpspc")
16479    (set_attr "mode" "XF")
16480    (set_attr "athlon_decode" "direct")
16481    (set_attr "amdfam10_decode" "direct")])
16483 (define_insn "sqrt_extend<mode>xf2_i387"
16484   [(set (match_operand:XF 0 "register_operand" "=f")
16485         (sqrt:XF
16486           (float_extend:XF
16487             (match_operand:MODEF 1 "register_operand" "0"))))]
16488   "TARGET_USE_FANCY_MATH_387"
16489   "fsqrt"
16490   [(set_attr "type" "fpspc")
16491    (set_attr "mode" "XF")
16492    (set_attr "athlon_decode" "direct")
16493    (set_attr "amdfam10_decode" "direct")])
16495 (define_insn "*rsqrtsf2_sse"
16496   [(set (match_operand:SF 0 "register_operand" "=x")
16497         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16498                    UNSPEC_RSQRT))]
16499   "TARGET_SSE_MATH"
16500   "rsqrtss\t{%1, %0|%0, %1}"
16501   [(set_attr "type" "sse")
16502    (set_attr "mode" "SF")])
16504 (define_expand "rsqrtsf2"
16505   [(set (match_operand:SF 0 "register_operand" "")
16506         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16507                    UNSPEC_RSQRT))]
16508   "TARGET_SSE_MATH"
16510   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16511   DONE;
16514 (define_insn "*sqrt<mode>2_sse"
16515   [(set (match_operand:MODEF 0 "register_operand" "=x")
16516         (sqrt:MODEF
16517           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16518   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16519   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16520   [(set_attr "type" "sse")
16521    (set_attr "mode" "<MODE>")
16522    (set_attr "athlon_decode" "*")
16523    (set_attr "amdfam10_decode" "*")])
16525 (define_expand "sqrt<mode>2"
16526   [(set (match_operand:MODEF 0 "register_operand" "")
16527         (sqrt:MODEF
16528           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16529   "TARGET_USE_FANCY_MATH_387
16530    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16532   if (<MODE>mode == SFmode
16533       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16534       && flag_finite_math_only && !flag_trapping_math
16535       && flag_unsafe_math_optimizations)
16536     {
16537       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16538       DONE;
16539     }
16541   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16542     {
16543       rtx op0 = gen_reg_rtx (XFmode);
16544       rtx op1 = force_reg (<MODE>mode, operands[1]);
16546       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16547       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16548       DONE;
16549    }
16552 (define_insn "fpremxf4_i387"
16553   [(set (match_operand:XF 0 "register_operand" "=f")
16554         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16555                     (match_operand:XF 3 "register_operand" "1")]
16556                    UNSPEC_FPREM_F))
16557    (set (match_operand:XF 1 "register_operand" "=u")
16558         (unspec:XF [(match_dup 2) (match_dup 3)]
16559                    UNSPEC_FPREM_U))
16560    (set (reg:CCFP FPSR_REG)
16561         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16562                      UNSPEC_C2_FLAG))]
16563   "TARGET_USE_FANCY_MATH_387"
16564   "fprem"
16565   [(set_attr "type" "fpspc")
16566    (set_attr "mode" "XF")])
16568 (define_expand "fmodxf3"
16569   [(use (match_operand:XF 0 "register_operand" ""))
16570    (use (match_operand:XF 1 "register_operand" ""))
16571    (use (match_operand:XF 2 "register_operand" ""))]
16572   "TARGET_USE_FANCY_MATH_387"
16574   rtx label = gen_label_rtx ();
16576   rtx op2;
16578   if (rtx_equal_p (operands[1], operands[2]))
16579     {
16580       op2 = gen_reg_rtx (XFmode);
16581       emit_move_insn (op2, operands[2]);
16582     }
16583   else
16584     op2 = operands[2];
16586   emit_label (label);
16587   emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16588   ix86_emit_fp_unordered_jump (label);
16589   LABEL_NUSES (label) = 1;
16591   emit_move_insn (operands[0], operands[1]);
16592   DONE;
16595 (define_expand "fmod<mode>3"
16596   [(use (match_operand:MODEF 0 "register_operand" ""))
16597    (use (match_operand:MODEF 1 "general_operand" ""))
16598    (use (match_operand:MODEF 2 "general_operand" ""))]
16599   "TARGET_USE_FANCY_MATH_387"
16601   rtx label = gen_label_rtx ();
16603   rtx op1 = gen_reg_rtx (XFmode);
16604   rtx op2 = gen_reg_rtx (XFmode);
16606   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16607   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16609   emit_label (label);
16610   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16611   ix86_emit_fp_unordered_jump (label);
16612   LABEL_NUSES (label) = 1;
16614   /* Truncate the result properly for strict SSE math.  */
16615   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16616       && !TARGET_MIX_SSE_I387)
16617     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16618   else
16619     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16621   DONE;
16624 (define_insn "fprem1xf4_i387"
16625   [(set (match_operand:XF 0 "register_operand" "=f")
16626         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16627                     (match_operand:XF 3 "register_operand" "1")]
16628                    UNSPEC_FPREM1_F))
16629    (set (match_operand:XF 1 "register_operand" "=u")
16630         (unspec:XF [(match_dup 2) (match_dup 3)]
16631                    UNSPEC_FPREM1_U))
16632    (set (reg:CCFP FPSR_REG)
16633         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16634                      UNSPEC_C2_FLAG))]
16635   "TARGET_USE_FANCY_MATH_387"
16636   "fprem1"
16637   [(set_attr "type" "fpspc")
16638    (set_attr "mode" "XF")])
16640 (define_expand "remainderxf3"
16641   [(use (match_operand:XF 0 "register_operand" ""))
16642    (use (match_operand:XF 1 "register_operand" ""))
16643    (use (match_operand:XF 2 "register_operand" ""))]
16644   "TARGET_USE_FANCY_MATH_387"
16646   rtx label = gen_label_rtx ();
16648   rtx op2;
16650   if (rtx_equal_p (operands[1], operands[2]))
16651     {
16652       op2 = gen_reg_rtx (XFmode);
16653       emit_move_insn (op2, operands[2]);
16654     }
16655   else
16656     op2 = operands[2];
16658   emit_label (label);
16659   emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16660   ix86_emit_fp_unordered_jump (label);
16661   LABEL_NUSES (label) = 1;
16663   emit_move_insn (operands[0], operands[1]);
16664   DONE;
16667 (define_expand "remainder<mode>3"
16668   [(use (match_operand:MODEF 0 "register_operand" ""))
16669    (use (match_operand:MODEF 1 "general_operand" ""))
16670    (use (match_operand:MODEF 2 "general_operand" ""))]
16671   "TARGET_USE_FANCY_MATH_387"
16673   rtx label = gen_label_rtx ();
16675   rtx op1 = gen_reg_rtx (XFmode);
16676   rtx op2 = gen_reg_rtx (XFmode);
16678   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16679   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16681   emit_label (label);
16683   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16684   ix86_emit_fp_unordered_jump (label);
16685   LABEL_NUSES (label) = 1;
16687   /* Truncate the result properly for strict SSE math.  */
16688   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16689       && !TARGET_MIX_SSE_I387)
16690     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16691   else
16692     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16694   DONE;
16697 (define_insn "*sinxf2_i387"
16698   [(set (match_operand:XF 0 "register_operand" "=f")
16699         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16700   "TARGET_USE_FANCY_MATH_387
16701    && flag_unsafe_math_optimizations"
16702   "fsin"
16703   [(set_attr "type" "fpspc")
16704    (set_attr "mode" "XF")])
16706 (define_insn "*sin_extend<mode>xf2_i387"
16707   [(set (match_operand:XF 0 "register_operand" "=f")
16708         (unspec:XF [(float_extend:XF
16709                       (match_operand:MODEF 1 "register_operand" "0"))]
16710                    UNSPEC_SIN))]
16711   "TARGET_USE_FANCY_MATH_387
16712    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16713        || TARGET_MIX_SSE_I387)
16714    && flag_unsafe_math_optimizations"
16715   "fsin"
16716   [(set_attr "type" "fpspc")
16717    (set_attr "mode" "XF")])
16719 (define_insn "*cosxf2_i387"
16720   [(set (match_operand:XF 0 "register_operand" "=f")
16721         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16722   "TARGET_USE_FANCY_MATH_387
16723    && flag_unsafe_math_optimizations"
16724   "fcos"
16725   [(set_attr "type" "fpspc")
16726    (set_attr "mode" "XF")])
16728 (define_insn "*cos_extend<mode>xf2_i387"
16729   [(set (match_operand:XF 0 "register_operand" "=f")
16730         (unspec:XF [(float_extend:XF
16731                       (match_operand:MODEF 1 "register_operand" "0"))]
16732                    UNSPEC_COS))]
16733   "TARGET_USE_FANCY_MATH_387
16734    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16735        || TARGET_MIX_SSE_I387)
16736    && flag_unsafe_math_optimizations"
16737   "fcos"
16738   [(set_attr "type" "fpspc")
16739    (set_attr "mode" "XF")])
16741 ;; When sincos pattern is defined, sin and cos builtin functions will be
16742 ;; expanded to sincos pattern with one of its outputs left unused.
16743 ;; CSE pass will figure out if two sincos patterns can be combined,
16744 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16745 ;; depending on the unused output.
16747 (define_insn "sincosxf3"
16748   [(set (match_operand:XF 0 "register_operand" "=f")
16749         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16750                    UNSPEC_SINCOS_COS))
16751    (set (match_operand:XF 1 "register_operand" "=u")
16752         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16753   "TARGET_USE_FANCY_MATH_387
16754    && flag_unsafe_math_optimizations"
16755   "fsincos"
16756   [(set_attr "type" "fpspc")
16757    (set_attr "mode" "XF")])
16759 (define_split
16760   [(set (match_operand:XF 0 "register_operand" "")
16761         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16762                    UNSPEC_SINCOS_COS))
16763    (set (match_operand:XF 1 "register_operand" "")
16764         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16765   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16766    && !(reload_completed || reload_in_progress)"
16767   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16768   "")
16770 (define_split
16771   [(set (match_operand:XF 0 "register_operand" "")
16772         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16773                    UNSPEC_SINCOS_COS))
16774    (set (match_operand:XF 1 "register_operand" "")
16775         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16776   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16777    && !(reload_completed || reload_in_progress)"
16778   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16779   "")
16781 (define_insn "sincos_extend<mode>xf3_i387"
16782   [(set (match_operand:XF 0 "register_operand" "=f")
16783         (unspec:XF [(float_extend:XF
16784                       (match_operand:MODEF 2 "register_operand" "0"))]
16785                    UNSPEC_SINCOS_COS))
16786    (set (match_operand:XF 1 "register_operand" "=u")
16787         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16788   "TARGET_USE_FANCY_MATH_387
16789    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16790        || TARGET_MIX_SSE_I387)
16791    && flag_unsafe_math_optimizations"
16792   "fsincos"
16793   [(set_attr "type" "fpspc")
16794    (set_attr "mode" "XF")])
16796 (define_split
16797   [(set (match_operand:XF 0 "register_operand" "")
16798         (unspec:XF [(float_extend:XF
16799                       (match_operand:MODEF 2 "register_operand" ""))]
16800                    UNSPEC_SINCOS_COS))
16801    (set (match_operand:XF 1 "register_operand" "")
16802         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16803   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16804    && !(reload_completed || reload_in_progress)"
16805   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16806   "")
16808 (define_split
16809   [(set (match_operand:XF 0 "register_operand" "")
16810         (unspec:XF [(float_extend:XF
16811                       (match_operand:MODEF 2 "register_operand" ""))]
16812                    UNSPEC_SINCOS_COS))
16813    (set (match_operand:XF 1 "register_operand" "")
16814         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16815   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16816    && !(reload_completed || reload_in_progress)"
16817   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16818   "")
16820 (define_expand "sincos<mode>3"
16821   [(use (match_operand:MODEF 0 "register_operand" ""))
16822    (use (match_operand:MODEF 1 "register_operand" ""))
16823    (use (match_operand:MODEF 2 "register_operand" ""))]
16824   "TARGET_USE_FANCY_MATH_387
16825    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16826        || TARGET_MIX_SSE_I387)
16827    && flag_unsafe_math_optimizations"
16829   rtx op0 = gen_reg_rtx (XFmode);
16830   rtx op1 = gen_reg_rtx (XFmode);
16832   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16833   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16834   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16835   DONE;
16838 (define_insn "fptanxf4_i387"
16839   [(set (match_operand:XF 0 "register_operand" "=f")
16840         (match_operand:XF 3 "const_double_operand" "F"))
16841    (set (match_operand:XF 1 "register_operand" "=u")
16842         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16843                    UNSPEC_TAN))]
16844   "TARGET_USE_FANCY_MATH_387
16845    && flag_unsafe_math_optimizations
16846    && standard_80387_constant_p (operands[3]) == 2"
16847   "fptan"
16848   [(set_attr "type" "fpspc")
16849    (set_attr "mode" "XF")])
16851 (define_insn "fptan_extend<mode>xf4_i387"
16852   [(set (match_operand:MODEF 0 "register_operand" "=f")
16853         (match_operand:MODEF 3 "const_double_operand" "F"))
16854    (set (match_operand:XF 1 "register_operand" "=u")
16855         (unspec:XF [(float_extend:XF
16856                       (match_operand:MODEF 2 "register_operand" "0"))]
16857                    UNSPEC_TAN))]
16858   "TARGET_USE_FANCY_MATH_387
16859    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16860        || TARGET_MIX_SSE_I387)
16861    && flag_unsafe_math_optimizations
16862    && standard_80387_constant_p (operands[3]) == 2"
16863   "fptan"
16864   [(set_attr "type" "fpspc")
16865    (set_attr "mode" "XF")])
16867 (define_expand "tanxf2"
16868   [(use (match_operand:XF 0 "register_operand" ""))
16869    (use (match_operand:XF 1 "register_operand" ""))]
16870   "TARGET_USE_FANCY_MATH_387
16871    && flag_unsafe_math_optimizations"
16873   rtx one = gen_reg_rtx (XFmode);
16874   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16876   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16877   DONE;
16880 (define_expand "tan<mode>2"
16881   [(use (match_operand:MODEF 0 "register_operand" ""))
16882    (use (match_operand:MODEF 1 "register_operand" ""))]
16883   "TARGET_USE_FANCY_MATH_387
16884    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16885        || TARGET_MIX_SSE_I387)
16886    && flag_unsafe_math_optimizations"
16888   rtx op0 = gen_reg_rtx (XFmode);
16890   rtx one = gen_reg_rtx (<MODE>mode);
16891   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16893   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16894                                              operands[1], op2));
16895   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16896   DONE;
16899 (define_insn "*fpatanxf3_i387"
16900   [(set (match_operand:XF 0 "register_operand" "=f")
16901         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16902                     (match_operand:XF 2 "register_operand" "u")]
16903                    UNSPEC_FPATAN))
16904    (clobber (match_scratch:XF 3 "=2"))]
16905   "TARGET_USE_FANCY_MATH_387
16906    && flag_unsafe_math_optimizations"
16907   "fpatan"
16908   [(set_attr "type" "fpspc")
16909    (set_attr "mode" "XF")])
16911 (define_insn "fpatan_extend<mode>xf3_i387"
16912   [(set (match_operand:XF 0 "register_operand" "=f")
16913         (unspec:XF [(float_extend:XF
16914                       (match_operand:MODEF 1 "register_operand" "0"))
16915                     (float_extend:XF
16916                       (match_operand:MODEF 2 "register_operand" "u"))]
16917                    UNSPEC_FPATAN))
16918    (clobber (match_scratch:XF 3 "=2"))]
16919   "TARGET_USE_FANCY_MATH_387
16920    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16921        || TARGET_MIX_SSE_I387)
16922    && flag_unsafe_math_optimizations"
16923   "fpatan"
16924   [(set_attr "type" "fpspc")
16925    (set_attr "mode" "XF")])
16927 (define_expand "atan2xf3"
16928   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16929                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16930                                (match_operand:XF 1 "register_operand" "")]
16931                               UNSPEC_FPATAN))
16932               (clobber (match_scratch:XF 3 ""))])]
16933   "TARGET_USE_FANCY_MATH_387
16934    && flag_unsafe_math_optimizations"
16935   "")
16937 (define_expand "atan2<mode>3"
16938   [(use (match_operand:MODEF 0 "register_operand" ""))
16939    (use (match_operand:MODEF 1 "register_operand" ""))
16940    (use (match_operand:MODEF 2 "register_operand" ""))]
16941   "TARGET_USE_FANCY_MATH_387
16942    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16943        || TARGET_MIX_SSE_I387)
16944    && flag_unsafe_math_optimizations"
16946   rtx op0 = gen_reg_rtx (XFmode);
16948   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16949   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16950   DONE;
16953 (define_expand "atanxf2"
16954   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16955                    (unspec:XF [(match_dup 2)
16956                                (match_operand:XF 1 "register_operand" "")]
16957                               UNSPEC_FPATAN))
16958               (clobber (match_scratch:XF 3 ""))])]
16959   "TARGET_USE_FANCY_MATH_387
16960    && flag_unsafe_math_optimizations"
16962   operands[2] = gen_reg_rtx (XFmode);
16963   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16966 (define_expand "atan<mode>2"
16967   [(use (match_operand:MODEF 0 "register_operand" ""))
16968    (use (match_operand:MODEF 1 "register_operand" ""))]
16969   "TARGET_USE_FANCY_MATH_387
16970    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16971        || TARGET_MIX_SSE_I387)
16972    && flag_unsafe_math_optimizations"
16974   rtx op0 = gen_reg_rtx (XFmode);
16976   rtx op2 = gen_reg_rtx (<MODE>mode);
16977   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16979   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16980   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16981   DONE;
16984 (define_expand "asinxf2"
16985   [(set (match_dup 2)
16986         (mult:XF (match_operand:XF 1 "register_operand" "")
16987                  (match_dup 1)))
16988    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16989    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16990    (parallel [(set (match_operand:XF 0 "register_operand" "")
16991                    (unspec:XF [(match_dup 5) (match_dup 1)]
16992                               UNSPEC_FPATAN))
16993               (clobber (match_scratch:XF 6 ""))])]
16994   "TARGET_USE_FANCY_MATH_387
16995    && flag_unsafe_math_optimizations && !optimize_size"
16997   int i;
16999   for (i = 2; i < 6; i++)
17000     operands[i] = gen_reg_rtx (XFmode);
17002   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17005 (define_expand "asin<mode>2"
17006   [(use (match_operand:MODEF 0 "register_operand" ""))
17007    (use (match_operand:MODEF 1 "general_operand" ""))]
17008  "TARGET_USE_FANCY_MATH_387
17009    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17010        || TARGET_MIX_SSE_I387)
17011    && flag_unsafe_math_optimizations && !optimize_size"
17013   rtx op0 = gen_reg_rtx (XFmode);
17014   rtx op1 = gen_reg_rtx (XFmode);
17016   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17017   emit_insn (gen_asinxf2 (op0, op1));
17018   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17019   DONE;
17022 (define_expand "acosxf2"
17023   [(set (match_dup 2)
17024         (mult:XF (match_operand:XF 1 "register_operand" "")
17025                  (match_dup 1)))
17026    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17027    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17028    (parallel [(set (match_operand:XF 0 "register_operand" "")
17029                    (unspec:XF [(match_dup 1) (match_dup 5)]
17030                               UNSPEC_FPATAN))
17031               (clobber (match_scratch:XF 6 ""))])]
17032   "TARGET_USE_FANCY_MATH_387
17033    && flag_unsafe_math_optimizations && !optimize_size"
17035   int i;
17037   for (i = 2; i < 6; i++)
17038     operands[i] = gen_reg_rtx (XFmode);
17040   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17043 (define_expand "acos<mode>2"
17044   [(use (match_operand:MODEF 0 "register_operand" ""))
17045    (use (match_operand:MODEF 1 "general_operand" ""))]
17046  "TARGET_USE_FANCY_MATH_387
17047    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17048        || TARGET_MIX_SSE_I387)
17049    && flag_unsafe_math_optimizations && !optimize_size"
17051   rtx op0 = gen_reg_rtx (XFmode);
17052   rtx op1 = gen_reg_rtx (XFmode);
17054   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17055   emit_insn (gen_acosxf2 (op0, op1));
17056   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17057   DONE;
17060 (define_insn "fyl2xxf3_i387"
17061   [(set (match_operand:XF 0 "register_operand" "=f")
17062         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17063                     (match_operand:XF 2 "register_operand" "u")]
17064                    UNSPEC_FYL2X))
17065    (clobber (match_scratch:XF 3 "=2"))]
17066   "TARGET_USE_FANCY_MATH_387
17067    && flag_unsafe_math_optimizations"
17068   "fyl2x"
17069   [(set_attr "type" "fpspc")
17070    (set_attr "mode" "XF")])
17072 (define_insn "fyl2x_extend<mode>xf3_i387"
17073   [(set (match_operand:XF 0 "register_operand" "=f")
17074         (unspec:XF [(float_extend:XF
17075                       (match_operand:MODEF 1 "register_operand" "0"))
17076                     (match_operand:XF 2 "register_operand" "u")]
17077                    UNSPEC_FYL2X))
17078    (clobber (match_scratch:XF 3 "=2"))]
17079   "TARGET_USE_FANCY_MATH_387
17080    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17081        || TARGET_MIX_SSE_I387)
17082    && flag_unsafe_math_optimizations"
17083   "fyl2x"
17084   [(set_attr "type" "fpspc")
17085    (set_attr "mode" "XF")])
17087 (define_expand "logxf2"
17088   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17089                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17090                                (match_dup 2)] UNSPEC_FYL2X))
17091               (clobber (match_scratch:XF 3 ""))])]
17092   "TARGET_USE_FANCY_MATH_387
17093    && flag_unsafe_math_optimizations"
17095   operands[2] = gen_reg_rtx (XFmode);
17096   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17099 (define_expand "log<mode>2"
17100   [(use (match_operand:MODEF 0 "register_operand" ""))
17101    (use (match_operand:MODEF 1 "register_operand" ""))]
17102   "TARGET_USE_FANCY_MATH_387
17103    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17104        || TARGET_MIX_SSE_I387)
17105    && flag_unsafe_math_optimizations"
17107   rtx op0 = gen_reg_rtx (XFmode);
17109   rtx op2 = gen_reg_rtx (XFmode);
17110   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17112   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17113   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17114   DONE;
17117 (define_expand "log10xf2"
17118   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17119                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17120                                (match_dup 2)] UNSPEC_FYL2X))
17121               (clobber (match_scratch:XF 3 ""))])]
17122   "TARGET_USE_FANCY_MATH_387
17123    && flag_unsafe_math_optimizations"
17125   operands[2] = gen_reg_rtx (XFmode);
17126   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17129 (define_expand "log10<mode>2"
17130   [(use (match_operand:MODEF 0 "register_operand" ""))
17131    (use (match_operand:MODEF 1 "register_operand" ""))]
17132   "TARGET_USE_FANCY_MATH_387
17133    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17134        || TARGET_MIX_SSE_I387)
17135    && flag_unsafe_math_optimizations"
17137   rtx op0 = gen_reg_rtx (XFmode);
17139   rtx op2 = gen_reg_rtx (XFmode);
17140   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17142   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17143   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17144   DONE;
17147 (define_expand "log2xf2"
17148   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17149                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17150                                (match_dup 2)] UNSPEC_FYL2X))
17151               (clobber (match_scratch:XF 3 ""))])]
17152   "TARGET_USE_FANCY_MATH_387
17153    && flag_unsafe_math_optimizations"
17155   operands[2] = gen_reg_rtx (XFmode);
17156   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17159 (define_expand "log2<mode>2"
17160   [(use (match_operand:MODEF 0 "register_operand" ""))
17161    (use (match_operand:MODEF 1 "register_operand" ""))]
17162   "TARGET_USE_FANCY_MATH_387
17163    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17164        || TARGET_MIX_SSE_I387)
17165    && flag_unsafe_math_optimizations"
17167   rtx op0 = gen_reg_rtx (XFmode);
17169   rtx op2 = gen_reg_rtx (XFmode);
17170   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17172   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17173   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17174   DONE;
17177 (define_insn "fyl2xp1xf3_i387"
17178   [(set (match_operand:XF 0 "register_operand" "=f")
17179         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17180                     (match_operand:XF 2 "register_operand" "u")]
17181                    UNSPEC_FYL2XP1))
17182    (clobber (match_scratch:XF 3 "=2"))]
17183   "TARGET_USE_FANCY_MATH_387
17184    && flag_unsafe_math_optimizations"
17185   "fyl2xp1"
17186   [(set_attr "type" "fpspc")
17187    (set_attr "mode" "XF")])
17189 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17190   [(set (match_operand:XF 0 "register_operand" "=f")
17191         (unspec:XF [(float_extend:XF
17192                       (match_operand:MODEF 1 "register_operand" "0"))
17193                     (match_operand:XF 2 "register_operand" "u")]
17194                    UNSPEC_FYL2XP1))
17195    (clobber (match_scratch:XF 3 "=2"))]
17196   "TARGET_USE_FANCY_MATH_387
17197    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17198        || TARGET_MIX_SSE_I387)
17199    && flag_unsafe_math_optimizations"
17200   "fyl2xp1"
17201   [(set_attr "type" "fpspc")
17202    (set_attr "mode" "XF")])
17204 (define_expand "log1pxf2"
17205   [(use (match_operand:XF 0 "register_operand" ""))
17206    (use (match_operand:XF 1 "register_operand" ""))]
17207   "TARGET_USE_FANCY_MATH_387
17208    && flag_unsafe_math_optimizations && !optimize_size"
17210   ix86_emit_i387_log1p (operands[0], operands[1]);
17211   DONE;
17214 (define_expand "log1p<mode>2"
17215   [(use (match_operand:MODEF 0 "register_operand" ""))
17216    (use (match_operand:MODEF 1 "register_operand" ""))]
17217   "TARGET_USE_FANCY_MATH_387
17218    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17219        || TARGET_MIX_SSE_I387)
17220    && flag_unsafe_math_optimizations && !optimize_size"
17222   rtx op0 = gen_reg_rtx (XFmode);
17224   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17226   ix86_emit_i387_log1p (op0, operands[1]);
17227   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17228   DONE;
17231 (define_insn "fxtractxf3_i387"
17232   [(set (match_operand:XF 0 "register_operand" "=f")
17233         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17234                    UNSPEC_XTRACT_FRACT))
17235    (set (match_operand:XF 1 "register_operand" "=u")
17236         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17237   "TARGET_USE_FANCY_MATH_387
17238    && flag_unsafe_math_optimizations"
17239   "fxtract"
17240   [(set_attr "type" "fpspc")
17241    (set_attr "mode" "XF")])
17243 (define_insn "fxtract_extend<mode>xf3_i387"
17244   [(set (match_operand:XF 0 "register_operand" "=f")
17245         (unspec:XF [(float_extend:XF
17246                       (match_operand:MODEF 2 "register_operand" "0"))]
17247                    UNSPEC_XTRACT_FRACT))
17248    (set (match_operand:XF 1 "register_operand" "=u")
17249         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17250   "TARGET_USE_FANCY_MATH_387
17251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17252        || TARGET_MIX_SSE_I387)
17253    && flag_unsafe_math_optimizations"
17254   "fxtract"
17255   [(set_attr "type" "fpspc")
17256    (set_attr "mode" "XF")])
17258 (define_expand "logbxf2"
17259   [(parallel [(set (match_dup 2)
17260                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17261                               UNSPEC_XTRACT_FRACT))
17262               (set (match_operand:XF 0 "register_operand" "")
17263                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17264   "TARGET_USE_FANCY_MATH_387
17265    && flag_unsafe_math_optimizations"
17267   operands[2] = gen_reg_rtx (XFmode);
17270 (define_expand "logb<mode>2"
17271   [(use (match_operand:MODEF 0 "register_operand" ""))
17272    (use (match_operand:MODEF 1 "register_operand" ""))]
17273   "TARGET_USE_FANCY_MATH_387
17274    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17275        || TARGET_MIX_SSE_I387)
17276    && flag_unsafe_math_optimizations"
17278   rtx op0 = gen_reg_rtx (XFmode);
17279   rtx op1 = gen_reg_rtx (XFmode);
17281   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17282   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17283   DONE;
17286 (define_expand "ilogbxf2"
17287   [(use (match_operand:SI 0 "register_operand" ""))
17288    (use (match_operand:XF 1 "register_operand" ""))]
17289   "TARGET_USE_FANCY_MATH_387
17290    && flag_unsafe_math_optimizations && !optimize_size"
17292   rtx op0 = gen_reg_rtx (XFmode);
17293   rtx op1 = gen_reg_rtx (XFmode);
17295   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17296   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17297   DONE;
17300 (define_expand "ilogb<mode>2"
17301   [(use (match_operand:SI 0 "register_operand" ""))
17302    (use (match_operand:MODEF 1 "register_operand" ""))]
17303   "TARGET_USE_FANCY_MATH_387
17304    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17305        || TARGET_MIX_SSE_I387)
17306    && flag_unsafe_math_optimizations && !optimize_size"
17308   rtx op0 = gen_reg_rtx (XFmode);
17309   rtx op1 = gen_reg_rtx (XFmode);
17311   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17312   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17313   DONE;
17316 (define_insn "*f2xm1xf2_i387"
17317   [(set (match_operand:XF 0 "register_operand" "=f")
17318         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17319                    UNSPEC_F2XM1))]
17320   "TARGET_USE_FANCY_MATH_387
17321    && flag_unsafe_math_optimizations"
17322   "f2xm1"
17323   [(set_attr "type" "fpspc")
17324    (set_attr "mode" "XF")])
17326 (define_insn "*fscalexf4_i387"
17327   [(set (match_operand:XF 0 "register_operand" "=f")
17328         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17329                     (match_operand:XF 3 "register_operand" "1")]
17330                    UNSPEC_FSCALE_FRACT))
17331    (set (match_operand:XF 1 "register_operand" "=u")
17332         (unspec:XF [(match_dup 2) (match_dup 3)]
17333                    UNSPEC_FSCALE_EXP))]
17334   "TARGET_USE_FANCY_MATH_387
17335    && flag_unsafe_math_optimizations"
17336   "fscale"
17337   [(set_attr "type" "fpspc")
17338    (set_attr "mode" "XF")])
17340 (define_expand "expNcorexf3"
17341   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17342                                (match_operand:XF 2 "register_operand" "")))
17343    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17344    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17345    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17346    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17347    (parallel [(set (match_operand:XF 0 "register_operand" "")
17348                    (unspec:XF [(match_dup 8) (match_dup 4)]
17349                               UNSPEC_FSCALE_FRACT))
17350               (set (match_dup 9)
17351                    (unspec:XF [(match_dup 8) (match_dup 4)]
17352                               UNSPEC_FSCALE_EXP))])]
17353   "TARGET_USE_FANCY_MATH_387
17354    && flag_unsafe_math_optimizations && !optimize_size"
17356   int i;
17358   for (i = 3; i < 10; i++)
17359     operands[i] = gen_reg_rtx (XFmode);
17361   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17364 (define_expand "expxf2"
17365   [(use (match_operand:XF 0 "register_operand" ""))
17366    (use (match_operand:XF 1 "register_operand" ""))]
17367   "TARGET_USE_FANCY_MATH_387
17368    && flag_unsafe_math_optimizations && !optimize_size"
17370   rtx op2 = gen_reg_rtx (XFmode);
17371   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17373   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17374   DONE;
17377 (define_expand "exp<mode>2"
17378   [(use (match_operand:MODEF 0 "register_operand" ""))
17379    (use (match_operand:MODEF 1 "general_operand" ""))]
17380  "TARGET_USE_FANCY_MATH_387
17381    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17382        || TARGET_MIX_SSE_I387)
17383    && flag_unsafe_math_optimizations && !optimize_size"
17385   rtx op0 = gen_reg_rtx (XFmode);
17386   rtx op1 = gen_reg_rtx (XFmode);
17388   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17389   emit_insn (gen_expxf2 (op0, op1));
17390   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17391   DONE;
17394 (define_expand "exp10xf2"
17395   [(use (match_operand:XF 0 "register_operand" ""))
17396    (use (match_operand:XF 1 "register_operand" ""))]
17397   "TARGET_USE_FANCY_MATH_387
17398    && flag_unsafe_math_optimizations && !optimize_size"
17400   rtx op2 = gen_reg_rtx (XFmode);
17401   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17403   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17404   DONE;
17407 (define_expand "exp10<mode>2"
17408   [(use (match_operand:MODEF 0 "register_operand" ""))
17409    (use (match_operand:MODEF 1 "general_operand" ""))]
17410  "TARGET_USE_FANCY_MATH_387
17411    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17412        || TARGET_MIX_SSE_I387)
17413    && flag_unsafe_math_optimizations && !optimize_size"
17415   rtx op0 = gen_reg_rtx (XFmode);
17416   rtx op1 = gen_reg_rtx (XFmode);
17418   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17419   emit_insn (gen_exp10xf2 (op0, op1));
17420   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17421   DONE;
17424 (define_expand "exp2xf2"
17425   [(use (match_operand:XF 0 "register_operand" ""))
17426    (use (match_operand:XF 1 "register_operand" ""))]
17427   "TARGET_USE_FANCY_MATH_387
17428    && flag_unsafe_math_optimizations && !optimize_size"
17430   rtx op2 = gen_reg_rtx (XFmode);
17431   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17433   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17434   DONE;
17437 (define_expand "exp2<mode>2"
17438   [(use (match_operand:MODEF 0 "register_operand" ""))
17439    (use (match_operand:MODEF 1 "general_operand" ""))]
17440  "TARGET_USE_FANCY_MATH_387
17441    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17442        || TARGET_MIX_SSE_I387)
17443    && flag_unsafe_math_optimizations && !optimize_size"
17445   rtx op0 = gen_reg_rtx (XFmode);
17446   rtx op1 = gen_reg_rtx (XFmode);
17448   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17449   emit_insn (gen_exp2xf2 (op0, op1));
17450   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17451   DONE;
17454 (define_expand "expm1xf2"
17455   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17456                                (match_dup 2)))
17457    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17458    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17459    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17460    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17461    (parallel [(set (match_dup 7)
17462                    (unspec:XF [(match_dup 6) (match_dup 4)]
17463                               UNSPEC_FSCALE_FRACT))
17464               (set (match_dup 8)
17465                    (unspec:XF [(match_dup 6) (match_dup 4)]
17466                               UNSPEC_FSCALE_EXP))])
17467    (parallel [(set (match_dup 10)
17468                    (unspec:XF [(match_dup 9) (match_dup 8)]
17469                               UNSPEC_FSCALE_FRACT))
17470               (set (match_dup 11)
17471                    (unspec:XF [(match_dup 9) (match_dup 8)]
17472                               UNSPEC_FSCALE_EXP))])
17473    (set (match_dup 12) (minus:XF (match_dup 10)
17474                                  (float_extend:XF (match_dup 13))))
17475    (set (match_operand:XF 0 "register_operand" "")
17476         (plus:XF (match_dup 12) (match_dup 7)))]
17477   "TARGET_USE_FANCY_MATH_387
17478    && flag_unsafe_math_optimizations && !optimize_size"
17480   int i;
17482   for (i = 2; i < 13; i++)
17483     operands[i] = gen_reg_rtx (XFmode);
17485   operands[13]
17486     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17488   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17491 (define_expand "expm1<mode>2"
17492   [(use (match_operand:MODEF 0 "register_operand" ""))
17493    (use (match_operand:MODEF 1 "general_operand" ""))]
17494  "TARGET_USE_FANCY_MATH_387
17495    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17496        || TARGET_MIX_SSE_I387)
17497    && flag_unsafe_math_optimizations && !optimize_size"
17499   rtx op0 = gen_reg_rtx (XFmode);
17500   rtx op1 = gen_reg_rtx (XFmode);
17502   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17503   emit_insn (gen_expm1xf2 (op0, op1));
17504   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17505   DONE;
17508 (define_expand "ldexpxf3"
17509   [(set (match_dup 3)
17510         (float:XF (match_operand:SI 2 "register_operand" "")))
17511    (parallel [(set (match_operand:XF 0 " register_operand" "")
17512                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17513                                (match_dup 3)]
17514                               UNSPEC_FSCALE_FRACT))
17515               (set (match_dup 4)
17516                    (unspec:XF [(match_dup 1) (match_dup 3)]
17517                               UNSPEC_FSCALE_EXP))])]
17518   "TARGET_USE_FANCY_MATH_387
17519    && flag_unsafe_math_optimizations && !optimize_size"
17521   operands[3] = gen_reg_rtx (XFmode);
17522   operands[4] = gen_reg_rtx (XFmode);
17525 (define_expand "ldexp<mode>3"
17526   [(use (match_operand:MODEF 0 "register_operand" ""))
17527    (use (match_operand:MODEF 1 "general_operand" ""))
17528    (use (match_operand:SI 2 "register_operand" ""))]
17529  "TARGET_USE_FANCY_MATH_387
17530    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17531        || TARGET_MIX_SSE_I387)
17532    && flag_unsafe_math_optimizations && !optimize_size"
17534   rtx op0 = gen_reg_rtx (XFmode);
17535   rtx op1 = gen_reg_rtx (XFmode);
17537   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17538   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17539   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17540   DONE;
17543 (define_expand "scalbxf3"
17544   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17545                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17546                                (match_operand:XF 2 "register_operand" "")]
17547                               UNSPEC_FSCALE_FRACT))
17548               (set (match_dup 3)
17549                    (unspec:XF [(match_dup 1) (match_dup 2)]
17550                               UNSPEC_FSCALE_EXP))])]
17551   "TARGET_USE_FANCY_MATH_387
17552    && flag_unsafe_math_optimizations && !optimize_size"
17554   operands[3] = gen_reg_rtx (XFmode);
17557 (define_expand "scalb<mode>3"
17558   [(use (match_operand:MODEF 0 "register_operand" ""))
17559    (use (match_operand:MODEF 1 "general_operand" ""))
17560    (use (match_operand:MODEF 2 "register_operand" ""))]
17561  "TARGET_USE_FANCY_MATH_387
17562    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17563        || TARGET_MIX_SSE_I387)
17564    && flag_unsafe_math_optimizations && !optimize_size"
17566   rtx op0 = gen_reg_rtx (XFmode);
17567   rtx op1 = gen_reg_rtx (XFmode);
17568   rtx op2 = gen_reg_rtx (XFmode);
17570   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17571   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17572   emit_insn (gen_scalbxf3 (op0, op1, op2));
17573   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17574   DONE;
17578 (define_insn "sse4_1_round<mode>2"
17579   [(set (match_operand:MODEF 0 "register_operand" "=x")
17580         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17581                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17582                       UNSPEC_ROUND))]
17583   "TARGET_ROUND"
17584   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17585   [(set_attr "type" "ssecvt")
17586    (set_attr "prefix_extra" "1")
17587    (set_attr "mode" "<MODE>")])
17589 (define_insn "rintxf2"
17590   [(set (match_operand:XF 0 "register_operand" "=f")
17591         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17592                    UNSPEC_FRNDINT))]
17593   "TARGET_USE_FANCY_MATH_387
17594    && flag_unsafe_math_optimizations"
17595   "frndint"
17596   [(set_attr "type" "fpspc")
17597    (set_attr "mode" "XF")])
17599 (define_expand "rint<mode>2"
17600   [(use (match_operand:MODEF 0 "register_operand" ""))
17601    (use (match_operand:MODEF 1 "register_operand" ""))]
17602   "(TARGET_USE_FANCY_MATH_387
17603     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17604         || TARGET_MIX_SSE_I387)
17605     && flag_unsafe_math_optimizations)
17606    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17607        && !flag_trapping_math
17608        && (TARGET_ROUND || !optimize_size))"
17610   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17611       && !flag_trapping_math
17612       && (TARGET_ROUND || !optimize_size))
17613     {
17614       if (TARGET_ROUND)
17615         emit_insn (gen_sse4_1_round<mode>2
17616                    (operands[0], operands[1], GEN_INT (0x04)));
17617       else
17618         ix86_expand_rint (operand0, operand1);
17619     }
17620   else
17621     {
17622       rtx op0 = gen_reg_rtx (XFmode);
17623       rtx op1 = gen_reg_rtx (XFmode);
17625       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17626       emit_insn (gen_rintxf2 (op0, op1));
17628       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17629     }
17630   DONE;
17633 (define_expand "round<mode>2"
17634   [(match_operand:MODEF 0 "register_operand" "")
17635    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17636   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17637    && !flag_trapping_math && !flag_rounding_math
17638    && !optimize_size"
17640   if (TARGET_64BIT || (<MODE>mode != DFmode))
17641     ix86_expand_round (operand0, operand1);
17642   else
17643     ix86_expand_rounddf_32 (operand0, operand1);
17644   DONE;
17647 (define_insn_and_split "*fistdi2_1"
17648   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17649         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17650                    UNSPEC_FIST))]
17651   "TARGET_USE_FANCY_MATH_387
17652    && !(reload_completed || reload_in_progress)"
17653   "#"
17654   "&& 1"
17655   [(const_int 0)]
17657   if (memory_operand (operands[0], VOIDmode))
17658     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17659   else
17660     {
17661       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17662       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17663                                          operands[2]));
17664     }
17665   DONE;
17667   [(set_attr "type" "fpspc")
17668    (set_attr "mode" "DI")])
17670 (define_insn "fistdi2"
17671   [(set (match_operand:DI 0 "memory_operand" "=m")
17672         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17673                    UNSPEC_FIST))
17674    (clobber (match_scratch:XF 2 "=&1f"))]
17675   "TARGET_USE_FANCY_MATH_387"
17676   "* return output_fix_trunc (insn, operands, 0);"
17677   [(set_attr "type" "fpspc")
17678    (set_attr "mode" "DI")])
17680 (define_insn "fistdi2_with_temp"
17681   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17682         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17683                    UNSPEC_FIST))
17684    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17685    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17686   "TARGET_USE_FANCY_MATH_387"
17687   "#"
17688   [(set_attr "type" "fpspc")
17689    (set_attr "mode" "DI")])
17691 (define_split
17692   [(set (match_operand:DI 0 "register_operand" "")
17693         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17694                    UNSPEC_FIST))
17695    (clobber (match_operand:DI 2 "memory_operand" ""))
17696    (clobber (match_scratch 3 ""))]
17697   "reload_completed"
17698   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17699               (clobber (match_dup 3))])
17700    (set (match_dup 0) (match_dup 2))]
17701   "")
17703 (define_split
17704   [(set (match_operand:DI 0 "memory_operand" "")
17705         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17706                    UNSPEC_FIST))
17707    (clobber (match_operand:DI 2 "memory_operand" ""))
17708    (clobber (match_scratch 3 ""))]
17709   "reload_completed"
17710   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17711               (clobber (match_dup 3))])]
17712   "")
17714 (define_insn_and_split "*fist<mode>2_1"
17715   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17716         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17717                            UNSPEC_FIST))]
17718   "TARGET_USE_FANCY_MATH_387
17719    && !(reload_completed || reload_in_progress)"
17720   "#"
17721   "&& 1"
17722   [(const_int 0)]
17724   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17725   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17726                                         operands[2]));
17727   DONE;
17729   [(set_attr "type" "fpspc")
17730    (set_attr "mode" "<MODE>")])
17732 (define_insn "fist<mode>2"
17733   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17734         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17735                            UNSPEC_FIST))]
17736   "TARGET_USE_FANCY_MATH_387"
17737   "* return output_fix_trunc (insn, operands, 0);"
17738   [(set_attr "type" "fpspc")
17739    (set_attr "mode" "<MODE>")])
17741 (define_insn "fist<mode>2_with_temp"
17742   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17743         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17744                            UNSPEC_FIST))
17745    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17746   "TARGET_USE_FANCY_MATH_387"
17747   "#"
17748   [(set_attr "type" "fpspc")
17749    (set_attr "mode" "<MODE>")])
17751 (define_split
17752   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17753         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17754                            UNSPEC_FIST))
17755    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17756   "reload_completed"
17757   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17758    (set (match_dup 0) (match_dup 2))]
17759   "")
17761 (define_split
17762   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17763         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17764                            UNSPEC_FIST))
17765    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17766   "reload_completed"
17767   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17768   "")
17770 (define_expand "lrintxf<mode>2"
17771   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17772      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17773                       UNSPEC_FIST))]
17774   "TARGET_USE_FANCY_MATH_387"
17775   "")
17777 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17778   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17779      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17780                         UNSPEC_FIX_NOTRUNC))]
17781   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17782    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17783   "")
17785 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17786   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17787    (match_operand:MODEF 1 "register_operand" "")]
17788   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17789    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17790    && !flag_trapping_math && !flag_rounding_math
17791    && !optimize_size"
17793   ix86_expand_lround (operand0, operand1);
17794   DONE;
17797 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17798 (define_insn_and_split "frndintxf2_floor"
17799   [(set (match_operand:XF 0 "register_operand" "")
17800         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17801          UNSPEC_FRNDINT_FLOOR))
17802    (clobber (reg:CC FLAGS_REG))]
17803   "TARGET_USE_FANCY_MATH_387
17804    && flag_unsafe_math_optimizations
17805    && !(reload_completed || reload_in_progress)"
17806   "#"
17807   "&& 1"
17808   [(const_int 0)]
17810   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17812   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17813   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17815   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17816                                         operands[2], operands[3]));
17817   DONE;
17819   [(set_attr "type" "frndint")
17820    (set_attr "i387_cw" "floor")
17821    (set_attr "mode" "XF")])
17823 (define_insn "frndintxf2_floor_i387"
17824   [(set (match_operand:XF 0 "register_operand" "=f")
17825         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17826          UNSPEC_FRNDINT_FLOOR))
17827    (use (match_operand:HI 2 "memory_operand" "m"))
17828    (use (match_operand:HI 3 "memory_operand" "m"))]
17829   "TARGET_USE_FANCY_MATH_387
17830    && flag_unsafe_math_optimizations"
17831   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17832   [(set_attr "type" "frndint")
17833    (set_attr "i387_cw" "floor")
17834    (set_attr "mode" "XF")])
17836 (define_expand "floorxf2"
17837   [(use (match_operand:XF 0 "register_operand" ""))
17838    (use (match_operand:XF 1 "register_operand" ""))]
17839   "TARGET_USE_FANCY_MATH_387
17840    && flag_unsafe_math_optimizations && !optimize_size"
17842   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17843   DONE;
17846 (define_expand "floor<mode>2"
17847   [(use (match_operand:MODEF 0 "register_operand" ""))
17848    (use (match_operand:MODEF 1 "register_operand" ""))]
17849   "(TARGET_USE_FANCY_MATH_387
17850     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17851         || TARGET_MIX_SSE_I387)
17852     && flag_unsafe_math_optimizations && !optimize_size)
17853    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17854        && !flag_trapping_math
17855        && (TARGET_ROUND || !optimize_size))"
17857   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17858       && !flag_trapping_math
17859       && (TARGET_ROUND || !optimize_size))
17860     {
17861       if (TARGET_ROUND)
17862         emit_insn (gen_sse4_1_round<mode>2
17863                    (operands[0], operands[1], GEN_INT (0x01)));
17864       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17865         ix86_expand_floorceil (operand0, operand1, true);
17866       else
17867         ix86_expand_floorceildf_32 (operand0, operand1, true);
17868     }
17869   else
17870     {
17871       rtx op0 = gen_reg_rtx (XFmode);
17872       rtx op1 = gen_reg_rtx (XFmode);
17874       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17875       emit_insn (gen_frndintxf2_floor (op0, op1));
17877       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17878     }
17879   DONE;
17882 (define_insn_and_split "*fist<mode>2_floor_1"
17883   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17884         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17885          UNSPEC_FIST_FLOOR))
17886    (clobber (reg:CC FLAGS_REG))]
17887   "TARGET_USE_FANCY_MATH_387
17888    && flag_unsafe_math_optimizations
17889    && !(reload_completed || reload_in_progress)"
17890   "#"
17891   "&& 1"
17892   [(const_int 0)]
17894   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17896   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17897   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17898   if (memory_operand (operands[0], VOIDmode))
17899     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17900                                       operands[2], operands[3]));
17901   else
17902     {
17903       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17904       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17905                                                   operands[2], operands[3],
17906                                                   operands[4]));
17907     }
17908   DONE;
17910   [(set_attr "type" "fistp")
17911    (set_attr "i387_cw" "floor")
17912    (set_attr "mode" "<MODE>")])
17914 (define_insn "fistdi2_floor"
17915   [(set (match_operand:DI 0 "memory_operand" "=m")
17916         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17917          UNSPEC_FIST_FLOOR))
17918    (use (match_operand:HI 2 "memory_operand" "m"))
17919    (use (match_operand:HI 3 "memory_operand" "m"))
17920    (clobber (match_scratch:XF 4 "=&1f"))]
17921   "TARGET_USE_FANCY_MATH_387
17922    && flag_unsafe_math_optimizations"
17923   "* return output_fix_trunc (insn, operands, 0);"
17924   [(set_attr "type" "fistp")
17925    (set_attr "i387_cw" "floor")
17926    (set_attr "mode" "DI")])
17928 (define_insn "fistdi2_floor_with_temp"
17929   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17930         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17931          UNSPEC_FIST_FLOOR))
17932    (use (match_operand:HI 2 "memory_operand" "m,m"))
17933    (use (match_operand:HI 3 "memory_operand" "m,m"))
17934    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17935    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17936   "TARGET_USE_FANCY_MATH_387
17937    && flag_unsafe_math_optimizations"
17938   "#"
17939   [(set_attr "type" "fistp")
17940    (set_attr "i387_cw" "floor")
17941    (set_attr "mode" "DI")])
17943 (define_split
17944   [(set (match_operand:DI 0 "register_operand" "")
17945         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17946          UNSPEC_FIST_FLOOR))
17947    (use (match_operand:HI 2 "memory_operand" ""))
17948    (use (match_operand:HI 3 "memory_operand" ""))
17949    (clobber (match_operand:DI 4 "memory_operand" ""))
17950    (clobber (match_scratch 5 ""))]
17951   "reload_completed"
17952   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17953               (use (match_dup 2))
17954               (use (match_dup 3))
17955               (clobber (match_dup 5))])
17956    (set (match_dup 0) (match_dup 4))]
17957   "")
17959 (define_split
17960   [(set (match_operand:DI 0 "memory_operand" "")
17961         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17962          UNSPEC_FIST_FLOOR))
17963    (use (match_operand:HI 2 "memory_operand" ""))
17964    (use (match_operand:HI 3 "memory_operand" ""))
17965    (clobber (match_operand:DI 4 "memory_operand" ""))
17966    (clobber (match_scratch 5 ""))]
17967   "reload_completed"
17968   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17969               (use (match_dup 2))
17970               (use (match_dup 3))
17971               (clobber (match_dup 5))])]
17972   "")
17974 (define_insn "fist<mode>2_floor"
17975   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17976         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17977          UNSPEC_FIST_FLOOR))
17978    (use (match_operand:HI 2 "memory_operand" "m"))
17979    (use (match_operand:HI 3 "memory_operand" "m"))]
17980   "TARGET_USE_FANCY_MATH_387
17981    && flag_unsafe_math_optimizations"
17982   "* return output_fix_trunc (insn, operands, 0);"
17983   [(set_attr "type" "fistp")
17984    (set_attr "i387_cw" "floor")
17985    (set_attr "mode" "<MODE>")])
17987 (define_insn "fist<mode>2_floor_with_temp"
17988   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17989         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17990          UNSPEC_FIST_FLOOR))
17991    (use (match_operand:HI 2 "memory_operand" "m,m"))
17992    (use (match_operand:HI 3 "memory_operand" "m,m"))
17993    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17994   "TARGET_USE_FANCY_MATH_387
17995    && flag_unsafe_math_optimizations"
17996   "#"
17997   [(set_attr "type" "fistp")
17998    (set_attr "i387_cw" "floor")
17999    (set_attr "mode" "<MODE>")])
18001 (define_split
18002   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18003         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18004          UNSPEC_FIST_FLOOR))
18005    (use (match_operand:HI 2 "memory_operand" ""))
18006    (use (match_operand:HI 3 "memory_operand" ""))
18007    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18008   "reload_completed"
18009   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18010                                   UNSPEC_FIST_FLOOR))
18011               (use (match_dup 2))
18012               (use (match_dup 3))])
18013    (set (match_dup 0) (match_dup 4))]
18014   "")
18016 (define_split
18017   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18018         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18019          UNSPEC_FIST_FLOOR))
18020    (use (match_operand:HI 2 "memory_operand" ""))
18021    (use (match_operand:HI 3 "memory_operand" ""))
18022    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18023   "reload_completed"
18024   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18025                                   UNSPEC_FIST_FLOOR))
18026               (use (match_dup 2))
18027               (use (match_dup 3))])]
18028   "")
18030 (define_expand "lfloorxf<mode>2"
18031   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18032                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18033                     UNSPEC_FIST_FLOOR))
18034               (clobber (reg:CC FLAGS_REG))])]
18035   "TARGET_USE_FANCY_MATH_387
18036    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18037    && flag_unsafe_math_optimizations"
18038   "")
18040 (define_expand "lfloor<mode>di2"
18041   [(match_operand:DI 0 "nonimmediate_operand" "")
18042    (match_operand:MODEF 1 "register_operand" "")]
18043   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18044    && !flag_trapping_math
18045    && !optimize_size"
18047   ix86_expand_lfloorceil (operand0, operand1, true);
18048   DONE;
18051 (define_expand "lfloor<mode>si2"
18052   [(match_operand:SI 0 "nonimmediate_operand" "")
18053    (match_operand:MODEF 1 "register_operand" "")]
18054   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18055    && !flag_trapping_math
18056    && (!optimize_size || !TARGET_64BIT)"
18058   ix86_expand_lfloorceil (operand0, operand1, true);
18059   DONE;
18062 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18063 (define_insn_and_split "frndintxf2_ceil"
18064   [(set (match_operand:XF 0 "register_operand" "")
18065         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18066          UNSPEC_FRNDINT_CEIL))
18067    (clobber (reg:CC FLAGS_REG))]
18068   "TARGET_USE_FANCY_MATH_387
18069    && flag_unsafe_math_optimizations
18070    && !(reload_completed || reload_in_progress)"
18071   "#"
18072   "&& 1"
18073   [(const_int 0)]
18075   ix86_optimize_mode_switching[I387_CEIL] = 1;
18077   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18078   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18080   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18081                                        operands[2], operands[3]));
18082   DONE;
18084   [(set_attr "type" "frndint")
18085    (set_attr "i387_cw" "ceil")
18086    (set_attr "mode" "XF")])
18088 (define_insn "frndintxf2_ceil_i387"
18089   [(set (match_operand:XF 0 "register_operand" "=f")
18090         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18091          UNSPEC_FRNDINT_CEIL))
18092    (use (match_operand:HI 2 "memory_operand" "m"))
18093    (use (match_operand:HI 3 "memory_operand" "m"))]
18094   "TARGET_USE_FANCY_MATH_387
18095    && flag_unsafe_math_optimizations"
18096   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18097   [(set_attr "type" "frndint")
18098    (set_attr "i387_cw" "ceil")
18099    (set_attr "mode" "XF")])
18101 (define_expand "ceilxf2"
18102   [(use (match_operand:XF 0 "register_operand" ""))
18103    (use (match_operand:XF 1 "register_operand" ""))]
18104   "TARGET_USE_FANCY_MATH_387
18105    && flag_unsafe_math_optimizations && !optimize_size"
18107   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18108   DONE;
18111 (define_expand "ceil<mode>2"
18112   [(use (match_operand:MODEF 0 "register_operand" ""))
18113    (use (match_operand:MODEF 1 "register_operand" ""))]
18114   "(TARGET_USE_FANCY_MATH_387
18115     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18116         || TARGET_MIX_SSE_I387)
18117     && flag_unsafe_math_optimizations && !optimize_size)
18118    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18119        && !flag_trapping_math
18120        && (TARGET_ROUND || !optimize_size))"
18122   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18123       && !flag_trapping_math
18124       && (TARGET_ROUND || !optimize_size))
18125     {
18126       if (TARGET_ROUND)
18127         emit_insn (gen_sse4_1_round<mode>2
18128                    (operands[0], operands[1], GEN_INT (0x02)));
18129       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18130         ix86_expand_floorceil (operand0, operand1, false);
18131       else
18132         ix86_expand_floorceildf_32 (operand0, operand1, false);
18133     }
18134   else
18135     {
18136       rtx op0 = gen_reg_rtx (XFmode);
18137       rtx op1 = gen_reg_rtx (XFmode);
18139       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18140       emit_insn (gen_frndintxf2_ceil (op0, op1));
18142       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18143     }
18144   DONE;
18147 (define_insn_and_split "*fist<mode>2_ceil_1"
18148   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18149         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18150          UNSPEC_FIST_CEIL))
18151    (clobber (reg:CC FLAGS_REG))]
18152   "TARGET_USE_FANCY_MATH_387
18153    && flag_unsafe_math_optimizations
18154    && !(reload_completed || reload_in_progress)"
18155   "#"
18156   "&& 1"
18157   [(const_int 0)]
18159   ix86_optimize_mode_switching[I387_CEIL] = 1;
18161   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18162   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18163   if (memory_operand (operands[0], VOIDmode))
18164     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18165                                      operands[2], operands[3]));
18166   else
18167     {
18168       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18169       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18170                                                  operands[2], operands[3],
18171                                                  operands[4]));
18172     }
18173   DONE;
18175   [(set_attr "type" "fistp")
18176    (set_attr "i387_cw" "ceil")
18177    (set_attr "mode" "<MODE>")])
18179 (define_insn "fistdi2_ceil"
18180   [(set (match_operand:DI 0 "memory_operand" "=m")
18181         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18182          UNSPEC_FIST_CEIL))
18183    (use (match_operand:HI 2 "memory_operand" "m"))
18184    (use (match_operand:HI 3 "memory_operand" "m"))
18185    (clobber (match_scratch:XF 4 "=&1f"))]
18186   "TARGET_USE_FANCY_MATH_387
18187    && flag_unsafe_math_optimizations"
18188   "* return output_fix_trunc (insn, operands, 0);"
18189   [(set_attr "type" "fistp")
18190    (set_attr "i387_cw" "ceil")
18191    (set_attr "mode" "DI")])
18193 (define_insn "fistdi2_ceil_with_temp"
18194   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18195         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18196          UNSPEC_FIST_CEIL))
18197    (use (match_operand:HI 2 "memory_operand" "m,m"))
18198    (use (match_operand:HI 3 "memory_operand" "m,m"))
18199    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18200    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18201   "TARGET_USE_FANCY_MATH_387
18202    && flag_unsafe_math_optimizations"
18203   "#"
18204   [(set_attr "type" "fistp")
18205    (set_attr "i387_cw" "ceil")
18206    (set_attr "mode" "DI")])
18208 (define_split
18209   [(set (match_operand:DI 0 "register_operand" "")
18210         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18211          UNSPEC_FIST_CEIL))
18212    (use (match_operand:HI 2 "memory_operand" ""))
18213    (use (match_operand:HI 3 "memory_operand" ""))
18214    (clobber (match_operand:DI 4 "memory_operand" ""))
18215    (clobber (match_scratch 5 ""))]
18216   "reload_completed"
18217   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18218               (use (match_dup 2))
18219               (use (match_dup 3))
18220               (clobber (match_dup 5))])
18221    (set (match_dup 0) (match_dup 4))]
18222   "")
18224 (define_split
18225   [(set (match_operand:DI 0 "memory_operand" "")
18226         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18227          UNSPEC_FIST_CEIL))
18228    (use (match_operand:HI 2 "memory_operand" ""))
18229    (use (match_operand:HI 3 "memory_operand" ""))
18230    (clobber (match_operand:DI 4 "memory_operand" ""))
18231    (clobber (match_scratch 5 ""))]
18232   "reload_completed"
18233   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18234               (use (match_dup 2))
18235               (use (match_dup 3))
18236               (clobber (match_dup 5))])]
18237   "")
18239 (define_insn "fist<mode>2_ceil"
18240   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18241         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18242          UNSPEC_FIST_CEIL))
18243    (use (match_operand:HI 2 "memory_operand" "m"))
18244    (use (match_operand:HI 3 "memory_operand" "m"))]
18245   "TARGET_USE_FANCY_MATH_387
18246    && flag_unsafe_math_optimizations"
18247   "* return output_fix_trunc (insn, operands, 0);"
18248   [(set_attr "type" "fistp")
18249    (set_attr "i387_cw" "ceil")
18250    (set_attr "mode" "<MODE>")])
18252 (define_insn "fist<mode>2_ceil_with_temp"
18253   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18254         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18255          UNSPEC_FIST_CEIL))
18256    (use (match_operand:HI 2 "memory_operand" "m,m"))
18257    (use (match_operand:HI 3 "memory_operand" "m,m"))
18258    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18259   "TARGET_USE_FANCY_MATH_387
18260    && flag_unsafe_math_optimizations"
18261   "#"
18262   [(set_attr "type" "fistp")
18263    (set_attr "i387_cw" "ceil")
18264    (set_attr "mode" "<MODE>")])
18266 (define_split
18267   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18268         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18269          UNSPEC_FIST_CEIL))
18270    (use (match_operand:HI 2 "memory_operand" ""))
18271    (use (match_operand:HI 3 "memory_operand" ""))
18272    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18273   "reload_completed"
18274   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18275                                   UNSPEC_FIST_CEIL))
18276               (use (match_dup 2))
18277               (use (match_dup 3))])
18278    (set (match_dup 0) (match_dup 4))]
18279   "")
18281 (define_split
18282   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18283         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18284          UNSPEC_FIST_CEIL))
18285    (use (match_operand:HI 2 "memory_operand" ""))
18286    (use (match_operand:HI 3 "memory_operand" ""))
18287    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18288   "reload_completed"
18289   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18290                                   UNSPEC_FIST_CEIL))
18291               (use (match_dup 2))
18292               (use (match_dup 3))])]
18293   "")
18295 (define_expand "lceilxf<mode>2"
18296   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18297                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18298                     UNSPEC_FIST_CEIL))
18299               (clobber (reg:CC FLAGS_REG))])]
18300   "TARGET_USE_FANCY_MATH_387
18301    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18302    && flag_unsafe_math_optimizations"
18303   "")
18305 (define_expand "lceil<mode>di2"
18306   [(match_operand:DI 0 "nonimmediate_operand" "")
18307    (match_operand:MODEF 1 "register_operand" "")]
18308   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18309    && !flag_trapping_math"
18311   ix86_expand_lfloorceil (operand0, operand1, false);
18312   DONE;
18315 (define_expand "lceil<mode>si2"
18316   [(match_operand:SI 0 "nonimmediate_operand" "")
18317    (match_operand:MODEF 1 "register_operand" "")]
18318   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18319    && !flag_trapping_math"
18321   ix86_expand_lfloorceil (operand0, operand1, false);
18322   DONE;
18325 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18326 (define_insn_and_split "frndintxf2_trunc"
18327   [(set (match_operand:XF 0 "register_operand" "")
18328         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18329          UNSPEC_FRNDINT_TRUNC))
18330    (clobber (reg:CC FLAGS_REG))]
18331   "TARGET_USE_FANCY_MATH_387
18332    && flag_unsafe_math_optimizations
18333    && !(reload_completed || reload_in_progress)"
18334   "#"
18335   "&& 1"
18336   [(const_int 0)]
18338   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18340   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18341   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18343   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18344                                         operands[2], operands[3]));
18345   DONE;
18347   [(set_attr "type" "frndint")
18348    (set_attr "i387_cw" "trunc")
18349    (set_attr "mode" "XF")])
18351 (define_insn "frndintxf2_trunc_i387"
18352   [(set (match_operand:XF 0 "register_operand" "=f")
18353         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18354          UNSPEC_FRNDINT_TRUNC))
18355    (use (match_operand:HI 2 "memory_operand" "m"))
18356    (use (match_operand:HI 3 "memory_operand" "m"))]
18357   "TARGET_USE_FANCY_MATH_387
18358    && flag_unsafe_math_optimizations"
18359   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18360   [(set_attr "type" "frndint")
18361    (set_attr "i387_cw" "trunc")
18362    (set_attr "mode" "XF")])
18364 (define_expand "btruncxf2"
18365   [(use (match_operand:XF 0 "register_operand" ""))
18366    (use (match_operand:XF 1 "register_operand" ""))]
18367   "TARGET_USE_FANCY_MATH_387
18368    && flag_unsafe_math_optimizations && !optimize_size"
18370   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18371   DONE;
18374 (define_expand "btrunc<mode>2"
18375   [(use (match_operand:MODEF 0 "register_operand" ""))
18376    (use (match_operand:MODEF 1 "register_operand" ""))]
18377   "(TARGET_USE_FANCY_MATH_387
18378     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18379         || TARGET_MIX_SSE_I387)
18380     && flag_unsafe_math_optimizations && !optimize_size)
18381    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18382        && !flag_trapping_math
18383        && (TARGET_ROUND || !optimize_size))"
18385   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18386       && !flag_trapping_math
18387       && (TARGET_ROUND || !optimize_size))
18388     {
18389       if (TARGET_ROUND)
18390         emit_insn (gen_sse4_1_round<mode>2
18391                    (operands[0], operands[1], GEN_INT (0x03)));
18392       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18393         ix86_expand_trunc (operand0, operand1);
18394       else
18395         ix86_expand_truncdf_32 (operand0, operand1);
18396     }
18397   else
18398     {
18399       rtx op0 = gen_reg_rtx (XFmode);
18400       rtx op1 = gen_reg_rtx (XFmode);
18402       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18403       emit_insn (gen_frndintxf2_trunc (op0, op1));
18405       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18406     }
18407   DONE;
18410 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18411 (define_insn_and_split "frndintxf2_mask_pm"
18412   [(set (match_operand:XF 0 "register_operand" "")
18413         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18414          UNSPEC_FRNDINT_MASK_PM))
18415    (clobber (reg:CC FLAGS_REG))]
18416   "TARGET_USE_FANCY_MATH_387
18417    && flag_unsafe_math_optimizations
18418    && !(reload_completed || reload_in_progress)"
18419   "#"
18420   "&& 1"
18421   [(const_int 0)]
18423   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18425   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18426   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18428   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18429                                           operands[2], operands[3]));
18430   DONE;
18432   [(set_attr "type" "frndint")
18433    (set_attr "i387_cw" "mask_pm")
18434    (set_attr "mode" "XF")])
18436 (define_insn "frndintxf2_mask_pm_i387"
18437   [(set (match_operand:XF 0 "register_operand" "=f")
18438         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18439          UNSPEC_FRNDINT_MASK_PM))
18440    (use (match_operand:HI 2 "memory_operand" "m"))
18441    (use (match_operand:HI 3 "memory_operand" "m"))]
18442   "TARGET_USE_FANCY_MATH_387
18443    && flag_unsafe_math_optimizations"
18444   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18445   [(set_attr "type" "frndint")
18446    (set_attr "i387_cw" "mask_pm")
18447    (set_attr "mode" "XF")])
18449 (define_expand "nearbyintxf2"
18450   [(use (match_operand:XF 0 "register_operand" ""))
18451    (use (match_operand:XF 1 "register_operand" ""))]
18452   "TARGET_USE_FANCY_MATH_387
18453    && flag_unsafe_math_optimizations"
18455   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18457   DONE;
18460 (define_expand "nearbyint<mode>2"
18461   [(use (match_operand:MODEF 0 "register_operand" ""))
18462    (use (match_operand:MODEF 1 "register_operand" ""))]
18463   "TARGET_USE_FANCY_MATH_387
18464    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18465        || TARGET_MIX_SSE_I387)
18466    && flag_unsafe_math_optimizations"
18468   rtx op0 = gen_reg_rtx (XFmode);
18469   rtx op1 = gen_reg_rtx (XFmode);
18471   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18472   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18474   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18475   DONE;
18478 (define_insn "fxam<mode>2_i387"
18479   [(set (match_operand:HI 0 "register_operand" "=a")
18480         (unspec:HI
18481           [(match_operand:X87MODEF 1 "register_operand" "f")]
18482           UNSPEC_FXAM))]
18483   "TARGET_USE_FANCY_MATH_387"
18484   "fxam\n\tfnstsw\t%0"
18485   [(set_attr "type" "multi")
18486    (set_attr "unit" "i387")
18487    (set_attr "mode" "<MODE>")])
18489 (define_expand "isinf<mode>2"
18490   [(use (match_operand:SI 0 "register_operand" ""))
18491    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18492   "TARGET_USE_FANCY_MATH_387
18493    && TARGET_C99_FUNCTIONS
18494    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18496   rtx mask = GEN_INT (0x45);
18497   rtx val = GEN_INT (0x05);
18499   rtx cond;
18501   rtx scratch = gen_reg_rtx (HImode);
18502   rtx res = gen_reg_rtx (QImode);
18504   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18505   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18506   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18507   cond = gen_rtx_fmt_ee (EQ, QImode,
18508                          gen_rtx_REG (CCmode, FLAGS_REG),
18509                          const0_rtx);
18510   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18511   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18512   DONE;
18515 (define_expand "signbit<mode>2"
18516   [(use (match_operand:SI 0 "register_operand" ""))
18517    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18518   "TARGET_USE_FANCY_MATH_387
18519    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18521   rtx mask = GEN_INT (0x0200);
18523   rtx scratch = gen_reg_rtx (HImode);
18525   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18526   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18527   DONE;
18530 ;; Block operation instructions
18532 (define_expand "movmemsi"
18533   [(use (match_operand:BLK 0 "memory_operand" ""))
18534    (use (match_operand:BLK 1 "memory_operand" ""))
18535    (use (match_operand:SI 2 "nonmemory_operand" ""))
18536    (use (match_operand:SI 3 "const_int_operand" ""))
18537    (use (match_operand:SI 4 "const_int_operand" ""))
18538    (use (match_operand:SI 5 "const_int_operand" ""))]
18539   ""
18541  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18542                          operands[4], operands[5]))
18543    DONE;
18544  else
18545    FAIL;
18548 (define_expand "movmemdi"
18549   [(use (match_operand:BLK 0 "memory_operand" ""))
18550    (use (match_operand:BLK 1 "memory_operand" ""))
18551    (use (match_operand:DI 2 "nonmemory_operand" ""))
18552    (use (match_operand:DI 3 "const_int_operand" ""))
18553    (use (match_operand:SI 4 "const_int_operand" ""))
18554    (use (match_operand:SI 5 "const_int_operand" ""))]
18555   "TARGET_64BIT"
18557  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18558                          operands[4], operands[5]))
18559    DONE;
18560  else
18561    FAIL;
18564 ;; Most CPUs don't like single string operations
18565 ;; Handle this case here to simplify previous expander.
18567 (define_expand "strmov"
18568   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18569    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18570    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18571               (clobber (reg:CC FLAGS_REG))])
18572    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18573               (clobber (reg:CC FLAGS_REG))])]
18574   ""
18576   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18578   /* If .md ever supports :P for Pmode, these can be directly
18579      in the pattern above.  */
18580   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18581   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18583   /* Can't use this if the user has appropriated esi or edi.  */
18584   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18585       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18586     {
18587       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18588                                       operands[2], operands[3],
18589                                       operands[5], operands[6]));
18590       DONE;
18591     }
18593   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18596 (define_expand "strmov_singleop"
18597   [(parallel [(set (match_operand 1 "memory_operand" "")
18598                    (match_operand 3 "memory_operand" ""))
18599               (set (match_operand 0 "register_operand" "")
18600                    (match_operand 4 "" ""))
18601               (set (match_operand 2 "register_operand" "")
18602                    (match_operand 5 "" ""))])]
18603   "TARGET_SINGLE_STRINGOP || optimize_size"
18604   "")
18606 (define_insn "*strmovdi_rex_1"
18607   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18608         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18609    (set (match_operand:DI 0 "register_operand" "=D")
18610         (plus:DI (match_dup 2)
18611                  (const_int 8)))
18612    (set (match_operand:DI 1 "register_operand" "=S")
18613         (plus:DI (match_dup 3)
18614                  (const_int 8)))]
18615   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18616   "movsq"
18617   [(set_attr "type" "str")
18618    (set_attr "mode" "DI")
18619    (set_attr "memory" "both")])
18621 (define_insn "*strmovsi_1"
18622   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18623         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18624    (set (match_operand:SI 0 "register_operand" "=D")
18625         (plus:SI (match_dup 2)
18626                  (const_int 4)))
18627    (set (match_operand:SI 1 "register_operand" "=S")
18628         (plus:SI (match_dup 3)
18629                  (const_int 4)))]
18630   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18631   "{movsl|movsd}"
18632   [(set_attr "type" "str")
18633    (set_attr "mode" "SI")
18634    (set_attr "memory" "both")])
18636 (define_insn "*strmovsi_rex_1"
18637   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18638         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18639    (set (match_operand:DI 0 "register_operand" "=D")
18640         (plus:DI (match_dup 2)
18641                  (const_int 4)))
18642    (set (match_operand:DI 1 "register_operand" "=S")
18643         (plus:DI (match_dup 3)
18644                  (const_int 4)))]
18645   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18646   "{movsl|movsd}"
18647   [(set_attr "type" "str")
18648    (set_attr "mode" "SI")
18649    (set_attr "memory" "both")])
18651 (define_insn "*strmovhi_1"
18652   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18653         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18654    (set (match_operand:SI 0 "register_operand" "=D")
18655         (plus:SI (match_dup 2)
18656                  (const_int 2)))
18657    (set (match_operand:SI 1 "register_operand" "=S")
18658         (plus:SI (match_dup 3)
18659                  (const_int 2)))]
18660   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18661   "movsw"
18662   [(set_attr "type" "str")
18663    (set_attr "memory" "both")
18664    (set_attr "mode" "HI")])
18666 (define_insn "*strmovhi_rex_1"
18667   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18668         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18669    (set (match_operand:DI 0 "register_operand" "=D")
18670         (plus:DI (match_dup 2)
18671                  (const_int 2)))
18672    (set (match_operand:DI 1 "register_operand" "=S")
18673         (plus:DI (match_dup 3)
18674                  (const_int 2)))]
18675   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18676   "movsw"
18677   [(set_attr "type" "str")
18678    (set_attr "memory" "both")
18679    (set_attr "mode" "HI")])
18681 (define_insn "*strmovqi_1"
18682   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18683         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18684    (set (match_operand:SI 0 "register_operand" "=D")
18685         (plus:SI (match_dup 2)
18686                  (const_int 1)))
18687    (set (match_operand:SI 1 "register_operand" "=S")
18688         (plus:SI (match_dup 3)
18689                  (const_int 1)))]
18690   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18691   "movsb"
18692   [(set_attr "type" "str")
18693    (set_attr "memory" "both")
18694    (set_attr "mode" "QI")])
18696 (define_insn "*strmovqi_rex_1"
18697   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18698         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18699    (set (match_operand:DI 0 "register_operand" "=D")
18700         (plus:DI (match_dup 2)
18701                  (const_int 1)))
18702    (set (match_operand:DI 1 "register_operand" "=S")
18703         (plus:DI (match_dup 3)
18704                  (const_int 1)))]
18705   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18706   "movsb"
18707   [(set_attr "type" "str")
18708    (set_attr "memory" "both")
18709    (set_attr "mode" "QI")])
18711 (define_expand "rep_mov"
18712   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18713               (set (match_operand 0 "register_operand" "")
18714                    (match_operand 5 "" ""))
18715               (set (match_operand 2 "register_operand" "")
18716                    (match_operand 6 "" ""))
18717               (set (match_operand 1 "memory_operand" "")
18718                    (match_operand 3 "memory_operand" ""))
18719               (use (match_dup 4))])]
18720   ""
18721   "")
18723 (define_insn "*rep_movdi_rex64"
18724   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18725    (set (match_operand:DI 0 "register_operand" "=D")
18726         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18727                             (const_int 3))
18728                  (match_operand:DI 3 "register_operand" "0")))
18729    (set (match_operand:DI 1 "register_operand" "=S")
18730         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18731                  (match_operand:DI 4 "register_operand" "1")))
18732    (set (mem:BLK (match_dup 3))
18733         (mem:BLK (match_dup 4)))
18734    (use (match_dup 5))]
18735   "TARGET_64BIT"
18736   "rep movsq"
18737   [(set_attr "type" "str")
18738    (set_attr "prefix_rep" "1")
18739    (set_attr "memory" "both")
18740    (set_attr "mode" "DI")])
18742 (define_insn "*rep_movsi"
18743   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18744    (set (match_operand:SI 0 "register_operand" "=D")
18745         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18746                             (const_int 2))
18747                  (match_operand:SI 3 "register_operand" "0")))
18748    (set (match_operand:SI 1 "register_operand" "=S")
18749         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18750                  (match_operand:SI 4 "register_operand" "1")))
18751    (set (mem:BLK (match_dup 3))
18752         (mem:BLK (match_dup 4)))
18753    (use (match_dup 5))]
18754   "!TARGET_64BIT"
18755   "rep movs{l|d}"
18756   [(set_attr "type" "str")
18757    (set_attr "prefix_rep" "1")
18758    (set_attr "memory" "both")
18759    (set_attr "mode" "SI")])
18761 (define_insn "*rep_movsi_rex64"
18762   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18763    (set (match_operand:DI 0 "register_operand" "=D")
18764         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18765                             (const_int 2))
18766                  (match_operand:DI 3 "register_operand" "0")))
18767    (set (match_operand:DI 1 "register_operand" "=S")
18768         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18769                  (match_operand:DI 4 "register_operand" "1")))
18770    (set (mem:BLK (match_dup 3))
18771         (mem:BLK (match_dup 4)))
18772    (use (match_dup 5))]
18773   "TARGET_64BIT"
18774   "rep movs{l|d}"
18775   [(set_attr "type" "str")
18776    (set_attr "prefix_rep" "1")
18777    (set_attr "memory" "both")
18778    (set_attr "mode" "SI")])
18780 (define_insn "*rep_movqi"
18781   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18782    (set (match_operand:SI 0 "register_operand" "=D")
18783         (plus:SI (match_operand:SI 3 "register_operand" "0")
18784                  (match_operand:SI 5 "register_operand" "2")))
18785    (set (match_operand:SI 1 "register_operand" "=S")
18786         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18787    (set (mem:BLK (match_dup 3))
18788         (mem:BLK (match_dup 4)))
18789    (use (match_dup 5))]
18790   "!TARGET_64BIT"
18791   "rep movsb"
18792   [(set_attr "type" "str")
18793    (set_attr "prefix_rep" "1")
18794    (set_attr "memory" "both")
18795    (set_attr "mode" "SI")])
18797 (define_insn "*rep_movqi_rex64"
18798   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18799    (set (match_operand:DI 0 "register_operand" "=D")
18800         (plus:DI (match_operand:DI 3 "register_operand" "0")
18801                  (match_operand:DI 5 "register_operand" "2")))
18802    (set (match_operand:DI 1 "register_operand" "=S")
18803         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18804    (set (mem:BLK (match_dup 3))
18805         (mem:BLK (match_dup 4)))
18806    (use (match_dup 5))]
18807   "TARGET_64BIT"
18808   "rep movsb"
18809   [(set_attr "type" "str")
18810    (set_attr "prefix_rep" "1")
18811    (set_attr "memory" "both")
18812    (set_attr "mode" "SI")])
18814 (define_expand "setmemsi"
18815    [(use (match_operand:BLK 0 "memory_operand" ""))
18816     (use (match_operand:SI 1 "nonmemory_operand" ""))
18817     (use (match_operand 2 "const_int_operand" ""))
18818     (use (match_operand 3 "const_int_operand" ""))
18819     (use (match_operand:SI 4 "const_int_operand" ""))
18820     (use (match_operand:SI 5 "const_int_operand" ""))]
18821   ""
18823  if (ix86_expand_setmem (operands[0], operands[1],
18824                          operands[2], operands[3],
18825                          operands[4], operands[5]))
18826    DONE;
18827  else
18828    FAIL;
18831 (define_expand "setmemdi"
18832    [(use (match_operand:BLK 0 "memory_operand" ""))
18833     (use (match_operand:DI 1 "nonmemory_operand" ""))
18834     (use (match_operand 2 "const_int_operand" ""))
18835     (use (match_operand 3 "const_int_operand" ""))
18836     (use (match_operand 4 "const_int_operand" ""))
18837     (use (match_operand 5 "const_int_operand" ""))]
18838   "TARGET_64BIT"
18840  if (ix86_expand_setmem (operands[0], operands[1],
18841                          operands[2], operands[3],
18842                          operands[4], operands[5]))
18843    DONE;
18844  else
18845    FAIL;
18848 ;; Most CPUs don't like single string operations
18849 ;; Handle this case here to simplify previous expander.
18851 (define_expand "strset"
18852   [(set (match_operand 1 "memory_operand" "")
18853         (match_operand 2 "register_operand" ""))
18854    (parallel [(set (match_operand 0 "register_operand" "")
18855                    (match_dup 3))
18856               (clobber (reg:CC FLAGS_REG))])]
18857   ""
18859   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18860     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18862   /* If .md ever supports :P for Pmode, this can be directly
18863      in the pattern above.  */
18864   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18865                               GEN_INT (GET_MODE_SIZE (GET_MODE
18866                                                       (operands[2]))));
18867   if (TARGET_SINGLE_STRINGOP || optimize_size)
18868     {
18869       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18870                                       operands[3]));
18871       DONE;
18872     }
18875 (define_expand "strset_singleop"
18876   [(parallel [(set (match_operand 1 "memory_operand" "")
18877                    (match_operand 2 "register_operand" ""))
18878               (set (match_operand 0 "register_operand" "")
18879                    (match_operand 3 "" ""))])]
18880   "TARGET_SINGLE_STRINGOP || optimize_size"
18881   "")
18883 (define_insn "*strsetdi_rex_1"
18884   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18885         (match_operand:DI 2 "register_operand" "a"))
18886    (set (match_operand:DI 0 "register_operand" "=D")
18887         (plus:DI (match_dup 1)
18888                  (const_int 8)))]
18889   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18890   "stosq"
18891   [(set_attr "type" "str")
18892    (set_attr "memory" "store")
18893    (set_attr "mode" "DI")])
18895 (define_insn "*strsetsi_1"
18896   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18897         (match_operand:SI 2 "register_operand" "a"))
18898    (set (match_operand:SI 0 "register_operand" "=D")
18899         (plus:SI (match_dup 1)
18900                  (const_int 4)))]
18901   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18902   "{stosl|stosd}"
18903   [(set_attr "type" "str")
18904    (set_attr "memory" "store")
18905    (set_attr "mode" "SI")])
18907 (define_insn "*strsetsi_rex_1"
18908   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18909         (match_operand:SI 2 "register_operand" "a"))
18910    (set (match_operand:DI 0 "register_operand" "=D")
18911         (plus:DI (match_dup 1)
18912                  (const_int 4)))]
18913   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18914   "{stosl|stosd}"
18915   [(set_attr "type" "str")
18916    (set_attr "memory" "store")
18917    (set_attr "mode" "SI")])
18919 (define_insn "*strsethi_1"
18920   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18921         (match_operand:HI 2 "register_operand" "a"))
18922    (set (match_operand:SI 0 "register_operand" "=D")
18923         (plus:SI (match_dup 1)
18924                  (const_int 2)))]
18925   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18926   "stosw"
18927   [(set_attr "type" "str")
18928    (set_attr "memory" "store")
18929    (set_attr "mode" "HI")])
18931 (define_insn "*strsethi_rex_1"
18932   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18933         (match_operand:HI 2 "register_operand" "a"))
18934    (set (match_operand:DI 0 "register_operand" "=D")
18935         (plus:DI (match_dup 1)
18936                  (const_int 2)))]
18937   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18938   "stosw"
18939   [(set_attr "type" "str")
18940    (set_attr "memory" "store")
18941    (set_attr "mode" "HI")])
18943 (define_insn "*strsetqi_1"
18944   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18945         (match_operand:QI 2 "register_operand" "a"))
18946    (set (match_operand:SI 0 "register_operand" "=D")
18947         (plus:SI (match_dup 1)
18948                  (const_int 1)))]
18949   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18950   "stosb"
18951   [(set_attr "type" "str")
18952    (set_attr "memory" "store")
18953    (set_attr "mode" "QI")])
18955 (define_insn "*strsetqi_rex_1"
18956   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18957         (match_operand:QI 2 "register_operand" "a"))
18958    (set (match_operand:DI 0 "register_operand" "=D")
18959         (plus:DI (match_dup 1)
18960                  (const_int 1)))]
18961   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18962   "stosb"
18963   [(set_attr "type" "str")
18964    (set_attr "memory" "store")
18965    (set_attr "mode" "QI")])
18967 (define_expand "rep_stos"
18968   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18969               (set (match_operand 0 "register_operand" "")
18970                    (match_operand 4 "" ""))
18971               (set (match_operand 2 "memory_operand" "") (const_int 0))
18972               (use (match_operand 3 "register_operand" ""))
18973               (use (match_dup 1))])]
18974   ""
18975   "")
18977 (define_insn "*rep_stosdi_rex64"
18978   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18979    (set (match_operand:DI 0 "register_operand" "=D")
18980         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18981                             (const_int 3))
18982                  (match_operand:DI 3 "register_operand" "0")))
18983    (set (mem:BLK (match_dup 3))
18984         (const_int 0))
18985    (use (match_operand:DI 2 "register_operand" "a"))
18986    (use (match_dup 4))]
18987   "TARGET_64BIT"
18988   "rep stosq"
18989   [(set_attr "type" "str")
18990    (set_attr "prefix_rep" "1")
18991    (set_attr "memory" "store")
18992    (set_attr "mode" "DI")])
18994 (define_insn "*rep_stossi"
18995   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18996    (set (match_operand:SI 0 "register_operand" "=D")
18997         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18998                             (const_int 2))
18999                  (match_operand:SI 3 "register_operand" "0")))
19000    (set (mem:BLK (match_dup 3))
19001         (const_int 0))
19002    (use (match_operand:SI 2 "register_operand" "a"))
19003    (use (match_dup 4))]
19004   "!TARGET_64BIT"
19005   "rep stos{l|d}"
19006   [(set_attr "type" "str")
19007    (set_attr "prefix_rep" "1")
19008    (set_attr "memory" "store")
19009    (set_attr "mode" "SI")])
19011 (define_insn "*rep_stossi_rex64"
19012   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19013    (set (match_operand:DI 0 "register_operand" "=D")
19014         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19015                             (const_int 2))
19016                  (match_operand:DI 3 "register_operand" "0")))
19017    (set (mem:BLK (match_dup 3))
19018         (const_int 0))
19019    (use (match_operand:SI 2 "register_operand" "a"))
19020    (use (match_dup 4))]
19021   "TARGET_64BIT"
19022   "rep stos{l|d}"
19023   [(set_attr "type" "str")
19024    (set_attr "prefix_rep" "1")
19025    (set_attr "memory" "store")
19026    (set_attr "mode" "SI")])
19028 (define_insn "*rep_stosqi"
19029   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19030    (set (match_operand:SI 0 "register_operand" "=D")
19031         (plus:SI (match_operand:SI 3 "register_operand" "0")
19032                  (match_operand:SI 4 "register_operand" "1")))
19033    (set (mem:BLK (match_dup 3))
19034         (const_int 0))
19035    (use (match_operand:QI 2 "register_operand" "a"))
19036    (use (match_dup 4))]
19037   "!TARGET_64BIT"
19038   "rep stosb"
19039   [(set_attr "type" "str")
19040    (set_attr "prefix_rep" "1")
19041    (set_attr "memory" "store")
19042    (set_attr "mode" "QI")])
19044 (define_insn "*rep_stosqi_rex64"
19045   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19046    (set (match_operand:DI 0 "register_operand" "=D")
19047         (plus:DI (match_operand:DI 3 "register_operand" "0")
19048                  (match_operand:DI 4 "register_operand" "1")))
19049    (set (mem:BLK (match_dup 3))
19050         (const_int 0))
19051    (use (match_operand:QI 2 "register_operand" "a"))
19052    (use (match_dup 4))]
19053   "TARGET_64BIT"
19054   "rep stosb"
19055   [(set_attr "type" "str")
19056    (set_attr "prefix_rep" "1")
19057    (set_attr "memory" "store")
19058    (set_attr "mode" "QI")])
19060 (define_expand "cmpstrnsi"
19061   [(set (match_operand:SI 0 "register_operand" "")
19062         (compare:SI (match_operand:BLK 1 "general_operand" "")
19063                     (match_operand:BLK 2 "general_operand" "")))
19064    (use (match_operand 3 "general_operand" ""))
19065    (use (match_operand 4 "immediate_operand" ""))]
19066   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19068   rtx addr1, addr2, out, outlow, count, countreg, align;
19070   /* Can't use this if the user has appropriated esi or edi.  */
19071   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19072     FAIL;
19074   out = operands[0];
19075   if (!REG_P (out))
19076     out = gen_reg_rtx (SImode);
19078   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19079   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19080   if (addr1 != XEXP (operands[1], 0))
19081     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19082   if (addr2 != XEXP (operands[2], 0))
19083     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19085   count = operands[3];
19086   countreg = ix86_zero_extend_to_Pmode (count);
19088   /* %%% Iff we are testing strict equality, we can use known alignment
19089      to good advantage.  This may be possible with combine, particularly
19090      once cc0 is dead.  */
19091   align = operands[4];
19093   if (CONST_INT_P (count))
19094     {
19095       if (INTVAL (count) == 0)
19096         {
19097           emit_move_insn (operands[0], const0_rtx);
19098           DONE;
19099         }
19100       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19101                                      operands[1], operands[2]));
19102     }
19103   else
19104     {
19105       if (TARGET_64BIT)
19106         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19107       else
19108         emit_insn (gen_cmpsi_1 (countreg, countreg));
19109       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19110                                   operands[1], operands[2]));
19111     }
19113   outlow = gen_lowpart (QImode, out);
19114   emit_insn (gen_cmpintqi (outlow));
19115   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19117   if (operands[0] != out)
19118     emit_move_insn (operands[0], out);
19120   DONE;
19123 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19125 (define_expand "cmpintqi"
19126   [(set (match_dup 1)
19127         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19128    (set (match_dup 2)
19129         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19130    (parallel [(set (match_operand:QI 0 "register_operand" "")
19131                    (minus:QI (match_dup 1)
19132                              (match_dup 2)))
19133               (clobber (reg:CC FLAGS_REG))])]
19134   ""
19135   "operands[1] = gen_reg_rtx (QImode);
19136    operands[2] = gen_reg_rtx (QImode);")
19138 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19139 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19141 (define_expand "cmpstrnqi_nz_1"
19142   [(parallel [(set (reg:CC FLAGS_REG)
19143                    (compare:CC (match_operand 4 "memory_operand" "")
19144                                (match_operand 5 "memory_operand" "")))
19145               (use (match_operand 2 "register_operand" ""))
19146               (use (match_operand:SI 3 "immediate_operand" ""))
19147               (clobber (match_operand 0 "register_operand" ""))
19148               (clobber (match_operand 1 "register_operand" ""))
19149               (clobber (match_dup 2))])]
19150   ""
19151   "")
19153 (define_insn "*cmpstrnqi_nz_1"
19154   [(set (reg:CC FLAGS_REG)
19155         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19156                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19157    (use (match_operand:SI 6 "register_operand" "2"))
19158    (use (match_operand:SI 3 "immediate_operand" "i"))
19159    (clobber (match_operand:SI 0 "register_operand" "=S"))
19160    (clobber (match_operand:SI 1 "register_operand" "=D"))
19161    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19162   "!TARGET_64BIT"
19163   "repz cmpsb"
19164   [(set_attr "type" "str")
19165    (set_attr "mode" "QI")
19166    (set_attr "prefix_rep" "1")])
19168 (define_insn "*cmpstrnqi_nz_rex_1"
19169   [(set (reg:CC FLAGS_REG)
19170         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19171                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19172    (use (match_operand:DI 6 "register_operand" "2"))
19173    (use (match_operand:SI 3 "immediate_operand" "i"))
19174    (clobber (match_operand:DI 0 "register_operand" "=S"))
19175    (clobber (match_operand:DI 1 "register_operand" "=D"))
19176    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19177   "TARGET_64BIT"
19178   "repz cmpsb"
19179   [(set_attr "type" "str")
19180    (set_attr "mode" "QI")
19181    (set_attr "prefix_rep" "1")])
19183 ;; The same, but the count is not known to not be zero.
19185 (define_expand "cmpstrnqi_1"
19186   [(parallel [(set (reg:CC FLAGS_REG)
19187                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19188                                      (const_int 0))
19189                   (compare:CC (match_operand 4 "memory_operand" "")
19190                               (match_operand 5 "memory_operand" ""))
19191                   (const_int 0)))
19192               (use (match_operand:SI 3 "immediate_operand" ""))
19193               (use (reg:CC FLAGS_REG))
19194               (clobber (match_operand 0 "register_operand" ""))
19195               (clobber (match_operand 1 "register_operand" ""))
19196               (clobber (match_dup 2))])]
19197   ""
19198   "")
19200 (define_insn "*cmpstrnqi_1"
19201   [(set (reg:CC FLAGS_REG)
19202         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19203                              (const_int 0))
19204           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19205                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19206           (const_int 0)))
19207    (use (match_operand:SI 3 "immediate_operand" "i"))
19208    (use (reg:CC FLAGS_REG))
19209    (clobber (match_operand:SI 0 "register_operand" "=S"))
19210    (clobber (match_operand:SI 1 "register_operand" "=D"))
19211    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19212   "!TARGET_64BIT"
19213   "repz cmpsb"
19214   [(set_attr "type" "str")
19215    (set_attr "mode" "QI")
19216    (set_attr "prefix_rep" "1")])
19218 (define_insn "*cmpstrnqi_rex_1"
19219   [(set (reg:CC FLAGS_REG)
19220         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19221                              (const_int 0))
19222           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19223                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19224           (const_int 0)))
19225    (use (match_operand:SI 3 "immediate_operand" "i"))
19226    (use (reg:CC FLAGS_REG))
19227    (clobber (match_operand:DI 0 "register_operand" "=S"))
19228    (clobber (match_operand:DI 1 "register_operand" "=D"))
19229    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19230   "TARGET_64BIT"
19231   "repz cmpsb"
19232   [(set_attr "type" "str")
19233    (set_attr "mode" "QI")
19234    (set_attr "prefix_rep" "1")])
19236 (define_expand "strlensi"
19237   [(set (match_operand:SI 0 "register_operand" "")
19238         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19239                     (match_operand:QI 2 "immediate_operand" "")
19240                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19241   ""
19243  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19244    DONE;
19245  else
19246    FAIL;
19249 (define_expand "strlendi"
19250   [(set (match_operand:DI 0 "register_operand" "")
19251         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19252                     (match_operand:QI 2 "immediate_operand" "")
19253                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19254   ""
19256  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19257    DONE;
19258  else
19259    FAIL;
19262 (define_expand "strlenqi_1"
19263   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19264               (clobber (match_operand 1 "register_operand" ""))
19265               (clobber (reg:CC FLAGS_REG))])]
19266   ""
19267   "")
19269 (define_insn "*strlenqi_1"
19270   [(set (match_operand:SI 0 "register_operand" "=&c")
19271         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19272                     (match_operand:QI 2 "register_operand" "a")
19273                     (match_operand:SI 3 "immediate_operand" "i")
19274                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19275    (clobber (match_operand:SI 1 "register_operand" "=D"))
19276    (clobber (reg:CC FLAGS_REG))]
19277   "!TARGET_64BIT"
19278   "repnz scasb"
19279   [(set_attr "type" "str")
19280    (set_attr "mode" "QI")
19281    (set_attr "prefix_rep" "1")])
19283 (define_insn "*strlenqi_rex_1"
19284   [(set (match_operand:DI 0 "register_operand" "=&c")
19285         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19286                     (match_operand:QI 2 "register_operand" "a")
19287                     (match_operand:DI 3 "immediate_operand" "i")
19288                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19289    (clobber (match_operand:DI 1 "register_operand" "=D"))
19290    (clobber (reg:CC FLAGS_REG))]
19291   "TARGET_64BIT"
19292   "repnz scasb"
19293   [(set_attr "type" "str")
19294    (set_attr "mode" "QI")
19295    (set_attr "prefix_rep" "1")])
19297 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19298 ;; handled in combine, but it is not currently up to the task.
19299 ;; When used for their truth value, the cmpstrn* expanders generate
19300 ;; code like this:
19302 ;;   repz cmpsb
19303 ;;   seta       %al
19304 ;;   setb       %dl
19305 ;;   cmpb       %al, %dl
19306 ;;   jcc        label
19308 ;; The intermediate three instructions are unnecessary.
19310 ;; This one handles cmpstrn*_nz_1...
19311 (define_peephole2
19312   [(parallel[
19313      (set (reg:CC FLAGS_REG)
19314           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19315                       (mem:BLK (match_operand 5 "register_operand" ""))))
19316      (use (match_operand 6 "register_operand" ""))
19317      (use (match_operand:SI 3 "immediate_operand" ""))
19318      (clobber (match_operand 0 "register_operand" ""))
19319      (clobber (match_operand 1 "register_operand" ""))
19320      (clobber (match_operand 2 "register_operand" ""))])
19321    (set (match_operand:QI 7 "register_operand" "")
19322         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19323    (set (match_operand:QI 8 "register_operand" "")
19324         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19325    (set (reg FLAGS_REG)
19326         (compare (match_dup 7) (match_dup 8)))
19327   ]
19328   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19329   [(parallel[
19330      (set (reg:CC FLAGS_REG)
19331           (compare:CC (mem:BLK (match_dup 4))
19332                       (mem:BLK (match_dup 5))))
19333      (use (match_dup 6))
19334      (use (match_dup 3))
19335      (clobber (match_dup 0))
19336      (clobber (match_dup 1))
19337      (clobber (match_dup 2))])]
19338   "")
19340 ;; ...and this one handles cmpstrn*_1.
19341 (define_peephole2
19342   [(parallel[
19343      (set (reg:CC FLAGS_REG)
19344           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19345                                (const_int 0))
19346             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19347                         (mem:BLK (match_operand 5 "register_operand" "")))
19348             (const_int 0)))
19349      (use (match_operand:SI 3 "immediate_operand" ""))
19350      (use (reg:CC FLAGS_REG))
19351      (clobber (match_operand 0 "register_operand" ""))
19352      (clobber (match_operand 1 "register_operand" ""))
19353      (clobber (match_operand 2 "register_operand" ""))])
19354    (set (match_operand:QI 7 "register_operand" "")
19355         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19356    (set (match_operand:QI 8 "register_operand" "")
19357         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19358    (set (reg FLAGS_REG)
19359         (compare (match_dup 7) (match_dup 8)))
19360   ]
19361   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19362   [(parallel[
19363      (set (reg:CC FLAGS_REG)
19364           (if_then_else:CC (ne (match_dup 6)
19365                                (const_int 0))
19366             (compare:CC (mem:BLK (match_dup 4))
19367                         (mem:BLK (match_dup 5)))
19368             (const_int 0)))
19369      (use (match_dup 3))
19370      (use (reg:CC FLAGS_REG))
19371      (clobber (match_dup 0))
19372      (clobber (match_dup 1))
19373      (clobber (match_dup 2))])]
19374   "")
19378 ;; Conditional move instructions.
19380 (define_expand "movdicc"
19381   [(set (match_operand:DI 0 "register_operand" "")
19382         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19383                          (match_operand:DI 2 "general_operand" "")
19384                          (match_operand:DI 3 "general_operand" "")))]
19385   "TARGET_64BIT"
19386   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19388 (define_insn "x86_movdicc_0_m1_rex64"
19389   [(set (match_operand:DI 0 "register_operand" "=r")
19390         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19391           (const_int -1)
19392           (const_int 0)))
19393    (clobber (reg:CC FLAGS_REG))]
19394   "TARGET_64BIT"
19395   "sbb{q}\t%0, %0"
19396   ; Since we don't have the proper number of operands for an alu insn,
19397   ; fill in all the blanks.
19398   [(set_attr "type" "alu")
19399    (set_attr "pent_pair" "pu")
19400    (set_attr "memory" "none")
19401    (set_attr "imm_disp" "false")
19402    (set_attr "mode" "DI")
19403    (set_attr "length_immediate" "0")])
19405 (define_insn "*movdicc_c_rex64"
19406   [(set (match_operand:DI 0 "register_operand" "=r,r")
19407         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19408                                 [(reg FLAGS_REG) (const_int 0)])
19409                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19410                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19411   "TARGET_64BIT && TARGET_CMOVE
19412    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19413   "@
19414    cmov%O2%C1\t{%2, %0|%0, %2}
19415    cmov%O2%c1\t{%3, %0|%0, %3}"
19416   [(set_attr "type" "icmov")
19417    (set_attr "mode" "DI")])
19419 (define_expand "movsicc"
19420   [(set (match_operand:SI 0 "register_operand" "")
19421         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19422                          (match_operand:SI 2 "general_operand" "")
19423                          (match_operand:SI 3 "general_operand" "")))]
19424   ""
19425   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19427 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19428 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19429 ;; So just document what we're doing explicitly.
19431 (define_insn "x86_movsicc_0_m1"
19432   [(set (match_operand:SI 0 "register_operand" "=r")
19433         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19434           (const_int -1)
19435           (const_int 0)))
19436    (clobber (reg:CC FLAGS_REG))]
19437   ""
19438   "sbb{l}\t%0, %0"
19439   ; Since we don't have the proper number of operands for an alu insn,
19440   ; fill in all the blanks.
19441   [(set_attr "type" "alu")
19442    (set_attr "pent_pair" "pu")
19443    (set_attr "memory" "none")
19444    (set_attr "imm_disp" "false")
19445    (set_attr "mode" "SI")
19446    (set_attr "length_immediate" "0")])
19448 (define_insn "*movsicc_noc"
19449   [(set (match_operand:SI 0 "register_operand" "=r,r")
19450         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19451                                 [(reg FLAGS_REG) (const_int 0)])
19452                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19453                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19454   "TARGET_CMOVE
19455    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19456   "@
19457    cmov%O2%C1\t{%2, %0|%0, %2}
19458    cmov%O2%c1\t{%3, %0|%0, %3}"
19459   [(set_attr "type" "icmov")
19460    (set_attr "mode" "SI")])
19462 (define_expand "movhicc"
19463   [(set (match_operand:HI 0 "register_operand" "")
19464         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19465                          (match_operand:HI 2 "general_operand" "")
19466                          (match_operand:HI 3 "general_operand" "")))]
19467   "TARGET_HIMODE_MATH"
19468   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19470 (define_insn "*movhicc_noc"
19471   [(set (match_operand:HI 0 "register_operand" "=r,r")
19472         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19473                                 [(reg FLAGS_REG) (const_int 0)])
19474                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19475                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19476   "TARGET_CMOVE
19477    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19478   "@
19479    cmov%O2%C1\t{%2, %0|%0, %2}
19480    cmov%O2%c1\t{%3, %0|%0, %3}"
19481   [(set_attr "type" "icmov")
19482    (set_attr "mode" "HI")])
19484 (define_expand "movqicc"
19485   [(set (match_operand:QI 0 "register_operand" "")
19486         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19487                          (match_operand:QI 2 "general_operand" "")
19488                          (match_operand:QI 3 "general_operand" "")))]
19489   "TARGET_QIMODE_MATH"
19490   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19492 (define_insn_and_split "*movqicc_noc"
19493   [(set (match_operand:QI 0 "register_operand" "=r,r")
19494         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19495                                 [(match_operand 4 "flags_reg_operand" "")
19496                                  (const_int 0)])
19497                       (match_operand:QI 2 "register_operand" "r,0")
19498                       (match_operand:QI 3 "register_operand" "0,r")))]
19499   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19500   "#"
19501   "&& reload_completed"
19502   [(set (match_dup 0)
19503         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19504                       (match_dup 2)
19505                       (match_dup 3)))]
19506   "operands[0] = gen_lowpart (SImode, operands[0]);
19507    operands[2] = gen_lowpart (SImode, operands[2]);
19508    operands[3] = gen_lowpart (SImode, operands[3]);"
19509   [(set_attr "type" "icmov")
19510    (set_attr "mode" "SI")])
19512 (define_expand "movsfcc"
19513   [(set (match_operand:SF 0 "register_operand" "")
19514         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19515                          (match_operand:SF 2 "register_operand" "")
19516                          (match_operand:SF 3 "register_operand" "")))]
19517   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19518   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19520 (define_insn "*movsfcc_1_387"
19521   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19522         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19523                                 [(reg FLAGS_REG) (const_int 0)])
19524                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19525                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19526   "TARGET_80387 && TARGET_CMOVE
19527    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19528   "@
19529    fcmov%F1\t{%2, %0|%0, %2}
19530    fcmov%f1\t{%3, %0|%0, %3}
19531    cmov%O2%C1\t{%2, %0|%0, %2}
19532    cmov%O2%c1\t{%3, %0|%0, %3}"
19533   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19534    (set_attr "mode" "SF,SF,SI,SI")])
19536 (define_expand "movdfcc"
19537   [(set (match_operand:DF 0 "register_operand" "")
19538         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19539                          (match_operand:DF 2 "register_operand" "")
19540                          (match_operand:DF 3 "register_operand" "")))]
19541   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19542   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19544 (define_insn "*movdfcc_1"
19545   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19546         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19547                                 [(reg FLAGS_REG) (const_int 0)])
19548                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19549                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19550   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19551    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19552   "@
19553    fcmov%F1\t{%2, %0|%0, %2}
19554    fcmov%f1\t{%3, %0|%0, %3}
19555    #
19556    #"
19557   [(set_attr "type" "fcmov,fcmov,multi,multi")
19558    (set_attr "mode" "DF")])
19560 (define_insn "*movdfcc_1_rex64"
19561   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19562         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19563                                 [(reg FLAGS_REG) (const_int 0)])
19564                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19565                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19566   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19567    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19568   "@
19569    fcmov%F1\t{%2, %0|%0, %2}
19570    fcmov%f1\t{%3, %0|%0, %3}
19571    cmov%O2%C1\t{%2, %0|%0, %2}
19572    cmov%O2%c1\t{%3, %0|%0, %3}"
19573   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19574    (set_attr "mode" "DF")])
19576 (define_split
19577   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19578         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19579                                 [(match_operand 4 "flags_reg_operand" "")
19580                                  (const_int 0)])
19581                       (match_operand:DF 2 "nonimmediate_operand" "")
19582                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19583   "!TARGET_64BIT && reload_completed"
19584   [(set (match_dup 2)
19585         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19586                       (match_dup 5)
19587                       (match_dup 7)))
19588    (set (match_dup 3)
19589         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19590                       (match_dup 6)
19591                       (match_dup 8)))]
19592   "split_di (operands+2, 1, operands+5, operands+6);
19593    split_di (operands+3, 1, operands+7, operands+8);
19594    split_di (operands, 1, operands+2, operands+3);")
19596 (define_expand "movxfcc"
19597   [(set (match_operand:XF 0 "register_operand" "")
19598         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19599                          (match_operand:XF 2 "register_operand" "")
19600                          (match_operand:XF 3 "register_operand" "")))]
19601   "TARGET_80387 && TARGET_CMOVE"
19602   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19604 (define_insn "*movxfcc_1"
19605   [(set (match_operand:XF 0 "register_operand" "=f,f")
19606         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19607                                 [(reg FLAGS_REG) (const_int 0)])
19608                       (match_operand:XF 2 "register_operand" "f,0")
19609                       (match_operand:XF 3 "register_operand" "0,f")))]
19610   "TARGET_80387 && TARGET_CMOVE"
19611   "@
19612    fcmov%F1\t{%2, %0|%0, %2}
19613    fcmov%f1\t{%3, %0|%0, %3}"
19614   [(set_attr "type" "fcmov")
19615    (set_attr "mode" "XF")])
19617 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19618 ;; the scalar versions to have only XMM registers as operands.
19620 ;; SSE5 conditional move
19621 (define_insn "*sse5_pcmov_<mode>"
19622   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19623         (if_then_else:MODEF
19624           (match_operand:MODEF 1 "register_operand" "x,0")
19625           (match_operand:MODEF 2 "register_operand" "0,x")
19626           (match_operand:MODEF 3 "register_operand" "x,x")))]
19627   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19628   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19629   [(set_attr "type" "sse4arg")])
19631 ;; These versions of the min/max patterns are intentionally ignorant of
19632 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19633 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19634 ;; are undefined in this condition, we're certain this is correct.
19636 (define_insn "sminsf3"
19637   [(set (match_operand:SF 0 "register_operand" "=x")
19638         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19639                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19640   "TARGET_SSE_MATH"
19641   "minss\t{%2, %0|%0, %2}"
19642   [(set_attr "type" "sseadd")
19643    (set_attr "mode" "SF")])
19645 (define_insn "smaxsf3"
19646   [(set (match_operand:SF 0 "register_operand" "=x")
19647         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19648                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19649   "TARGET_SSE_MATH"
19650   "maxss\t{%2, %0|%0, %2}"
19651   [(set_attr "type" "sseadd")
19652    (set_attr "mode" "SF")])
19654 (define_insn "smindf3"
19655   [(set (match_operand:DF 0 "register_operand" "=x")
19656         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19657                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19658   "TARGET_SSE2 && TARGET_SSE_MATH"
19659   "minsd\t{%2, %0|%0, %2}"
19660   [(set_attr "type" "sseadd")
19661    (set_attr "mode" "DF")])
19663 (define_insn "smaxdf3"
19664   [(set (match_operand:DF 0 "register_operand" "=x")
19665         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19666                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19667   "TARGET_SSE2 && TARGET_SSE_MATH"
19668   "maxsd\t{%2, %0|%0, %2}"
19669   [(set_attr "type" "sseadd")
19670    (set_attr "mode" "DF")])
19672 ;; These versions of the min/max patterns implement exactly the operations
19673 ;;   min = (op1 < op2 ? op1 : op2)
19674 ;;   max = (!(op1 < op2) ? op1 : op2)
19675 ;; Their operands are not commutative, and thus they may be used in the
19676 ;; presence of -0.0 and NaN.
19678 (define_insn "*ieee_sminsf3"
19679   [(set (match_operand:SF 0 "register_operand" "=x")
19680         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19681                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19682                    UNSPEC_IEEE_MIN))]
19683   "TARGET_SSE_MATH"
19684   "minss\t{%2, %0|%0, %2}"
19685   [(set_attr "type" "sseadd")
19686    (set_attr "mode" "SF")])
19688 (define_insn "*ieee_smaxsf3"
19689   [(set (match_operand:SF 0 "register_operand" "=x")
19690         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19691                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19692                    UNSPEC_IEEE_MAX))]
19693   "TARGET_SSE_MATH"
19694   "maxss\t{%2, %0|%0, %2}"
19695   [(set_attr "type" "sseadd")
19696    (set_attr "mode" "SF")])
19698 (define_insn "*ieee_smindf3"
19699   [(set (match_operand:DF 0 "register_operand" "=x")
19700         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19701                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19702                    UNSPEC_IEEE_MIN))]
19703   "TARGET_SSE2 && TARGET_SSE_MATH"
19704   "minsd\t{%2, %0|%0, %2}"
19705   [(set_attr "type" "sseadd")
19706    (set_attr "mode" "DF")])
19708 (define_insn "*ieee_smaxdf3"
19709   [(set (match_operand:DF 0 "register_operand" "=x")
19710         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19711                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19712                    UNSPEC_IEEE_MAX))]
19713   "TARGET_SSE2 && TARGET_SSE_MATH"
19714   "maxsd\t{%2, %0|%0, %2}"
19715   [(set_attr "type" "sseadd")
19716    (set_attr "mode" "DF")])
19718 ;; Make two stack loads independent:
19719 ;;   fld aa              fld aa
19720 ;;   fld %st(0)     ->   fld bb
19721 ;;   fmul bb             fmul %st(1), %st
19723 ;; Actually we only match the last two instructions for simplicity.
19724 (define_peephole2
19725   [(set (match_operand 0 "fp_register_operand" "")
19726         (match_operand 1 "fp_register_operand" ""))
19727    (set (match_dup 0)
19728         (match_operator 2 "binary_fp_operator"
19729            [(match_dup 0)
19730             (match_operand 3 "memory_operand" "")]))]
19731   "REGNO (operands[0]) != REGNO (operands[1])"
19732   [(set (match_dup 0) (match_dup 3))
19733    (set (match_dup 0) (match_dup 4))]
19735   ;; The % modifier is not operational anymore in peephole2's, so we have to
19736   ;; swap the operands manually in the case of addition and multiplication.
19737   "if (COMMUTATIVE_ARITH_P (operands[2]))
19738      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19739                                  operands[0], operands[1]);
19740    else
19741      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19742                                  operands[1], operands[0]);")
19744 ;; Conditional addition patterns
19745 (define_expand "addqicc"
19746   [(match_operand:QI 0 "register_operand" "")
19747    (match_operand 1 "comparison_operator" "")
19748    (match_operand:QI 2 "register_operand" "")
19749    (match_operand:QI 3 "const_int_operand" "")]
19750   ""
19751   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19753 (define_expand "addhicc"
19754   [(match_operand:HI 0 "register_operand" "")
19755    (match_operand 1 "comparison_operator" "")
19756    (match_operand:HI 2 "register_operand" "")
19757    (match_operand:HI 3 "const_int_operand" "")]
19758   ""
19759   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19761 (define_expand "addsicc"
19762   [(match_operand:SI 0 "register_operand" "")
19763    (match_operand 1 "comparison_operator" "")
19764    (match_operand:SI 2 "register_operand" "")
19765    (match_operand:SI 3 "const_int_operand" "")]
19766   ""
19767   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19769 (define_expand "adddicc"
19770   [(match_operand:DI 0 "register_operand" "")
19771    (match_operand 1 "comparison_operator" "")
19772    (match_operand:DI 2 "register_operand" "")
19773    (match_operand:DI 3 "const_int_operand" "")]
19774   "TARGET_64BIT"
19775   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19778 ;; Misc patterns (?)
19780 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19781 ;; Otherwise there will be nothing to keep
19783 ;; [(set (reg ebp) (reg esp))]
19784 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19785 ;;  (clobber (eflags)]
19786 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19788 ;; in proper program order.
19789 (define_insn "pro_epilogue_adjust_stack_1"
19790   [(set (match_operand:SI 0 "register_operand" "=r,r")
19791         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19792                  (match_operand:SI 2 "immediate_operand" "i,i")))
19793    (clobber (reg:CC FLAGS_REG))
19794    (clobber (mem:BLK (scratch)))]
19795   "!TARGET_64BIT"
19797   switch (get_attr_type (insn))
19798     {
19799     case TYPE_IMOV:
19800       return "mov{l}\t{%1, %0|%0, %1}";
19802     case TYPE_ALU:
19803       if (CONST_INT_P (operands[2])
19804           && (INTVAL (operands[2]) == 128
19805               || (INTVAL (operands[2]) < 0
19806                   && INTVAL (operands[2]) != -128)))
19807         {
19808           operands[2] = GEN_INT (-INTVAL (operands[2]));
19809           return "sub{l}\t{%2, %0|%0, %2}";
19810         }
19811       return "add{l}\t{%2, %0|%0, %2}";
19813     case TYPE_LEA:
19814       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19815       return "lea{l}\t{%a2, %0|%0, %a2}";
19817     default:
19818       gcc_unreachable ();
19819     }
19821   [(set (attr "type")
19822         (cond [(eq_attr "alternative" "0")
19823                  (const_string "alu")
19824                (match_operand:SI 2 "const0_operand" "")
19825                  (const_string "imov")
19826               ]
19827               (const_string "lea")))
19828    (set_attr "mode" "SI")])
19830 (define_insn "pro_epilogue_adjust_stack_rex64"
19831   [(set (match_operand:DI 0 "register_operand" "=r,r")
19832         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19833                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19834    (clobber (reg:CC FLAGS_REG))
19835    (clobber (mem:BLK (scratch)))]
19836   "TARGET_64BIT"
19838   switch (get_attr_type (insn))
19839     {
19840     case TYPE_IMOV:
19841       return "mov{q}\t{%1, %0|%0, %1}";
19843     case TYPE_ALU:
19844       if (CONST_INT_P (operands[2])
19845           /* Avoid overflows.  */
19846           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19847           && (INTVAL (operands[2]) == 128
19848               || (INTVAL (operands[2]) < 0
19849                   && INTVAL (operands[2]) != -128)))
19850         {
19851           operands[2] = GEN_INT (-INTVAL (operands[2]));
19852           return "sub{q}\t{%2, %0|%0, %2}";
19853         }
19854       return "add{q}\t{%2, %0|%0, %2}";
19856     case TYPE_LEA:
19857       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19858       return "lea{q}\t{%a2, %0|%0, %a2}";
19860     default:
19861       gcc_unreachable ();
19862     }
19864   [(set (attr "type")
19865         (cond [(eq_attr "alternative" "0")
19866                  (const_string "alu")
19867                (match_operand:DI 2 "const0_operand" "")
19868                  (const_string "imov")
19869               ]
19870               (const_string "lea")))
19871    (set_attr "mode" "DI")])
19873 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19874   [(set (match_operand:DI 0 "register_operand" "=r,r")
19875         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19876                  (match_operand:DI 3 "immediate_operand" "i,i")))
19877    (use (match_operand:DI 2 "register_operand" "r,r"))
19878    (clobber (reg:CC FLAGS_REG))
19879    (clobber (mem:BLK (scratch)))]
19880   "TARGET_64BIT"
19882   switch (get_attr_type (insn))
19883     {
19884     case TYPE_ALU:
19885       return "add{q}\t{%2, %0|%0, %2}";
19887     case TYPE_LEA:
19888       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19889       return "lea{q}\t{%a2, %0|%0, %a2}";
19891     default:
19892       gcc_unreachable ();
19893     }
19895   [(set_attr "type" "alu,lea")
19896    (set_attr "mode" "DI")])
19898 (define_insn "allocate_stack_worker_32"
19899   [(set (match_operand:SI 0 "register_operand" "+a")
19900         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19901    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19902    (clobber (reg:CC FLAGS_REG))]
19903   "!TARGET_64BIT && TARGET_STACK_PROBE"
19904   "call\t__alloca"
19905   [(set_attr "type" "multi")
19906    (set_attr "length" "5")])
19908 (define_insn "allocate_stack_worker_64"
19909   [(set (match_operand:DI 0 "register_operand" "=a")
19910         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19911    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19912    (clobber (reg:DI R10_REG))
19913    (clobber (reg:DI R11_REG))
19914    (clobber (reg:CC FLAGS_REG))]
19915   "TARGET_64BIT && TARGET_STACK_PROBE"
19916   "call\t___chkstk"
19917   [(set_attr "type" "multi")
19918    (set_attr "length" "5")])
19920 (define_expand "allocate_stack"
19921   [(match_operand 0 "register_operand" "")
19922    (match_operand 1 "general_operand" "")]
19923   "TARGET_STACK_PROBE"
19925   rtx x;
19927 #ifndef CHECK_STACK_LIMIT
19928 #define CHECK_STACK_LIMIT 0
19929 #endif
19931   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19932       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19933     {
19934       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19935                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19936       if (x != stack_pointer_rtx)
19937         emit_move_insn (stack_pointer_rtx, x);
19938     }
19939   else
19940     {
19941       x = copy_to_mode_reg (Pmode, operands[1]);
19942       if (TARGET_64BIT)
19943         x = gen_allocate_stack_worker_64 (x);
19944       else
19945         x = gen_allocate_stack_worker_32 (x);
19946       emit_insn (x);
19947     }
19949   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19950   DONE;
19953 (define_expand "builtin_setjmp_receiver"
19954   [(label_ref (match_operand 0 "" ""))]
19955   "!TARGET_64BIT && flag_pic"
19957   if (TARGET_MACHO)
19958     {
19959       rtx xops[3];
19960       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19961       rtx label_rtx = gen_label_rtx ();
19962       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19963       xops[0] = xops[1] = picreg;
19964       xops[2] = gen_rtx_CONST (SImode,
19965                   gen_rtx_MINUS (SImode,
19966                     gen_rtx_LABEL_REF (SImode, label_rtx),
19967                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19968       ix86_expand_binary_operator (MINUS, SImode, xops);
19969     }
19970   else
19971     emit_insn (gen_set_got (pic_offset_table_rtx));
19972   DONE;
19975 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19977 (define_split
19978   [(set (match_operand 0 "register_operand" "")
19979         (match_operator 3 "promotable_binary_operator"
19980            [(match_operand 1 "register_operand" "")
19981             (match_operand 2 "aligned_operand" "")]))
19982    (clobber (reg:CC FLAGS_REG))]
19983   "! TARGET_PARTIAL_REG_STALL && reload_completed
19984    && ((GET_MODE (operands[0]) == HImode
19985         && ((!optimize_size && !TARGET_FAST_PREFIX)
19986             /* ??? next two lines just !satisfies_constraint_K (...) */
19987             || !CONST_INT_P (operands[2])
19988             || satisfies_constraint_K (operands[2])))
19989        || (GET_MODE (operands[0]) == QImode
19990            && (TARGET_PROMOTE_QImode || optimize_size)))"
19991   [(parallel [(set (match_dup 0)
19992                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19993               (clobber (reg:CC FLAGS_REG))])]
19994   "operands[0] = gen_lowpart (SImode, operands[0]);
19995    operands[1] = gen_lowpart (SImode, operands[1]);
19996    if (GET_CODE (operands[3]) != ASHIFT)
19997      operands[2] = gen_lowpart (SImode, operands[2]);
19998    PUT_MODE (operands[3], SImode);")
20000 ; Promote the QImode tests, as i386 has encoding of the AND
20001 ; instruction with 32-bit sign-extended immediate and thus the
20002 ; instruction size is unchanged, except in the %eax case for
20003 ; which it is increased by one byte, hence the ! optimize_size.
20004 (define_split
20005   [(set (match_operand 0 "flags_reg_operand" "")
20006         (match_operator 2 "compare_operator"
20007           [(and (match_operand 3 "aligned_operand" "")
20008                 (match_operand 4 "const_int_operand" ""))
20009            (const_int 0)]))
20010    (set (match_operand 1 "register_operand" "")
20011         (and (match_dup 3) (match_dup 4)))]
20012   "! TARGET_PARTIAL_REG_STALL && reload_completed
20013    && ! optimize_size
20014    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20015        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20016    /* Ensure that the operand will remain sign-extended immediate.  */
20017    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20018   [(parallel [(set (match_dup 0)
20019                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20020                                     (const_int 0)]))
20021               (set (match_dup 1)
20022                    (and:SI (match_dup 3) (match_dup 4)))])]
20024   operands[4]
20025     = gen_int_mode (INTVAL (operands[4])
20026                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20027   operands[1] = gen_lowpart (SImode, operands[1]);
20028   operands[3] = gen_lowpart (SImode, operands[3]);
20031 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20032 ; the TEST instruction with 32-bit sign-extended immediate and thus
20033 ; the instruction size would at least double, which is not what we
20034 ; want even with ! optimize_size.
20035 (define_split
20036   [(set (match_operand 0 "flags_reg_operand" "")
20037         (match_operator 1 "compare_operator"
20038           [(and (match_operand:HI 2 "aligned_operand" "")
20039                 (match_operand:HI 3 "const_int_operand" ""))
20040            (const_int 0)]))]
20041   "! TARGET_PARTIAL_REG_STALL && reload_completed
20042    && ! TARGET_FAST_PREFIX
20043    && ! optimize_size
20044    /* Ensure that the operand will remain sign-extended immediate.  */
20045    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20046   [(set (match_dup 0)
20047         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20048                          (const_int 0)]))]
20050   operands[3]
20051     = gen_int_mode (INTVAL (operands[3])
20052                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20053   operands[2] = gen_lowpart (SImode, operands[2]);
20056 (define_split
20057   [(set (match_operand 0 "register_operand" "")
20058         (neg (match_operand 1 "register_operand" "")))
20059    (clobber (reg:CC FLAGS_REG))]
20060   "! TARGET_PARTIAL_REG_STALL && reload_completed
20061    && (GET_MODE (operands[0]) == HImode
20062        || (GET_MODE (operands[0]) == QImode
20063            && (TARGET_PROMOTE_QImode || optimize_size)))"
20064   [(parallel [(set (match_dup 0)
20065                    (neg:SI (match_dup 1)))
20066               (clobber (reg:CC FLAGS_REG))])]
20067   "operands[0] = gen_lowpart (SImode, operands[0]);
20068    operands[1] = gen_lowpart (SImode, operands[1]);")
20070 (define_split
20071   [(set (match_operand 0 "register_operand" "")
20072         (not (match_operand 1 "register_operand" "")))]
20073   "! TARGET_PARTIAL_REG_STALL && reload_completed
20074    && (GET_MODE (operands[0]) == HImode
20075        || (GET_MODE (operands[0]) == QImode
20076            && (TARGET_PROMOTE_QImode || optimize_size)))"
20077   [(set (match_dup 0)
20078         (not:SI (match_dup 1)))]
20079   "operands[0] = gen_lowpart (SImode, operands[0]);
20080    operands[1] = gen_lowpart (SImode, operands[1]);")
20082 (define_split
20083   [(set (match_operand 0 "register_operand" "")
20084         (if_then_else (match_operator 1 "comparison_operator"
20085                                 [(reg FLAGS_REG) (const_int 0)])
20086                       (match_operand 2 "register_operand" "")
20087                       (match_operand 3 "register_operand" "")))]
20088   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20089    && (GET_MODE (operands[0]) == HImode
20090        || (GET_MODE (operands[0]) == QImode
20091            && (TARGET_PROMOTE_QImode || optimize_size)))"
20092   [(set (match_dup 0)
20093         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20094   "operands[0] = gen_lowpart (SImode, operands[0]);
20095    operands[2] = gen_lowpart (SImode, operands[2]);
20096    operands[3] = gen_lowpart (SImode, operands[3]);")
20099 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20100 ;; transform a complex memory operation into two memory to register operations.
20102 ;; Don't push memory operands
20103 (define_peephole2
20104   [(set (match_operand:SI 0 "push_operand" "")
20105         (match_operand:SI 1 "memory_operand" ""))
20106    (match_scratch:SI 2 "r")]
20107   "!optimize_size && !TARGET_PUSH_MEMORY
20108    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20109   [(set (match_dup 2) (match_dup 1))
20110    (set (match_dup 0) (match_dup 2))]
20111   "")
20113 (define_peephole2
20114   [(set (match_operand:DI 0 "push_operand" "")
20115         (match_operand:DI 1 "memory_operand" ""))
20116    (match_scratch:DI 2 "r")]
20117   "!optimize_size && !TARGET_PUSH_MEMORY
20118    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20119   [(set (match_dup 2) (match_dup 1))
20120    (set (match_dup 0) (match_dup 2))]
20121   "")
20123 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20124 ;; SImode pushes.
20125 (define_peephole2
20126   [(set (match_operand:SF 0 "push_operand" "")
20127         (match_operand:SF 1 "memory_operand" ""))
20128    (match_scratch:SF 2 "r")]
20129   "!optimize_size && !TARGET_PUSH_MEMORY
20130    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20131   [(set (match_dup 2) (match_dup 1))
20132    (set (match_dup 0) (match_dup 2))]
20133   "")
20135 (define_peephole2
20136   [(set (match_operand:HI 0 "push_operand" "")
20137         (match_operand:HI 1 "memory_operand" ""))
20138    (match_scratch:HI 2 "r")]
20139   "!optimize_size && !TARGET_PUSH_MEMORY
20140    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20141   [(set (match_dup 2) (match_dup 1))
20142    (set (match_dup 0) (match_dup 2))]
20143   "")
20145 (define_peephole2
20146   [(set (match_operand:QI 0 "push_operand" "")
20147         (match_operand:QI 1 "memory_operand" ""))
20148    (match_scratch:QI 2 "q")]
20149   "!optimize_size && !TARGET_PUSH_MEMORY
20150    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20151   [(set (match_dup 2) (match_dup 1))
20152    (set (match_dup 0) (match_dup 2))]
20153   "")
20155 ;; Don't move an immediate directly to memory when the instruction
20156 ;; gets too big.
20157 (define_peephole2
20158   [(match_scratch:SI 1 "r")
20159    (set (match_operand:SI 0 "memory_operand" "")
20160         (const_int 0))]
20161   "! optimize_size
20162    && ! TARGET_USE_MOV0
20163    && TARGET_SPLIT_LONG_MOVES
20164    && get_attr_length (insn) >= ix86_cost->large_insn
20165    && peep2_regno_dead_p (0, FLAGS_REG)"
20166   [(parallel [(set (match_dup 1) (const_int 0))
20167               (clobber (reg:CC FLAGS_REG))])
20168    (set (match_dup 0) (match_dup 1))]
20169   "")
20171 (define_peephole2
20172   [(match_scratch:HI 1 "r")
20173    (set (match_operand:HI 0 "memory_operand" "")
20174         (const_int 0))]
20175   "! optimize_size
20176    && ! TARGET_USE_MOV0
20177    && TARGET_SPLIT_LONG_MOVES
20178    && get_attr_length (insn) >= ix86_cost->large_insn
20179    && peep2_regno_dead_p (0, FLAGS_REG)"
20180   [(parallel [(set (match_dup 2) (const_int 0))
20181               (clobber (reg:CC FLAGS_REG))])
20182    (set (match_dup 0) (match_dup 1))]
20183   "operands[2] = gen_lowpart (SImode, operands[1]);")
20185 (define_peephole2
20186   [(match_scratch:QI 1 "q")
20187    (set (match_operand:QI 0 "memory_operand" "")
20188         (const_int 0))]
20189   "! optimize_size
20190    && ! TARGET_USE_MOV0
20191    && TARGET_SPLIT_LONG_MOVES
20192    && get_attr_length (insn) >= ix86_cost->large_insn
20193    && peep2_regno_dead_p (0, FLAGS_REG)"
20194   [(parallel [(set (match_dup 2) (const_int 0))
20195               (clobber (reg:CC FLAGS_REG))])
20196    (set (match_dup 0) (match_dup 1))]
20197   "operands[2] = gen_lowpart (SImode, operands[1]);")
20199 (define_peephole2
20200   [(match_scratch:SI 2 "r")
20201    (set (match_operand:SI 0 "memory_operand" "")
20202         (match_operand:SI 1 "immediate_operand" ""))]
20203   "! optimize_size
20204    && TARGET_SPLIT_LONG_MOVES
20205    && get_attr_length (insn) >= ix86_cost->large_insn"
20206   [(set (match_dup 2) (match_dup 1))
20207    (set (match_dup 0) (match_dup 2))]
20208   "")
20210 (define_peephole2
20211   [(match_scratch:HI 2 "r")
20212    (set (match_operand:HI 0 "memory_operand" "")
20213         (match_operand:HI 1 "immediate_operand" ""))]
20214   "! optimize_size
20215    && TARGET_SPLIT_LONG_MOVES
20216    && get_attr_length (insn) >= ix86_cost->large_insn"
20217   [(set (match_dup 2) (match_dup 1))
20218    (set (match_dup 0) (match_dup 2))]
20219   "")
20221 (define_peephole2
20222   [(match_scratch:QI 2 "q")
20223    (set (match_operand:QI 0 "memory_operand" "")
20224         (match_operand:QI 1 "immediate_operand" ""))]
20225   "! optimize_size
20226    && TARGET_SPLIT_LONG_MOVES
20227    && get_attr_length (insn) >= ix86_cost->large_insn"
20228   [(set (match_dup 2) (match_dup 1))
20229    (set (match_dup 0) (match_dup 2))]
20230   "")
20232 ;; Don't compare memory with zero, load and use a test instead.
20233 (define_peephole2
20234   [(set (match_operand 0 "flags_reg_operand" "")
20235         (match_operator 1 "compare_operator"
20236           [(match_operand:SI 2 "memory_operand" "")
20237            (const_int 0)]))
20238    (match_scratch:SI 3 "r")]
20239   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20240   [(set (match_dup 3) (match_dup 2))
20241    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20242   "")
20244 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20245 ;; Don't split NOTs with a displacement operand, because resulting XOR
20246 ;; will not be pairable anyway.
20248 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20249 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20250 ;; so this split helps here as well.
20252 ;; Note: Can't do this as a regular split because we can't get proper
20253 ;; lifetime information then.
20255 (define_peephole2
20256   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20257         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20258   "!optimize_size
20259    && ((TARGET_NOT_UNPAIRABLE
20260         && (!MEM_P (operands[0])
20261             || !memory_displacement_operand (operands[0], SImode)))
20262        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20263    && peep2_regno_dead_p (0, FLAGS_REG)"
20264   [(parallel [(set (match_dup 0)
20265                    (xor:SI (match_dup 1) (const_int -1)))
20266               (clobber (reg:CC FLAGS_REG))])]
20267   "")
20269 (define_peephole2
20270   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20271         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20272   "!optimize_size
20273    && ((TARGET_NOT_UNPAIRABLE
20274         && (!MEM_P (operands[0])
20275             || !memory_displacement_operand (operands[0], HImode)))
20276        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20277    && peep2_regno_dead_p (0, FLAGS_REG)"
20278   [(parallel [(set (match_dup 0)
20279                    (xor:HI (match_dup 1) (const_int -1)))
20280               (clobber (reg:CC FLAGS_REG))])]
20281   "")
20283 (define_peephole2
20284   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20285         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20286   "!optimize_size
20287    && ((TARGET_NOT_UNPAIRABLE
20288         && (!MEM_P (operands[0])
20289             || !memory_displacement_operand (operands[0], QImode)))
20290        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20291    && peep2_regno_dead_p (0, FLAGS_REG)"
20292   [(parallel [(set (match_dup 0)
20293                    (xor:QI (match_dup 1) (const_int -1)))
20294               (clobber (reg:CC FLAGS_REG))])]
20295   "")
20297 ;; Non pairable "test imm, reg" instructions can be translated to
20298 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20299 ;; byte opcode instead of two, have a short form for byte operands),
20300 ;; so do it for other CPUs as well.  Given that the value was dead,
20301 ;; this should not create any new dependencies.  Pass on the sub-word
20302 ;; versions if we're concerned about partial register stalls.
20304 (define_peephole2
20305   [(set (match_operand 0 "flags_reg_operand" "")
20306         (match_operator 1 "compare_operator"
20307           [(and:SI (match_operand:SI 2 "register_operand" "")
20308                    (match_operand:SI 3 "immediate_operand" ""))
20309            (const_int 0)]))]
20310   "ix86_match_ccmode (insn, CCNOmode)
20311    && (true_regnum (operands[2]) != AX_REG
20312        || satisfies_constraint_K (operands[3]))
20313    && peep2_reg_dead_p (1, operands[2])"
20314   [(parallel
20315      [(set (match_dup 0)
20316            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20317                             (const_int 0)]))
20318       (set (match_dup 2)
20319            (and:SI (match_dup 2) (match_dup 3)))])]
20320   "")
20322 ;; We don't need to handle HImode case, because it will be promoted to SImode
20323 ;; on ! TARGET_PARTIAL_REG_STALL
20325 (define_peephole2
20326   [(set (match_operand 0 "flags_reg_operand" "")
20327         (match_operator 1 "compare_operator"
20328           [(and:QI (match_operand:QI 2 "register_operand" "")
20329                    (match_operand:QI 3 "immediate_operand" ""))
20330            (const_int 0)]))]
20331   "! TARGET_PARTIAL_REG_STALL
20332    && ix86_match_ccmode (insn, CCNOmode)
20333    && true_regnum (operands[2]) != AX_REG
20334    && peep2_reg_dead_p (1, operands[2])"
20335   [(parallel
20336      [(set (match_dup 0)
20337            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20338                             (const_int 0)]))
20339       (set (match_dup 2)
20340            (and:QI (match_dup 2) (match_dup 3)))])]
20341   "")
20343 (define_peephole2
20344   [(set (match_operand 0 "flags_reg_operand" "")
20345         (match_operator 1 "compare_operator"
20346           [(and:SI
20347              (zero_extract:SI
20348                (match_operand 2 "ext_register_operand" "")
20349                (const_int 8)
20350                (const_int 8))
20351              (match_operand 3 "const_int_operand" ""))
20352            (const_int 0)]))]
20353   "! TARGET_PARTIAL_REG_STALL
20354    && ix86_match_ccmode (insn, CCNOmode)
20355    && true_regnum (operands[2]) != AX_REG
20356    && peep2_reg_dead_p (1, operands[2])"
20357   [(parallel [(set (match_dup 0)
20358                    (match_op_dup 1
20359                      [(and:SI
20360                         (zero_extract:SI
20361                           (match_dup 2)
20362                           (const_int 8)
20363                           (const_int 8))
20364                         (match_dup 3))
20365                       (const_int 0)]))
20366               (set (zero_extract:SI (match_dup 2)
20367                                     (const_int 8)
20368                                     (const_int 8))
20369                    (and:SI
20370                      (zero_extract:SI
20371                        (match_dup 2)
20372                        (const_int 8)
20373                        (const_int 8))
20374                      (match_dup 3)))])]
20375   "")
20377 ;; Don't do logical operations with memory inputs.
20378 (define_peephole2
20379   [(match_scratch:SI 2 "r")
20380    (parallel [(set (match_operand:SI 0 "register_operand" "")
20381                    (match_operator:SI 3 "arith_or_logical_operator"
20382                      [(match_dup 0)
20383                       (match_operand:SI 1 "memory_operand" "")]))
20384               (clobber (reg:CC FLAGS_REG))])]
20385   "! optimize_size && ! TARGET_READ_MODIFY"
20386   [(set (match_dup 2) (match_dup 1))
20387    (parallel [(set (match_dup 0)
20388                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20389               (clobber (reg:CC FLAGS_REG))])]
20390   "")
20392 (define_peephole2
20393   [(match_scratch:SI 2 "r")
20394    (parallel [(set (match_operand:SI 0 "register_operand" "")
20395                    (match_operator:SI 3 "arith_or_logical_operator"
20396                      [(match_operand:SI 1 "memory_operand" "")
20397                       (match_dup 0)]))
20398               (clobber (reg:CC FLAGS_REG))])]
20399   "! optimize_size && ! TARGET_READ_MODIFY"
20400   [(set (match_dup 2) (match_dup 1))
20401    (parallel [(set (match_dup 0)
20402                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20403               (clobber (reg:CC FLAGS_REG))])]
20404   "")
20406 ; Don't do logical operations with memory outputs
20408 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20409 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20410 ; the same decoder scheduling characteristics as the original.
20412 (define_peephole2
20413   [(match_scratch:SI 2 "r")
20414    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20415                    (match_operator:SI 3 "arith_or_logical_operator"
20416                      [(match_dup 0)
20417                       (match_operand:SI 1 "nonmemory_operand" "")]))
20418               (clobber (reg:CC FLAGS_REG))])]
20419   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20420   [(set (match_dup 2) (match_dup 0))
20421    (parallel [(set (match_dup 2)
20422                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20423               (clobber (reg:CC FLAGS_REG))])
20424    (set (match_dup 0) (match_dup 2))]
20425   "")
20427 (define_peephole2
20428   [(match_scratch:SI 2 "r")
20429    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20430                    (match_operator:SI 3 "arith_or_logical_operator"
20431                      [(match_operand:SI 1 "nonmemory_operand" "")
20432                       (match_dup 0)]))
20433               (clobber (reg:CC FLAGS_REG))])]
20434   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20435   [(set (match_dup 2) (match_dup 0))
20436    (parallel [(set (match_dup 2)
20437                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20438               (clobber (reg:CC FLAGS_REG))])
20439    (set (match_dup 0) (match_dup 2))]
20440   "")
20442 ;; Attempt to always use XOR for zeroing registers.
20443 (define_peephole2
20444   [(set (match_operand 0 "register_operand" "")
20445         (match_operand 1 "const0_operand" ""))]
20446   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20447    && (! TARGET_USE_MOV0 || optimize_size)
20448    && GENERAL_REG_P (operands[0])
20449    && peep2_regno_dead_p (0, FLAGS_REG)"
20450   [(parallel [(set (match_dup 0) (const_int 0))
20451               (clobber (reg:CC FLAGS_REG))])]
20453   operands[0] = gen_lowpart (word_mode, operands[0]);
20456 (define_peephole2
20457   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20458         (const_int 0))]
20459   "(GET_MODE (operands[0]) == QImode
20460     || GET_MODE (operands[0]) == HImode)
20461    && (! TARGET_USE_MOV0 || optimize_size)
20462    && peep2_regno_dead_p (0, FLAGS_REG)"
20463   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20464               (clobber (reg:CC FLAGS_REG))])])
20466 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20467 (define_peephole2
20468   [(set (match_operand 0 "register_operand" "")
20469         (const_int -1))]
20470   "(GET_MODE (operands[0]) == HImode
20471     || GET_MODE (operands[0]) == SImode
20472     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20473    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20474    && peep2_regno_dead_p (0, FLAGS_REG)"
20475   [(parallel [(set (match_dup 0) (const_int -1))
20476               (clobber (reg:CC FLAGS_REG))])]
20477   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20478                               operands[0]);")
20480 ;; Attempt to convert simple leas to adds. These can be created by
20481 ;; move expanders.
20482 (define_peephole2
20483   [(set (match_operand:SI 0 "register_operand" "")
20484         (plus:SI (match_dup 0)
20485                  (match_operand:SI 1 "nonmemory_operand" "")))]
20486   "peep2_regno_dead_p (0, FLAGS_REG)"
20487   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20488               (clobber (reg:CC FLAGS_REG))])]
20489   "")
20491 (define_peephole2
20492   [(set (match_operand:SI 0 "register_operand" "")
20493         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20494                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20495   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20496   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20497               (clobber (reg:CC FLAGS_REG))])]
20498   "operands[2] = gen_lowpart (SImode, operands[2]);")
20500 (define_peephole2
20501   [(set (match_operand:DI 0 "register_operand" "")
20502         (plus:DI (match_dup 0)
20503                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20504   "peep2_regno_dead_p (0, FLAGS_REG)"
20505   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20506               (clobber (reg:CC FLAGS_REG))])]
20507   "")
20509 (define_peephole2
20510   [(set (match_operand:SI 0 "register_operand" "")
20511         (mult:SI (match_dup 0)
20512                  (match_operand:SI 1 "const_int_operand" "")))]
20513   "exact_log2 (INTVAL (operands[1])) >= 0
20514    && peep2_regno_dead_p (0, FLAGS_REG)"
20515   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20516               (clobber (reg:CC FLAGS_REG))])]
20517   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20519 (define_peephole2
20520   [(set (match_operand:DI 0 "register_operand" "")
20521         (mult:DI (match_dup 0)
20522                  (match_operand:DI 1 "const_int_operand" "")))]
20523   "exact_log2 (INTVAL (operands[1])) >= 0
20524    && peep2_regno_dead_p (0, FLAGS_REG)"
20525   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20526               (clobber (reg:CC FLAGS_REG))])]
20527   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20529 (define_peephole2
20530   [(set (match_operand:SI 0 "register_operand" "")
20531         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20532                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20533   "exact_log2 (INTVAL (operands[2])) >= 0
20534    && REGNO (operands[0]) == REGNO (operands[1])
20535    && peep2_regno_dead_p (0, FLAGS_REG)"
20536   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20537               (clobber (reg:CC FLAGS_REG))])]
20538   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20540 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20541 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20542 ;; many CPUs it is also faster, since special hardware to avoid esp
20543 ;; dependencies is present.
20545 ;; While some of these conversions may be done using splitters, we use peepholes
20546 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20548 ;; Convert prologue esp subtractions to push.
20549 ;; We need register to push.  In order to keep verify_flow_info happy we have
20550 ;; two choices
20551 ;; - use scratch and clobber it in order to avoid dependencies
20552 ;; - use already live register
20553 ;; We can't use the second way right now, since there is no reliable way how to
20554 ;; verify that given register is live.  First choice will also most likely in
20555 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20556 ;; call clobbered registers are dead.  We may want to use base pointer as an
20557 ;; alternative when no register is available later.
20559 (define_peephole2
20560   [(match_scratch:SI 0 "r")
20561    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20562               (clobber (reg:CC FLAGS_REG))
20563               (clobber (mem:BLK (scratch)))])]
20564   "optimize_size || !TARGET_SUB_ESP_4"
20565   [(clobber (match_dup 0))
20566    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20567               (clobber (mem:BLK (scratch)))])])
20569 (define_peephole2
20570   [(match_scratch:SI 0 "r")
20571    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20572               (clobber (reg:CC FLAGS_REG))
20573               (clobber (mem:BLK (scratch)))])]
20574   "optimize_size || !TARGET_SUB_ESP_8"
20575   [(clobber (match_dup 0))
20576    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20577    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20578               (clobber (mem:BLK (scratch)))])])
20580 ;; Convert esp subtractions to push.
20581 (define_peephole2
20582   [(match_scratch:SI 0 "r")
20583    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20584               (clobber (reg:CC FLAGS_REG))])]
20585   "optimize_size || !TARGET_SUB_ESP_4"
20586   [(clobber (match_dup 0))
20587    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20589 (define_peephole2
20590   [(match_scratch:SI 0 "r")
20591    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20592               (clobber (reg:CC FLAGS_REG))])]
20593   "optimize_size || !TARGET_SUB_ESP_8"
20594   [(clobber (match_dup 0))
20595    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20596    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20598 ;; Convert epilogue deallocator to pop.
20599 (define_peephole2
20600   [(match_scratch:SI 0 "r")
20601    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20602               (clobber (reg:CC FLAGS_REG))
20603               (clobber (mem:BLK (scratch)))])]
20604   "optimize_size || !TARGET_ADD_ESP_4"
20605   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20606               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20607               (clobber (mem:BLK (scratch)))])]
20608   "")
20610 ;; Two pops case is tricky, since pop causes dependency on destination register.
20611 ;; We use two registers if available.
20612 (define_peephole2
20613   [(match_scratch:SI 0 "r")
20614    (match_scratch:SI 1 "r")
20615    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20616               (clobber (reg:CC FLAGS_REG))
20617               (clobber (mem:BLK (scratch)))])]
20618   "optimize_size || !TARGET_ADD_ESP_8"
20619   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20620               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20621               (clobber (mem:BLK (scratch)))])
20622    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20623               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20624   "")
20626 (define_peephole2
20627   [(match_scratch:SI 0 "r")
20628    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20629               (clobber (reg:CC FLAGS_REG))
20630               (clobber (mem:BLK (scratch)))])]
20631   "optimize_size"
20632   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20633               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20634               (clobber (mem:BLK (scratch)))])
20635    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20636               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20637   "")
20639 ;; Convert esp additions to pop.
20640 (define_peephole2
20641   [(match_scratch:SI 0 "r")
20642    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20643               (clobber (reg:CC FLAGS_REG))])]
20644   ""
20645   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20646               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20647   "")
20649 ;; Two pops case is tricky, since pop causes dependency on destination register.
20650 ;; We use two registers if available.
20651 (define_peephole2
20652   [(match_scratch:SI 0 "r")
20653    (match_scratch:SI 1 "r")
20654    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20655               (clobber (reg:CC FLAGS_REG))])]
20656   ""
20657   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20658               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20659    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20660               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20661   "")
20663 (define_peephole2
20664   [(match_scratch:SI 0 "r")
20665    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20666               (clobber (reg:CC FLAGS_REG))])]
20667   "optimize_size"
20668   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20669               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20670    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20671               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20672   "")
20674 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20675 ;; required and register dies.  Similarly for 128 to plus -128.
20676 (define_peephole2
20677   [(set (match_operand 0 "flags_reg_operand" "")
20678         (match_operator 1 "compare_operator"
20679           [(match_operand 2 "register_operand" "")
20680            (match_operand 3 "const_int_operand" "")]))]
20681   "(INTVAL (operands[3]) == -1
20682     || INTVAL (operands[3]) == 1
20683     || INTVAL (operands[3]) == 128)
20684    && ix86_match_ccmode (insn, CCGCmode)
20685    && peep2_reg_dead_p (1, operands[2])"
20686   [(parallel [(set (match_dup 0)
20687                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20688               (clobber (match_dup 2))])]
20689   "")
20691 (define_peephole2
20692   [(match_scratch:DI 0 "r")
20693    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20694               (clobber (reg:CC FLAGS_REG))
20695               (clobber (mem:BLK (scratch)))])]
20696   "optimize_size || !TARGET_SUB_ESP_4"
20697   [(clobber (match_dup 0))
20698    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20699               (clobber (mem:BLK (scratch)))])])
20701 (define_peephole2
20702   [(match_scratch:DI 0 "r")
20703    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20704               (clobber (reg:CC FLAGS_REG))
20705               (clobber (mem:BLK (scratch)))])]
20706   "optimize_size || !TARGET_SUB_ESP_8"
20707   [(clobber (match_dup 0))
20708    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20709    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20710               (clobber (mem:BLK (scratch)))])])
20712 ;; Convert esp subtractions to push.
20713 (define_peephole2
20714   [(match_scratch:DI 0 "r")
20715    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20716               (clobber (reg:CC FLAGS_REG))])]
20717   "optimize_size || !TARGET_SUB_ESP_4"
20718   [(clobber (match_dup 0))
20719    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20721 (define_peephole2
20722   [(match_scratch:DI 0 "r")
20723    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20724               (clobber (reg:CC FLAGS_REG))])]
20725   "optimize_size || !TARGET_SUB_ESP_8"
20726   [(clobber (match_dup 0))
20727    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20728    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20730 ;; Convert epilogue deallocator to pop.
20731 (define_peephole2
20732   [(match_scratch:DI 0 "r")
20733    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20734               (clobber (reg:CC FLAGS_REG))
20735               (clobber (mem:BLK (scratch)))])]
20736   "optimize_size || !TARGET_ADD_ESP_4"
20737   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20738               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20739               (clobber (mem:BLK (scratch)))])]
20740   "")
20742 ;; Two pops case is tricky, since pop causes dependency on destination register.
20743 ;; We use two registers if available.
20744 (define_peephole2
20745   [(match_scratch:DI 0 "r")
20746    (match_scratch:DI 1 "r")
20747    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20748               (clobber (reg:CC FLAGS_REG))
20749               (clobber (mem:BLK (scratch)))])]
20750   "optimize_size || !TARGET_ADD_ESP_8"
20751   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20752               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20753               (clobber (mem:BLK (scratch)))])
20754    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20755               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20756   "")
20758 (define_peephole2
20759   [(match_scratch:DI 0 "r")
20760    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20761               (clobber (reg:CC FLAGS_REG))
20762               (clobber (mem:BLK (scratch)))])]
20763   "optimize_size"
20764   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20765               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20766               (clobber (mem:BLK (scratch)))])
20767    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20768               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20769   "")
20771 ;; Convert esp additions to pop.
20772 (define_peephole2
20773   [(match_scratch:DI 0 "r")
20774    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20775               (clobber (reg:CC FLAGS_REG))])]
20776   ""
20777   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20778               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20779   "")
20781 ;; Two pops case is tricky, since pop causes dependency on destination register.
20782 ;; We use two registers if available.
20783 (define_peephole2
20784   [(match_scratch:DI 0 "r")
20785    (match_scratch:DI 1 "r")
20786    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20787               (clobber (reg:CC FLAGS_REG))])]
20788   ""
20789   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20790               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20791    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20792               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20793   "")
20795 (define_peephole2
20796   [(match_scratch:DI 0 "r")
20797    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20798               (clobber (reg:CC FLAGS_REG))])]
20799   "optimize_size"
20800   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20801               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20802    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20803               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20804   "")
20806 ;; Convert imul by three, five and nine into lea
20807 (define_peephole2
20808   [(parallel
20809     [(set (match_operand:SI 0 "register_operand" "")
20810           (mult:SI (match_operand:SI 1 "register_operand" "")
20811                    (match_operand:SI 2 "const_int_operand" "")))
20812      (clobber (reg:CC FLAGS_REG))])]
20813   "INTVAL (operands[2]) == 3
20814    || INTVAL (operands[2]) == 5
20815    || INTVAL (operands[2]) == 9"
20816   [(set (match_dup 0)
20817         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20818                  (match_dup 1)))]
20819   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20821 (define_peephole2
20822   [(parallel
20823     [(set (match_operand:SI 0 "register_operand" "")
20824           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20825                    (match_operand:SI 2 "const_int_operand" "")))
20826      (clobber (reg:CC FLAGS_REG))])]
20827   "!optimize_size
20828    && (INTVAL (operands[2]) == 3
20829        || INTVAL (operands[2]) == 5
20830        || INTVAL (operands[2]) == 9)"
20831   [(set (match_dup 0) (match_dup 1))
20832    (set (match_dup 0)
20833         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20834                  (match_dup 0)))]
20835   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20837 (define_peephole2
20838   [(parallel
20839     [(set (match_operand:DI 0 "register_operand" "")
20840           (mult:DI (match_operand:DI 1 "register_operand" "")
20841                    (match_operand:DI 2 "const_int_operand" "")))
20842      (clobber (reg:CC FLAGS_REG))])]
20843   "TARGET_64BIT
20844    && (INTVAL (operands[2]) == 3
20845        || INTVAL (operands[2]) == 5
20846        || INTVAL (operands[2]) == 9)"
20847   [(set (match_dup 0)
20848         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20849                  (match_dup 1)))]
20850   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20852 (define_peephole2
20853   [(parallel
20854     [(set (match_operand:DI 0 "register_operand" "")
20855           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20856                    (match_operand:DI 2 "const_int_operand" "")))
20857      (clobber (reg:CC FLAGS_REG))])]
20858   "TARGET_64BIT
20859    && !optimize_size
20860    && (INTVAL (operands[2]) == 3
20861        || INTVAL (operands[2]) == 5
20862        || INTVAL (operands[2]) == 9)"
20863   [(set (match_dup 0) (match_dup 1))
20864    (set (match_dup 0)
20865         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20866                  (match_dup 0)))]
20867   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20869 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20870 ;; imul $32bit_imm, reg, reg is direct decoded.
20871 (define_peephole2
20872   [(match_scratch:DI 3 "r")
20873    (parallel [(set (match_operand:DI 0 "register_operand" "")
20874                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20875                             (match_operand:DI 2 "immediate_operand" "")))
20876               (clobber (reg:CC FLAGS_REG))])]
20877   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20878    && !satisfies_constraint_K (operands[2])"
20879   [(set (match_dup 3) (match_dup 1))
20880    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20881               (clobber (reg:CC FLAGS_REG))])]
20884 (define_peephole2
20885   [(match_scratch:SI 3 "r")
20886    (parallel [(set (match_operand:SI 0 "register_operand" "")
20887                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20888                             (match_operand:SI 2 "immediate_operand" "")))
20889               (clobber (reg:CC FLAGS_REG))])]
20890   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20891    && !satisfies_constraint_K (operands[2])"
20892   [(set (match_dup 3) (match_dup 1))
20893    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20894               (clobber (reg:CC FLAGS_REG))])]
20897 (define_peephole2
20898   [(match_scratch:SI 3 "r")
20899    (parallel [(set (match_operand:DI 0 "register_operand" "")
20900                    (zero_extend:DI
20901                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20902                               (match_operand:SI 2 "immediate_operand" ""))))
20903               (clobber (reg:CC FLAGS_REG))])]
20904   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20905    && !satisfies_constraint_K (operands[2])"
20906   [(set (match_dup 3) (match_dup 1))
20907    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20908               (clobber (reg:CC FLAGS_REG))])]
20911 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20912 ;; Convert it into imul reg, reg
20913 ;; It would be better to force assembler to encode instruction using long
20914 ;; immediate, but there is apparently no way to do so.
20915 (define_peephole2
20916   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20917                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20918                             (match_operand:DI 2 "const_int_operand" "")))
20919               (clobber (reg:CC FLAGS_REG))])
20920    (match_scratch:DI 3 "r")]
20921   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20922    && satisfies_constraint_K (operands[2])"
20923   [(set (match_dup 3) (match_dup 2))
20924    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20925               (clobber (reg:CC FLAGS_REG))])]
20927   if (!rtx_equal_p (operands[0], operands[1]))
20928     emit_move_insn (operands[0], operands[1]);
20931 (define_peephole2
20932   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20933                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20934                             (match_operand:SI 2 "const_int_operand" "")))
20935               (clobber (reg:CC FLAGS_REG))])
20936    (match_scratch:SI 3 "r")]
20937   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20938    && satisfies_constraint_K (operands[2])"
20939   [(set (match_dup 3) (match_dup 2))
20940    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20941               (clobber (reg:CC FLAGS_REG))])]
20943   if (!rtx_equal_p (operands[0], operands[1]))
20944     emit_move_insn (operands[0], operands[1]);
20947 (define_peephole2
20948   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20949                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20950                             (match_operand:HI 2 "immediate_operand" "")))
20951               (clobber (reg:CC FLAGS_REG))])
20952    (match_scratch:HI 3 "r")]
20953   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20954   [(set (match_dup 3) (match_dup 2))
20955    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20956               (clobber (reg:CC FLAGS_REG))])]
20958   if (!rtx_equal_p (operands[0], operands[1]))
20959     emit_move_insn (operands[0], operands[1]);
20962 ;; After splitting up read-modify operations, array accesses with memory
20963 ;; operands might end up in form:
20964 ;;  sall    $2, %eax
20965 ;;  movl    4(%esp), %edx
20966 ;;  addl    %edx, %eax
20967 ;; instead of pre-splitting:
20968 ;;  sall    $2, %eax
20969 ;;  addl    4(%esp), %eax
20970 ;; Turn it into:
20971 ;;  movl    4(%esp), %edx
20972 ;;  leal    (%edx,%eax,4), %eax
20974 (define_peephole2
20975   [(parallel [(set (match_operand 0 "register_operand" "")
20976                    (ashift (match_operand 1 "register_operand" "")
20977                            (match_operand 2 "const_int_operand" "")))
20978                (clobber (reg:CC FLAGS_REG))])
20979    (set (match_operand 3 "register_operand")
20980         (match_operand 4 "x86_64_general_operand" ""))
20981    (parallel [(set (match_operand 5 "register_operand" "")
20982                    (plus (match_operand 6 "register_operand" "")
20983                          (match_operand 7 "register_operand" "")))
20984                    (clobber (reg:CC FLAGS_REG))])]
20985   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20986    /* Validate MODE for lea.  */
20987    && ((!TARGET_PARTIAL_REG_STALL
20988         && (GET_MODE (operands[0]) == QImode
20989             || GET_MODE (operands[0]) == HImode))
20990        || GET_MODE (operands[0]) == SImode
20991        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20992    /* We reorder load and the shift.  */
20993    && !rtx_equal_p (operands[1], operands[3])
20994    && !reg_overlap_mentioned_p (operands[0], operands[4])
20995    /* Last PLUS must consist of operand 0 and 3.  */
20996    && !rtx_equal_p (operands[0], operands[3])
20997    && (rtx_equal_p (operands[3], operands[6])
20998        || rtx_equal_p (operands[3], operands[7]))
20999    && (rtx_equal_p (operands[0], operands[6])
21000        || rtx_equal_p (operands[0], operands[7]))
21001    /* The intermediate operand 0 must die or be same as output.  */
21002    && (rtx_equal_p (operands[0], operands[5])
21003        || peep2_reg_dead_p (3, operands[0]))"
21004   [(set (match_dup 3) (match_dup 4))
21005    (set (match_dup 0) (match_dup 1))]
21007   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21008   int scale = 1 << INTVAL (operands[2]);
21009   rtx index = gen_lowpart (Pmode, operands[1]);
21010   rtx base = gen_lowpart (Pmode, operands[3]);
21011   rtx dest = gen_lowpart (mode, operands[5]);
21013   operands[1] = gen_rtx_PLUS (Pmode, base,
21014                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21015   if (mode != Pmode)
21016     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21017   operands[0] = dest;
21020 ;; Call-value patterns last so that the wildcard operand does not
21021 ;; disrupt insn-recog's switch tables.
21023 (define_insn "*call_value_pop_0"
21024   [(set (match_operand 0 "" "")
21025         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21026               (match_operand:SI 2 "" "")))
21027    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21028                             (match_operand:SI 3 "immediate_operand" "")))]
21029   "!TARGET_64BIT"
21031   if (SIBLING_CALL_P (insn))
21032     return "jmp\t%P1";
21033   else
21034     return "call\t%P1";
21036   [(set_attr "type" "callv")])
21038 (define_insn "*call_value_pop_1"
21039   [(set (match_operand 0 "" "")
21040         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21041               (match_operand:SI 2 "" "")))
21042    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21043                             (match_operand:SI 3 "immediate_operand" "i")))]
21044   "!TARGET_64BIT"
21046   if (constant_call_address_operand (operands[1], Pmode))
21047     {
21048       if (SIBLING_CALL_P (insn))
21049         return "jmp\t%P1";
21050       else
21051         return "call\t%P1";
21052     }
21053   if (SIBLING_CALL_P (insn))
21054     return "jmp\t%A1";
21055   else
21056     return "call\t%A1";
21058   [(set_attr "type" "callv")])
21060 (define_insn "*call_value_0"
21061   [(set (match_operand 0 "" "")
21062         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21063               (match_operand:SI 2 "" "")))]
21064   "!TARGET_64BIT"
21066   if (SIBLING_CALL_P (insn))
21067     return "jmp\t%P1";
21068   else
21069     return "call\t%P1";
21071   [(set_attr "type" "callv")])
21073 (define_insn "*call_value_0_rex64"
21074   [(set (match_operand 0 "" "")
21075         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21076               (match_operand:DI 2 "const_int_operand" "")))]
21077   "TARGET_64BIT"
21079   if (SIBLING_CALL_P (insn))
21080     return "jmp\t%P1";
21081   else
21082     return "call\t%P1";
21084   [(set_attr "type" "callv")])
21086 (define_insn "*call_value_1"
21087   [(set (match_operand 0 "" "")
21088         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21089               (match_operand:SI 2 "" "")))]
21090   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21092   if (constant_call_address_operand (operands[1], Pmode))
21093     return "call\t%P1";
21094   return "call\t%A1";
21096   [(set_attr "type" "callv")])
21098 (define_insn "*sibcall_value_1"
21099   [(set (match_operand 0 "" "")
21100         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21101               (match_operand:SI 2 "" "")))]
21102   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21104   if (constant_call_address_operand (operands[1], Pmode))
21105     return "jmp\t%P1";
21106   return "jmp\t%A1";
21108   [(set_attr "type" "callv")])
21110 (define_insn "*call_value_1_rex64"
21111   [(set (match_operand 0 "" "")
21112         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21113               (match_operand:DI 2 "" "")))]
21114   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21115    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21117   if (constant_call_address_operand (operands[1], Pmode))
21118     return "call\t%P1";
21119   return "call\t%A1";
21121   [(set_attr "type" "callv")])
21123 (define_insn "*call_value_1_rex64_large"
21124   [(set (match_operand 0 "" "")
21125         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21126               (match_operand:DI 2 "" "")))]
21127   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21128   "call\t%A1"
21129   [(set_attr "type" "callv")])
21131 (define_insn "*sibcall_value_1_rex64"
21132   [(set (match_operand 0 "" "")
21133         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21134               (match_operand:DI 2 "" "")))]
21135   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21136   "jmp\t%P1"
21137   [(set_attr "type" "callv")])
21139 (define_insn "*sibcall_value_1_rex64_v"
21140   [(set (match_operand 0 "" "")
21141         (call (mem:QI (reg:DI R11_REG))
21142               (match_operand:DI 1 "" "")))]
21143   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21144   "jmp\t{*%%}r11"
21145   [(set_attr "type" "callv")])
21147 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21148 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21149 ;; caught for use by garbage collectors and the like.  Using an insn that
21150 ;; maps to SIGILL makes it more likely the program will rightfully die.
21151 ;; Keeping with tradition, "6" is in honor of #UD.
21152 (define_insn "trap"
21153   [(trap_if (const_int 1) (const_int 6))]
21154   ""
21155   { return ASM_SHORT "0x0b0f"; }
21156   [(set_attr "length" "2")])
21158 (define_expand "sse_prologue_save"
21159   [(parallel [(set (match_operand:BLK 0 "" "")
21160                    (unspec:BLK [(reg:DI 21)
21161                                 (reg:DI 22)
21162                                 (reg:DI 23)
21163                                 (reg:DI 24)
21164                                 (reg:DI 25)
21165                                 (reg:DI 26)
21166                                 (reg:DI 27)
21167                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21168               (use (match_operand:DI 1 "register_operand" ""))
21169               (use (match_operand:DI 2 "immediate_operand" ""))
21170               (use (label_ref:DI (match_operand 3 "" "")))])]
21171   "TARGET_64BIT"
21172   "")
21174 (define_insn "*sse_prologue_save_insn"
21175   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21176                           (match_operand:DI 4 "const_int_operand" "n")))
21177         (unspec:BLK [(reg:DI 21)
21178                      (reg:DI 22)
21179                      (reg:DI 23)
21180                      (reg:DI 24)
21181                      (reg:DI 25)
21182                      (reg:DI 26)
21183                      (reg:DI 27)
21184                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21185    (use (match_operand:DI 1 "register_operand" "r"))
21186    (use (match_operand:DI 2 "const_int_operand" "i"))
21187    (use (label_ref:DI (match_operand 3 "" "X")))]
21188   "TARGET_64BIT
21189    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21190    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21191   "*
21193   int i;
21194   operands[0] = gen_rtx_MEM (Pmode,
21195                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21196   output_asm_insn (\"jmp\\t%A1\", operands);
21197   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21198     {
21199       operands[4] = adjust_address (operands[0], DImode, i*16);
21200       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21201       PUT_MODE (operands[4], TImode);
21202       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21203         output_asm_insn (\"rex\", operands);
21204       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21205     }
21206   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21207                              CODE_LABEL_NUMBER (operands[3]));
21208   return \"\";
21210   "
21211   [(set_attr "type" "other")
21212    (set_attr "length_immediate" "0")
21213    (set_attr "length_address" "0")
21214    (set_attr "length" "135")
21215    (set_attr "memory" "store")
21216    (set_attr "modrm" "0")
21217    (set_attr "mode" "DI")])
21219 (define_expand "prefetch"
21220   [(prefetch (match_operand 0 "address_operand" "")
21221              (match_operand:SI 1 "const_int_operand" "")
21222              (match_operand:SI 2 "const_int_operand" ""))]
21223   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21225   int rw = INTVAL (operands[1]);
21226   int locality = INTVAL (operands[2]);
21228   gcc_assert (rw == 0 || rw == 1);
21229   gcc_assert (locality >= 0 && locality <= 3);
21230   gcc_assert (GET_MODE (operands[0]) == Pmode
21231               || GET_MODE (operands[0]) == VOIDmode);
21233   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21234      supported by SSE counterpart or the SSE prefetch is not available
21235      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21236      of locality.  */
21237   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21238     operands[2] = GEN_INT (3);
21239   else
21240     operands[1] = const0_rtx;
21243 (define_insn "*prefetch_sse"
21244   [(prefetch (match_operand:SI 0 "address_operand" "p")
21245              (const_int 0)
21246              (match_operand:SI 1 "const_int_operand" ""))]
21247   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21249   static const char * const patterns[4] = {
21250    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21251   };
21253   int locality = INTVAL (operands[1]);
21254   gcc_assert (locality >= 0 && locality <= 3);
21256   return patterns[locality];
21258   [(set_attr "type" "sse")
21259    (set_attr "memory" "none")])
21261 (define_insn "*prefetch_sse_rex"
21262   [(prefetch (match_operand:DI 0 "address_operand" "p")
21263              (const_int 0)
21264              (match_operand:SI 1 "const_int_operand" ""))]
21265   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21267   static const char * const patterns[4] = {
21268    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21269   };
21271   int locality = INTVAL (operands[1]);
21272   gcc_assert (locality >= 0 && locality <= 3);
21274   return patterns[locality];
21276   [(set_attr "type" "sse")
21277    (set_attr "memory" "none")])
21279 (define_insn "*prefetch_3dnow"
21280   [(prefetch (match_operand:SI 0 "address_operand" "p")
21281              (match_operand:SI 1 "const_int_operand" "n")
21282              (const_int 3))]
21283   "TARGET_3DNOW && !TARGET_64BIT"
21285   if (INTVAL (operands[1]) == 0)
21286     return "prefetch\t%a0";
21287   else
21288     return "prefetchw\t%a0";
21290   [(set_attr "type" "mmx")
21291    (set_attr "memory" "none")])
21293 (define_insn "*prefetch_3dnow_rex"
21294   [(prefetch (match_operand:DI 0 "address_operand" "p")
21295              (match_operand:SI 1 "const_int_operand" "n")
21296              (const_int 3))]
21297   "TARGET_3DNOW && TARGET_64BIT"
21299   if (INTVAL (operands[1]) == 0)
21300     return "prefetch\t%a0";
21301   else
21302     return "prefetchw\t%a0";
21304   [(set_attr "type" "mmx")
21305    (set_attr "memory" "none")])
21307 (define_expand "stack_protect_set"
21308   [(match_operand 0 "memory_operand" "")
21309    (match_operand 1 "memory_operand" "")]
21310   ""
21312 #ifdef TARGET_THREAD_SSP_OFFSET
21313   if (TARGET_64BIT)
21314     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21315                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21316   else
21317     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21318                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21319 #else
21320   if (TARGET_64BIT)
21321     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21322   else
21323     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21324 #endif
21325   DONE;
21328 (define_insn "stack_protect_set_si"
21329   [(set (match_operand:SI 0 "memory_operand" "=m")
21330         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21331    (set (match_scratch:SI 2 "=&r") (const_int 0))
21332    (clobber (reg:CC FLAGS_REG))]
21333   ""
21334   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21335   [(set_attr "type" "multi")])
21337 (define_insn "stack_protect_set_di"
21338   [(set (match_operand:DI 0 "memory_operand" "=m")
21339         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21340    (set (match_scratch:DI 2 "=&r") (const_int 0))
21341    (clobber (reg:CC FLAGS_REG))]
21342   "TARGET_64BIT"
21343   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21344   [(set_attr "type" "multi")])
21346 (define_insn "stack_tls_protect_set_si"
21347   [(set (match_operand:SI 0 "memory_operand" "=m")
21348         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21349    (set (match_scratch:SI 2 "=&r") (const_int 0))
21350    (clobber (reg:CC FLAGS_REG))]
21351   ""
21352   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21353   [(set_attr "type" "multi")])
21355 (define_insn "stack_tls_protect_set_di"
21356   [(set (match_operand:DI 0 "memory_operand" "=m")
21357         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21358    (set (match_scratch:DI 2 "=&r") (const_int 0))
21359    (clobber (reg:CC FLAGS_REG))]
21360   "TARGET_64BIT"
21361   {
21362      /* The kernel uses a different segment register for performance reasons; a
21363         system call would not have to trash the userspace segment register,
21364         which would be expensive */
21365      if (ix86_cmodel != CM_KERNEL)
21366         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21367      else
21368         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21369   }
21370   [(set_attr "type" "multi")])
21372 (define_expand "stack_protect_test"
21373   [(match_operand 0 "memory_operand" "")
21374    (match_operand 1 "memory_operand" "")
21375    (match_operand 2 "" "")]
21376   ""
21378   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21379   ix86_compare_op0 = operands[0];
21380   ix86_compare_op1 = operands[1];
21381   ix86_compare_emitted = flags;
21383 #ifdef TARGET_THREAD_SSP_OFFSET
21384   if (TARGET_64BIT)
21385     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21386                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21387   else
21388     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21389                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21390 #else
21391   if (TARGET_64BIT)
21392     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21393   else
21394     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21395 #endif
21396   emit_jump_insn (gen_beq (operands[2]));
21397   DONE;
21400 (define_insn "stack_protect_test_si"
21401   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21402         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21403                      (match_operand:SI 2 "memory_operand" "m")]
21404                     UNSPEC_SP_TEST))
21405    (clobber (match_scratch:SI 3 "=&r"))]
21406   ""
21407   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21408   [(set_attr "type" "multi")])
21410 (define_insn "stack_protect_test_di"
21411   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21412         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21413                      (match_operand:DI 2 "memory_operand" "m")]
21414                     UNSPEC_SP_TEST))
21415    (clobber (match_scratch:DI 3 "=&r"))]
21416   "TARGET_64BIT"
21417   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21418   [(set_attr "type" "multi")])
21420 (define_insn "stack_tls_protect_test_si"
21421   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21422         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21423                      (match_operand:SI 2 "const_int_operand" "i")]
21424                     UNSPEC_SP_TLS_TEST))
21425    (clobber (match_scratch:SI 3 "=r"))]
21426   ""
21427   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21428   [(set_attr "type" "multi")])
21430 (define_insn "stack_tls_protect_test_di"
21431   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21432         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21433                      (match_operand:DI 2 "const_int_operand" "i")]
21434                     UNSPEC_SP_TLS_TEST))
21435    (clobber (match_scratch:DI 3 "=r"))]
21436   "TARGET_64BIT"
21437   {
21438      /* The kernel uses a different segment register for performance reasons; a
21439         system call would not have to trash the userspace segment register,
21440         which would be expensive */
21441      if (ix86_cmodel != CM_KERNEL)
21442         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21443      else
21444         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21445   }
21446   [(set_attr "type" "multi")])
21448 (define_mode_iterator CRC32MODE [QI HI SI])
21449 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21450 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21452 (define_insn "sse4_2_crc32<mode>"
21453   [(set (match_operand:SI 0 "register_operand" "=r")
21454         (unspec:SI
21455           [(match_operand:SI 1 "register_operand" "0")
21456            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21457           UNSPEC_CRC32))]
21458   "TARGET_SSE4_2"
21459   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21460   [(set_attr "type" "sselog1")
21461    (set_attr "prefix_rep" "1")
21462    (set_attr "prefix_extra" "1")
21463    (set_attr "mode" "SI")])
21465 (define_insn "sse4_2_crc32di"
21466   [(set (match_operand:DI 0 "register_operand" "=r")
21467         (unspec:DI
21468           [(match_operand:DI 1 "register_operand" "0")
21469            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21470           UNSPEC_CRC32))]
21471   "TARGET_SSE4_2 && TARGET_64BIT"
21472   "crc32q\t{%2, %0|%0, %2}"
21473   [(set_attr "type" "sselog1")
21474    (set_attr "prefix_rep" "1")
21475    (set_attr "prefix_extra" "1")
21476    (set_attr "mode" "DI")])
21478 (include "mmx.md")
21479 (include "sse.md")
21480 (include "sync.md")