Support ptr_mode != Pmode in x86_output_mi_thunk.
[gcc.git] / gcc / config / i386 / i386.md
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, 2009, 2010, 2011
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.
14 ;;
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.
19 ;;
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/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 ;; UNSPEC usage:
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81
82 ;; Prologue support
83 UNSPEC_STACK_ALLOC
84 UNSPEC_SET_GOT
85 UNSPEC_REG_SAVE
86 UNSPEC_DEF_CFA
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
112 UNSPEC_PAUSE
113
114 ;; For SSE/MMX support:
115 UNSPEC_FIX_NOTRUNC
116 UNSPEC_MASKMOV
117 UNSPEC_MOVMSK
118 UNSPEC_MOVNT
119 UNSPEC_MOVU
120 UNSPEC_RCP
121 UNSPEC_RSQRT
122 UNSPEC_SFENCE
123 UNSPEC_PFRCP
124 UNSPEC_PFRCPIT1
125 UNSPEC_PFRCPIT2
126 UNSPEC_PFRSQRT
127 UNSPEC_PFRSQIT1
128 UNSPEC_MFENCE
129 UNSPEC_LFENCE
130 UNSPEC_PSADBW
131 UNSPEC_LDDQU
132 UNSPEC_MS_TO_SYSV_CALL
133
134 ;; Generic math support
135 UNSPEC_COPYSIGN
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
138
139 ;; x87 Floating point
140 UNSPEC_SIN
141 UNSPEC_COS
142 UNSPEC_FPATAN
143 UNSPEC_FYL2X
144 UNSPEC_FYL2XP1
145 UNSPEC_FRNDINT
146 UNSPEC_FIST
147 UNSPEC_F2XM1
148 UNSPEC_TAN
149 UNSPEC_FXAM
150
151 ;; x87 Rounding
152 UNSPEC_FRNDINT_FLOOR
153 UNSPEC_FRNDINT_CEIL
154 UNSPEC_FRNDINT_TRUNC
155 UNSPEC_FRNDINT_MASK_PM
156 UNSPEC_FIST_FLOOR
157 UNSPEC_FIST_CEIL
158
159 ;; x87 Double output FP
160 UNSPEC_SINCOS_COS
161 UNSPEC_SINCOS_SIN
162 UNSPEC_XTRACT_FRACT
163 UNSPEC_XTRACT_EXP
164 UNSPEC_FSCALE_FRACT
165 UNSPEC_FSCALE_EXP
166 UNSPEC_FPREM_F
167 UNSPEC_FPREM_U
168 UNSPEC_FPREM1_F
169 UNSPEC_FPREM1_U
170
171 UNSPEC_C2_FLAG
172 UNSPEC_FXAM_MEM
173
174 ;; SSP patterns
175 UNSPEC_SP_SET
176 UNSPEC_SP_TEST
177 UNSPEC_SP_TLS_SET
178 UNSPEC_SP_TLS_TEST
179
180 ;; SSSE3
181 UNSPEC_PSHUFB
182 UNSPEC_PSIGN
183 UNSPEC_PALIGNR
184
185 ;; For SSE4A support
186 UNSPEC_EXTRQI
187 UNSPEC_EXTRQ
188 UNSPEC_INSERTQI
189 UNSPEC_INSERTQ
190
191 ;; For SSE4.1 support
192 UNSPEC_BLENDV
193 UNSPEC_INSERTPS
194 UNSPEC_DP
195 UNSPEC_MOVNTDQA
196 UNSPEC_MPSADBW
197 UNSPEC_PHMINPOSUW
198 UNSPEC_PTEST
199 UNSPEC_ROUND
200
201 ;; For SSE4.2 support
202 UNSPEC_CRC32
203 UNSPEC_PCMPESTR
204 UNSPEC_PCMPISTR
205
206 ;; For FMA4 support
207 UNSPEC_FMADDSUB
208 UNSPEC_XOP_UNSIGNED_CMP
209 UNSPEC_XOP_TRUEFALSE
210 UNSPEC_XOP_PERMUTE
211 UNSPEC_FRCZ
212
213 ;; For AES support
214 UNSPEC_AESENC
215 UNSPEC_AESENCLAST
216 UNSPEC_AESDEC
217 UNSPEC_AESDECLAST
218 UNSPEC_AESIMC
219 UNSPEC_AESKEYGENASSIST
220
221 ;; For PCLMUL support
222 UNSPEC_PCLMUL
223
224 ;; For AVX support
225 UNSPEC_PCMP
226 UNSPEC_VPERMIL
227 UNSPEC_VPERMIL2
228 UNSPEC_VPERMIL2F128
229 UNSPEC_CAST
230 UNSPEC_VTESTP
231 UNSPEC_VCVTPH2PS
232 UNSPEC_VCVTPS2PH
233
234 ;; For BMI support
235 UNSPEC_BEXTR
236
237 ;; For RDRAND support
238 UNSPEC_RDRAND
239 ])
240
241 (define_c_enum "unspecv" [
242 UNSPECV_BLOCKAGE
243 UNSPECV_STACK_PROBE
244 UNSPECV_PROBE_STACK_RANGE
245 UNSPECV_EMMS
246 UNSPECV_LDMXCSR
247 UNSPECV_STMXCSR
248 UNSPECV_FEMMS
249 UNSPECV_CLFLUSH
250 UNSPECV_ALIGN
251 UNSPECV_MONITOR
252 UNSPECV_MWAIT
253 UNSPECV_CMPXCHG
254 UNSPECV_XCHG
255 UNSPECV_LOCK
256 UNSPECV_PROLOGUE_USE
257 UNSPECV_CLD
258 UNSPECV_NOPS
259 UNSPECV_VZEROALL
260 UNSPECV_VZEROUPPER
261 UNSPECV_RDTSC
262 UNSPECV_RDTSCP
263 UNSPECV_RDPMC
264 UNSPECV_LLWP_INTRINSIC
265 UNSPECV_SLWP_INTRINSIC
266 UNSPECV_LWPVAL_INTRINSIC
267 UNSPECV_LWPINS_INTRINSIC
268 UNSPECV_RDFSBASE
269 UNSPECV_RDGSBASE
270 UNSPECV_WRFSBASE
271 UNSPECV_WRGSBASE
272 UNSPECV_SPLIT_STACK_RETURN
273 ])
274
275 ;; Constants to represent rounding modes in the ROUND instruction
276 (define_constants
277 [(ROUND_FLOOR 0x1)
278 (ROUND_CEIL 0x2)
279 (ROUND_TRUNC 0x3)
280 (ROUND_MXCSR 0x4)
281 (ROUND_NO_EXC 0x8)
282 ])
283
284 ;; Constants to represent pcomtrue/pcomfalse variants
285 (define_constants
286 [(PCOM_FALSE 0)
287 (PCOM_TRUE 1)
288 (COM_FALSE_S 2)
289 (COM_FALSE_P 3)
290 (COM_TRUE_S 4)
291 (COM_TRUE_P 5)
292 ])
293
294 ;; Constants used in the XOP pperm instruction
295 (define_constants
296 [(PPERM_SRC 0x00) /* copy source */
297 (PPERM_INVERT 0x20) /* invert source */
298 (PPERM_REVERSE 0x40) /* bit reverse source */
299 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
300 (PPERM_ZERO 0x80) /* all 0's */
301 (PPERM_ONES 0xa0) /* all 1's */
302 (PPERM_SIGN 0xc0) /* propagate sign bit */
303 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
304 (PPERM_SRC1 0x00) /* use first source byte */
305 (PPERM_SRC2 0x10) /* use second source byte */
306 ])
307
308 ;; Registers by name.
309 (define_constants
310 [(AX_REG 0)
311 (DX_REG 1)
312 (CX_REG 2)
313 (BX_REG 3)
314 (SI_REG 4)
315 (DI_REG 5)
316 (BP_REG 6)
317 (SP_REG 7)
318 (ST0_REG 8)
319 (ST1_REG 9)
320 (ST2_REG 10)
321 (ST3_REG 11)
322 (ST4_REG 12)
323 (ST5_REG 13)
324 (ST6_REG 14)
325 (ST7_REG 15)
326 (FLAGS_REG 17)
327 (FPSR_REG 18)
328 (FPCR_REG 19)
329 (XMM0_REG 21)
330 (XMM1_REG 22)
331 (XMM2_REG 23)
332 (XMM3_REG 24)
333 (XMM4_REG 25)
334 (XMM5_REG 26)
335 (XMM6_REG 27)
336 (XMM7_REG 28)
337 (MM0_REG 29)
338 (MM1_REG 30)
339 (MM2_REG 31)
340 (MM3_REG 32)
341 (MM4_REG 33)
342 (MM5_REG 34)
343 (MM6_REG 35)
344 (MM7_REG 36)
345 (R8_REG 37)
346 (R9_REG 38)
347 (R10_REG 39)
348 (R11_REG 40)
349 (R12_REG 41)
350 (R13_REG 42)
351 (XMM8_REG 45)
352 (XMM9_REG 46)
353 (XMM10_REG 47)
354 (XMM11_REG 48)
355 (XMM12_REG 49)
356 (XMM13_REG 50)
357 (XMM14_REG 51)
358 (XMM15_REG 52)
359 ])
360
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; from i386.c.
363
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first. This allows for better optimization. For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
368
369 \f
370 ;; Processor type.
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372 atom,generic64,amdfam10,bdver1,bdver2,btver1"
373 (const (symbol_ref "ix86_schedule")))
374
375 ;; A basic instruction type. Refinements due to arguments to be
376 ;; provided in other attributes.
377 (define_attr "type"
378 "other,multi,
379 alu,alu1,negnot,imov,imovx,lea,
380 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381 icmp,test,ibr,setcc,icmov,
382 push,pop,call,callv,leave,
383 str,bitmanip,
384 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387 ssemuladd,sse4arg,lwp,
388 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389 (const_string "other"))
390
391 ;; Main data type used by the insn
392 (define_attr "mode"
393 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394 (const_string "unknown"))
395
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
403 (const_string "sse")
404 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
405 (const_string "mmx")
406 (eq_attr "type" "other")
407 (const_string "unknown")]
408 (const_string "integer")))
409
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413 bitmanip")
414 (const_int 0)
415 (eq_attr "unit" "i387,sse,mmx")
416 (const_int 0)
417 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
418 imul,icmp,push,pop")
419 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420 (eq_attr "type" "imov,test")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422 (eq_attr "type" "call")
423 (if_then_else (match_operand 0 "constant_call_address_operand" "")
424 (const_int 4)
425 (const_int 0))
426 (eq_attr "type" "callv")
427 (if_then_else (match_operand 1 "constant_call_address_operand" "")
428 (const_int 4)
429 (const_int 0))
430 ;; We don't know the size before shorten_branches. Expect
431 ;; the instruction to fit for better scheduling.
432 (eq_attr "type" "ibr")
433 (const_int 1)
434 ]
435 (symbol_ref "/* Update immediate_length and other attributes! */
436 gcc_unreachable (),1")))
437
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440 (cond [(eq_attr "type" "str,other,multi,fxch")
441 (const_int 0)
442 (and (eq_attr "type" "call")
443 (match_operand 0 "constant_call_address_operand" ""))
444 (const_int 0)
445 (and (eq_attr "type" "callv")
446 (match_operand 1 "constant_call_address_operand" ""))
447 (const_int 0)
448 ]
449 (symbol_ref "ix86_attr_length_address_default (insn)")))
450
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
454 (const_int 0)
455 (eq_attr "mode" "HI")
456 (const_int 1)
457 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
458 (const_int 1)
459 ]
460 (const_int 0)))
461
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
465 (const_int 0)
466 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
467 (const_int 1)
468 ]
469 (const_int 0)))
470
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
473 (if_then_else
474 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475 (eq_attr "unit" "sse,mmx"))
476 (const_int 1)
477 (const_int 0)))
478
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
482 (const_int 0)
483 (and (eq_attr "mode" "DI")
484 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485 (eq_attr "unit" "!mmx")))
486 (const_int 1)
487 (and (eq_attr "mode" "QI")
488 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489 (const_int 0)))
490 (const_int 1)
491 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492 (const_int 0))
493 (const_int 1)
494 (and (eq_attr "type" "imovx")
495 (match_operand:QI 1 "ext_QIreg_operand" ""))
496 (const_int 1)
497 ]
498 (const_int 0)))
499
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg")
506 (const_int 2)
507 (eq_attr "type" "sseiadd1,ssecvt1")
508 (const_int 1)
509 ]
510 (const_int 0)))
511
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
515 (const_string "vex")
516 (const_string "orig")))
517
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
520
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526 (if_then_else (and (eq_attr "prefix_0f" "1")
527 (eq_attr "prefix_extra" "0"))
528 (if_then_else (eq_attr "prefix_vex_w" "1")
529 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
534
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537 (cond [(eq_attr "type" "str,leave")
538 (const_int 0)
539 (eq_attr "unit" "i387")
540 (const_int 0)
541 (and (eq_attr "type" "incdec")
542 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543 (ior (match_operand:SI 1 "register_operand" "")
544 (match_operand:HI 1 "register_operand" ""))))
545 (const_int 0)
546 (and (eq_attr "type" "push")
547 (not (match_operand 1 "memory_operand" "")))
548 (const_int 0)
549 (and (eq_attr "type" "pop")
550 (not (match_operand 0 "memory_operand" "")))
551 (const_int 0)
552 (and (eq_attr "type" "imov")
553 (and (not (eq_attr "mode" "DI"))
554 (ior (and (match_operand 0 "register_operand" "")
555 (match_operand 1 "immediate_operand" ""))
556 (ior (and (match_operand 0 "ax_reg_operand" "")
557 (match_operand 1 "memory_displacement_only_operand" ""))
558 (and (match_operand 0 "memory_displacement_only_operand" "")
559 (match_operand 1 "ax_reg_operand" ""))))))
560 (const_int 0)
561 (and (eq_attr "type" "call")
562 (match_operand 0 "constant_call_address_operand" ""))
563 (const_int 0)
564 (and (eq_attr "type" "callv")
565 (match_operand 1 "constant_call_address_operand" ""))
566 (const_int 0)
567 (and (eq_attr "type" "alu,alu1,icmp,test")
568 (match_operand 0 "ax_reg_operand" ""))
569 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
570 ]
571 (const_int 1)))
572
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
576 ;; other insns.
577 (define_attr "length" ""
578 (cond [(eq_attr "type" "other,multi,fistp,frndint")
579 (const_int 16)
580 (eq_attr "type" "fcmp")
581 (const_int 4)
582 (eq_attr "unit" "i387")
583 (plus (const_int 2)
584 (plus (attr "prefix_data16")
585 (attr "length_address")))
586 (ior (eq_attr "prefix" "vex")
587 (and (eq_attr "prefix" "maybe_vex")
588 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589 (plus (attr "length_vex")
590 (plus (attr "length_immediate")
591 (plus (attr "modrm")
592 (attr "length_address"))))]
593 (plus (plus (attr "modrm")
594 (plus (attr "prefix_0f")
595 (plus (attr "prefix_rex")
596 (plus (attr "prefix_extra")
597 (const_int 1)))))
598 (plus (attr "prefix_rep")
599 (plus (attr "prefix_data16")
600 (plus (attr "length_immediate")
601 (attr "length_address")))))))
602
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
606
607 (define_attr "memory" "none,load,store,both,unknown"
608 (cond [(eq_attr "type" "other,multi,str,lwp")
609 (const_string "unknown")
610 (eq_attr "type" "lea,fcmov,fpspc")
611 (const_string "none")
612 (eq_attr "type" "fistp,leave")
613 (const_string "both")
614 (eq_attr "type" "frndint")
615 (const_string "load")
616 (eq_attr "type" "push")
617 (if_then_else (match_operand 1 "memory_operand" "")
618 (const_string "both")
619 (const_string "store"))
620 (eq_attr "type" "pop")
621 (if_then_else (match_operand 0 "memory_operand" "")
622 (const_string "both")
623 (const_string "load"))
624 (eq_attr "type" "setcc")
625 (if_then_else (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (const_string "none"))
628 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629 (if_then_else (ior (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "load")
632 (const_string "none"))
633 (eq_attr "type" "ibr")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "load")
636 (const_string "none"))
637 (eq_attr "type" "call")
638 (if_then_else (match_operand 0 "constant_call_address_operand" "")
639 (const_string "none")
640 (const_string "load"))
641 (eq_attr "type" "callv")
642 (if_then_else (match_operand 1 "constant_call_address_operand" "")
643 (const_string "none")
644 (const_string "load"))
645 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646 (match_operand 1 "memory_operand" ""))
647 (const_string "both")
648 (and (match_operand 0 "memory_operand" "")
649 (match_operand 1 "memory_operand" ""))
650 (const_string "both")
651 (match_operand 0 "memory_operand" "")
652 (const_string "store")
653 (match_operand 1 "memory_operand" "")
654 (const_string "load")
655 (and (eq_attr "type"
656 "!alu1,negnot,ishift1,
657 imov,imovx,icmp,test,bitmanip,
658 fmov,fcmp,fsgn,
659 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661 (match_operand 2 "memory_operand" ""))
662 (const_string "load")
663 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664 (match_operand 3 "memory_operand" ""))
665 (const_string "load")
666 ]
667 (const_string "none")))
668
669 ;; Indicates if an instruction has both an immediate and a displacement.
670
671 (define_attr "imm_disp" "false,true,unknown"
672 (cond [(eq_attr "type" "other,multi")
673 (const_string "unknown")
674 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675 (and (match_operand 0 "memory_displacement_operand" "")
676 (match_operand 1 "immediate_operand" "")))
677 (const_string "true")
678 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679 (and (match_operand 0 "memory_displacement_operand" "")
680 (match_operand 2 "immediate_operand" "")))
681 (const_string "true")
682 ]
683 (const_string "false")))
684
685 ;; Indicates if an FP operation has an integer source.
686
687 (define_attr "fp_int_src" "false,true"
688 (const_string "false"))
689
690 ;; Defines rounding mode of an FP operation.
691
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693 (const_string "any"))
694
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
697
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
700
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703 (const_string "base"))
704
705 (define_attr "enabled" ""
706 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
708 ]
709 (const_int 1)))
710
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713 [(set_attr "length" "128")
714 (set_attr "type" "multi")])
715
716 (define_code_iterator plusminus [plus minus])
717
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
719
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727 [(plus "add") (ss_plus "adds") (us_plus "addus")
728 (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730 [(plus "adc") (minus "sbb")])
731
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734 (minus "") (ss_minus "") (us_minus "")])
735
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
738
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
741
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744 (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
746
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
750
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
753
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
756
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
759
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
762
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
765
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
768
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
771
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
774
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
777
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
780
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783 (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
785
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
788
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791 (div "i") (udiv "")])
792
793 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
795
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
798
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
801
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
804
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
807
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
810
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
813
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
816
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
819
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI DI (TI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
828 SI (DI "TARGET_64BIT")])
829
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832 (HI "TARGET_HIMODE_MATH")
833 SI])
834
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837 SI (DI "TARGET_64BIT")])
838
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841 (TI "TARGET_64BIT")])
842
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
846
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849 (DI "TARGET_64BIT")])
850
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
853
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
856 (HI "WORD")
857 (SI "DWORD")
858 (DI "QWORD")])
859
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
862
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
865
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
868
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "iF") (DI "e")])
871
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
874
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877 [(QI "general_operand")
878 (HI "general_operand")
879 (SI "general_operand")
880 (DI "x86_64_general_operand")
881 (TI "x86_64_general_operand")])
882
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885 [(QI "general_operand")
886 (HI "general_operand")
887 (SI "general_operand")
888 (DI "x86_64_szext_general_operand")])
889
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892 [(QI "immediate_operand")
893 (HI "immediate_operand")
894 (SI "immediate_operand")
895 (DI "x86_64_immediate_operand")])
896
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899 [(QI "nonmemory_operand")
900 (HI "nonmemory_operand")
901 (SI "nonmemory_operand")
902 (DI "x86_64_nonmemory_operand")])
903
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906 [(QI "nonimmediate_operand")
907 (HI "nonimmediate_operand")
908 (SI "nonimmediate_operand")
909 (DI "shiftdi_operand")
910 (TI "register_operand")])
911
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914 [(QI "const_1_to_31_operand")
915 (HI "const_1_to_31_operand")
916 (SI "const_1_to_31_operand")
917 (DI "const_1_to_63_operand")])
918
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921 [(QI "nonimmediate_operand")
922 (HI "nonimmediate_operand")
923 (SI "nonimmediate_operand")
924 (DI "ashldi_input_operand")
925 (TI "reg_or_pm1_operand")])
926
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
929
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
932
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
935 [(SF "ss") (DF "sd")
936 (V8SF "ps") (V4DF "pd")
937 (V4SF "ps") (V2DF "pd")
938 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
939 (V8SI "si")])
940
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
943
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
947
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
950
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
954 \f
955 ;; Scheduling descriptions
956
957 (include "pentium.md")
958 (include "ppro.md")
959 (include "k6.md")
960 (include "athlon.md")
961 (include "bdver1.md")
962 (include "geode.md")
963 (include "atom.md")
964 (include "core2.md")
965
966 \f
967 ;; Operand and operator predicates and constraints
968
969 (include "predicates.md")
970 (include "constraints.md")
971
972 \f
973 ;; Compare and branch/compare and store instructions.
974
975 (define_expand "cbranch<mode>4"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978 (match_operand:SDWIM 2 "<general_operand>" "")))
979 (set (pc) (if_then_else
980 (match_operator 0 "ordered_comparison_operator"
981 [(reg:CC FLAGS_REG) (const_int 0)])
982 (label_ref (match_operand 3 "" ""))
983 (pc)))]
984 ""
985 {
986 if (MEM_P (operands[1]) && MEM_P (operands[2]))
987 operands[1] = force_reg (<MODE>mode, operands[1]);
988 ix86_expand_branch (GET_CODE (operands[0]),
989 operands[1], operands[2], operands[3]);
990 DONE;
991 })
992
993 (define_expand "cstore<mode>4"
994 [(set (reg:CC FLAGS_REG)
995 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996 (match_operand:SWIM 3 "<general_operand>" "")))
997 (set (match_operand:QI 0 "register_operand" "")
998 (match_operator 1 "ordered_comparison_operator"
999 [(reg:CC FLAGS_REG) (const_int 0)]))]
1000 ""
1001 {
1002 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003 operands[2] = force_reg (<MODE>mode, operands[2]);
1004 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005 operands[2], operands[3]);
1006 DONE;
1007 })
1008
1009 (define_expand "cmp<mode>_1"
1010 [(set (reg:CC FLAGS_REG)
1011 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012 (match_operand:SWI48 1 "<general_operand>" "")))])
1013
1014 (define_insn "*cmp<mode>_ccno_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017 (match_operand:SWI 1 "const0_operand" "")))]
1018 "ix86_match_ccmode (insn, CCNOmode)"
1019 "@
1020 test{<imodesuffix>}\t%0, %0
1021 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022 [(set_attr "type" "test,icmp")
1023 (set_attr "length_immediate" "0,1")
1024 (set_attr "mode" "<MODE>")])
1025
1026 (define_insn "*cmp<mode>_1"
1027 [(set (reg FLAGS_REG)
1028 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030 "ix86_match_ccmode (insn, CCmode)"
1031 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032 [(set_attr "type" "icmp")
1033 (set_attr "mode" "<MODE>")])
1034
1035 (define_insn "*cmp<mode>_minus_1"
1036 [(set (reg FLAGS_REG)
1037 (compare
1038 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1040 (const_int 0)))]
1041 "ix86_match_ccmode (insn, CCGOCmode)"
1042 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "<MODE>")])
1045
1046 (define_insn "*cmpqi_ext_1"
1047 [(set (reg FLAGS_REG)
1048 (compare
1049 (match_operand:QI 0 "general_operand" "Qm")
1050 (subreg:QI
1051 (zero_extract:SI
1052 (match_operand 1 "ext_register_operand" "Q")
1053 (const_int 8)
1054 (const_int 8)) 0)))]
1055 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%h1, %0|%0, %h1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "mode" "QI")])
1059
1060 (define_insn "*cmpqi_ext_1_rex64"
1061 [(set (reg FLAGS_REG)
1062 (compare
1063 (match_operand:QI 0 "register_operand" "Q")
1064 (subreg:QI
1065 (zero_extract:SI
1066 (match_operand 1 "ext_register_operand" "Q")
1067 (const_int 8)
1068 (const_int 8)) 0)))]
1069 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070 "cmp{b}\t{%h1, %0|%0, %h1}"
1071 [(set_attr "type" "icmp")
1072 (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_2"
1075 [(set (reg FLAGS_REG)
1076 (compare
1077 (subreg:QI
1078 (zero_extract:SI
1079 (match_operand 0 "ext_register_operand" "Q")
1080 (const_int 8)
1081 (const_int 8)) 0)
1082 (match_operand:QI 1 "const0_operand" "")))]
1083 "ix86_match_ccmode (insn, CCNOmode)"
1084 "test{b}\t%h0, %h0"
1085 [(set_attr "type" "test")
1086 (set_attr "length_immediate" "0")
1087 (set_attr "mode" "QI")])
1088
1089 (define_expand "cmpqi_ext_3"
1090 [(set (reg:CC FLAGS_REG)
1091 (compare:CC
1092 (subreg:QI
1093 (zero_extract:SI
1094 (match_operand 0 "ext_register_operand" "")
1095 (const_int 8)
1096 (const_int 8)) 0)
1097 (match_operand:QI 1 "immediate_operand" "")))])
1098
1099 (define_insn "*cmpqi_ext_3_insn"
1100 [(set (reg FLAGS_REG)
1101 (compare
1102 (subreg:QI
1103 (zero_extract:SI
1104 (match_operand 0 "ext_register_operand" "Q")
1105 (const_int 8)
1106 (const_int 8)) 0)
1107 (match_operand:QI 1 "general_operand" "Qmn")))]
1108 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%1, %h0|%h0, %1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "modrm" "1")
1112 (set_attr "mode" "QI")])
1113
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115 [(set (reg FLAGS_REG)
1116 (compare
1117 (subreg:QI
1118 (zero_extract:SI
1119 (match_operand 0 "ext_register_operand" "Q")
1120 (const_int 8)
1121 (const_int 8)) 0)
1122 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124 "cmp{b}\t{%1, %h0|%h0, %1}"
1125 [(set_attr "type" "icmp")
1126 (set_attr "modrm" "1")
1127 (set_attr "mode" "QI")])
1128
1129 (define_insn "*cmpqi_ext_4"
1130 [(set (reg FLAGS_REG)
1131 (compare
1132 (subreg:QI
1133 (zero_extract:SI
1134 (match_operand 0 "ext_register_operand" "Q")
1135 (const_int 8)
1136 (const_int 8)) 0)
1137 (subreg:QI
1138 (zero_extract:SI
1139 (match_operand 1 "ext_register_operand" "Q")
1140 (const_int 8)
1141 (const_int 8)) 0)))]
1142 "ix86_match_ccmode (insn, CCmode)"
1143 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "QI")])
1146
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares. Which is what
1150 ;; the old patterns did, but with many more of them.
1151
1152 (define_expand "cbranchxf4"
1153 [(set (reg:CC FLAGS_REG)
1154 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155 (match_operand:XF 2 "nonmemory_operand" "")))
1156 (set (pc) (if_then_else
1157 (match_operator 0 "ix86_fp_comparison_operator"
1158 [(reg:CC FLAGS_REG)
1159 (const_int 0)])
1160 (label_ref (match_operand 3 "" ""))
1161 (pc)))]
1162 "TARGET_80387"
1163 {
1164 ix86_expand_branch (GET_CODE (operands[0]),
1165 operands[1], operands[2], operands[3]);
1166 DONE;
1167 })
1168
1169 (define_expand "cstorexf4"
1170 [(set (reg:CC FLAGS_REG)
1171 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172 (match_operand:XF 3 "nonmemory_operand" "")))
1173 (set (match_operand:QI 0 "register_operand" "")
1174 (match_operator 1 "ix86_fp_comparison_operator"
1175 [(reg:CC FLAGS_REG)
1176 (const_int 0)]))]
1177 "TARGET_80387"
1178 {
1179 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180 operands[2], operands[3]);
1181 DONE;
1182 })
1183
1184 (define_expand "cbranch<mode>4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188 (set (pc) (if_then_else
1189 (match_operator 0 "ix86_fp_comparison_operator"
1190 [(reg:CC FLAGS_REG)
1191 (const_int 0)])
1192 (label_ref (match_operand 3 "" ""))
1193 (pc)))]
1194 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1195 {
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1198 DONE;
1199 })
1200
1201 (define_expand "cstore<mode>4"
1202 [(set (reg:CC FLAGS_REG)
1203 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205 (set (match_operand:QI 0 "register_operand" "")
1206 (match_operator 1 "ix86_fp_comparison_operator"
1207 [(reg:CC FLAGS_REG)
1208 (const_int 0)]))]
1209 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1210 {
1211 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212 operands[2], operands[3]);
1213 DONE;
1214 })
1215
1216 (define_expand "cbranchcc4"
1217 [(set (pc) (if_then_else
1218 (match_operator 0 "comparison_operator"
1219 [(match_operand 1 "flags_reg_operand" "")
1220 (match_operand 2 "const0_operand" "")])
1221 (label_ref (match_operand 3 "" ""))
1222 (pc)))]
1223 ""
1224 {
1225 ix86_expand_branch (GET_CODE (operands[0]),
1226 operands[1], operands[2], operands[3]);
1227 DONE;
1228 })
1229
1230 (define_expand "cstorecc4"
1231 [(set (match_operand:QI 0 "register_operand" "")
1232 (match_operator 1 "comparison_operator"
1233 [(match_operand 2 "flags_reg_operand" "")
1234 (match_operand 3 "const0_operand" "")]))]
1235 ""
1236 {
1237 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238 operands[2], operands[3]);
1239 DONE;
1240 })
1241
1242
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1245 ;;
1246 ;; CCFPmode compare with exceptions
1247 ;; CCFPUmode compare with no exceptions
1248
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1251
1252 (define_insn "*cmpfp_0"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1254 (unspec:HI
1255 [(compare:CCFP
1256 (match_operand 1 "register_operand" "f")
1257 (match_operand 2 "const0_operand" ""))]
1258 UNSPEC_FNSTSW))]
1259 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261 "* return output_fp_compare (insn, operands, false, false);"
1262 [(set_attr "type" "multi")
1263 (set_attr "unit" "i387")
1264 (set (attr "mode")
1265 (cond [(match_operand:SF 1 "" "")
1266 (const_string "SF")
1267 (match_operand:DF 1 "" "")
1268 (const_string "DF")
1269 ]
1270 (const_string "XF")))])
1271
1272 (define_insn_and_split "*cmpfp_0_cc"
1273 [(set (reg:CCFP FLAGS_REG)
1274 (compare:CCFP
1275 (match_operand 1 "register_operand" "f")
1276 (match_operand 2 "const0_operand" "")))
1277 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279 && TARGET_SAHF && !TARGET_CMOVE
1280 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1281 "#"
1282 "&& reload_completed"
1283 [(set (match_dup 0)
1284 (unspec:HI
1285 [(compare:CCFP (match_dup 1)(match_dup 2))]
1286 UNSPEC_FNSTSW))
1287 (set (reg:CC FLAGS_REG)
1288 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289 ""
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1292 (set (attr "mode")
1293 (cond [(match_operand:SF 1 "" "")
1294 (const_string "SF")
1295 (match_operand:DF 1 "" "")
1296 (const_string "DF")
1297 ]
1298 (const_string "XF")))])
1299
1300 (define_insn "*cmpfp_xf"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1302 (unspec:HI
1303 [(compare:CCFP
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f"))]
1306 UNSPEC_FNSTSW))]
1307 "TARGET_80387"
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "XF")])
1312
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1315 (compare:CCFP
1316 (match_operand:XF 1 "register_operand" "f")
1317 (match_operand:XF 2 "register_operand" "f")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319 "TARGET_80387
1320 && TARGET_SAHF && !TARGET_CMOVE"
1321 "#"
1322 "&& reload_completed"
1323 [(set (match_dup 0)
1324 (unspec:HI
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1326 UNSPEC_FNSTSW))
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329 ""
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "XF")])
1333
1334 (define_insn "*cmpfp_<mode>"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1336 (unspec:HI
1337 [(compare:CCFP
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1340 UNSPEC_FNSTSW))]
1341 "TARGET_80387"
1342 "* return output_fp_compare (insn, operands, false, false);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set_attr "mode" "<MODE>")])
1346
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348 [(set (reg:CCFP FLAGS_REG)
1349 (compare:CCFP
1350 (match_operand:MODEF 1 "register_operand" "f")
1351 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1353 "TARGET_80387
1354 && TARGET_SAHF && !TARGET_CMOVE"
1355 "#"
1356 "&& reload_completed"
1357 [(set (match_dup 0)
1358 (unspec:HI
1359 [(compare:CCFP (match_dup 1)(match_dup 2))]
1360 UNSPEC_FNSTSW))
1361 (set (reg:CC FLAGS_REG)
1362 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1363 ""
1364 [(set_attr "type" "multi")
1365 (set_attr "unit" "i387")
1366 (set_attr "mode" "<MODE>")])
1367
1368 (define_insn "*cmpfp_u"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1370 (unspec:HI
1371 [(compare:CCFPU
1372 (match_operand 1 "register_operand" "f")
1373 (match_operand 2 "register_operand" "f"))]
1374 UNSPEC_FNSTSW))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377 "* return output_fp_compare (insn, operands, false, true);"
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1380 (set (attr "mode")
1381 (cond [(match_operand:SF 1 "" "")
1382 (const_string "SF")
1383 (match_operand:DF 1 "" "")
1384 (const_string "DF")
1385 ]
1386 (const_string "XF")))])
1387
1388 (define_insn_and_split "*cmpfp_u_cc"
1389 [(set (reg:CCFPU FLAGS_REG)
1390 (compare:CCFPU
1391 (match_operand 1 "register_operand" "f")
1392 (match_operand 2 "register_operand" "f")))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && TARGET_SAHF && !TARGET_CMOVE
1396 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1397 "#"
1398 "&& reload_completed"
1399 [(set (match_dup 0)
1400 (unspec:HI
1401 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1402 UNSPEC_FNSTSW))
1403 (set (reg:CC FLAGS_REG)
1404 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1405 ""
1406 [(set_attr "type" "multi")
1407 (set_attr "unit" "i387")
1408 (set (attr "mode")
1409 (cond [(match_operand:SF 1 "" "")
1410 (const_string "SF")
1411 (match_operand:DF 1 "" "")
1412 (const_string "DF")
1413 ]
1414 (const_string "XF")))])
1415
1416 (define_insn "*cmpfp_<mode>"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1418 (unspec:HI
1419 [(compare:CCFP
1420 (match_operand 1 "register_operand" "f")
1421 (match_operator 3 "float_operator"
1422 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1423 UNSPEC_FNSTSW))]
1424 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427 "* return output_fp_compare (insn, operands, false, false);"
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1432
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434 [(set (reg:CCFP FLAGS_REG)
1435 (compare:CCFP
1436 (match_operand 1 "register_operand" "f")
1437 (match_operator 3 "float_operator"
1438 [(match_operand:SWI24 2 "memory_operand" "m")])))
1439 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441 && TARGET_SAHF && !TARGET_CMOVE
1442 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1444 "#"
1445 "&& reload_completed"
1446 [(set (match_dup 0)
1447 (unspec:HI
1448 [(compare:CCFP
1449 (match_dup 1)
1450 (match_op_dup 3 [(match_dup 2)]))]
1451 UNSPEC_FNSTSW))
1452 (set (reg:CC FLAGS_REG)
1453 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1454 ""
1455 [(set_attr "type" "multi")
1456 (set_attr "unit" "i387")
1457 (set_attr "fp_int_src" "true")
1458 (set_attr "mode" "<MODE>")])
1459
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1462
1463 (define_insn "x86_fnstsw_1"
1464 [(set (match_operand:HI 0 "register_operand" "=a")
1465 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1466 "TARGET_80387"
1467 "fnstsw\t%0"
1468 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469 (set_attr "mode" "SI")
1470 (set_attr "unit" "i387")])
1471
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1474
1475 (define_insn "x86_sahf_1"
1476 [(set (reg:CC FLAGS_REG)
1477 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1478 UNSPEC_SAHF))]
1479 "TARGET_SAHF"
1480 {
1481 #ifndef HAVE_AS_IX86_SAHF
1482 if (TARGET_64BIT)
1483 return ASM_BYTE "0x9e";
1484 else
1485 #endif
1486 return "sahf";
1487 }
1488 [(set_attr "length" "1")
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "direct")
1492 (set_attr "mode" "SI")])
1493
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500 "TARGET_MIX_SSE_I387
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp,ssecomi")
1505 (set_attr "prefix" "orig,maybe_vex")
1506 (set (attr "mode")
1507 (if_then_else (match_operand:SF 1 "" "")
1508 (const_string "SF")
1509 (const_string "DF")))
1510 (set (attr "prefix_rep")
1511 (if_then_else (eq_attr "type" "ssecomi")
1512 (const_string "0")
1513 (const_string "*")))
1514 (set (attr "prefix_data16")
1515 (cond [(eq_attr "type" "fcmp")
1516 (const_string "*")
1517 (eq_attr "mode" "DF")
1518 (const_string "1")
1519 ]
1520 (const_string "0")))
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "double")])
1524
1525 (define_insn "*cmpfp_i_sse"
1526 [(set (reg:CCFP FLAGS_REG)
1527 (compare:CCFP (match_operand 0 "register_operand" "x")
1528 (match_operand 1 "nonimmediate_operand" "xm")))]
1529 "TARGET_SSE_MATH
1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532 "* return output_fp_compare (insn, operands, true, false);"
1533 [(set_attr "type" "ssecomi")
1534 (set_attr "prefix" "maybe_vex")
1535 (set (attr "mode")
1536 (if_then_else (match_operand:SF 1 "" "")
1537 (const_string "SF")
1538 (const_string "DF")))
1539 (set_attr "prefix_rep" "0")
1540 (set (attr "prefix_data16")
1541 (if_then_else (eq_attr "mode" "DF")
1542 (const_string "1")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1547
1548 (define_insn "*cmpfp_i_i387"
1549 [(set (reg:CCFP FLAGS_REG)
1550 (compare:CCFP (match_operand 0 "register_operand" "f")
1551 (match_operand 1 "register_operand" "f")))]
1552 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && TARGET_CMOVE
1554 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, false);"
1557 [(set_attr "type" "fcmp")
1558 (set (attr "mode")
1559 (cond [(match_operand:SF 1 "" "")
1560 (const_string "SF")
1561 (match_operand:DF 1 "" "")
1562 (const_string "DF")
1563 ]
1564 (const_string "XF")))
1565 (set_attr "athlon_decode" "vector")
1566 (set_attr "amdfam10_decode" "direct")
1567 (set_attr "bdver1_decode" "double")])
1568
1569 (define_insn "*cmpfp_iu_mixed"
1570 [(set (reg:CCFPU FLAGS_REG)
1571 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573 "TARGET_MIX_SSE_I387
1574 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp,ssecomi")
1578 (set_attr "prefix" "orig,maybe_vex")
1579 (set (attr "mode")
1580 (if_then_else (match_operand:SF 1 "" "")
1581 (const_string "SF")
1582 (const_string "DF")))
1583 (set (attr "prefix_rep")
1584 (if_then_else (eq_attr "type" "ssecomi")
1585 (const_string "0")
1586 (const_string "*")))
1587 (set (attr "prefix_data16")
1588 (cond [(eq_attr "type" "fcmp")
1589 (const_string "*")
1590 (eq_attr "mode" "DF")
1591 (const_string "1")
1592 ]
1593 (const_string "0")))
1594 (set_attr "athlon_decode" "vector")
1595 (set_attr "amdfam10_decode" "direct")
1596 (set_attr "bdver1_decode" "double")])
1597
1598 (define_insn "*cmpfp_iu_sse"
1599 [(set (reg:CCFPU FLAGS_REG)
1600 (compare:CCFPU (match_operand 0 "register_operand" "x")
1601 (match_operand 1 "nonimmediate_operand" "xm")))]
1602 "TARGET_SSE_MATH
1603 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605 "* return output_fp_compare (insn, operands, true, true);"
1606 [(set_attr "type" "ssecomi")
1607 (set_attr "prefix" "maybe_vex")
1608 (set (attr "mode")
1609 (if_then_else (match_operand:SF 1 "" "")
1610 (const_string "SF")
1611 (const_string "DF")))
1612 (set_attr "prefix_rep" "0")
1613 (set (attr "prefix_data16")
1614 (if_then_else (eq_attr "mode" "DF")
1615 (const_string "1")
1616 (const_string "0")))
1617 (set_attr "athlon_decode" "vector")
1618 (set_attr "amdfam10_decode" "direct")
1619 (set_attr "bdver1_decode" "double")])
1620
1621 (define_insn "*cmpfp_iu_387"
1622 [(set (reg:CCFPU FLAGS_REG)
1623 (compare:CCFPU (match_operand 0 "register_operand" "f")
1624 (match_operand 1 "register_operand" "f")))]
1625 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1626 && TARGET_CMOVE
1627 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629 "* return output_fp_compare (insn, operands, true, true);"
1630 [(set_attr "type" "fcmp")
1631 (set (attr "mode")
1632 (cond [(match_operand:SF 1 "" "")
1633 (const_string "SF")
1634 (match_operand:DF 1 "" "")
1635 (const_string "DF")
1636 ]
1637 (const_string "XF")))
1638 (set_attr "athlon_decode" "vector")
1639 (set_attr "amdfam10_decode" "direct")
1640 (set_attr "bdver1_decode" "direct")])
1641 \f
1642 ;; Push/pop instructions.
1643
1644 (define_insn "*push<mode>2"
1645 [(set (match_operand:DWI 0 "push_operand" "=<")
1646 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1647 ""
1648 "#")
1649
1650 (define_split
1651 [(set (match_operand:TI 0 "push_operand" "")
1652 (match_operand:TI 1 "general_operand" ""))]
1653 "TARGET_64BIT && reload_completed
1654 && !SSE_REG_P (operands[1])"
1655 [(const_int 0)]
1656 "ix86_split_long_move (operands); DONE;")
1657
1658 (define_insn "*pushdi2_rex64"
1659 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1661 "TARGET_64BIT"
1662 "@
1663 push{q}\t%1
1664 #"
1665 [(set_attr "type" "push,multi")
1666 (set_attr "mode" "DI")])
1667
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it. In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1672 (define_peephole2
1673 [(match_scratch:DI 2 "r")
1674 (set (match_operand:DI 0 "push_operand" "")
1675 (match_operand:DI 1 "immediate_operand" ""))]
1676 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677 && !x86_64_immediate_operand (operands[1], DImode)"
1678 [(set (match_dup 2) (match_dup 1))
1679 (set (match_dup 0) (match_dup 2))])
1680
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1684 (define_peephole2
1685 [(set (match_operand:DI 0 "push_operand" "")
1686 (match_operand:DI 1 "immediate_operand" ""))]
1687 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689 [(set (match_dup 0) (match_dup 1))
1690 (set (match_dup 2) (match_dup 3))]
1691 {
1692 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1693
1694 operands[1] = gen_lowpart (DImode, operands[2]);
1695 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1696 GEN_INT (4)));
1697 })
1698
1699 (define_split
1700 [(set (match_operand:DI 0 "push_operand" "")
1701 (match_operand:DI 1 "immediate_operand" ""))]
1702 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703 ? epilogue_completed : reload_completed)
1704 && !symbolic_operand (operands[1], DImode)
1705 && !x86_64_immediate_operand (operands[1], DImode)"
1706 [(set (match_dup 0) (match_dup 1))
1707 (set (match_dup 2) (match_dup 3))]
1708 {
1709 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1710
1711 operands[1] = gen_lowpart (DImode, operands[2]);
1712 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1713 GEN_INT (4)));
1714 })
1715
1716 (define_split
1717 [(set (match_operand:DI 0 "push_operand" "")
1718 (match_operand:DI 1 "general_operand" ""))]
1719 "!TARGET_64BIT && reload_completed
1720 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1721 [(const_int 0)]
1722 "ix86_split_long_move (operands); DONE;")
1723
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1727 "!TARGET_64BIT"
1728 "push{l}\t%1"
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1731
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word". But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1735
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738 [(set (match_operand:SWI124 0 "push_operand" "=X")
1739 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1740 "TARGET_64BIT"
1741 "push{q}\t%q1"
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1744
1745 (define_insn "*push<mode>2"
1746 [(set (match_operand:SWI12 0 "push_operand" "=X")
1747 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1748 "!TARGET_64BIT"
1749 "push{l}\t%k1"
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1752
1753 (define_insn "*push<mode>2_prologue"
1754 [(set (match_operand:P 0 "push_operand" "=<")
1755 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756 (clobber (mem:BLK (scratch)))]
1757 ""
1758 "push{<imodesuffix>}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "<MODE>")])
1761
1762 (define_insn "*pop<mode>1"
1763 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764 (match_operand:P 1 "pop_operand" ">"))]
1765 ""
1766 "pop{<imodesuffix>}\t%0"
1767 [(set_attr "type" "pop")
1768 (set_attr "mode" "<MODE>")])
1769
1770 (define_insn "*pop<mode>1_epilogue"
1771 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772 (match_operand:P 1 "pop_operand" ">"))
1773 (clobber (mem:BLK (scratch)))]
1774 ""
1775 "pop{<imodesuffix>}\t%0"
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "<MODE>")])
1778 \f
1779 ;; Move instructions.
1780
1781 (define_expand "movoi"
1782 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783 (match_operand:OI 1 "general_operand" ""))]
1784 "TARGET_AVX"
1785 "ix86_expand_move (OImode, operands); DONE;")
1786
1787 (define_expand "movti"
1788 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789 (match_operand:TI 1 "nonimmediate_operand" ""))]
1790 "TARGET_64BIT || TARGET_SSE"
1791 {
1792 if (TARGET_64BIT)
1793 ix86_expand_move (TImode, operands);
1794 else if (push_operand (operands[0], TImode))
1795 ix86_expand_push (TImode, operands[1]);
1796 else
1797 ix86_expand_vector_move (TImode, operands);
1798 DONE;
1799 })
1800
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern. Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807 (match_operand:CDI 1 "general_operand" ""))]
1808 ""
1809 {
1810 if (push_operand (operands[0], CDImode))
1811 emit_move_complex_push (CDImode, operands[0], operands[1]);
1812 else
1813 emit_move_complex_parts (operands[0], operands[1]);
1814 DONE;
1815 })
1816
1817 (define_expand "mov<mode>"
1818 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819 (match_operand:SWI1248x 1 "general_operand" ""))]
1820 ""
1821 "ix86_expand_move (<MODE>mode, operands); DONE;")
1822
1823 (define_insn "*mov<mode>_xor"
1824 [(set (match_operand:SWI48 0 "register_operand" "=r")
1825 (match_operand:SWI48 1 "const0_operand" ""))
1826 (clobber (reg:CC FLAGS_REG))]
1827 "reload_completed"
1828 "xor{l}\t%k0, %k0"
1829 [(set_attr "type" "alu1")
1830 (set_attr "mode" "SI")
1831 (set_attr "length_immediate" "0")])
1832
1833 (define_insn "*mov<mode>_or"
1834 [(set (match_operand:SWI48 0 "register_operand" "=r")
1835 (match_operand:SWI48 1 "const_int_operand" ""))
1836 (clobber (reg:CC FLAGS_REG))]
1837 "reload_completed
1838 && operands[1] == constm1_rtx"
1839 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840 [(set_attr "type" "alu1")
1841 (set_attr "mode" "<MODE>")
1842 (set_attr "length_immediate" "1")])
1843
1844 (define_insn "*movoi_internal_avx"
1845 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1848 {
1849 switch (which_alternative)
1850 {
1851 case 0:
1852 return standard_sse_constant_opcode (insn, operands[1]);
1853 case 1:
1854 case 2:
1855 if (misaligned_operand (operands[0], OImode)
1856 || misaligned_operand (operands[1], OImode))
1857 return "vmovdqu\t{%1, %0|%0, %1}";
1858 else
1859 return "vmovdqa\t{%1, %0|%0, %1}";
1860 default:
1861 gcc_unreachable ();
1862 }
1863 }
1864 [(set_attr "type" "sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "vex")
1866 (set_attr "mode" "OI")])
1867
1868 (define_insn "*movti_internal_rex64"
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1872 {
1873 switch (which_alternative)
1874 {
1875 case 0:
1876 case 1:
1877 return "#";
1878 case 2:
1879 return standard_sse_constant_opcode (insn, operands[1]);
1880 case 3:
1881 case 4:
1882 /* TDmode values are passed as TImode on the stack. Moving them
1883 to stack may result in unaligned memory access. */
1884 if (misaligned_operand (operands[0], TImode)
1885 || misaligned_operand (operands[1], TImode))
1886 {
1887 if (get_attr_mode (insn) == MODE_V4SF)
1888 return "%vmovups\t{%1, %0|%0, %1}";
1889 else
1890 return "%vmovdqu\t{%1, %0|%0, %1}";
1891 }
1892 else
1893 {
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovaps\t{%1, %0|%0, %1}";
1896 else
1897 return "%vmovdqa\t{%1, %0|%0, %1}";
1898 }
1899 default:
1900 gcc_unreachable ();
1901 }
1902 }
1903 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1905 (set (attr "mode")
1906 (cond [(eq_attr "alternative" "2,3")
1907 (if_then_else
1908 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1909 (const_int 0))
1910 (const_string "V4SF")
1911 (const_string "TI"))
1912 (eq_attr "alternative" "4")
1913 (if_then_else
1914 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1915 (const_int 0))
1916 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917 (const_int 0)))
1918 (const_string "V4SF")
1919 (const_string "TI"))]
1920 (const_string "DI")))])
1921
1922 (define_split
1923 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924 (match_operand:TI 1 "general_operand" ""))]
1925 "reload_completed
1926 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1927 [(const_int 0)]
1928 "ix86_split_long_move (operands); DONE;")
1929
1930 (define_insn "*movti_internal_sse"
1931 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933 "TARGET_SSE && !TARGET_64BIT
1934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 {
1936 switch (which_alternative)
1937 {
1938 case 0:
1939 return standard_sse_constant_opcode (insn, operands[1]);
1940 case 1:
1941 case 2:
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1946 {
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1949 else
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1951 }
1952 else
1953 {
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1956 else
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1958 }
1959 default:
1960 gcc_unreachable ();
1961 }
1962 }
1963 [(set_attr "type" "sselog1,ssemov,ssemov")
1964 (set_attr "prefix" "maybe_vex")
1965 (set (attr "mode")
1966 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1968 (const_int 0)))
1969 (const_string "V4SF")
1970 (and (eq_attr "alternative" "2")
1971 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1972 (const_int 0)))
1973 (const_string "V4SF")]
1974 (const_string "TI")))])
1975
1976 (define_insn "*movdi_internal_rex64"
1977 [(set (match_operand:DI 0 "nonimmediate_operand"
1978 "=r,r ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1979 (match_operand:DI 1 "general_operand"
1980 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1981 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 {
1983 switch (get_attr_type (insn))
1984 {
1985 case TYPE_SSECVT:
1986 if (SSE_REG_P (operands[0]))
1987 return "movq2dq\t{%1, %0|%0, %1}";
1988 else
1989 return "movdq2q\t{%1, %0|%0, %1}";
1990
1991 case TYPE_SSEMOV:
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "%vmovdqa\t{%1, %0|%0, %1}";
1994 /* Handle broken assemblers that require movd instead of movq. */
1995 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996 return "%vmovd\t{%1, %0|%0, %1}";
1997 else
1998 return "%vmovq\t{%1, %0|%0, %1}";
1999
2000 case TYPE_MMXMOV:
2001 /* Handle broken assemblers that require movd instead of movq. */
2002 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003 return "movd\t{%1, %0|%0, %1}";
2004 else
2005 return "movq\t{%1, %0|%0, %1}";
2006
2007 case TYPE_SSELOG1:
2008 return standard_sse_constant_opcode (insn, operands[1]);
2009
2010 case TYPE_MMX:
2011 return "pxor\t%0, %0";
2012
2013 case TYPE_MULTI:
2014 return "#";
2015
2016 case TYPE_LEA:
2017 return "lea{q}\t{%a1, %0|%0, %a1}";
2018
2019 default:
2020 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021 if (get_attr_mode (insn) == MODE_SI)
2022 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023 else if (which_alternative == 2)
2024 return "movabs{q}\t{%1, %0|%0, %1}";
2025 else
2026 return "mov{q}\t{%1, %0|%0, %1}";
2027 }
2028 }
2029 [(set (attr "type")
2030 (cond [(eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (eq_attr "alternative" "5")
2033 (const_string "mmx")
2034 (eq_attr "alternative" "6,7,8,9")
2035 (const_string "mmxmov")
2036 (eq_attr "alternative" "10")
2037 (const_string "sselog1")
2038 (eq_attr "alternative" "11,12,13,14,15")
2039 (const_string "ssemov")
2040 (eq_attr "alternative" "16,17")
2041 (const_string "ssecvt")
2042 (match_operand:DI 1 "pic_32bit_operand" "")
2043 (const_string "lea")
2044 ]
2045 (const_string "imov")))
2046 (set (attr "modrm")
2047 (if_then_else
2048 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2049 (const_string "0")
2050 (const_string "*")))
2051 (set (attr "length_immediate")
2052 (if_then_else
2053 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2054 (const_string "8")
2055 (const_string "*")))
2056 (set (attr "prefix_rex")
2057 (if_then_else (eq_attr "alternative" "8,9")
2058 (const_string "1")
2059 (const_string "*")))
2060 (set (attr "prefix_data16")
2061 (if_then_else (eq_attr "alternative" "11")
2062 (const_string "1")
2063 (const_string "*")))
2064 (set (attr "prefix")
2065 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2066 (const_string "maybe_vex")
2067 (const_string "orig")))
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))])
2081
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 (define_peephole2
2086 [(set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2093
2094 (define_split
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098 ? epilogue_completed : reload_completed)
2099 && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode)"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2104
2105 (define_insn "*movdi_internal"
2106 [(set (match_operand:DI 0 "nonimmediate_operand"
2107 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108 (match_operand:DI 1 "general_operand"
2109 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2111 {
2112 switch (get_attr_type (insn))
2113 {
2114 case TYPE_SSECVT:
2115 if (SSE_REG_P (operands[0]))
2116 return "movq2dq\t{%1, %0|%0, %1}";
2117 else
2118 return "movdq2q\t{%1, %0|%0, %1}";
2119
2120 case TYPE_SSEMOV:
2121 switch (get_attr_mode (insn))
2122 {
2123 case MODE_TI:
2124 return "%vmovdqa\t{%1, %0|%0, %1}";
2125 case MODE_DI:
2126 return "%vmovq\t{%1, %0|%0, %1}";
2127 case MODE_V4SF:
2128 return "movaps\t{%1, %0|%0, %1}";
2129 case MODE_V2SF:
2130 return "movlps\t{%1, %0|%0, %1}";
2131 default:
2132 gcc_unreachable ();
2133 }
2134
2135 case TYPE_MMXMOV:
2136 return "movq\t{%1, %0|%0, %1}";
2137
2138 case TYPE_SSELOG1:
2139 return standard_sse_constant_opcode (insn, operands[1]);
2140
2141 case TYPE_MMX:
2142 return "pxor\t%0, %0";
2143
2144 case TYPE_MULTI:
2145 return "#";
2146
2147 default:
2148 gcc_unreachable ();
2149 }
2150 }
2151 [(set (attr "isa")
2152 (if_then_else (eq_attr "alternative" "9,10,11,12")
2153 (const_string "noavx")
2154 (const_string "*")))
2155 (set (attr "type")
2156 (cond [(eq_attr "alternative" "0,1")
2157 (const_string "multi")
2158 (eq_attr "alternative" "2")
2159 (const_string "mmx")
2160 (eq_attr "alternative" "3,4")
2161 (const_string "mmxmov")
2162 (eq_attr "alternative" "5,9")
2163 (const_string "sselog1")
2164 (eq_attr "alternative" "13,14")
2165 (const_string "ssecvt")
2166 ]
2167 (const_string "ssemov")))
2168 (set (attr "prefix")
2169 (if_then_else (eq_attr "alternative" "5,6,7,8")
2170 (const_string "maybe_vex")
2171 (const_string "orig")))
2172 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2173
2174 (define_split
2175 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176 (match_operand:DI 1 "general_operand" ""))]
2177 "!TARGET_64BIT && reload_completed
2178 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2180 [(const_int 0)]
2181 "ix86_split_long_move (operands); DONE;")
2182
2183 (define_insn "*movsi_internal"
2184 [(set (match_operand:SI 0 "nonimmediate_operand"
2185 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186 (match_operand:SI 1 "general_operand"
2187 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2188 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 {
2190 switch (get_attr_type (insn))
2191 {
2192 case TYPE_SSELOG1:
2193 return standard_sse_constant_opcode (insn, operands[1]);
2194
2195 case TYPE_SSEMOV:
2196 switch (get_attr_mode (insn))
2197 {
2198 case MODE_TI:
2199 return "%vmovdqa\t{%1, %0|%0, %1}";
2200 case MODE_V4SF:
2201 return "%vmovaps\t{%1, %0|%0, %1}";
2202 case MODE_SI:
2203 return "%vmovd\t{%1, %0|%0, %1}";
2204 case MODE_SF:
2205 return "%vmovss\t{%1, %0|%0, %1}";
2206 default:
2207 gcc_unreachable ();
2208 }
2209
2210 case TYPE_MMX:
2211 return "pxor\t%0, %0";
2212
2213 case TYPE_MMXMOV:
2214 if (get_attr_mode (insn) == MODE_DI)
2215 return "movq\t{%1, %0|%0, %1}";
2216 return "movd\t{%1, %0|%0, %1}";
2217
2218 case TYPE_LEA:
2219 return "lea{l}\t{%a1, %0|%0, %a1}";
2220
2221 default:
2222 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2223 return "mov{l}\t{%1, %0|%0, %1}";
2224 }
2225 }
2226 [(set (attr "type")
2227 (cond [(eq_attr "alternative" "2")
2228 (const_string "mmx")
2229 (eq_attr "alternative" "3,4,5")
2230 (const_string "mmxmov")
2231 (eq_attr "alternative" "6")
2232 (const_string "sselog1")
2233 (eq_attr "alternative" "7,8,9,10,11")
2234 (const_string "ssemov")
2235 (match_operand:DI 1 "pic_32bit_operand" "")
2236 (const_string "lea")
2237 ]
2238 (const_string "imov")))
2239 (set (attr "prefix")
2240 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241 (const_string "orig")
2242 (const_string "maybe_vex")))
2243 (set (attr "prefix_data16")
2244 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2245 (const_string "1")
2246 (const_string "*")))
2247 (set (attr "mode")
2248 (cond [(eq_attr "alternative" "2,3")
2249 (const_string "DI")
2250 (eq_attr "alternative" "6,7")
2251 (if_then_else
2252 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253 (const_string "V4SF")
2254 (const_string "TI"))
2255 (and (eq_attr "alternative" "8,9,10,11")
2256 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2257 (const_string "SF")
2258 ]
2259 (const_string "SI")))])
2260
2261 (define_insn "*movhi_internal"
2262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2265 {
2266 switch (get_attr_type (insn))
2267 {
2268 case TYPE_IMOVX:
2269 /* movzwl is faster than movw on p2 due to partial word stalls,
2270 though not as fast as an aligned movl. */
2271 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2272 default:
2273 if (get_attr_mode (insn) == MODE_SI)
2274 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2275 else
2276 return "mov{w}\t{%1, %0|%0, %1}";
2277 }
2278 }
2279 [(set (attr "type")
2280 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2281 (const_int 0))
2282 (const_string "imov")
2283 (and (eq_attr "alternative" "0")
2284 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2285 (const_int 0))
2286 (eq (symbol_ref "TARGET_HIMODE_MATH")
2287 (const_int 0))))
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "1,2")
2290 (match_operand:HI 1 "aligned_operand" ""))
2291 (const_string "imov")
2292 (and (ne (symbol_ref "TARGET_MOVX")
2293 (const_int 0))
2294 (eq_attr "alternative" "0,2"))
2295 (const_string "imovx")
2296 ]
2297 (const_string "imov")))
2298 (set (attr "mode")
2299 (cond [(eq_attr "type" "imovx")
2300 (const_string "SI")
2301 (and (eq_attr "alternative" "1,2")
2302 (match_operand:HI 1 "aligned_operand" ""))
2303 (const_string "SI")
2304 (and (eq_attr "alternative" "0")
2305 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2306 (const_int 0))
2307 (eq (symbol_ref "TARGET_HIMODE_MATH")
2308 (const_int 0))))
2309 (const_string "SI")
2310 ]
2311 (const_string "HI")))])
2312
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2318 ;; instruction).
2319 ;;
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there. Then we use movzx.
2323 (define_insn "*movqi_internal"
2324 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2327 {
2328 switch (get_attr_type (insn))
2329 {
2330 case TYPE_IMOVX:
2331 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2333 default:
2334 if (get_attr_mode (insn) == MODE_SI)
2335 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2336 else
2337 return "mov{b}\t{%1, %0|%0, %1}";
2338 }
2339 }
2340 [(set (attr "type")
2341 (cond [(and (eq_attr "alternative" "5")
2342 (not (match_operand:QI 1 "aligned_operand" "")))
2343 (const_string "imovx")
2344 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2345 (const_int 0))
2346 (const_string "imov")
2347 (and (eq_attr "alternative" "3")
2348 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2349 (const_int 0))
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2351 (const_int 0))))
2352 (const_string "imov")
2353 (eq_attr "alternative" "3,5")
2354 (const_string "imovx")
2355 (and (ne (symbol_ref "TARGET_MOVX")
2356 (const_int 0))
2357 (eq_attr "alternative" "2"))
2358 (const_string "imovx")
2359 ]
2360 (const_string "imov")))
2361 (set (attr "mode")
2362 (cond [(eq_attr "alternative" "3,4,5")
2363 (const_string "SI")
2364 (eq_attr "alternative" "6")
2365 (const_string "QI")
2366 (eq_attr "type" "imovx")
2367 (const_string "SI")
2368 (and (eq_attr "type" "imov")
2369 (and (eq_attr "alternative" "0,1")
2370 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2371 (const_int 0))
2372 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2373 (const_int 0))
2374 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2375 (const_int 0))))))
2376 (const_string "SI")
2377 ;; Avoid partial register stalls when not using QImode arithmetic
2378 (and (eq_attr "type" "imov")
2379 (and (eq_attr "alternative" "0,1")
2380 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2381 (const_int 0))
2382 (eq (symbol_ref "TARGET_QIMODE_MATH")
2383 (const_int 0)))))
2384 (const_string "SI")
2385 ]
2386 (const_string "QI")))])
2387
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2395 "@
2396 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398 [(set_attr "type" "imov")
2399 (set_attr "modrm" "0,*")
2400 (set_attr "length_address" "8,0")
2401 (set_attr "length_immediate" "0,*")
2402 (set_attr "memory" "store")
2403 (set_attr "mode" "<MODE>")])
2404
2405 (define_insn "*movabs<mode>_2"
2406 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2409 "@
2410 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412 [(set_attr "type" "imov")
2413 (set_attr "modrm" "0,*")
2414 (set_attr "length_address" "8,0")
2415 (set_attr "length_immediate" "0")
2416 (set_attr "memory" "load")
2417 (set_attr "mode" "<MODE>")])
2418
2419 (define_insn "*swap<mode>"
2420 [(set (match_operand:SWI48 0 "register_operand" "+r")
2421 (match_operand:SWI48 1 "register_operand" "+r"))
2422 (set (match_dup 1)
2423 (match_dup 0))]
2424 ""
2425 "xchg{<imodesuffix>}\t%1, %0"
2426 [(set_attr "type" "imov")
2427 (set_attr "mode" "<MODE>")
2428 (set_attr "pent_pair" "np")
2429 (set_attr "athlon_decode" "vector")
2430 (set_attr "amdfam10_decode" "double")
2431 (set_attr "bdver1_decode" "double")])
2432
2433 (define_insn "*swap<mode>_1"
2434 [(set (match_operand:SWI12 0 "register_operand" "+r")
2435 (match_operand:SWI12 1 "register_operand" "+r"))
2436 (set (match_dup 1)
2437 (match_dup 0))]
2438 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2439 "xchg{l}\t%k1, %k0"
2440 [(set_attr "type" "imov")
2441 (set_attr "mode" "SI")
2442 (set_attr "pent_pair" "np")
2443 (set_attr "athlon_decode" "vector")
2444 (set_attr "amdfam10_decode" "double")
2445 (set_attr "bdver1_decode" "double")])
2446
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451 (match_operand:SWI12 1 "register_operand" "+<r>"))
2452 (set (match_dup 1)
2453 (match_dup 0))]
2454 "TARGET_PARTIAL_REG_STALL"
2455 "xchg{<imodesuffix>}\t%1, %0"
2456 [(set_attr "type" "imov")
2457 (set_attr "mode" "<MODE>")
2458 (set_attr "pent_pair" "np")
2459 (set_attr "athlon_decode" "vector")])
2460
2461 (define_expand "movstrict<mode>"
2462 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463 (match_operand:SWI12 1 "general_operand" ""))]
2464 ""
2465 {
2466 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2467 FAIL;
2468 if (GET_CODE (operands[0]) == SUBREG
2469 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2470 FAIL;
2471 /* Don't generate memory->memory moves, go through a register */
2472 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473 operands[1] = force_reg (<MODE>mode, operands[1]);
2474 })
2475
2476 (define_insn "*movstrict<mode>_1"
2477 [(set (strict_low_part
2478 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483 [(set_attr "type" "imov")
2484 (set_attr "mode" "<MODE>")])
2485
2486 (define_insn "*movstrict<mode>_xor"
2487 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488 (match_operand:SWI12 1 "const0_operand" ""))
2489 (clobber (reg:CC FLAGS_REG))]
2490 "reload_completed"
2491 "xor{<imodesuffix>}\t%0, %0"
2492 [(set_attr "type" "alu1")
2493 (set_attr "mode" "<MODE>")
2494 (set_attr "length_immediate" "0")])
2495
2496 (define_insn "*mov<mode>_extv_1"
2497 [(set (match_operand:SWI24 0 "register_operand" "=R")
2498 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2499 (const_int 8)
2500 (const_int 8)))]
2501 ""
2502 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503 [(set_attr "type" "imovx")
2504 (set_attr "mode" "SI")])
2505
2506 (define_insn "*movqi_extv_1_rex64"
2507 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2509 (const_int 8)
2510 (const_int 8)))]
2511 "TARGET_64BIT"
2512 {
2513 switch (get_attr_type (insn))
2514 {
2515 case TYPE_IMOVX:
2516 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2517 default:
2518 return "mov{b}\t{%h1, %0|%0, %h1}";
2519 }
2520 }
2521 [(set (attr "type")
2522 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523 (ne (symbol_ref "TARGET_MOVX")
2524 (const_int 0)))
2525 (const_string "imovx")
2526 (const_string "imov")))
2527 (set (attr "mode")
2528 (if_then_else (eq_attr "type" "imovx")
2529 (const_string "SI")
2530 (const_string "QI")))])
2531
2532 (define_insn "*movqi_extv_1"
2533 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2535 (const_int 8)
2536 (const_int 8)))]
2537 "!TARGET_64BIT"
2538 {
2539 switch (get_attr_type (insn))
2540 {
2541 case TYPE_IMOVX:
2542 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2543 default:
2544 return "mov{b}\t{%h1, %0|%0, %h1}";
2545 }
2546 }
2547 [(set (attr "type")
2548 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550 (ne (symbol_ref "TARGET_MOVX")
2551 (const_int 0))))
2552 (const_string "imovx")
2553 (const_string "imov")))
2554 (set (attr "mode")
2555 (if_then_else (eq_attr "type" "imovx")
2556 (const_string "SI")
2557 (const_string "QI")))])
2558
2559 (define_insn "*mov<mode>_extzv_1"
2560 [(set (match_operand:SWI48 0 "register_operand" "=R")
2561 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2562 (const_int 8)
2563 (const_int 8)))]
2564 ""
2565 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566 [(set_attr "type" "imovx")
2567 (set_attr "mode" "SI")])
2568
2569 (define_insn "*movqi_extzv_2_rex64"
2570 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2571 (subreg:QI
2572 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2573 (const_int 8)
2574 (const_int 8)) 0))]
2575 "TARGET_64BIT"
2576 {
2577 switch (get_attr_type (insn))
2578 {
2579 case TYPE_IMOVX:
2580 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2581 default:
2582 return "mov{b}\t{%h1, %0|%0, %h1}";
2583 }
2584 }
2585 [(set (attr "type")
2586 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587 (ne (symbol_ref "TARGET_MOVX")
2588 (const_int 0)))
2589 (const_string "imovx")
2590 (const_string "imov")))
2591 (set (attr "mode")
2592 (if_then_else (eq_attr "type" "imovx")
2593 (const_string "SI")
2594 (const_string "QI")))])
2595
2596 (define_insn "*movqi_extzv_2"
2597 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2598 (subreg:QI
2599 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2600 (const_int 8)
2601 (const_int 8)) 0))]
2602 "!TARGET_64BIT"
2603 {
2604 switch (get_attr_type (insn))
2605 {
2606 case TYPE_IMOVX:
2607 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2608 default:
2609 return "mov{b}\t{%h1, %0|%0, %h1}";
2610 }
2611 }
2612 [(set (attr "type")
2613 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615 (ne (symbol_ref "TARGET_MOVX")
2616 (const_int 0))))
2617 (const_string "imovx")
2618 (const_string "imov")))
2619 (set (attr "mode")
2620 (if_then_else (eq_attr "type" "imovx")
2621 (const_string "SI")
2622 (const_string "QI")))])
2623
2624 (define_expand "mov<mode>_insv_1"
2625 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2626 (const_int 8)
2627 (const_int 8))
2628 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2629
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2632 (const_int 8)
2633 (const_int 8))
2634 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2635 "TARGET_64BIT"
2636 "mov{b}\t{%b1, %h0|%h0, %b1}"
2637 [(set_attr "type" "imov")
2638 (set_attr "mode" "QI")])
2639
2640 (define_insn "*movsi_insv_1"
2641 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2642 (const_int 8)
2643 (const_int 8))
2644 (match_operand:SI 1 "general_operand" "Qmn"))]
2645 "!TARGET_64BIT"
2646 "mov{b}\t{%b1, %h0|%h0, %b1}"
2647 [(set_attr "type" "imov")
2648 (set_attr "mode" "QI")])
2649
2650 (define_insn "*movqi_insv_2"
2651 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2652 (const_int 8)
2653 (const_int 8))
2654 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2655 (const_int 8)))]
2656 ""
2657 "mov{b}\t{%h1, %h0|%h0, %h1}"
2658 [(set_attr "type" "imov")
2659 (set_attr "mode" "QI")])
2660 \f
2661 ;; Floating point push instructions.
2662
2663 (define_insn "*pushtf"
2664 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2666 "TARGET_SSE2"
2667 {
2668 /* This insn should be already split before reg-stack. */
2669 gcc_unreachable ();
2670 }
2671 [(set_attr "type" "multi")
2672 (set_attr "unit" "sse,*,*")
2673 (set_attr "mode" "TF,SI,SI")])
2674
2675 ;; %%% Kill this when call knows how to work this out.
2676 (define_split
2677 [(set (match_operand:TF 0 "push_operand" "")
2678 (match_operand:TF 1 "sse_reg_operand" ""))]
2679 "TARGET_SSE2 && reload_completed"
2680 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2682
2683 (define_insn "*pushxf"
2684 [(set (match_operand:XF 0 "push_operand" "=<,<")
2685 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686 "optimize_function_for_speed_p (cfun)"
2687 {
2688 /* This insn should be already split before reg-stack. */
2689 gcc_unreachable ();
2690 }
2691 [(set_attr "type" "multi")
2692 (set_attr "unit" "i387,*")
2693 (set_attr "mode" "XF,SI")])
2694
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2700
2701 (define_insn "*pushxf_nointeger"
2702 [(set (match_operand:XF 0 "push_operand" "=X,X")
2703 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704 "optimize_function_for_size_p (cfun)"
2705 {
2706 /* This insn should be already split before reg-stack. */
2707 gcc_unreachable ();
2708 }
2709 [(set_attr "type" "multi")
2710 (set_attr "unit" "i387,*")
2711 (set_attr "mode" "XF,SI")])
2712
2713 ;; %%% Kill this when call knows how to work this out.
2714 (define_split
2715 [(set (match_operand:XF 0 "push_operand" "")
2716 (match_operand:XF 1 "fp_register_operand" ""))]
2717 "reload_completed"
2718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2721
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2725
2726 (define_insn "*pushdf"
2727 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2729 ""
2730 {
2731 /* This insn should be already split before reg-stack. */
2732 gcc_unreachable ();
2733 }
2734 [(set_attr "type" "multi")
2735 (set_attr "unit" "i387,*,*")
2736 (set_attr "mode" "DF,SI,DF")])
2737
2738 ;; %%% Kill this when call knows how to work this out.
2739 (define_split
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2742 "reload_completed"
2743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2745
2746 (define_insn "*pushsf_rex64"
2747 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2749 "TARGET_64BIT"
2750 {
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{q}\t%q1";
2754 }
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,DI,SF")])
2758
2759 (define_insn "*pushsf"
2760 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2762 "!TARGET_64BIT"
2763 {
2764 /* Anything else should be already split before reg-stack. */
2765 gcc_assert (which_alternative == 1);
2766 return "push{l}\t%1";
2767 }
2768 [(set_attr "type" "multi,push,multi")
2769 (set_attr "unit" "i387,*,*")
2770 (set_attr "mode" "SF,SI,SF")])
2771
2772 ;; %%% Kill this when call knows how to work this out.
2773 (define_split
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2776 "reload_completed"
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2780
2781 (define_split
2782 [(set (match_operand:SF 0 "push_operand" "")
2783 (match_operand:SF 1 "memory_operand" ""))]
2784 "reload_completed
2785 && (operands[2] = find_constant_src (insn))"
2786 [(set (match_dup 0) (match_dup 2))])
2787
2788 (define_split
2789 [(set (match_operand 0 "push_operand" "")
2790 (match_operand 1 "general_operand" ""))]
2791 "reload_completed
2792 && (GET_MODE (operands[0]) == TFmode
2793 || GET_MODE (operands[0]) == XFmode
2794 || GET_MODE (operands[0]) == DFmode)
2795 && !ANY_FP_REG_P (operands[1])"
2796 [(const_int 0)]
2797 "ix86_split_long_move (operands); DONE;")
2798 \f
2799 ;; Floating point move instructions.
2800
2801 (define_expand "movtf"
2802 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803 (match_operand:TF 1 "nonimmediate_operand" ""))]
2804 "TARGET_SSE2"
2805 {
2806 ix86_expand_move (TFmode, operands);
2807 DONE;
2808 })
2809
2810 (define_expand "mov<mode>"
2811 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812 (match_operand:X87MODEF 1 "general_operand" ""))]
2813 ""
2814 "ix86_expand_move (<MODE>mode, operands); DONE;")
2815
2816 (define_insn "*movtf_internal"
2817 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2819 "TARGET_SSE2
2820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821 && (!can_create_pseudo_p ()
2822 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823 || GET_CODE (operands[1]) != CONST_DOUBLE
2824 || (optimize_function_for_size_p (cfun)
2825 && standard_sse_constant_p (operands[1])
2826 && !memory_operand (operands[0], TFmode))
2827 || (!TARGET_MEMORY_MISMATCH_STALL
2828 && memory_operand (operands[0], TFmode)))"
2829 {
2830 switch (which_alternative)
2831 {
2832 case 0:
2833 case 1:
2834 /* Handle misaligned load/store since we
2835 don't have movmisaligntf pattern. */
2836 if (misaligned_operand (operands[0], TFmode)
2837 || misaligned_operand (operands[1], TFmode))
2838 {
2839 if (get_attr_mode (insn) == MODE_V4SF)
2840 return "%vmovups\t{%1, %0|%0, %1}";
2841 else
2842 return "%vmovdqu\t{%1, %0|%0, %1}";
2843 }
2844 else
2845 {
2846 if (get_attr_mode (insn) == MODE_V4SF)
2847 return "%vmovaps\t{%1, %0|%0, %1}";
2848 else
2849 return "%vmovdqa\t{%1, %0|%0, %1}";
2850 }
2851
2852 case 2:
2853 return standard_sse_constant_opcode (insn, operands[1]);
2854
2855 case 3:
2856 case 4:
2857 return "#";
2858
2859 default:
2860 gcc_unreachable ();
2861 }
2862 }
2863 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2865 (set (attr "mode")
2866 (cond [(eq_attr "alternative" "0,2")
2867 (if_then_else
2868 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2869 (const_int 0))
2870 (const_string "V4SF")
2871 (const_string "TI"))
2872 (eq_attr "alternative" "1")
2873 (if_then_else
2874 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2875 (const_int 0))
2876 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2877 (const_int 0)))
2878 (const_string "V4SF")
2879 (const_string "TI"))]
2880 (const_string "DI")))])
2881
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2886 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887 && (!can_create_pseudo_p ()
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || GET_CODE (operands[1]) != CONST_DOUBLE
2890 || (optimize_function_for_size_p (cfun)
2891 && standard_80387_constant_p (operands[1]) > 0
2892 && !memory_operand (operands[0], XFmode))
2893 || (!TARGET_MEMORY_MISMATCH_STALL
2894 && memory_operand (operands[0], XFmode)))"
2895 {
2896 switch (which_alternative)
2897 {
2898 case 0:
2899 case 1:
2900 return output_387_reg_move (insn, operands);
2901
2902 case 2:
2903 return standard_80387_constant_opcode (operands[1]);
2904
2905 case 3:
2906 case 4:
2907 return "#";
2908
2909 default:
2910 gcc_unreachable ();
2911 }
2912 }
2913 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914 (set_attr "mode" "XF,XF,XF,SI,SI")])
2915
2916 (define_insn "*movdf_internal_rex64"
2917 [(set (match_operand:DF 0 "nonimmediate_operand"
2918 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2919 (match_operand:DF 1 "general_operand"
2920 "fm,f,G,rm,r ,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2921 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && (!can_create_pseudo_p ()
2923 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924 || GET_CODE (operands[1]) != CONST_DOUBLE
2925 || (optimize_function_for_size_p (cfun)
2926 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927 && standard_80387_constant_p (operands[1]) > 0)
2928 || (TARGET_SSE2 && TARGET_SSE_MATH
2929 && standard_sse_constant_p (operands[1]))))
2930 || memory_operand (operands[0], DFmode))"
2931 {
2932 switch (which_alternative)
2933 {
2934 case 0:
2935 case 1:
2936 return output_387_reg_move (insn, operands);
2937
2938 case 2:
2939 return standard_80387_constant_opcode (operands[1]);
2940
2941 case 3:
2942 case 4:
2943 return "mov{q}\t{%1, %0|%0, %1}";
2944
2945 case 5:
2946 return "movabs{q}\t{%1, %0|%0, %1}";
2947
2948 case 6:
2949 return "#";
2950
2951 case 7:
2952 return standard_sse_constant_opcode (insn, operands[1]);
2953
2954 case 8:
2955 case 9:
2956 case 10:
2957 switch (get_attr_mode (insn))
2958 {
2959 case MODE_V2DF:
2960 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961 return "%vmovapd\t{%1, %0|%0, %1}";
2962 case MODE_V4SF:
2963 return "%vmovaps\t{%1, %0|%0, %1}";
2964
2965 case MODE_DI:
2966 return "%vmovq\t{%1, %0|%0, %1}";
2967 case MODE_DF:
2968 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2969 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2970 return "%vmovsd\t{%1, %0|%0, %1}";
2971 case MODE_V1DF:
2972 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2973 case MODE_V2SF:
2974 return "%vmovlps\t{%1, %d0|%d0, %1}";
2975 default:
2976 gcc_unreachable ();
2977 }
2978
2979 case 11:
2980 case 12:
2981 /* Handle broken assemblers that require movd instead of movq. */
2982 return "%vmovd\t{%1, %0|%0, %1}";
2983
2984 default:
2985 gcc_unreachable();
2986 }
2987 }
2988 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2989 (set (attr "modrm")
2990 (if_then_else
2991 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2992 (const_string "0")
2993 (const_string "*")))
2994 (set (attr "length_immediate")
2995 (if_then_else
2996 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2997 (const_string "8")
2998 (const_string "*")))
2999 (set (attr "prefix")
3000 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3001 (const_string "orig")
3002 (const_string "maybe_vex")))
3003 (set (attr "prefix_data16")
3004 (if_then_else (eq_attr "mode" "V1DF")
3005 (const_string "1")
3006 (const_string "*")))
3007 (set (attr "mode")
3008 (cond [(eq_attr "alternative" "0,1,2")
3009 (const_string "DF")
3010 (eq_attr "alternative" "3,4,5,6,11,12")
3011 (const_string "DI")
3012
3013 /* xorps is one byte shorter. */
3014 (eq_attr "alternative" "7")
3015 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3016 (const_int 0))
3017 (const_string "V4SF")
3018 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3019 (const_int 0))
3020 (const_string "TI")
3021 ]
3022 (const_string "V2DF"))
3023
3024 /* For architectures resolving dependencies on
3025 whole SSE registers use APD move to break dependency
3026 chains, otherwise use short move to avoid extra work.
3027
3028 movaps encodes one byte shorter. */
3029 (eq_attr "alternative" "8")
3030 (cond
3031 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3032 (const_int 0))
3033 (const_string "V4SF")
3034 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3035 (const_int 0))
3036 (const_string "V2DF")
3037 ]
3038 (const_string "DF"))
3039 /* For architectures resolving dependencies on register
3040 parts we may avoid extra work to zero out upper part
3041 of register. */
3042 (eq_attr "alternative" "9")
3043 (if_then_else
3044 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3045 (const_int 0))
3046 (const_string "V1DF")
3047 (const_string "DF"))
3048 ]
3049 (const_string "DF")))])
3050
3051 ;; Possible store forwarding (partial memory) stall in alternative 4.
3052 (define_insn "*movdf_internal"
3053 [(set (match_operand:DF 0 "nonimmediate_operand"
3054 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3055 (match_operand:DF 1 "general_operand"
3056 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3057 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3058 && (!can_create_pseudo_p ()
3059 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060 || GET_CODE (operands[1]) != CONST_DOUBLE
3061 || (optimize_function_for_size_p (cfun)
3062 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3063 && standard_80387_constant_p (operands[1]) > 0)
3064 || (TARGET_SSE2 && TARGET_SSE_MATH
3065 && standard_sse_constant_p (operands[1])))
3066 && !memory_operand (operands[0], DFmode))
3067 || (!TARGET_MEMORY_MISMATCH_STALL
3068 && memory_operand (operands[0], DFmode)))"
3069 {
3070 switch (which_alternative)
3071 {
3072 case 0:
3073 case 1:
3074 return output_387_reg_move (insn, operands);
3075
3076 case 2:
3077 return standard_80387_constant_opcode (operands[1]);
3078
3079 case 3:
3080 case 4:
3081 return "#";
3082
3083 case 5:
3084 return standard_sse_constant_opcode (insn, operands[1]);
3085
3086 case 6:
3087 case 7:
3088 case 8:
3089 switch (get_attr_mode (insn))
3090 {
3091 case MODE_V2DF:
3092 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "%vmovapd\t{%1, %0|%0, %1}";
3094 case MODE_V4SF:
3095 return "%vmovaps\t{%1, %0|%0, %1}";
3096
3097 case MODE_DI:
3098 return "%vmovq\t{%1, %0|%0, %1}";
3099 case MODE_DF:
3100 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3101 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102 return "%vmovsd\t{%1, %0|%0, %1}";
3103 case MODE_V1DF:
3104 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3105 case MODE_V2SF:
3106 return "%vmovlps\t{%1, %d0|%d0, %1}";
3107 default:
3108 gcc_unreachable ();
3109 }
3110
3111 default:
3112 gcc_unreachable ();
3113 }
3114 }
3115 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3122 (const_string "1")
3123 (const_string "*")))
3124 (set (attr "mode")
3125 (cond [(eq_attr "alternative" "0,1,2")
3126 (const_string "DF")
3127 (eq_attr "alternative" "3,4")
3128 (const_string "SI")
3129
3130 /* For SSE1, we have many fewer alternatives. */
3131 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3132 (if_then_else
3133 (eq_attr "alternative" "5,6")
3134 (const_string "V4SF")
3135 (const_string "V2SF"))
3136
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5")
3139 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3140 (const_int 0))
3141 (const_string "V4SF")
3142 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3143 (const_int 0))
3144 (const_string "TI")
3145 ]
3146 (const_string "V2DF"))
3147
3148 /* For architectures resolving dependencies on
3149 whole SSE registers use APD move to break dependency
3150 chains, otherwise use short move to avoid extra work.
3151
3152 movaps encodes one byte shorter. */
3153 (eq_attr "alternative" "6")
3154 (cond
3155 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3156 (const_int 0))
3157 (const_string "V4SF")
3158 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3159 (const_int 0))
3160 (const_string "V2DF")
3161 ]
3162 (const_string "DF"))
3163 /* For architectures resolving dependencies on register
3164 parts we may avoid extra work to zero out upper part
3165 of register. */
3166 (eq_attr "alternative" "7")
3167 (if_then_else
3168 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3169 (const_int 0))
3170 (const_string "V1DF")
3171 (const_string "DF"))
3172 ]
3173 (const_string "DF")))])
3174
3175 (define_insn "*movsf_internal"
3176 [(set (match_operand:SF 0 "nonimmediate_operand"
3177 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178 (match_operand:SF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (!can_create_pseudo_p ()
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || (optimize_function_for_size_p (cfun)
3185 && ((!TARGET_SSE_MATH
3186 && standard_80387_constant_p (operands[1]) > 0)
3187 || (TARGET_SSE_MATH
3188 && standard_sse_constant_p (operands[1]))))
3189 || memory_operand (operands[0], SFmode))"
3190 {
3191 switch (which_alternative)
3192 {
3193 case 0:
3194 case 1:
3195 return output_387_reg_move (insn, operands);
3196
3197 case 2:
3198 return standard_80387_constant_opcode (operands[1]);
3199
3200 case 3:
3201 case 4:
3202 return "mov{l}\t{%1, %0|%0, %1}";
3203
3204 case 5:
3205 return standard_sse_constant_opcode (insn, operands[1]);
3206
3207 case 6:
3208 if (get_attr_mode (insn) == MODE_V4SF)
3209 return "%vmovaps\t{%1, %0|%0, %1}";
3210 if (TARGET_AVX)
3211 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3212
3213 case 7:
3214 case 8:
3215 return "%vmovss\t{%1, %0|%0, %1}";
3216
3217 case 9:
3218 case 10:
3219 case 14:
3220 case 15:
3221 return "movd\t{%1, %0|%0, %1}";
3222
3223 case 11:
3224 return "movq\t{%1, %0|%0, %1}";
3225
3226 case 12:
3227 case 13:
3228 return "%vmovd\t{%1, %0|%0, %1}";
3229
3230 default:
3231 gcc_unreachable ();
3232 }
3233 }
3234 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3235 (set (attr "prefix")
3236 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3237 (const_string "maybe_vex")
3238 (const_string "orig")))
3239 (set (attr "mode")
3240 (cond [(eq_attr "alternative" "3,4,9,10")
3241 (const_string "SI")
3242 (eq_attr "alternative" "5")
3243 (if_then_else
3244 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3245 (const_int 0))
3246 (ne (symbol_ref "TARGET_SSE2")
3247 (const_int 0)))
3248 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3249 (const_int 0)))
3250 (const_string "TI")
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3255
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3263 (if_then_else
3264 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265 (const_int 0))
3266 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3267 (const_int 0)))
3268 (const_string "V4SF")
3269 (const_string "SF"))
3270 (eq_attr "alternative" "11")
3271 (const_string "DI")]
3272 (const_string "SF")))])
3273
3274 (define_split
3275 [(set (match_operand 0 "any_fp_register_operand" "")
3276 (match_operand 1 "memory_operand" ""))]
3277 "reload_completed
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == DFmode
3281 || GET_MODE (operands[0]) == SFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3284 {
3285 rtx c = operands[2];
3286 int r = REGNO (operands[0]);
3287
3288 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3290 FAIL;
3291 })
3292
3293 (define_split
3294 [(set (match_operand 0 "any_fp_register_operand" "")
3295 (float_extend (match_operand 1 "memory_operand" "")))]
3296 "reload_completed
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode)
3300 && (operands[2] = find_constant_src (insn))"
3301 [(set (match_dup 0) (match_dup 2))]
3302 {
3303 rtx c = operands[2];
3304 int r = REGNO (operands[0]);
3305
3306 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3308 FAIL;
3309 })
3310
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3312 (define_split
3313 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3315 "reload_completed
3316 && (standard_80387_constant_p (operands[1]) == 8
3317 || standard_80387_constant_p (operands[1]) == 9)"
3318 [(set (match_dup 0)(match_dup 1))
3319 (set (match_dup 0)
3320 (neg:X87MODEF (match_dup 0)))]
3321 {
3322 REAL_VALUE_TYPE r;
3323
3324 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325 if (real_isnegzero (&r))
3326 operands[1] = CONST0_RTX (<MODE>mode);
3327 else
3328 operands[1] = CONST1_RTX (<MODE>mode);
3329 })
3330
3331 (define_split
3332 [(set (match_operand 0 "nonimmediate_operand" "")
3333 (match_operand 1 "general_operand" ""))]
3334 "reload_completed
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3339 [(const_int 0)]
3340 "ix86_split_long_move (operands); DONE;")
3341
3342 (define_insn "swapxf"
3343 [(set (match_operand:XF 0 "register_operand" "+f")
3344 (match_operand:XF 1 "register_operand" "+f"))
3345 (set (match_dup 1)
3346 (match_dup 0))]
3347 "TARGET_80387"
3348 {
3349 if (STACK_TOP_P (operands[0]))
3350 return "fxch\t%1";
3351 else
3352 return "fxch\t%0";
3353 }
3354 [(set_attr "type" "fxch")
3355 (set_attr "mode" "XF")])
3356
3357 (define_insn "*swap<mode>"
3358 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3360 (set (match_dup 1)
3361 (match_dup 0))]
3362 "TARGET_80387 || reload_completed"
3363 {
3364 if (STACK_TOP_P (operands[0]))
3365 return "fxch\t%1";
3366 else
3367 return "fxch\t%0";
3368 }
3369 [(set_attr "type" "fxch")
3370 (set_attr "mode" "<MODE>")])
3371 \f
3372 ;; Zero extension instructions
3373
3374 (define_expand "zero_extendsidi2"
3375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3377 ""
3378 {
3379 if (!TARGET_64BIT)
3380 {
3381 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3382 DONE;
3383 }
3384 })
3385
3386 (define_insn "*zero_extendsidi2_rex64"
3387 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3388 (zero_extend:DI
3389 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3390 "TARGET_64BIT"
3391 "@
3392 mov\t{%k1, %k0|%k0, %k1}
3393 #
3394 movd\t{%1, %0|%0, %1}
3395 movd\t{%1, %0|%0, %1}
3396 %vmovd\t{%1, %0|%0, %1}
3397 %vmovd\t{%1, %0|%0, %1}"
3398 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3399 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400 (set_attr "prefix_0f" "0,*,*,*,*,*")
3401 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3402
3403 (define_split
3404 [(set (match_operand:DI 0 "memory_operand" "")
3405 (zero_extend:DI (match_dup 0)))]
3406 "TARGET_64BIT"
3407 [(set (match_dup 4) (const_int 0))]
3408 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3409
3410 ;; %%% Kill me once multi-word ops are sane.
3411 (define_insn "zero_extendsidi2_1"
3412 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3413 (zero_extend:DI
3414 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3415 (clobber (reg:CC FLAGS_REG))]
3416 "!TARGET_64BIT"
3417 "@
3418 #
3419 #
3420 #
3421 movd\t{%1, %0|%0, %1}
3422 movd\t{%1, %0|%0, %1}
3423 %vmovd\t{%1, %0|%0, %1}
3424 %vmovd\t{%1, %0|%0, %1}"
3425 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3426 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3427 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3428
3429 (define_split
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3432 (clobber (reg:CC FLAGS_REG))]
3433 "!TARGET_64BIT && reload_completed
3434 && true_regnum (operands[0]) == true_regnum (operands[1])"
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3437
3438 (define_split
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3441 (clobber (reg:CC FLAGS_REG))]
3442 "!TARGET_64BIT && reload_completed
3443 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444 [(set (match_dup 3) (match_dup 1))
3445 (set (match_dup 4) (const_int 0))]
3446 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447
3448 (define_insn "zero_extend<mode>di2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (zero_extend:DI
3451 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3452 "TARGET_64BIT"
3453 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "SI")])
3456
3457 (define_expand "zero_extendhisi2"
3458 [(set (match_operand:SI 0 "register_operand" "")
3459 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3460 ""
3461 {
3462 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3463 {
3464 operands[1] = force_reg (HImode, operands[1]);
3465 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3466 DONE;
3467 }
3468 })
3469
3470 (define_insn_and_split "zero_extendhisi2_and"
3471 [(set (match_operand:SI 0 "register_operand" "=r")
3472 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3473 (clobber (reg:CC FLAGS_REG))]
3474 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3475 "#"
3476 "&& reload_completed"
3477 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3478 (clobber (reg:CC FLAGS_REG))])]
3479 ""
3480 [(set_attr "type" "alu1")
3481 (set_attr "mode" "SI")])
3482
3483 (define_insn "*zero_extendhisi2_movzwl"
3484 [(set (match_operand:SI 0 "register_operand" "=r")
3485 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3486 "!TARGET_ZERO_EXTEND_WITH_AND
3487 || optimize_function_for_size_p (cfun)"
3488 "movz{wl|x}\t{%1, %0|%0, %1}"
3489 [(set_attr "type" "imovx")
3490 (set_attr "mode" "SI")])
3491
3492 (define_expand "zero_extendqi<mode>2"
3493 [(parallel
3494 [(set (match_operand:SWI24 0 "register_operand" "")
3495 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3496 (clobber (reg:CC FLAGS_REG))])])
3497
3498 (define_insn "*zero_extendqi<mode>2_and"
3499 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3500 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3501 (clobber (reg:CC FLAGS_REG))]
3502 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3503 "#"
3504 [(set_attr "type" "alu1")
3505 (set_attr "mode" "<MODE>")])
3506
3507 ;; When source and destination does not overlap, clear destination
3508 ;; first and then do the movb
3509 (define_split
3510 [(set (match_operand:SWI24 0 "register_operand" "")
3511 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512 (clobber (reg:CC FLAGS_REG))]
3513 "reload_completed
3514 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3515 && ANY_QI_REG_P (operands[0])
3516 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3517 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3518 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3519 {
3520 operands[2] = gen_lowpart (QImode, operands[0]);
3521 ix86_expand_clear (operands[0]);
3522 })
3523
3524 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3525 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3526 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527 (clobber (reg:CC FLAGS_REG))]
3528 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3529 "#"
3530 [(set_attr "type" "imovx,alu1")
3531 (set_attr "mode" "<MODE>")])
3532
3533 ;; For the movzbl case strip only the clobber
3534 (define_split
3535 [(set (match_operand:SWI24 0 "register_operand" "")
3536 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3537 (clobber (reg:CC FLAGS_REG))]
3538 "reload_completed
3539 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3540 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3541 [(set (match_dup 0)
3542 (zero_extend:SWI24 (match_dup 1)))])
3543
3544 ; zero extend to SImode to avoid partial register stalls
3545 (define_insn "*zero_extendqi<mode>2_movzbl"
3546 [(set (match_operand:SWI24 0 "register_operand" "=r")
3547 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3548 "reload_completed
3549 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3550 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3551 [(set_attr "type" "imovx")
3552 (set_attr "mode" "SI")])
3553
3554 ;; Rest is handled by single and.
3555 (define_split
3556 [(set (match_operand:SWI24 0 "register_operand" "")
3557 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3558 (clobber (reg:CC FLAGS_REG))]
3559 "reload_completed
3560 && true_regnum (operands[0]) == true_regnum (operands[1])"
3561 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3562 (clobber (reg:CC FLAGS_REG))])])
3563 \f
3564 ;; Sign extension instructions
3565
3566 (define_expand "extendsidi2"
3567 [(set (match_operand:DI 0 "register_operand" "")
3568 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3569 ""
3570 {
3571 if (!TARGET_64BIT)
3572 {
3573 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3574 DONE;
3575 }
3576 })
3577
3578 (define_insn "*extendsidi2_rex64"
3579 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3580 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3581 "TARGET_64BIT"
3582 "@
3583 {cltq|cdqe}
3584 movs{lq|x}\t{%1, %0|%0, %1}"
3585 [(set_attr "type" "imovx")
3586 (set_attr "mode" "DI")
3587 (set_attr "prefix_0f" "0")
3588 (set_attr "modrm" "0,1")])
3589
3590 (define_insn "extendsidi2_1"
3591 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3592 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3593 (clobber (reg:CC FLAGS_REG))
3594 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3595 "!TARGET_64BIT"
3596 "#")
3597
3598 ;; Extend to memory case when source register does die.
3599 (define_split
3600 [(set (match_operand:DI 0 "memory_operand" "")
3601 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3602 (clobber (reg:CC FLAGS_REG))
3603 (clobber (match_operand:SI 2 "register_operand" ""))]
3604 "(reload_completed
3605 && dead_or_set_p (insn, operands[1])
3606 && !reg_mentioned_p (operands[1], operands[0]))"
3607 [(set (match_dup 3) (match_dup 1))
3608 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3609 (clobber (reg:CC FLAGS_REG))])
3610 (set (match_dup 4) (match_dup 1))]
3611 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3612
3613 ;; Extend to memory case when source register does not die.
3614 (define_split
3615 [(set (match_operand:DI 0 "memory_operand" "")
3616 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617 (clobber (reg:CC FLAGS_REG))
3618 (clobber (match_operand:SI 2 "register_operand" ""))]
3619 "reload_completed"
3620 [(const_int 0)]
3621 {
3622 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3623
3624 emit_move_insn (operands[3], operands[1]);
3625
3626 /* Generate a cltd if possible and doing so it profitable. */
3627 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3628 && true_regnum (operands[1]) == AX_REG
3629 && true_regnum (operands[2]) == DX_REG)
3630 {
3631 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3632 }
3633 else
3634 {
3635 emit_move_insn (operands[2], operands[1]);
3636 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3637 }
3638 emit_move_insn (operands[4], operands[2]);
3639 DONE;
3640 })
3641
3642 ;; Extend to register case. Optimize case where source and destination
3643 ;; registers match and cases where we can use cltd.
3644 (define_split
3645 [(set (match_operand:DI 0 "register_operand" "")
3646 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3647 (clobber (reg:CC FLAGS_REG))
3648 (clobber (match_scratch:SI 2 ""))]
3649 "reload_completed"
3650 [(const_int 0)]
3651 {
3652 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3653
3654 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3655 emit_move_insn (operands[3], operands[1]);
3656
3657 /* Generate a cltd if possible and doing so it profitable. */
3658 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3659 && true_regnum (operands[3]) == AX_REG
3660 && true_regnum (operands[4]) == DX_REG)
3661 {
3662 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3663 DONE;
3664 }
3665
3666 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3667 emit_move_insn (operands[4], operands[1]);
3668
3669 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3670 DONE;
3671 })
3672
3673 (define_insn "extend<mode>di2"
3674 [(set (match_operand:DI 0 "register_operand" "=r")
3675 (sign_extend:DI
3676 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3677 "TARGET_64BIT"
3678 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3679 [(set_attr "type" "imovx")
3680 (set_attr "mode" "DI")])
3681
3682 (define_insn "extendhisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3684 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3685 ""
3686 {
3687 switch (get_attr_prefix_0f (insn))
3688 {
3689 case 0:
3690 return "{cwtl|cwde}";
3691 default:
3692 return "movs{wl|x}\t{%1, %0|%0, %1}";
3693 }
3694 }
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "SI")
3697 (set (attr "prefix_0f")
3698 ;; movsx is short decodable while cwtl is vector decoded.
3699 (if_then_else (and (eq_attr "cpu" "!k6")
3700 (eq_attr "alternative" "0"))
3701 (const_string "0")
3702 (const_string "1")))
3703 (set (attr "modrm")
3704 (if_then_else (eq_attr "prefix_0f" "0")
3705 (const_string "0")
3706 (const_string "1")))])
3707
3708 (define_insn "*extendhisi2_zext"
3709 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3710 (zero_extend:DI
3711 (sign_extend:SI
3712 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3713 "TARGET_64BIT"
3714 {
3715 switch (get_attr_prefix_0f (insn))
3716 {
3717 case 0:
3718 return "{cwtl|cwde}";
3719 default:
3720 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3721 }
3722 }
3723 [(set_attr "type" "imovx")
3724 (set_attr "mode" "SI")
3725 (set (attr "prefix_0f")
3726 ;; movsx is short decodable while cwtl is vector decoded.
3727 (if_then_else (and (eq_attr "cpu" "!k6")
3728 (eq_attr "alternative" "0"))
3729 (const_string "0")
3730 (const_string "1")))
3731 (set (attr "modrm")
3732 (if_then_else (eq_attr "prefix_0f" "0")
3733 (const_string "0")
3734 (const_string "1")))])
3735
3736 (define_insn "extendqisi2"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3738 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 ""
3740 "movs{bl|x}\t{%1, %0|%0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3743
3744 (define_insn "*extendqisi2_zext"
3745 [(set (match_operand:DI 0 "register_operand" "=r")
3746 (zero_extend:DI
3747 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3748 "TARGET_64BIT"
3749 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "SI")])
3752
3753 (define_insn "extendqihi2"
3754 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3755 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3756 ""
3757 {
3758 switch (get_attr_prefix_0f (insn))
3759 {
3760 case 0:
3761 return "{cbtw|cbw}";
3762 default:
3763 return "movs{bw|x}\t{%1, %0|%0, %1}";
3764 }
3765 }
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "HI")
3768 (set (attr "prefix_0f")
3769 ;; movsx is short decodable while cwtl is vector decoded.
3770 (if_then_else (and (eq_attr "cpu" "!k6")
3771 (eq_attr "alternative" "0"))
3772 (const_string "0")
3773 (const_string "1")))
3774 (set (attr "modrm")
3775 (if_then_else (eq_attr "prefix_0f" "0")
3776 (const_string "0")
3777 (const_string "1")))])
3778 \f
3779 ;; Conversions between float and double.
3780
3781 ;; These are all no-ops in the model used for the 80387.
3782 ;; So just emit moves.
3783
3784 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3785 (define_split
3786 [(set (match_operand:DF 0 "push_operand" "")
3787 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3788 "reload_completed"
3789 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3790 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3791
3792 (define_split
3793 [(set (match_operand:XF 0 "push_operand" "")
3794 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3795 "reload_completed"
3796 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3797 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3798 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3799
3800 (define_expand "extendsfdf2"
3801 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3802 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3803 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3804 {
3805 /* ??? Needed for compress_float_constant since all fp constants
3806 are TARGET_LEGITIMATE_CONSTANT_P. */
3807 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3808 {
3809 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3810 && standard_80387_constant_p (operands[1]) > 0)
3811 {
3812 operands[1] = simplify_const_unary_operation
3813 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3814 emit_move_insn_1 (operands[0], operands[1]);
3815 DONE;
3816 }
3817 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3818 }
3819 })
3820
3821 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3822 cvtss2sd:
3823 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3824 cvtps2pd xmm2,xmm1
3825 We do the conversion post reload to avoid producing of 128bit spills
3826 that might lead to ICE on 32bit target. The sequence unlikely combine
3827 anyway. */
3828 (define_split
3829 [(set (match_operand:DF 0 "register_operand" "")
3830 (float_extend:DF
3831 (match_operand:SF 1 "nonimmediate_operand" "")))]
3832 "TARGET_USE_VECTOR_FP_CONVERTS
3833 && optimize_insn_for_speed_p ()
3834 && reload_completed && SSE_REG_P (operands[0])"
3835 [(set (match_dup 2)
3836 (float_extend:V2DF
3837 (vec_select:V2SF
3838 (match_dup 3)
3839 (parallel [(const_int 0) (const_int 1)]))))]
3840 {
3841 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3842 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3843 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3844 Try to avoid move when unpacking can be done in source. */
3845 if (REG_P (operands[1]))
3846 {
3847 /* If it is unsafe to overwrite upper half of source, we need
3848 to move to destination and unpack there. */
3849 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3850 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3851 && true_regnum (operands[0]) != true_regnum (operands[1]))
3852 {
3853 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3854 emit_move_insn (tmp, operands[1]);
3855 }
3856 else
3857 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3858 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3859 operands[3]));
3860 }
3861 else
3862 emit_insn (gen_vec_setv4sf_0 (operands[3],
3863 CONST0_RTX (V4SFmode), operands[1]));
3864 })
3865
3866 (define_insn "*extendsfdf2_mixed"
3867 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3868 (float_extend:DF
3869 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3870 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3871 {
3872 switch (which_alternative)
3873 {
3874 case 0:
3875 case 1:
3876 return output_387_reg_move (insn, operands);
3877
3878 case 2:
3879 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3880
3881 default:
3882 gcc_unreachable ();
3883 }
3884 }
3885 [(set_attr "type" "fmov,fmov,ssecvt")
3886 (set_attr "prefix" "orig,orig,maybe_vex")
3887 (set_attr "mode" "SF,XF,DF")])
3888
3889 (define_insn "*extendsfdf2_sse"
3890 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3891 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3892 "TARGET_SSE2 && TARGET_SSE_MATH"
3893 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3894 [(set_attr "type" "ssecvt")
3895 (set_attr "prefix" "maybe_vex")
3896 (set_attr "mode" "DF")])
3897
3898 (define_insn "*extendsfdf2_i387"
3899 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3900 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3901 "TARGET_80387"
3902 "* return output_387_reg_move (insn, operands);"
3903 [(set_attr "type" "fmov")
3904 (set_attr "mode" "SF,XF")])
3905
3906 (define_expand "extend<mode>xf2"
3907 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3908 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3909 "TARGET_80387"
3910 {
3911 /* ??? Needed for compress_float_constant since all fp constants
3912 are TARGET_LEGITIMATE_CONSTANT_P. */
3913 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3914 {
3915 if (standard_80387_constant_p (operands[1]) > 0)
3916 {
3917 operands[1] = simplify_const_unary_operation
3918 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3919 emit_move_insn_1 (operands[0], operands[1]);
3920 DONE;
3921 }
3922 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3923 }
3924 })
3925
3926 (define_insn "*extend<mode>xf2_i387"
3927 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3928 (float_extend:XF
3929 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3930 "TARGET_80387"
3931 "* return output_387_reg_move (insn, operands);"
3932 [(set_attr "type" "fmov")
3933 (set_attr "mode" "<MODE>,XF")])
3934
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case. Otherwise this is just like a simple move
3938 ;; insn. So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3940
3941 ;; Conversion from DFmode to SFmode.
3942
3943 (define_expand "truncdfsf2"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3945 (float_truncate:SF
3946 (match_operand:DF 1 "nonimmediate_operand" "")))]
3947 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 {
3949 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950 ;
3951 else if (flag_unsafe_math_optimizations)
3952 ;
3953 else
3954 {
3955 enum ix86_stack_slot slot = (virtuals_instantiated
3956 ? SLOT_TEMP
3957 : SLOT_VIRTUAL);
3958 rtx temp = assign_386_stack_local (SFmode, slot);
3959 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3960 DONE;
3961 }
3962 })
3963
3964 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3965 cvtsd2ss:
3966 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3967 cvtpd2ps xmm2,xmm1
3968 We do the conversion post reload to avoid producing of 128bit spills
3969 that might lead to ICE on 32bit target. The sequence unlikely combine
3970 anyway. */
3971 (define_split
3972 [(set (match_operand:SF 0 "register_operand" "")
3973 (float_truncate:SF
3974 (match_operand:DF 1 "nonimmediate_operand" "")))]
3975 "TARGET_USE_VECTOR_FP_CONVERTS
3976 && optimize_insn_for_speed_p ()
3977 && reload_completed && SSE_REG_P (operands[0])"
3978 [(set (match_dup 2)
3979 (vec_concat:V4SF
3980 (float_truncate:V2SF
3981 (match_dup 4))
3982 (match_dup 3)))]
3983 {
3984 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3985 operands[3] = CONST0_RTX (V2SFmode);
3986 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3987 /* Use movsd for loading from memory, unpcklpd for registers.
3988 Try to avoid move when unpacking can be done in source, or SSE3
3989 movddup is available. */
3990 if (REG_P (operands[1]))
3991 {
3992 if (!TARGET_SSE3
3993 && true_regnum (operands[0]) != true_regnum (operands[1])
3994 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3995 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3996 {
3997 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3998 emit_move_insn (tmp, operands[1]);
3999 operands[1] = tmp;
4000 }
4001 else if (!TARGET_SSE3)
4002 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4003 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4004 }
4005 else
4006 emit_insn (gen_sse2_loadlpd (operands[4],
4007 CONST0_RTX (V2DFmode), operands[1]));
4008 })
4009
4010 (define_expand "truncdfsf2_with_temp"
4011 [(parallel [(set (match_operand:SF 0 "" "")
4012 (float_truncate:SF (match_operand:DF 1 "" "")))
4013 (clobber (match_operand:SF 2 "" ""))])])
4014
4015 (define_insn "*truncdfsf_fast_mixed"
4016 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4017 (float_truncate:SF
4018 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4019 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4020 {
4021 switch (which_alternative)
4022 {
4023 case 0:
4024 return output_387_reg_move (insn, operands);
4025 case 1:
4026 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4027 default:
4028 gcc_unreachable ();
4029 }
4030 }
4031 [(set_attr "type" "fmov,ssecvt")
4032 (set_attr "prefix" "orig,maybe_vex")
4033 (set_attr "mode" "SF")])
4034
4035 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4036 ;; because nothing we do here is unsafe.
4037 (define_insn "*truncdfsf_fast_sse"
4038 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4039 (float_truncate:SF
4040 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4041 "TARGET_SSE2 && TARGET_SSE_MATH"
4042 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4043 [(set_attr "type" "ssecvt")
4044 (set_attr "prefix" "maybe_vex")
4045 (set_attr "mode" "SF")])
4046
4047 (define_insn "*truncdfsf_fast_i387"
4048 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4049 (float_truncate:SF
4050 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4051 "TARGET_80387 && flag_unsafe_math_optimizations"
4052 "* return output_387_reg_move (insn, operands);"
4053 [(set_attr "type" "fmov")
4054 (set_attr "mode" "SF")])
4055
4056 (define_insn "*truncdfsf_mixed"
4057 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4058 (float_truncate:SF
4059 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4060 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4061 "TARGET_MIX_SSE_I387"
4062 {
4063 switch (which_alternative)
4064 {
4065 case 0:
4066 return output_387_reg_move (insn, operands);
4067 case 1:
4068 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4069
4070 default:
4071 return "#";
4072 }
4073 }
4074 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4078
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4081 (float_truncate:SF
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4084 "TARGET_80387"
4085 {
4086 switch (which_alternative)
4087 {
4088 case 0:
4089 return output_387_reg_move (insn, operands);
4090
4091 default:
4092 return "#";
4093 }
4094 }
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4098
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4101 (float_truncate:SF
4102 (match_operand:DF 1 "register_operand" "f")))]
4103 "TARGET_80387
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4109
4110 (define_split
4111 [(set (match_operand:SF 0 "register_operand" "")
4112 (float_truncate:SF
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4115 "reload_completed"
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4119
4120 ;; Conversion from XFmode to {SF,DF}mode
4121
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4127 "TARGET_80387"
4128 {
4129 if (flag_unsafe_math_optimizations)
4130 {
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4135 DONE;
4136 }
4137 else
4138 {
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4140 ? SLOT_TEMP
4141 : SLOT_VIRTUAL);
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4143 }
4144 })
4145
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4148 (float_truncate:SF
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4151 "TARGET_80387"
4152 {
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4155 }
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4162 (float_truncate:DF
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4165 "TARGET_80387"
4166 {
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4169 }
4170 [(set_attr "type" "fmov,multi,multi,multi")
4171 (set_attr "unit" "*,i387,i387,i387")
4172 (set_attr "mode" "DF")])
4173
4174 (define_insn "truncxf<mode>2_i387_noop"
4175 [(set (match_operand:MODEF 0 "register_operand" "=f")
4176 (float_truncate:MODEF
4177 (match_operand:XF 1 "register_operand" "f")))]
4178 "TARGET_80387 && flag_unsafe_math_optimizations"
4179 "* return output_387_reg_move (insn, operands);"
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "<MODE>")])
4182
4183 (define_insn "*truncxf<mode>2_i387"
4184 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4185 (float_truncate:MODEF
4186 (match_operand:XF 1 "register_operand" "f")))]
4187 "TARGET_80387"
4188 "* return output_387_reg_move (insn, operands);"
4189 [(set_attr "type" "fmov")
4190 (set_attr "mode" "<MODE>")])
4191
4192 (define_split
4193 [(set (match_operand:MODEF 0 "register_operand" "")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4197 "TARGET_80387 && reload_completed"
4198 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4199 (set (match_dup 0) (match_dup 2))])
4200
4201 (define_split
4202 [(set (match_operand:MODEF 0 "memory_operand" "")
4203 (float_truncate:MODEF
4204 (match_operand:XF 1 "register_operand" "")))
4205 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4206 "TARGET_80387"
4207 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4208 \f
4209 ;; Signed conversion to DImode.
4210
4211 (define_expand "fix_truncxfdi2"
4212 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213 (fix:DI (match_operand:XF 1 "register_operand" "")))
4214 (clobber (reg:CC FLAGS_REG))])]
4215 "TARGET_80387"
4216 {
4217 if (TARGET_FISTTP)
4218 {
4219 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4220 DONE;
4221 }
4222 })
4223
4224 (define_expand "fix_trunc<mode>di2"
4225 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4227 (clobber (reg:CC FLAGS_REG))])]
4228 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4229 {
4230 if (TARGET_FISTTP
4231 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4232 {
4233 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4234 DONE;
4235 }
4236 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4237 {
4238 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4239 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4240 if (out != operands[0])
4241 emit_move_insn (operands[0], out);
4242 DONE;
4243 }
4244 })
4245
4246 ;; Signed conversion to SImode.
4247
4248 (define_expand "fix_truncxfsi2"
4249 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4250 (fix:SI (match_operand:XF 1 "register_operand" "")))
4251 (clobber (reg:CC FLAGS_REG))])]
4252 "TARGET_80387"
4253 {
4254 if (TARGET_FISTTP)
4255 {
4256 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4257 DONE;
4258 }
4259 })
4260
4261 (define_expand "fix_trunc<mode>si2"
4262 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4263 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4264 (clobber (reg:CC FLAGS_REG))])]
4265 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4266 {
4267 if (TARGET_FISTTP
4268 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4269 {
4270 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4271 DONE;
4272 }
4273 if (SSE_FLOAT_MODE_P (<MODE>mode))
4274 {
4275 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4276 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4277 if (out != operands[0])
4278 emit_move_insn (operands[0], out);
4279 DONE;
4280 }
4281 })
4282
4283 ;; Signed conversion to HImode.
4284
4285 (define_expand "fix_trunc<mode>hi2"
4286 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4287 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4288 (clobber (reg:CC FLAGS_REG))])]
4289 "TARGET_80387
4290 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4291 {
4292 if (TARGET_FISTTP)
4293 {
4294 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4295 DONE;
4296 }
4297 })
4298
4299 ;; Unsigned conversion to SImode.
4300
4301 (define_expand "fixuns_trunc<mode>si2"
4302 [(parallel
4303 [(set (match_operand:SI 0 "register_operand" "")
4304 (unsigned_fix:SI
4305 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4306 (use (match_dup 2))
4307 (clobber (match_scratch:<ssevecmode> 3 ""))
4308 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4309 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4310 {
4311 enum machine_mode mode = <MODE>mode;
4312 enum machine_mode vecmode = <ssevecmode>mode;
4313 REAL_VALUE_TYPE TWO31r;
4314 rtx two31;
4315
4316 if (optimize_insn_for_size_p ())
4317 FAIL;
4318
4319 real_ldexp (&TWO31r, &dconst1, 31);
4320 two31 = const_double_from_real_value (TWO31r, mode);
4321 two31 = ix86_build_const_vector (vecmode, true, two31);
4322 operands[2] = force_reg (vecmode, two31);
4323 })
4324
4325 (define_insn_and_split "*fixuns_trunc<mode>_1"
4326 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4327 (unsigned_fix:SI
4328 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4329 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4330 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4331 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4332 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4333 && optimize_function_for_speed_p (cfun)"
4334 "#"
4335 "&& reload_completed"
4336 [(const_int 0)]
4337 {
4338 ix86_split_convert_uns_si_sse (operands);
4339 DONE;
4340 })
4341
4342 ;; Unsigned conversion to HImode.
4343 ;; Without these patterns, we'll try the unsigned SI conversion which
4344 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4345
4346 (define_expand "fixuns_trunc<mode>hi2"
4347 [(set (match_dup 2)
4348 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4349 (set (match_operand:HI 0 "nonimmediate_operand" "")
4350 (subreg:HI (match_dup 2) 0))]
4351 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4352 "operands[2] = gen_reg_rtx (SImode);")
4353
4354 ;; When SSE is available, it is always faster to use it!
4355 (define_insn "fix_trunc<mode>di_sse"
4356 [(set (match_operand:DI 0 "register_operand" "=r,r")
4357 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4358 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4359 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4360 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4361 [(set_attr "type" "sseicvt")
4362 (set_attr "prefix" "maybe_vex")
4363 (set_attr "prefix_rex" "1")
4364 (set_attr "mode" "<MODE>")
4365 (set_attr "athlon_decode" "double,vector")
4366 (set_attr "amdfam10_decode" "double,double")
4367 (set_attr "bdver1_decode" "double,double")])
4368
4369 (define_insn "fix_trunc<mode>si_sse"
4370 [(set (match_operand:SI 0 "register_operand" "=r,r")
4371 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4372 "SSE_FLOAT_MODE_P (<MODE>mode)
4373 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4375 [(set_attr "type" "sseicvt")
4376 (set_attr "prefix" "maybe_vex")
4377 (set_attr "mode" "<MODE>")
4378 (set_attr "athlon_decode" "double,vector")
4379 (set_attr "amdfam10_decode" "double,double")
4380 (set_attr "bdver1_decode" "double,double")])
4381
4382 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4383 (define_peephole2
4384 [(set (match_operand:MODEF 0 "register_operand" "")
4385 (match_operand:MODEF 1 "memory_operand" ""))
4386 (set (match_operand:SWI48x 2 "register_operand" "")
4387 (fix:SWI48x (match_dup 0)))]
4388 "TARGET_SHORTEN_X87_SSE
4389 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4390 && peep2_reg_dead_p (2, operands[0])"
4391 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4392
4393 ;; Avoid vector decoded forms of the instruction.
4394 (define_peephole2
4395 [(match_scratch:DF 2 "Y2")
4396 (set (match_operand:SWI48x 0 "register_operand" "")
4397 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4398 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4399 [(set (match_dup 2) (match_dup 1))
4400 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4401
4402 (define_peephole2
4403 [(match_scratch:SF 2 "x")
4404 (set (match_operand:SWI48x 0 "register_operand" "")
4405 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4406 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4407 [(set (match_dup 2) (match_dup 1))
4408 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4409
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4412 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4414 && TARGET_FISTTP
4415 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && (TARGET_64BIT || <MODE>mode != DImode))
4417 && TARGET_SSE_MATH)
4418 && can_create_pseudo_p ()"
4419 "#"
4420 "&& 1"
4421 [(const_int 0)]
4422 {
4423 if (memory_operand (operands[0], VOIDmode))
4424 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4425 else
4426 {
4427 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4429 operands[1],
4430 operands[2]));
4431 }
4432 DONE;
4433 }
4434 [(set_attr "type" "fisttp")
4435 (set_attr "mode" "<MODE>")])
4436
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4439 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4440 (clobber (match_scratch:XF 2 "=&1f"))]
4441 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4442 && TARGET_FISTTP
4443 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && (TARGET_64BIT || <MODE>mode != DImode))
4445 && TARGET_SSE_MATH)"
4446 "* return output_fix_trunc (insn, operands, true);"
4447 [(set_attr "type" "fisttp")
4448 (set_attr "mode" "<MODE>")])
4449
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4452 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4453 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4454 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4456 && TARGET_FISTTP
4457 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && (TARGET_64BIT || <MODE>mode != DImode))
4459 && TARGET_SSE_MATH)"
4460 "#"
4461 [(set_attr "type" "fisttp")
4462 (set_attr "mode" "<MODE>")])
4463
4464 (define_split
4465 [(set (match_operand:SWI248x 0 "register_operand" "")
4466 (fix:SWI248x (match_operand 1 "register_operand" "")))
4467 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468 (clobber (match_scratch 3 ""))]
4469 "reload_completed"
4470 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4471 (clobber (match_dup 3))])
4472 (set (match_dup 0) (match_dup 2))])
4473
4474 (define_split
4475 [(set (match_operand:SWI248x 0 "memory_operand" "")
4476 (fix:SWI248x (match_operand 1 "register_operand" "")))
4477 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4478 (clobber (match_scratch 3 ""))]
4479 "reload_completed"
4480 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4481 (clobber (match_dup 3))])])
4482
4483 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4484 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4485 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4486 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4487 ;; function in i386.c.
4488 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4489 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4490 (fix:SWI248x (match_operand 1 "register_operand" "")))
4491 (clobber (reg:CC FLAGS_REG))]
4492 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && !TARGET_FISTTP
4494 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && can_create_pseudo_p ()"
4497 "#"
4498 "&& 1"
4499 [(const_int 0)]
4500 {
4501 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4502
4503 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4504 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4505 if (memory_operand (operands[0], VOIDmode))
4506 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4507 operands[2], operands[3]));
4508 else
4509 {
4510 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4511 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4512 operands[2], operands[3],
4513 operands[4]));
4514 }
4515 DONE;
4516 }
4517 [(set_attr "type" "fistp")
4518 (set_attr "i387_cw" "trunc")
4519 (set_attr "mode" "<MODE>")])
4520
4521 (define_insn "fix_truncdi_i387"
4522 [(set (match_operand:DI 0 "memory_operand" "=m")
4523 (fix:DI (match_operand 1 "register_operand" "f")))
4524 (use (match_operand:HI 2 "memory_operand" "m"))
4525 (use (match_operand:HI 3 "memory_operand" "m"))
4526 (clobber (match_scratch:XF 4 "=&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && !TARGET_FISTTP
4529 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4530 "* return output_fix_trunc (insn, operands, false);"
4531 [(set_attr "type" "fistp")
4532 (set_attr "i387_cw" "trunc")
4533 (set_attr "mode" "DI")])
4534
4535 (define_insn "fix_truncdi_i387_with_temp"
4536 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4537 (fix:DI (match_operand 1 "register_operand" "f,f")))
4538 (use (match_operand:HI 2 "memory_operand" "m,m"))
4539 (use (match_operand:HI 3 "memory_operand" "m,m"))
4540 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4541 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543 && !TARGET_FISTTP
4544 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4545 "#"
4546 [(set_attr "type" "fistp")
4547 (set_attr "i387_cw" "trunc")
4548 (set_attr "mode" "DI")])
4549
4550 (define_split
4551 [(set (match_operand:DI 0 "register_operand" "")
4552 (fix:DI (match_operand 1 "register_operand" "")))
4553 (use (match_operand:HI 2 "memory_operand" ""))
4554 (use (match_operand:HI 3 "memory_operand" ""))
4555 (clobber (match_operand:DI 4 "memory_operand" ""))
4556 (clobber (match_scratch 5 ""))]
4557 "reload_completed"
4558 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4559 (use (match_dup 2))
4560 (use (match_dup 3))
4561 (clobber (match_dup 5))])
4562 (set (match_dup 0) (match_dup 4))])
4563
4564 (define_split
4565 [(set (match_operand:DI 0 "memory_operand" "")
4566 (fix:DI (match_operand 1 "register_operand" "")))
4567 (use (match_operand:HI 2 "memory_operand" ""))
4568 (use (match_operand:HI 3 "memory_operand" ""))
4569 (clobber (match_operand:DI 4 "memory_operand" ""))
4570 (clobber (match_scratch 5 ""))]
4571 "reload_completed"
4572 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4573 (use (match_dup 2))
4574 (use (match_dup 3))
4575 (clobber (match_dup 5))])])
4576
4577 (define_insn "fix_trunc<mode>_i387"
4578 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4579 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4580 (use (match_operand:HI 2 "memory_operand" "m"))
4581 (use (match_operand:HI 3 "memory_operand" "m"))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !TARGET_FISTTP
4584 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4585 "* return output_fix_trunc (insn, operands, false);"
4586 [(set_attr "type" "fistp")
4587 (set_attr "i387_cw" "trunc")
4588 (set_attr "mode" "<MODE>")])
4589
4590 (define_insn "fix_trunc<mode>_i387_with_temp"
4591 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4592 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4593 (use (match_operand:HI 2 "memory_operand" "m,m"))
4594 (use (match_operand:HI 3 "memory_operand" "m,m"))
4595 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4596 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597 && !TARGET_FISTTP
4598 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4599 "#"
4600 [(set_attr "type" "fistp")
4601 (set_attr "i387_cw" "trunc")
4602 (set_attr "mode" "<MODE>")])
4603
4604 (define_split
4605 [(set (match_operand:SWI24 0 "register_operand" "")
4606 (fix:SWI24 (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4610 "reload_completed"
4611 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4612 (use (match_dup 2))
4613 (use (match_dup 3))])
4614 (set (match_dup 0) (match_dup 4))])
4615
4616 (define_split
4617 [(set (match_operand:SWI24 0 "memory_operand" "")
4618 (fix:SWI24 (match_operand 1 "register_operand" "")))
4619 (use (match_operand:HI 2 "memory_operand" ""))
4620 (use (match_operand:HI 3 "memory_operand" ""))
4621 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4622 "reload_completed"
4623 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4624 (use (match_dup 2))
4625 (use (match_dup 3))])])
4626
4627 (define_insn "x86_fnstcw_1"
4628 [(set (match_operand:HI 0 "memory_operand" "=m")
4629 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4630 "TARGET_80387"
4631 "fnstcw\t%0"
4632 [(set (attr "length")
4633 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4634 (set_attr "mode" "HI")
4635 (set_attr "unit" "i387")
4636 (set_attr "bdver1_decode" "vector")])
4637
4638 (define_insn "x86_fldcw_1"
4639 [(set (reg:HI FPCR_REG)
4640 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4641 "TARGET_80387"
4642 "fldcw\t%0"
4643 [(set (attr "length")
4644 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4645 (set_attr "mode" "HI")
4646 (set_attr "unit" "i387")
4647 (set_attr "athlon_decode" "vector")
4648 (set_attr "amdfam10_decode" "vector")
4649 (set_attr "bdver1_decode" "vector")])
4650 \f
4651 ;; Conversion between fixed point and floating point.
4652
4653 ;; Even though we only accept memory inputs, the backend _really_
4654 ;; wants to be able to do this between registers.
4655
4656 (define_expand "floathi<mode>2"
4657 [(set (match_operand:X87MODEF 0 "register_operand" "")
4658 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4659 "TARGET_80387
4660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661 || TARGET_MIX_SSE_I387)")
4662
4663 ;; Pre-reload splitter to add memory clobber to the pattern.
4664 (define_insn_and_split "*floathi<mode>2_1"
4665 [(set (match_operand:X87MODEF 0 "register_operand" "")
4666 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4667 "TARGET_80387
4668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669 || TARGET_MIX_SSE_I387)
4670 && can_create_pseudo_p ()"
4671 "#"
4672 "&& 1"
4673 [(parallel [(set (match_dup 0)
4674 (float:X87MODEF (match_dup 1)))
4675 (clobber (match_dup 2))])]
4676 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4677
4678 (define_insn "*floathi<mode>2_i387_with_temp"
4679 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4680 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4681 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4682 "TARGET_80387
4683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4684 || TARGET_MIX_SSE_I387)"
4685 "#"
4686 [(set_attr "type" "fmov,multi")
4687 (set_attr "mode" "<MODE>")
4688 (set_attr "unit" "*,i387")
4689 (set_attr "fp_int_src" "true")])
4690
4691 (define_insn "*floathi<mode>2_i387"
4692 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4693 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4694 "TARGET_80387
4695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696 || TARGET_MIX_SSE_I387)"
4697 "fild%Z1\t%1"
4698 [(set_attr "type" "fmov")
4699 (set_attr "mode" "<MODE>")
4700 (set_attr "fp_int_src" "true")])
4701
4702 (define_split
4703 [(set (match_operand:X87MODEF 0 "register_operand" "")
4704 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4705 (clobber (match_operand:HI 2 "memory_operand" ""))]
4706 "TARGET_80387
4707 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4708 || TARGET_MIX_SSE_I387)
4709 && reload_completed"
4710 [(set (match_dup 2) (match_dup 1))
4711 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4712
4713 (define_split
4714 [(set (match_operand:X87MODEF 0 "register_operand" "")
4715 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4716 (clobber (match_operand:HI 2 "memory_operand" ""))]
4717 "TARGET_80387
4718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719 || TARGET_MIX_SSE_I387)
4720 && reload_completed"
4721 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4722
4723 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4724 [(set (match_operand:X87MODEF 0 "register_operand" "")
4725 (float:X87MODEF
4726 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4727 "TARGET_80387
4728 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4729 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4730 {
4731 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4732 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4733 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4734 {
4735 rtx reg = gen_reg_rtx (XFmode);
4736 rtx (*insn)(rtx, rtx);
4737
4738 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4739
4740 if (<X87MODEF:MODE>mode == SFmode)
4741 insn = gen_truncxfsf2;
4742 else if (<X87MODEF:MODE>mode == DFmode)
4743 insn = gen_truncxfdf2;
4744 else
4745 gcc_unreachable ();
4746
4747 emit_insn (insn (operands[0], reg));
4748 DONE;
4749 }
4750 })
4751
4752 ;; Pre-reload splitter to add memory clobber to the pattern.
4753 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4754 [(set (match_operand:X87MODEF 0 "register_operand" "")
4755 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4756 "((TARGET_80387
4757 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4758 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4759 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387))
4761 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4762 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4763 && ((<SWI48x:MODE>mode == SImode
4764 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4765 && optimize_function_for_speed_p (cfun)
4766 && flag_trapping_math)
4767 || !(TARGET_INTER_UNIT_CONVERSIONS
4768 || optimize_function_for_size_p (cfun)))))
4769 && can_create_pseudo_p ()"
4770 "#"
4771 "&& 1"
4772 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4773 (clobber (match_dup 2))])]
4774 {
4775 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4776
4777 /* Avoid store forwarding (partial memory) stall penalty
4778 by passing DImode value through XMM registers. */
4779 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4780 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4781 && optimize_function_for_speed_p (cfun))
4782 {
4783 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4784 operands[1],
4785 operands[2]));
4786 DONE;
4787 }
4788 })
4789
4790 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4791 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4792 (float:MODEF
4793 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4794 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4795 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4796 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4797 "#"
4798 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4799 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4800 (set_attr "unit" "*,i387,*,*,*")
4801 (set_attr "athlon_decode" "*,*,double,direct,double")
4802 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4803 (set_attr "bdver1_decode" "*,*,double,direct,double")
4804 (set_attr "fp_int_src" "true")])
4805
4806 (define_insn "*floatsi<mode>2_vector_mixed"
4807 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4808 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4809 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4810 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4811 "@
4812 fild%Z1\t%1
4813 #"
4814 [(set_attr "type" "fmov,sseicvt")
4815 (set_attr "mode" "<MODE>,<ssevecmode>")
4816 (set_attr "unit" "i387,*")
4817 (set_attr "athlon_decode" "*,direct")
4818 (set_attr "amdfam10_decode" "*,double")
4819 (set_attr "bdver1_decode" "*,direct")
4820 (set_attr "fp_int_src" "true")])
4821
4822 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4823 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4824 (float:MODEF
4825 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4826 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4827 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4829 "#"
4830 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4831 (set_attr "mode" "<MODEF:MODE>")
4832 (set_attr "unit" "*,i387,*,*")
4833 (set_attr "athlon_decode" "*,*,double,direct")
4834 (set_attr "amdfam10_decode" "*,*,vector,double")
4835 (set_attr "bdver1_decode" "*,*,double,direct")
4836 (set_attr "fp_int_src" "true")])
4837
4838 (define_split
4839 [(set (match_operand:MODEF 0 "register_operand" "")
4840 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4841 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4842 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4843 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844 && TARGET_INTER_UNIT_CONVERSIONS
4845 && reload_completed
4846 && (SSE_REG_P (operands[0])
4847 || (GET_CODE (operands[0]) == SUBREG
4848 && SSE_REG_P (operands[0])))"
4849 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4850
4851 (define_split
4852 [(set (match_operand:MODEF 0 "register_operand" "")
4853 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4854 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4855 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4856 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4857 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4858 && reload_completed
4859 && (SSE_REG_P (operands[0])
4860 || (GET_CODE (operands[0]) == SUBREG
4861 && SSE_REG_P (operands[0])))"
4862 [(set (match_dup 2) (match_dup 1))
4863 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4864
4865 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4866 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4867 (float:MODEF
4868 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4869 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4870 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4871 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4872 "@
4873 fild%Z1\t%1
4874 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4876 [(set_attr "type" "fmov,sseicvt,sseicvt")
4877 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4878 (set_attr "mode" "<MODEF:MODE>")
4879 (set (attr "prefix_rex")
4880 (if_then_else
4881 (and (eq_attr "prefix" "maybe_vex")
4882 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4883 (const_string "1")
4884 (const_string "*")))
4885 (set_attr "unit" "i387,*,*")
4886 (set_attr "athlon_decode" "*,double,direct")
4887 (set_attr "amdfam10_decode" "*,vector,double")
4888 (set_attr "bdver1_decode" "*,double,direct")
4889 (set_attr "fp_int_src" "true")])
4890
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4893 (float:MODEF
4894 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4895 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4896 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4897 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4898 "@
4899 fild%Z1\t%1
4900 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4901 [(set_attr "type" "fmov,sseicvt")
4902 (set_attr "prefix" "orig,maybe_vex")
4903 (set_attr "mode" "<MODEF:MODE>")
4904 (set (attr "prefix_rex")
4905 (if_then_else
4906 (and (eq_attr "prefix" "maybe_vex")
4907 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4908 (const_string "1")
4909 (const_string "*")))
4910 (set_attr "athlon_decode" "*,direct")
4911 (set_attr "amdfam10_decode" "*,double")
4912 (set_attr "bdver1_decode" "*,direct")
4913 (set_attr "fp_int_src" "true")])
4914
4915 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4916 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4917 (float:MODEF
4918 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4919 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4920 "TARGET_SSE2 && TARGET_SSE_MATH
4921 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4922 "#"
4923 [(set_attr "type" "sseicvt")
4924 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4925 (set_attr "athlon_decode" "double,direct,double")
4926 (set_attr "amdfam10_decode" "vector,double,double")
4927 (set_attr "bdver1_decode" "double,direct,double")
4928 (set_attr "fp_int_src" "true")])
4929
4930 (define_insn "*floatsi<mode>2_vector_sse"
4931 [(set (match_operand:MODEF 0 "register_operand" "=x")
4932 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4933 "TARGET_SSE2 && TARGET_SSE_MATH
4934 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4935 "#"
4936 [(set_attr "type" "sseicvt")
4937 (set_attr "mode" "<MODE>")
4938 (set_attr "athlon_decode" "direct")
4939 (set_attr "amdfam10_decode" "double")
4940 (set_attr "bdver1_decode" "direct")
4941 (set_attr "fp_int_src" "true")])
4942
4943 (define_split
4944 [(set (match_operand:MODEF 0 "register_operand" "")
4945 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4946 (clobber (match_operand:SI 2 "memory_operand" ""))]
4947 "TARGET_SSE2 && TARGET_SSE_MATH
4948 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4949 && reload_completed
4950 && (SSE_REG_P (operands[0])
4951 || (GET_CODE (operands[0]) == SUBREG
4952 && SSE_REG_P (operands[0])))"
4953 [(const_int 0)]
4954 {
4955 rtx op1 = operands[1];
4956
4957 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4958 <MODE>mode, 0);
4959 if (GET_CODE (op1) == SUBREG)
4960 op1 = SUBREG_REG (op1);
4961
4962 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4963 {
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 emit_insn (gen_sse2_loadld (operands[4],
4966 CONST0_RTX (V4SImode), operands[1]));
4967 }
4968 /* We can ignore possible trapping value in the
4969 high part of SSE register for non-trapping math. */
4970 else if (SSE_REG_P (op1) && !flag_trapping_math)
4971 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4972 else
4973 {
4974 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4975 emit_move_insn (operands[2], operands[1]);
4976 emit_insn (gen_sse2_loadld (operands[4],
4977 CONST0_RTX (V4SImode), operands[2]));
4978 }
4979 emit_insn
4980 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
4981 DONE;
4982 })
4983
4984 (define_split
4985 [(set (match_operand:MODEF 0 "register_operand" "")
4986 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4987 (clobber (match_operand:SI 2 "memory_operand" ""))]
4988 "TARGET_SSE2 && TARGET_SSE_MATH
4989 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4990 && reload_completed
4991 && (SSE_REG_P (operands[0])
4992 || (GET_CODE (operands[0]) == SUBREG
4993 && SSE_REG_P (operands[0])))"
4994 [(const_int 0)]
4995 {
4996 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4997 <MODE>mode, 0);
4998 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4999
5000 emit_insn (gen_sse2_loadld (operands[4],
5001 CONST0_RTX (V4SImode), operands[1]));
5002 emit_insn
5003 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5004 DONE;
5005 })
5006
5007 (define_split
5008 [(set (match_operand:MODEF 0 "register_operand" "")
5009 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5010 "TARGET_SSE2 && TARGET_SSE_MATH
5011 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5012 && reload_completed
5013 && (SSE_REG_P (operands[0])
5014 || (GET_CODE (operands[0]) == SUBREG
5015 && SSE_REG_P (operands[0])))"
5016 [(const_int 0)]
5017 {
5018 rtx op1 = operands[1];
5019
5020 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5021 <MODE>mode, 0);
5022 if (GET_CODE (op1) == SUBREG)
5023 op1 = SUBREG_REG (op1);
5024
5025 if (GENERAL_REG_P (op1))
5026 {
5027 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5028 if (TARGET_INTER_UNIT_MOVES)
5029 emit_insn (gen_sse2_loadld (operands[4],
5030 CONST0_RTX (V4SImode), operands[1]));
5031 else
5032 {
5033 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5034 operands[1]);
5035 emit_insn (gen_sse2_loadld (operands[4],
5036 CONST0_RTX (V4SImode), operands[5]));
5037 ix86_free_from_memory (GET_MODE (operands[1]));
5038 }
5039 }
5040 /* We can ignore possible trapping value in the
5041 high part of SSE register for non-trapping math. */
5042 else if (SSE_REG_P (op1) && !flag_trapping_math)
5043 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5044 else
5045 gcc_unreachable ();
5046 emit_insn
5047 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5048 DONE;
5049 })
5050
5051 (define_split
5052 [(set (match_operand:MODEF 0 "register_operand" "")
5053 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5054 "TARGET_SSE2 && TARGET_SSE_MATH
5055 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5056 && reload_completed
5057 && (SSE_REG_P (operands[0])
5058 || (GET_CODE (operands[0]) == SUBREG
5059 && SSE_REG_P (operands[0])))"
5060 [(const_int 0)]
5061 {
5062 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5063 <MODE>mode, 0);
5064 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5065
5066 emit_insn (gen_sse2_loadld (operands[4],
5067 CONST0_RTX (V4SImode), operands[1]));
5068 emit_insn
5069 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5070 DONE;
5071 })
5072
5073 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5074 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5075 (float:MODEF
5076 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5077 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5078 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5080 "#"
5081 [(set_attr "type" "sseicvt")
5082 (set_attr "mode" "<MODEF:MODE>")
5083 (set_attr "athlon_decode" "double,direct")
5084 (set_attr "amdfam10_decode" "vector,double")
5085 (set_attr "bdver1_decode" "double,direct")
5086 (set_attr "fp_int_src" "true")])
5087
5088 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5089 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5090 (float:MODEF
5091 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5092 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5093 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5094 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5095 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5096 [(set_attr "type" "sseicvt")
5097 (set_attr "prefix" "maybe_vex")
5098 (set_attr "mode" "<MODEF:MODE>")
5099 (set (attr "prefix_rex")
5100 (if_then_else
5101 (and (eq_attr "prefix" "maybe_vex")
5102 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5103 (const_string "1")
5104 (const_string "*")))
5105 (set_attr "athlon_decode" "double,direct")
5106 (set_attr "amdfam10_decode" "vector,double")
5107 (set_attr "bdver1_decode" "double,direct")
5108 (set_attr "fp_int_src" "true")])
5109
5110 (define_split
5111 [(set (match_operand:MODEF 0 "register_operand" "")
5112 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5113 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5114 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5115 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5116 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5117 && reload_completed
5118 && (SSE_REG_P (operands[0])
5119 || (GET_CODE (operands[0]) == SUBREG
5120 && SSE_REG_P (operands[0])))"
5121 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5122
5123 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5124 [(set (match_operand:MODEF 0 "register_operand" "=x")
5125 (float:MODEF
5126 (match_operand:SWI48x 1 "memory_operand" "m")))]
5127 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5128 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5129 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5130 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5131 [(set_attr "type" "sseicvt")
5132 (set_attr "prefix" "maybe_vex")
5133 (set_attr "mode" "<MODEF:MODE>")
5134 (set (attr "prefix_rex")
5135 (if_then_else
5136 (and (eq_attr "prefix" "maybe_vex")
5137 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5138 (const_string "1")
5139 (const_string "*")))
5140 (set_attr "athlon_decode" "direct")
5141 (set_attr "amdfam10_decode" "double")
5142 (set_attr "bdver1_decode" "direct")
5143 (set_attr "fp_int_src" "true")])
5144
5145 (define_split
5146 [(set (match_operand:MODEF 0 "register_operand" "")
5147 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5148 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5149 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5151 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5152 && reload_completed
5153 && (SSE_REG_P (operands[0])
5154 || (GET_CODE (operands[0]) == SUBREG
5155 && SSE_REG_P (operands[0])))"
5156 [(set (match_dup 2) (match_dup 1))
5157 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5158
5159 (define_split
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5162 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5165 && reload_completed
5166 && (SSE_REG_P (operands[0])
5167 || (GET_CODE (operands[0]) == SUBREG
5168 && SSE_REG_P (operands[0])))"
5169 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5170
5171 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5172 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5173 (float:X87MODEF
5174 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5175 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5176 "TARGET_80387
5177 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5178 "@
5179 fild%Z1\t%1
5180 #"
5181 [(set_attr "type" "fmov,multi")
5182 (set_attr "mode" "<X87MODEF:MODE>")
5183 (set_attr "unit" "*,i387")
5184 (set_attr "fp_int_src" "true")])
5185
5186 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5187 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5188 (float:X87MODEF
5189 (match_operand:SWI48x 1 "memory_operand" "m")))]
5190 "TARGET_80387
5191 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5192 "fild%Z1\t%1"
5193 [(set_attr "type" "fmov")
5194 (set_attr "mode" "<X87MODEF:MODE>")
5195 (set_attr "fp_int_src" "true")])
5196
5197 (define_split
5198 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5199 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5200 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5201 "TARGET_80387
5202 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5203 && reload_completed"
5204 [(set (match_dup 2) (match_dup 1))
5205 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5206
5207 (define_split
5208 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5209 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5210 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5211 "TARGET_80387
5212 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5213 && reload_completed"
5214 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5215
5216 ;; Avoid store forwarding (partial memory) stall penalty
5217 ;; by passing DImode value through XMM registers. */
5218
5219 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5220 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5221 (float:X87MODEF
5222 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5223 (clobber (match_scratch:V4SI 3 "=X,x"))
5224 (clobber (match_scratch:V4SI 4 "=X,x"))
5225 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5226 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5227 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5228 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5229 "#"
5230 [(set_attr "type" "multi")
5231 (set_attr "mode" "<X87MODEF:MODE>")
5232 (set_attr "unit" "i387")
5233 (set_attr "fp_int_src" "true")])
5234
5235 (define_split
5236 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5237 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5238 (clobber (match_scratch:V4SI 3 ""))
5239 (clobber (match_scratch:V4SI 4 ""))
5240 (clobber (match_operand:DI 2 "memory_operand" ""))]
5241 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5242 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5243 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5244 && reload_completed"
5245 [(set (match_dup 2) (match_dup 3))
5246 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5247 {
5248 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5249 Assemble the 64-bit DImode value in an xmm register. */
5250 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5251 gen_rtx_SUBREG (SImode, operands[1], 0)));
5252 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5253 gen_rtx_SUBREG (SImode, operands[1], 4)));
5254 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5255 operands[4]));
5256
5257 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5258 })
5259
5260 (define_split
5261 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5263 (clobber (match_scratch:V4SI 3 ""))
5264 (clobber (match_scratch:V4SI 4 ""))
5265 (clobber (match_operand:DI 2 "memory_operand" ""))]
5266 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5267 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5268 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5269 && reload_completed"
5270 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5271
5272 ;; Avoid store forwarding (partial memory) stall penalty by extending
5273 ;; SImode value to DImode through XMM register instead of pushing two
5274 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5275 ;; targets benefit from this optimization. Also note that fild
5276 ;; loads from memory only.
5277
5278 (define_insn "*floatunssi<mode>2_1"
5279 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5280 (unsigned_float:X87MODEF
5281 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5282 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5283 (clobber (match_scratch:SI 3 "=X,x"))]
5284 "!TARGET_64BIT
5285 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286 && TARGET_SSE"
5287 "#"
5288 [(set_attr "type" "multi")
5289 (set_attr "mode" "<MODE>")])
5290
5291 (define_split
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (unsigned_float:X87MODEF
5294 (match_operand:SI 1 "register_operand" "")))
5295 (clobber (match_operand:DI 2 "memory_operand" ""))
5296 (clobber (match_scratch:SI 3 ""))]
5297 "!TARGET_64BIT
5298 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5299 && TARGET_SSE
5300 && reload_completed"
5301 [(set (match_dup 2) (match_dup 1))
5302 (set (match_dup 0)
5303 (float:X87MODEF (match_dup 2)))]
5304 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5305
5306 (define_split
5307 [(set (match_operand:X87MODEF 0 "register_operand" "")
5308 (unsigned_float:X87MODEF
5309 (match_operand:SI 1 "memory_operand" "")))
5310 (clobber (match_operand:DI 2 "memory_operand" ""))
5311 (clobber (match_scratch:SI 3 ""))]
5312 "!TARGET_64BIT
5313 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5314 && TARGET_SSE
5315 && reload_completed"
5316 [(set (match_dup 2) (match_dup 3))
5317 (set (match_dup 0)
5318 (float:X87MODEF (match_dup 2)))]
5319 {
5320 emit_move_insn (operands[3], operands[1]);
5321 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5322 })
5323
5324 (define_expand "floatunssi<mode>2"
5325 [(parallel
5326 [(set (match_operand:X87MODEF 0 "register_operand" "")
5327 (unsigned_float:X87MODEF
5328 (match_operand:SI 1 "nonimmediate_operand" "")))
5329 (clobber (match_dup 2))
5330 (clobber (match_scratch:SI 3 ""))])]
5331 "!TARGET_64BIT
5332 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5333 && TARGET_SSE)
5334 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5335 {
5336 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5337 {
5338 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5339 DONE;
5340 }
5341 else
5342 {
5343 enum ix86_stack_slot slot = (virtuals_instantiated
5344 ? SLOT_TEMP
5345 : SLOT_VIRTUAL);
5346 operands[2] = assign_386_stack_local (DImode, slot);
5347 }
5348 })
5349
5350 (define_expand "floatunsdisf2"
5351 [(use (match_operand:SF 0 "register_operand" ""))
5352 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5353 "TARGET_64BIT && TARGET_SSE_MATH"
5354 "x86_emit_floatuns (operands); DONE;")
5355
5356 (define_expand "floatunsdidf2"
5357 [(use (match_operand:DF 0 "register_operand" ""))
5358 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5359 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5360 && TARGET_SSE2 && TARGET_SSE_MATH"
5361 {
5362 if (TARGET_64BIT)
5363 x86_emit_floatuns (operands);
5364 else
5365 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5366 DONE;
5367 })
5368 \f
5369 ;; Add instructions
5370
5371 (define_expand "add<mode>3"
5372 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5373 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5374 (match_operand:SDWIM 2 "<general_operand>" "")))]
5375 ""
5376 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5377
5378 (define_insn_and_split "*add<dwi>3_doubleword"
5379 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5380 (plus:<DWI>
5381 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5382 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5383 (clobber (reg:CC FLAGS_REG))]
5384 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5385 "#"
5386 "reload_completed"
5387 [(parallel [(set (reg:CC FLAGS_REG)
5388 (unspec:CC [(match_dup 1) (match_dup 2)]
5389 UNSPEC_ADD_CARRY))
5390 (set (match_dup 0)
5391 (plus:DWIH (match_dup 1) (match_dup 2)))])
5392 (parallel [(set (match_dup 3)
5393 (plus:DWIH
5394 (match_dup 4)
5395 (plus:DWIH
5396 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5397 (match_dup 5))))
5398 (clobber (reg:CC FLAGS_REG))])]
5399 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5400
5401 (define_insn "*add<mode>3_cc"
5402 [(set (reg:CC FLAGS_REG)
5403 (unspec:CC
5404 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5405 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5406 UNSPEC_ADD_CARRY))
5407 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5408 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5409 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5410 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5411 [(set_attr "type" "alu")
5412 (set_attr "mode" "<MODE>")])
5413
5414 (define_insn "addqi3_cc"
5415 [(set (reg:CC FLAGS_REG)
5416 (unspec:CC
5417 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5418 (match_operand:QI 2 "general_operand" "qn,qm")]
5419 UNSPEC_ADD_CARRY))
5420 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5421 (plus:QI (match_dup 1) (match_dup 2)))]
5422 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5423 "add{b}\t{%2, %0|%0, %2}"
5424 [(set_attr "type" "alu")
5425 (set_attr "mode" "QI")])
5426
5427 (define_insn "*lea_1"
5428 [(set (match_operand:P 0 "register_operand" "=r")
5429 (match_operand:P 1 "no_seg_address_operand" "p"))]
5430 ""
5431 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5432 [(set_attr "type" "lea")
5433 (set_attr "mode" "<MODE>")])
5434
5435 (define_insn "*lea_2"
5436 [(set (match_operand:SI 0 "register_operand" "=r")
5437 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5438 "TARGET_64BIT"
5439 "lea{l}\t{%a1, %0|%0, %a1}"
5440 [(set_attr "type" "lea")
5441 (set_attr "mode" "SI")])
5442
5443 (define_insn "*lea_2_zext"
5444 [(set (match_operand:DI 0 "register_operand" "=r")
5445 (zero_extend:DI
5446 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5447 "TARGET_64BIT"
5448 "lea{l}\t{%a1, %k0|%k0, %a1}"
5449 [(set_attr "type" "lea")
5450 (set_attr "mode" "SI")])
5451
5452 (define_insn "*add<mode>_1"
5453 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5454 (plus:SWI48
5455 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5456 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5457 (clobber (reg:CC FLAGS_REG))]
5458 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5459 {
5460 switch (get_attr_type (insn))
5461 {
5462 case TYPE_LEA:
5463 return "#";
5464
5465 case TYPE_INCDEC:
5466 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5467 if (operands[2] == const1_rtx)
5468 return "inc{<imodesuffix>}\t%0";
5469 else
5470 {
5471 gcc_assert (operands[2] == constm1_rtx);
5472 return "dec{<imodesuffix>}\t%0";
5473 }
5474
5475 default:
5476 /* For most processors, ADD is faster than LEA. This alternative
5477 was added to use ADD as much as possible. */
5478 if (which_alternative == 2)
5479 {
5480 rtx tmp;
5481 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5482 }
5483
5484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5485 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5486 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5487
5488 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5489 }
5490 }
5491 [(set (attr "type")
5492 (cond [(eq_attr "alternative" "3")
5493 (const_string "lea")
5494 (match_operand:SWI48 2 "incdec_operand" "")
5495 (const_string "incdec")
5496 ]
5497 (const_string "alu")))
5498 (set (attr "length_immediate")
5499 (if_then_else
5500 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5501 (const_string "1")
5502 (const_string "*")))
5503 (set_attr "mode" "<MODE>")])
5504
5505 ;; It may seem that nonimmediate operand is proper one for operand 1.
5506 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5507 ;; we take care in ix86_binary_operator_ok to not allow two memory
5508 ;; operands so proper swapping will be done in reload. This allow
5509 ;; patterns constructed from addsi_1 to match.
5510
5511 (define_insn "addsi_1_zext"
5512 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5513 (zero_extend:DI
5514 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5515 (match_operand:SI 2 "general_operand" "g,0,li"))))
5516 (clobber (reg:CC FLAGS_REG))]
5517 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5518 {
5519 switch (get_attr_type (insn))
5520 {
5521 case TYPE_LEA:
5522 return "#";
5523
5524 case TYPE_INCDEC:
5525 if (operands[2] == const1_rtx)
5526 return "inc{l}\t%k0";
5527 else
5528 {
5529 gcc_assert (operands[2] == constm1_rtx);
5530 return "dec{l}\t%k0";
5531 }
5532
5533 default:
5534 /* For most processors, ADD is faster than LEA. This alternative
5535 was added to use ADD as much as possible. */
5536 if (which_alternative == 1)
5537 {
5538 rtx tmp;
5539 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5540 }
5541
5542 if (x86_maybe_negate_const_int (&operands[2], SImode))
5543 return "sub{l}\t{%2, %k0|%k0, %2}";
5544
5545 return "add{l}\t{%2, %k0|%k0, %2}";
5546 }
5547 }
5548 [(set (attr "type")
5549 (cond [(eq_attr "alternative" "2")
5550 (const_string "lea")
5551 (match_operand:SI 2 "incdec_operand" "")
5552 (const_string "incdec")
5553 ]
5554 (const_string "alu")))
5555 (set (attr "length_immediate")
5556 (if_then_else
5557 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5558 (const_string "1")
5559 (const_string "*")))
5560 (set_attr "mode" "SI")])
5561
5562 (define_insn "*addhi_1"
5563 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5564 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5565 (match_operand:HI 2 "general_operand" "rn,rm")))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "TARGET_PARTIAL_REG_STALL
5568 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5569 {
5570 switch (get_attr_type (insn))
5571 {
5572 case TYPE_INCDEC:
5573 if (operands[2] == const1_rtx)
5574 return "inc{w}\t%0";
5575 else
5576 {
5577 gcc_assert (operands[2] == constm1_rtx);
5578 return "dec{w}\t%0";
5579 }
5580
5581 default:
5582 if (x86_maybe_negate_const_int (&operands[2], HImode))
5583 return "sub{w}\t{%2, %0|%0, %2}";
5584
5585 return "add{w}\t{%2, %0|%0, %2}";
5586 }
5587 }
5588 [(set (attr "type")
5589 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5590 (const_string "incdec")
5591 (const_string "alu")))
5592 (set (attr "length_immediate")
5593 (if_then_else
5594 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5595 (const_string "1")
5596 (const_string "*")))
5597 (set_attr "mode" "HI")])
5598
5599 (define_insn "*addhi_1_lea"
5600 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5601 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5602 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "!TARGET_PARTIAL_REG_STALL
5605 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5606 {
5607 switch (get_attr_type (insn))
5608 {
5609 case TYPE_LEA:
5610 return "#";
5611
5612 case TYPE_INCDEC:
5613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614 if (operands[2] == const1_rtx)
5615 return "inc{w}\t%0";
5616 else
5617 {
5618 gcc_assert (operands[2] == constm1_rtx);
5619 return "dec{w}\t%0";
5620 }
5621
5622 default:
5623 /* For most processors, ADD is faster than LEA. This alternative
5624 was added to use ADD as much as possible. */
5625 if (which_alternative == 2)
5626 {
5627 rtx tmp;
5628 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5629 }
5630
5631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632 if (x86_maybe_negate_const_int (&operands[2], HImode))
5633 return "sub{w}\t{%2, %0|%0, %2}";
5634
5635 return "add{w}\t{%2, %0|%0, %2}";
5636 }
5637 }
5638 [(set (attr "type")
5639 (cond [(eq_attr "alternative" "3")
5640 (const_string "lea")
5641 (match_operand:HI 2 "incdec_operand" "")
5642 (const_string "incdec")
5643 ]
5644 (const_string "alu")))
5645 (set (attr "length_immediate")
5646 (if_then_else
5647 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5648 (const_string "1")
5649 (const_string "*")))
5650 (set_attr "mode" "HI,HI,HI,SI")])
5651
5652 ;; %%% Potential partial reg stall on alternative 2. What to do?
5653 (define_insn "*addqi_1"
5654 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5655 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5656 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5657 (clobber (reg:CC FLAGS_REG))]
5658 "TARGET_PARTIAL_REG_STALL
5659 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5660 {
5661 int widen = (which_alternative == 2);
5662 switch (get_attr_type (insn))
5663 {
5664 case TYPE_INCDEC:
5665 if (operands[2] == const1_rtx)
5666 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5667 else
5668 {
5669 gcc_assert (operands[2] == constm1_rtx);
5670 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5671 }
5672
5673 default:
5674 if (x86_maybe_negate_const_int (&operands[2], QImode))
5675 {
5676 if (widen)
5677 return "sub{l}\t{%2, %k0|%k0, %2}";
5678 else
5679 return "sub{b}\t{%2, %0|%0, %2}";
5680 }
5681 if (widen)
5682 return "add{l}\t{%k2, %k0|%k0, %k2}";
5683 else
5684 return "add{b}\t{%2, %0|%0, %2}";
5685 }
5686 }
5687 [(set (attr "type")
5688 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5689 (const_string "incdec")
5690 (const_string "alu")))
5691 (set (attr "length_immediate")
5692 (if_then_else
5693 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5694 (const_string "1")
5695 (const_string "*")))
5696 (set_attr "mode" "QI,QI,SI")])
5697
5698 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5699 (define_insn "*addqi_1_lea"
5700 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5701 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5702 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5703 (clobber (reg:CC FLAGS_REG))]
5704 "!TARGET_PARTIAL_REG_STALL
5705 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5706 {
5707 int widen = (which_alternative == 3 || which_alternative == 4);
5708
5709 switch (get_attr_type (insn))
5710 {
5711 case TYPE_LEA:
5712 return "#";
5713
5714 case TYPE_INCDEC:
5715 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716 if (operands[2] == const1_rtx)
5717 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5718 else
5719 {
5720 gcc_assert (operands[2] == constm1_rtx);
5721 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5722 }
5723
5724 default:
5725 /* For most processors, ADD is faster than LEA. These alternatives
5726 were added to use ADD as much as possible. */
5727 if (which_alternative == 2 || which_alternative == 4)
5728 {
5729 rtx tmp;
5730 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5731 }
5732
5733 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734 if (x86_maybe_negate_const_int (&operands[2], QImode))
5735 {
5736 if (widen)
5737 return "sub{l}\t{%2, %k0|%k0, %2}";
5738 else
5739 return "sub{b}\t{%2, %0|%0, %2}";
5740 }
5741 if (widen)
5742 return "add{l}\t{%k2, %k0|%k0, %k2}";
5743 else
5744 return "add{b}\t{%2, %0|%0, %2}";
5745 }
5746 }
5747 [(set (attr "type")
5748 (cond [(eq_attr "alternative" "5")
5749 (const_string "lea")
5750 (match_operand:QI 2 "incdec_operand" "")
5751 (const_string "incdec")
5752 ]
5753 (const_string "alu")))
5754 (set (attr "length_immediate")
5755 (if_then_else
5756 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5757 (const_string "1")
5758 (const_string "*")))
5759 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5760
5761 (define_insn "*addqi_1_slp"
5762 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5763 (plus:QI (match_dup 0)
5764 (match_operand:QI 1 "general_operand" "qn,qnm")))
5765 (clobber (reg:CC FLAGS_REG))]
5766 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5767 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5768 {
5769 switch (get_attr_type (insn))
5770 {
5771 case TYPE_INCDEC:
5772 if (operands[1] == const1_rtx)
5773 return "inc{b}\t%0";
5774 else
5775 {
5776 gcc_assert (operands[1] == constm1_rtx);
5777 return "dec{b}\t%0";
5778 }
5779
5780 default:
5781 if (x86_maybe_negate_const_int (&operands[1], QImode))
5782 return "sub{b}\t{%1, %0|%0, %1}";
5783
5784 return "add{b}\t{%1, %0|%0, %1}";
5785 }
5786 }
5787 [(set (attr "type")
5788 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5789 (const_string "incdec")
5790 (const_string "alu1")))
5791 (set (attr "memory")
5792 (if_then_else (match_operand 1 "memory_operand" "")
5793 (const_string "load")
5794 (const_string "none")))
5795 (set_attr "mode" "QI")])
5796
5797 ;; Convert lea to the lea pattern to avoid flags dependency.
5798 (define_split
5799 [(set (match_operand 0 "register_operand" "")
5800 (plus (match_operand 1 "register_operand" "")
5801 (match_operand 2 "nonmemory_operand" "")))
5802 (clobber (reg:CC FLAGS_REG))]
5803 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5804 [(const_int 0)]
5805 {
5806 rtx pat;
5807 enum machine_mode mode = GET_MODE (operands[0]);
5808
5809 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5810 may confuse gen_lowpart. */
5811 if (mode != Pmode)
5812 {
5813 operands[1] = gen_lowpart (Pmode, operands[1]);
5814 operands[2] = gen_lowpart (Pmode, operands[2]);
5815 }
5816
5817 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5818
5819 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5820 operands[0] = gen_lowpart (SImode, operands[0]);
5821
5822 if (TARGET_64BIT && mode != Pmode)
5823 pat = gen_rtx_SUBREG (SImode, pat, 0);
5824
5825 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5826 DONE;
5827 })
5828
5829 ;; Convert lea to the lea pattern to avoid flags dependency.
5830 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5831 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5832 (define_split
5833 [(set (match_operand:DI 0 "register_operand" "")
5834 (plus:DI (match_operand:DI 1 "register_operand" "")
5835 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5836 (clobber (reg:CC FLAGS_REG))]
5837 "TARGET_64BIT && reload_completed
5838 && true_regnum (operands[0]) != true_regnum (operands[1])"
5839 [(set (match_dup 0)
5840 (plus:DI (match_dup 1) (match_dup 2)))])
5841
5842 ;; Convert lea to the lea pattern to avoid flags dependency.
5843 (define_split
5844 [(set (match_operand:DI 0 "register_operand" "")
5845 (zero_extend:DI
5846 (plus:SI (match_operand:SI 1 "register_operand" "")
5847 (match_operand:SI 2 "nonmemory_operand" ""))))
5848 (clobber (reg:CC FLAGS_REG))]
5849 "TARGET_64BIT && reload_completed
5850 && ix86_lea_for_add_ok (insn, operands)"
5851 [(set (match_dup 0)
5852 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5853 {
5854 operands[1] = gen_lowpart (DImode, operands[1]);
5855 operands[2] = gen_lowpart (DImode, operands[2]);
5856 })
5857
5858 (define_insn "*add<mode>_2"
5859 [(set (reg FLAGS_REG)
5860 (compare
5861 (plus:SWI
5862 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5863 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5864 (const_int 0)))
5865 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5866 (plus:SWI (match_dup 1) (match_dup 2)))]
5867 "ix86_match_ccmode (insn, CCGOCmode)
5868 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5869 {
5870 switch (get_attr_type (insn))
5871 {
5872 case TYPE_INCDEC:
5873 if (operands[2] == const1_rtx)
5874 return "inc{<imodesuffix>}\t%0";
5875 else
5876 {
5877 gcc_assert (operands[2] == constm1_rtx);
5878 return "dec{<imodesuffix>}\t%0";
5879 }
5880
5881 default:
5882 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5883 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5884
5885 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5886 }
5887 }
5888 [(set (attr "type")
5889 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5890 (const_string "incdec")
5891 (const_string "alu")))
5892 (set (attr "length_immediate")
5893 (if_then_else
5894 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5895 (const_string "1")
5896 (const_string "*")))
5897 (set_attr "mode" "<MODE>")])
5898
5899 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5900 (define_insn "*addsi_2_zext"
5901 [(set (reg FLAGS_REG)
5902 (compare
5903 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5904 (match_operand:SI 2 "general_operand" "g"))
5905 (const_int 0)))
5906 (set (match_operand:DI 0 "register_operand" "=r")
5907 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5908 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5909 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5910 {
5911 switch (get_attr_type (insn))
5912 {
5913 case TYPE_INCDEC:
5914 if (operands[2] == const1_rtx)
5915 return "inc{l}\t%k0";
5916 else
5917 {
5918 gcc_assert (operands[2] == constm1_rtx);
5919 return "dec{l}\t%k0";
5920 }
5921
5922 default:
5923 if (x86_maybe_negate_const_int (&operands[2], SImode))
5924 return "sub{l}\t{%2, %k0|%k0, %2}";
5925
5926 return "add{l}\t{%2, %k0|%k0, %2}";
5927 }
5928 }
5929 [(set (attr "type")
5930 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5931 (const_string "incdec")
5932 (const_string "alu")))
5933 (set (attr "length_immediate")
5934 (if_then_else
5935 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5936 (const_string "1")
5937 (const_string "*")))
5938 (set_attr "mode" "SI")])
5939
5940 (define_insn "*add<mode>_3"
5941 [(set (reg FLAGS_REG)
5942 (compare
5943 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5944 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5945 (clobber (match_scratch:SWI 0 "=<r>"))]
5946 "ix86_match_ccmode (insn, CCZmode)
5947 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5948 {
5949 switch (get_attr_type (insn))
5950 {
5951 case TYPE_INCDEC:
5952 if (operands[2] == const1_rtx)
5953 return "inc{<imodesuffix>}\t%0";
5954 else
5955 {
5956 gcc_assert (operands[2] == constm1_rtx);
5957 return "dec{<imodesuffix>}\t%0";
5958 }
5959
5960 default:
5961 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5962 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5963
5964 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5965 }
5966 }
5967 [(set (attr "type")
5968 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5969 (const_string "incdec")
5970 (const_string "alu")))
5971 (set (attr "length_immediate")
5972 (if_then_else
5973 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5974 (const_string "1")
5975 (const_string "*")))
5976 (set_attr "mode" "<MODE>")])
5977
5978 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5979 (define_insn "*addsi_3_zext"
5980 [(set (reg FLAGS_REG)
5981 (compare
5982 (neg:SI (match_operand:SI 2 "general_operand" "g"))
5983 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5984 (set (match_operand:DI 0 "register_operand" "=r")
5985 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5986 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5987 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5988 {
5989 switch (get_attr_type (insn))
5990 {
5991 case TYPE_INCDEC:
5992 if (operands[2] == const1_rtx)
5993 return "inc{l}\t%k0";
5994 else
5995 {
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{l}\t%k0";
5998 }
5999
6000 default:
6001 if (x86_maybe_negate_const_int (&operands[2], SImode))
6002 return "sub{l}\t{%2, %k0|%k0, %2}";
6003
6004 return "add{l}\t{%2, %k0|%k0, %2}";
6005 }
6006 }
6007 [(set (attr "type")
6008 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6009 (const_string "incdec")
6010 (const_string "alu")))
6011 (set (attr "length_immediate")
6012 (if_then_else
6013 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6014 (const_string "1")
6015 (const_string "*")))
6016 (set_attr "mode" "SI")])
6017
6018 ; For comparisons against 1, -1 and 128, we may generate better code
6019 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6020 ; is matched then. We can't accept general immediate, because for
6021 ; case of overflows, the result is messed up.
6022 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6023 ; only for comparisons not depending on it.
6024
6025 (define_insn "*adddi_4"
6026 [(set (reg FLAGS_REG)
6027 (compare
6028 (match_operand:DI 1 "nonimmediate_operand" "0")
6029 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6030 (clobber (match_scratch:DI 0 "=rm"))]
6031 "TARGET_64BIT
6032 && ix86_match_ccmode (insn, CCGCmode)"
6033 {
6034 switch (get_attr_type (insn))
6035 {
6036 case TYPE_INCDEC:
6037 if (operands[2] == constm1_rtx)
6038 return "inc{q}\t%0";
6039 else
6040 {
6041 gcc_assert (operands[2] == const1_rtx);
6042 return "dec{q}\t%0";
6043 }
6044
6045 default:
6046 if (x86_maybe_negate_const_int (&operands[2], DImode))
6047 return "add{q}\t{%2, %0|%0, %2}";
6048
6049 return "sub{q}\t{%2, %0|%0, %2}";
6050 }
6051 }
6052 [(set (attr "type")
6053 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6054 (const_string "incdec")
6055 (const_string "alu")))
6056 (set (attr "length_immediate")
6057 (if_then_else
6058 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6059 (const_string "1")
6060 (const_string "*")))
6061 (set_attr "mode" "DI")])
6062
6063 ; For comparisons against 1, -1 and 128, we may generate better code
6064 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6065 ; is matched then. We can't accept general immediate, because for
6066 ; case of overflows, the result is messed up.
6067 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6068 ; only for comparisons not depending on it.
6069
6070 (define_insn "*add<mode>_4"
6071 [(set (reg FLAGS_REG)
6072 (compare
6073 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6074 (match_operand:SWI124 2 "const_int_operand" "n")))
6075 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6076 "ix86_match_ccmode (insn, CCGCmode)"
6077 {
6078 switch (get_attr_type (insn))
6079 {
6080 case TYPE_INCDEC:
6081 if (operands[2] == constm1_rtx)
6082 return "inc{<imodesuffix>}\t%0";
6083 else
6084 {
6085 gcc_assert (operands[2] == const1_rtx);
6086 return "dec{<imodesuffix>}\t%0";
6087 }
6088
6089 default:
6090 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6091 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6092
6093 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6094 }
6095 }
6096 [(set (attr "type")
6097 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6098 (const_string "incdec")
6099 (const_string "alu")))
6100 (set (attr "length_immediate")
6101 (if_then_else
6102 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6103 (const_string "1")
6104 (const_string "*")))
6105 (set_attr "mode" "<MODE>")])
6106
6107 (define_insn "*add<mode>_5"
6108 [(set (reg FLAGS_REG)
6109 (compare
6110 (plus:SWI
6111 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6112 (match_operand:SWI 2 "<general_operand>" "<g>"))
6113 (const_int 0)))
6114 (clobber (match_scratch:SWI 0 "=<r>"))]
6115 "ix86_match_ccmode (insn, CCGOCmode)
6116 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6117 {
6118 switch (get_attr_type (insn))
6119 {
6120 case TYPE_INCDEC:
6121 if (operands[2] == const1_rtx)
6122 return "inc{<imodesuffix>}\t%0";
6123 else
6124 {
6125 gcc_assert (operands[2] == constm1_rtx);
6126 return "dec{<imodesuffix>}\t%0";
6127 }
6128
6129 default:
6130 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6131 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6132
6133 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6134 }
6135 }
6136 [(set (attr "type")
6137 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6138 (const_string "incdec")
6139 (const_string "alu")))
6140 (set (attr "length_immediate")
6141 (if_then_else
6142 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6143 (const_string "1")
6144 (const_string "*")))
6145 (set_attr "mode" "<MODE>")])
6146
6147 (define_insn "*addqi_ext_1_rex64"
6148 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6149 (const_int 8)
6150 (const_int 8))
6151 (plus:SI
6152 (zero_extract:SI
6153 (match_operand 1 "ext_register_operand" "0")
6154 (const_int 8)
6155 (const_int 8))
6156 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6157 (clobber (reg:CC FLAGS_REG))]
6158 "TARGET_64BIT"
6159 {
6160 switch (get_attr_type (insn))
6161 {
6162 case TYPE_INCDEC:
6163 if (operands[2] == const1_rtx)
6164 return "inc{b}\t%h0";
6165 else
6166 {
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{b}\t%h0";
6169 }
6170
6171 default:
6172 return "add{b}\t{%2, %h0|%h0, %2}";
6173 }
6174 }
6175 [(set (attr "type")
6176 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set_attr "modrm" "1")
6180 (set_attr "mode" "QI")])
6181
6182 (define_insn "addqi_ext_1"
6183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6184 (const_int 8)
6185 (const_int 8))
6186 (plus:SI
6187 (zero_extract:SI
6188 (match_operand 1 "ext_register_operand" "0")
6189 (const_int 8)
6190 (const_int 8))
6191 (match_operand:QI 2 "general_operand" "Qmn")))
6192 (clobber (reg:CC FLAGS_REG))]
6193 "!TARGET_64BIT"
6194 {
6195 switch (get_attr_type (insn))
6196 {
6197 case TYPE_INCDEC:
6198 if (operands[2] == const1_rtx)
6199 return "inc{b}\t%h0";
6200 else
6201 {
6202 gcc_assert (operands[2] == constm1_rtx);
6203 return "dec{b}\t%h0";
6204 }
6205
6206 default:
6207 return "add{b}\t{%2, %h0|%h0, %2}";
6208 }
6209 }
6210 [(set (attr "type")
6211 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212 (const_string "incdec")
6213 (const_string "alu")))
6214 (set_attr "modrm" "1")
6215 (set_attr "mode" "QI")])
6216
6217 (define_insn "*addqi_ext_2"
6218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6219 (const_int 8)
6220 (const_int 8))
6221 (plus:SI
6222 (zero_extract:SI
6223 (match_operand 1 "ext_register_operand" "%0")
6224 (const_int 8)
6225 (const_int 8))
6226 (zero_extract:SI
6227 (match_operand 2 "ext_register_operand" "Q")
6228 (const_int 8)
6229 (const_int 8))))
6230 (clobber (reg:CC FLAGS_REG))]
6231 ""
6232 "add{b}\t{%h2, %h0|%h0, %h2}"
6233 [(set_attr "type" "alu")
6234 (set_attr "mode" "QI")])
6235
6236 ;; The lea patterns for non-Pmodes needs to be matched by
6237 ;; several insns converted to real lea by splitters.
6238
6239 (define_insn_and_split "*lea_general_1"
6240 [(set (match_operand 0 "register_operand" "=r")
6241 (plus (plus (match_operand 1 "index_register_operand" "l")
6242 (match_operand 2 "register_operand" "r"))
6243 (match_operand 3 "immediate_operand" "i")))]
6244 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6245 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6246 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6247 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6248 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6249 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6250 || GET_MODE (operands[3]) == VOIDmode)"
6251 "#"
6252 "&& reload_completed"
6253 [(const_int 0)]
6254 {
6255 rtx pat;
6256 operands[0] = gen_lowpart (SImode, operands[0]);
6257 operands[1] = gen_lowpart (Pmode, operands[1]);
6258 operands[2] = gen_lowpart (Pmode, operands[2]);
6259 operands[3] = gen_lowpart (Pmode, operands[3]);
6260 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6261 operands[3]);
6262 if (Pmode != SImode)
6263 pat = gen_rtx_SUBREG (SImode, pat, 0);
6264 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6265 DONE;
6266 }
6267 [(set_attr "type" "lea")
6268 (set_attr "mode" "SI")])
6269
6270 (define_insn_and_split "*lea_general_1_zext"
6271 [(set (match_operand:DI 0 "register_operand" "=r")
6272 (zero_extend:DI
6273 (plus:SI (plus:SI
6274 (match_operand:SI 1 "index_register_operand" "l")
6275 (match_operand:SI 2 "register_operand" "r"))
6276 (match_operand:SI 3 "immediate_operand" "i"))))]
6277 "TARGET_64BIT"
6278 "#"
6279 "&& reload_completed"
6280 [(set (match_dup 0)
6281 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6282 (match_dup 2))
6283 (match_dup 3)) 0)))]
6284 {
6285 operands[1] = gen_lowpart (Pmode, operands[1]);
6286 operands[2] = gen_lowpart (Pmode, operands[2]);
6287 operands[3] = gen_lowpart (Pmode, operands[3]);
6288 }
6289 [(set_attr "type" "lea")
6290 (set_attr "mode" "SI")])
6291
6292 (define_insn_and_split "*lea_general_2"
6293 [(set (match_operand 0 "register_operand" "=r")
6294 (plus (mult (match_operand 1 "index_register_operand" "l")
6295 (match_operand 2 "const248_operand" "i"))
6296 (match_operand 3 "nonmemory_operand" "ri")))]
6297 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6298 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6299 && (!TARGET_PARTIAL_REG_STALL
6300 || GET_MODE (operands[0]) == SImode
6301 || optimize_function_for_size_p (cfun))
6302 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6303 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6304 || GET_MODE (operands[3]) == VOIDmode)"
6305 "#"
6306 "&& reload_completed"
6307 [(const_int 0)]
6308 {
6309 rtx pat;
6310 operands[0] = gen_lowpart (SImode, operands[0]);
6311 operands[1] = gen_lowpart (Pmode, operands[1]);
6312 operands[3] = gen_lowpart (Pmode, operands[3]);
6313 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6314 operands[3]);
6315 if (Pmode != SImode)
6316 pat = gen_rtx_SUBREG (SImode, pat, 0);
6317 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6318 DONE;
6319 }
6320 [(set_attr "type" "lea")
6321 (set_attr "mode" "SI")])
6322
6323 (define_insn_and_split "*lea_general_2_zext"
6324 [(set (match_operand:DI 0 "register_operand" "=r")
6325 (zero_extend:DI
6326 (plus:SI (mult:SI
6327 (match_operand:SI 1 "index_register_operand" "l")
6328 (match_operand:SI 2 "const248_operand" "n"))
6329 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6330 "TARGET_64BIT"
6331 "#"
6332 "&& reload_completed"
6333 [(set (match_dup 0)
6334 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6335 (match_dup 2))
6336 (match_dup 3)) 0)))]
6337 {
6338 operands[1] = gen_lowpart (Pmode, operands[1]);
6339 operands[3] = gen_lowpart (Pmode, operands[3]);
6340 }
6341 [(set_attr "type" "lea")
6342 (set_attr "mode" "SI")])
6343
6344 (define_insn_and_split "*lea_general_3"
6345 [(set (match_operand 0 "register_operand" "=r")
6346 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6347 (match_operand 2 "const248_operand" "i"))
6348 (match_operand 3 "register_operand" "r"))
6349 (match_operand 4 "immediate_operand" "i")))]
6350 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6351 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6352 && (!TARGET_PARTIAL_REG_STALL
6353 || GET_MODE (operands[0]) == SImode
6354 || optimize_function_for_size_p (cfun))
6355 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6356 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6357 "#"
6358 "&& reload_completed"
6359 [(const_int 0)]
6360 {
6361 rtx pat;
6362 operands[0] = gen_lowpart (SImode, operands[0]);
6363 operands[1] = gen_lowpart (Pmode, operands[1]);
6364 operands[3] = gen_lowpart (Pmode, operands[3]);
6365 operands[4] = gen_lowpart (Pmode, operands[4]);
6366 pat = gen_rtx_PLUS (Pmode,
6367 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6368 operands[2]),
6369 operands[3]),
6370 operands[4]);
6371 if (Pmode != SImode)
6372 pat = gen_rtx_SUBREG (SImode, pat, 0);
6373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6374 DONE;
6375 }
6376 [(set_attr "type" "lea")
6377 (set_attr "mode" "SI")])
6378
6379 (define_insn_and_split "*lea_general_3_zext"
6380 [(set (match_operand:DI 0 "register_operand" "=r")
6381 (zero_extend:DI
6382 (plus:SI (plus:SI
6383 (mult:SI
6384 (match_operand:SI 1 "index_register_operand" "l")
6385 (match_operand:SI 2 "const248_operand" "n"))
6386 (match_operand:SI 3 "register_operand" "r"))
6387 (match_operand:SI 4 "immediate_operand" "i"))))]
6388 "TARGET_64BIT"
6389 "#"
6390 "&& reload_completed"
6391 [(set (match_dup 0)
6392 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6393 (match_dup 2))
6394 (match_dup 3))
6395 (match_dup 4)) 0)))]
6396 {
6397 operands[1] = gen_lowpart (Pmode, operands[1]);
6398 operands[3] = gen_lowpart (Pmode, operands[3]);
6399 operands[4] = gen_lowpart (Pmode, operands[4]);
6400 }
6401 [(set_attr "type" "lea")
6402 (set_attr "mode" "SI")])
6403
6404 (define_insn_and_split "*lea_general_4"
6405 [(set (match_operand:SWI 0 "register_operand" "=r")
6406 (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" "l")
6407 (match_operand:SWI 2 "const_int_operand" "n"))
6408 (match_operand 3 "const_int_operand" "n")))]
6409 "(<MODE>mode == DImode
6410 || <MODE>mode == SImode
6411 || !TARGET_PARTIAL_REG_STALL
6412 || optimize_function_for_size_p (cfun))
6413 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6414 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6415 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6416 "#"
6417 "&& reload_completed"
6418 [(const_int 0)]
6419 {
6420 rtx pat;
6421 if (<MODE>mode != DImode)
6422 operands[0] = gen_lowpart (SImode, operands[0]);
6423 operands[1] = gen_lowpart (Pmode, operands[1]);
6424 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6425 pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]),
6426 INTVAL (operands[3]));
6427 if (Pmode != SImode && <MODE>mode != DImode)
6428 pat = gen_rtx_SUBREG (SImode, pat, 0);
6429 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6430 DONE;
6431 }
6432 [(set_attr "type" "lea")
6433 (set (attr "mode")
6434 (if_then_else (eq (symbol_ref "<MODE>mode == DImode") (const_int 0))
6435 (const_string "SI")
6436 (const_string "DI")))])
6437 \f
6438 ;; Subtract instructions
6439
6440 (define_expand "sub<mode>3"
6441 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6442 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6443 (match_operand:SDWIM 2 "<general_operand>" "")))]
6444 ""
6445 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6446
6447 (define_insn_and_split "*sub<dwi>3_doubleword"
6448 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6449 (minus:<DWI>
6450 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6451 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6452 (clobber (reg:CC FLAGS_REG))]
6453 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6454 "#"
6455 "reload_completed"
6456 [(parallel [(set (reg:CC FLAGS_REG)
6457 (compare:CC (match_dup 1) (match_dup 2)))
6458 (set (match_dup 0)
6459 (minus:DWIH (match_dup 1) (match_dup 2)))])
6460 (parallel [(set (match_dup 3)
6461 (minus:DWIH
6462 (match_dup 4)
6463 (plus:DWIH
6464 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6465 (match_dup 5))))
6466 (clobber (reg:CC FLAGS_REG))])]
6467 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6468
6469 (define_insn "*sub<mode>_1"
6470 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6471 (minus:SWI
6472 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474 (clobber (reg:CC FLAGS_REG))]
6475 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6476 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6477 [(set_attr "type" "alu")
6478 (set_attr "mode" "<MODE>")])
6479
6480 (define_insn "*subsi_1_zext"
6481 [(set (match_operand:DI 0 "register_operand" "=r")
6482 (zero_extend:DI
6483 (minus:SI (match_operand:SI 1 "register_operand" "0")
6484 (match_operand:SI 2 "general_operand" "g"))))
6485 (clobber (reg:CC FLAGS_REG))]
6486 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6487 "sub{l}\t{%2, %k0|%k0, %2}"
6488 [(set_attr "type" "alu")
6489 (set_attr "mode" "SI")])
6490
6491 (define_insn "*subqi_1_slp"
6492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6493 (minus:QI (match_dup 0)
6494 (match_operand:QI 1 "general_operand" "qn,qm")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6498 "sub{b}\t{%1, %0|%0, %1}"
6499 [(set_attr "type" "alu1")
6500 (set_attr "mode" "QI")])
6501
6502 (define_insn "*sub<mode>_2"
6503 [(set (reg FLAGS_REG)
6504 (compare
6505 (minus:SWI
6506 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6507 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6508 (const_int 0)))
6509 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6510 (minus:SWI (match_dup 1) (match_dup 2)))]
6511 "ix86_match_ccmode (insn, CCGOCmode)
6512 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6513 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6516
6517 (define_insn "*subsi_2_zext"
6518 [(set (reg FLAGS_REG)
6519 (compare
6520 (minus:SI (match_operand:SI 1 "register_operand" "0")
6521 (match_operand:SI 2 "general_operand" "g"))
6522 (const_int 0)))
6523 (set (match_operand:DI 0 "register_operand" "=r")
6524 (zero_extend:DI
6525 (minus:SI (match_dup 1)
6526 (match_dup 2))))]
6527 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6528 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6529 "sub{l}\t{%2, %k0|%k0, %2}"
6530 [(set_attr "type" "alu")
6531 (set_attr "mode" "SI")])
6532
6533 (define_insn "*sub<mode>_3"
6534 [(set (reg FLAGS_REG)
6535 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6537 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6538 (minus:SWI (match_dup 1) (match_dup 2)))]
6539 "ix86_match_ccmode (insn, CCmode)
6540 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6541 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6542 [(set_attr "type" "alu")
6543 (set_attr "mode" "<MODE>")])
6544
6545 (define_insn "*subsi_3_zext"
6546 [(set (reg FLAGS_REG)
6547 (compare (match_operand:SI 1 "register_operand" "0")
6548 (match_operand:SI 2 "general_operand" "g")))
6549 (set (match_operand:DI 0 "register_operand" "=r")
6550 (zero_extend:DI
6551 (minus:SI (match_dup 1)
6552 (match_dup 2))))]
6553 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6554 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555 "sub{l}\t{%2, %1|%1, %2}"
6556 [(set_attr "type" "alu")
6557 (set_attr "mode" "SI")])
6558 \f
6559 ;; Add with carry and subtract with borrow
6560
6561 (define_expand "<plusminus_insn><mode>3_carry"
6562 [(parallel
6563 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6564 (plusminus:SWI
6565 (match_operand:SWI 1 "nonimmediate_operand" "")
6566 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6567 [(match_operand 3 "flags_reg_operand" "")
6568 (const_int 0)])
6569 (match_operand:SWI 2 "<general_operand>" ""))))
6570 (clobber (reg:CC FLAGS_REG))])]
6571 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6572
6573 (define_insn "*<plusminus_insn><mode>3_carry"
6574 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6575 (plusminus:SWI
6576 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6577 (plus:SWI
6578 (match_operator 3 "ix86_carry_flag_operator"
6579 [(reg FLAGS_REG) (const_int 0)])
6580 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6581 (clobber (reg:CC FLAGS_REG))]
6582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6583 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "use_carry" "1")
6586 (set_attr "pent_pair" "pu")
6587 (set_attr "mode" "<MODE>")])
6588
6589 (define_insn "*addsi3_carry_zext"
6590 [(set (match_operand:DI 0 "register_operand" "=r")
6591 (zero_extend:DI
6592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6593 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6594 [(reg FLAGS_REG) (const_int 0)])
6595 (match_operand:SI 2 "general_operand" "g")))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6598 "adc{l}\t{%2, %k0|%k0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "SI")])
6603
6604 (define_insn "*subsi3_carry_zext"
6605 [(set (match_operand:DI 0 "register_operand" "=r")
6606 (zero_extend:DI
6607 (minus:SI (match_operand:SI 1 "register_operand" "0")
6608 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6609 [(reg FLAGS_REG) (const_int 0)])
6610 (match_operand:SI 2 "general_operand" "g")))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6613 "sbb{l}\t{%2, %k0|%k0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "SI")])
6617 \f
6618 ;; Overflow setting add and subtract instructions
6619
6620 (define_insn "*add<mode>3_cconly_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6622 (compare:CCC
6623 (plus:SWI
6624 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6625 (match_operand:SWI 2 "<general_operand>" "<g>"))
6626 (match_dup 1)))
6627 (clobber (match_scratch:SWI 0 "=<r>"))]
6628 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6629 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "<MODE>")])
6632
6633 (define_insn "*sub<mode>3_cconly_overflow"
6634 [(set (reg:CCC FLAGS_REG)
6635 (compare:CCC
6636 (minus:SWI
6637 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6638 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6639 (match_dup 0)))]
6640 ""
6641 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6642 [(set_attr "type" "icmp")
6643 (set_attr "mode" "<MODE>")])
6644
6645 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6646 [(set (reg:CCC FLAGS_REG)
6647 (compare:CCC
6648 (plusminus:SWI
6649 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6650 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6651 (match_dup 1)))
6652 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6653 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6654 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6655 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "mode" "<MODE>")])
6658
6659 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6660 [(set (reg:CCC FLAGS_REG)
6661 (compare:CCC
6662 (plusminus:SI
6663 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6664 (match_operand:SI 2 "general_operand" "g"))
6665 (match_dup 1)))
6666 (set (match_operand:DI 0 "register_operand" "=r")
6667 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6668 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6669 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "SI")])
6672
6673 ;; The patterns that match these are at the end of this file.
6674
6675 (define_expand "<plusminus_insn>xf3"
6676 [(set (match_operand:XF 0 "register_operand" "")
6677 (plusminus:XF
6678 (match_operand:XF 1 "register_operand" "")
6679 (match_operand:XF 2 "register_operand" "")))]
6680 "TARGET_80387")
6681
6682 (define_expand "<plusminus_insn><mode>3"
6683 [(set (match_operand:MODEF 0 "register_operand" "")
6684 (plusminus:MODEF
6685 (match_operand:MODEF 1 "register_operand" "")
6686 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6687 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6688 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6689 \f
6690 ;; Multiply instructions
6691
6692 (define_expand "mul<mode>3"
6693 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6694 (mult:SWIM248
6695 (match_operand:SWIM248 1 "register_operand" "")
6696 (match_operand:SWIM248 2 "<general_operand>" "")))
6697 (clobber (reg:CC FLAGS_REG))])])
6698
6699 (define_expand "mulqi3"
6700 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6701 (mult:QI
6702 (match_operand:QI 1 "register_operand" "")
6703 (match_operand:QI 2 "nonimmediate_operand" "")))
6704 (clobber (reg:CC FLAGS_REG))])]
6705 "TARGET_QIMODE_MATH")
6706
6707 ;; On AMDFAM10
6708 ;; IMUL reg32/64, reg32/64, imm8 Direct
6709 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6710 ;; IMUL reg32/64, reg32/64, imm32 Direct
6711 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6712 ;; IMUL reg32/64, reg32/64 Direct
6713 ;; IMUL reg32/64, mem32/64 Direct
6714 ;;
6715 ;; On BDVER1, all above IMULs use DirectPath
6716
6717 (define_insn "*mul<mode>3_1"
6718 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6719 (mult:SWI48
6720 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6721 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6724 "@
6725 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6726 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6727 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6728 [(set_attr "type" "imul")
6729 (set_attr "prefix_0f" "0,0,1")
6730 (set (attr "athlon_decode")
6731 (cond [(eq_attr "cpu" "athlon")
6732 (const_string "vector")
6733 (eq_attr "alternative" "1")
6734 (const_string "vector")
6735 (and (eq_attr "alternative" "2")
6736 (match_operand 1 "memory_operand" ""))
6737 (const_string "vector")]
6738 (const_string "direct")))
6739 (set (attr "amdfam10_decode")
6740 (cond [(and (eq_attr "alternative" "0,1")
6741 (match_operand 1 "memory_operand" ""))
6742 (const_string "vector")]
6743 (const_string "direct")))
6744 (set_attr "bdver1_decode" "direct")
6745 (set_attr "mode" "<MODE>")])
6746
6747 (define_insn "*mulsi3_1_zext"
6748 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6749 (zero_extend:DI
6750 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6751 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "TARGET_64BIT
6754 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6755 "@
6756 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6757 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6758 imul{l}\t{%2, %k0|%k0, %2}"
6759 [(set_attr "type" "imul")
6760 (set_attr "prefix_0f" "0,0,1")
6761 (set (attr "athlon_decode")
6762 (cond [(eq_attr "cpu" "athlon")
6763 (const_string "vector")
6764 (eq_attr "alternative" "1")
6765 (const_string "vector")
6766 (and (eq_attr "alternative" "2")
6767 (match_operand 1 "memory_operand" ""))
6768 (const_string "vector")]
6769 (const_string "direct")))
6770 (set (attr "amdfam10_decode")
6771 (cond [(and (eq_attr "alternative" "0,1")
6772 (match_operand 1 "memory_operand" ""))
6773 (const_string "vector")]
6774 (const_string "direct")))
6775 (set_attr "bdver1_decode" "direct")
6776 (set_attr "mode" "SI")])
6777
6778 ;; On AMDFAM10
6779 ;; IMUL reg16, reg16, imm8 VectorPath
6780 ;; IMUL reg16, mem16, imm8 VectorPath
6781 ;; IMUL reg16, reg16, imm16 VectorPath
6782 ;; IMUL reg16, mem16, imm16 VectorPath
6783 ;; IMUL reg16, reg16 Direct
6784 ;; IMUL reg16, mem16 Direct
6785 ;;
6786 ;; On BDVER1, all HI MULs use DoublePath
6787
6788 (define_insn "*mulhi3_1"
6789 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6790 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6791 (match_operand:HI 2 "general_operand" "K,n,mr")))
6792 (clobber (reg:CC FLAGS_REG))]
6793 "TARGET_HIMODE_MATH
6794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6795 "@
6796 imul{w}\t{%2, %1, %0|%0, %1, %2}
6797 imul{w}\t{%2, %1, %0|%0, %1, %2}
6798 imul{w}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "imul")
6800 (set_attr "prefix_0f" "0,0,1")
6801 (set (attr "athlon_decode")
6802 (cond [(eq_attr "cpu" "athlon")
6803 (const_string "vector")
6804 (eq_attr "alternative" "1,2")
6805 (const_string "vector")]
6806 (const_string "direct")))
6807 (set (attr "amdfam10_decode")
6808 (cond [(eq_attr "alternative" "0,1")
6809 (const_string "vector")]
6810 (const_string "direct")))
6811 (set_attr "bdver1_decode" "double")
6812 (set_attr "mode" "HI")])
6813
6814 ;;On AMDFAM10 and BDVER1
6815 ;; MUL reg8 Direct
6816 ;; MUL mem8 Direct
6817
6818 (define_insn "*mulqi3_1"
6819 [(set (match_operand:QI 0 "register_operand" "=a")
6820 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6821 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6822 (clobber (reg:CC FLAGS_REG))]
6823 "TARGET_QIMODE_MATH
6824 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6825 "mul{b}\t%2"
6826 [(set_attr "type" "imul")
6827 (set_attr "length_immediate" "0")
6828 (set (attr "athlon_decode")
6829 (if_then_else (eq_attr "cpu" "athlon")
6830 (const_string "vector")
6831 (const_string "direct")))
6832 (set_attr "amdfam10_decode" "direct")
6833 (set_attr "bdver1_decode" "direct")
6834 (set_attr "mode" "QI")])
6835
6836 (define_expand "<u>mul<mode><dwi>3"
6837 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6838 (mult:<DWI>
6839 (any_extend:<DWI>
6840 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6841 (any_extend:<DWI>
6842 (match_operand:DWIH 2 "register_operand" ""))))
6843 (clobber (reg:CC FLAGS_REG))])])
6844
6845 (define_expand "<u>mulqihi3"
6846 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6847 (mult:HI
6848 (any_extend:HI
6849 (match_operand:QI 1 "nonimmediate_operand" ""))
6850 (any_extend:HI
6851 (match_operand:QI 2 "register_operand" ""))))
6852 (clobber (reg:CC FLAGS_REG))])]
6853 "TARGET_QIMODE_MATH")
6854
6855 (define_insn "*<u>mul<mode><dwi>3_1"
6856 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6857 (mult:<DWI>
6858 (any_extend:<DWI>
6859 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6860 (any_extend:<DWI>
6861 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6862 (clobber (reg:CC FLAGS_REG))]
6863 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864 "<sgnprefix>mul{<imodesuffix>}\t%2"
6865 [(set_attr "type" "imul")
6866 (set_attr "length_immediate" "0")
6867 (set (attr "athlon_decode")
6868 (if_then_else (eq_attr "cpu" "athlon")
6869 (const_string "vector")
6870 (const_string "double")))
6871 (set_attr "amdfam10_decode" "double")
6872 (set_attr "bdver1_decode" "direct")
6873 (set_attr "mode" "<MODE>")])
6874
6875 (define_insn "*<u>mulqihi3_1"
6876 [(set (match_operand:HI 0 "register_operand" "=a")
6877 (mult:HI
6878 (any_extend:HI
6879 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6880 (any_extend:HI
6881 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6882 (clobber (reg:CC FLAGS_REG))]
6883 "TARGET_QIMODE_MATH
6884 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885 "<sgnprefix>mul{b}\t%2"
6886 [(set_attr "type" "imul")
6887 (set_attr "length_immediate" "0")
6888 (set (attr "athlon_decode")
6889 (if_then_else (eq_attr "cpu" "athlon")
6890 (const_string "vector")
6891 (const_string "direct")))
6892 (set_attr "amdfam10_decode" "direct")
6893 (set_attr "bdver1_decode" "direct")
6894 (set_attr "mode" "QI")])
6895
6896 (define_expand "<s>mul<mode>3_highpart"
6897 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6898 (truncate:SWI48
6899 (lshiftrt:<DWI>
6900 (mult:<DWI>
6901 (any_extend:<DWI>
6902 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6903 (any_extend:<DWI>
6904 (match_operand:SWI48 2 "register_operand" "")))
6905 (match_dup 4))))
6906 (clobber (match_scratch:SWI48 3 ""))
6907 (clobber (reg:CC FLAGS_REG))])]
6908 ""
6909 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6910
6911 (define_insn "*<s>muldi3_highpart_1"
6912 [(set (match_operand:DI 0 "register_operand" "=d")
6913 (truncate:DI
6914 (lshiftrt:TI
6915 (mult:TI
6916 (any_extend:TI
6917 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6918 (any_extend:TI
6919 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6920 (const_int 64))))
6921 (clobber (match_scratch:DI 3 "=1"))
6922 (clobber (reg:CC FLAGS_REG))]
6923 "TARGET_64BIT
6924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6925 "<sgnprefix>mul{q}\t%2"
6926 [(set_attr "type" "imul")
6927 (set_attr "length_immediate" "0")
6928 (set (attr "athlon_decode")
6929 (if_then_else (eq_attr "cpu" "athlon")
6930 (const_string "vector")
6931 (const_string "double")))
6932 (set_attr "amdfam10_decode" "double")
6933 (set_attr "bdver1_decode" "direct")
6934 (set_attr "mode" "DI")])
6935
6936 (define_insn "*<s>mulsi3_highpart_1"
6937 [(set (match_operand:SI 0 "register_operand" "=d")
6938 (truncate:SI
6939 (lshiftrt:DI
6940 (mult:DI
6941 (any_extend:DI
6942 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6943 (any_extend:DI
6944 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6945 (const_int 32))))
6946 (clobber (match_scratch:SI 3 "=1"))
6947 (clobber (reg:CC FLAGS_REG))]
6948 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6949 "<sgnprefix>mul{l}\t%2"
6950 [(set_attr "type" "imul")
6951 (set_attr "length_immediate" "0")
6952 (set (attr "athlon_decode")
6953 (if_then_else (eq_attr "cpu" "athlon")
6954 (const_string "vector")
6955 (const_string "double")))
6956 (set_attr "amdfam10_decode" "double")
6957 (set_attr "bdver1_decode" "direct")
6958 (set_attr "mode" "SI")])
6959
6960 (define_insn "*<s>mulsi3_highpart_zext"
6961 [(set (match_operand:DI 0 "register_operand" "=d")
6962 (zero_extend:DI (truncate:SI
6963 (lshiftrt:DI
6964 (mult:DI (any_extend:DI
6965 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6966 (any_extend:DI
6967 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6968 (const_int 32)))))
6969 (clobber (match_scratch:SI 3 "=1"))
6970 (clobber (reg:CC FLAGS_REG))]
6971 "TARGET_64BIT
6972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973 "<sgnprefix>mul{l}\t%2"
6974 [(set_attr "type" "imul")
6975 (set_attr "length_immediate" "0")
6976 (set (attr "athlon_decode")
6977 (if_then_else (eq_attr "cpu" "athlon")
6978 (const_string "vector")
6979 (const_string "double")))
6980 (set_attr "amdfam10_decode" "double")
6981 (set_attr "bdver1_decode" "direct")
6982 (set_attr "mode" "SI")])
6983
6984 ;; The patterns that match these are at the end of this file.
6985
6986 (define_expand "mulxf3"
6987 [(set (match_operand:XF 0 "register_operand" "")
6988 (mult:XF (match_operand:XF 1 "register_operand" "")
6989 (match_operand:XF 2 "register_operand" "")))]
6990 "TARGET_80387")
6991
6992 (define_expand "mul<mode>3"
6993 [(set (match_operand:MODEF 0 "register_operand" "")
6994 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6995 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6996 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6997 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6998 \f
6999 ;; Divide instructions
7000
7001 ;; The patterns that match these are at the end of this file.
7002
7003 (define_expand "divxf3"
7004 [(set (match_operand:XF 0 "register_operand" "")
7005 (div:XF (match_operand:XF 1 "register_operand" "")
7006 (match_operand:XF 2 "register_operand" "")))]
7007 "TARGET_80387")
7008
7009 (define_expand "divdf3"
7010 [(set (match_operand:DF 0 "register_operand" "")
7011 (div:DF (match_operand:DF 1 "register_operand" "")
7012 (match_operand:DF 2 "nonimmediate_operand" "")))]
7013 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7014 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7015
7016 (define_expand "divsf3"
7017 [(set (match_operand:SF 0 "register_operand" "")
7018 (div:SF (match_operand:SF 1 "register_operand" "")
7019 (match_operand:SF 2 "nonimmediate_operand" "")))]
7020 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7021 || TARGET_SSE_MATH"
7022 {
7023 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7024 && flag_finite_math_only && !flag_trapping_math
7025 && flag_unsafe_math_optimizations)
7026 {
7027 ix86_emit_swdivsf (operands[0], operands[1],
7028 operands[2], SFmode);
7029 DONE;
7030 }
7031 })
7032 \f
7033 ;; Divmod instructions.
7034
7035 (define_expand "divmod<mode>4"
7036 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7037 (div:SWIM248
7038 (match_operand:SWIM248 1 "register_operand" "")
7039 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7040 (set (match_operand:SWIM248 3 "register_operand" "")
7041 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7042 (clobber (reg:CC FLAGS_REG))])])
7043
7044 ;; Split with 8bit unsigned divide:
7045 ;; if (dividend an divisor are in [0-255])
7046 ;; use 8bit unsigned integer divide
7047 ;; else
7048 ;; use original integer divide
7049 (define_split
7050 [(set (match_operand:SWI48 0 "register_operand" "")
7051 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7052 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7053 (set (match_operand:SWI48 1 "register_operand" "")
7054 (mod:SWI48 (match_dup 2) (match_dup 3)))
7055 (clobber (reg:CC FLAGS_REG))]
7056 "TARGET_USE_8BIT_IDIV
7057 && TARGET_QIMODE_MATH
7058 && can_create_pseudo_p ()
7059 && !optimize_insn_for_size_p ()"
7060 [(const_int 0)]
7061 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7062
7063 (define_insn_and_split "divmod<mode>4_1"
7064 [(set (match_operand:SWI48 0 "register_operand" "=a")
7065 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7066 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7067 (set (match_operand:SWI48 1 "register_operand" "=&d")
7068 (mod:SWI48 (match_dup 2) (match_dup 3)))
7069 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7070 (clobber (reg:CC FLAGS_REG))]
7071 ""
7072 "#"
7073 "reload_completed"
7074 [(parallel [(set (match_dup 1)
7075 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7076 (clobber (reg:CC FLAGS_REG))])
7077 (parallel [(set (match_dup 0)
7078 (div:SWI48 (match_dup 2) (match_dup 3)))
7079 (set (match_dup 1)
7080 (mod:SWI48 (match_dup 2) (match_dup 3)))
7081 (use (match_dup 1))
7082 (clobber (reg:CC FLAGS_REG))])]
7083 {
7084 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7085
7086 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7087 operands[4] = operands[2];
7088 else
7089 {
7090 /* Avoid use of cltd in favor of a mov+shift. */
7091 emit_move_insn (operands[1], operands[2]);
7092 operands[4] = operands[1];
7093 }
7094 }
7095 [(set_attr "type" "multi")
7096 (set_attr "mode" "<MODE>")])
7097
7098 (define_insn_and_split "*divmod<mode>4"
7099 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7100 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7101 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7102 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7103 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7104 (clobber (reg:CC FLAGS_REG))]
7105 ""
7106 "#"
7107 "reload_completed"
7108 [(parallel [(set (match_dup 1)
7109 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7110 (clobber (reg:CC FLAGS_REG))])
7111 (parallel [(set (match_dup 0)
7112 (div:SWIM248 (match_dup 2) (match_dup 3)))
7113 (set (match_dup 1)
7114 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7115 (use (match_dup 1))
7116 (clobber (reg:CC FLAGS_REG))])]
7117 {
7118 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7119
7120 if (<MODE>mode != HImode
7121 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7122 operands[4] = operands[2];
7123 else
7124 {
7125 /* Avoid use of cltd in favor of a mov+shift. */
7126 emit_move_insn (operands[1], operands[2]);
7127 operands[4] = operands[1];
7128 }
7129 }
7130 [(set_attr "type" "multi")
7131 (set_attr "mode" "<MODE>")])
7132
7133 (define_insn "*divmod<mode>4_noext"
7134 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7135 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7136 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7137 (set (match_operand:SWIM248 1 "register_operand" "=d")
7138 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7139 (use (match_operand:SWIM248 4 "register_operand" "1"))
7140 (clobber (reg:CC FLAGS_REG))]
7141 ""
7142 "idiv{<imodesuffix>}\t%3"
7143 [(set_attr "type" "idiv")
7144 (set_attr "mode" "<MODE>")])
7145
7146 (define_expand "divmodqi4"
7147 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7148 (div:QI
7149 (match_operand:QI 1 "register_operand" "")
7150 (match_operand:QI 2 "nonimmediate_operand" "")))
7151 (set (match_operand:QI 3 "register_operand" "")
7152 (mod:QI (match_dup 1) (match_dup 2)))
7153 (clobber (reg:CC FLAGS_REG))])]
7154 "TARGET_QIMODE_MATH"
7155 {
7156 rtx div, mod, insn;
7157 rtx tmp0, tmp1;
7158
7159 tmp0 = gen_reg_rtx (HImode);
7160 tmp1 = gen_reg_rtx (HImode);
7161
7162 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7163 in AX. */
7164 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7165 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7166
7167 /* Extract remainder from AH. */
7168 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7169 insn = emit_move_insn (operands[3], tmp1);
7170
7171 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7172 set_unique_reg_note (insn, REG_EQUAL, mod);
7173
7174 /* Extract quotient from AL. */
7175 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7176
7177 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7178 set_unique_reg_note (insn, REG_EQUAL, div);
7179
7180 DONE;
7181 })
7182
7183 ;; Divide AX by r/m8, with result stored in
7184 ;; AL <- Quotient
7185 ;; AH <- Remainder
7186 ;; Change div/mod to HImode and extend the second argument to HImode
7187 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7188 ;; combine may fail.
7189 (define_insn "divmodhiqi3"
7190 [(set (match_operand:HI 0 "register_operand" "=a")
7191 (ior:HI
7192 (ashift:HI
7193 (zero_extend:HI
7194 (truncate:QI
7195 (mod:HI (match_operand:HI 1 "register_operand" "0")
7196 (sign_extend:HI
7197 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7198 (const_int 8))
7199 (zero_extend:HI
7200 (truncate:QI
7201 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7202 (clobber (reg:CC FLAGS_REG))]
7203 "TARGET_QIMODE_MATH"
7204 "idiv{b}\t%2"
7205 [(set_attr "type" "idiv")
7206 (set_attr "mode" "QI")])
7207
7208 (define_expand "udivmod<mode>4"
7209 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7210 (udiv:SWIM248
7211 (match_operand:SWIM248 1 "register_operand" "")
7212 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7213 (set (match_operand:SWIM248 3 "register_operand" "")
7214 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7215 (clobber (reg:CC FLAGS_REG))])])
7216
7217 ;; Split with 8bit unsigned divide:
7218 ;; if (dividend an divisor are in [0-255])
7219 ;; use 8bit unsigned integer divide
7220 ;; else
7221 ;; use original integer divide
7222 (define_split
7223 [(set (match_operand:SWI48 0 "register_operand" "")
7224 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7225 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7226 (set (match_operand:SWI48 1 "register_operand" "")
7227 (umod:SWI48 (match_dup 2) (match_dup 3)))
7228 (clobber (reg:CC FLAGS_REG))]
7229 "TARGET_USE_8BIT_IDIV
7230 && TARGET_QIMODE_MATH
7231 && can_create_pseudo_p ()
7232 && !optimize_insn_for_size_p ()"
7233 [(const_int 0)]
7234 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7235
7236 (define_insn_and_split "udivmod<mode>4_1"
7237 [(set (match_operand:SWI48 0 "register_operand" "=a")
7238 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7239 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7240 (set (match_operand:SWI48 1 "register_operand" "=&d")
7241 (umod:SWI48 (match_dup 2) (match_dup 3)))
7242 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7243 (clobber (reg:CC FLAGS_REG))]
7244 ""
7245 "#"
7246 "reload_completed"
7247 [(set (match_dup 1) (const_int 0))
7248 (parallel [(set (match_dup 0)
7249 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7250 (set (match_dup 1)
7251 (umod:SWI48 (match_dup 2) (match_dup 3)))
7252 (use (match_dup 1))
7253 (clobber (reg:CC FLAGS_REG))])]
7254 ""
7255 [(set_attr "type" "multi")
7256 (set_attr "mode" "<MODE>")])
7257
7258 (define_insn_and_split "*udivmod<mode>4"
7259 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7263 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264 (clobber (reg:CC FLAGS_REG))]
7265 ""
7266 "#"
7267 "reload_completed"
7268 [(set (match_dup 1) (const_int 0))
7269 (parallel [(set (match_dup 0)
7270 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7271 (set (match_dup 1)
7272 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7273 (use (match_dup 1))
7274 (clobber (reg:CC FLAGS_REG))])]
7275 ""
7276 [(set_attr "type" "multi")
7277 (set_attr "mode" "<MODE>")])
7278
7279 (define_insn "*udivmod<mode>4_noext"
7280 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7281 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7282 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7283 (set (match_operand:SWIM248 1 "register_operand" "=d")
7284 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7285 (use (match_operand:SWIM248 4 "register_operand" "1"))
7286 (clobber (reg:CC FLAGS_REG))]
7287 ""
7288 "div{<imodesuffix>}\t%3"
7289 [(set_attr "type" "idiv")
7290 (set_attr "mode" "<MODE>")])
7291
7292 (define_expand "udivmodqi4"
7293 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7294 (udiv:QI
7295 (match_operand:QI 1 "register_operand" "")
7296 (match_operand:QI 2 "nonimmediate_operand" "")))
7297 (set (match_operand:QI 3 "register_operand" "")
7298 (umod:QI (match_dup 1) (match_dup 2)))
7299 (clobber (reg:CC FLAGS_REG))])]
7300 "TARGET_QIMODE_MATH"
7301 {
7302 rtx div, mod, insn;
7303 rtx tmp0, tmp1;
7304
7305 tmp0 = gen_reg_rtx (HImode);
7306 tmp1 = gen_reg_rtx (HImode);
7307
7308 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7309 in AX. */
7310 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7311 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7312
7313 /* Extract remainder from AH. */
7314 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7315 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7316 insn = emit_move_insn (operands[3], tmp1);
7317
7318 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7319 set_unique_reg_note (insn, REG_EQUAL, mod);
7320
7321 /* Extract quotient from AL. */
7322 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7323
7324 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7325 set_unique_reg_note (insn, REG_EQUAL, div);
7326
7327 DONE;
7328 })
7329
7330 (define_insn "udivmodhiqi3"
7331 [(set (match_operand:HI 0 "register_operand" "=a")
7332 (ior:HI
7333 (ashift:HI
7334 (zero_extend:HI
7335 (truncate:QI
7336 (mod:HI (match_operand:HI 1 "register_operand" "0")
7337 (zero_extend:HI
7338 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7339 (const_int 8))
7340 (zero_extend:HI
7341 (truncate:QI
7342 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7343 (clobber (reg:CC FLAGS_REG))]
7344 "TARGET_QIMODE_MATH"
7345 "div{b}\t%2"
7346 [(set_attr "type" "idiv")
7347 (set_attr "mode" "QI")])
7348
7349 ;; We cannot use div/idiv for double division, because it causes
7350 ;; "division by zero" on the overflow and that's not what we expect
7351 ;; from truncate. Because true (non truncating) double division is
7352 ;; never generated, we can't create this insn anyway.
7353 ;
7354 ;(define_insn ""
7355 ; [(set (match_operand:SI 0 "register_operand" "=a")
7356 ; (truncate:SI
7357 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7358 ; (zero_extend:DI
7359 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7360 ; (set (match_operand:SI 3 "register_operand" "=d")
7361 ; (truncate:SI
7362 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7363 ; (clobber (reg:CC FLAGS_REG))]
7364 ; ""
7365 ; "div{l}\t{%2, %0|%0, %2}"
7366 ; [(set_attr "type" "idiv")])
7367 \f
7368 ;;- Logical AND instructions
7369
7370 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7371 ;; Note that this excludes ah.
7372
7373 (define_expand "testsi_ccno_1"
7374 [(set (reg:CCNO FLAGS_REG)
7375 (compare:CCNO
7376 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7377 (match_operand:SI 1 "nonmemory_operand" ""))
7378 (const_int 0)))])
7379
7380 (define_expand "testqi_ccz_1"
7381 [(set (reg:CCZ FLAGS_REG)
7382 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7383 (match_operand:QI 1 "nonmemory_operand" ""))
7384 (const_int 0)))])
7385
7386 (define_expand "testdi_ccno_1"
7387 [(set (reg:CCNO FLAGS_REG)
7388 (compare:CCNO
7389 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7390 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7391 (const_int 0)))]
7392 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7393
7394 (define_insn "*testdi_1"
7395 [(set (reg FLAGS_REG)
7396 (compare
7397 (and:DI
7398 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7399 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7400 (const_int 0)))]
7401 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7403 "@
7404 test{l}\t{%k1, %k0|%k0, %k1}
7405 test{l}\t{%k1, %k0|%k0, %k1}
7406 test{q}\t{%1, %0|%0, %1}
7407 test{q}\t{%1, %0|%0, %1}
7408 test{q}\t{%1, %0|%0, %1}"
7409 [(set_attr "type" "test")
7410 (set_attr "modrm" "0,1,0,1,1")
7411 (set_attr "mode" "SI,SI,DI,DI,DI")])
7412
7413 (define_insn "*testqi_1_maybe_si"
7414 [(set (reg FLAGS_REG)
7415 (compare
7416 (and:QI
7417 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7418 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7419 (const_int 0)))]
7420 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7421 && ix86_match_ccmode (insn,
7422 CONST_INT_P (operands[1])
7423 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7424 {
7425 if (which_alternative == 3)
7426 {
7427 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7428 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7429 return "test{l}\t{%1, %k0|%k0, %1}";
7430 }
7431 return "test{b}\t{%1, %0|%0, %1}";
7432 }
7433 [(set_attr "type" "test")
7434 (set_attr "modrm" "0,1,1,1")
7435 (set_attr "mode" "QI,QI,QI,SI")
7436 (set_attr "pent_pair" "uv,np,uv,np")])
7437
7438 (define_insn "*test<mode>_1"
7439 [(set (reg FLAGS_REG)
7440 (compare
7441 (and:SWI124
7442 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7443 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7444 (const_int 0)))]
7445 "ix86_match_ccmode (insn, CCNOmode)
7446 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7447 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7448 [(set_attr "type" "test")
7449 (set_attr "modrm" "0,1,1")
7450 (set_attr "mode" "<MODE>")
7451 (set_attr "pent_pair" "uv,np,uv")])
7452
7453 (define_expand "testqi_ext_ccno_0"
7454 [(set (reg:CCNO FLAGS_REG)
7455 (compare:CCNO
7456 (and:SI
7457 (zero_extract:SI
7458 (match_operand 0 "ext_register_operand" "")
7459 (const_int 8)
7460 (const_int 8))
7461 (match_operand 1 "const_int_operand" ""))
7462 (const_int 0)))])
7463
7464 (define_insn "*testqi_ext_0"
7465 [(set (reg FLAGS_REG)
7466 (compare
7467 (and:SI
7468 (zero_extract:SI
7469 (match_operand 0 "ext_register_operand" "Q")
7470 (const_int 8)
7471 (const_int 8))
7472 (match_operand 1 "const_int_operand" "n"))
7473 (const_int 0)))]
7474 "ix86_match_ccmode (insn, CCNOmode)"
7475 "test{b}\t{%1, %h0|%h0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "mode" "QI")
7478 (set_attr "length_immediate" "1")
7479 (set_attr "modrm" "1")
7480 (set_attr "pent_pair" "np")])
7481
7482 (define_insn "*testqi_ext_1_rex64"
7483 [(set (reg FLAGS_REG)
7484 (compare
7485 (and:SI
7486 (zero_extract:SI
7487 (match_operand 0 "ext_register_operand" "Q")
7488 (const_int 8)
7489 (const_int 8))
7490 (zero_extend:SI
7491 (match_operand:QI 1 "register_operand" "Q")))
7492 (const_int 0)))]
7493 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7494 "test{b}\t{%1, %h0|%h0, %1}"
7495 [(set_attr "type" "test")
7496 (set_attr "mode" "QI")])
7497
7498 (define_insn "*testqi_ext_1"
7499 [(set (reg FLAGS_REG)
7500 (compare
7501 (and:SI
7502 (zero_extract:SI
7503 (match_operand 0 "ext_register_operand" "Q")
7504 (const_int 8)
7505 (const_int 8))
7506 (zero_extend:SI
7507 (match_operand:QI 1 "general_operand" "Qm")))
7508 (const_int 0)))]
7509 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7510 "test{b}\t{%1, %h0|%h0, %1}"
7511 [(set_attr "type" "test")
7512 (set_attr "mode" "QI")])
7513
7514 (define_insn "*testqi_ext_2"
7515 [(set (reg FLAGS_REG)
7516 (compare
7517 (and:SI
7518 (zero_extract:SI
7519 (match_operand 0 "ext_register_operand" "Q")
7520 (const_int 8)
7521 (const_int 8))
7522 (zero_extract:SI
7523 (match_operand 1 "ext_register_operand" "Q")
7524 (const_int 8)
7525 (const_int 8)))
7526 (const_int 0)))]
7527 "ix86_match_ccmode (insn, CCNOmode)"
7528 "test{b}\t{%h1, %h0|%h0, %h1}"
7529 [(set_attr "type" "test")
7530 (set_attr "mode" "QI")])
7531
7532 (define_insn "*testqi_ext_3_rex64"
7533 [(set (reg FLAGS_REG)
7534 (compare (zero_extract:DI
7535 (match_operand 0 "nonimmediate_operand" "rm")
7536 (match_operand:DI 1 "const_int_operand" "")
7537 (match_operand:DI 2 "const_int_operand" ""))
7538 (const_int 0)))]
7539 "TARGET_64BIT
7540 && ix86_match_ccmode (insn, CCNOmode)
7541 && INTVAL (operands[1]) > 0
7542 && INTVAL (operands[2]) >= 0
7543 /* Ensure that resulting mask is zero or sign extended operand. */
7544 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7545 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7546 && INTVAL (operands[1]) > 32))
7547 && (GET_MODE (operands[0]) == SImode
7548 || GET_MODE (operands[0]) == DImode
7549 || GET_MODE (operands[0]) == HImode
7550 || GET_MODE (operands[0]) == QImode)"
7551 "#")
7552
7553 ;; Combine likes to form bit extractions for some tests. Humor it.
7554 (define_insn "*testqi_ext_3"
7555 [(set (reg FLAGS_REG)
7556 (compare (zero_extract:SI
7557 (match_operand 0 "nonimmediate_operand" "rm")
7558 (match_operand:SI 1 "const_int_operand" "")
7559 (match_operand:SI 2 "const_int_operand" ""))
7560 (const_int 0)))]
7561 "ix86_match_ccmode (insn, CCNOmode)
7562 && INTVAL (operands[1]) > 0
7563 && INTVAL (operands[2]) >= 0
7564 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7565 && (GET_MODE (operands[0]) == SImode
7566 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7567 || GET_MODE (operands[0]) == HImode
7568 || GET_MODE (operands[0]) == QImode)"
7569 "#")
7570
7571 (define_split
7572 [(set (match_operand 0 "flags_reg_operand" "")
7573 (match_operator 1 "compare_operator"
7574 [(zero_extract
7575 (match_operand 2 "nonimmediate_operand" "")
7576 (match_operand 3 "const_int_operand" "")
7577 (match_operand 4 "const_int_operand" ""))
7578 (const_int 0)]))]
7579 "ix86_match_ccmode (insn, CCNOmode)"
7580 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7581 {
7582 rtx val = operands[2];
7583 HOST_WIDE_INT len = INTVAL (operands[3]);
7584 HOST_WIDE_INT pos = INTVAL (operands[4]);
7585 HOST_WIDE_INT mask;
7586 enum machine_mode mode, submode;
7587
7588 mode = GET_MODE (val);
7589 if (MEM_P (val))
7590 {
7591 /* ??? Combine likes to put non-volatile mem extractions in QImode
7592 no matter the size of the test. So find a mode that works. */
7593 if (! MEM_VOLATILE_P (val))
7594 {
7595 mode = smallest_mode_for_size (pos + len, MODE_INT);
7596 val = adjust_address (val, mode, 0);
7597 }
7598 }
7599 else if (GET_CODE (val) == SUBREG
7600 && (submode = GET_MODE (SUBREG_REG (val)),
7601 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7602 && pos + len <= GET_MODE_BITSIZE (submode)
7603 && GET_MODE_CLASS (submode) == MODE_INT)
7604 {
7605 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7606 mode = submode;
7607 val = SUBREG_REG (val);
7608 }
7609 else if (mode == HImode && pos + len <= 8)
7610 {
7611 /* Small HImode tests can be converted to QImode. */
7612 mode = QImode;
7613 val = gen_lowpart (QImode, val);
7614 }
7615
7616 if (len == HOST_BITS_PER_WIDE_INT)
7617 mask = -1;
7618 else
7619 mask = ((HOST_WIDE_INT)1 << len) - 1;
7620 mask <<= pos;
7621
7622 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7623 })
7624
7625 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7626 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7627 ;; this is relatively important trick.
7628 ;; Do the conversion only post-reload to avoid limiting of the register class
7629 ;; to QI regs.
7630 (define_split
7631 [(set (match_operand 0 "flags_reg_operand" "")
7632 (match_operator 1 "compare_operator"
7633 [(and (match_operand 2 "register_operand" "")
7634 (match_operand 3 "const_int_operand" ""))
7635 (const_int 0)]))]
7636 "reload_completed
7637 && QI_REG_P (operands[2])
7638 && GET_MODE (operands[2]) != QImode
7639 && ((ix86_match_ccmode (insn, CCZmode)
7640 && !(INTVAL (operands[3]) & ~(255 << 8)))
7641 || (ix86_match_ccmode (insn, CCNOmode)
7642 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7643 [(set (match_dup 0)
7644 (match_op_dup 1
7645 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7646 (match_dup 3))
7647 (const_int 0)]))]
7648 "operands[2] = gen_lowpart (SImode, operands[2]);
7649 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7650
7651 (define_split
7652 [(set (match_operand 0 "flags_reg_operand" "")
7653 (match_operator 1 "compare_operator"
7654 [(and (match_operand 2 "nonimmediate_operand" "")
7655 (match_operand 3 "const_int_operand" ""))
7656 (const_int 0)]))]
7657 "reload_completed
7658 && GET_MODE (operands[2]) != QImode
7659 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7660 && ((ix86_match_ccmode (insn, CCZmode)
7661 && !(INTVAL (operands[3]) & ~255))
7662 || (ix86_match_ccmode (insn, CCNOmode)
7663 && !(INTVAL (operands[3]) & ~127)))"
7664 [(set (match_dup 0)
7665 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7666 (const_int 0)]))]
7667 "operands[2] = gen_lowpart (QImode, operands[2]);
7668 operands[3] = gen_lowpart (QImode, operands[3]);")
7669
7670 ;; %%% This used to optimize known byte-wide and operations to memory,
7671 ;; and sometimes to QImode registers. If this is considered useful,
7672 ;; it should be done with splitters.
7673
7674 (define_expand "and<mode>3"
7675 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7676 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7677 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7678 ""
7679 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7680
7681 (define_insn "*anddi_1"
7682 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7683 (and:DI
7684 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7685 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7686 (clobber (reg:CC FLAGS_REG))]
7687 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7688 {
7689 switch (get_attr_type (insn))
7690 {
7691 case TYPE_IMOVX:
7692 {
7693 enum machine_mode mode;
7694
7695 gcc_assert (CONST_INT_P (operands[2]));
7696 if (INTVAL (operands[2]) == 0xff)
7697 mode = QImode;
7698 else
7699 {
7700 gcc_assert (INTVAL (operands[2]) == 0xffff);
7701 mode = HImode;
7702 }
7703
7704 operands[1] = gen_lowpart (mode, operands[1]);
7705 if (mode == QImode)
7706 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7707 else
7708 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7709 }
7710
7711 default:
7712 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7713 if (get_attr_mode (insn) == MODE_SI)
7714 return "and{l}\t{%k2, %k0|%k0, %k2}";
7715 else
7716 return "and{q}\t{%2, %0|%0, %2}";
7717 }
7718 }
7719 [(set_attr "type" "alu,alu,alu,imovx")
7720 (set_attr "length_immediate" "*,*,*,0")
7721 (set (attr "prefix_rex")
7722 (if_then_else
7723 (and (eq_attr "type" "imovx")
7724 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7725 (match_operand 1 "ext_QIreg_operand" "")))
7726 (const_string "1")
7727 (const_string "*")))
7728 (set_attr "mode" "SI,DI,DI,SI")])
7729
7730 (define_insn "*andsi_1"
7731 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7732 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7733 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7734 (clobber (reg:CC FLAGS_REG))]
7735 "ix86_binary_operator_ok (AND, SImode, operands)"
7736 {
7737 switch (get_attr_type (insn))
7738 {
7739 case TYPE_IMOVX:
7740 {
7741 enum machine_mode mode;
7742
7743 gcc_assert (CONST_INT_P (operands[2]));
7744 if (INTVAL (operands[2]) == 0xff)
7745 mode = QImode;
7746 else
7747 {
7748 gcc_assert (INTVAL (operands[2]) == 0xffff);
7749 mode = HImode;
7750 }
7751
7752 operands[1] = gen_lowpart (mode, operands[1]);
7753 if (mode == QImode)
7754 return "movz{bl|x}\t{%1, %0|%0, %1}";
7755 else
7756 return "movz{wl|x}\t{%1, %0|%0, %1}";
7757 }
7758
7759 default:
7760 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7761 return "and{l}\t{%2, %0|%0, %2}";
7762 }
7763 }
7764 [(set_attr "type" "alu,alu,imovx")
7765 (set (attr "prefix_rex")
7766 (if_then_else
7767 (and (eq_attr "type" "imovx")
7768 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7769 (match_operand 1 "ext_QIreg_operand" "")))
7770 (const_string "1")
7771 (const_string "*")))
7772 (set_attr "length_immediate" "*,*,0")
7773 (set_attr "mode" "SI")])
7774
7775 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7776 (define_insn "*andsi_1_zext"
7777 [(set (match_operand:DI 0 "register_operand" "=r")
7778 (zero_extend:DI
7779 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7780 (match_operand:SI 2 "general_operand" "g"))))
7781 (clobber (reg:CC FLAGS_REG))]
7782 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7783 "and{l}\t{%2, %k0|%k0, %2}"
7784 [(set_attr "type" "alu")
7785 (set_attr "mode" "SI")])
7786
7787 (define_insn "*andhi_1"
7788 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7789 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7790 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7791 (clobber (reg:CC FLAGS_REG))]
7792 "ix86_binary_operator_ok (AND, HImode, operands)"
7793 {
7794 switch (get_attr_type (insn))
7795 {
7796 case TYPE_IMOVX:
7797 gcc_assert (CONST_INT_P (operands[2]));
7798 gcc_assert (INTVAL (operands[2]) == 0xff);
7799 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7800
7801 default:
7802 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7803
7804 return "and{w}\t{%2, %0|%0, %2}";
7805 }
7806 }
7807 [(set_attr "type" "alu,alu,imovx")
7808 (set_attr "length_immediate" "*,*,0")
7809 (set (attr "prefix_rex")
7810 (if_then_else
7811 (and (eq_attr "type" "imovx")
7812 (match_operand 1 "ext_QIreg_operand" ""))
7813 (const_string "1")
7814 (const_string "*")))
7815 (set_attr "mode" "HI,HI,SI")])
7816
7817 ;; %%% Potential partial reg stall on alternative 2. What to do?
7818 (define_insn "*andqi_1"
7819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7820 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7821 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7822 (clobber (reg:CC FLAGS_REG))]
7823 "ix86_binary_operator_ok (AND, QImode, operands)"
7824 "@
7825 and{b}\t{%2, %0|%0, %2}
7826 and{b}\t{%2, %0|%0, %2}
7827 and{l}\t{%k2, %k0|%k0, %k2}"
7828 [(set_attr "type" "alu")
7829 (set_attr "mode" "QI,QI,SI")])
7830
7831 (define_insn "*andqi_1_slp"
7832 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7833 (and:QI (match_dup 0)
7834 (match_operand:QI 1 "general_operand" "qn,qmn")))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7837 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7838 "and{b}\t{%1, %0|%0, %1}"
7839 [(set_attr "type" "alu1")
7840 (set_attr "mode" "QI")])
7841
7842 (define_split
7843 [(set (match_operand 0 "register_operand" "")
7844 (and (match_dup 0)
7845 (const_int -65536)))
7846 (clobber (reg:CC FLAGS_REG))]
7847 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7848 || optimize_function_for_size_p (cfun)"
7849 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7850 "operands[1] = gen_lowpart (HImode, operands[0]);")
7851
7852 (define_split
7853 [(set (match_operand 0 "ext_register_operand" "")
7854 (and (match_dup 0)
7855 (const_int -256)))
7856 (clobber (reg:CC FLAGS_REG))]
7857 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7858 && reload_completed"
7859 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7860 "operands[1] = gen_lowpart (QImode, operands[0]);")
7861
7862 (define_split
7863 [(set (match_operand 0 "ext_register_operand" "")
7864 (and (match_dup 0)
7865 (const_int -65281)))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7868 && reload_completed"
7869 [(parallel [(set (zero_extract:SI (match_dup 0)
7870 (const_int 8)
7871 (const_int 8))
7872 (xor:SI
7873 (zero_extract:SI (match_dup 0)
7874 (const_int 8)
7875 (const_int 8))
7876 (zero_extract:SI (match_dup 0)
7877 (const_int 8)
7878 (const_int 8))))
7879 (clobber (reg:CC FLAGS_REG))])]
7880 "operands[0] = gen_lowpart (SImode, operands[0]);")
7881
7882 (define_insn "*anddi_2"
7883 [(set (reg FLAGS_REG)
7884 (compare
7885 (and:DI
7886 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7887 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7888 (const_int 0)))
7889 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7890 (and:DI (match_dup 1) (match_dup 2)))]
7891 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7892 && ix86_binary_operator_ok (AND, DImode, operands)"
7893 "@
7894 and{l}\t{%k2, %k0|%k0, %k2}
7895 and{q}\t{%2, %0|%0, %2}
7896 and{q}\t{%2, %0|%0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "SI,DI,DI")])
7899
7900 (define_insn "*andqi_2_maybe_si"
7901 [(set (reg FLAGS_REG)
7902 (compare (and:QI
7903 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7904 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7905 (const_int 0)))
7906 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7907 (and:QI (match_dup 1) (match_dup 2)))]
7908 "ix86_binary_operator_ok (AND, QImode, operands)
7909 && ix86_match_ccmode (insn,
7910 CONST_INT_P (operands[2])
7911 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7912 {
7913 if (which_alternative == 2)
7914 {
7915 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7916 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7917 return "and{l}\t{%2, %k0|%k0, %2}";
7918 }
7919 return "and{b}\t{%2, %0|%0, %2}";
7920 }
7921 [(set_attr "type" "alu")
7922 (set_attr "mode" "QI,QI,SI")])
7923
7924 (define_insn "*and<mode>_2"
7925 [(set (reg FLAGS_REG)
7926 (compare (and:SWI124
7927 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7928 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7929 (const_int 0)))
7930 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7931 (and:SWI124 (match_dup 1) (match_dup 2)))]
7932 "ix86_match_ccmode (insn, CCNOmode)
7933 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7934 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7935 [(set_attr "type" "alu")
7936 (set_attr "mode" "<MODE>")])
7937
7938 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7939 (define_insn "*andsi_2_zext"
7940 [(set (reg FLAGS_REG)
7941 (compare (and:SI
7942 (match_operand:SI 1 "nonimmediate_operand" "%0")
7943 (match_operand:SI 2 "general_operand" "g"))
7944 (const_int 0)))
7945 (set (match_operand:DI 0 "register_operand" "=r")
7946 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7947 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7948 && ix86_binary_operator_ok (AND, SImode, operands)"
7949 "and{l}\t{%2, %k0|%k0, %2}"
7950 [(set_attr "type" "alu")
7951 (set_attr "mode" "SI")])
7952
7953 (define_insn "*andqi_2_slp"
7954 [(set (reg FLAGS_REG)
7955 (compare (and:QI
7956 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7957 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7958 (const_int 0)))
7959 (set (strict_low_part (match_dup 0))
7960 (and:QI (match_dup 0) (match_dup 1)))]
7961 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7962 && ix86_match_ccmode (insn, CCNOmode)
7963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7964 "and{b}\t{%1, %0|%0, %1}"
7965 [(set_attr "type" "alu1")
7966 (set_attr "mode" "QI")])
7967
7968 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7969 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7970 ;; for a QImode operand, which of course failed.
7971 (define_insn "andqi_ext_0"
7972 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7973 (const_int 8)
7974 (const_int 8))
7975 (and:SI
7976 (zero_extract:SI
7977 (match_operand 1 "ext_register_operand" "0")
7978 (const_int 8)
7979 (const_int 8))
7980 (match_operand 2 "const_int_operand" "n")))
7981 (clobber (reg:CC FLAGS_REG))]
7982 ""
7983 "and{b}\t{%2, %h0|%h0, %2}"
7984 [(set_attr "type" "alu")
7985 (set_attr "length_immediate" "1")
7986 (set_attr "modrm" "1")
7987 (set_attr "mode" "QI")])
7988
7989 ;; Generated by peephole translating test to and. This shows up
7990 ;; often in fp comparisons.
7991 (define_insn "*andqi_ext_0_cc"
7992 [(set (reg FLAGS_REG)
7993 (compare
7994 (and:SI
7995 (zero_extract:SI
7996 (match_operand 1 "ext_register_operand" "0")
7997 (const_int 8)
7998 (const_int 8))
7999 (match_operand 2 "const_int_operand" "n"))
8000 (const_int 0)))
8001 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8002 (const_int 8)
8003 (const_int 8))
8004 (and:SI
8005 (zero_extract:SI
8006 (match_dup 1)
8007 (const_int 8)
8008 (const_int 8))
8009 (match_dup 2)))]
8010 "ix86_match_ccmode (insn, CCNOmode)"
8011 "and{b}\t{%2, %h0|%h0, %2}"
8012 [(set_attr "type" "alu")
8013 (set_attr "length_immediate" "1")
8014 (set_attr "modrm" "1")
8015 (set_attr "mode" "QI")])
8016
8017 (define_insn "*andqi_ext_1_rex64"
8018 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8019 (const_int 8)
8020 (const_int 8))
8021 (and:SI
8022 (zero_extract:SI
8023 (match_operand 1 "ext_register_operand" "0")
8024 (const_int 8)
8025 (const_int 8))
8026 (zero_extend:SI
8027 (match_operand 2 "ext_register_operand" "Q"))))
8028 (clobber (reg:CC FLAGS_REG))]
8029 "TARGET_64BIT"
8030 "and{b}\t{%2, %h0|%h0, %2}"
8031 [(set_attr "type" "alu")
8032 (set_attr "length_immediate" "0")
8033 (set_attr "mode" "QI")])
8034
8035 (define_insn "*andqi_ext_1"
8036 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8037 (const_int 8)
8038 (const_int 8))
8039 (and:SI
8040 (zero_extract:SI
8041 (match_operand 1 "ext_register_operand" "0")
8042 (const_int 8)
8043 (const_int 8))
8044 (zero_extend:SI
8045 (match_operand:QI 2 "general_operand" "Qm"))))
8046 (clobber (reg:CC FLAGS_REG))]
8047 "!TARGET_64BIT"
8048 "and{b}\t{%2, %h0|%h0, %2}"
8049 [(set_attr "type" "alu")
8050 (set_attr "length_immediate" "0")
8051 (set_attr "mode" "QI")])
8052
8053 (define_insn "*andqi_ext_2"
8054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8055 (const_int 8)
8056 (const_int 8))
8057 (and:SI
8058 (zero_extract:SI
8059 (match_operand 1 "ext_register_operand" "%0")
8060 (const_int 8)
8061 (const_int 8))
8062 (zero_extract:SI
8063 (match_operand 2 "ext_register_operand" "Q")
8064 (const_int 8)
8065 (const_int 8))))
8066 (clobber (reg:CC FLAGS_REG))]
8067 ""
8068 "and{b}\t{%h2, %h0|%h0, %h2}"
8069 [(set_attr "type" "alu")
8070 (set_attr "length_immediate" "0")
8071 (set_attr "mode" "QI")])
8072
8073 ;; Convert wide AND instructions with immediate operand to shorter QImode
8074 ;; equivalents when possible.
8075 ;; Don't do the splitting with memory operands, since it introduces risk
8076 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8077 ;; for size, but that can (should?) be handled by generic code instead.
8078 (define_split
8079 [(set (match_operand 0 "register_operand" "")
8080 (and (match_operand 1 "register_operand" "")
8081 (match_operand 2 "const_int_operand" "")))
8082 (clobber (reg:CC FLAGS_REG))]
8083 "reload_completed
8084 && QI_REG_P (operands[0])
8085 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086 && !(~INTVAL (operands[2]) & ~(255 << 8))
8087 && GET_MODE (operands[0]) != QImode"
8088 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8089 (and:SI (zero_extract:SI (match_dup 1)
8090 (const_int 8) (const_int 8))
8091 (match_dup 2)))
8092 (clobber (reg:CC FLAGS_REG))])]
8093 "operands[0] = gen_lowpart (SImode, operands[0]);
8094 operands[1] = gen_lowpart (SImode, operands[1]);
8095 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8096
8097 ;; Since AND can be encoded with sign extended immediate, this is only
8098 ;; profitable when 7th bit is not set.
8099 (define_split
8100 [(set (match_operand 0 "register_operand" "")
8101 (and (match_operand 1 "general_operand" "")
8102 (match_operand 2 "const_int_operand" "")))
8103 (clobber (reg:CC FLAGS_REG))]
8104 "reload_completed
8105 && ANY_QI_REG_P (operands[0])
8106 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8107 && !(~INTVAL (operands[2]) & ~255)
8108 && !(INTVAL (operands[2]) & 128)
8109 && GET_MODE (operands[0]) != QImode"
8110 [(parallel [(set (strict_low_part (match_dup 0))
8111 (and:QI (match_dup 1)
8112 (match_dup 2)))
8113 (clobber (reg:CC FLAGS_REG))])]
8114 "operands[0] = gen_lowpart (QImode, operands[0]);
8115 operands[1] = gen_lowpart (QImode, operands[1]);
8116 operands[2] = gen_lowpart (QImode, operands[2]);")
8117 \f
8118 ;; Logical inclusive and exclusive OR instructions
8119
8120 ;; %%% This used to optimize known byte-wide and operations to memory.
8121 ;; If this is considered useful, it should be done with splitters.
8122
8123 (define_expand "<code><mode>3"
8124 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8125 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8126 (match_operand:SWIM 2 "<general_operand>" "")))]
8127 ""
8128 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8129
8130 (define_insn "*<code><mode>_1"
8131 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8132 (any_or:SWI248
8133 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8134 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8137 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8138 [(set_attr "type" "alu")
8139 (set_attr "mode" "<MODE>")])
8140
8141 ;; %%% Potential partial reg stall on alternative 2. What to do?
8142 (define_insn "*<code>qi_1"
8143 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8144 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8145 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8146 (clobber (reg:CC FLAGS_REG))]
8147 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8148 "@
8149 <logic>{b}\t{%2, %0|%0, %2}
8150 <logic>{b}\t{%2, %0|%0, %2}
8151 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "mode" "QI,QI,SI")])
8154
8155 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8156 (define_insn "*<code>si_1_zext"
8157 [(set (match_operand:DI 0 "register_operand" "=r")
8158 (zero_extend:DI
8159 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8160 (match_operand:SI 2 "general_operand" "g"))))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8163 "<logic>{l}\t{%2, %k0|%k0, %2}"
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "SI")])
8166
8167 (define_insn "*<code>si_1_zext_imm"
8168 [(set (match_operand:DI 0 "register_operand" "=r")
8169 (any_or:DI
8170 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8171 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8172 (clobber (reg:CC FLAGS_REG))]
8173 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8174 "<logic>{l}\t{%2, %k0|%k0, %2}"
8175 [(set_attr "type" "alu")
8176 (set_attr "mode" "SI")])
8177
8178 (define_insn "*<code>qi_1_slp"
8179 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8180 (any_or:QI (match_dup 0)
8181 (match_operand:QI 1 "general_operand" "qmn,qn")))
8182 (clobber (reg:CC FLAGS_REG))]
8183 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8184 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8185 "<logic>{b}\t{%1, %0|%0, %1}"
8186 [(set_attr "type" "alu1")
8187 (set_attr "mode" "QI")])
8188
8189 (define_insn "*<code><mode>_2"
8190 [(set (reg FLAGS_REG)
8191 (compare (any_or:SWI
8192 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8193 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8194 (const_int 0)))
8195 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8196 (any_or:SWI (match_dup 1) (match_dup 2)))]
8197 "ix86_match_ccmode (insn, CCNOmode)
8198 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8199 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "mode" "<MODE>")])
8202
8203 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8204 ;; ??? Special case for immediate operand is missing - it is tricky.
8205 (define_insn "*<code>si_2_zext"
8206 [(set (reg FLAGS_REG)
8207 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8208 (match_operand:SI 2 "general_operand" "g"))
8209 (const_int 0)))
8210 (set (match_operand:DI 0 "register_operand" "=r")
8211 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8212 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8213 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8214 "<logic>{l}\t{%2, %k0|%k0, %2}"
8215 [(set_attr "type" "alu")
8216 (set_attr "mode" "SI")])
8217
8218 (define_insn "*<code>si_2_zext_imm"
8219 [(set (reg FLAGS_REG)
8220 (compare (any_or:SI
8221 (match_operand:SI 1 "nonimmediate_operand" "%0")
8222 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8223 (const_int 0)))
8224 (set (match_operand:DI 0 "register_operand" "=r")
8225 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8226 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8227 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8228 "<logic>{l}\t{%2, %k0|%k0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "mode" "SI")])
8231
8232 (define_insn "*<code>qi_2_slp"
8233 [(set (reg FLAGS_REG)
8234 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8235 (match_operand:QI 1 "general_operand" "qmn,qn"))
8236 (const_int 0)))
8237 (set (strict_low_part (match_dup 0))
8238 (any_or:QI (match_dup 0) (match_dup 1)))]
8239 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8240 && ix86_match_ccmode (insn, CCNOmode)
8241 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8242 "<logic>{b}\t{%1, %0|%0, %1}"
8243 [(set_attr "type" "alu1")
8244 (set_attr "mode" "QI")])
8245
8246 (define_insn "*<code><mode>_3"
8247 [(set (reg FLAGS_REG)
8248 (compare (any_or:SWI
8249 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8250 (match_operand:SWI 2 "<general_operand>" "<g>"))
8251 (const_int 0)))
8252 (clobber (match_scratch:SWI 0 "=<r>"))]
8253 "ix86_match_ccmode (insn, CCNOmode)
8254 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8255 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8256 [(set_attr "type" "alu")
8257 (set_attr "mode" "<MODE>")])
8258
8259 (define_insn "*<code>qi_ext_0"
8260 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8261 (const_int 8)
8262 (const_int 8))
8263 (any_or:SI
8264 (zero_extract:SI
8265 (match_operand 1 "ext_register_operand" "0")
8266 (const_int 8)
8267 (const_int 8))
8268 (match_operand 2 "const_int_operand" "n")))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8271 "<logic>{b}\t{%2, %h0|%h0, %2}"
8272 [(set_attr "type" "alu")
8273 (set_attr "length_immediate" "1")
8274 (set_attr "modrm" "1")
8275 (set_attr "mode" "QI")])
8276
8277 (define_insn "*<code>qi_ext_1_rex64"
8278 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8279 (const_int 8)
8280 (const_int 8))
8281 (any_or:SI
8282 (zero_extract:SI
8283 (match_operand 1 "ext_register_operand" "0")
8284 (const_int 8)
8285 (const_int 8))
8286 (zero_extend:SI
8287 (match_operand 2 "ext_register_operand" "Q"))))
8288 (clobber (reg:CC FLAGS_REG))]
8289 "TARGET_64BIT
8290 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8291 "<logic>{b}\t{%2, %h0|%h0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "length_immediate" "0")
8294 (set_attr "mode" "QI")])
8295
8296 (define_insn "*<code>qi_ext_1"
8297 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8298 (const_int 8)
8299 (const_int 8))
8300 (any_or:SI
8301 (zero_extract:SI
8302 (match_operand 1 "ext_register_operand" "0")
8303 (const_int 8)
8304 (const_int 8))
8305 (zero_extend:SI
8306 (match_operand:QI 2 "general_operand" "Qm"))))
8307 (clobber (reg:CC FLAGS_REG))]
8308 "!TARGET_64BIT
8309 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8310 "<logic>{b}\t{%2, %h0|%h0, %2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "length_immediate" "0")
8313 (set_attr "mode" "QI")])
8314
8315 (define_insn "*<code>qi_ext_2"
8316 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8317 (const_int 8)
8318 (const_int 8))
8319 (any_or:SI
8320 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8321 (const_int 8)
8322 (const_int 8))
8323 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8324 (const_int 8)
8325 (const_int 8))))
8326 (clobber (reg:CC FLAGS_REG))]
8327 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8328 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "length_immediate" "0")
8331 (set_attr "mode" "QI")])
8332
8333 (define_split
8334 [(set (match_operand 0 "register_operand" "")
8335 (any_or (match_operand 1 "register_operand" "")
8336 (match_operand 2 "const_int_operand" "")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "reload_completed
8339 && QI_REG_P (operands[0])
8340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8341 && !(INTVAL (operands[2]) & ~(255 << 8))
8342 && GET_MODE (operands[0]) != QImode"
8343 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8344 (any_or:SI (zero_extract:SI (match_dup 1)
8345 (const_int 8) (const_int 8))
8346 (match_dup 2)))
8347 (clobber (reg:CC FLAGS_REG))])]
8348 "operands[0] = gen_lowpart (SImode, operands[0]);
8349 operands[1] = gen_lowpart (SImode, operands[1]);
8350 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8351
8352 ;; Since OR can be encoded with sign extended immediate, this is only
8353 ;; profitable when 7th bit is set.
8354 (define_split
8355 [(set (match_operand 0 "register_operand" "")
8356 (any_or (match_operand 1 "general_operand" "")
8357 (match_operand 2 "const_int_operand" "")))
8358 (clobber (reg:CC FLAGS_REG))]
8359 "reload_completed
8360 && ANY_QI_REG_P (operands[0])
8361 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8362 && !(INTVAL (operands[2]) & ~255)
8363 && (INTVAL (operands[2]) & 128)
8364 && GET_MODE (operands[0]) != QImode"
8365 [(parallel [(set (strict_low_part (match_dup 0))
8366 (any_or:QI (match_dup 1)
8367 (match_dup 2)))
8368 (clobber (reg:CC FLAGS_REG))])]
8369 "operands[0] = gen_lowpart (QImode, operands[0]);
8370 operands[1] = gen_lowpart (QImode, operands[1]);
8371 operands[2] = gen_lowpart (QImode, operands[2]);")
8372
8373 (define_expand "xorqi_cc_ext_1"
8374 [(parallel [
8375 (set (reg:CCNO FLAGS_REG)
8376 (compare:CCNO
8377 (xor:SI
8378 (zero_extract:SI
8379 (match_operand 1 "ext_register_operand" "")
8380 (const_int 8)
8381 (const_int 8))
8382 (match_operand:QI 2 "general_operand" ""))
8383 (const_int 0)))
8384 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8385 (const_int 8)
8386 (const_int 8))
8387 (xor:SI
8388 (zero_extract:SI
8389 (match_dup 1)
8390 (const_int 8)
8391 (const_int 8))
8392 (match_dup 2)))])])
8393
8394 (define_insn "*xorqi_cc_ext_1_rex64"
8395 [(set (reg FLAGS_REG)
8396 (compare
8397 (xor:SI
8398 (zero_extract:SI
8399 (match_operand 1 "ext_register_operand" "0")
8400 (const_int 8)
8401 (const_int 8))
8402 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8403 (const_int 0)))
8404 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405 (const_int 8)
8406 (const_int 8))
8407 (xor:SI
8408 (zero_extract:SI
8409 (match_dup 1)
8410 (const_int 8)
8411 (const_int 8))
8412 (match_dup 2)))]
8413 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8414 "xor{b}\t{%2, %h0|%h0, %2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "modrm" "1")
8417 (set_attr "mode" "QI")])
8418
8419 (define_insn "*xorqi_cc_ext_1"
8420 [(set (reg FLAGS_REG)
8421 (compare
8422 (xor:SI
8423 (zero_extract:SI
8424 (match_operand 1 "ext_register_operand" "0")
8425 (const_int 8)
8426 (const_int 8))
8427 (match_operand:QI 2 "general_operand" "qmn"))
8428 (const_int 0)))
8429 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8430 (const_int 8)
8431 (const_int 8))
8432 (xor:SI
8433 (zero_extract:SI
8434 (match_dup 1)
8435 (const_int 8)
8436 (const_int 8))
8437 (match_dup 2)))]
8438 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8439 "xor{b}\t{%2, %h0|%h0, %2}"
8440 [(set_attr "type" "alu")
8441 (set_attr "modrm" "1")
8442 (set_attr "mode" "QI")])
8443 \f
8444 ;; Negation instructions
8445
8446 (define_expand "neg<mode>2"
8447 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8448 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8449 ""
8450 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8451
8452 (define_insn_and_split "*neg<dwi>2_doubleword"
8453 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8454 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8455 (clobber (reg:CC FLAGS_REG))]
8456 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8457 "#"
8458 "reload_completed"
8459 [(parallel
8460 [(set (reg:CCZ FLAGS_REG)
8461 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8462 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8463 (parallel
8464 [(set (match_dup 2)
8465 (plus:DWIH (match_dup 3)
8466 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8467 (const_int 0))))
8468 (clobber (reg:CC FLAGS_REG))])
8469 (parallel
8470 [(set (match_dup 2)
8471 (neg:DWIH (match_dup 2)))
8472 (clobber (reg:CC FLAGS_REG))])]
8473 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8474
8475 (define_insn "*neg<mode>2_1"
8476 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8477 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8480 "neg{<imodesuffix>}\t%0"
8481 [(set_attr "type" "negnot")
8482 (set_attr "mode" "<MODE>")])
8483
8484 ;; Combine is quite creative about this pattern.
8485 (define_insn "*negsi2_1_zext"
8486 [(set (match_operand:DI 0 "register_operand" "=r")
8487 (lshiftrt:DI
8488 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8489 (const_int 32)))
8490 (const_int 32)))
8491 (clobber (reg:CC FLAGS_REG))]
8492 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8493 "neg{l}\t%k0"
8494 [(set_attr "type" "negnot")
8495 (set_attr "mode" "SI")])
8496
8497 ;; The problem with neg is that it does not perform (compare x 0),
8498 ;; it really performs (compare 0 x), which leaves us with the zero
8499 ;; flag being the only useful item.
8500
8501 (define_insn "*neg<mode>2_cmpz"
8502 [(set (reg:CCZ FLAGS_REG)
8503 (compare:CCZ
8504 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8505 (const_int 0)))
8506 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8507 (neg:SWI (match_dup 1)))]
8508 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8509 "neg{<imodesuffix>}\t%0"
8510 [(set_attr "type" "negnot")
8511 (set_attr "mode" "<MODE>")])
8512
8513 (define_insn "*negsi2_cmpz_zext"
8514 [(set (reg:CCZ FLAGS_REG)
8515 (compare:CCZ
8516 (lshiftrt:DI
8517 (neg:DI (ashift:DI
8518 (match_operand:DI 1 "register_operand" "0")
8519 (const_int 32)))
8520 (const_int 32))
8521 (const_int 0)))
8522 (set (match_operand:DI 0 "register_operand" "=r")
8523 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8524 (const_int 32)))
8525 (const_int 32)))]
8526 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8527 "neg{l}\t%k0"
8528 [(set_attr "type" "negnot")
8529 (set_attr "mode" "SI")])
8530
8531 ;; Changing of sign for FP values is doable using integer unit too.
8532
8533 (define_expand "<code><mode>2"
8534 [(set (match_operand:X87MODEF 0 "register_operand" "")
8535 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8536 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8537 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8538
8539 (define_insn "*absneg<mode>2_mixed"
8540 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8541 (match_operator:MODEF 3 "absneg_operator"
8542 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8543 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8544 (clobber (reg:CC FLAGS_REG))]
8545 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8546 "#")
8547
8548 (define_insn "*absneg<mode>2_sse"
8549 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8550 (match_operator:MODEF 3 "absneg_operator"
8551 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8552 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8555 "#")
8556
8557 (define_insn "*absneg<mode>2_i387"
8558 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8559 (match_operator:X87MODEF 3 "absneg_operator"
8560 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8561 (use (match_operand 2 "" ""))
8562 (clobber (reg:CC FLAGS_REG))]
8563 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8564 "#")
8565
8566 (define_expand "<code>tf2"
8567 [(set (match_operand:TF 0 "register_operand" "")
8568 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8569 "TARGET_SSE2"
8570 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8571
8572 (define_insn "*absnegtf2_sse"
8573 [(set (match_operand:TF 0 "register_operand" "=x,x")
8574 (match_operator:TF 3 "absneg_operator"
8575 [(match_operand:TF 1 "register_operand" "0,x")]))
8576 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8577 (clobber (reg:CC FLAGS_REG))]
8578 "TARGET_SSE2"
8579 "#")
8580
8581 ;; Splitters for fp abs and neg.
8582
8583 (define_split
8584 [(set (match_operand 0 "fp_register_operand" "")
8585 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8586 (use (match_operand 2 "" ""))
8587 (clobber (reg:CC FLAGS_REG))]
8588 "reload_completed"
8589 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8590
8591 (define_split
8592 [(set (match_operand 0 "register_operand" "")
8593 (match_operator 3 "absneg_operator"
8594 [(match_operand 1 "register_operand" "")]))
8595 (use (match_operand 2 "nonimmediate_operand" ""))
8596 (clobber (reg:CC FLAGS_REG))]
8597 "reload_completed && SSE_REG_P (operands[0])"
8598 [(set (match_dup 0) (match_dup 3))]
8599 {
8600 enum machine_mode mode = GET_MODE (operands[0]);
8601 enum machine_mode vmode = GET_MODE (operands[2]);
8602 rtx tmp;
8603
8604 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8605 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8606 if (operands_match_p (operands[0], operands[2]))
8607 {
8608 tmp = operands[1];
8609 operands[1] = operands[2];
8610 operands[2] = tmp;
8611 }
8612 if (GET_CODE (operands[3]) == ABS)
8613 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8614 else
8615 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8616 operands[3] = tmp;
8617 })
8618
8619 (define_split
8620 [(set (match_operand:SF 0 "register_operand" "")
8621 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8622 (use (match_operand:V4SF 2 "" ""))
8623 (clobber (reg:CC FLAGS_REG))]
8624 "reload_completed"
8625 [(parallel [(set (match_dup 0) (match_dup 1))
8626 (clobber (reg:CC FLAGS_REG))])]
8627 {
8628 rtx tmp;
8629 operands[0] = gen_lowpart (SImode, operands[0]);
8630 if (GET_CODE (operands[1]) == ABS)
8631 {
8632 tmp = gen_int_mode (0x7fffffff, SImode);
8633 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8634 }
8635 else
8636 {
8637 tmp = gen_int_mode (0x80000000, SImode);
8638 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8639 }
8640 operands[1] = tmp;
8641 })
8642
8643 (define_split
8644 [(set (match_operand:DF 0 "register_operand" "")
8645 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8646 (use (match_operand 2 "" ""))
8647 (clobber (reg:CC FLAGS_REG))]
8648 "reload_completed"
8649 [(parallel [(set (match_dup 0) (match_dup 1))
8650 (clobber (reg:CC FLAGS_REG))])]
8651 {
8652 rtx tmp;
8653 if (TARGET_64BIT)
8654 {
8655 tmp = gen_lowpart (DImode, operands[0]);
8656 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8657 operands[0] = tmp;
8658
8659 if (GET_CODE (operands[1]) == ABS)
8660 tmp = const0_rtx;
8661 else
8662 tmp = gen_rtx_NOT (DImode, tmp);
8663 }
8664 else
8665 {
8666 operands[0] = gen_highpart (SImode, operands[0]);
8667 if (GET_CODE (operands[1]) == ABS)
8668 {
8669 tmp = gen_int_mode (0x7fffffff, SImode);
8670 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8671 }
8672 else
8673 {
8674 tmp = gen_int_mode (0x80000000, SImode);
8675 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8676 }
8677 }
8678 operands[1] = tmp;
8679 })
8680
8681 (define_split
8682 [(set (match_operand:XF 0 "register_operand" "")
8683 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8684 (use (match_operand 2 "" ""))
8685 (clobber (reg:CC FLAGS_REG))]
8686 "reload_completed"
8687 [(parallel [(set (match_dup 0) (match_dup 1))
8688 (clobber (reg:CC FLAGS_REG))])]
8689 {
8690 rtx tmp;
8691 operands[0] = gen_rtx_REG (SImode,
8692 true_regnum (operands[0])
8693 + (TARGET_64BIT ? 1 : 2));
8694 if (GET_CODE (operands[1]) == ABS)
8695 {
8696 tmp = GEN_INT (0x7fff);
8697 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8698 }
8699 else
8700 {
8701 tmp = GEN_INT (0x8000);
8702 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8703 }
8704 operands[1] = tmp;
8705 })
8706
8707 ;; Conditionalize these after reload. If they match before reload, we
8708 ;; lose the clobber and ability to use integer instructions.
8709
8710 (define_insn "*<code><mode>2_1"
8711 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8712 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8713 "TARGET_80387
8714 && (reload_completed
8715 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8716 "f<absneg_mnemonic>"
8717 [(set_attr "type" "fsgn")
8718 (set_attr "mode" "<MODE>")])
8719
8720 (define_insn "*<code>extendsfdf2"
8721 [(set (match_operand:DF 0 "register_operand" "=f")
8722 (absneg:DF (float_extend:DF
8723 (match_operand:SF 1 "register_operand" "0"))))]
8724 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8725 "f<absneg_mnemonic>"
8726 [(set_attr "type" "fsgn")
8727 (set_attr "mode" "DF")])
8728
8729 (define_insn "*<code>extendsfxf2"
8730 [(set (match_operand:XF 0 "register_operand" "=f")
8731 (absneg:XF (float_extend:XF
8732 (match_operand:SF 1 "register_operand" "0"))))]
8733 "TARGET_80387"
8734 "f<absneg_mnemonic>"
8735 [(set_attr "type" "fsgn")
8736 (set_attr "mode" "XF")])
8737
8738 (define_insn "*<code>extenddfxf2"
8739 [(set (match_operand:XF 0 "register_operand" "=f")
8740 (absneg:XF (float_extend:XF
8741 (match_operand:DF 1 "register_operand" "0"))))]
8742 "TARGET_80387"
8743 "f<absneg_mnemonic>"
8744 [(set_attr "type" "fsgn")
8745 (set_attr "mode" "XF")])
8746
8747 ;; Copysign instructions
8748
8749 (define_mode_iterator CSGNMODE [SF DF TF])
8750 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8751
8752 (define_expand "copysign<mode>3"
8753 [(match_operand:CSGNMODE 0 "register_operand" "")
8754 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8755 (match_operand:CSGNMODE 2 "register_operand" "")]
8756 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8757 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8758 "ix86_expand_copysign (operands); DONE;")
8759
8760 (define_insn_and_split "copysign<mode>3_const"
8761 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8762 (unspec:CSGNMODE
8763 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8764 (match_operand:CSGNMODE 2 "register_operand" "0")
8765 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8766 UNSPEC_COPYSIGN))]
8767 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8768 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8769 "#"
8770 "&& reload_completed"
8771 [(const_int 0)]
8772 "ix86_split_copysign_const (operands); DONE;")
8773
8774 (define_insn "copysign<mode>3_var"
8775 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8776 (unspec:CSGNMODE
8777 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8778 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8779 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8780 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8781 UNSPEC_COPYSIGN))
8782 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8783 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8784 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8785 "#")
8786
8787 (define_split
8788 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8789 (unspec:CSGNMODE
8790 [(match_operand:CSGNMODE 2 "register_operand" "")
8791 (match_operand:CSGNMODE 3 "register_operand" "")
8792 (match_operand:<CSGNVMODE> 4 "" "")
8793 (match_operand:<CSGNVMODE> 5 "" "")]
8794 UNSPEC_COPYSIGN))
8795 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8796 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8797 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8798 && reload_completed"
8799 [(const_int 0)]
8800 "ix86_split_copysign_var (operands); DONE;")
8801 \f
8802 ;; One complement instructions
8803
8804 (define_expand "one_cmpl<mode>2"
8805 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8806 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8807 ""
8808 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8809
8810 (define_insn "*one_cmpl<mode>2_1"
8811 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8812 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8813 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8814 "not{<imodesuffix>}\t%0"
8815 [(set_attr "type" "negnot")
8816 (set_attr "mode" "<MODE>")])
8817
8818 ;; %%% Potential partial reg stall on alternative 1. What to do?
8819 (define_insn "*one_cmplqi2_1"
8820 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8821 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8822 "ix86_unary_operator_ok (NOT, QImode, operands)"
8823 "@
8824 not{b}\t%0
8825 not{l}\t%k0"
8826 [(set_attr "type" "negnot")
8827 (set_attr "mode" "QI,SI")])
8828
8829 ;; ??? Currently never generated - xor is used instead.
8830 (define_insn "*one_cmplsi2_1_zext"
8831 [(set (match_operand:DI 0 "register_operand" "=r")
8832 (zero_extend:DI
8833 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8834 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8835 "not{l}\t%k0"
8836 [(set_attr "type" "negnot")
8837 (set_attr "mode" "SI")])
8838
8839 (define_insn "*one_cmpl<mode>2_2"
8840 [(set (reg FLAGS_REG)
8841 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8842 (const_int 0)))
8843 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8844 (not:SWI (match_dup 1)))]
8845 "ix86_match_ccmode (insn, CCNOmode)
8846 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8847 "#"
8848 [(set_attr "type" "alu1")
8849 (set_attr "mode" "<MODE>")])
8850
8851 (define_split
8852 [(set (match_operand 0 "flags_reg_operand" "")
8853 (match_operator 2 "compare_operator"
8854 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8855 (const_int 0)]))
8856 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8857 (not:SWI (match_dup 3)))]
8858 "ix86_match_ccmode (insn, CCNOmode)"
8859 [(parallel [(set (match_dup 0)
8860 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8861 (const_int 0)]))
8862 (set (match_dup 1)
8863 (xor:SWI (match_dup 3) (const_int -1)))])])
8864
8865 ;; ??? Currently never generated - xor is used instead.
8866 (define_insn "*one_cmplsi2_2_zext"
8867 [(set (reg FLAGS_REG)
8868 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8869 (const_int 0)))
8870 (set (match_operand:DI 0 "register_operand" "=r")
8871 (zero_extend:DI (not:SI (match_dup 1))))]
8872 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8873 && ix86_unary_operator_ok (NOT, SImode, operands)"
8874 "#"
8875 [(set_attr "type" "alu1")
8876 (set_attr "mode" "SI")])
8877
8878 (define_split
8879 [(set (match_operand 0 "flags_reg_operand" "")
8880 (match_operator 2 "compare_operator"
8881 [(not:SI (match_operand:SI 3 "register_operand" ""))
8882 (const_int 0)]))
8883 (set (match_operand:DI 1 "register_operand" "")
8884 (zero_extend:DI (not:SI (match_dup 3))))]
8885 "ix86_match_ccmode (insn, CCNOmode)"
8886 [(parallel [(set (match_dup 0)
8887 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8888 (const_int 0)]))
8889 (set (match_dup 1)
8890 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8891 \f
8892 ;; Shift instructions
8893
8894 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8895 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8896 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8897 ;; from the assembler input.
8898 ;;
8899 ;; This instruction shifts the target reg/mem as usual, but instead of
8900 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8901 ;; is a left shift double, bits are taken from the high order bits of
8902 ;; reg, else if the insn is a shift right double, bits are taken from the
8903 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8904 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8905 ;;
8906 ;; Since sh[lr]d does not change the `reg' operand, that is done
8907 ;; separately, making all shifts emit pairs of shift double and normal
8908 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8909 ;; support a 63 bit shift, each shift where the count is in a reg expands
8910 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8911 ;;
8912 ;; If the shift count is a constant, we need never emit more than one
8913 ;; shift pair, instead using moves and sign extension for counts greater
8914 ;; than 31.
8915
8916 (define_expand "ashl<mode>3"
8917 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8918 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8919 (match_operand:QI 2 "nonmemory_operand" "")))]
8920 ""
8921 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8922
8923 (define_insn "*ashl<mode>3_doubleword"
8924 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8925 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8926 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8927 (clobber (reg:CC FLAGS_REG))]
8928 ""
8929 "#"
8930 [(set_attr "type" "multi")])
8931
8932 (define_split
8933 [(set (match_operand:DWI 0 "register_operand" "")
8934 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8935 (match_operand:QI 2 "nonmemory_operand" "")))
8936 (clobber (reg:CC FLAGS_REG))]
8937 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8938 [(const_int 0)]
8939 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8940
8941 ;; By default we don't ask for a scratch register, because when DWImode
8942 ;; values are manipulated, registers are already at a premium. But if
8943 ;; we have one handy, we won't turn it away.
8944
8945 (define_peephole2
8946 [(match_scratch:DWIH 3 "r")
8947 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8948 (ashift:<DWI>
8949 (match_operand:<DWI> 1 "nonmemory_operand" "")
8950 (match_operand:QI 2 "nonmemory_operand" "")))
8951 (clobber (reg:CC FLAGS_REG))])
8952 (match_dup 3)]
8953 "TARGET_CMOVE"
8954 [(const_int 0)]
8955 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8956
8957 (define_insn "x86_64_shld"
8958 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8959 (ior:DI (ashift:DI (match_dup 0)
8960 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8961 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8962 (minus:QI (const_int 64) (match_dup 2)))))
8963 (clobber (reg:CC FLAGS_REG))]
8964 "TARGET_64BIT"
8965 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8966 [(set_attr "type" "ishift")
8967 (set_attr "prefix_0f" "1")
8968 (set_attr "mode" "DI")
8969 (set_attr "athlon_decode" "vector")
8970 (set_attr "amdfam10_decode" "vector")
8971 (set_attr "bdver1_decode" "vector")])
8972
8973 (define_insn "x86_shld"
8974 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8975 (ior:SI (ashift:SI (match_dup 0)
8976 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8977 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8978 (minus:QI (const_int 32) (match_dup 2)))))
8979 (clobber (reg:CC FLAGS_REG))]
8980 ""
8981 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8982 [(set_attr "type" "ishift")
8983 (set_attr "prefix_0f" "1")
8984 (set_attr "mode" "SI")
8985 (set_attr "pent_pair" "np")
8986 (set_attr "athlon_decode" "vector")
8987 (set_attr "amdfam10_decode" "vector")
8988 (set_attr "bdver1_decode" "vector")])
8989
8990 (define_expand "x86_shift<mode>_adj_1"
8991 [(set (reg:CCZ FLAGS_REG)
8992 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8993 (match_dup 4))
8994 (const_int 0)))
8995 (set (match_operand:SWI48 0 "register_operand" "")
8996 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8997 (match_operand:SWI48 1 "register_operand" "")
8998 (match_dup 0)))
8999 (set (match_dup 1)
9000 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9001 (match_operand:SWI48 3 "register_operand" "r")
9002 (match_dup 1)))]
9003 "TARGET_CMOVE"
9004 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9005
9006 (define_expand "x86_shift<mode>_adj_2"
9007 [(use (match_operand:SWI48 0 "register_operand" ""))
9008 (use (match_operand:SWI48 1 "register_operand" ""))
9009 (use (match_operand:QI 2 "register_operand" ""))]
9010 ""
9011 {
9012 rtx label = gen_label_rtx ();
9013 rtx tmp;
9014
9015 emit_insn (gen_testqi_ccz_1 (operands[2],
9016 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9017
9018 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9019 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9020 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9021 gen_rtx_LABEL_REF (VOIDmode, label),
9022 pc_rtx);
9023 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9024 JUMP_LABEL (tmp) = label;
9025
9026 emit_move_insn (operands[0], operands[1]);
9027 ix86_expand_clear (operands[1]);
9028
9029 emit_label (label);
9030 LABEL_NUSES (label) = 1;
9031
9032 DONE;
9033 })
9034
9035 ;; Avoid useless masking of count operand.
9036 (define_insn_and_split "*ashl<mode>3_mask"
9037 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9038 (ashift:SWI48
9039 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9040 (subreg:QI
9041 (and:SI
9042 (match_operand:SI 2 "nonimmediate_operand" "c")
9043 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9044 (clobber (reg:CC FLAGS_REG))]
9045 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9046 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9047 == GET_MODE_BITSIZE (<MODE>mode)-1"
9048 "#"
9049 "&& 1"
9050 [(parallel [(set (match_dup 0)
9051 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9052 (clobber (reg:CC FLAGS_REG))])]
9053 {
9054 if (can_create_pseudo_p ())
9055 operands [2] = force_reg (SImode, operands[2]);
9056
9057 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9058 }
9059 [(set_attr "type" "ishift")
9060 (set_attr "mode" "<MODE>")])
9061
9062 (define_insn "*ashl<mode>3_1"
9063 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9064 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9065 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9066 (clobber (reg:CC FLAGS_REG))]
9067 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9068 {
9069 switch (get_attr_type (insn))
9070 {
9071 case TYPE_LEA:
9072 return "#";
9073
9074 case TYPE_ALU:
9075 gcc_assert (operands[2] == const1_rtx);
9076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9077 return "add{<imodesuffix>}\t%0, %0";
9078
9079 default:
9080 if (operands[2] == const1_rtx
9081 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9082 return "sal{<imodesuffix>}\t%0";
9083 else
9084 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9085 }
9086 }
9087 [(set (attr "type")
9088 (cond [(eq_attr "alternative" "1")
9089 (const_string "lea")
9090 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9091 (const_int 0))
9092 (match_operand 0 "register_operand" ""))
9093 (match_operand 2 "const1_operand" ""))
9094 (const_string "alu")
9095 ]
9096 (const_string "ishift")))
9097 (set (attr "length_immediate")
9098 (if_then_else
9099 (ior (eq_attr "type" "alu")
9100 (and (eq_attr "type" "ishift")
9101 (and (match_operand 2 "const1_operand" "")
9102 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9103 (const_int 0)))))
9104 (const_string "0")
9105 (const_string "*")))
9106 (set_attr "mode" "<MODE>")])
9107
9108 (define_insn "*ashlsi3_1_zext"
9109 [(set (match_operand:DI 0 "register_operand" "=r,r")
9110 (zero_extend:DI
9111 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9112 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9113 (clobber (reg:CC FLAGS_REG))]
9114 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9115 {
9116 switch (get_attr_type (insn))
9117 {
9118 case TYPE_LEA:
9119 return "#";
9120
9121 case TYPE_ALU:
9122 gcc_assert (operands[2] == const1_rtx);
9123 return "add{l}\t%k0, %k0";
9124
9125 default:
9126 if (operands[2] == const1_rtx
9127 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9128 return "sal{l}\t%k0";
9129 else
9130 return "sal{l}\t{%2, %k0|%k0, %2}";
9131 }
9132 }
9133 [(set (attr "type")
9134 (cond [(eq_attr "alternative" "1")
9135 (const_string "lea")
9136 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9137 (const_int 0))
9138 (match_operand 2 "const1_operand" ""))
9139 (const_string "alu")
9140 ]
9141 (const_string "ishift")))
9142 (set (attr "length_immediate")
9143 (if_then_else
9144 (ior (eq_attr "type" "alu")
9145 (and (eq_attr "type" "ishift")
9146 (and (match_operand 2 "const1_operand" "")
9147 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9148 (const_int 0)))))
9149 (const_string "0")
9150 (const_string "*")))
9151 (set_attr "mode" "SI")])
9152
9153 (define_insn "*ashlhi3_1"
9154 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9155 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9156 (match_operand:QI 2 "nonmemory_operand" "cI")))
9157 (clobber (reg:CC FLAGS_REG))]
9158 "TARGET_PARTIAL_REG_STALL
9159 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9160 {
9161 switch (get_attr_type (insn))
9162 {
9163 case TYPE_ALU:
9164 gcc_assert (operands[2] == const1_rtx);
9165 return "add{w}\t%0, %0";
9166
9167 default:
9168 if (operands[2] == const1_rtx
9169 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9170 return "sal{w}\t%0";
9171 else
9172 return "sal{w}\t{%2, %0|%0, %2}";
9173 }
9174 }
9175 [(set (attr "type")
9176 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9177 (const_int 0))
9178 (match_operand 0 "register_operand" ""))
9179 (match_operand 2 "const1_operand" ""))
9180 (const_string "alu")
9181 ]
9182 (const_string "ishift")))
9183 (set (attr "length_immediate")
9184 (if_then_else
9185 (ior (eq_attr "type" "alu")
9186 (and (eq_attr "type" "ishift")
9187 (and (match_operand 2 "const1_operand" "")
9188 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9189 (const_int 0)))))
9190 (const_string "0")
9191 (const_string "*")))
9192 (set_attr "mode" "HI")])
9193
9194 (define_insn "*ashlhi3_1_lea"
9195 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9196 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9197 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9198 (clobber (reg:CC FLAGS_REG))]
9199 "!TARGET_PARTIAL_REG_STALL
9200 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9201 {
9202 switch (get_attr_type (insn))
9203 {
9204 case TYPE_LEA:
9205 return "#";
9206
9207 case TYPE_ALU:
9208 gcc_assert (operands[2] == const1_rtx);
9209 return "add{w}\t%0, %0";
9210
9211 default:
9212 if (operands[2] == const1_rtx
9213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9214 return "sal{w}\t%0";
9215 else
9216 return "sal{w}\t{%2, %0|%0, %2}";
9217 }
9218 }
9219 [(set (attr "type")
9220 (cond [(eq_attr "alternative" "1")
9221 (const_string "lea")
9222 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9223 (const_int 0))
9224 (match_operand 0 "register_operand" ""))
9225 (match_operand 2 "const1_operand" ""))
9226 (const_string "alu")
9227 ]
9228 (const_string "ishift")))
9229 (set (attr "length_immediate")
9230 (if_then_else
9231 (ior (eq_attr "type" "alu")
9232 (and (eq_attr "type" "ishift")
9233 (and (match_operand 2 "const1_operand" "")
9234 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9235 (const_int 0)))))
9236 (const_string "0")
9237 (const_string "*")))
9238 (set_attr "mode" "HI,SI")])
9239
9240 (define_insn "*ashlqi3_1"
9241 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9242 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9243 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9244 (clobber (reg:CC FLAGS_REG))]
9245 "TARGET_PARTIAL_REG_STALL
9246 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9247 {
9248 switch (get_attr_type (insn))
9249 {
9250 case TYPE_ALU:
9251 gcc_assert (operands[2] == const1_rtx);
9252 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9253 return "add{l}\t%k0, %k0";
9254 else
9255 return "add{b}\t%0, %0";
9256
9257 default:
9258 if (operands[2] == const1_rtx
9259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9260 {
9261 if (get_attr_mode (insn) == MODE_SI)
9262 return "sal{l}\t%k0";
9263 else
9264 return "sal{b}\t%0";
9265 }
9266 else
9267 {
9268 if (get_attr_mode (insn) == MODE_SI)
9269 return "sal{l}\t{%2, %k0|%k0, %2}";
9270 else
9271 return "sal{b}\t{%2, %0|%0, %2}";
9272 }
9273 }
9274 }
9275 [(set (attr "type")
9276 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9277 (const_int 0))
9278 (match_operand 0 "register_operand" ""))
9279 (match_operand 2 "const1_operand" ""))
9280 (const_string "alu")
9281 ]
9282 (const_string "ishift")))
9283 (set (attr "length_immediate")
9284 (if_then_else
9285 (ior (eq_attr "type" "alu")
9286 (and (eq_attr "type" "ishift")
9287 (and (match_operand 2 "const1_operand" "")
9288 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9289 (const_int 0)))))
9290 (const_string "0")
9291 (const_string "*")))
9292 (set_attr "mode" "QI,SI")])
9293
9294 ;; %%% Potential partial reg stall on alternative 2. What to do?
9295 (define_insn "*ashlqi3_1_lea"
9296 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9297 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9298 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9299 (clobber (reg:CC FLAGS_REG))]
9300 "!TARGET_PARTIAL_REG_STALL
9301 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9302 {
9303 switch (get_attr_type (insn))
9304 {
9305 case TYPE_LEA:
9306 return "#";
9307
9308 case TYPE_ALU:
9309 gcc_assert (operands[2] == const1_rtx);
9310 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9311 return "add{l}\t%k0, %k0";
9312 else
9313 return "add{b}\t%0, %0";
9314
9315 default:
9316 if (operands[2] == const1_rtx
9317 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9318 {
9319 if (get_attr_mode (insn) == MODE_SI)
9320 return "sal{l}\t%k0";
9321 else
9322 return "sal{b}\t%0";
9323 }
9324 else
9325 {
9326 if (get_attr_mode (insn) == MODE_SI)
9327 return "sal{l}\t{%2, %k0|%k0, %2}";
9328 else
9329 return "sal{b}\t{%2, %0|%0, %2}";
9330 }
9331 }
9332 }
9333 [(set (attr "type")
9334 (cond [(eq_attr "alternative" "2")
9335 (const_string "lea")
9336 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9337 (const_int 0))
9338 (match_operand 0 "register_operand" ""))
9339 (match_operand 2 "const1_operand" ""))
9340 (const_string "alu")
9341 ]
9342 (const_string "ishift")))
9343 (set (attr "length_immediate")
9344 (if_then_else
9345 (ior (eq_attr "type" "alu")
9346 (and (eq_attr "type" "ishift")
9347 (and (match_operand 2 "const1_operand" "")
9348 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9349 (const_int 0)))))
9350 (const_string "0")
9351 (const_string "*")))
9352 (set_attr "mode" "QI,SI,SI")])
9353
9354 (define_insn "*ashlqi3_1_slp"
9355 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9356 (ashift:QI (match_dup 0)
9357 (match_operand:QI 1 "nonmemory_operand" "cI")))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "(optimize_function_for_size_p (cfun)
9360 || !TARGET_PARTIAL_FLAG_REG_STALL
9361 || (operands[1] == const1_rtx
9362 && (TARGET_SHIFT1
9363 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9364 {
9365 switch (get_attr_type (insn))
9366 {
9367 case TYPE_ALU:
9368 gcc_assert (operands[1] == const1_rtx);
9369 return "add{b}\t%0, %0";
9370
9371 default:
9372 if (operands[1] == const1_rtx
9373 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9374 return "sal{b}\t%0";
9375 else
9376 return "sal{b}\t{%1, %0|%0, %1}";
9377 }
9378 }
9379 [(set (attr "type")
9380 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9381 (const_int 0))
9382 (match_operand 0 "register_operand" ""))
9383 (match_operand 1 "const1_operand" ""))
9384 (const_string "alu")
9385 ]
9386 (const_string "ishift1")))
9387 (set (attr "length_immediate")
9388 (if_then_else
9389 (ior (eq_attr "type" "alu")
9390 (and (eq_attr "type" "ishift1")
9391 (and (match_operand 1 "const1_operand" "")
9392 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9393 (const_int 0)))))
9394 (const_string "0")
9395 (const_string "*")))
9396 (set_attr "mode" "QI")])
9397
9398 ;; Convert lea to the lea pattern to avoid flags dependency.
9399 (define_split
9400 [(set (match_operand 0 "register_operand" "")
9401 (ashift (match_operand 1 "index_register_operand" "")
9402 (match_operand:QI 2 "const_int_operand" "")))
9403 (clobber (reg:CC FLAGS_REG))]
9404 "reload_completed
9405 && true_regnum (operands[0]) != true_regnum (operands[1])"
9406 [(const_int 0)]
9407 {
9408 rtx pat;
9409 enum machine_mode mode = GET_MODE (operands[0]);
9410
9411 if (mode != Pmode)
9412 operands[1] = gen_lowpart (Pmode, operands[1]);
9413 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9414
9415 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9416
9417 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9418 operands[0] = gen_lowpart (SImode, operands[0]);
9419
9420 if (TARGET_64BIT && mode != Pmode)
9421 pat = gen_rtx_SUBREG (SImode, pat, 0);
9422
9423 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9424 DONE;
9425 })
9426
9427 ;; Convert lea to the lea pattern to avoid flags dependency.
9428 (define_split
9429 [(set (match_operand:DI 0 "register_operand" "")
9430 (zero_extend:DI
9431 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9432 (match_operand:QI 2 "const_int_operand" ""))))
9433 (clobber (reg:CC FLAGS_REG))]
9434 "TARGET_64BIT && reload_completed
9435 && true_regnum (operands[0]) != true_regnum (operands[1])"
9436 [(set (match_dup 0)
9437 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9438 {
9439 operands[1] = gen_lowpart (DImode, operands[1]);
9440 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9441 })
9442
9443 ;; This pattern can't accept a variable shift count, since shifts by
9444 ;; zero don't affect the flags. We assume that shifts by constant
9445 ;; zero are optimized away.
9446 (define_insn "*ashl<mode>3_cmp"
9447 [(set (reg FLAGS_REG)
9448 (compare
9449 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9450 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9451 (const_int 0)))
9452 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9453 (ashift:SWI (match_dup 1) (match_dup 2)))]
9454 "(optimize_function_for_size_p (cfun)
9455 || !TARGET_PARTIAL_FLAG_REG_STALL
9456 || (operands[2] == const1_rtx
9457 && (TARGET_SHIFT1
9458 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9459 && ix86_match_ccmode (insn, CCGOCmode)
9460 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9461 {
9462 switch (get_attr_type (insn))
9463 {
9464 case TYPE_ALU:
9465 gcc_assert (operands[2] == const1_rtx);
9466 return "add{<imodesuffix>}\t%0, %0";
9467
9468 default:
9469 if (operands[2] == const1_rtx
9470 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9471 return "sal{<imodesuffix>}\t%0";
9472 else
9473 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9474 }
9475 }
9476 [(set (attr "type")
9477 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9478 (const_int 0))
9479 (match_operand 0 "register_operand" ""))
9480 (match_operand 2 "const1_operand" ""))
9481 (const_string "alu")
9482 ]
9483 (const_string "ishift")))
9484 (set (attr "length_immediate")
9485 (if_then_else
9486 (ior (eq_attr "type" "alu")
9487 (and (eq_attr "type" "ishift")
9488 (and (match_operand 2 "const1_operand" "")
9489 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9490 (const_int 0)))))
9491 (const_string "0")
9492 (const_string "*")))
9493 (set_attr "mode" "<MODE>")])
9494
9495 (define_insn "*ashlsi3_cmp_zext"
9496 [(set (reg FLAGS_REG)
9497 (compare
9498 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9499 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9500 (const_int 0)))
9501 (set (match_operand:DI 0 "register_operand" "=r")
9502 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9503 "TARGET_64BIT
9504 && (optimize_function_for_size_p (cfun)
9505 || !TARGET_PARTIAL_FLAG_REG_STALL
9506 || (operands[2] == const1_rtx
9507 && (TARGET_SHIFT1
9508 || TARGET_DOUBLE_WITH_ADD)))
9509 && ix86_match_ccmode (insn, CCGOCmode)
9510 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9511 {
9512 switch (get_attr_type (insn))
9513 {
9514 case TYPE_ALU:
9515 gcc_assert (operands[2] == const1_rtx);
9516 return "add{l}\t%k0, %k0";
9517
9518 default:
9519 if (operands[2] == const1_rtx
9520 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9521 return "sal{l}\t%k0";
9522 else
9523 return "sal{l}\t{%2, %k0|%k0, %2}";
9524 }
9525 }
9526 [(set (attr "type")
9527 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9528 (const_int 0))
9529 (match_operand 2 "const1_operand" ""))
9530 (const_string "alu")
9531 ]
9532 (const_string "ishift")))
9533 (set (attr "length_immediate")
9534 (if_then_else
9535 (ior (eq_attr "type" "alu")
9536 (and (eq_attr "type" "ishift")
9537 (and (match_operand 2 "const1_operand" "")
9538 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9539 (const_int 0)))))
9540 (const_string "0")
9541 (const_string "*")))
9542 (set_attr "mode" "SI")])
9543
9544 (define_insn "*ashl<mode>3_cconly"
9545 [(set (reg FLAGS_REG)
9546 (compare
9547 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9548 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9549 (const_int 0)))
9550 (clobber (match_scratch:SWI 0 "=<r>"))]
9551 "(optimize_function_for_size_p (cfun)
9552 || !TARGET_PARTIAL_FLAG_REG_STALL
9553 || (operands[2] == const1_rtx
9554 && (TARGET_SHIFT1
9555 || TARGET_DOUBLE_WITH_ADD)))
9556 && ix86_match_ccmode (insn, CCGOCmode)"
9557 {
9558 switch (get_attr_type (insn))
9559 {
9560 case TYPE_ALU:
9561 gcc_assert (operands[2] == const1_rtx);
9562 return "add{<imodesuffix>}\t%0, %0";
9563
9564 default:
9565 if (operands[2] == const1_rtx
9566 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9567 return "sal{<imodesuffix>}\t%0";
9568 else
9569 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9570 }
9571 }
9572 [(set (attr "type")
9573 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9574 (const_int 0))
9575 (match_operand 0 "register_operand" ""))
9576 (match_operand 2 "const1_operand" ""))
9577 (const_string "alu")
9578 ]
9579 (const_string "ishift")))
9580 (set (attr "length_immediate")
9581 (if_then_else
9582 (ior (eq_attr "type" "alu")
9583 (and (eq_attr "type" "ishift")
9584 (and (match_operand 2 "const1_operand" "")
9585 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9586 (const_int 0)))))
9587 (const_string "0")
9588 (const_string "*")))
9589 (set_attr "mode" "<MODE>")])
9590
9591 ;; See comment above `ashl<mode>3' about how this works.
9592
9593 (define_expand "<shiftrt_insn><mode>3"
9594 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9595 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9596 (match_operand:QI 2 "nonmemory_operand" "")))]
9597 ""
9598 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9599
9600 ;; Avoid useless masking of count operand.
9601 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9602 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9603 (any_shiftrt:SWI48
9604 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9605 (subreg:QI
9606 (and:SI
9607 (match_operand:SI 2 "nonimmediate_operand" "c")
9608 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9609 (clobber (reg:CC FLAGS_REG))]
9610 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9611 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9612 == GET_MODE_BITSIZE (<MODE>mode)-1"
9613 "#"
9614 "&& 1"
9615 [(parallel [(set (match_dup 0)
9616 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9617 (clobber (reg:CC FLAGS_REG))])]
9618 {
9619 if (can_create_pseudo_p ())
9620 operands [2] = force_reg (SImode, operands[2]);
9621
9622 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9623 }
9624 [(set_attr "type" "ishift")
9625 (set_attr "mode" "<MODE>")])
9626
9627 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9628 [(set (match_operand:DWI 0 "register_operand" "=r")
9629 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9630 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9631 (clobber (reg:CC FLAGS_REG))]
9632 ""
9633 "#"
9634 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9635 [(const_int 0)]
9636 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9637 [(set_attr "type" "multi")])
9638
9639 ;; By default we don't ask for a scratch register, because when DWImode
9640 ;; values are manipulated, registers are already at a premium. But if
9641 ;; we have one handy, we won't turn it away.
9642
9643 (define_peephole2
9644 [(match_scratch:DWIH 3 "r")
9645 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9646 (any_shiftrt:<DWI>
9647 (match_operand:<DWI> 1 "register_operand" "")
9648 (match_operand:QI 2 "nonmemory_operand" "")))
9649 (clobber (reg:CC FLAGS_REG))])
9650 (match_dup 3)]
9651 "TARGET_CMOVE"
9652 [(const_int 0)]
9653 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9654
9655 (define_insn "x86_64_shrd"
9656 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9657 (ior:DI (ashiftrt:DI (match_dup 0)
9658 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9659 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9660 (minus:QI (const_int 64) (match_dup 2)))))
9661 (clobber (reg:CC FLAGS_REG))]
9662 "TARGET_64BIT"
9663 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9664 [(set_attr "type" "ishift")
9665 (set_attr "prefix_0f" "1")
9666 (set_attr "mode" "DI")
9667 (set_attr "athlon_decode" "vector")
9668 (set_attr "amdfam10_decode" "vector")
9669 (set_attr "bdver1_decode" "vector")])
9670
9671 (define_insn "x86_shrd"
9672 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9673 (ior:SI (ashiftrt:SI (match_dup 0)
9674 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9675 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9676 (minus:QI (const_int 32) (match_dup 2)))))
9677 (clobber (reg:CC FLAGS_REG))]
9678 ""
9679 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9680 [(set_attr "type" "ishift")
9681 (set_attr "prefix_0f" "1")
9682 (set_attr "mode" "SI")
9683 (set_attr "pent_pair" "np")
9684 (set_attr "athlon_decode" "vector")
9685 (set_attr "amdfam10_decode" "vector")
9686 (set_attr "bdver1_decode" "vector")])
9687
9688 (define_insn "ashrdi3_cvt"
9689 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9690 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9691 (match_operand:QI 2 "const_int_operand" "")))
9692 (clobber (reg:CC FLAGS_REG))]
9693 "TARGET_64BIT && INTVAL (operands[2]) == 63
9694 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9695 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9696 "@
9697 {cqto|cqo}
9698 sar{q}\t{%2, %0|%0, %2}"
9699 [(set_attr "type" "imovx,ishift")
9700 (set_attr "prefix_0f" "0,*")
9701 (set_attr "length_immediate" "0,*")
9702 (set_attr "modrm" "0,1")
9703 (set_attr "mode" "DI")])
9704
9705 (define_insn "ashrsi3_cvt"
9706 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9707 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9708 (match_operand:QI 2 "const_int_operand" "")))
9709 (clobber (reg:CC FLAGS_REG))]
9710 "INTVAL (operands[2]) == 31
9711 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9712 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9713 "@
9714 {cltd|cdq}
9715 sar{l}\t{%2, %0|%0, %2}"
9716 [(set_attr "type" "imovx,ishift")
9717 (set_attr "prefix_0f" "0,*")
9718 (set_attr "length_immediate" "0,*")
9719 (set_attr "modrm" "0,1")
9720 (set_attr "mode" "SI")])
9721
9722 (define_insn "*ashrsi3_cvt_zext"
9723 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9724 (zero_extend:DI
9725 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9726 (match_operand:QI 2 "const_int_operand" ""))))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "TARGET_64BIT && INTVAL (operands[2]) == 31
9729 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9730 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9731 "@
9732 {cltd|cdq}
9733 sar{l}\t{%2, %k0|%k0, %2}"
9734 [(set_attr "type" "imovx,ishift")
9735 (set_attr "prefix_0f" "0,*")
9736 (set_attr "length_immediate" "0,*")
9737 (set_attr "modrm" "0,1")
9738 (set_attr "mode" "SI")])
9739
9740 (define_expand "x86_shift<mode>_adj_3"
9741 [(use (match_operand:SWI48 0 "register_operand" ""))
9742 (use (match_operand:SWI48 1 "register_operand" ""))
9743 (use (match_operand:QI 2 "register_operand" ""))]
9744 ""
9745 {
9746 rtx label = gen_label_rtx ();
9747 rtx tmp;
9748
9749 emit_insn (gen_testqi_ccz_1 (operands[2],
9750 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9751
9752 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9753 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9754 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9755 gen_rtx_LABEL_REF (VOIDmode, label),
9756 pc_rtx);
9757 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9758 JUMP_LABEL (tmp) = label;
9759
9760 emit_move_insn (operands[0], operands[1]);
9761 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9762 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9763 emit_label (label);
9764 LABEL_NUSES (label) = 1;
9765
9766 DONE;
9767 })
9768
9769 (define_insn "*<shiftrt_insn><mode>3_1"
9770 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9771 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9772 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9775 {
9776 if (operands[2] == const1_rtx
9777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9778 return "<shiftrt>{<imodesuffix>}\t%0";
9779 else
9780 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9781 }
9782 [(set_attr "type" "ishift")
9783 (set (attr "length_immediate")
9784 (if_then_else
9785 (and (match_operand 2 "const1_operand" "")
9786 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9787 (const_int 0)))
9788 (const_string "0")
9789 (const_string "*")))
9790 (set_attr "mode" "<MODE>")])
9791
9792 (define_insn "*<shiftrt_insn>si3_1_zext"
9793 [(set (match_operand:DI 0 "register_operand" "=r")
9794 (zero_extend:DI
9795 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9796 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9799 {
9800 if (operands[2] == const1_rtx
9801 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9802 return "<shiftrt>{l}\t%k0";
9803 else
9804 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9805 }
9806 [(set_attr "type" "ishift")
9807 (set (attr "length_immediate")
9808 (if_then_else
9809 (and (match_operand 2 "const1_operand" "")
9810 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9811 (const_int 0)))
9812 (const_string "0")
9813 (const_string "*")))
9814 (set_attr "mode" "SI")])
9815
9816 (define_insn "*<shiftrt_insn>qi3_1_slp"
9817 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9818 (any_shiftrt:QI (match_dup 0)
9819 (match_operand:QI 1 "nonmemory_operand" "cI")))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "(optimize_function_for_size_p (cfun)
9822 || !TARGET_PARTIAL_REG_STALL
9823 || (operands[1] == const1_rtx
9824 && TARGET_SHIFT1))"
9825 {
9826 if (operands[1] == const1_rtx
9827 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9828 return "<shiftrt>{b}\t%0";
9829 else
9830 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9831 }
9832 [(set_attr "type" "ishift1")
9833 (set (attr "length_immediate")
9834 (if_then_else
9835 (and (match_operand 1 "const1_operand" "")
9836 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9837 (const_int 0)))
9838 (const_string "0")
9839 (const_string "*")))
9840 (set_attr "mode" "QI")])
9841
9842 ;; This pattern can't accept a variable shift count, since shifts by
9843 ;; zero don't affect the flags. We assume that shifts by constant
9844 ;; zero are optimized away.
9845 (define_insn "*<shiftrt_insn><mode>3_cmp"
9846 [(set (reg FLAGS_REG)
9847 (compare
9848 (any_shiftrt:SWI
9849 (match_operand:SWI 1 "nonimmediate_operand" "0")
9850 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9851 (const_int 0)))
9852 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9853 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9854 "(optimize_function_for_size_p (cfun)
9855 || !TARGET_PARTIAL_FLAG_REG_STALL
9856 || (operands[2] == const1_rtx
9857 && TARGET_SHIFT1))
9858 && ix86_match_ccmode (insn, CCGOCmode)
9859 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9860 {
9861 if (operands[2] == const1_rtx
9862 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9863 return "<shiftrt>{<imodesuffix>}\t%0";
9864 else
9865 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9866 }
9867 [(set_attr "type" "ishift")
9868 (set (attr "length_immediate")
9869 (if_then_else
9870 (and (match_operand 2 "const1_operand" "")
9871 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9872 (const_int 0)))
9873 (const_string "0")
9874 (const_string "*")))
9875 (set_attr "mode" "<MODE>")])
9876
9877 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9878 [(set (reg FLAGS_REG)
9879 (compare
9880 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9881 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9882 (const_int 0)))
9883 (set (match_operand:DI 0 "register_operand" "=r")
9884 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9885 "TARGET_64BIT
9886 && (optimize_function_for_size_p (cfun)
9887 || !TARGET_PARTIAL_FLAG_REG_STALL
9888 || (operands[2] == const1_rtx
9889 && TARGET_SHIFT1))
9890 && ix86_match_ccmode (insn, CCGOCmode)
9891 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9892 {
9893 if (operands[2] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 return "<shiftrt>{l}\t%k0";
9896 else
9897 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9898 }
9899 [(set_attr "type" "ishift")
9900 (set (attr "length_immediate")
9901 (if_then_else
9902 (and (match_operand 2 "const1_operand" "")
9903 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9904 (const_int 0)))
9905 (const_string "0")
9906 (const_string "*")))
9907 (set_attr "mode" "SI")])
9908
9909 (define_insn "*<shiftrt_insn><mode>3_cconly"
9910 [(set (reg FLAGS_REG)
9911 (compare
9912 (any_shiftrt:SWI
9913 (match_operand:SWI 1 "register_operand" "0")
9914 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9915 (const_int 0)))
9916 (clobber (match_scratch:SWI 0 "=<r>"))]
9917 "(optimize_function_for_size_p (cfun)
9918 || !TARGET_PARTIAL_FLAG_REG_STALL
9919 || (operands[2] == const1_rtx
9920 && TARGET_SHIFT1))
9921 && ix86_match_ccmode (insn, CCGOCmode)"
9922 {
9923 if (operands[2] == const1_rtx
9924 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9925 return "<shiftrt>{<imodesuffix>}\t%0";
9926 else
9927 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9928 }
9929 [(set_attr "type" "ishift")
9930 (set (attr "length_immediate")
9931 (if_then_else
9932 (and (match_operand 2 "const1_operand" "")
9933 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9934 (const_int 0)))
9935 (const_string "0")
9936 (const_string "*")))
9937 (set_attr "mode" "<MODE>")])
9938 \f
9939 ;; Rotate instructions
9940
9941 (define_expand "<rotate_insn>ti3"
9942 [(set (match_operand:TI 0 "register_operand" "")
9943 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9944 (match_operand:QI 2 "nonmemory_operand" "")))]
9945 "TARGET_64BIT"
9946 {
9947 if (const_1_to_63_operand (operands[2], VOIDmode))
9948 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9949 (operands[0], operands[1], operands[2]));
9950 else
9951 FAIL;
9952
9953 DONE;
9954 })
9955
9956 (define_expand "<rotate_insn>di3"
9957 [(set (match_operand:DI 0 "shiftdi_operand" "")
9958 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9959 (match_operand:QI 2 "nonmemory_operand" "")))]
9960 ""
9961 {
9962 if (TARGET_64BIT)
9963 ix86_expand_binary_operator (<CODE>, DImode, operands);
9964 else if (const_1_to_31_operand (operands[2], VOIDmode))
9965 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9966 (operands[0], operands[1], operands[2]));
9967 else
9968 FAIL;
9969
9970 DONE;
9971 })
9972
9973 (define_expand "<rotate_insn><mode>3"
9974 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9975 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9976 (match_operand:QI 2 "nonmemory_operand" "")))]
9977 ""
9978 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9979
9980 ;; Avoid useless masking of count operand.
9981 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9982 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9983 (any_rotate:SWI48
9984 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9985 (subreg:QI
9986 (and:SI
9987 (match_operand:SI 2 "nonimmediate_operand" "c")
9988 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9989 (clobber (reg:CC FLAGS_REG))]
9990 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9991 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9992 == GET_MODE_BITSIZE (<MODE>mode)-1"
9993 "#"
9994 "&& 1"
9995 [(parallel [(set (match_dup 0)
9996 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9997 (clobber (reg:CC FLAGS_REG))])]
9998 {
9999 if (can_create_pseudo_p ())
10000 operands [2] = force_reg (SImode, operands[2]);
10001
10002 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10003 }
10004 [(set_attr "type" "rotate")
10005 (set_attr "mode" "<MODE>")])
10006
10007 ;; Implement rotation using two double-precision
10008 ;; shift instructions and a scratch register.
10009
10010 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10011 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10012 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10013 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10014 (clobber (reg:CC FLAGS_REG))
10015 (clobber (match_scratch:DWIH 3 "=&r"))]
10016 ""
10017 "#"
10018 "reload_completed"
10019 [(set (match_dup 3) (match_dup 4))
10020 (parallel
10021 [(set (match_dup 4)
10022 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10023 (lshiftrt:DWIH (match_dup 5)
10024 (minus:QI (match_dup 6) (match_dup 2)))))
10025 (clobber (reg:CC FLAGS_REG))])
10026 (parallel
10027 [(set (match_dup 5)
10028 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10029 (lshiftrt:DWIH (match_dup 3)
10030 (minus:QI (match_dup 6) (match_dup 2)))))
10031 (clobber (reg:CC FLAGS_REG))])]
10032 {
10033 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10034
10035 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10036 })
10037
10038 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10039 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10040 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10041 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10042 (clobber (reg:CC FLAGS_REG))
10043 (clobber (match_scratch:DWIH 3 "=&r"))]
10044 ""
10045 "#"
10046 "reload_completed"
10047 [(set (match_dup 3) (match_dup 4))
10048 (parallel
10049 [(set (match_dup 4)
10050 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10051 (ashift:DWIH (match_dup 5)
10052 (minus:QI (match_dup 6) (match_dup 2)))))
10053 (clobber (reg:CC FLAGS_REG))])
10054 (parallel
10055 [(set (match_dup 5)
10056 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10057 (ashift:DWIH (match_dup 3)
10058 (minus:QI (match_dup 6) (match_dup 2)))))
10059 (clobber (reg:CC FLAGS_REG))])]
10060 {
10061 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10062
10063 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10064 })
10065
10066 (define_insn "*<rotate_insn><mode>3_1"
10067 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10068 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10069 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10072 {
10073 if (operands[2] == const1_rtx
10074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10075 return "<rotate>{<imodesuffix>}\t%0";
10076 else
10077 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10078 }
10079 [(set_attr "type" "rotate")
10080 (set (attr "length_immediate")
10081 (if_then_else
10082 (and (match_operand 2 "const1_operand" "")
10083 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10084 (const_int 0)))
10085 (const_string "0")
10086 (const_string "*")))
10087 (set_attr "mode" "<MODE>")])
10088
10089 (define_insn "*<rotate_insn>si3_1_zext"
10090 [(set (match_operand:DI 0 "register_operand" "=r")
10091 (zero_extend:DI
10092 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10093 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10096 {
10097 if (operands[2] == const1_rtx
10098 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10099 return "<rotate>{l}\t%k0";
10100 else
10101 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10102 }
10103 [(set_attr "type" "rotate")
10104 (set (attr "length_immediate")
10105 (if_then_else
10106 (and (match_operand 2 "const1_operand" "")
10107 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10108 (const_int 0)))
10109 (const_string "0")
10110 (const_string "*")))
10111 (set_attr "mode" "SI")])
10112
10113 (define_insn "*<rotate_insn>qi3_1_slp"
10114 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10115 (any_rotate:QI (match_dup 0)
10116 (match_operand:QI 1 "nonmemory_operand" "cI")))
10117 (clobber (reg:CC FLAGS_REG))]
10118 "(optimize_function_for_size_p (cfun)
10119 || !TARGET_PARTIAL_REG_STALL
10120 || (operands[1] == const1_rtx
10121 && TARGET_SHIFT1))"
10122 {
10123 if (operands[1] == const1_rtx
10124 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10125 return "<rotate>{b}\t%0";
10126 else
10127 return "<rotate>{b}\t{%1, %0|%0, %1}";
10128 }
10129 [(set_attr "type" "rotate1")
10130 (set (attr "length_immediate")
10131 (if_then_else
10132 (and (match_operand 1 "const1_operand" "")
10133 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10134 (const_int 0)))
10135 (const_string "0")
10136 (const_string "*")))
10137 (set_attr "mode" "QI")])
10138
10139 (define_split
10140 [(set (match_operand:HI 0 "register_operand" "")
10141 (any_rotate:HI (match_dup 0) (const_int 8)))
10142 (clobber (reg:CC FLAGS_REG))]
10143 "reload_completed
10144 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10145 [(parallel [(set (strict_low_part (match_dup 0))
10146 (bswap:HI (match_dup 0)))
10147 (clobber (reg:CC FLAGS_REG))])])
10148 \f
10149 ;; Bit set / bit test instructions
10150
10151 (define_expand "extv"
10152 [(set (match_operand:SI 0 "register_operand" "")
10153 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10154 (match_operand:SI 2 "const8_operand" "")
10155 (match_operand:SI 3 "const8_operand" "")))]
10156 ""
10157 {
10158 /* Handle extractions from %ah et al. */
10159 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10160 FAIL;
10161
10162 /* From mips.md: extract_bit_field doesn't verify that our source
10163 matches the predicate, so check it again here. */
10164 if (! ext_register_operand (operands[1], VOIDmode))
10165 FAIL;
10166 })
10167
10168 (define_expand "extzv"
10169 [(set (match_operand:SI 0 "register_operand" "")
10170 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10171 (match_operand:SI 2 "const8_operand" "")
10172 (match_operand:SI 3 "const8_operand" "")))]
10173 ""
10174 {
10175 /* Handle extractions from %ah et al. */
10176 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10177 FAIL;
10178
10179 /* From mips.md: extract_bit_field doesn't verify that our source
10180 matches the predicate, so check it again here. */
10181 if (! ext_register_operand (operands[1], VOIDmode))
10182 FAIL;
10183 })
10184
10185 (define_expand "insv"
10186 [(set (zero_extract (match_operand 0 "register_operand" "")
10187 (match_operand 1 "const_int_operand" "")
10188 (match_operand 2 "const_int_operand" ""))
10189 (match_operand 3 "register_operand" ""))]
10190 ""
10191 {
10192 rtx (*gen_mov_insv_1) (rtx, rtx);
10193
10194 if (ix86_expand_pinsr (operands))
10195 DONE;
10196
10197 /* Handle insertions to %ah et al. */
10198 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10199 FAIL;
10200
10201 /* From mips.md: insert_bit_field doesn't verify that our source
10202 matches the predicate, so check it again here. */
10203 if (! ext_register_operand (operands[0], VOIDmode))
10204 FAIL;
10205
10206 gen_mov_insv_1 = (TARGET_64BIT
10207 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10208
10209 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10210 DONE;
10211 })
10212
10213 ;; %%% bts, btr, btc, bt.
10214 ;; In general these instructions are *slow* when applied to memory,
10215 ;; since they enforce atomic operation. When applied to registers,
10216 ;; it depends on the cpu implementation. They're never faster than
10217 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10218 ;; no point. But in 64-bit, we can't hold the relevant immediates
10219 ;; within the instruction itself, so operating on bits in the high
10220 ;; 32-bits of a register becomes easier.
10221 ;;
10222 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10223 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10224 ;; negdf respectively, so they can never be disabled entirely.
10225
10226 (define_insn "*btsq"
10227 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10228 (const_int 1)
10229 (match_operand:DI 1 "const_0_to_63_operand" ""))
10230 (const_int 1))
10231 (clobber (reg:CC FLAGS_REG))]
10232 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10233 "bts{q}\t{%1, %0|%0, %1}"
10234 [(set_attr "type" "alu1")
10235 (set_attr "prefix_0f" "1")
10236 (set_attr "mode" "DI")])
10237
10238 (define_insn "*btrq"
10239 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10240 (const_int 1)
10241 (match_operand:DI 1 "const_0_to_63_operand" ""))
10242 (const_int 0))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10245 "btr{q}\t{%1, %0|%0, %1}"
10246 [(set_attr "type" "alu1")
10247 (set_attr "prefix_0f" "1")
10248 (set_attr "mode" "DI")])
10249
10250 (define_insn "*btcq"
10251 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10252 (const_int 1)
10253 (match_operand:DI 1 "const_0_to_63_operand" ""))
10254 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10255 (clobber (reg:CC FLAGS_REG))]
10256 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10257 "btc{q}\t{%1, %0|%0, %1}"
10258 [(set_attr "type" "alu1")
10259 (set_attr "prefix_0f" "1")
10260 (set_attr "mode" "DI")])
10261
10262 ;; Allow Nocona to avoid these instructions if a register is available.
10263
10264 (define_peephole2
10265 [(match_scratch:DI 2 "r")
10266 (parallel [(set (zero_extract:DI
10267 (match_operand:DI 0 "register_operand" "")
10268 (const_int 1)
10269 (match_operand:DI 1 "const_0_to_63_operand" ""))
10270 (const_int 1))
10271 (clobber (reg:CC FLAGS_REG))])]
10272 "TARGET_64BIT && !TARGET_USE_BT"
10273 [(const_int 0)]
10274 {
10275 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10276 rtx op1;
10277
10278 if (HOST_BITS_PER_WIDE_INT >= 64)
10279 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10280 else if (i < HOST_BITS_PER_WIDE_INT)
10281 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10282 else
10283 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10284
10285 op1 = immed_double_const (lo, hi, DImode);
10286 if (i >= 31)
10287 {
10288 emit_move_insn (operands[2], op1);
10289 op1 = operands[2];
10290 }
10291
10292 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10293 DONE;
10294 })
10295
10296 (define_peephole2
10297 [(match_scratch:DI 2 "r")
10298 (parallel [(set (zero_extract:DI
10299 (match_operand:DI 0 "register_operand" "")
10300 (const_int 1)
10301 (match_operand:DI 1 "const_0_to_63_operand" ""))
10302 (const_int 0))
10303 (clobber (reg:CC FLAGS_REG))])]
10304 "TARGET_64BIT && !TARGET_USE_BT"
10305 [(const_int 0)]
10306 {
10307 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10308 rtx op1;
10309
10310 if (HOST_BITS_PER_WIDE_INT >= 64)
10311 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10312 else if (i < HOST_BITS_PER_WIDE_INT)
10313 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10314 else
10315 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10316
10317 op1 = immed_double_const (~lo, ~hi, DImode);
10318 if (i >= 32)
10319 {
10320 emit_move_insn (operands[2], op1);
10321 op1 = operands[2];
10322 }
10323
10324 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10325 DONE;
10326 })
10327
10328 (define_peephole2
10329 [(match_scratch:DI 2 "r")
10330 (parallel [(set (zero_extract:DI
10331 (match_operand:DI 0 "register_operand" "")
10332 (const_int 1)
10333 (match_operand:DI 1 "const_0_to_63_operand" ""))
10334 (not:DI (zero_extract:DI
10335 (match_dup 0) (const_int 1) (match_dup 1))))
10336 (clobber (reg:CC FLAGS_REG))])]
10337 "TARGET_64BIT && !TARGET_USE_BT"
10338 [(const_int 0)]
10339 {
10340 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10341 rtx op1;
10342
10343 if (HOST_BITS_PER_WIDE_INT >= 64)
10344 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10345 else if (i < HOST_BITS_PER_WIDE_INT)
10346 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10347 else
10348 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10349
10350 op1 = immed_double_const (lo, hi, DImode);
10351 if (i >= 31)
10352 {
10353 emit_move_insn (operands[2], op1);
10354 op1 = operands[2];
10355 }
10356
10357 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10358 DONE;
10359 })
10360
10361 (define_insn "*bt<mode>"
10362 [(set (reg:CCC FLAGS_REG)
10363 (compare:CCC
10364 (zero_extract:SWI48
10365 (match_operand:SWI48 0 "register_operand" "r")
10366 (const_int 1)
10367 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10368 (const_int 0)))]
10369 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10370 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10371 [(set_attr "type" "alu1")
10372 (set_attr "prefix_0f" "1")
10373 (set_attr "mode" "<MODE>")])
10374 \f
10375 ;; Store-flag instructions.
10376
10377 ;; For all sCOND expanders, also expand the compare or test insn that
10378 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10379
10380 (define_insn_and_split "*setcc_di_1"
10381 [(set (match_operand:DI 0 "register_operand" "=q")
10382 (match_operator:DI 1 "ix86_comparison_operator"
10383 [(reg FLAGS_REG) (const_int 0)]))]
10384 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10385 "#"
10386 "&& reload_completed"
10387 [(set (match_dup 2) (match_dup 1))
10388 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10389 {
10390 PUT_MODE (operands[1], QImode);
10391 operands[2] = gen_lowpart (QImode, operands[0]);
10392 })
10393
10394 (define_insn_and_split "*setcc_si_1_and"
10395 [(set (match_operand:SI 0 "register_operand" "=q")
10396 (match_operator:SI 1 "ix86_comparison_operator"
10397 [(reg FLAGS_REG) (const_int 0)]))
10398 (clobber (reg:CC FLAGS_REG))]
10399 "!TARGET_PARTIAL_REG_STALL
10400 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10401 "#"
10402 "&& reload_completed"
10403 [(set (match_dup 2) (match_dup 1))
10404 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10405 (clobber (reg:CC FLAGS_REG))])]
10406 {
10407 PUT_MODE (operands[1], QImode);
10408 operands[2] = gen_lowpart (QImode, operands[0]);
10409 })
10410
10411 (define_insn_and_split "*setcc_si_1_movzbl"
10412 [(set (match_operand:SI 0 "register_operand" "=q")
10413 (match_operator:SI 1 "ix86_comparison_operator"
10414 [(reg FLAGS_REG) (const_int 0)]))]
10415 "!TARGET_PARTIAL_REG_STALL
10416 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10417 "#"
10418 "&& reload_completed"
10419 [(set (match_dup 2) (match_dup 1))
10420 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10421 {
10422 PUT_MODE (operands[1], QImode);
10423 operands[2] = gen_lowpart (QImode, operands[0]);
10424 })
10425
10426 (define_insn "*setcc_qi"
10427 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10428 (match_operator:QI 1 "ix86_comparison_operator"
10429 [(reg FLAGS_REG) (const_int 0)]))]
10430 ""
10431 "set%C1\t%0"
10432 [(set_attr "type" "setcc")
10433 (set_attr "mode" "QI")])
10434
10435 (define_insn "*setcc_qi_slp"
10436 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10437 (match_operator:QI 1 "ix86_comparison_operator"
10438 [(reg FLAGS_REG) (const_int 0)]))]
10439 ""
10440 "set%C1\t%0"
10441 [(set_attr "type" "setcc")
10442 (set_attr "mode" "QI")])
10443
10444 ;; In general it is not safe to assume too much about CCmode registers,
10445 ;; so simplify-rtx stops when it sees a second one. Under certain
10446 ;; conditions this is safe on x86, so help combine not create
10447 ;;
10448 ;; seta %al
10449 ;; testb %al, %al
10450 ;; sete %al
10451
10452 (define_split
10453 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10454 (ne:QI (match_operator 1 "ix86_comparison_operator"
10455 [(reg FLAGS_REG) (const_int 0)])
10456 (const_int 0)))]
10457 ""
10458 [(set (match_dup 0) (match_dup 1))]
10459 "PUT_MODE (operands[1], QImode);")
10460
10461 (define_split
10462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10463 (ne:QI (match_operator 1 "ix86_comparison_operator"
10464 [(reg FLAGS_REG) (const_int 0)])
10465 (const_int 0)))]
10466 ""
10467 [(set (match_dup 0) (match_dup 1))]
10468 "PUT_MODE (operands[1], QImode);")
10469
10470 (define_split
10471 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10472 (eq:QI (match_operator 1 "ix86_comparison_operator"
10473 [(reg FLAGS_REG) (const_int 0)])
10474 (const_int 0)))]
10475 ""
10476 [(set (match_dup 0) (match_dup 1))]
10477 {
10478 rtx new_op1 = copy_rtx (operands[1]);
10479 operands[1] = new_op1;
10480 PUT_MODE (new_op1, QImode);
10481 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10482 GET_MODE (XEXP (new_op1, 0))));
10483
10484 /* Make sure that (a) the CCmode we have for the flags is strong
10485 enough for the reversed compare or (b) we have a valid FP compare. */
10486 if (! ix86_comparison_operator (new_op1, VOIDmode))
10487 FAIL;
10488 })
10489
10490 (define_split
10491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10492 (eq:QI (match_operator 1 "ix86_comparison_operator"
10493 [(reg FLAGS_REG) (const_int 0)])
10494 (const_int 0)))]
10495 ""
10496 [(set (match_dup 0) (match_dup 1))]
10497 {
10498 rtx new_op1 = copy_rtx (operands[1]);
10499 operands[1] = new_op1;
10500 PUT_MODE (new_op1, QImode);
10501 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10502 GET_MODE (XEXP (new_op1, 0))));
10503
10504 /* Make sure that (a) the CCmode we have for the flags is strong
10505 enough for the reversed compare or (b) we have a valid FP compare. */
10506 if (! ix86_comparison_operator (new_op1, VOIDmode))
10507 FAIL;
10508 })
10509
10510 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10511 ;; subsequent logical operations are used to imitate conditional moves.
10512 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10513 ;; it directly.
10514
10515 (define_insn "setcc_<mode>_sse"
10516 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10517 (match_operator:MODEF 3 "sse_comparison_operator"
10518 [(match_operand:MODEF 1 "register_operand" "0,x")
10519 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10520 "SSE_FLOAT_MODE_P (<MODE>mode)"
10521 "@
10522 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10523 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10524 [(set_attr "isa" "noavx,avx")
10525 (set_attr "type" "ssecmp")
10526 (set_attr "length_immediate" "1")
10527 (set_attr "prefix" "orig,vex")
10528 (set_attr "mode" "<MODE>")])
10529 \f
10530 ;; Basic conditional jump instructions.
10531 ;; We ignore the overflow flag for signed branch instructions.
10532
10533 (define_insn "*jcc_1"
10534 [(set (pc)
10535 (if_then_else (match_operator 1 "ix86_comparison_operator"
10536 [(reg FLAGS_REG) (const_int 0)])
10537 (label_ref (match_operand 0 "" ""))
10538 (pc)))]
10539 ""
10540 "%+j%C1\t%l0"
10541 [(set_attr "type" "ibr")
10542 (set_attr "modrm" "0")
10543 (set (attr "length")
10544 (if_then_else (and (ge (minus (match_dup 0) (pc))
10545 (const_int -126))
10546 (lt (minus (match_dup 0) (pc))
10547 (const_int 128)))
10548 (const_int 2)
10549 (const_int 6)))])
10550
10551 (define_insn "*jcc_2"
10552 [(set (pc)
10553 (if_then_else (match_operator 1 "ix86_comparison_operator"
10554 [(reg FLAGS_REG) (const_int 0)])
10555 (pc)
10556 (label_ref (match_operand 0 "" ""))))]
10557 ""
10558 "%+j%c1\t%l0"
10559 [(set_attr "type" "ibr")
10560 (set_attr "modrm" "0")
10561 (set (attr "length")
10562 (if_then_else (and (ge (minus (match_dup 0) (pc))
10563 (const_int -126))
10564 (lt (minus (match_dup 0) (pc))
10565 (const_int 128)))
10566 (const_int 2)
10567 (const_int 6)))])
10568
10569 ;; In general it is not safe to assume too much about CCmode registers,
10570 ;; so simplify-rtx stops when it sees a second one. Under certain
10571 ;; conditions this is safe on x86, so help combine not create
10572 ;;
10573 ;; seta %al
10574 ;; testb %al, %al
10575 ;; je Lfoo
10576
10577 (define_split
10578 [(set (pc)
10579 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10580 [(reg FLAGS_REG) (const_int 0)])
10581 (const_int 0))
10582 (label_ref (match_operand 1 "" ""))
10583 (pc)))]
10584 ""
10585 [(set (pc)
10586 (if_then_else (match_dup 0)
10587 (label_ref (match_dup 1))
10588 (pc)))]
10589 "PUT_MODE (operands[0], VOIDmode);")
10590
10591 (define_split
10592 [(set (pc)
10593 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)])
10595 (const_int 0))
10596 (label_ref (match_operand 1 "" ""))
10597 (pc)))]
10598 ""
10599 [(set (pc)
10600 (if_then_else (match_dup 0)
10601 (label_ref (match_dup 1))
10602 (pc)))]
10603 {
10604 rtx new_op0 = copy_rtx (operands[0]);
10605 operands[0] = new_op0;
10606 PUT_MODE (new_op0, VOIDmode);
10607 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10608 GET_MODE (XEXP (new_op0, 0))));
10609
10610 /* Make sure that (a) the CCmode we have for the flags is strong
10611 enough for the reversed compare or (b) we have a valid FP compare. */
10612 if (! ix86_comparison_operator (new_op0, VOIDmode))
10613 FAIL;
10614 })
10615
10616 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10617 ;; pass generates from shift insn with QImode operand. Actually, the mode
10618 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10619 ;; appropriate modulo of the bit offset value.
10620
10621 (define_insn_and_split "*jcc_bt<mode>"
10622 [(set (pc)
10623 (if_then_else (match_operator 0 "bt_comparison_operator"
10624 [(zero_extract:SWI48
10625 (match_operand:SWI48 1 "register_operand" "r")
10626 (const_int 1)
10627 (zero_extend:SI
10628 (match_operand:QI 2 "register_operand" "r")))
10629 (const_int 0)])
10630 (label_ref (match_operand 3 "" ""))
10631 (pc)))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10634 "#"
10635 "&& 1"
10636 [(set (reg:CCC FLAGS_REG)
10637 (compare:CCC
10638 (zero_extract:SWI48
10639 (match_dup 1)
10640 (const_int 1)
10641 (match_dup 2))
10642 (const_int 0)))
10643 (set (pc)
10644 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10645 (label_ref (match_dup 3))
10646 (pc)))]
10647 {
10648 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10649
10650 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10651 })
10652
10653 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10654 ;; also for DImode, this is what combine produces.
10655 (define_insn_and_split "*jcc_bt<mode>_mask"
10656 [(set (pc)
10657 (if_then_else (match_operator 0 "bt_comparison_operator"
10658 [(zero_extract:SWI48
10659 (match_operand:SWI48 1 "register_operand" "r")
10660 (const_int 1)
10661 (and:SI
10662 (match_operand:SI 2 "register_operand" "r")
10663 (match_operand:SI 3 "const_int_operand" "n")))])
10664 (label_ref (match_operand 4 "" ""))
10665 (pc)))
10666 (clobber (reg:CC FLAGS_REG))]
10667 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10668 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10669 == GET_MODE_BITSIZE (<MODE>mode)-1"
10670 "#"
10671 "&& 1"
10672 [(set (reg:CCC FLAGS_REG)
10673 (compare:CCC
10674 (zero_extract:SWI48
10675 (match_dup 1)
10676 (const_int 1)
10677 (match_dup 2))
10678 (const_int 0)))
10679 (set (pc)
10680 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10681 (label_ref (match_dup 4))
10682 (pc)))]
10683 {
10684 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10685
10686 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10687 })
10688
10689 (define_insn_and_split "*jcc_btsi_1"
10690 [(set (pc)
10691 (if_then_else (match_operator 0 "bt_comparison_operator"
10692 [(and:SI
10693 (lshiftrt:SI
10694 (match_operand:SI 1 "register_operand" "r")
10695 (match_operand:QI 2 "register_operand" "r"))
10696 (const_int 1))
10697 (const_int 0)])
10698 (label_ref (match_operand 3 "" ""))
10699 (pc)))
10700 (clobber (reg:CC FLAGS_REG))]
10701 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10702 "#"
10703 "&& 1"
10704 [(set (reg:CCC FLAGS_REG)
10705 (compare:CCC
10706 (zero_extract:SI
10707 (match_dup 1)
10708 (const_int 1)
10709 (match_dup 2))
10710 (const_int 0)))
10711 (set (pc)
10712 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10713 (label_ref (match_dup 3))
10714 (pc)))]
10715 {
10716 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10717
10718 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10719 })
10720
10721 ;; avoid useless masking of bit offset operand
10722 (define_insn_and_split "*jcc_btsi_mask_1"
10723 [(set (pc)
10724 (if_then_else
10725 (match_operator 0 "bt_comparison_operator"
10726 [(and:SI
10727 (lshiftrt:SI
10728 (match_operand:SI 1 "register_operand" "r")
10729 (subreg:QI
10730 (and:SI
10731 (match_operand:SI 2 "register_operand" "r")
10732 (match_operand:SI 3 "const_int_operand" "n")) 0))
10733 (const_int 1))
10734 (const_int 0)])
10735 (label_ref (match_operand 4 "" ""))
10736 (pc)))
10737 (clobber (reg:CC FLAGS_REG))]
10738 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10739 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10740 "#"
10741 "&& 1"
10742 [(set (reg:CCC FLAGS_REG)
10743 (compare:CCC
10744 (zero_extract:SI
10745 (match_dup 1)
10746 (const_int 1)
10747 (match_dup 2))
10748 (const_int 0)))
10749 (set (pc)
10750 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10751 (label_ref (match_dup 4))
10752 (pc)))]
10753 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10754
10755 ;; Define combination compare-and-branch fp compare instructions to help
10756 ;; combine.
10757
10758 (define_insn "*fp_jcc_1_387"
10759 [(set (pc)
10760 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10761 [(match_operand 1 "register_operand" "f")
10762 (match_operand 2 "nonimmediate_operand" "fm")])
10763 (label_ref (match_operand 3 "" ""))
10764 (pc)))
10765 (clobber (reg:CCFP FPSR_REG))
10766 (clobber (reg:CCFP FLAGS_REG))
10767 (clobber (match_scratch:HI 4 "=a"))]
10768 "TARGET_80387
10769 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10771 && SELECT_CC_MODE (GET_CODE (operands[0]),
10772 operands[1], operands[2]) == CCFPmode
10773 && !TARGET_CMOVE"
10774 "#")
10775
10776 (define_insn "*fp_jcc_1r_387"
10777 [(set (pc)
10778 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10779 [(match_operand 1 "register_operand" "f")
10780 (match_operand 2 "nonimmediate_operand" "fm")])
10781 (pc)
10782 (label_ref (match_operand 3 "" ""))))
10783 (clobber (reg:CCFP FPSR_REG))
10784 (clobber (reg:CCFP FLAGS_REG))
10785 (clobber (match_scratch:HI 4 "=a"))]
10786 "TARGET_80387
10787 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10788 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10789 && SELECT_CC_MODE (GET_CODE (operands[0]),
10790 operands[1], operands[2]) == CCFPmode
10791 && !TARGET_CMOVE"
10792 "#")
10793
10794 (define_insn "*fp_jcc_2_387"
10795 [(set (pc)
10796 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10797 [(match_operand 1 "register_operand" "f")
10798 (match_operand 2 "register_operand" "f")])
10799 (label_ref (match_operand 3 "" ""))
10800 (pc)))
10801 (clobber (reg:CCFP FPSR_REG))
10802 (clobber (reg:CCFP FLAGS_REG))
10803 (clobber (match_scratch:HI 4 "=a"))]
10804 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10806 && !TARGET_CMOVE"
10807 "#")
10808
10809 (define_insn "*fp_jcc_2r_387"
10810 [(set (pc)
10811 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10812 [(match_operand 1 "register_operand" "f")
10813 (match_operand 2 "register_operand" "f")])
10814 (pc)
10815 (label_ref (match_operand 3 "" ""))))
10816 (clobber (reg:CCFP FPSR_REG))
10817 (clobber (reg:CCFP FLAGS_REG))
10818 (clobber (match_scratch:HI 4 "=a"))]
10819 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10820 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10821 && !TARGET_CMOVE"
10822 "#")
10823
10824 (define_insn "*fp_jcc_3_387"
10825 [(set (pc)
10826 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10827 [(match_operand 1 "register_operand" "f")
10828 (match_operand 2 "const0_operand" "")])
10829 (label_ref (match_operand 3 "" ""))
10830 (pc)))
10831 (clobber (reg:CCFP FPSR_REG))
10832 (clobber (reg:CCFP FLAGS_REG))
10833 (clobber (match_scratch:HI 4 "=a"))]
10834 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10835 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10836 && SELECT_CC_MODE (GET_CODE (operands[0]),
10837 operands[1], operands[2]) == CCFPmode
10838 && !TARGET_CMOVE"
10839 "#")
10840
10841 (define_split
10842 [(set (pc)
10843 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10844 [(match_operand 1 "register_operand" "")
10845 (match_operand 2 "nonimmediate_operand" "")])
10846 (match_operand 3 "" "")
10847 (match_operand 4 "" "")))
10848 (clobber (reg:CCFP FPSR_REG))
10849 (clobber (reg:CCFP FLAGS_REG))]
10850 "reload_completed"
10851 [(const_int 0)]
10852 {
10853 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10854 operands[3], operands[4], NULL_RTX, NULL_RTX);
10855 DONE;
10856 })
10857
10858 (define_split
10859 [(set (pc)
10860 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10861 [(match_operand 1 "register_operand" "")
10862 (match_operand 2 "general_operand" "")])
10863 (match_operand 3 "" "")
10864 (match_operand 4 "" "")))
10865 (clobber (reg:CCFP FPSR_REG))
10866 (clobber (reg:CCFP FLAGS_REG))
10867 (clobber (match_scratch:HI 5 "=a"))]
10868 "reload_completed"
10869 [(const_int 0)]
10870 {
10871 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10872 operands[3], operands[4], operands[5], NULL_RTX);
10873 DONE;
10874 })
10875
10876 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10877 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10878 ;; with a precedence over other operators and is always put in the first
10879 ;; place. Swap condition and operands to match ficom instruction.
10880
10881 (define_insn "*fp_jcc_4_<mode>_387"
10882 [(set (pc)
10883 (if_then_else
10884 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10885 [(match_operator 1 "float_operator"
10886 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10887 (match_operand 3 "register_operand" "f,f")])
10888 (label_ref (match_operand 4 "" ""))
10889 (pc)))
10890 (clobber (reg:CCFP FPSR_REG))
10891 (clobber (reg:CCFP FLAGS_REG))
10892 (clobber (match_scratch:HI 5 "=a,a"))]
10893 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10894 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10895 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10896 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10897 && !TARGET_CMOVE"
10898 "#")
10899
10900 (define_split
10901 [(set (pc)
10902 (if_then_else
10903 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10904 [(match_operator 1 "float_operator"
10905 [(match_operand:SWI24 2 "memory_operand" "")])
10906 (match_operand 3 "register_operand" "")])
10907 (match_operand 4 "" "")
10908 (match_operand 5 "" "")))
10909 (clobber (reg:CCFP FPSR_REG))
10910 (clobber (reg:CCFP FLAGS_REG))
10911 (clobber (match_scratch:HI 6 "=a"))]
10912 "reload_completed"
10913 [(const_int 0)]
10914 {
10915 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10916
10917 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10918 operands[3], operands[7],
10919 operands[4], operands[5], operands[6], NULL_RTX);
10920 DONE;
10921 })
10922
10923 ;; %%% Kill this when reload knows how to do it.
10924 (define_split
10925 [(set (pc)
10926 (if_then_else
10927 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10928 [(match_operator 1 "float_operator"
10929 [(match_operand:SWI24 2 "register_operand" "")])
10930 (match_operand 3 "register_operand" "")])
10931 (match_operand 4 "" "")
10932 (match_operand 5 "" "")))
10933 (clobber (reg:CCFP FPSR_REG))
10934 (clobber (reg:CCFP FLAGS_REG))
10935 (clobber (match_scratch:HI 6 "=a"))]
10936 "reload_completed"
10937 [(const_int 0)]
10938 {
10939 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10940 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10941
10942 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10943 operands[3], operands[7],
10944 operands[4], operands[5], operands[6], operands[2]);
10945 DONE;
10946 })
10947 \f
10948 ;; Unconditional and other jump instructions
10949
10950 (define_insn "jump"
10951 [(set (pc)
10952 (label_ref (match_operand 0 "" "")))]
10953 ""
10954 "jmp\t%l0"
10955 [(set_attr "type" "ibr")
10956 (set (attr "length")
10957 (if_then_else (and (ge (minus (match_dup 0) (pc))
10958 (const_int -126))
10959 (lt (minus (match_dup 0) (pc))
10960 (const_int 128)))
10961 (const_int 2)
10962 (const_int 5)))
10963 (set_attr "modrm" "0")])
10964
10965 (define_expand "indirect_jump"
10966 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))])
10967
10968 (define_insn "*indirect_jump"
10969 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10970 ""
10971 "jmp\t%A0"
10972 [(set_attr "type" "ibr")
10973 (set_attr "length_immediate" "0")])
10974
10975 (define_expand "tablejump"
10976 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10977 (use (label_ref (match_operand 1 "" "")))])]
10978 ""
10979 {
10980 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10981 relative. Convert the relative address to an absolute address. */
10982 if (flag_pic)
10983 {
10984 rtx op0, op1;
10985 enum rtx_code code;
10986
10987 /* We can't use @GOTOFF for text labels on VxWorks;
10988 see gotoff_operand. */
10989 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10990 {
10991 code = PLUS;
10992 op0 = operands[0];
10993 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10994 }
10995 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10996 {
10997 code = PLUS;
10998 op0 = operands[0];
10999 op1 = pic_offset_table_rtx;
11000 }
11001 else
11002 {
11003 code = MINUS;
11004 op0 = pic_offset_table_rtx;
11005 op1 = operands[0];
11006 }
11007
11008 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11009 OPTAB_DIRECT);
11010 }
11011 })
11012
11013 (define_insn "*tablejump_1"
11014 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11015 (use (label_ref (match_operand 1 "" "")))]
11016 ""
11017 "jmp\t%A0"
11018 [(set_attr "type" "ibr")
11019 (set_attr "length_immediate" "0")])
11020 \f
11021 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11022
11023 (define_peephole2
11024 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11025 (set (match_operand:QI 1 "register_operand" "")
11026 (match_operator:QI 2 "ix86_comparison_operator"
11027 [(reg FLAGS_REG) (const_int 0)]))
11028 (set (match_operand 3 "q_regs_operand" "")
11029 (zero_extend (match_dup 1)))]
11030 "(peep2_reg_dead_p (3, operands[1])
11031 || operands_match_p (operands[1], operands[3]))
11032 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11033 [(set (match_dup 4) (match_dup 0))
11034 (set (strict_low_part (match_dup 5))
11035 (match_dup 2))]
11036 {
11037 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11038 operands[5] = gen_lowpart (QImode, operands[3]);
11039 ix86_expand_clear (operands[3]);
11040 })
11041
11042 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11043
11044 (define_peephole2
11045 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11046 (set (match_operand:QI 1 "register_operand" "")
11047 (match_operator:QI 2 "ix86_comparison_operator"
11048 [(reg FLAGS_REG) (const_int 0)]))
11049 (parallel [(set (match_operand 3 "q_regs_operand" "")
11050 (zero_extend (match_dup 1)))
11051 (clobber (reg:CC FLAGS_REG))])]
11052 "(peep2_reg_dead_p (3, operands[1])
11053 || operands_match_p (operands[1], operands[3]))
11054 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11055 [(set (match_dup 4) (match_dup 0))
11056 (set (strict_low_part (match_dup 5))
11057 (match_dup 2))]
11058 {
11059 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11060 operands[5] = gen_lowpart (QImode, operands[3]);
11061 ix86_expand_clear (operands[3]);
11062 })
11063 \f
11064 ;; Call instructions.
11065
11066 ;; The predicates normally associated with named expanders are not properly
11067 ;; checked for calls. This is a bug in the generic code, but it isn't that
11068 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11069
11070 ;; P6 processors will jump to the address after the decrement when %esp
11071 ;; is used as a call operand, so they will execute return address as a code.
11072 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11073
11074 ;; Register constraint for call instruction.
11075 (define_mode_attr c [(SI "l") (DI "r")])
11076
11077 ;; Call subroutine returning no value.
11078
11079 (define_expand "call"
11080 [(call (match_operand:QI 0 "" "")
11081 (match_operand 1 "" ""))
11082 (use (match_operand 2 "" ""))]
11083 ""
11084 {
11085 ix86_expand_call (NULL, operands[0], operands[1],
11086 operands[2], NULL, false);
11087 DONE;
11088 })
11089
11090 (define_expand "sibcall"
11091 [(call (match_operand:QI 0 "" "")
11092 (match_operand 1 "" ""))
11093 (use (match_operand 2 "" ""))]
11094 ""
11095 {
11096 ix86_expand_call (NULL, operands[0], operands[1],
11097 operands[2], NULL, true);
11098 DONE;
11099 })
11100
11101 (define_insn_and_split "*call_vzeroupper"
11102 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11103 (match_operand 1 "" ""))
11104 (unspec [(match_operand 2 "const_int_operand" "")]
11105 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11106 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11107 "#"
11108 "&& reload_completed"
11109 [(const_int 0)]
11110 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11111 [(set_attr "type" "call")])
11112
11113 (define_insn "*call"
11114 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11115 (match_operand 1 "" ""))]
11116 "!SIBLING_CALL_P (insn)"
11117 "* return ix86_output_call_insn (insn, operands[0]);"
11118 [(set_attr "type" "call")])
11119
11120 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11121 [(parallel
11122 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11123 (match_operand 1 "" ""))
11124 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11125 (clobber (reg:TI XMM6_REG))
11126 (clobber (reg:TI XMM7_REG))
11127 (clobber (reg:TI XMM8_REG))
11128 (clobber (reg:TI XMM9_REG))
11129 (clobber (reg:TI XMM10_REG))
11130 (clobber (reg:TI XMM11_REG))
11131 (clobber (reg:TI XMM12_REG))
11132 (clobber (reg:TI XMM13_REG))
11133 (clobber (reg:TI XMM14_REG))
11134 (clobber (reg:TI XMM15_REG))
11135 (clobber (reg:DI SI_REG))
11136 (clobber (reg:DI DI_REG))])
11137 (unspec [(match_operand 2 "const_int_operand" "")]
11138 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11139 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11140 "#"
11141 "&& reload_completed"
11142 [(const_int 0)]
11143 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11144 [(set_attr "type" "call")])
11145
11146 (define_insn "*call_rex64_ms_sysv"
11147 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11148 (match_operand 1 "" ""))
11149 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11150 (clobber (reg:TI XMM6_REG))
11151 (clobber (reg:TI XMM7_REG))
11152 (clobber (reg:TI XMM8_REG))
11153 (clobber (reg:TI XMM9_REG))
11154 (clobber (reg:TI XMM10_REG))
11155 (clobber (reg:TI XMM11_REG))
11156 (clobber (reg:TI XMM12_REG))
11157 (clobber (reg:TI XMM13_REG))
11158 (clobber (reg:TI XMM14_REG))
11159 (clobber (reg:TI XMM15_REG))
11160 (clobber (reg:DI SI_REG))
11161 (clobber (reg:DI DI_REG))]
11162 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11163 "* return ix86_output_call_insn (insn, operands[0]);"
11164 [(set_attr "type" "call")])
11165
11166 (define_insn_and_split "*sibcall_vzeroupper"
11167 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11168 (match_operand 1 "" ""))
11169 (unspec [(match_operand 2 "const_int_operand" "")]
11170 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11171 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11172 "#"
11173 "&& reload_completed"
11174 [(const_int 0)]
11175 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11176 [(set_attr "type" "call")])
11177
11178 (define_insn "*sibcall"
11179 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11180 (match_operand 1 "" ""))]
11181 "SIBLING_CALL_P (insn)"
11182 "* return ix86_output_call_insn (insn, operands[0]);"
11183 [(set_attr "type" "call")])
11184
11185 (define_expand "call_pop"
11186 [(parallel [(call (match_operand:QI 0 "" "")
11187 (match_operand:SI 1 "" ""))
11188 (set (reg:SI SP_REG)
11189 (plus:SI (reg:SI SP_REG)
11190 (match_operand:SI 3 "" "")))])]
11191 "!TARGET_64BIT"
11192 {
11193 ix86_expand_call (NULL, operands[0], operands[1],
11194 operands[2], operands[3], false);
11195 DONE;
11196 })
11197
11198 (define_insn_and_split "*call_pop_vzeroupper"
11199 [(parallel
11200 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11201 (match_operand:SI 1 "" ""))
11202 (set (reg:SI SP_REG)
11203 (plus:SI (reg:SI SP_REG)
11204 (match_operand:SI 2 "immediate_operand" "i")))])
11205 (unspec [(match_operand 3 "const_int_operand" "")]
11206 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11207 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11208 "#"
11209 "&& reload_completed"
11210 [(const_int 0)]
11211 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11212 [(set_attr "type" "call")])
11213
11214 (define_insn "*call_pop"
11215 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11216 (match_operand 1 "" ""))
11217 (set (reg:SI SP_REG)
11218 (plus:SI (reg:SI SP_REG)
11219 (match_operand:SI 2 "immediate_operand" "i")))]
11220 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11221 "* return ix86_output_call_insn (insn, operands[0]);"
11222 [(set_attr "type" "call")])
11223
11224 (define_insn_and_split "*sibcall_pop_vzeroupper"
11225 [(parallel
11226 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11227 (match_operand 1 "" ""))
11228 (set (reg:SI SP_REG)
11229 (plus:SI (reg:SI SP_REG)
11230 (match_operand:SI 2 "immediate_operand" "i")))])
11231 (unspec [(match_operand 3 "const_int_operand" "")]
11232 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11233 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11234 "#"
11235 "&& reload_completed"
11236 [(const_int 0)]
11237 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11238 [(set_attr "type" "call")])
11239
11240 (define_insn "*sibcall_pop"
11241 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11242 (match_operand 1 "" ""))
11243 (set (reg:SI SP_REG)
11244 (plus:SI (reg:SI SP_REG)
11245 (match_operand:SI 2 "immediate_operand" "i")))]
11246 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11247 "* return ix86_output_call_insn (insn, operands[0]);"
11248 [(set_attr "type" "call")])
11249
11250 ;; Call subroutine, returning value in operand 0
11251
11252 (define_expand "call_value"
11253 [(set (match_operand 0 "" "")
11254 (call (match_operand:QI 1 "" "")
11255 (match_operand 2 "" "")))
11256 (use (match_operand 3 "" ""))]
11257 ""
11258 {
11259 ix86_expand_call (operands[0], operands[1], operands[2],
11260 operands[3], NULL, false);
11261 DONE;
11262 })
11263
11264 (define_expand "sibcall_value"
11265 [(set (match_operand 0 "" "")
11266 (call (match_operand:QI 1 "" "")
11267 (match_operand 2 "" "")))
11268 (use (match_operand 3 "" ""))]
11269 ""
11270 {
11271 ix86_expand_call (operands[0], operands[1], operands[2],
11272 operands[3], NULL, true);
11273 DONE;
11274 })
11275
11276 (define_insn_and_split "*call_value_vzeroupper"
11277 [(set (match_operand 0 "" "")
11278 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11279 (match_operand 2 "" "")))
11280 (unspec [(match_operand 3 "const_int_operand" "")]
11281 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11282 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11283 "#"
11284 "&& reload_completed"
11285 [(const_int 0)]
11286 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11287 [(set_attr "type" "callv")])
11288
11289 (define_insn "*call_value"
11290 [(set (match_operand 0 "" "")
11291 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11292 (match_operand 2 "" "")))]
11293 "!SIBLING_CALL_P (insn)"
11294 "* return ix86_output_call_insn (insn, operands[1]);"
11295 [(set_attr "type" "callv")])
11296
11297 (define_insn_and_split "*sibcall_value_vzeroupper"
11298 [(set (match_operand 0 "" "")
11299 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11300 (match_operand 2 "" "")))
11301 (unspec [(match_operand 3 "const_int_operand" "")]
11302 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11303 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11304 "#"
11305 "&& reload_completed"
11306 [(const_int 0)]
11307 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11308 [(set_attr "type" "callv")])
11309
11310 (define_insn "*sibcall_value"
11311 [(set (match_operand 0 "" "")
11312 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11313 (match_operand 2 "" "")))]
11314 "SIBLING_CALL_P (insn)"
11315 "* return ix86_output_call_insn (insn, operands[1]);"
11316 [(set_attr "type" "callv")])
11317
11318 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11319 [(parallel
11320 [(set (match_operand 0 "" "")
11321 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11322 (match_operand 2 "" "")))
11323 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11324 (clobber (reg:TI XMM6_REG))
11325 (clobber (reg:TI XMM7_REG))
11326 (clobber (reg:TI XMM8_REG))
11327 (clobber (reg:TI XMM9_REG))
11328 (clobber (reg:TI XMM10_REG))
11329 (clobber (reg:TI XMM11_REG))
11330 (clobber (reg:TI XMM12_REG))
11331 (clobber (reg:TI XMM13_REG))
11332 (clobber (reg:TI XMM14_REG))
11333 (clobber (reg:TI XMM15_REG))
11334 (clobber (reg:DI SI_REG))
11335 (clobber (reg:DI DI_REG))])
11336 (unspec [(match_operand 3 "const_int_operand" "")]
11337 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11338 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11339 "#"
11340 "&& reload_completed"
11341 [(const_int 0)]
11342 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11343 [(set_attr "type" "callv")])
11344
11345 (define_insn "*call_value_rex64_ms_sysv"
11346 [(set (match_operand 0 "" "")
11347 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11348 (match_operand 2 "" "")))
11349 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11350 (clobber (reg:TI XMM6_REG))
11351 (clobber (reg:TI XMM7_REG))
11352 (clobber (reg:TI XMM8_REG))
11353 (clobber (reg:TI XMM9_REG))
11354 (clobber (reg:TI XMM10_REG))
11355 (clobber (reg:TI XMM11_REG))
11356 (clobber (reg:TI XMM12_REG))
11357 (clobber (reg:TI XMM13_REG))
11358 (clobber (reg:TI XMM14_REG))
11359 (clobber (reg:TI XMM15_REG))
11360 (clobber (reg:DI SI_REG))
11361 (clobber (reg:DI DI_REG))]
11362 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11363 "* return ix86_output_call_insn (insn, operands[1]);"
11364 [(set_attr "type" "callv")])
11365
11366 (define_expand "call_value_pop"
11367 [(parallel [(set (match_operand 0 "" "")
11368 (call (match_operand:QI 1 "" "")
11369 (match_operand:SI 2 "" "")))
11370 (set (reg:SI SP_REG)
11371 (plus:SI (reg:SI SP_REG)
11372 (match_operand:SI 4 "" "")))])]
11373 "!TARGET_64BIT"
11374 {
11375 ix86_expand_call (operands[0], operands[1], operands[2],
11376 operands[3], operands[4], false);
11377 DONE;
11378 })
11379
11380 (define_insn_and_split "*call_value_pop_vzeroupper"
11381 [(parallel
11382 [(set (match_operand 0 "" "")
11383 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11384 (match_operand 2 "" "")))
11385 (set (reg:SI SP_REG)
11386 (plus:SI (reg:SI SP_REG)
11387 (match_operand:SI 3 "immediate_operand" "i")))])
11388 (unspec [(match_operand 4 "const_int_operand" "")]
11389 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11390 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11391 "#"
11392 "&& reload_completed"
11393 [(const_int 0)]
11394 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11395 [(set_attr "type" "callv")])
11396
11397 (define_insn "*call_value_pop"
11398 [(set (match_operand 0 "" "")
11399 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11400 (match_operand 2 "" "")))
11401 (set (reg:SI SP_REG)
11402 (plus:SI (reg:SI SP_REG)
11403 (match_operand:SI 3 "immediate_operand" "i")))]
11404 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11405 "* return ix86_output_call_insn (insn, operands[1]);"
11406 [(set_attr "type" "callv")])
11407
11408 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11409 [(parallel
11410 [(set (match_operand 0 "" "")
11411 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11412 (match_operand 2 "" "")))
11413 (set (reg:SI SP_REG)
11414 (plus:SI (reg:SI SP_REG)
11415 (match_operand:SI 3 "immediate_operand" "i")))])
11416 (unspec [(match_operand 4 "const_int_operand" "")]
11417 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11418 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11419 "#"
11420 "&& reload_completed"
11421 [(const_int 0)]
11422 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11423 [(set_attr "type" "callv")])
11424
11425 (define_insn "*sibcall_value_pop"
11426 [(set (match_operand 0 "" "")
11427 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11428 (match_operand 2 "" "")))
11429 (set (reg:SI SP_REG)
11430 (plus:SI (reg:SI SP_REG)
11431 (match_operand:SI 3 "immediate_operand" "i")))]
11432 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11433 "* return ix86_output_call_insn (insn, operands[1]);"
11434 [(set_attr "type" "callv")])
11435
11436 ;; Call subroutine returning any type.
11437
11438 (define_expand "untyped_call"
11439 [(parallel [(call (match_operand 0 "" "")
11440 (const_int 0))
11441 (match_operand 1 "" "")
11442 (match_operand 2 "" "")])]
11443 ""
11444 {
11445 int i;
11446
11447 /* In order to give reg-stack an easier job in validating two
11448 coprocessor registers as containing a possible return value,
11449 simply pretend the untyped call returns a complex long double
11450 value.
11451
11452 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11453 and should have the default ABI. */
11454
11455 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11456 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11457 operands[0], const0_rtx,
11458 GEN_INT ((TARGET_64BIT
11459 ? (ix86_abi == SYSV_ABI
11460 ? X86_64_SSE_REGPARM_MAX
11461 : X86_64_MS_SSE_REGPARM_MAX)
11462 : X86_32_SSE_REGPARM_MAX)
11463 - 1),
11464 NULL, false);
11465
11466 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11467 {
11468 rtx set = XVECEXP (operands[2], 0, i);
11469 emit_move_insn (SET_DEST (set), SET_SRC (set));
11470 }
11471
11472 /* The optimizer does not know that the call sets the function value
11473 registers we stored in the result block. We avoid problems by
11474 claiming that all hard registers are used and clobbered at this
11475 point. */
11476 emit_insn (gen_blockage ());
11477
11478 DONE;
11479 })
11480 \f
11481 ;; Prologue and epilogue instructions
11482
11483 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11484 ;; all of memory. This blocks insns from being moved across this point.
11485
11486 (define_insn "blockage"
11487 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11488 ""
11489 ""
11490 [(set_attr "length" "0")])
11491
11492 ;; Do not schedule instructions accessing memory across this point.
11493
11494 (define_expand "memory_blockage"
11495 [(set (match_dup 0)
11496 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11497 ""
11498 {
11499 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11500 MEM_VOLATILE_P (operands[0]) = 1;
11501 })
11502
11503 (define_insn "*memory_blockage"
11504 [(set (match_operand:BLK 0 "" "")
11505 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11506 ""
11507 ""
11508 [(set_attr "length" "0")])
11509
11510 ;; As USE insns aren't meaningful after reload, this is used instead
11511 ;; to prevent deleting instructions setting registers for PIC code
11512 (define_insn "prologue_use"
11513 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11514 ""
11515 ""
11516 [(set_attr "length" "0")])
11517
11518 ;; Insn emitted into the body of a function to return from a function.
11519 ;; This is only done if the function's epilogue is known to be simple.
11520 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11521
11522 (define_expand "return"
11523 [(return)]
11524 "ix86_can_use_return_insn_p ()"
11525 {
11526 if (crtl->args.pops_args)
11527 {
11528 rtx popc = GEN_INT (crtl->args.pops_args);
11529 emit_jump_insn (gen_return_pop_internal (popc));
11530 DONE;
11531 }
11532 })
11533
11534 (define_insn "return_internal"
11535 [(return)]
11536 "reload_completed"
11537 "ret"
11538 [(set_attr "length" "1")
11539 (set_attr "atom_unit" "jeu")
11540 (set_attr "length_immediate" "0")
11541 (set_attr "modrm" "0")])
11542
11543 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11544 ;; instruction Athlon and K8 have.
11545
11546 (define_insn "return_internal_long"
11547 [(return)
11548 (unspec [(const_int 0)] UNSPEC_REP)]
11549 "reload_completed"
11550 "rep\;ret"
11551 [(set_attr "length" "2")
11552 (set_attr "atom_unit" "jeu")
11553 (set_attr "length_immediate" "0")
11554 (set_attr "prefix_rep" "1")
11555 (set_attr "modrm" "0")])
11556
11557 (define_insn "return_pop_internal"
11558 [(return)
11559 (use (match_operand:SI 0 "const_int_operand" ""))]
11560 "reload_completed"
11561 "ret\t%0"
11562 [(set_attr "length" "3")
11563 (set_attr "atom_unit" "jeu")
11564 (set_attr "length_immediate" "2")
11565 (set_attr "modrm" "0")])
11566
11567 (define_insn "return_indirect_internal"
11568 [(return)
11569 (use (match_operand:SI 0 "register_operand" "r"))]
11570 "reload_completed"
11571 "jmp\t%A0"
11572 [(set_attr "type" "ibr")
11573 (set_attr "length_immediate" "0")])
11574
11575 (define_insn "nop"
11576 [(const_int 0)]
11577 ""
11578 "nop"
11579 [(set_attr "length" "1")
11580 (set_attr "length_immediate" "0")
11581 (set_attr "modrm" "0")])
11582
11583 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11584 (define_insn "nops"
11585 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11586 UNSPECV_NOPS)]
11587 "reload_completed"
11588 {
11589 int num = INTVAL (operands[0]);
11590
11591 gcc_assert (num >= 1 && num <= 8);
11592
11593 while (num--)
11594 fputs ("\tnop\n", asm_out_file);
11595
11596 return "";
11597 }
11598 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11599 (set_attr "length_immediate" "0")
11600 (set_attr "modrm" "0")])
11601
11602 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11603 ;; branch prediction penalty for the third jump in a 16-byte
11604 ;; block on K8.
11605
11606 (define_insn "pad"
11607 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11608 ""
11609 {
11610 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11611 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11612 #else
11613 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11614 The align insn is used to avoid 3 jump instructions in the row to improve
11615 branch prediction and the benefits hardly outweigh the cost of extra 8
11616 nops on the average inserted by full alignment pseudo operation. */
11617 #endif
11618 return "";
11619 }
11620 [(set_attr "length" "16")])
11621
11622 (define_expand "prologue"
11623 [(const_int 0)]
11624 ""
11625 "ix86_expand_prologue (); DONE;")
11626
11627 (define_insn "set_got"
11628 [(set (match_operand:SI 0 "register_operand" "=r")
11629 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11630 (clobber (reg:CC FLAGS_REG))]
11631 "!TARGET_64BIT"
11632 "* return output_set_got (operands[0], NULL_RTX);"
11633 [(set_attr "type" "multi")
11634 (set_attr "length" "12")])
11635
11636 (define_insn "set_got_labelled"
11637 [(set (match_operand:SI 0 "register_operand" "=r")
11638 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11639 UNSPEC_SET_GOT))
11640 (clobber (reg:CC FLAGS_REG))]
11641 "!TARGET_64BIT"
11642 "* return output_set_got (operands[0], operands[1]);"
11643 [(set_attr "type" "multi")
11644 (set_attr "length" "12")])
11645
11646 (define_insn "set_got_rex64"
11647 [(set (match_operand:DI 0 "register_operand" "=r")
11648 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11649 "TARGET_64BIT"
11650 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11651 [(set_attr "type" "lea")
11652 (set_attr "length_address" "4")
11653 (set_attr "mode" "DI")])
11654
11655 (define_insn "set_rip_rex64"
11656 [(set (match_operand:DI 0 "register_operand" "=r")
11657 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11658 "TARGET_64BIT"
11659 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11660 [(set_attr "type" "lea")
11661 (set_attr "length_address" "4")
11662 (set_attr "mode" "DI")])
11663
11664 (define_insn "set_got_offset_rex64"
11665 [(set (match_operand:DI 0 "register_operand" "=r")
11666 (unspec:DI
11667 [(label_ref (match_operand 1 "" ""))]
11668 UNSPEC_SET_GOT_OFFSET))]
11669 "TARGET_64BIT"
11670 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11671 [(set_attr "type" "imov")
11672 (set_attr "length_immediate" "0")
11673 (set_attr "length_address" "8")
11674 (set_attr "mode" "DI")])
11675
11676 (define_expand "epilogue"
11677 [(const_int 0)]
11678 ""
11679 "ix86_expand_epilogue (1); DONE;")
11680
11681 (define_expand "sibcall_epilogue"
11682 [(const_int 0)]
11683 ""
11684 "ix86_expand_epilogue (0); DONE;")
11685
11686 (define_expand "eh_return"
11687 [(use (match_operand 0 "register_operand" ""))]
11688 ""
11689 {
11690 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11691
11692 /* Tricky bit: we write the address of the handler to which we will
11693 be returning into someone else's stack frame, one word below the
11694 stack address we wish to restore. */
11695 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11696 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11697 tmp = gen_rtx_MEM (Pmode, tmp);
11698 emit_move_insn (tmp, ra);
11699
11700 emit_jump_insn (gen_eh_return_internal ());
11701 emit_barrier ();
11702 DONE;
11703 })
11704
11705 (define_insn_and_split "eh_return_internal"
11706 [(eh_return)]
11707 ""
11708 "#"
11709 "epilogue_completed"
11710 [(const_int 0)]
11711 "ix86_expand_epilogue (2); DONE;")
11712
11713 (define_insn "leave"
11714 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11715 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11716 (clobber (mem:BLK (scratch)))]
11717 "!TARGET_64BIT"
11718 "leave"
11719 [(set_attr "type" "leave")])
11720
11721 (define_insn "leave_rex64"
11722 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11723 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11724 (clobber (mem:BLK (scratch)))]
11725 "TARGET_64BIT"
11726 "leave"
11727 [(set_attr "type" "leave")])
11728 \f
11729 ;; Handle -fsplit-stack.
11730
11731 (define_expand "split_stack_prologue"
11732 [(const_int 0)]
11733 ""
11734 {
11735 ix86_expand_split_stack_prologue ();
11736 DONE;
11737 })
11738
11739 ;; In order to support the call/return predictor, we use a return
11740 ;; instruction which the middle-end doesn't see.
11741 (define_insn "split_stack_return"
11742 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11743 UNSPECV_SPLIT_STACK_RETURN)]
11744 ""
11745 {
11746 if (operands[0] == const0_rtx)
11747 return "ret";
11748 else
11749 return "ret\t%0";
11750 }
11751 [(set_attr "atom_unit" "jeu")
11752 (set_attr "modrm" "0")
11753 (set (attr "length")
11754 (if_then_else (match_operand:SI 0 "const0_operand" "")
11755 (const_int 1)
11756 (const_int 3)))
11757 (set (attr "length_immediate")
11758 (if_then_else (match_operand:SI 0 "const0_operand" "")
11759 (const_int 0)
11760 (const_int 2)))])
11761
11762 ;; If there are operand 0 bytes available on the stack, jump to
11763 ;; operand 1.
11764
11765 (define_expand "split_stack_space_check"
11766 [(set (pc) (if_then_else
11767 (ltu (minus (reg SP_REG)
11768 (match_operand 0 "register_operand" ""))
11769 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11770 (label_ref (match_operand 1 "" ""))
11771 (pc)))]
11772 ""
11773 {
11774 rtx reg, size, limit;
11775
11776 reg = gen_reg_rtx (Pmode);
11777 size = force_reg (Pmode, operands[0]);
11778 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11779 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11780 UNSPEC_STACK_CHECK);
11781 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11782 ix86_expand_branch (GEU, reg, limit, operands[1]);
11783
11784 DONE;
11785 })
11786 \f
11787 ;; Bit manipulation instructions.
11788
11789 (define_expand "ffs<mode>2"
11790 [(set (match_dup 2) (const_int -1))
11791 (parallel [(set (reg:CCZ FLAGS_REG)
11792 (compare:CCZ
11793 (match_operand:SWI48 1 "nonimmediate_operand" "")
11794 (const_int 0)))
11795 (set (match_operand:SWI48 0 "register_operand" "")
11796 (ctz:SWI48 (match_dup 1)))])
11797 (set (match_dup 0) (if_then_else:SWI48
11798 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11799 (match_dup 2)
11800 (match_dup 0)))
11801 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11802 (clobber (reg:CC FLAGS_REG))])]
11803 ""
11804 {
11805 if (<MODE>mode == SImode && !TARGET_CMOVE)
11806 {
11807 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11808 DONE;
11809 }
11810 operands[2] = gen_reg_rtx (<MODE>mode);
11811 })
11812
11813 (define_insn_and_split "ffssi2_no_cmove"
11814 [(set (match_operand:SI 0 "register_operand" "=r")
11815 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11816 (clobber (match_scratch:SI 2 "=&q"))
11817 (clobber (reg:CC FLAGS_REG))]
11818 "!TARGET_CMOVE"
11819 "#"
11820 "&& reload_completed"
11821 [(parallel [(set (reg:CCZ FLAGS_REG)
11822 (compare:CCZ (match_dup 1) (const_int 0)))
11823 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11824 (set (strict_low_part (match_dup 3))
11825 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11826 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11827 (clobber (reg:CC FLAGS_REG))])
11828 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11829 (clobber (reg:CC FLAGS_REG))])
11830 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11831 (clobber (reg:CC FLAGS_REG))])]
11832 {
11833 operands[3] = gen_lowpart (QImode, operands[2]);
11834 ix86_expand_clear (operands[2]);
11835 })
11836
11837 (define_insn "*ffs<mode>_1"
11838 [(set (reg:CCZ FLAGS_REG)
11839 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11840 (const_int 0)))
11841 (set (match_operand:SWI48 0 "register_operand" "=r")
11842 (ctz:SWI48 (match_dup 1)))]
11843 ""
11844 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11845 [(set_attr "type" "alu1")
11846 (set_attr "prefix_0f" "1")
11847 (set_attr "mode" "<MODE>")])
11848
11849 (define_insn "ctz<mode>2"
11850 [(set (match_operand:SWI248 0 "register_operand" "=r")
11851 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11852 (clobber (reg:CC FLAGS_REG))]
11853 ""
11854 {
11855 if (TARGET_BMI)
11856 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11857 else
11858 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11859 }
11860 [(set_attr "type" "alu1")
11861 (set_attr "prefix_0f" "1")
11862 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11863 (set_attr "mode" "<MODE>")])
11864
11865 (define_expand "clz<mode>2"
11866 [(parallel
11867 [(set (match_operand:SWI248 0 "register_operand" "")
11868 (minus:SWI248
11869 (match_dup 2)
11870 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11871 (clobber (reg:CC FLAGS_REG))])
11872 (parallel
11873 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11874 (clobber (reg:CC FLAGS_REG))])]
11875 ""
11876 {
11877 if (TARGET_ABM)
11878 {
11879 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11880 DONE;
11881 }
11882 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11883 })
11884
11885 (define_insn "clz<mode>2_abm"
11886 [(set (match_operand:SWI248 0 "register_operand" "=r")
11887 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "TARGET_ABM || TARGET_BMI"
11890 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11891 [(set_attr "prefix_rep" "1")
11892 (set_attr "type" "bitmanip")
11893 (set_attr "mode" "<MODE>")])
11894
11895 ;; BMI instructions.
11896 (define_insn "*bmi_andn_<mode>"
11897 [(set (match_operand:SWI48 0 "register_operand" "=r")
11898 (and:SWI48
11899 (not:SWI48
11900 (match_operand:SWI48 1 "register_operand" "r"))
11901 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11902 (clobber (reg:CC FLAGS_REG))]
11903 "TARGET_BMI"
11904 "andn\t{%2, %1, %0|%0, %1, %2}"
11905 [(set_attr "type" "bitmanip")
11906 (set_attr "mode" "<MODE>")])
11907
11908 (define_insn "bmi_bextr_<mode>"
11909 [(set (match_operand:SWI48 0 "register_operand" "=r")
11910 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11911 (match_operand:SWI48 2 "register_operand" "r")]
11912 UNSPEC_BEXTR))
11913 (clobber (reg:CC FLAGS_REG))]
11914 "TARGET_BMI"
11915 "bextr\t{%2, %1, %0|%0, %1, %2}"
11916 [(set_attr "type" "bitmanip")
11917 (set_attr "mode" "<MODE>")])
11918
11919 (define_insn "*bmi_blsi_<mode>"
11920 [(set (match_operand:SWI48 0 "register_operand" "=r")
11921 (and:SWI48
11922 (neg:SWI48
11923 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11924 (match_dup 1)))
11925 (clobber (reg:CC FLAGS_REG))]
11926 "TARGET_BMI"
11927 "blsi\t{%1, %0|%0, %1}"
11928 [(set_attr "type" "bitmanip")
11929 (set_attr "mode" "<MODE>")])
11930
11931 (define_insn "*bmi_blsmsk_<mode>"
11932 [(set (match_operand:SWI48 0 "register_operand" "=r")
11933 (xor:SWI48
11934 (plus:SWI48
11935 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11936 (const_int -1))
11937 (match_dup 1)))
11938 (clobber (reg:CC FLAGS_REG))]
11939 "TARGET_BMI"
11940 "blsmsk\t{%1, %0|%0, %1}"
11941 [(set_attr "type" "bitmanip")
11942 (set_attr "mode" "<MODE>")])
11943
11944 (define_insn "*bmi_blsr_<mode>"
11945 [(set (match_operand:SWI48 0 "register_operand" "=r")
11946 (and:SWI48
11947 (plus:SWI48
11948 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11949 (const_int -1))
11950 (match_dup 1)))
11951 (clobber (reg:CC FLAGS_REG))]
11952 "TARGET_BMI"
11953 "blsr\t{%1, %0|%0, %1}"
11954 [(set_attr "type" "bitmanip")
11955 (set_attr "mode" "<MODE>")])
11956
11957 ;; TBM instructions.
11958 (define_insn "tbm_bextri_<mode>"
11959 [(set (match_operand:SWI48 0 "register_operand" "=r")
11960 (zero_extract:SWI48
11961 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11962 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11963 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11964 (clobber (reg:CC FLAGS_REG))]
11965 "TARGET_TBM"
11966 {
11967 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11968 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11969 }
11970 [(set_attr "type" "bitmanip")
11971 (set_attr "mode" "<MODE>")])
11972
11973 (define_insn "*tbm_blcfill_<mode>"
11974 [(set (match_operand:SWI48 0 "register_operand" "=r")
11975 (and:SWI48
11976 (plus:SWI48
11977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11978 (const_int 1))
11979 (match_dup 1)))
11980 (clobber (reg:CC FLAGS_REG))]
11981 "TARGET_TBM"
11982 "blcfill\t{%1, %0|%0, %1}"
11983 [(set_attr "type" "bitmanip")
11984 (set_attr "mode" "<MODE>")])
11985
11986 (define_insn "*tbm_blci_<mode>"
11987 [(set (match_operand:SWI48 0 "register_operand" "=r")
11988 (ior:SWI48
11989 (not:SWI48
11990 (plus:SWI48
11991 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11992 (const_int 1)))
11993 (match_dup 1)))
11994 (clobber (reg:CC FLAGS_REG))]
11995 "TARGET_TBM"
11996 "blci\t{%1, %0|%0, %1}"
11997 [(set_attr "type" "bitmanip")
11998 (set_attr "mode" "<MODE>")])
11999
12000 (define_insn "*tbm_blcic_<mode>"
12001 [(set (match_operand:SWI48 0 "register_operand" "=r")
12002 (and:SWI48
12003 (plus:SWI48
12004 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12005 (const_int 1))
12006 (not:SWI48
12007 (match_dup 1))))
12008 (clobber (reg:CC FLAGS_REG))]
12009 "TARGET_TBM"
12010 "blcic\t{%1, %0|%0, %1}"
12011 [(set_attr "type" "bitmanip")
12012 (set_attr "mode" "<MODE>")])
12013
12014 (define_insn "*tbm_blcmsk_<mode>"
12015 [(set (match_operand:SWI48 0 "register_operand" "=r")
12016 (xor:SWI48
12017 (plus:SWI48
12018 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12019 (const_int 1))
12020 (match_dup 1)))
12021 (clobber (reg:CC FLAGS_REG))]
12022 "TARGET_TBM"
12023 "blcmsk\t{%1, %0|%0, %1}"
12024 [(set_attr "type" "bitmanip")
12025 (set_attr "mode" "<MODE>")])
12026
12027 (define_insn "*tbm_blcs_<mode>"
12028 [(set (match_operand:SWI48 0 "register_operand" "=r")
12029 (ior:SWI48
12030 (plus:SWI48
12031 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12032 (const_int 1))
12033 (match_dup 1)))
12034 (clobber (reg:CC FLAGS_REG))]
12035 "TARGET_TBM"
12036 "blcs\t{%1, %0|%0, %1}"
12037 [(set_attr "type" "bitmanip")
12038 (set_attr "mode" "<MODE>")])
12039
12040 (define_insn "*tbm_blsfill_<mode>"
12041 [(set (match_operand:SWI48 0 "register_operand" "=r")
12042 (ior:SWI48
12043 (plus:SWI48
12044 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12045 (const_int -1))
12046 (match_dup 1)))
12047 (clobber (reg:CC FLAGS_REG))]
12048 "TARGET_TBM"
12049 "blsfill\t{%1, %0|%0, %1}"
12050 [(set_attr "type" "bitmanip")
12051 (set_attr "mode" "<MODE>")])
12052
12053 (define_insn "*tbm_blsic_<mode>"
12054 [(set (match_operand:SWI48 0 "register_operand" "=r")
12055 (ior:SWI48
12056 (plus:SWI48
12057 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12058 (const_int -1))
12059 (not:SWI48
12060 (match_dup 1))))
12061 (clobber (reg:CC FLAGS_REG))]
12062 "TARGET_TBM"
12063 "blsic\t{%1, %0|%0, %1}"
12064 [(set_attr "type" "bitmanip")
12065 (set_attr "mode" "<MODE>")])
12066
12067 (define_insn "*tbm_t1mskc_<mode>"
12068 [(set (match_operand:SWI48 0 "register_operand" "=r")
12069 (ior:SWI48
12070 (plus:SWI48
12071 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12072 (const_int 1))
12073 (not:SWI48
12074 (match_dup 1))))
12075 (clobber (reg:CC FLAGS_REG))]
12076 "TARGET_TBM"
12077 "t1mskc\t{%1, %0|%0, %1}"
12078 [(set_attr "type" "bitmanip")
12079 (set_attr "mode" "<MODE>")])
12080
12081 (define_insn "*tbm_tzmsk_<mode>"
12082 [(set (match_operand:SWI48 0 "register_operand" "=r")
12083 (and:SWI48
12084 (plus:SWI48
12085 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12086 (const_int -1))
12087 (not:SWI48
12088 (match_dup 1))))
12089 (clobber (reg:CC FLAGS_REG))]
12090 "TARGET_TBM"
12091 "tzmsk\t{%1, %0|%0, %1}"
12092 [(set_attr "type" "bitmanip")
12093 (set_attr "mode" "<MODE>")])
12094
12095 (define_insn "bsr_rex64"
12096 [(set (match_operand:DI 0 "register_operand" "=r")
12097 (minus:DI (const_int 63)
12098 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12099 (clobber (reg:CC FLAGS_REG))]
12100 "TARGET_64BIT"
12101 "bsr{q}\t{%1, %0|%0, %1}"
12102 [(set_attr "type" "alu1")
12103 (set_attr "prefix_0f" "1")
12104 (set_attr "mode" "DI")])
12105
12106 (define_insn "bsr"
12107 [(set (match_operand:SI 0 "register_operand" "=r")
12108 (minus:SI (const_int 31)
12109 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12110 (clobber (reg:CC FLAGS_REG))]
12111 ""
12112 "bsr{l}\t{%1, %0|%0, %1}"
12113 [(set_attr "type" "alu1")
12114 (set_attr "prefix_0f" "1")
12115 (set_attr "mode" "SI")])
12116
12117 (define_insn "*bsrhi"
12118 [(set (match_operand:HI 0 "register_operand" "=r")
12119 (minus:HI (const_int 15)
12120 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12121 (clobber (reg:CC FLAGS_REG))]
12122 ""
12123 "bsr{w}\t{%1, %0|%0, %1}"
12124 [(set_attr "type" "alu1")
12125 (set_attr "prefix_0f" "1")
12126 (set_attr "mode" "HI")])
12127
12128 (define_insn "popcount<mode>2"
12129 [(set (match_operand:SWI248 0 "register_operand" "=r")
12130 (popcount:SWI248
12131 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12132 (clobber (reg:CC FLAGS_REG))]
12133 "TARGET_POPCNT"
12134 {
12135 #if TARGET_MACHO
12136 return "popcnt\t{%1, %0|%0, %1}";
12137 #else
12138 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12139 #endif
12140 }
12141 [(set_attr "prefix_rep" "1")
12142 (set_attr "type" "bitmanip")
12143 (set_attr "mode" "<MODE>")])
12144
12145 (define_insn "*popcount<mode>2_cmp"
12146 [(set (reg FLAGS_REG)
12147 (compare
12148 (popcount:SWI248
12149 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12150 (const_int 0)))
12151 (set (match_operand:SWI248 0 "register_operand" "=r")
12152 (popcount:SWI248 (match_dup 1)))]
12153 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12154 {
12155 #if TARGET_MACHO
12156 return "popcnt\t{%1, %0|%0, %1}";
12157 #else
12158 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12159 #endif
12160 }
12161 [(set_attr "prefix_rep" "1")
12162 (set_attr "type" "bitmanip")
12163 (set_attr "mode" "<MODE>")])
12164
12165 (define_insn "*popcountsi2_cmp_zext"
12166 [(set (reg FLAGS_REG)
12167 (compare
12168 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12169 (const_int 0)))
12170 (set (match_operand:DI 0 "register_operand" "=r")
12171 (zero_extend:DI(popcount:SI (match_dup 1))))]
12172 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12173 {
12174 #if TARGET_MACHO
12175 return "popcnt\t{%1, %0|%0, %1}";
12176 #else
12177 return "popcnt{l}\t{%1, %0|%0, %1}";
12178 #endif
12179 }
12180 [(set_attr "prefix_rep" "1")
12181 (set_attr "type" "bitmanip")
12182 (set_attr "mode" "SI")])
12183
12184 (define_expand "bswap<mode>2"
12185 [(set (match_operand:SWI48 0 "register_operand" "")
12186 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12187 ""
12188 {
12189 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12190 {
12191 rtx x = operands[0];
12192
12193 emit_move_insn (x, operands[1]);
12194 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12195 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12196 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12197 DONE;
12198 }
12199 })
12200
12201 (define_insn "*bswap<mode>2_movbe"
12202 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12203 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12204 "TARGET_MOVBE
12205 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12206 "@
12207 bswap\t%0
12208 movbe\t{%1, %0|%0, %1}
12209 movbe\t{%1, %0|%0, %1}"
12210 [(set_attr "type" "bitmanip,imov,imov")
12211 (set_attr "modrm" "0,1,1")
12212 (set_attr "prefix_0f" "*,1,1")
12213 (set_attr "prefix_extra" "*,1,1")
12214 (set_attr "mode" "<MODE>")])
12215
12216 (define_insn "*bswap<mode>2_1"
12217 [(set (match_operand:SWI48 0 "register_operand" "=r")
12218 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12219 "TARGET_BSWAP"
12220 "bswap\t%0"
12221 [(set_attr "type" "bitmanip")
12222 (set_attr "modrm" "0")
12223 (set_attr "mode" "<MODE>")])
12224
12225 (define_insn "*bswaphi_lowpart_1"
12226 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12227 (bswap:HI (match_dup 0)))
12228 (clobber (reg:CC FLAGS_REG))]
12229 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12230 "@
12231 xchg{b}\t{%h0, %b0|%b0, %h0}
12232 rol{w}\t{$8, %0|%0, 8}"
12233 [(set_attr "length" "2,4")
12234 (set_attr "mode" "QI,HI")])
12235
12236 (define_insn "bswaphi_lowpart"
12237 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12238 (bswap:HI (match_dup 0)))
12239 (clobber (reg:CC FLAGS_REG))]
12240 ""
12241 "rol{w}\t{$8, %0|%0, 8}"
12242 [(set_attr "length" "4")
12243 (set_attr "mode" "HI")])
12244
12245 (define_expand "paritydi2"
12246 [(set (match_operand:DI 0 "register_operand" "")
12247 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12248 "! TARGET_POPCNT"
12249 {
12250 rtx scratch = gen_reg_rtx (QImode);
12251 rtx cond;
12252
12253 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12254 NULL_RTX, operands[1]));
12255
12256 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12257 gen_rtx_REG (CCmode, FLAGS_REG),
12258 const0_rtx);
12259 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12260
12261 if (TARGET_64BIT)
12262 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12263 else
12264 {
12265 rtx tmp = gen_reg_rtx (SImode);
12266
12267 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12268 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12269 }
12270 DONE;
12271 })
12272
12273 (define_expand "paritysi2"
12274 [(set (match_operand:SI 0 "register_operand" "")
12275 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12276 "! TARGET_POPCNT"
12277 {
12278 rtx scratch = gen_reg_rtx (QImode);
12279 rtx cond;
12280
12281 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12282
12283 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12284 gen_rtx_REG (CCmode, FLAGS_REG),
12285 const0_rtx);
12286 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12287
12288 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12289 DONE;
12290 })
12291
12292 (define_insn_and_split "paritydi2_cmp"
12293 [(set (reg:CC FLAGS_REG)
12294 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12295 UNSPEC_PARITY))
12296 (clobber (match_scratch:DI 0 "=r"))
12297 (clobber (match_scratch:SI 1 "=&r"))
12298 (clobber (match_scratch:HI 2 "=Q"))]
12299 "! TARGET_POPCNT"
12300 "#"
12301 "&& reload_completed"
12302 [(parallel
12303 [(set (match_dup 1)
12304 (xor:SI (match_dup 1) (match_dup 4)))
12305 (clobber (reg:CC FLAGS_REG))])
12306 (parallel
12307 [(set (reg:CC FLAGS_REG)
12308 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12309 (clobber (match_dup 1))
12310 (clobber (match_dup 2))])]
12311 {
12312 operands[4] = gen_lowpart (SImode, operands[3]);
12313
12314 if (TARGET_64BIT)
12315 {
12316 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12317 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12318 }
12319 else
12320 operands[1] = gen_highpart (SImode, operands[3]);
12321 })
12322
12323 (define_insn_and_split "paritysi2_cmp"
12324 [(set (reg:CC FLAGS_REG)
12325 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12326 UNSPEC_PARITY))
12327 (clobber (match_scratch:SI 0 "=r"))
12328 (clobber (match_scratch:HI 1 "=&Q"))]
12329 "! TARGET_POPCNT"
12330 "#"
12331 "&& reload_completed"
12332 [(parallel
12333 [(set (match_dup 1)
12334 (xor:HI (match_dup 1) (match_dup 3)))
12335 (clobber (reg:CC FLAGS_REG))])
12336 (parallel
12337 [(set (reg:CC FLAGS_REG)
12338 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12339 (clobber (match_dup 1))])]
12340 {
12341 operands[3] = gen_lowpart (HImode, operands[2]);
12342
12343 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12344 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12345 })
12346
12347 (define_insn "*parityhi2_cmp"
12348 [(set (reg:CC FLAGS_REG)
12349 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12350 UNSPEC_PARITY))
12351 (clobber (match_scratch:HI 0 "=Q"))]
12352 "! TARGET_POPCNT"
12353 "xor{b}\t{%h0, %b0|%b0, %h0}"
12354 [(set_attr "length" "2")
12355 (set_attr "mode" "HI")])
12356 \f
12357 ;; Thread-local storage patterns for ELF.
12358 ;;
12359 ;; Note that these code sequences must appear exactly as shown
12360 ;; in order to allow linker relaxation.
12361
12362 (define_insn "*tls_global_dynamic_32_gnu"
12363 [(set (match_operand:SI 0 "register_operand" "=a")
12364 (unspec:SI
12365 [(match_operand:SI 1 "register_operand" "b")
12366 (match_operand:SI 2 "tls_symbolic_operand" "")
12367 (match_operand:SI 3 "constant_call_address_operand" "z")]
12368 UNSPEC_TLS_GD))
12369 (clobber (match_scratch:SI 4 "=d"))
12370 (clobber (match_scratch:SI 5 "=c"))
12371 (clobber (reg:CC FLAGS_REG))]
12372 "!TARGET_64BIT && TARGET_GNU_TLS"
12373 {
12374 output_asm_insn
12375 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12376 if (TARGET_SUN_TLS)
12377 #ifdef HAVE_AS_IX86_TLSGDPLT
12378 return "call\t%a2@tlsgdplt";
12379 #else
12380 return "call\t%p3@plt";
12381 #endif
12382 return "call\t%P3";
12383 }
12384 [(set_attr "type" "multi")
12385 (set_attr "length" "12")])
12386
12387 (define_expand "tls_global_dynamic_32"
12388 [(parallel
12389 [(set (match_operand:SI 0 "register_operand" "")
12390 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12391 (match_operand:SI 1 "tls_symbolic_operand" "")
12392 (match_operand:SI 3 "constant_call_address_operand" "")]
12393 UNSPEC_TLS_GD))
12394 (clobber (match_scratch:SI 4 ""))
12395 (clobber (match_scratch:SI 5 ""))
12396 (clobber (reg:CC FLAGS_REG))])])
12397
12398 (define_insn "*tls_global_dynamic_64"
12399 [(set (match_operand:DI 0 "register_operand" "=a")
12400 (call:DI
12401 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12402 (match_operand:DI 3 "" "")))
12403 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12404 UNSPEC_TLS_GD)]
12405 "TARGET_64BIT"
12406 {
12407 fputs (ASM_BYTE "0x66\n", asm_out_file);
12408 output_asm_insn
12409 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12410 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12411 fputs ("\trex64\n", asm_out_file);
12412 if (TARGET_SUN_TLS)
12413 return "call\t%p2@plt";
12414 return "call\t%P2";
12415 }
12416 [(set_attr "type" "multi")
12417 (set_attr "length" "16")])
12418
12419 (define_expand "tls_global_dynamic_64"
12420 [(parallel
12421 [(set (match_operand:DI 0 "register_operand" "")
12422 (call:DI
12423 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12424 (const_int 0)))
12425 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12426 UNSPEC_TLS_GD)])])
12427
12428 (define_insn "*tls_local_dynamic_base_32_gnu"
12429 [(set (match_operand:SI 0 "register_operand" "=a")
12430 (unspec:SI
12431 [(match_operand:SI 1 "register_operand" "b")
12432 (match_operand:SI 2 "constant_call_address_operand" "z")]
12433 UNSPEC_TLS_LD_BASE))
12434 (clobber (match_scratch:SI 3 "=d"))
12435 (clobber (match_scratch:SI 4 "=c"))
12436 (clobber (reg:CC FLAGS_REG))]
12437 "!TARGET_64BIT && TARGET_GNU_TLS"
12438 {
12439 output_asm_insn
12440 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12441 if (TARGET_SUN_TLS)
12442 #ifdef HAVE_AS_IX86_TLSLDMPLT
12443 return "call\t%&@tlsldmplt";
12444 #else
12445 return "call\t%p2@plt";
12446 #endif
12447 return "call\t%P2";
12448 }
12449 [(set_attr "type" "multi")
12450 (set_attr "length" "11")])
12451
12452 (define_expand "tls_local_dynamic_base_32"
12453 [(parallel
12454 [(set (match_operand:SI 0 "register_operand" "")
12455 (unspec:SI
12456 [(match_operand:SI 1 "register_operand" "")
12457 (match_operand:SI 2 "constant_call_address_operand" "")]
12458 UNSPEC_TLS_LD_BASE))
12459 (clobber (match_scratch:SI 3 ""))
12460 (clobber (match_scratch:SI 4 ""))
12461 (clobber (reg:CC FLAGS_REG))])])
12462
12463 (define_insn "*tls_local_dynamic_base_64"
12464 [(set (match_operand:DI 0 "register_operand" "=a")
12465 (call:DI
12466 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12467 (match_operand:DI 2 "" "")))
12468 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12469 "TARGET_64BIT"
12470 {
12471 output_asm_insn
12472 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12473 if (TARGET_SUN_TLS)
12474 return "call\t%p1@plt";
12475 return "call\t%P1";
12476 }
12477 [(set_attr "type" "multi")
12478 (set_attr "length" "12")])
12479
12480 (define_expand "tls_local_dynamic_base_64"
12481 [(parallel
12482 [(set (match_operand:DI 0 "register_operand" "")
12483 (call:DI
12484 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12485 (const_int 0)))
12486 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12487
12488 ;; Local dynamic of a single variable is a lose. Show combine how
12489 ;; to convert that back to global dynamic.
12490
12491 (define_insn_and_split "*tls_local_dynamic_32_once"
12492 [(set (match_operand:SI 0 "register_operand" "=a")
12493 (plus:SI
12494 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12495 (match_operand:SI 2 "constant_call_address_operand" "z")]
12496 UNSPEC_TLS_LD_BASE)
12497 (const:SI (unspec:SI
12498 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12499 UNSPEC_DTPOFF))))
12500 (clobber (match_scratch:SI 4 "=d"))
12501 (clobber (match_scratch:SI 5 "=c"))
12502 (clobber (reg:CC FLAGS_REG))]
12503 ""
12504 "#"
12505 ""
12506 [(parallel
12507 [(set (match_dup 0)
12508 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12509 UNSPEC_TLS_GD))
12510 (clobber (match_dup 4))
12511 (clobber (match_dup 5))
12512 (clobber (reg:CC FLAGS_REG))])])
12513
12514 ;; Segment register for the thread base ptr load
12515 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12516
12517 ;; Load and add the thread base pointer from %<tp_seg>:0.
12518 (define_insn "*load_tp_<mode>"
12519 [(set (match_operand:P 0 "register_operand" "=r")
12520 (unspec:P [(const_int 0)] UNSPEC_TP))]
12521 ""
12522 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12523 [(set_attr "type" "imov")
12524 (set_attr "modrm" "0")
12525 (set_attr "length" "7")
12526 (set_attr "memory" "load")
12527 (set_attr "imm_disp" "false")])
12528
12529 (define_insn "*add_tp_<mode>"
12530 [(set (match_operand:P 0 "register_operand" "=r")
12531 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12532 (match_operand:P 1 "register_operand" "0")))
12533 (clobber (reg:CC FLAGS_REG))]
12534 ""
12535 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12536 [(set_attr "type" "alu")
12537 (set_attr "modrm" "0")
12538 (set_attr "length" "7")
12539 (set_attr "memory" "load")
12540 (set_attr "imm_disp" "false")])
12541
12542 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12543 ;; %rax as destination of the initial executable code sequence.
12544 (define_insn "tls_initial_exec_64_sun"
12545 [(set (match_operand:DI 0 "register_operand" "=a")
12546 (unspec:DI
12547 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12548 UNSPEC_TLS_IE_SUN))
12549 (clobber (reg:CC FLAGS_REG))]
12550 "TARGET_64BIT && TARGET_SUN_TLS"
12551 {
12552 output_asm_insn
12553 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12554 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12555 }
12556 [(set_attr "type" "multi")])
12557
12558 ;; GNU2 TLS patterns can be split.
12559
12560 (define_expand "tls_dynamic_gnu2_32"
12561 [(set (match_dup 3)
12562 (plus:SI (match_operand:SI 2 "register_operand" "")
12563 (const:SI
12564 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12565 UNSPEC_TLSDESC))))
12566 (parallel
12567 [(set (match_operand:SI 0 "register_operand" "")
12568 (unspec:SI [(match_dup 1) (match_dup 3)
12569 (match_dup 2) (reg:SI SP_REG)]
12570 UNSPEC_TLSDESC))
12571 (clobber (reg:CC FLAGS_REG))])]
12572 "!TARGET_64BIT && TARGET_GNU2_TLS"
12573 {
12574 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12575 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12576 })
12577
12578 (define_insn "*tls_dynamic_lea_32"
12579 [(set (match_operand:SI 0 "register_operand" "=r")
12580 (plus:SI (match_operand:SI 1 "register_operand" "b")
12581 (const:SI
12582 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12583 UNSPEC_TLSDESC))))]
12584 "!TARGET_64BIT && TARGET_GNU2_TLS"
12585 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12586 [(set_attr "type" "lea")
12587 (set_attr "mode" "SI")
12588 (set_attr "length" "6")
12589 (set_attr "length_address" "4")])
12590
12591 (define_insn "*tls_dynamic_call_32"
12592 [(set (match_operand:SI 0 "register_operand" "=a")
12593 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12594 (match_operand:SI 2 "register_operand" "0")
12595 ;; we have to make sure %ebx still points to the GOT
12596 (match_operand:SI 3 "register_operand" "b")
12597 (reg:SI SP_REG)]
12598 UNSPEC_TLSDESC))
12599 (clobber (reg:CC FLAGS_REG))]
12600 "!TARGET_64BIT && TARGET_GNU2_TLS"
12601 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12602 [(set_attr "type" "call")
12603 (set_attr "length" "2")
12604 (set_attr "length_address" "0")])
12605
12606 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12607 [(set (match_operand:SI 0 "register_operand" "=&a")
12608 (plus:SI
12609 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12610 (match_operand:SI 4 "" "")
12611 (match_operand:SI 2 "register_operand" "b")
12612 (reg:SI SP_REG)]
12613 UNSPEC_TLSDESC)
12614 (const:SI (unspec:SI
12615 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12616 UNSPEC_DTPOFF))))
12617 (clobber (reg:CC FLAGS_REG))]
12618 "!TARGET_64BIT && TARGET_GNU2_TLS"
12619 "#"
12620 ""
12621 [(set (match_dup 0) (match_dup 5))]
12622 {
12623 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12624 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12625 })
12626
12627 (define_expand "tls_dynamic_gnu2_64"
12628 [(set (match_dup 2)
12629 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12630 UNSPEC_TLSDESC))
12631 (parallel
12632 [(set (match_operand:DI 0 "register_operand" "")
12633 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12634 UNSPEC_TLSDESC))
12635 (clobber (reg:CC FLAGS_REG))])]
12636 "TARGET_64BIT && TARGET_GNU2_TLS"
12637 {
12638 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12639 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12640 })
12641
12642 (define_insn "*tls_dynamic_lea_64"
12643 [(set (match_operand:DI 0 "register_operand" "=r")
12644 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12645 UNSPEC_TLSDESC))]
12646 "TARGET_64BIT && TARGET_GNU2_TLS"
12647 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12648 [(set_attr "type" "lea")
12649 (set_attr "mode" "DI")
12650 (set_attr "length" "7")
12651 (set_attr "length_address" "4")])
12652
12653 (define_insn "*tls_dynamic_call_64"
12654 [(set (match_operand:DI 0 "register_operand" "=a")
12655 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12656 (match_operand:DI 2 "register_operand" "0")
12657 (reg:DI SP_REG)]
12658 UNSPEC_TLSDESC))
12659 (clobber (reg:CC FLAGS_REG))]
12660 "TARGET_64BIT && TARGET_GNU2_TLS"
12661 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12662 [(set_attr "type" "call")
12663 (set_attr "length" "2")
12664 (set_attr "length_address" "0")])
12665
12666 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12667 [(set (match_operand:DI 0 "register_operand" "=&a")
12668 (plus:DI
12669 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12670 (match_operand:DI 3 "" "")
12671 (reg:DI SP_REG)]
12672 UNSPEC_TLSDESC)
12673 (const:DI (unspec:DI
12674 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12675 UNSPEC_DTPOFF))))
12676 (clobber (reg:CC FLAGS_REG))]
12677 "TARGET_64BIT && TARGET_GNU2_TLS"
12678 "#"
12679 ""
12680 [(set (match_dup 0) (match_dup 4))]
12681 {
12682 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12683 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12684 })
12685 \f
12686 ;; These patterns match the binary 387 instructions for addM3, subM3,
12687 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12688 ;; SFmode. The first is the normal insn, the second the same insn but
12689 ;; with one operand a conversion, and the third the same insn but with
12690 ;; the other operand a conversion. The conversion may be SFmode or
12691 ;; SImode if the target mode DFmode, but only SImode if the target mode
12692 ;; is SFmode.
12693
12694 ;; Gcc is slightly more smart about handling normal two address instructions
12695 ;; so use special patterns for add and mull.
12696
12697 (define_insn "*fop_<mode>_comm_mixed"
12698 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12699 (match_operator:MODEF 3 "binary_fp_operator"
12700 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12701 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12702 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12703 && COMMUTATIVE_ARITH_P (operands[3])
12704 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12705 "* return output_387_binary_op (insn, operands);"
12706 [(set (attr "type")
12707 (if_then_else (eq_attr "alternative" "1,2")
12708 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12709 (const_string "ssemul")
12710 (const_string "sseadd"))
12711 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12712 (const_string "fmul")
12713 (const_string "fop"))))
12714 (set_attr "isa" "*,noavx,avx")
12715 (set_attr "prefix" "orig,orig,vex")
12716 (set_attr "mode" "<MODE>")])
12717
12718 (define_insn "*fop_<mode>_comm_sse"
12719 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12720 (match_operator:MODEF 3 "binary_fp_operator"
12721 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12722 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12723 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12724 && COMMUTATIVE_ARITH_P (operands[3])
12725 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12726 "* return output_387_binary_op (insn, operands);"
12727 [(set (attr "type")
12728 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12729 (const_string "ssemul")
12730 (const_string "sseadd")))
12731 (set_attr "isa" "noavx,avx")
12732 (set_attr "prefix" "orig,vex")
12733 (set_attr "mode" "<MODE>")])
12734
12735 (define_insn "*fop_<mode>_comm_i387"
12736 [(set (match_operand:MODEF 0 "register_operand" "=f")
12737 (match_operator:MODEF 3 "binary_fp_operator"
12738 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12739 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12740 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12741 && COMMUTATIVE_ARITH_P (operands[3])
12742 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12743 "* return output_387_binary_op (insn, operands);"
12744 [(set (attr "type")
12745 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12746 (const_string "fmul")
12747 (const_string "fop")))
12748 (set_attr "mode" "<MODE>")])
12749
12750 (define_insn "*fop_<mode>_1_mixed"
12751 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12752 (match_operator:MODEF 3 "binary_fp_operator"
12753 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12754 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12755 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12756 && !COMMUTATIVE_ARITH_P (operands[3])
12757 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12758 "* return output_387_binary_op (insn, operands);"
12759 [(set (attr "type")
12760 (cond [(and (eq_attr "alternative" "2,3")
12761 (match_operand:MODEF 3 "mult_operator" ""))
12762 (const_string "ssemul")
12763 (and (eq_attr "alternative" "2,3")
12764 (match_operand:MODEF 3 "div_operator" ""))
12765 (const_string "ssediv")
12766 (eq_attr "alternative" "2,3")
12767 (const_string "sseadd")
12768 (match_operand:MODEF 3 "mult_operator" "")
12769 (const_string "fmul")
12770 (match_operand:MODEF 3 "div_operator" "")
12771 (const_string "fdiv")
12772 ]
12773 (const_string "fop")))
12774 (set_attr "isa" "*,*,noavx,avx")
12775 (set_attr "prefix" "orig,orig,orig,vex")
12776 (set_attr "mode" "<MODE>")])
12777
12778 (define_insn "*rcpsf2_sse"
12779 [(set (match_operand:SF 0 "register_operand" "=x")
12780 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12781 UNSPEC_RCP))]
12782 "TARGET_SSE_MATH"
12783 "%vrcpss\t{%1, %d0|%d0, %1}"
12784 [(set_attr "type" "sse")
12785 (set_attr "atom_sse_attr" "rcp")
12786 (set_attr "prefix" "maybe_vex")
12787 (set_attr "mode" "SF")])
12788
12789 (define_insn "*fop_<mode>_1_sse"
12790 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12791 (match_operator:MODEF 3 "binary_fp_operator"
12792 [(match_operand:MODEF 1 "register_operand" "0,x")
12793 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12794 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12795 && !COMMUTATIVE_ARITH_P (operands[3])"
12796 "* return output_387_binary_op (insn, operands);"
12797 [(set (attr "type")
12798 (cond [(match_operand:MODEF 3 "mult_operator" "")
12799 (const_string "ssemul")
12800 (match_operand:MODEF 3 "div_operator" "")
12801 (const_string "ssediv")
12802 ]
12803 (const_string "sseadd")))
12804 (set_attr "isa" "noavx,avx")
12805 (set_attr "prefix" "orig,vex")
12806 (set_attr "mode" "<MODE>")])
12807
12808 ;; This pattern is not fully shadowed by the pattern above.
12809 (define_insn "*fop_<mode>_1_i387"
12810 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12811 (match_operator:MODEF 3 "binary_fp_operator"
12812 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12813 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12814 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12815 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12816 && !COMMUTATIVE_ARITH_P (operands[3])
12817 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12818 "* return output_387_binary_op (insn, operands);"
12819 [(set (attr "type")
12820 (cond [(match_operand:MODEF 3 "mult_operator" "")
12821 (const_string "fmul")
12822 (match_operand:MODEF 3 "div_operator" "")
12823 (const_string "fdiv")
12824 ]
12825 (const_string "fop")))
12826 (set_attr "mode" "<MODE>")])
12827
12828 ;; ??? Add SSE splitters for these!
12829 (define_insn "*fop_<MODEF:mode>_2_i387"
12830 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12831 (match_operator:MODEF 3 "binary_fp_operator"
12832 [(float:MODEF
12833 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12834 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12835 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12836 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12837 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12838 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12839 [(set (attr "type")
12840 (cond [(match_operand:MODEF 3 "mult_operator" "")
12841 (const_string "fmul")
12842 (match_operand:MODEF 3 "div_operator" "")
12843 (const_string "fdiv")
12844 ]
12845 (const_string "fop")))
12846 (set_attr "fp_int_src" "true")
12847 (set_attr "mode" "<SWI24:MODE>")])
12848
12849 (define_insn "*fop_<MODEF:mode>_3_i387"
12850 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12851 (match_operator:MODEF 3 "binary_fp_operator"
12852 [(match_operand:MODEF 1 "register_operand" "0,0")
12853 (float:MODEF
12854 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12855 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12856 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12857 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12858 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12859 [(set (attr "type")
12860 (cond [(match_operand:MODEF 3 "mult_operator" "")
12861 (const_string "fmul")
12862 (match_operand:MODEF 3 "div_operator" "")
12863 (const_string "fdiv")
12864 ]
12865 (const_string "fop")))
12866 (set_attr "fp_int_src" "true")
12867 (set_attr "mode" "<MODE>")])
12868
12869 (define_insn "*fop_df_4_i387"
12870 [(set (match_operand:DF 0 "register_operand" "=f,f")
12871 (match_operator:DF 3 "binary_fp_operator"
12872 [(float_extend:DF
12873 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12874 (match_operand:DF 2 "register_operand" "0,f")]))]
12875 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12876 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12877 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12878 "* return output_387_binary_op (insn, operands);"
12879 [(set (attr "type")
12880 (cond [(match_operand:DF 3 "mult_operator" "")
12881 (const_string "fmul")
12882 (match_operand:DF 3 "div_operator" "")
12883 (const_string "fdiv")
12884 ]
12885 (const_string "fop")))
12886 (set_attr "mode" "SF")])
12887
12888 (define_insn "*fop_df_5_i387"
12889 [(set (match_operand:DF 0 "register_operand" "=f,f")
12890 (match_operator:DF 3 "binary_fp_operator"
12891 [(match_operand:DF 1 "register_operand" "0,f")
12892 (float_extend:DF
12893 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12894 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12895 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12896 "* return output_387_binary_op (insn, operands);"
12897 [(set (attr "type")
12898 (cond [(match_operand:DF 3 "mult_operator" "")
12899 (const_string "fmul")
12900 (match_operand:DF 3 "div_operator" "")
12901 (const_string "fdiv")
12902 ]
12903 (const_string "fop")))
12904 (set_attr "mode" "SF")])
12905
12906 (define_insn "*fop_df_6_i387"
12907 [(set (match_operand:DF 0 "register_operand" "=f,f")
12908 (match_operator:DF 3 "binary_fp_operator"
12909 [(float_extend:DF
12910 (match_operand:SF 1 "register_operand" "0,f"))
12911 (float_extend:DF
12912 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12913 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12914 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12915 "* return output_387_binary_op (insn, operands);"
12916 [(set (attr "type")
12917 (cond [(match_operand:DF 3 "mult_operator" "")
12918 (const_string "fmul")
12919 (match_operand:DF 3 "div_operator" "")
12920 (const_string "fdiv")
12921 ]
12922 (const_string "fop")))
12923 (set_attr "mode" "SF")])
12924
12925 (define_insn "*fop_xf_comm_i387"
12926 [(set (match_operand:XF 0 "register_operand" "=f")
12927 (match_operator:XF 3 "binary_fp_operator"
12928 [(match_operand:XF 1 "register_operand" "%0")
12929 (match_operand:XF 2 "register_operand" "f")]))]
12930 "TARGET_80387
12931 && COMMUTATIVE_ARITH_P (operands[3])"
12932 "* return output_387_binary_op (insn, operands);"
12933 [(set (attr "type")
12934 (if_then_else (match_operand:XF 3 "mult_operator" "")
12935 (const_string "fmul")
12936 (const_string "fop")))
12937 (set_attr "mode" "XF")])
12938
12939 (define_insn "*fop_xf_1_i387"
12940 [(set (match_operand:XF 0 "register_operand" "=f,f")
12941 (match_operator:XF 3 "binary_fp_operator"
12942 [(match_operand:XF 1 "register_operand" "0,f")
12943 (match_operand:XF 2 "register_operand" "f,0")]))]
12944 "TARGET_80387
12945 && !COMMUTATIVE_ARITH_P (operands[3])"
12946 "* return output_387_binary_op (insn, operands);"
12947 [(set (attr "type")
12948 (cond [(match_operand:XF 3 "mult_operator" "")
12949 (const_string "fmul")
12950 (match_operand:XF 3 "div_operator" "")
12951 (const_string "fdiv")
12952 ]
12953 (const_string "fop")))
12954 (set_attr "mode" "XF")])
12955
12956 (define_insn "*fop_xf_2_i387"
12957 [(set (match_operand:XF 0 "register_operand" "=f,f")
12958 (match_operator:XF 3 "binary_fp_operator"
12959 [(float:XF
12960 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12961 (match_operand:XF 2 "register_operand" "0,0")]))]
12962 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12963 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (cond [(match_operand:XF 3 "mult_operator" "")
12966 (const_string "fmul")
12967 (match_operand:XF 3 "div_operator" "")
12968 (const_string "fdiv")
12969 ]
12970 (const_string "fop")))
12971 (set_attr "fp_int_src" "true")
12972 (set_attr "mode" "<MODE>")])
12973
12974 (define_insn "*fop_xf_3_i387"
12975 [(set (match_operand:XF 0 "register_operand" "=f,f")
12976 (match_operator:XF 3 "binary_fp_operator"
12977 [(match_operand:XF 1 "register_operand" "0,0")
12978 (float:XF
12979 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12980 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12981 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12982 [(set (attr "type")
12983 (cond [(match_operand:XF 3 "mult_operator" "")
12984 (const_string "fmul")
12985 (match_operand:XF 3 "div_operator" "")
12986 (const_string "fdiv")
12987 ]
12988 (const_string "fop")))
12989 (set_attr "fp_int_src" "true")
12990 (set_attr "mode" "<MODE>")])
12991
12992 (define_insn "*fop_xf_4_i387"
12993 [(set (match_operand:XF 0 "register_operand" "=f,f")
12994 (match_operator:XF 3 "binary_fp_operator"
12995 [(float_extend:XF
12996 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12997 (match_operand:XF 2 "register_operand" "0,f")]))]
12998 "TARGET_80387"
12999 "* return output_387_binary_op (insn, operands);"
13000 [(set (attr "type")
13001 (cond [(match_operand:XF 3 "mult_operator" "")
13002 (const_string "fmul")
13003 (match_operand:XF 3 "div_operator" "")
13004 (const_string "fdiv")
13005 ]
13006 (const_string "fop")))
13007 (set_attr "mode" "<MODE>")])
13008
13009 (define_insn "*fop_xf_5_i387"
13010 [(set (match_operand:XF 0 "register_operand" "=f,f")
13011 (match_operator:XF 3 "binary_fp_operator"
13012 [(match_operand:XF 1 "register_operand" "0,f")
13013 (float_extend:XF
13014 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13015 "TARGET_80387"
13016 "* return output_387_binary_op (insn, operands);"
13017 [(set (attr "type")
13018 (cond [(match_operand:XF 3 "mult_operator" "")
13019 (const_string "fmul")
13020 (match_operand:XF 3 "div_operator" "")
13021 (const_string "fdiv")
13022 ]
13023 (const_string "fop")))
13024 (set_attr "mode" "<MODE>")])
13025
13026 (define_insn "*fop_xf_6_i387"
13027 [(set (match_operand:XF 0 "register_operand" "=f,f")
13028 (match_operator:XF 3 "binary_fp_operator"
13029 [(float_extend:XF
13030 (match_operand:MODEF 1 "register_operand" "0,f"))
13031 (float_extend:XF
13032 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13033 "TARGET_80387"
13034 "* return output_387_binary_op (insn, operands);"
13035 [(set (attr "type")
13036 (cond [(match_operand:XF 3 "mult_operator" "")
13037 (const_string "fmul")
13038 (match_operand:XF 3 "div_operator" "")
13039 (const_string "fdiv")
13040 ]
13041 (const_string "fop")))
13042 (set_attr "mode" "<MODE>")])
13043
13044 (define_split
13045 [(set (match_operand 0 "register_operand" "")
13046 (match_operator 3 "binary_fp_operator"
13047 [(float (match_operand:SWI24 1 "register_operand" ""))
13048 (match_operand 2 "register_operand" "")]))]
13049 "reload_completed
13050 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13051 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13052 [(const_int 0)]
13053 {
13054 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13055 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13056 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13057 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13058 GET_MODE (operands[3]),
13059 operands[4],
13060 operands[2])));
13061 ix86_free_from_memory (GET_MODE (operands[1]));
13062 DONE;
13063 })
13064
13065 (define_split
13066 [(set (match_operand 0 "register_operand" "")
13067 (match_operator 3 "binary_fp_operator"
13068 [(match_operand 1 "register_operand" "")
13069 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13070 "reload_completed
13071 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13072 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13073 [(const_int 0)]
13074 {
13075 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13076 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13077 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13078 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13079 GET_MODE (operands[3]),
13080 operands[1],
13081 operands[4])));
13082 ix86_free_from_memory (GET_MODE (operands[2]));
13083 DONE;
13084 })
13085 \f
13086 ;; FPU special functions.
13087
13088 ;; This pattern implements a no-op XFmode truncation for
13089 ;; all fancy i386 XFmode math functions.
13090
13091 (define_insn "truncxf<mode>2_i387_noop_unspec"
13092 [(set (match_operand:MODEF 0 "register_operand" "=f")
13093 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13094 UNSPEC_TRUNC_NOOP))]
13095 "TARGET_USE_FANCY_MATH_387"
13096 "* return output_387_reg_move (insn, operands);"
13097 [(set_attr "type" "fmov")
13098 (set_attr "mode" "<MODE>")])
13099
13100 (define_insn "sqrtxf2"
13101 [(set (match_operand:XF 0 "register_operand" "=f")
13102 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13103 "TARGET_USE_FANCY_MATH_387"
13104 "fsqrt"
13105 [(set_attr "type" "fpspc")
13106 (set_attr "mode" "XF")
13107 (set_attr "athlon_decode" "direct")
13108 (set_attr "amdfam10_decode" "direct")
13109 (set_attr "bdver1_decode" "direct")])
13110
13111 (define_insn "sqrt_extend<mode>xf2_i387"
13112 [(set (match_operand:XF 0 "register_operand" "=f")
13113 (sqrt:XF
13114 (float_extend:XF
13115 (match_operand:MODEF 1 "register_operand" "0"))))]
13116 "TARGET_USE_FANCY_MATH_387"
13117 "fsqrt"
13118 [(set_attr "type" "fpspc")
13119 (set_attr "mode" "XF")
13120 (set_attr "athlon_decode" "direct")
13121 (set_attr "amdfam10_decode" "direct")
13122 (set_attr "bdver1_decode" "direct")])
13123
13124 (define_insn "*rsqrtsf2_sse"
13125 [(set (match_operand:SF 0 "register_operand" "=x")
13126 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13127 UNSPEC_RSQRT))]
13128 "TARGET_SSE_MATH"
13129 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13130 [(set_attr "type" "sse")
13131 (set_attr "atom_sse_attr" "rcp")
13132 (set_attr "prefix" "maybe_vex")
13133 (set_attr "mode" "SF")])
13134
13135 (define_expand "rsqrtsf2"
13136 [(set (match_operand:SF 0 "register_operand" "")
13137 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13138 UNSPEC_RSQRT))]
13139 "TARGET_SSE_MATH"
13140 {
13141 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13142 DONE;
13143 })
13144
13145 (define_insn "*sqrt<mode>2_sse"
13146 [(set (match_operand:MODEF 0 "register_operand" "=x")
13147 (sqrt:MODEF
13148 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13149 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13150 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13151 [(set_attr "type" "sse")
13152 (set_attr "atom_sse_attr" "sqrt")
13153 (set_attr "prefix" "maybe_vex")
13154 (set_attr "mode" "<MODE>")
13155 (set_attr "athlon_decode" "*")
13156 (set_attr "amdfam10_decode" "*")
13157 (set_attr "bdver1_decode" "*")])
13158
13159 (define_expand "sqrt<mode>2"
13160 [(set (match_operand:MODEF 0 "register_operand" "")
13161 (sqrt:MODEF
13162 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13163 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13164 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13165 {
13166 if (<MODE>mode == SFmode
13167 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13168 && flag_finite_math_only && !flag_trapping_math
13169 && flag_unsafe_math_optimizations)
13170 {
13171 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13172 DONE;
13173 }
13174
13175 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13176 {
13177 rtx op0 = gen_reg_rtx (XFmode);
13178 rtx op1 = force_reg (<MODE>mode, operands[1]);
13179
13180 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13181 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13182 DONE;
13183 }
13184 })
13185
13186 (define_insn "fpremxf4_i387"
13187 [(set (match_operand:XF 0 "register_operand" "=f")
13188 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13189 (match_operand:XF 3 "register_operand" "1")]
13190 UNSPEC_FPREM_F))
13191 (set (match_operand:XF 1 "register_operand" "=u")
13192 (unspec:XF [(match_dup 2) (match_dup 3)]
13193 UNSPEC_FPREM_U))
13194 (set (reg:CCFP FPSR_REG)
13195 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13196 UNSPEC_C2_FLAG))]
13197 "TARGET_USE_FANCY_MATH_387"
13198 "fprem"
13199 [(set_attr "type" "fpspc")
13200 (set_attr "mode" "XF")])
13201
13202 (define_expand "fmodxf3"
13203 [(use (match_operand:XF 0 "register_operand" ""))
13204 (use (match_operand:XF 1 "general_operand" ""))
13205 (use (match_operand:XF 2 "general_operand" ""))]
13206 "TARGET_USE_FANCY_MATH_387"
13207 {
13208 rtx label = gen_label_rtx ();
13209
13210 rtx op1 = gen_reg_rtx (XFmode);
13211 rtx op2 = gen_reg_rtx (XFmode);
13212
13213 emit_move_insn (op2, operands[2]);
13214 emit_move_insn (op1, operands[1]);
13215
13216 emit_label (label);
13217 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13218 ix86_emit_fp_unordered_jump (label);
13219 LABEL_NUSES (label) = 1;
13220
13221 emit_move_insn (operands[0], op1);
13222 DONE;
13223 })
13224
13225 (define_expand "fmod<mode>3"
13226 [(use (match_operand:MODEF 0 "register_operand" ""))
13227 (use (match_operand:MODEF 1 "general_operand" ""))
13228 (use (match_operand:MODEF 2 "general_operand" ""))]
13229 "TARGET_USE_FANCY_MATH_387"
13230 {
13231 rtx (*gen_truncxf) (rtx, rtx);
13232
13233 rtx label = gen_label_rtx ();
13234
13235 rtx op1 = gen_reg_rtx (XFmode);
13236 rtx op2 = gen_reg_rtx (XFmode);
13237
13238 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13239 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13240
13241 emit_label (label);
13242 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13243 ix86_emit_fp_unordered_jump (label);
13244 LABEL_NUSES (label) = 1;
13245
13246 /* Truncate the result properly for strict SSE math. */
13247 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13248 && !TARGET_MIX_SSE_I387)
13249 gen_truncxf = gen_truncxf<mode>2;
13250 else
13251 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13252
13253 emit_insn (gen_truncxf (operands[0], op1));
13254 DONE;
13255 })
13256
13257 (define_insn "fprem1xf4_i387"
13258 [(set (match_operand:XF 0 "register_operand" "=f")
13259 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13260 (match_operand:XF 3 "register_operand" "1")]
13261 UNSPEC_FPREM1_F))
13262 (set (match_operand:XF 1 "register_operand" "=u")
13263 (unspec:XF [(match_dup 2) (match_dup 3)]
13264 UNSPEC_FPREM1_U))
13265 (set (reg:CCFP FPSR_REG)
13266 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13267 UNSPEC_C2_FLAG))]
13268 "TARGET_USE_FANCY_MATH_387"
13269 "fprem1"
13270 [(set_attr "type" "fpspc")
13271 (set_attr "mode" "XF")])
13272
13273 (define_expand "remainderxf3"
13274 [(use (match_operand:XF 0 "register_operand" ""))
13275 (use (match_operand:XF 1 "general_operand" ""))
13276 (use (match_operand:XF 2 "general_operand" ""))]
13277 "TARGET_USE_FANCY_MATH_387"
13278 {
13279 rtx label = gen_label_rtx ();
13280
13281 rtx op1 = gen_reg_rtx (XFmode);
13282 rtx op2 = gen_reg_rtx (XFmode);
13283
13284 emit_move_insn (op2, operands[2]);
13285 emit_move_insn (op1, operands[1]);
13286
13287 emit_label (label);
13288 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13289 ix86_emit_fp_unordered_jump (label);
13290 LABEL_NUSES (label) = 1;
13291
13292 emit_move_insn (operands[0], op1);
13293 DONE;
13294 })
13295
13296 (define_expand "remainder<mode>3"
13297 [(use (match_operand:MODEF 0 "register_operand" ""))
13298 (use (match_operand:MODEF 1 "general_operand" ""))
13299 (use (match_operand:MODEF 2 "general_operand" ""))]
13300 "TARGET_USE_FANCY_MATH_387"
13301 {
13302 rtx (*gen_truncxf) (rtx, rtx);
13303
13304 rtx label = gen_label_rtx ();
13305
13306 rtx op1 = gen_reg_rtx (XFmode);
13307 rtx op2 = gen_reg_rtx (XFmode);
13308
13309 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13310 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13311
13312 emit_label (label);
13313
13314 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13315 ix86_emit_fp_unordered_jump (label);
13316 LABEL_NUSES (label) = 1;
13317
13318 /* Truncate the result properly for strict SSE math. */
13319 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13320 && !TARGET_MIX_SSE_I387)
13321 gen_truncxf = gen_truncxf<mode>2;
13322 else
13323 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13324
13325 emit_insn (gen_truncxf (operands[0], op1));
13326 DONE;
13327 })
13328
13329 (define_insn "*sinxf2_i387"
13330 [(set (match_operand:XF 0 "register_operand" "=f")
13331 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13332 "TARGET_USE_FANCY_MATH_387
13333 && flag_unsafe_math_optimizations"
13334 "fsin"
13335 [(set_attr "type" "fpspc")
13336 (set_attr "mode" "XF")])
13337
13338 (define_insn "*sin_extend<mode>xf2_i387"
13339 [(set (match_operand:XF 0 "register_operand" "=f")
13340 (unspec:XF [(float_extend:XF
13341 (match_operand:MODEF 1 "register_operand" "0"))]
13342 UNSPEC_SIN))]
13343 "TARGET_USE_FANCY_MATH_387
13344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13345 || TARGET_MIX_SSE_I387)
13346 && flag_unsafe_math_optimizations"
13347 "fsin"
13348 [(set_attr "type" "fpspc")
13349 (set_attr "mode" "XF")])
13350
13351 (define_insn "*cosxf2_i387"
13352 [(set (match_operand:XF 0 "register_operand" "=f")
13353 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13354 "TARGET_USE_FANCY_MATH_387
13355 && flag_unsafe_math_optimizations"
13356 "fcos"
13357 [(set_attr "type" "fpspc")
13358 (set_attr "mode" "XF")])
13359
13360 (define_insn "*cos_extend<mode>xf2_i387"
13361 [(set (match_operand:XF 0 "register_operand" "=f")
13362 (unspec:XF [(float_extend:XF
13363 (match_operand:MODEF 1 "register_operand" "0"))]
13364 UNSPEC_COS))]
13365 "TARGET_USE_FANCY_MATH_387
13366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13367 || TARGET_MIX_SSE_I387)
13368 && flag_unsafe_math_optimizations"
13369 "fcos"
13370 [(set_attr "type" "fpspc")
13371 (set_attr "mode" "XF")])
13372
13373 ;; When sincos pattern is defined, sin and cos builtin functions will be
13374 ;; expanded to sincos pattern with one of its outputs left unused.
13375 ;; CSE pass will figure out if two sincos patterns can be combined,
13376 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13377 ;; depending on the unused output.
13378
13379 (define_insn "sincosxf3"
13380 [(set (match_operand:XF 0 "register_operand" "=f")
13381 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13382 UNSPEC_SINCOS_COS))
13383 (set (match_operand:XF 1 "register_operand" "=u")
13384 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13385 "TARGET_USE_FANCY_MATH_387
13386 && flag_unsafe_math_optimizations"
13387 "fsincos"
13388 [(set_attr "type" "fpspc")
13389 (set_attr "mode" "XF")])
13390
13391 (define_split
13392 [(set (match_operand:XF 0 "register_operand" "")
13393 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13394 UNSPEC_SINCOS_COS))
13395 (set (match_operand:XF 1 "register_operand" "")
13396 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13397 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13398 && can_create_pseudo_p ()"
13399 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13400
13401 (define_split
13402 [(set (match_operand:XF 0 "register_operand" "")
13403 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13404 UNSPEC_SINCOS_COS))
13405 (set (match_operand:XF 1 "register_operand" "")
13406 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13407 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13408 && can_create_pseudo_p ()"
13409 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13410
13411 (define_insn "sincos_extend<mode>xf3_i387"
13412 [(set (match_operand:XF 0 "register_operand" "=f")
13413 (unspec:XF [(float_extend:XF
13414 (match_operand:MODEF 2 "register_operand" "0"))]
13415 UNSPEC_SINCOS_COS))
13416 (set (match_operand:XF 1 "register_operand" "=u")
13417 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13418 "TARGET_USE_FANCY_MATH_387
13419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13420 || TARGET_MIX_SSE_I387)
13421 && flag_unsafe_math_optimizations"
13422 "fsincos"
13423 [(set_attr "type" "fpspc")
13424 (set_attr "mode" "XF")])
13425
13426 (define_split
13427 [(set (match_operand:XF 0 "register_operand" "")
13428 (unspec:XF [(float_extend:XF
13429 (match_operand:MODEF 2 "register_operand" ""))]
13430 UNSPEC_SINCOS_COS))
13431 (set (match_operand:XF 1 "register_operand" "")
13432 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13433 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13434 && can_create_pseudo_p ()"
13435 [(set (match_dup 1)
13436 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13437
13438 (define_split
13439 [(set (match_operand:XF 0 "register_operand" "")
13440 (unspec:XF [(float_extend:XF
13441 (match_operand:MODEF 2 "register_operand" ""))]
13442 UNSPEC_SINCOS_COS))
13443 (set (match_operand:XF 1 "register_operand" "")
13444 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13445 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13446 && can_create_pseudo_p ()"
13447 [(set (match_dup 0)
13448 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13449
13450 (define_expand "sincos<mode>3"
13451 [(use (match_operand:MODEF 0 "register_operand" ""))
13452 (use (match_operand:MODEF 1 "register_operand" ""))
13453 (use (match_operand:MODEF 2 "register_operand" ""))]
13454 "TARGET_USE_FANCY_MATH_387
13455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13456 || TARGET_MIX_SSE_I387)
13457 && flag_unsafe_math_optimizations"
13458 {
13459 rtx op0 = gen_reg_rtx (XFmode);
13460 rtx op1 = gen_reg_rtx (XFmode);
13461
13462 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13463 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13465 DONE;
13466 })
13467
13468 (define_insn "fptanxf4_i387"
13469 [(set (match_operand:XF 0 "register_operand" "=f")
13470 (match_operand:XF 3 "const_double_operand" "F"))
13471 (set (match_operand:XF 1 "register_operand" "=u")
13472 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13473 UNSPEC_TAN))]
13474 "TARGET_USE_FANCY_MATH_387
13475 && flag_unsafe_math_optimizations
13476 && standard_80387_constant_p (operands[3]) == 2"
13477 "fptan"
13478 [(set_attr "type" "fpspc")
13479 (set_attr "mode" "XF")])
13480
13481 (define_insn "fptan_extend<mode>xf4_i387"
13482 [(set (match_operand:MODEF 0 "register_operand" "=f")
13483 (match_operand:MODEF 3 "const_double_operand" "F"))
13484 (set (match_operand:XF 1 "register_operand" "=u")
13485 (unspec:XF [(float_extend:XF
13486 (match_operand:MODEF 2 "register_operand" "0"))]
13487 UNSPEC_TAN))]
13488 "TARGET_USE_FANCY_MATH_387
13489 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13490 || TARGET_MIX_SSE_I387)
13491 && flag_unsafe_math_optimizations
13492 && standard_80387_constant_p (operands[3]) == 2"
13493 "fptan"
13494 [(set_attr "type" "fpspc")
13495 (set_attr "mode" "XF")])
13496
13497 (define_expand "tanxf2"
13498 [(use (match_operand:XF 0 "register_operand" ""))
13499 (use (match_operand:XF 1 "register_operand" ""))]
13500 "TARGET_USE_FANCY_MATH_387
13501 && flag_unsafe_math_optimizations"
13502 {
13503 rtx one = gen_reg_rtx (XFmode);
13504 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13505
13506 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13507 DONE;
13508 })
13509
13510 (define_expand "tan<mode>2"
13511 [(use (match_operand:MODEF 0 "register_operand" ""))
13512 (use (match_operand:MODEF 1 "register_operand" ""))]
13513 "TARGET_USE_FANCY_MATH_387
13514 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13515 || TARGET_MIX_SSE_I387)
13516 && flag_unsafe_math_optimizations"
13517 {
13518 rtx op0 = gen_reg_rtx (XFmode);
13519
13520 rtx one = gen_reg_rtx (<MODE>mode);
13521 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13522
13523 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13524 operands[1], op2));
13525 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13526 DONE;
13527 })
13528
13529 (define_insn "*fpatanxf3_i387"
13530 [(set (match_operand:XF 0 "register_operand" "=f")
13531 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13532 (match_operand:XF 2 "register_operand" "u")]
13533 UNSPEC_FPATAN))
13534 (clobber (match_scratch:XF 3 "=2"))]
13535 "TARGET_USE_FANCY_MATH_387
13536 && flag_unsafe_math_optimizations"
13537 "fpatan"
13538 [(set_attr "type" "fpspc")
13539 (set_attr "mode" "XF")])
13540
13541 (define_insn "fpatan_extend<mode>xf3_i387"
13542 [(set (match_operand:XF 0 "register_operand" "=f")
13543 (unspec:XF [(float_extend:XF
13544 (match_operand:MODEF 1 "register_operand" "0"))
13545 (float_extend:XF
13546 (match_operand:MODEF 2 "register_operand" "u"))]
13547 UNSPEC_FPATAN))
13548 (clobber (match_scratch:XF 3 "=2"))]
13549 "TARGET_USE_FANCY_MATH_387
13550 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13551 || TARGET_MIX_SSE_I387)
13552 && flag_unsafe_math_optimizations"
13553 "fpatan"
13554 [(set_attr "type" "fpspc")
13555 (set_attr "mode" "XF")])
13556
13557 (define_expand "atan2xf3"
13558 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13559 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13560 (match_operand:XF 1 "register_operand" "")]
13561 UNSPEC_FPATAN))
13562 (clobber (match_scratch:XF 3 ""))])]
13563 "TARGET_USE_FANCY_MATH_387
13564 && flag_unsafe_math_optimizations")
13565
13566 (define_expand "atan2<mode>3"
13567 [(use (match_operand:MODEF 0 "register_operand" ""))
13568 (use (match_operand:MODEF 1 "register_operand" ""))
13569 (use (match_operand:MODEF 2 "register_operand" ""))]
13570 "TARGET_USE_FANCY_MATH_387
13571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13572 || TARGET_MIX_SSE_I387)
13573 && flag_unsafe_math_optimizations"
13574 {
13575 rtx op0 = gen_reg_rtx (XFmode);
13576
13577 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13578 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13579 DONE;
13580 })
13581
13582 (define_expand "atanxf2"
13583 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13584 (unspec:XF [(match_dup 2)
13585 (match_operand:XF 1 "register_operand" "")]
13586 UNSPEC_FPATAN))
13587 (clobber (match_scratch:XF 3 ""))])]
13588 "TARGET_USE_FANCY_MATH_387
13589 && flag_unsafe_math_optimizations"
13590 {
13591 operands[2] = gen_reg_rtx (XFmode);
13592 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13593 })
13594
13595 (define_expand "atan<mode>2"
13596 [(use (match_operand:MODEF 0 "register_operand" ""))
13597 (use (match_operand:MODEF 1 "register_operand" ""))]
13598 "TARGET_USE_FANCY_MATH_387
13599 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13600 || TARGET_MIX_SSE_I387)
13601 && flag_unsafe_math_optimizations"
13602 {
13603 rtx op0 = gen_reg_rtx (XFmode);
13604
13605 rtx op2 = gen_reg_rtx (<MODE>mode);
13606 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13607
13608 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13609 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13610 DONE;
13611 })
13612
13613 (define_expand "asinxf2"
13614 [(set (match_dup 2)
13615 (mult:XF (match_operand:XF 1 "register_operand" "")
13616 (match_dup 1)))
13617 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13618 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13619 (parallel [(set (match_operand:XF 0 "register_operand" "")
13620 (unspec:XF [(match_dup 5) (match_dup 1)]
13621 UNSPEC_FPATAN))
13622 (clobber (match_scratch:XF 6 ""))])]
13623 "TARGET_USE_FANCY_MATH_387
13624 && flag_unsafe_math_optimizations"
13625 {
13626 int i;
13627
13628 if (optimize_insn_for_size_p ())
13629 FAIL;
13630
13631 for (i = 2; i < 6; i++)
13632 operands[i] = gen_reg_rtx (XFmode);
13633
13634 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13635 })
13636
13637 (define_expand "asin<mode>2"
13638 [(use (match_operand:MODEF 0 "register_operand" ""))
13639 (use (match_operand:MODEF 1 "general_operand" ""))]
13640 "TARGET_USE_FANCY_MATH_387
13641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642 || TARGET_MIX_SSE_I387)
13643 && flag_unsafe_math_optimizations"
13644 {
13645 rtx op0 = gen_reg_rtx (XFmode);
13646 rtx op1 = gen_reg_rtx (XFmode);
13647
13648 if (optimize_insn_for_size_p ())
13649 FAIL;
13650
13651 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13652 emit_insn (gen_asinxf2 (op0, op1));
13653 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13654 DONE;
13655 })
13656
13657 (define_expand "acosxf2"
13658 [(set (match_dup 2)
13659 (mult:XF (match_operand:XF 1 "register_operand" "")
13660 (match_dup 1)))
13661 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13662 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13663 (parallel [(set (match_operand:XF 0 "register_operand" "")
13664 (unspec:XF [(match_dup 1) (match_dup 5)]
13665 UNSPEC_FPATAN))
13666 (clobber (match_scratch:XF 6 ""))])]
13667 "TARGET_USE_FANCY_MATH_387
13668 && flag_unsafe_math_optimizations"
13669 {
13670 int i;
13671
13672 if (optimize_insn_for_size_p ())
13673 FAIL;
13674
13675 for (i = 2; i < 6; i++)
13676 operands[i] = gen_reg_rtx (XFmode);
13677
13678 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13679 })
13680
13681 (define_expand "acos<mode>2"
13682 [(use (match_operand:MODEF 0 "register_operand" ""))
13683 (use (match_operand:MODEF 1 "general_operand" ""))]
13684 "TARGET_USE_FANCY_MATH_387
13685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13686 || TARGET_MIX_SSE_I387)
13687 && flag_unsafe_math_optimizations"
13688 {
13689 rtx op0 = gen_reg_rtx (XFmode);
13690 rtx op1 = gen_reg_rtx (XFmode);
13691
13692 if (optimize_insn_for_size_p ())
13693 FAIL;
13694
13695 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13696 emit_insn (gen_acosxf2 (op0, op1));
13697 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13698 DONE;
13699 })
13700
13701 (define_insn "fyl2xxf3_i387"
13702 [(set (match_operand:XF 0 "register_operand" "=f")
13703 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13704 (match_operand:XF 2 "register_operand" "u")]
13705 UNSPEC_FYL2X))
13706 (clobber (match_scratch:XF 3 "=2"))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && flag_unsafe_math_optimizations"
13709 "fyl2x"
13710 [(set_attr "type" "fpspc")
13711 (set_attr "mode" "XF")])
13712
13713 (define_insn "fyl2x_extend<mode>xf3_i387"
13714 [(set (match_operand:XF 0 "register_operand" "=f")
13715 (unspec:XF [(float_extend:XF
13716 (match_operand:MODEF 1 "register_operand" "0"))
13717 (match_operand:XF 2 "register_operand" "u")]
13718 UNSPEC_FYL2X))
13719 (clobber (match_scratch:XF 3 "=2"))]
13720 "TARGET_USE_FANCY_MATH_387
13721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13722 || TARGET_MIX_SSE_I387)
13723 && flag_unsafe_math_optimizations"
13724 "fyl2x"
13725 [(set_attr "type" "fpspc")
13726 (set_attr "mode" "XF")])
13727
13728 (define_expand "logxf2"
13729 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13730 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13731 (match_dup 2)] UNSPEC_FYL2X))
13732 (clobber (match_scratch:XF 3 ""))])]
13733 "TARGET_USE_FANCY_MATH_387
13734 && flag_unsafe_math_optimizations"
13735 {
13736 operands[2] = gen_reg_rtx (XFmode);
13737 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13738 })
13739
13740 (define_expand "log<mode>2"
13741 [(use (match_operand:MODEF 0 "register_operand" ""))
13742 (use (match_operand:MODEF 1 "register_operand" ""))]
13743 "TARGET_USE_FANCY_MATH_387
13744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13745 || TARGET_MIX_SSE_I387)
13746 && flag_unsafe_math_optimizations"
13747 {
13748 rtx op0 = gen_reg_rtx (XFmode);
13749
13750 rtx op2 = gen_reg_rtx (XFmode);
13751 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13752
13753 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13755 DONE;
13756 })
13757
13758 (define_expand "log10xf2"
13759 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13760 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13761 (match_dup 2)] UNSPEC_FYL2X))
13762 (clobber (match_scratch:XF 3 ""))])]
13763 "TARGET_USE_FANCY_MATH_387
13764 && flag_unsafe_math_optimizations"
13765 {
13766 operands[2] = gen_reg_rtx (XFmode);
13767 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13768 })
13769
13770 (define_expand "log10<mode>2"
13771 [(use (match_operand:MODEF 0 "register_operand" ""))
13772 (use (match_operand:MODEF 1 "register_operand" ""))]
13773 "TARGET_USE_FANCY_MATH_387
13774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13775 || TARGET_MIX_SSE_I387)
13776 && flag_unsafe_math_optimizations"
13777 {
13778 rtx op0 = gen_reg_rtx (XFmode);
13779
13780 rtx op2 = gen_reg_rtx (XFmode);
13781 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13782
13783 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13784 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13785 DONE;
13786 })
13787
13788 (define_expand "log2xf2"
13789 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13790 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13791 (match_dup 2)] UNSPEC_FYL2X))
13792 (clobber (match_scratch:XF 3 ""))])]
13793 "TARGET_USE_FANCY_MATH_387
13794 && flag_unsafe_math_optimizations"
13795 {
13796 operands[2] = gen_reg_rtx (XFmode);
13797 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13798 })
13799
13800 (define_expand "log2<mode>2"
13801 [(use (match_operand:MODEF 0 "register_operand" ""))
13802 (use (match_operand:MODEF 1 "register_operand" ""))]
13803 "TARGET_USE_FANCY_MATH_387
13804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13805 || TARGET_MIX_SSE_I387)
13806 && flag_unsafe_math_optimizations"
13807 {
13808 rtx op0 = gen_reg_rtx (XFmode);
13809
13810 rtx op2 = gen_reg_rtx (XFmode);
13811 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13812
13813 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13815 DONE;
13816 })
13817
13818 (define_insn "fyl2xp1xf3_i387"
13819 [(set (match_operand:XF 0 "register_operand" "=f")
13820 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13821 (match_operand:XF 2 "register_operand" "u")]
13822 UNSPEC_FYL2XP1))
13823 (clobber (match_scratch:XF 3 "=2"))]
13824 "TARGET_USE_FANCY_MATH_387
13825 && flag_unsafe_math_optimizations"
13826 "fyl2xp1"
13827 [(set_attr "type" "fpspc")
13828 (set_attr "mode" "XF")])
13829
13830 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13831 [(set (match_operand:XF 0 "register_operand" "=f")
13832 (unspec:XF [(float_extend:XF
13833 (match_operand:MODEF 1 "register_operand" "0"))
13834 (match_operand:XF 2 "register_operand" "u")]
13835 UNSPEC_FYL2XP1))
13836 (clobber (match_scratch:XF 3 "=2"))]
13837 "TARGET_USE_FANCY_MATH_387
13838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13839 || TARGET_MIX_SSE_I387)
13840 && flag_unsafe_math_optimizations"
13841 "fyl2xp1"
13842 [(set_attr "type" "fpspc")
13843 (set_attr "mode" "XF")])
13844
13845 (define_expand "log1pxf2"
13846 [(use (match_operand:XF 0 "register_operand" ""))
13847 (use (match_operand:XF 1 "register_operand" ""))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && flag_unsafe_math_optimizations"
13850 {
13851 if (optimize_insn_for_size_p ())
13852 FAIL;
13853
13854 ix86_emit_i387_log1p (operands[0], operands[1]);
13855 DONE;
13856 })
13857
13858 (define_expand "log1p<mode>2"
13859 [(use (match_operand:MODEF 0 "register_operand" ""))
13860 (use (match_operand:MODEF 1 "register_operand" ""))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13863 || TARGET_MIX_SSE_I387)
13864 && flag_unsafe_math_optimizations"
13865 {
13866 rtx op0;
13867
13868 if (optimize_insn_for_size_p ())
13869 FAIL;
13870
13871 op0 = gen_reg_rtx (XFmode);
13872
13873 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13874
13875 ix86_emit_i387_log1p (op0, operands[1]);
13876 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13877 DONE;
13878 })
13879
13880 (define_insn "fxtractxf3_i387"
13881 [(set (match_operand:XF 0 "register_operand" "=f")
13882 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13883 UNSPEC_XTRACT_FRACT))
13884 (set (match_operand:XF 1 "register_operand" "=u")
13885 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13886 "TARGET_USE_FANCY_MATH_387
13887 && flag_unsafe_math_optimizations"
13888 "fxtract"
13889 [(set_attr "type" "fpspc")
13890 (set_attr "mode" "XF")])
13891
13892 (define_insn "fxtract_extend<mode>xf3_i387"
13893 [(set (match_operand:XF 0 "register_operand" "=f")
13894 (unspec:XF [(float_extend:XF
13895 (match_operand:MODEF 2 "register_operand" "0"))]
13896 UNSPEC_XTRACT_FRACT))
13897 (set (match_operand:XF 1 "register_operand" "=u")
13898 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13899 "TARGET_USE_FANCY_MATH_387
13900 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13901 || TARGET_MIX_SSE_I387)
13902 && flag_unsafe_math_optimizations"
13903 "fxtract"
13904 [(set_attr "type" "fpspc")
13905 (set_attr "mode" "XF")])
13906
13907 (define_expand "logbxf2"
13908 [(parallel [(set (match_dup 2)
13909 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13910 UNSPEC_XTRACT_FRACT))
13911 (set (match_operand:XF 0 "register_operand" "")
13912 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13913 "TARGET_USE_FANCY_MATH_387
13914 && flag_unsafe_math_optimizations"
13915 "operands[2] = gen_reg_rtx (XFmode);")
13916
13917 (define_expand "logb<mode>2"
13918 [(use (match_operand:MODEF 0 "register_operand" ""))
13919 (use (match_operand:MODEF 1 "register_operand" ""))]
13920 "TARGET_USE_FANCY_MATH_387
13921 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13922 || TARGET_MIX_SSE_I387)
13923 && flag_unsafe_math_optimizations"
13924 {
13925 rtx op0 = gen_reg_rtx (XFmode);
13926 rtx op1 = gen_reg_rtx (XFmode);
13927
13928 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13930 DONE;
13931 })
13932
13933 (define_expand "ilogbxf2"
13934 [(use (match_operand:SI 0 "register_operand" ""))
13935 (use (match_operand:XF 1 "register_operand" ""))]
13936 "TARGET_USE_FANCY_MATH_387
13937 && flag_unsafe_math_optimizations"
13938 {
13939 rtx op0, op1;
13940
13941 if (optimize_insn_for_size_p ())
13942 FAIL;
13943
13944 op0 = gen_reg_rtx (XFmode);
13945 op1 = gen_reg_rtx (XFmode);
13946
13947 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13948 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13949 DONE;
13950 })
13951
13952 (define_expand "ilogb<mode>2"
13953 [(use (match_operand:SI 0 "register_operand" ""))
13954 (use (match_operand:MODEF 1 "register_operand" ""))]
13955 "TARGET_USE_FANCY_MATH_387
13956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13957 || TARGET_MIX_SSE_I387)
13958 && flag_unsafe_math_optimizations"
13959 {
13960 rtx op0, op1;
13961
13962 if (optimize_insn_for_size_p ())
13963 FAIL;
13964
13965 op0 = gen_reg_rtx (XFmode);
13966 op1 = gen_reg_rtx (XFmode);
13967
13968 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13969 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13970 DONE;
13971 })
13972
13973 (define_insn "*f2xm1xf2_i387"
13974 [(set (match_operand:XF 0 "register_operand" "=f")
13975 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13976 UNSPEC_F2XM1))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && flag_unsafe_math_optimizations"
13979 "f2xm1"
13980 [(set_attr "type" "fpspc")
13981 (set_attr "mode" "XF")])
13982
13983 (define_insn "*fscalexf4_i387"
13984 [(set (match_operand:XF 0 "register_operand" "=f")
13985 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13986 (match_operand:XF 3 "register_operand" "1")]
13987 UNSPEC_FSCALE_FRACT))
13988 (set (match_operand:XF 1 "register_operand" "=u")
13989 (unspec:XF [(match_dup 2) (match_dup 3)]
13990 UNSPEC_FSCALE_EXP))]
13991 "TARGET_USE_FANCY_MATH_387
13992 && flag_unsafe_math_optimizations"
13993 "fscale"
13994 [(set_attr "type" "fpspc")
13995 (set_attr "mode" "XF")])
13996
13997 (define_expand "expNcorexf3"
13998 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13999 (match_operand:XF 2 "register_operand" "")))
14000 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14001 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14002 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14003 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14004 (parallel [(set (match_operand:XF 0 "register_operand" "")
14005 (unspec:XF [(match_dup 8) (match_dup 4)]
14006 UNSPEC_FSCALE_FRACT))
14007 (set (match_dup 9)
14008 (unspec:XF [(match_dup 8) (match_dup 4)]
14009 UNSPEC_FSCALE_EXP))])]
14010 "TARGET_USE_FANCY_MATH_387
14011 && flag_unsafe_math_optimizations"
14012 {
14013 int i;
14014
14015 if (optimize_insn_for_size_p ())
14016 FAIL;
14017
14018 for (i = 3; i < 10; i++)
14019 operands[i] = gen_reg_rtx (XFmode);
14020
14021 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14022 })
14023
14024 (define_expand "expxf2"
14025 [(use (match_operand:XF 0 "register_operand" ""))
14026 (use (match_operand:XF 1 "register_operand" ""))]
14027 "TARGET_USE_FANCY_MATH_387
14028 && flag_unsafe_math_optimizations"
14029 {
14030 rtx op2;
14031
14032 if (optimize_insn_for_size_p ())
14033 FAIL;
14034
14035 op2 = gen_reg_rtx (XFmode);
14036 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14037
14038 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14039 DONE;
14040 })
14041
14042 (define_expand "exp<mode>2"
14043 [(use (match_operand:MODEF 0 "register_operand" ""))
14044 (use (match_operand:MODEF 1 "general_operand" ""))]
14045 "TARGET_USE_FANCY_MATH_387
14046 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14047 || TARGET_MIX_SSE_I387)
14048 && flag_unsafe_math_optimizations"
14049 {
14050 rtx op0, op1;
14051
14052 if (optimize_insn_for_size_p ())
14053 FAIL;
14054
14055 op0 = gen_reg_rtx (XFmode);
14056 op1 = gen_reg_rtx (XFmode);
14057
14058 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14059 emit_insn (gen_expxf2 (op0, op1));
14060 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14061 DONE;
14062 })
14063
14064 (define_expand "exp10xf2"
14065 [(use (match_operand:XF 0 "register_operand" ""))
14066 (use (match_operand:XF 1 "register_operand" ""))]
14067 "TARGET_USE_FANCY_MATH_387
14068 && flag_unsafe_math_optimizations"
14069 {
14070 rtx op2;
14071
14072 if (optimize_insn_for_size_p ())
14073 FAIL;
14074
14075 op2 = gen_reg_rtx (XFmode);
14076 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14077
14078 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14079 DONE;
14080 })
14081
14082 (define_expand "exp10<mode>2"
14083 [(use (match_operand:MODEF 0 "register_operand" ""))
14084 (use (match_operand:MODEF 1 "general_operand" ""))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14087 || TARGET_MIX_SSE_I387)
14088 && flag_unsafe_math_optimizations"
14089 {
14090 rtx op0, op1;
14091
14092 if (optimize_insn_for_size_p ())
14093 FAIL;
14094
14095 op0 = gen_reg_rtx (XFmode);
14096 op1 = gen_reg_rtx (XFmode);
14097
14098 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14099 emit_insn (gen_exp10xf2 (op0, op1));
14100 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14101 DONE;
14102 })
14103
14104 (define_expand "exp2xf2"
14105 [(use (match_operand:XF 0 "register_operand" ""))
14106 (use (match_operand:XF 1 "register_operand" ""))]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14109 {
14110 rtx op2;
14111
14112 if (optimize_insn_for_size_p ())
14113 FAIL;
14114
14115 op2 = gen_reg_rtx (XFmode);
14116 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14117
14118 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14119 DONE;
14120 })
14121
14122 (define_expand "exp2<mode>2"
14123 [(use (match_operand:MODEF 0 "register_operand" ""))
14124 (use (match_operand:MODEF 1 "general_operand" ""))]
14125 "TARGET_USE_FANCY_MATH_387
14126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14127 || TARGET_MIX_SSE_I387)
14128 && flag_unsafe_math_optimizations"
14129 {
14130 rtx op0, op1;
14131
14132 if (optimize_insn_for_size_p ())
14133 FAIL;
14134
14135 op0 = gen_reg_rtx (XFmode);
14136 op1 = gen_reg_rtx (XFmode);
14137
14138 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14139 emit_insn (gen_exp2xf2 (op0, op1));
14140 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14141 DONE;
14142 })
14143
14144 (define_expand "expm1xf2"
14145 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14146 (match_dup 2)))
14147 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14148 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14149 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14150 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14151 (parallel [(set (match_dup 7)
14152 (unspec:XF [(match_dup 6) (match_dup 4)]
14153 UNSPEC_FSCALE_FRACT))
14154 (set (match_dup 8)
14155 (unspec:XF [(match_dup 6) (match_dup 4)]
14156 UNSPEC_FSCALE_EXP))])
14157 (parallel [(set (match_dup 10)
14158 (unspec:XF [(match_dup 9) (match_dup 8)]
14159 UNSPEC_FSCALE_FRACT))
14160 (set (match_dup 11)
14161 (unspec:XF [(match_dup 9) (match_dup 8)]
14162 UNSPEC_FSCALE_EXP))])
14163 (set (match_dup 12) (minus:XF (match_dup 10)
14164 (float_extend:XF (match_dup 13))))
14165 (set (match_operand:XF 0 "register_operand" "")
14166 (plus:XF (match_dup 12) (match_dup 7)))]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14169 {
14170 int i;
14171
14172 if (optimize_insn_for_size_p ())
14173 FAIL;
14174
14175 for (i = 2; i < 13; i++)
14176 operands[i] = gen_reg_rtx (XFmode);
14177
14178 operands[13]
14179 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14180
14181 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14182 })
14183
14184 (define_expand "expm1<mode>2"
14185 [(use (match_operand:MODEF 0 "register_operand" ""))
14186 (use (match_operand:MODEF 1 "general_operand" ""))]
14187 "TARGET_USE_FANCY_MATH_387
14188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14189 || TARGET_MIX_SSE_I387)
14190 && flag_unsafe_math_optimizations"
14191 {
14192 rtx op0, op1;
14193
14194 if (optimize_insn_for_size_p ())
14195 FAIL;
14196
14197 op0 = gen_reg_rtx (XFmode);
14198 op1 = gen_reg_rtx (XFmode);
14199
14200 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14201 emit_insn (gen_expm1xf2 (op0, op1));
14202 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14203 DONE;
14204 })
14205
14206 (define_expand "ldexpxf3"
14207 [(set (match_dup 3)
14208 (float:XF (match_operand:SI 2 "register_operand" "")))
14209 (parallel [(set (match_operand:XF 0 " register_operand" "")
14210 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14211 (match_dup 3)]
14212 UNSPEC_FSCALE_FRACT))
14213 (set (match_dup 4)
14214 (unspec:XF [(match_dup 1) (match_dup 3)]
14215 UNSPEC_FSCALE_EXP))])]
14216 "TARGET_USE_FANCY_MATH_387
14217 && flag_unsafe_math_optimizations"
14218 {
14219 if (optimize_insn_for_size_p ())
14220 FAIL;
14221
14222 operands[3] = gen_reg_rtx (XFmode);
14223 operands[4] = gen_reg_rtx (XFmode);
14224 })
14225
14226 (define_expand "ldexp<mode>3"
14227 [(use (match_operand:MODEF 0 "register_operand" ""))
14228 (use (match_operand:MODEF 1 "general_operand" ""))
14229 (use (match_operand:SI 2 "register_operand" ""))]
14230 "TARGET_USE_FANCY_MATH_387
14231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14232 || TARGET_MIX_SSE_I387)
14233 && flag_unsafe_math_optimizations"
14234 {
14235 rtx op0, op1;
14236
14237 if (optimize_insn_for_size_p ())
14238 FAIL;
14239
14240 op0 = gen_reg_rtx (XFmode);
14241 op1 = gen_reg_rtx (XFmode);
14242
14243 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14244 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14245 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14246 DONE;
14247 })
14248
14249 (define_expand "scalbxf3"
14250 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14251 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14252 (match_operand:XF 2 "register_operand" "")]
14253 UNSPEC_FSCALE_FRACT))
14254 (set (match_dup 3)
14255 (unspec:XF [(match_dup 1) (match_dup 2)]
14256 UNSPEC_FSCALE_EXP))])]
14257 "TARGET_USE_FANCY_MATH_387
14258 && flag_unsafe_math_optimizations"
14259 {
14260 if (optimize_insn_for_size_p ())
14261 FAIL;
14262
14263 operands[3] = gen_reg_rtx (XFmode);
14264 })
14265
14266 (define_expand "scalb<mode>3"
14267 [(use (match_operand:MODEF 0 "register_operand" ""))
14268 (use (match_operand:MODEF 1 "general_operand" ""))
14269 (use (match_operand:MODEF 2 "general_operand" ""))]
14270 "TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations"
14274 {
14275 rtx op0, op1, op2;
14276
14277 if (optimize_insn_for_size_p ())
14278 FAIL;
14279
14280 op0 = gen_reg_rtx (XFmode);
14281 op1 = gen_reg_rtx (XFmode);
14282 op2 = gen_reg_rtx (XFmode);
14283
14284 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14285 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14286 emit_insn (gen_scalbxf3 (op0, op1, op2));
14287 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14288 DONE;
14289 })
14290
14291 (define_expand "significandxf2"
14292 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14293 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14294 UNSPEC_XTRACT_FRACT))
14295 (set (match_dup 2)
14296 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14297 "TARGET_USE_FANCY_MATH_387
14298 && flag_unsafe_math_optimizations"
14299 "operands[2] = gen_reg_rtx (XFmode);")
14300
14301 (define_expand "significand<mode>2"
14302 [(use (match_operand:MODEF 0 "register_operand" ""))
14303 (use (match_operand:MODEF 1 "register_operand" ""))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14306 || TARGET_MIX_SSE_I387)
14307 && flag_unsafe_math_optimizations"
14308 {
14309 rtx op0 = gen_reg_rtx (XFmode);
14310 rtx op1 = gen_reg_rtx (XFmode);
14311
14312 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14313 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14314 DONE;
14315 })
14316 \f
14317
14318 (define_insn "sse4_1_round<mode>2"
14319 [(set (match_operand:MODEF 0 "register_operand" "=x")
14320 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14321 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14322 UNSPEC_ROUND))]
14323 "TARGET_ROUND"
14324 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14325 [(set_attr "type" "ssecvt")
14326 (set_attr "prefix_extra" "1")
14327 (set_attr "prefix" "maybe_vex")
14328 (set_attr "mode" "<MODE>")])
14329
14330 (define_insn "rintxf2"
14331 [(set (match_operand:XF 0 "register_operand" "=f")
14332 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14333 UNSPEC_FRNDINT))]
14334 "TARGET_USE_FANCY_MATH_387
14335 && flag_unsafe_math_optimizations"
14336 "frndint"
14337 [(set_attr "type" "fpspc")
14338 (set_attr "mode" "XF")])
14339
14340 (define_expand "rint<mode>2"
14341 [(use (match_operand:MODEF 0 "register_operand" ""))
14342 (use (match_operand:MODEF 1 "register_operand" ""))]
14343 "(TARGET_USE_FANCY_MATH_387
14344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14345 || TARGET_MIX_SSE_I387)
14346 && flag_unsafe_math_optimizations)
14347 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14348 && !flag_trapping_math)"
14349 {
14350 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14351 && !flag_trapping_math)
14352 {
14353 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14354 FAIL;
14355 if (TARGET_ROUND)
14356 emit_insn (gen_sse4_1_round<mode>2
14357 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14358 else
14359 ix86_expand_rint (operand0, operand1);
14360 }
14361 else
14362 {
14363 rtx op0 = gen_reg_rtx (XFmode);
14364 rtx op1 = gen_reg_rtx (XFmode);
14365
14366 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14367 emit_insn (gen_rintxf2 (op0, op1));
14368
14369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14370 }
14371 DONE;
14372 })
14373
14374 (define_expand "round<mode>2"
14375 [(match_operand:MODEF 0 "register_operand" "")
14376 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14377 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14378 && !flag_trapping_math && !flag_rounding_math"
14379 {
14380 if (optimize_insn_for_size_p ())
14381 FAIL;
14382 if (TARGET_64BIT || (<MODE>mode != DFmode))
14383 ix86_expand_round (operand0, operand1);
14384 else
14385 ix86_expand_rounddf_32 (operand0, operand1);
14386 DONE;
14387 })
14388
14389 (define_insn_and_split "*fistdi2_1"
14390 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14391 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14392 UNSPEC_FIST))]
14393 "TARGET_USE_FANCY_MATH_387
14394 && can_create_pseudo_p ()"
14395 "#"
14396 "&& 1"
14397 [(const_int 0)]
14398 {
14399 if (memory_operand (operands[0], VOIDmode))
14400 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14401 else
14402 {
14403 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14404 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14405 operands[2]));
14406 }
14407 DONE;
14408 }
14409 [(set_attr "type" "fpspc")
14410 (set_attr "mode" "DI")])
14411
14412 (define_insn "fistdi2"
14413 [(set (match_operand:DI 0 "memory_operand" "=m")
14414 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14415 UNSPEC_FIST))
14416 (clobber (match_scratch:XF 2 "=&1f"))]
14417 "TARGET_USE_FANCY_MATH_387"
14418 "* return output_fix_trunc (insn, operands, false);"
14419 [(set_attr "type" "fpspc")
14420 (set_attr "mode" "DI")])
14421
14422 (define_insn "fistdi2_with_temp"
14423 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14424 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14425 UNSPEC_FIST))
14426 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14427 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14428 "TARGET_USE_FANCY_MATH_387"
14429 "#"
14430 [(set_attr "type" "fpspc")
14431 (set_attr "mode" "DI")])
14432
14433 (define_split
14434 [(set (match_operand:DI 0 "register_operand" "")
14435 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14436 UNSPEC_FIST))
14437 (clobber (match_operand:DI 2 "memory_operand" ""))
14438 (clobber (match_scratch 3 ""))]
14439 "reload_completed"
14440 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14441 (clobber (match_dup 3))])
14442 (set (match_dup 0) (match_dup 2))])
14443
14444 (define_split
14445 [(set (match_operand:DI 0 "memory_operand" "")
14446 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14447 UNSPEC_FIST))
14448 (clobber (match_operand:DI 2 "memory_operand" ""))
14449 (clobber (match_scratch 3 ""))]
14450 "reload_completed"
14451 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14452 (clobber (match_dup 3))])])
14453
14454 (define_insn_and_split "*fist<mode>2_1"
14455 [(set (match_operand:SWI24 0 "register_operand" "")
14456 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14457 UNSPEC_FIST))]
14458 "TARGET_USE_FANCY_MATH_387
14459 && can_create_pseudo_p ()"
14460 "#"
14461 "&& 1"
14462 [(const_int 0)]
14463 {
14464 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14465 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14466 operands[2]));
14467 DONE;
14468 }
14469 [(set_attr "type" "fpspc")
14470 (set_attr "mode" "<MODE>")])
14471
14472 (define_insn "fist<mode>2"
14473 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14474 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14475 UNSPEC_FIST))]
14476 "TARGET_USE_FANCY_MATH_387"
14477 "* return output_fix_trunc (insn, operands, false);"
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "<MODE>")])
14480
14481 (define_insn "fist<mode>2_with_temp"
14482 [(set (match_operand:SWI24 0 "register_operand" "=r")
14483 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14484 UNSPEC_FIST))
14485 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14486 "TARGET_USE_FANCY_MATH_387"
14487 "#"
14488 [(set_attr "type" "fpspc")
14489 (set_attr "mode" "<MODE>")])
14490
14491 (define_split
14492 [(set (match_operand:SWI24 0 "register_operand" "")
14493 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14494 UNSPEC_FIST))
14495 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14496 "reload_completed"
14497 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14498 (set (match_dup 0) (match_dup 2))])
14499
14500 (define_split
14501 [(set (match_operand:SWI24 0 "memory_operand" "")
14502 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14503 UNSPEC_FIST))
14504 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14505 "reload_completed"
14506 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14507
14508 (define_expand "lrintxf<mode>2"
14509 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14510 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14511 UNSPEC_FIST))]
14512 "TARGET_USE_FANCY_MATH_387")
14513
14514 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14515 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14516 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14517 UNSPEC_FIX_NOTRUNC))]
14518 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14519 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14520
14521 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14522 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14523 (match_operand:MODEF 1 "register_operand" "")]
14524 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14525 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14526 && !flag_trapping_math && !flag_rounding_math"
14527 {
14528 if (optimize_insn_for_size_p ())
14529 FAIL;
14530 ix86_expand_lround (operand0, operand1);
14531 DONE;
14532 })
14533
14534 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14535 (define_insn_and_split "frndintxf2_floor"
14536 [(set (match_operand:XF 0 "register_operand" "")
14537 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14538 UNSPEC_FRNDINT_FLOOR))
14539 (clobber (reg:CC FLAGS_REG))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_unsafe_math_optimizations
14542 && can_create_pseudo_p ()"
14543 "#"
14544 "&& 1"
14545 [(const_int 0)]
14546 {
14547 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14548
14549 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14550 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14551
14552 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14553 operands[2], operands[3]));
14554 DONE;
14555 }
14556 [(set_attr "type" "frndint")
14557 (set_attr "i387_cw" "floor")
14558 (set_attr "mode" "XF")])
14559
14560 (define_insn "frndintxf2_floor_i387"
14561 [(set (match_operand:XF 0 "register_operand" "=f")
14562 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14563 UNSPEC_FRNDINT_FLOOR))
14564 (use (match_operand:HI 2 "memory_operand" "m"))
14565 (use (match_operand:HI 3 "memory_operand" "m"))]
14566 "TARGET_USE_FANCY_MATH_387
14567 && flag_unsafe_math_optimizations"
14568 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14569 [(set_attr "type" "frndint")
14570 (set_attr "i387_cw" "floor")
14571 (set_attr "mode" "XF")])
14572
14573 (define_expand "floorxf2"
14574 [(use (match_operand:XF 0 "register_operand" ""))
14575 (use (match_operand:XF 1 "register_operand" ""))]
14576 "TARGET_USE_FANCY_MATH_387
14577 && flag_unsafe_math_optimizations"
14578 {
14579 if (optimize_insn_for_size_p ())
14580 FAIL;
14581 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14582 DONE;
14583 })
14584
14585 (define_expand "floor<mode>2"
14586 [(use (match_operand:MODEF 0 "register_operand" ""))
14587 (use (match_operand:MODEF 1 "register_operand" ""))]
14588 "(TARGET_USE_FANCY_MATH_387
14589 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14590 || TARGET_MIX_SSE_I387)
14591 && flag_unsafe_math_optimizations)
14592 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14593 && !flag_trapping_math)"
14594 {
14595 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14596 && !flag_trapping_math
14597 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14598 {
14599 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14600 FAIL;
14601 if (TARGET_ROUND)
14602 emit_insn (gen_sse4_1_round<mode>2
14603 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14604 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14605 ix86_expand_floorceil (operand0, operand1, true);
14606 else
14607 ix86_expand_floorceildf_32 (operand0, operand1, true);
14608 }
14609 else
14610 {
14611 rtx op0, op1;
14612
14613 if (optimize_insn_for_size_p ())
14614 FAIL;
14615
14616 op0 = gen_reg_rtx (XFmode);
14617 op1 = gen_reg_rtx (XFmode);
14618 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14619 emit_insn (gen_frndintxf2_floor (op0, op1));
14620
14621 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14622 }
14623 DONE;
14624 })
14625
14626 (define_insn_and_split "*fist<mode>2_floor_1"
14627 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14628 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14629 UNSPEC_FIST_FLOOR))
14630 (clobber (reg:CC FLAGS_REG))]
14631 "TARGET_USE_FANCY_MATH_387
14632 && flag_unsafe_math_optimizations
14633 && can_create_pseudo_p ()"
14634 "#"
14635 "&& 1"
14636 [(const_int 0)]
14637 {
14638 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14639
14640 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14641 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14642 if (memory_operand (operands[0], VOIDmode))
14643 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14644 operands[2], operands[3]));
14645 else
14646 {
14647 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14648 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14649 operands[2], operands[3],
14650 operands[4]));
14651 }
14652 DONE;
14653 }
14654 [(set_attr "type" "fistp")
14655 (set_attr "i387_cw" "floor")
14656 (set_attr "mode" "<MODE>")])
14657
14658 (define_insn "fistdi2_floor"
14659 [(set (match_operand:DI 0 "memory_operand" "=m")
14660 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14661 UNSPEC_FIST_FLOOR))
14662 (use (match_operand:HI 2 "memory_operand" "m"))
14663 (use (match_operand:HI 3 "memory_operand" "m"))
14664 (clobber (match_scratch:XF 4 "=&1f"))]
14665 "TARGET_USE_FANCY_MATH_387
14666 && flag_unsafe_math_optimizations"
14667 "* return output_fix_trunc (insn, operands, false);"
14668 [(set_attr "type" "fistp")
14669 (set_attr "i387_cw" "floor")
14670 (set_attr "mode" "DI")])
14671
14672 (define_insn "fistdi2_floor_with_temp"
14673 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14674 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14675 UNSPEC_FIST_FLOOR))
14676 (use (match_operand:HI 2 "memory_operand" "m,m"))
14677 (use (match_operand:HI 3 "memory_operand" "m,m"))
14678 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14679 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14680 "TARGET_USE_FANCY_MATH_387
14681 && flag_unsafe_math_optimizations"
14682 "#"
14683 [(set_attr "type" "fistp")
14684 (set_attr "i387_cw" "floor")
14685 (set_attr "mode" "DI")])
14686
14687 (define_split
14688 [(set (match_operand:DI 0 "register_operand" "")
14689 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14690 UNSPEC_FIST_FLOOR))
14691 (use (match_operand:HI 2 "memory_operand" ""))
14692 (use (match_operand:HI 3 "memory_operand" ""))
14693 (clobber (match_operand:DI 4 "memory_operand" ""))
14694 (clobber (match_scratch 5 ""))]
14695 "reload_completed"
14696 [(parallel [(set (match_dup 4)
14697 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14698 (use (match_dup 2))
14699 (use (match_dup 3))
14700 (clobber (match_dup 5))])
14701 (set (match_dup 0) (match_dup 4))])
14702
14703 (define_split
14704 [(set (match_operand:DI 0 "memory_operand" "")
14705 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14706 UNSPEC_FIST_FLOOR))
14707 (use (match_operand:HI 2 "memory_operand" ""))
14708 (use (match_operand:HI 3 "memory_operand" ""))
14709 (clobber (match_operand:DI 4 "memory_operand" ""))
14710 (clobber (match_scratch 5 ""))]
14711 "reload_completed"
14712 [(parallel [(set (match_dup 0)
14713 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14714 (use (match_dup 2))
14715 (use (match_dup 3))
14716 (clobber (match_dup 5))])])
14717
14718 (define_insn "fist<mode>2_floor"
14719 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14720 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14721 UNSPEC_FIST_FLOOR))
14722 (use (match_operand:HI 2 "memory_operand" "m"))
14723 (use (match_operand:HI 3 "memory_operand" "m"))]
14724 "TARGET_USE_FANCY_MATH_387
14725 && flag_unsafe_math_optimizations"
14726 "* return output_fix_trunc (insn, operands, false);"
14727 [(set_attr "type" "fistp")
14728 (set_attr "i387_cw" "floor")
14729 (set_attr "mode" "<MODE>")])
14730
14731 (define_insn "fist<mode>2_floor_with_temp"
14732 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14733 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14734 UNSPEC_FIST_FLOOR))
14735 (use (match_operand:HI 2 "memory_operand" "m,m"))
14736 (use (match_operand:HI 3 "memory_operand" "m,m"))
14737 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14738 "TARGET_USE_FANCY_MATH_387
14739 && flag_unsafe_math_optimizations"
14740 "#"
14741 [(set_attr "type" "fistp")
14742 (set_attr "i387_cw" "floor")
14743 (set_attr "mode" "<MODE>")])
14744
14745 (define_split
14746 [(set (match_operand:SWI24 0 "register_operand" "")
14747 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14748 UNSPEC_FIST_FLOOR))
14749 (use (match_operand:HI 2 "memory_operand" ""))
14750 (use (match_operand:HI 3 "memory_operand" ""))
14751 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14752 "reload_completed"
14753 [(parallel [(set (match_dup 4)
14754 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14755 (use (match_dup 2))
14756 (use (match_dup 3))])
14757 (set (match_dup 0) (match_dup 4))])
14758
14759 (define_split
14760 [(set (match_operand:SWI24 0 "memory_operand" "")
14761 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14762 UNSPEC_FIST_FLOOR))
14763 (use (match_operand:HI 2 "memory_operand" ""))
14764 (use (match_operand:HI 3 "memory_operand" ""))
14765 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14766 "reload_completed"
14767 [(parallel [(set (match_dup 0)
14768 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14769 (use (match_dup 2))
14770 (use (match_dup 3))])])
14771
14772 (define_expand "lfloorxf<mode>2"
14773 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14774 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14775 UNSPEC_FIST_FLOOR))
14776 (clobber (reg:CC FLAGS_REG))])]
14777 "TARGET_USE_FANCY_MATH_387
14778 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14779 && flag_unsafe_math_optimizations")
14780
14781 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14782 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14783 (match_operand:MODEF 1 "register_operand" "")]
14784 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14785 && !flag_trapping_math"
14786 {
14787 if (TARGET_64BIT && optimize_insn_for_size_p ())
14788 FAIL;
14789 ix86_expand_lfloorceil (operand0, operand1, true);
14790 DONE;
14791 })
14792
14793 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14794 (define_insn_and_split "frndintxf2_ceil"
14795 [(set (match_operand:XF 0 "register_operand" "")
14796 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14797 UNSPEC_FRNDINT_CEIL))
14798 (clobber (reg:CC FLAGS_REG))]
14799 "TARGET_USE_FANCY_MATH_387
14800 && flag_unsafe_math_optimizations
14801 && can_create_pseudo_p ()"
14802 "#"
14803 "&& 1"
14804 [(const_int 0)]
14805 {
14806 ix86_optimize_mode_switching[I387_CEIL] = 1;
14807
14808 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14809 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14810
14811 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14812 operands[2], operands[3]));
14813 DONE;
14814 }
14815 [(set_attr "type" "frndint")
14816 (set_attr "i387_cw" "ceil")
14817 (set_attr "mode" "XF")])
14818
14819 (define_insn "frndintxf2_ceil_i387"
14820 [(set (match_operand:XF 0 "register_operand" "=f")
14821 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14822 UNSPEC_FRNDINT_CEIL))
14823 (use (match_operand:HI 2 "memory_operand" "m"))
14824 (use (match_operand:HI 3 "memory_operand" "m"))]
14825 "TARGET_USE_FANCY_MATH_387
14826 && flag_unsafe_math_optimizations"
14827 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14828 [(set_attr "type" "frndint")
14829 (set_attr "i387_cw" "ceil")
14830 (set_attr "mode" "XF")])
14831
14832 (define_expand "ceilxf2"
14833 [(use (match_operand:XF 0 "register_operand" ""))
14834 (use (match_operand:XF 1 "register_operand" ""))]
14835 "TARGET_USE_FANCY_MATH_387
14836 && flag_unsafe_math_optimizations"
14837 {
14838 if (optimize_insn_for_size_p ())
14839 FAIL;
14840 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14841 DONE;
14842 })
14843
14844 (define_expand "ceil<mode>2"
14845 [(use (match_operand:MODEF 0 "register_operand" ""))
14846 (use (match_operand:MODEF 1 "register_operand" ""))]
14847 "(TARGET_USE_FANCY_MATH_387
14848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14849 || TARGET_MIX_SSE_I387)
14850 && flag_unsafe_math_optimizations)
14851 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14852 && !flag_trapping_math)"
14853 {
14854 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14855 && !flag_trapping_math
14856 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14857 {
14858 if (TARGET_ROUND)
14859 emit_insn (gen_sse4_1_round<mode>2
14860 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14861 else if (optimize_insn_for_size_p ())
14862 FAIL;
14863 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14864 ix86_expand_floorceil (operand0, operand1, false);
14865 else
14866 ix86_expand_floorceildf_32 (operand0, operand1, false);
14867 }
14868 else
14869 {
14870 rtx op0, op1;
14871
14872 if (optimize_insn_for_size_p ())
14873 FAIL;
14874
14875 op0 = gen_reg_rtx (XFmode);
14876 op1 = gen_reg_rtx (XFmode);
14877 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14878 emit_insn (gen_frndintxf2_ceil (op0, op1));
14879
14880 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14881 }
14882 DONE;
14883 })
14884
14885 (define_insn_and_split "*fist<mode>2_ceil_1"
14886 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14887 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14888 UNSPEC_FIST_CEIL))
14889 (clobber (reg:CC FLAGS_REG))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && flag_unsafe_math_optimizations
14892 && can_create_pseudo_p ()"
14893 "#"
14894 "&& 1"
14895 [(const_int 0)]
14896 {
14897 ix86_optimize_mode_switching[I387_CEIL] = 1;
14898
14899 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14900 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14901 if (memory_operand (operands[0], VOIDmode))
14902 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14903 operands[2], operands[3]));
14904 else
14905 {
14906 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14907 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14908 operands[2], operands[3],
14909 operands[4]));
14910 }
14911 DONE;
14912 }
14913 [(set_attr "type" "fistp")
14914 (set_attr "i387_cw" "ceil")
14915 (set_attr "mode" "<MODE>")])
14916
14917 (define_insn "fistdi2_ceil"
14918 [(set (match_operand:DI 0 "memory_operand" "=m")
14919 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14920 UNSPEC_FIST_CEIL))
14921 (use (match_operand:HI 2 "memory_operand" "m"))
14922 (use (match_operand:HI 3 "memory_operand" "m"))
14923 (clobber (match_scratch:XF 4 "=&1f"))]
14924 "TARGET_USE_FANCY_MATH_387
14925 && flag_unsafe_math_optimizations"
14926 "* return output_fix_trunc (insn, operands, false);"
14927 [(set_attr "type" "fistp")
14928 (set_attr "i387_cw" "ceil")
14929 (set_attr "mode" "DI")])
14930
14931 (define_insn "fistdi2_ceil_with_temp"
14932 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14933 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14934 UNSPEC_FIST_CEIL))
14935 (use (match_operand:HI 2 "memory_operand" "m,m"))
14936 (use (match_operand:HI 3 "memory_operand" "m,m"))
14937 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14938 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations"
14941 "#"
14942 [(set_attr "type" "fistp")
14943 (set_attr "i387_cw" "ceil")
14944 (set_attr "mode" "DI")])
14945
14946 (define_split
14947 [(set (match_operand:DI 0 "register_operand" "")
14948 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14949 UNSPEC_FIST_CEIL))
14950 (use (match_operand:HI 2 "memory_operand" ""))
14951 (use (match_operand:HI 3 "memory_operand" ""))
14952 (clobber (match_operand:DI 4 "memory_operand" ""))
14953 (clobber (match_scratch 5 ""))]
14954 "reload_completed"
14955 [(parallel [(set (match_dup 4)
14956 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14957 (use (match_dup 2))
14958 (use (match_dup 3))
14959 (clobber (match_dup 5))])
14960 (set (match_dup 0) (match_dup 4))])
14961
14962 (define_split
14963 [(set (match_operand:DI 0 "memory_operand" "")
14964 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14965 UNSPEC_FIST_CEIL))
14966 (use (match_operand:HI 2 "memory_operand" ""))
14967 (use (match_operand:HI 3 "memory_operand" ""))
14968 (clobber (match_operand:DI 4 "memory_operand" ""))
14969 (clobber (match_scratch 5 ""))]
14970 "reload_completed"
14971 [(parallel [(set (match_dup 0)
14972 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14973 (use (match_dup 2))
14974 (use (match_dup 3))
14975 (clobber (match_dup 5))])])
14976
14977 (define_insn "fist<mode>2_ceil"
14978 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14979 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14980 UNSPEC_FIST_CEIL))
14981 (use (match_operand:HI 2 "memory_operand" "m"))
14982 (use (match_operand:HI 3 "memory_operand" "m"))]
14983 "TARGET_USE_FANCY_MATH_387
14984 && flag_unsafe_math_optimizations"
14985 "* return output_fix_trunc (insn, operands, false);"
14986 [(set_attr "type" "fistp")
14987 (set_attr "i387_cw" "ceil")
14988 (set_attr "mode" "<MODE>")])
14989
14990 (define_insn "fist<mode>2_ceil_with_temp"
14991 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14992 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14993 UNSPEC_FIST_CEIL))
14994 (use (match_operand:HI 2 "memory_operand" "m,m"))
14995 (use (match_operand:HI 3 "memory_operand" "m,m"))
14996 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14997 "TARGET_USE_FANCY_MATH_387
14998 && flag_unsafe_math_optimizations"
14999 "#"
15000 [(set_attr "type" "fistp")
15001 (set_attr "i387_cw" "ceil")
15002 (set_attr "mode" "<MODE>")])
15003
15004 (define_split
15005 [(set (match_operand:SWI24 0 "register_operand" "")
15006 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15007 UNSPEC_FIST_CEIL))
15008 (use (match_operand:HI 2 "memory_operand" ""))
15009 (use (match_operand:HI 3 "memory_operand" ""))
15010 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15011 "reload_completed"
15012 [(parallel [(set (match_dup 4)
15013 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15014 (use (match_dup 2))
15015 (use (match_dup 3))])
15016 (set (match_dup 0) (match_dup 4))])
15017
15018 (define_split
15019 [(set (match_operand:SWI24 0 "memory_operand" "")
15020 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15021 UNSPEC_FIST_CEIL))
15022 (use (match_operand:HI 2 "memory_operand" ""))
15023 (use (match_operand:HI 3 "memory_operand" ""))
15024 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15025 "reload_completed"
15026 [(parallel [(set (match_dup 0)
15027 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15028 (use (match_dup 2))
15029 (use (match_dup 3))])])
15030
15031 (define_expand "lceilxf<mode>2"
15032 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15033 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15034 UNSPEC_FIST_CEIL))
15035 (clobber (reg:CC FLAGS_REG))])]
15036 "TARGET_USE_FANCY_MATH_387
15037 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15038 && flag_unsafe_math_optimizations")
15039
15040 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15041 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15042 (match_operand:MODEF 1 "register_operand" "")]
15043 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15044 && !flag_trapping_math"
15045 {
15046 ix86_expand_lfloorceil (operand0, operand1, false);
15047 DONE;
15048 })
15049
15050 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15051 (define_insn_and_split "frndintxf2_trunc"
15052 [(set (match_operand:XF 0 "register_operand" "")
15053 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15054 UNSPEC_FRNDINT_TRUNC))
15055 (clobber (reg:CC FLAGS_REG))]
15056 "TARGET_USE_FANCY_MATH_387
15057 && flag_unsafe_math_optimizations
15058 && can_create_pseudo_p ()"
15059 "#"
15060 "&& 1"
15061 [(const_int 0)]
15062 {
15063 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15064
15065 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15066 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15067
15068 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15069 operands[2], operands[3]));
15070 DONE;
15071 }
15072 [(set_attr "type" "frndint")
15073 (set_attr "i387_cw" "trunc")
15074 (set_attr "mode" "XF")])
15075
15076 (define_insn "frndintxf2_trunc_i387"
15077 [(set (match_operand:XF 0 "register_operand" "=f")
15078 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15079 UNSPEC_FRNDINT_TRUNC))
15080 (use (match_operand:HI 2 "memory_operand" "m"))
15081 (use (match_operand:HI 3 "memory_operand" "m"))]
15082 "TARGET_USE_FANCY_MATH_387
15083 && flag_unsafe_math_optimizations"
15084 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15085 [(set_attr "type" "frndint")
15086 (set_attr "i387_cw" "trunc")
15087 (set_attr "mode" "XF")])
15088
15089 (define_expand "btruncxf2"
15090 [(use (match_operand:XF 0 "register_operand" ""))
15091 (use (match_operand:XF 1 "register_operand" ""))]
15092 "TARGET_USE_FANCY_MATH_387
15093 && flag_unsafe_math_optimizations"
15094 {
15095 if (optimize_insn_for_size_p ())
15096 FAIL;
15097 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15098 DONE;
15099 })
15100
15101 (define_expand "btrunc<mode>2"
15102 [(use (match_operand:MODEF 0 "register_operand" ""))
15103 (use (match_operand:MODEF 1 "register_operand" ""))]
15104 "(TARGET_USE_FANCY_MATH_387
15105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15106 || TARGET_MIX_SSE_I387)
15107 && flag_unsafe_math_optimizations)
15108 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15109 && !flag_trapping_math)"
15110 {
15111 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15112 && !flag_trapping_math
15113 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15114 {
15115 if (TARGET_ROUND)
15116 emit_insn (gen_sse4_1_round<mode>2
15117 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15118 else if (optimize_insn_for_size_p ())
15119 FAIL;
15120 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15121 ix86_expand_trunc (operand0, operand1);
15122 else
15123 ix86_expand_truncdf_32 (operand0, operand1);
15124 }
15125 else
15126 {
15127 rtx op0, op1;
15128
15129 if (optimize_insn_for_size_p ())
15130 FAIL;
15131
15132 op0 = gen_reg_rtx (XFmode);
15133 op1 = gen_reg_rtx (XFmode);
15134 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15135 emit_insn (gen_frndintxf2_trunc (op0, op1));
15136
15137 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15138 }
15139 DONE;
15140 })
15141
15142 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15143 (define_insn_and_split "frndintxf2_mask_pm"
15144 [(set (match_operand:XF 0 "register_operand" "")
15145 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15146 UNSPEC_FRNDINT_MASK_PM))
15147 (clobber (reg:CC FLAGS_REG))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations
15150 && can_create_pseudo_p ()"
15151 "#"
15152 "&& 1"
15153 [(const_int 0)]
15154 {
15155 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15156
15157 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15158 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15159
15160 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15161 operands[2], operands[3]));
15162 DONE;
15163 }
15164 [(set_attr "type" "frndint")
15165 (set_attr "i387_cw" "mask_pm")
15166 (set_attr "mode" "XF")])
15167
15168 (define_insn "frndintxf2_mask_pm_i387"
15169 [(set (match_operand:XF 0 "register_operand" "=f")
15170 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15171 UNSPEC_FRNDINT_MASK_PM))
15172 (use (match_operand:HI 2 "memory_operand" "m"))
15173 (use (match_operand:HI 3 "memory_operand" "m"))]
15174 "TARGET_USE_FANCY_MATH_387
15175 && flag_unsafe_math_optimizations"
15176 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15177 [(set_attr "type" "frndint")
15178 (set_attr "i387_cw" "mask_pm")
15179 (set_attr "mode" "XF")])
15180
15181 (define_expand "nearbyintxf2"
15182 [(use (match_operand:XF 0 "register_operand" ""))
15183 (use (match_operand:XF 1 "register_operand" ""))]
15184 "TARGET_USE_FANCY_MATH_387
15185 && flag_unsafe_math_optimizations"
15186 {
15187 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15188 DONE;
15189 })
15190
15191 (define_expand "nearbyint<mode>2"
15192 [(use (match_operand:MODEF 0 "register_operand" ""))
15193 (use (match_operand:MODEF 1 "register_operand" ""))]
15194 "TARGET_USE_FANCY_MATH_387
15195 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15196 || TARGET_MIX_SSE_I387)
15197 && flag_unsafe_math_optimizations"
15198 {
15199 rtx op0 = gen_reg_rtx (XFmode);
15200 rtx op1 = gen_reg_rtx (XFmode);
15201
15202 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15203 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15204
15205 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15206 DONE;
15207 })
15208
15209 (define_insn "fxam<mode>2_i387"
15210 [(set (match_operand:HI 0 "register_operand" "=a")
15211 (unspec:HI
15212 [(match_operand:X87MODEF 1 "register_operand" "f")]
15213 UNSPEC_FXAM))]
15214 "TARGET_USE_FANCY_MATH_387"
15215 "fxam\n\tfnstsw\t%0"
15216 [(set_attr "type" "multi")
15217 (set_attr "length" "4")
15218 (set_attr "unit" "i387")
15219 (set_attr "mode" "<MODE>")])
15220
15221 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15222 [(set (match_operand:HI 0 "register_operand" "")
15223 (unspec:HI
15224 [(match_operand:MODEF 1 "memory_operand" "")]
15225 UNSPEC_FXAM_MEM))]
15226 "TARGET_USE_FANCY_MATH_387
15227 && can_create_pseudo_p ()"
15228 "#"
15229 "&& 1"
15230 [(set (match_dup 2)(match_dup 1))
15231 (set (match_dup 0)
15232 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15233 {
15234 operands[2] = gen_reg_rtx (<MODE>mode);
15235
15236 MEM_VOLATILE_P (operands[1]) = 1;
15237 }
15238 [(set_attr "type" "multi")
15239 (set_attr "unit" "i387")
15240 (set_attr "mode" "<MODE>")])
15241
15242 (define_expand "isinfxf2"
15243 [(use (match_operand:SI 0 "register_operand" ""))
15244 (use (match_operand:XF 1 "register_operand" ""))]
15245 "TARGET_USE_FANCY_MATH_387
15246 && TARGET_C99_FUNCTIONS"
15247 {
15248 rtx mask = GEN_INT (0x45);
15249 rtx val = GEN_INT (0x05);
15250
15251 rtx cond;
15252
15253 rtx scratch = gen_reg_rtx (HImode);
15254 rtx res = gen_reg_rtx (QImode);
15255
15256 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15257
15258 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15259 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15260 cond = gen_rtx_fmt_ee (EQ, QImode,
15261 gen_rtx_REG (CCmode, FLAGS_REG),
15262 const0_rtx);
15263 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15264 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15265 DONE;
15266 })
15267
15268 (define_expand "isinf<mode>2"
15269 [(use (match_operand:SI 0 "register_operand" ""))
15270 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15271 "TARGET_USE_FANCY_MATH_387
15272 && TARGET_C99_FUNCTIONS
15273 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15274 {
15275 rtx mask = GEN_INT (0x45);
15276 rtx val = GEN_INT (0x05);
15277
15278 rtx cond;
15279
15280 rtx scratch = gen_reg_rtx (HImode);
15281 rtx res = gen_reg_rtx (QImode);
15282
15283 /* Remove excess precision by forcing value through memory. */
15284 if (memory_operand (operands[1], VOIDmode))
15285 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15286 else
15287 {
15288 enum ix86_stack_slot slot = (virtuals_instantiated
15289 ? SLOT_TEMP
15290 : SLOT_VIRTUAL);
15291 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15292
15293 emit_move_insn (temp, operands[1]);
15294 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15295 }
15296
15297 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15298 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15299 cond = gen_rtx_fmt_ee (EQ, QImode,
15300 gen_rtx_REG (CCmode, FLAGS_REG),
15301 const0_rtx);
15302 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15303 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15304 DONE;
15305 })
15306
15307 (define_expand "signbitxf2"
15308 [(use (match_operand:SI 0 "register_operand" ""))
15309 (use (match_operand:XF 1 "register_operand" ""))]
15310 "TARGET_USE_FANCY_MATH_387"
15311 {
15312 rtx scratch = gen_reg_rtx (HImode);
15313
15314 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15315 emit_insn (gen_andsi3 (operands[0],
15316 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15317 DONE;
15318 })
15319
15320 (define_insn "movmsk_df"
15321 [(set (match_operand:SI 0 "register_operand" "=r")
15322 (unspec:SI
15323 [(match_operand:DF 1 "register_operand" "x")]
15324 UNSPEC_MOVMSK))]
15325 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15326 "%vmovmskpd\t{%1, %0|%0, %1}"
15327 [(set_attr "type" "ssemov")
15328 (set_attr "prefix" "maybe_vex")
15329 (set_attr "mode" "DF")])
15330
15331 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15332 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15333 (define_expand "signbitdf2"
15334 [(use (match_operand:SI 0 "register_operand" ""))
15335 (use (match_operand:DF 1 "register_operand" ""))]
15336 "TARGET_USE_FANCY_MATH_387
15337 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15338 {
15339 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15340 {
15341 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15342 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15343 }
15344 else
15345 {
15346 rtx scratch = gen_reg_rtx (HImode);
15347
15348 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15349 emit_insn (gen_andsi3 (operands[0],
15350 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15351 }
15352 DONE;
15353 })
15354
15355 (define_expand "signbitsf2"
15356 [(use (match_operand:SI 0 "register_operand" ""))
15357 (use (match_operand:SF 1 "register_operand" ""))]
15358 "TARGET_USE_FANCY_MATH_387
15359 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15360 {
15361 rtx scratch = gen_reg_rtx (HImode);
15362
15363 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15364 emit_insn (gen_andsi3 (operands[0],
15365 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15366 DONE;
15367 })
15368 \f
15369 ;; Block operation instructions
15370
15371 (define_insn "cld"
15372 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15373 ""
15374 "cld"
15375 [(set_attr "length" "1")
15376 (set_attr "length_immediate" "0")
15377 (set_attr "modrm" "0")])
15378
15379 (define_expand "movmem<mode>"
15380 [(use (match_operand:BLK 0 "memory_operand" ""))
15381 (use (match_operand:BLK 1 "memory_operand" ""))
15382 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15383 (use (match_operand:SWI48 3 "const_int_operand" ""))
15384 (use (match_operand:SI 4 "const_int_operand" ""))
15385 (use (match_operand:SI 5 "const_int_operand" ""))]
15386 ""
15387 {
15388 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15389 operands[4], operands[5]))
15390 DONE;
15391 else
15392 FAIL;
15393 })
15394
15395 ;; Most CPUs don't like single string operations
15396 ;; Handle this case here to simplify previous expander.
15397
15398 (define_expand "strmov"
15399 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15400 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15401 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15402 (clobber (reg:CC FLAGS_REG))])
15403 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15404 (clobber (reg:CC FLAGS_REG))])]
15405 ""
15406 {
15407 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15408
15409 /* If .md ever supports :P for Pmode, these can be directly
15410 in the pattern above. */
15411 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15412 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15413
15414 /* Can't use this if the user has appropriated esi or edi. */
15415 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15416 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15417 {
15418 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15419 operands[2], operands[3],
15420 operands[5], operands[6]));
15421 DONE;
15422 }
15423
15424 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15425 })
15426
15427 (define_expand "strmov_singleop"
15428 [(parallel [(set (match_operand 1 "memory_operand" "")
15429 (match_operand 3 "memory_operand" ""))
15430 (set (match_operand 0 "register_operand" "")
15431 (match_operand 4 "" ""))
15432 (set (match_operand 2 "register_operand" "")
15433 (match_operand 5 "" ""))])]
15434 ""
15435 "ix86_current_function_needs_cld = 1;")
15436
15437 (define_insn "*strmovdi_rex_1"
15438 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15439 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15440 (set (match_operand:DI 0 "register_operand" "=D")
15441 (plus:DI (match_dup 2)
15442 (const_int 8)))
15443 (set (match_operand:DI 1 "register_operand" "=S")
15444 (plus:DI (match_dup 3)
15445 (const_int 8)))]
15446 "TARGET_64BIT"
15447 "movsq"
15448 [(set_attr "type" "str")
15449 (set_attr "memory" "both")
15450 (set_attr "mode" "DI")])
15451
15452 (define_insn "*strmovsi_1"
15453 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15454 (mem:SI (match_operand:P 3 "register_operand" "1")))
15455 (set (match_operand:P 0 "register_operand" "=D")
15456 (plus:P (match_dup 2)
15457 (const_int 4)))
15458 (set (match_operand:P 1 "register_operand" "=S")
15459 (plus:P (match_dup 3)
15460 (const_int 4)))]
15461 ""
15462 "movs{l|d}"
15463 [(set_attr "type" "str")
15464 (set_attr "memory" "both")
15465 (set_attr "mode" "SI")])
15466
15467 (define_insn "*strmovhi_1"
15468 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15469 (mem:HI (match_operand:P 3 "register_operand" "1")))
15470 (set (match_operand:P 0 "register_operand" "=D")
15471 (plus:P (match_dup 2)
15472 (const_int 2)))
15473 (set (match_operand:P 1 "register_operand" "=S")
15474 (plus:P (match_dup 3)
15475 (const_int 2)))]
15476 ""
15477 "movsw"
15478 [(set_attr "type" "str")
15479 (set_attr "memory" "both")
15480 (set_attr "mode" "HI")])
15481
15482 (define_insn "*strmovqi_1"
15483 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15484 (mem:QI (match_operand:P 3 "register_operand" "1")))
15485 (set (match_operand:P 0 "register_operand" "=D")
15486 (plus:P (match_dup 2)
15487 (const_int 1)))
15488 (set (match_operand:P 1 "register_operand" "=S")
15489 (plus:P (match_dup 3)
15490 (const_int 1)))]
15491 ""
15492 "movsb"
15493 [(set_attr "type" "str")
15494 (set_attr "memory" "both")
15495 (set (attr "prefix_rex")
15496 (if_then_else
15497 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15498 (const_string "0")
15499 (const_string "*")))
15500 (set_attr "mode" "QI")])
15501
15502 (define_expand "rep_mov"
15503 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15504 (set (match_operand 0 "register_operand" "")
15505 (match_operand 5 "" ""))
15506 (set (match_operand 2 "register_operand" "")
15507 (match_operand 6 "" ""))
15508 (set (match_operand 1 "memory_operand" "")
15509 (match_operand 3 "memory_operand" ""))
15510 (use (match_dup 4))])]
15511 ""
15512 "ix86_current_function_needs_cld = 1;")
15513
15514 (define_insn "*rep_movdi_rex64"
15515 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15516 (set (match_operand:DI 0 "register_operand" "=D")
15517 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15518 (const_int 3))
15519 (match_operand:DI 3 "register_operand" "0")))
15520 (set (match_operand:DI 1 "register_operand" "=S")
15521 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15522 (match_operand:DI 4 "register_operand" "1")))
15523 (set (mem:BLK (match_dup 3))
15524 (mem:BLK (match_dup 4)))
15525 (use (match_dup 5))]
15526 "TARGET_64BIT"
15527 "rep{%;} movsq"
15528 [(set_attr "type" "str")
15529 (set_attr "prefix_rep" "1")
15530 (set_attr "memory" "both")
15531 (set_attr "mode" "DI")])
15532
15533 (define_insn "*rep_movsi"
15534 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15535 (set (match_operand:P 0 "register_operand" "=D")
15536 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15537 (const_int 2))
15538 (match_operand:P 3 "register_operand" "0")))
15539 (set (match_operand:P 1 "register_operand" "=S")
15540 (plus:P (ashift:P (match_dup 5) (const_int 2))
15541 (match_operand:P 4 "register_operand" "1")))
15542 (set (mem:BLK (match_dup 3))
15543 (mem:BLK (match_dup 4)))
15544 (use (match_dup 5))]
15545 ""
15546 "rep{%;} movs{l|d}"
15547 [(set_attr "type" "str")
15548 (set_attr "prefix_rep" "1")
15549 (set_attr "memory" "both")
15550 (set_attr "mode" "SI")])
15551
15552 (define_insn "*rep_movqi"
15553 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15554 (set (match_operand:P 0 "register_operand" "=D")
15555 (plus:P (match_operand:P 3 "register_operand" "0")
15556 (match_operand:P 5 "register_operand" "2")))
15557 (set (match_operand:P 1 "register_operand" "=S")
15558 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15559 (set (mem:BLK (match_dup 3))
15560 (mem:BLK (match_dup 4)))
15561 (use (match_dup 5))]
15562 ""
15563 "rep{%;} movsb"
15564 [(set_attr "type" "str")
15565 (set_attr "prefix_rep" "1")
15566 (set_attr "memory" "both")
15567 (set_attr "mode" "QI")])
15568
15569 (define_expand "setmem<mode>"
15570 [(use (match_operand:BLK 0 "memory_operand" ""))
15571 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15572 (use (match_operand:QI 2 "nonmemory_operand" ""))
15573 (use (match_operand 3 "const_int_operand" ""))
15574 (use (match_operand:SI 4 "const_int_operand" ""))
15575 (use (match_operand:SI 5 "const_int_operand" ""))]
15576 ""
15577 {
15578 if (ix86_expand_setmem (operands[0], operands[1],
15579 operands[2], operands[3],
15580 operands[4], operands[5]))
15581 DONE;
15582 else
15583 FAIL;
15584 })
15585
15586 ;; Most CPUs don't like single string operations
15587 ;; Handle this case here to simplify previous expander.
15588
15589 (define_expand "strset"
15590 [(set (match_operand 1 "memory_operand" "")
15591 (match_operand 2 "register_operand" ""))
15592 (parallel [(set (match_operand 0 "register_operand" "")
15593 (match_dup 3))
15594 (clobber (reg:CC FLAGS_REG))])]
15595 ""
15596 {
15597 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15598 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15599
15600 /* If .md ever supports :P for Pmode, this can be directly
15601 in the pattern above. */
15602 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15603 GEN_INT (GET_MODE_SIZE (GET_MODE
15604 (operands[2]))));
15605 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15606 {
15607 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15608 operands[3]));
15609 DONE;
15610 }
15611 })
15612
15613 (define_expand "strset_singleop"
15614 [(parallel [(set (match_operand 1 "memory_operand" "")
15615 (match_operand 2 "register_operand" ""))
15616 (set (match_operand 0 "register_operand" "")
15617 (match_operand 3 "" ""))])]
15618 ""
15619 "ix86_current_function_needs_cld = 1;")
15620
15621 (define_insn "*strsetdi_rex_1"
15622 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15623 (match_operand:DI 2 "register_operand" "a"))
15624 (set (match_operand:DI 0 "register_operand" "=D")
15625 (plus:DI (match_dup 1)
15626 (const_int 8)))]
15627 "TARGET_64BIT"
15628 "stosq"
15629 [(set_attr "type" "str")
15630 (set_attr "memory" "store")
15631 (set_attr "mode" "DI")])
15632
15633 (define_insn "*strsetsi_1"
15634 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15635 (match_operand:SI 2 "register_operand" "a"))
15636 (set (match_operand:P 0 "register_operand" "=D")
15637 (plus:P (match_dup 1)
15638 (const_int 4)))]
15639 ""
15640 "stos{l|d}"
15641 [(set_attr "type" "str")
15642 (set_attr "memory" "store")
15643 (set_attr "mode" "SI")])
15644
15645 (define_insn "*strsethi_1"
15646 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15647 (match_operand:HI 2 "register_operand" "a"))
15648 (set (match_operand:P 0 "register_operand" "=D")
15649 (plus:P (match_dup 1)
15650 (const_int 2)))]
15651 ""
15652 "stosw"
15653 [(set_attr "type" "str")
15654 (set_attr "memory" "store")
15655 (set_attr "mode" "HI")])
15656
15657 (define_insn "*strsetqi_1"
15658 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15659 (match_operand:QI 2 "register_operand" "a"))
15660 (set (match_operand:P 0 "register_operand" "=D")
15661 (plus:P (match_dup 1)
15662 (const_int 1)))]
15663 ""
15664 "stosb"
15665 [(set_attr "type" "str")
15666 (set_attr "memory" "store")
15667 (set (attr "prefix_rex")
15668 (if_then_else
15669 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15670 (const_string "0")
15671 (const_string "*")))
15672 (set_attr "mode" "QI")])
15673
15674 (define_expand "rep_stos"
15675 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15676 (set (match_operand 0 "register_operand" "")
15677 (match_operand 4 "" ""))
15678 (set (match_operand 2 "memory_operand" "") (const_int 0))
15679 (use (match_operand 3 "register_operand" ""))
15680 (use (match_dup 1))])]
15681 ""
15682 "ix86_current_function_needs_cld = 1;")
15683
15684 (define_insn "*rep_stosdi_rex64"
15685 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15686 (set (match_operand:DI 0 "register_operand" "=D")
15687 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15688 (const_int 3))
15689 (match_operand:DI 3 "register_operand" "0")))
15690 (set (mem:BLK (match_dup 3))
15691 (const_int 0))
15692 (use (match_operand:DI 2 "register_operand" "a"))
15693 (use (match_dup 4))]
15694 "TARGET_64BIT"
15695 "rep{%;} stosq"
15696 [(set_attr "type" "str")
15697 (set_attr "prefix_rep" "1")
15698 (set_attr "memory" "store")
15699 (set_attr "mode" "DI")])
15700
15701 (define_insn "*rep_stossi"
15702 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15703 (set (match_operand:P 0 "register_operand" "=D")
15704 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15705 (const_int 2))
15706 (match_operand:P 3 "register_operand" "0")))
15707 (set (mem:BLK (match_dup 3))
15708 (const_int 0))
15709 (use (match_operand:SI 2 "register_operand" "a"))
15710 (use (match_dup 4))]
15711 ""
15712 "rep{%;} stos{l|d}"
15713 [(set_attr "type" "str")
15714 (set_attr "prefix_rep" "1")
15715 (set_attr "memory" "store")
15716 (set_attr "mode" "SI")])
15717
15718 (define_insn "*rep_stosqi"
15719 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15720 (set (match_operand:P 0 "register_operand" "=D")
15721 (plus:P (match_operand:P 3 "register_operand" "0")
15722 (match_operand:P 4 "register_operand" "1")))
15723 (set (mem:BLK (match_dup 3))
15724 (const_int 0))
15725 (use (match_operand:QI 2 "register_operand" "a"))
15726 (use (match_dup 4))]
15727 ""
15728 "rep{%;} stosb"
15729 [(set_attr "type" "str")
15730 (set_attr "prefix_rep" "1")
15731 (set_attr "memory" "store")
15732 (set (attr "prefix_rex")
15733 (if_then_else
15734 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15735 (const_string "0")
15736 (const_string "*")))
15737 (set_attr "mode" "QI")])
15738
15739 (define_expand "cmpstrnsi"
15740 [(set (match_operand:SI 0 "register_operand" "")
15741 (compare:SI (match_operand:BLK 1 "general_operand" "")
15742 (match_operand:BLK 2 "general_operand" "")))
15743 (use (match_operand 3 "general_operand" ""))
15744 (use (match_operand 4 "immediate_operand" ""))]
15745 ""
15746 {
15747 rtx addr1, addr2, out, outlow, count, countreg, align;
15748
15749 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15750 FAIL;
15751
15752 /* Can't use this if the user has appropriated esi or edi. */
15753 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15754 FAIL;
15755
15756 out = operands[0];
15757 if (!REG_P (out))
15758 out = gen_reg_rtx (SImode);
15759
15760 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15761 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15762 if (addr1 != XEXP (operands[1], 0))
15763 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15764 if (addr2 != XEXP (operands[2], 0))
15765 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15766
15767 count = operands[3];
15768 countreg = ix86_zero_extend_to_Pmode (count);
15769
15770 /* %%% Iff we are testing strict equality, we can use known alignment
15771 to good advantage. This may be possible with combine, particularly
15772 once cc0 is dead. */
15773 align = operands[4];
15774
15775 if (CONST_INT_P (count))
15776 {
15777 if (INTVAL (count) == 0)
15778 {
15779 emit_move_insn (operands[0], const0_rtx);
15780 DONE;
15781 }
15782 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15783 operands[1], operands[2]));
15784 }
15785 else
15786 {
15787 rtx (*gen_cmp) (rtx, rtx);
15788
15789 gen_cmp = (TARGET_64BIT
15790 ? gen_cmpdi_1 : gen_cmpsi_1);
15791
15792 emit_insn (gen_cmp (countreg, countreg));
15793 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15794 operands[1], operands[2]));
15795 }
15796
15797 outlow = gen_lowpart (QImode, out);
15798 emit_insn (gen_cmpintqi (outlow));
15799 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15800
15801 if (operands[0] != out)
15802 emit_move_insn (operands[0], out);
15803
15804 DONE;
15805 })
15806
15807 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15808
15809 (define_expand "cmpintqi"
15810 [(set (match_dup 1)
15811 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15812 (set (match_dup 2)
15813 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15814 (parallel [(set (match_operand:QI 0 "register_operand" "")
15815 (minus:QI (match_dup 1)
15816 (match_dup 2)))
15817 (clobber (reg:CC FLAGS_REG))])]
15818 ""
15819 {
15820 operands[1] = gen_reg_rtx (QImode);
15821 operands[2] = gen_reg_rtx (QImode);
15822 })
15823
15824 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15825 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15826
15827 (define_expand "cmpstrnqi_nz_1"
15828 [(parallel [(set (reg:CC FLAGS_REG)
15829 (compare:CC (match_operand 4 "memory_operand" "")
15830 (match_operand 5 "memory_operand" "")))
15831 (use (match_operand 2 "register_operand" ""))
15832 (use (match_operand:SI 3 "immediate_operand" ""))
15833 (clobber (match_operand 0 "register_operand" ""))
15834 (clobber (match_operand 1 "register_operand" ""))
15835 (clobber (match_dup 2))])]
15836 ""
15837 "ix86_current_function_needs_cld = 1;")
15838
15839 (define_insn "*cmpstrnqi_nz_1"
15840 [(set (reg:CC FLAGS_REG)
15841 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15842 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15843 (use (match_operand:P 6 "register_operand" "2"))
15844 (use (match_operand:SI 3 "immediate_operand" "i"))
15845 (clobber (match_operand:P 0 "register_operand" "=S"))
15846 (clobber (match_operand:P 1 "register_operand" "=D"))
15847 (clobber (match_operand:P 2 "register_operand" "=c"))]
15848 ""
15849 "repz{%;} cmpsb"
15850 [(set_attr "type" "str")
15851 (set_attr "mode" "QI")
15852 (set (attr "prefix_rex")
15853 (if_then_else
15854 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15855 (const_string "0")
15856 (const_string "*")))
15857 (set_attr "prefix_rep" "1")])
15858
15859 ;; The same, but the count is not known to not be zero.
15860
15861 (define_expand "cmpstrnqi_1"
15862 [(parallel [(set (reg:CC FLAGS_REG)
15863 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15864 (const_int 0))
15865 (compare:CC (match_operand 4 "memory_operand" "")
15866 (match_operand 5 "memory_operand" ""))
15867 (const_int 0)))
15868 (use (match_operand:SI 3 "immediate_operand" ""))
15869 (use (reg:CC FLAGS_REG))
15870 (clobber (match_operand 0 "register_operand" ""))
15871 (clobber (match_operand 1 "register_operand" ""))
15872 (clobber (match_dup 2))])]
15873 ""
15874 "ix86_current_function_needs_cld = 1;")
15875
15876 (define_insn "*cmpstrnqi_1"
15877 [(set (reg:CC FLAGS_REG)
15878 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15879 (const_int 0))
15880 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15881 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15882 (const_int 0)))
15883 (use (match_operand:SI 3 "immediate_operand" "i"))
15884 (use (reg:CC FLAGS_REG))
15885 (clobber (match_operand:P 0 "register_operand" "=S"))
15886 (clobber (match_operand:P 1 "register_operand" "=D"))
15887 (clobber (match_operand:P 2 "register_operand" "=c"))]
15888 ""
15889 "repz{%;} cmpsb"
15890 [(set_attr "type" "str")
15891 (set_attr "mode" "QI")
15892 (set (attr "prefix_rex")
15893 (if_then_else
15894 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15895 (const_string "0")
15896 (const_string "*")))
15897 (set_attr "prefix_rep" "1")])
15898
15899 (define_expand "strlen<mode>"
15900 [(set (match_operand:SWI48x 0 "register_operand" "")
15901 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15902 (match_operand:QI 2 "immediate_operand" "")
15903 (match_operand 3 "immediate_operand" "")]
15904 UNSPEC_SCAS))]
15905 ""
15906 {
15907 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15908 DONE;
15909 else
15910 FAIL;
15911 })
15912
15913 (define_expand "strlenqi_1"
15914 [(parallel [(set (match_operand 0 "register_operand" "")
15915 (match_operand 2 "" ""))
15916 (clobber (match_operand 1 "register_operand" ""))
15917 (clobber (reg:CC FLAGS_REG))])]
15918 ""
15919 "ix86_current_function_needs_cld = 1;")
15920
15921 (define_insn "*strlenqi_1"
15922 [(set (match_operand:P 0 "register_operand" "=&c")
15923 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15924 (match_operand:QI 2 "register_operand" "a")
15925 (match_operand:P 3 "immediate_operand" "i")
15926 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15927 (clobber (match_operand:P 1 "register_operand" "=D"))
15928 (clobber (reg:CC FLAGS_REG))]
15929 ""
15930 "repnz{%;} scasb"
15931 [(set_attr "type" "str")
15932 (set_attr "mode" "QI")
15933 (set (attr "prefix_rex")
15934 (if_then_else
15935 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15936 (const_string "0")
15937 (const_string "*")))
15938 (set_attr "prefix_rep" "1")])
15939
15940 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15941 ;; handled in combine, but it is not currently up to the task.
15942 ;; When used for their truth value, the cmpstrn* expanders generate
15943 ;; code like this:
15944 ;;
15945 ;; repz cmpsb
15946 ;; seta %al
15947 ;; setb %dl
15948 ;; cmpb %al, %dl
15949 ;; jcc label
15950 ;;
15951 ;; The intermediate three instructions are unnecessary.
15952
15953 ;; This one handles cmpstrn*_nz_1...
15954 (define_peephole2
15955 [(parallel[
15956 (set (reg:CC FLAGS_REG)
15957 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15958 (mem:BLK (match_operand 5 "register_operand" ""))))
15959 (use (match_operand 6 "register_operand" ""))
15960 (use (match_operand:SI 3 "immediate_operand" ""))
15961 (clobber (match_operand 0 "register_operand" ""))
15962 (clobber (match_operand 1 "register_operand" ""))
15963 (clobber (match_operand 2 "register_operand" ""))])
15964 (set (match_operand:QI 7 "register_operand" "")
15965 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15966 (set (match_operand:QI 8 "register_operand" "")
15967 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15968 (set (reg FLAGS_REG)
15969 (compare (match_dup 7) (match_dup 8)))
15970 ]
15971 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15972 [(parallel[
15973 (set (reg:CC FLAGS_REG)
15974 (compare:CC (mem:BLK (match_dup 4))
15975 (mem:BLK (match_dup 5))))
15976 (use (match_dup 6))
15977 (use (match_dup 3))
15978 (clobber (match_dup 0))
15979 (clobber (match_dup 1))
15980 (clobber (match_dup 2))])])
15981
15982 ;; ...and this one handles cmpstrn*_1.
15983 (define_peephole2
15984 [(parallel[
15985 (set (reg:CC FLAGS_REG)
15986 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15987 (const_int 0))
15988 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15989 (mem:BLK (match_operand 5 "register_operand" "")))
15990 (const_int 0)))
15991 (use (match_operand:SI 3 "immediate_operand" ""))
15992 (use (reg:CC FLAGS_REG))
15993 (clobber (match_operand 0 "register_operand" ""))
15994 (clobber (match_operand 1 "register_operand" ""))
15995 (clobber (match_operand 2 "register_operand" ""))])
15996 (set (match_operand:QI 7 "register_operand" "")
15997 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15998 (set (match_operand:QI 8 "register_operand" "")
15999 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16000 (set (reg FLAGS_REG)
16001 (compare (match_dup 7) (match_dup 8)))
16002 ]
16003 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16004 [(parallel[
16005 (set (reg:CC FLAGS_REG)
16006 (if_then_else:CC (ne (match_dup 6)
16007 (const_int 0))
16008 (compare:CC (mem:BLK (match_dup 4))
16009 (mem:BLK (match_dup 5)))
16010 (const_int 0)))
16011 (use (match_dup 3))
16012 (use (reg:CC FLAGS_REG))
16013 (clobber (match_dup 0))
16014 (clobber (match_dup 1))
16015 (clobber (match_dup 2))])])
16016 \f
16017 ;; Conditional move instructions.
16018
16019 (define_expand "mov<mode>cc"
16020 [(set (match_operand:SWIM 0 "register_operand" "")
16021 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16022 (match_operand:SWIM 2 "general_operand" "")
16023 (match_operand:SWIM 3 "general_operand" "")))]
16024 ""
16025 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16026
16027 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16028 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16029 ;; So just document what we're doing explicitly.
16030
16031 (define_expand "x86_mov<mode>cc_0_m1"
16032 [(parallel
16033 [(set (match_operand:SWI48 0 "register_operand" "")
16034 (if_then_else:SWI48
16035 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16036 [(match_operand 1 "flags_reg_operand" "")
16037 (const_int 0)])
16038 (const_int -1)
16039 (const_int 0)))
16040 (clobber (reg:CC FLAGS_REG))])])
16041
16042 (define_insn "*x86_mov<mode>cc_0_m1"
16043 [(set (match_operand:SWI48 0 "register_operand" "=r")
16044 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16045 [(reg FLAGS_REG) (const_int 0)])
16046 (const_int -1)
16047 (const_int 0)))
16048 (clobber (reg:CC FLAGS_REG))]
16049 ""
16050 "sbb{<imodesuffix>}\t%0, %0"
16051 ; Since we don't have the proper number of operands for an alu insn,
16052 ; fill in all the blanks.
16053 [(set_attr "type" "alu")
16054 (set_attr "use_carry" "1")
16055 (set_attr "pent_pair" "pu")
16056 (set_attr "memory" "none")
16057 (set_attr "imm_disp" "false")
16058 (set_attr "mode" "<MODE>")
16059 (set_attr "length_immediate" "0")])
16060
16061 (define_insn "*x86_mov<mode>cc_0_m1_se"
16062 [(set (match_operand:SWI48 0 "register_operand" "=r")
16063 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16064 [(reg FLAGS_REG) (const_int 0)])
16065 (const_int 1)
16066 (const_int 0)))
16067 (clobber (reg:CC FLAGS_REG))]
16068 ""
16069 "sbb{<imodesuffix>}\t%0, %0"
16070 [(set_attr "type" "alu")
16071 (set_attr "use_carry" "1")
16072 (set_attr "pent_pair" "pu")
16073 (set_attr "memory" "none")
16074 (set_attr "imm_disp" "false")
16075 (set_attr "mode" "<MODE>")
16076 (set_attr "length_immediate" "0")])
16077
16078 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16079 [(set (match_operand:SWI48 0 "register_operand" "=r")
16080 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16081 [(reg FLAGS_REG) (const_int 0)])))]
16082 ""
16083 "sbb{<imodesuffix>}\t%0, %0"
16084 [(set_attr "type" "alu")
16085 (set_attr "use_carry" "1")
16086 (set_attr "pent_pair" "pu")
16087 (set_attr "memory" "none")
16088 (set_attr "imm_disp" "false")
16089 (set_attr "mode" "<MODE>")
16090 (set_attr "length_immediate" "0")])
16091
16092 (define_insn "*mov<mode>cc_noc"
16093 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16094 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16095 [(reg FLAGS_REG) (const_int 0)])
16096 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16097 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16098 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16099 "@
16100 cmov%O2%C1\t{%2, %0|%0, %2}
16101 cmov%O2%c1\t{%3, %0|%0, %3}"
16102 [(set_attr "type" "icmov")
16103 (set_attr "mode" "<MODE>")])
16104
16105 (define_insn_and_split "*movqicc_noc"
16106 [(set (match_operand:QI 0 "register_operand" "=r,r")
16107 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16108 [(match_operand 4 "flags_reg_operand" "")
16109 (const_int 0)])
16110 (match_operand:QI 2 "register_operand" "r,0")
16111 (match_operand:QI 3 "register_operand" "0,r")))]
16112 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16113 "#"
16114 "&& reload_completed"
16115 [(set (match_dup 0)
16116 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16117 (match_dup 2)
16118 (match_dup 3)))]
16119 "operands[0] = gen_lowpart (SImode, operands[0]);
16120 operands[2] = gen_lowpart (SImode, operands[2]);
16121 operands[3] = gen_lowpart (SImode, operands[3]);"
16122 [(set_attr "type" "icmov")
16123 (set_attr "mode" "SI")])
16124
16125 (define_expand "mov<mode>cc"
16126 [(set (match_operand:X87MODEF 0 "register_operand" "")
16127 (if_then_else:X87MODEF
16128 (match_operand 1 "ix86_fp_comparison_operator" "")
16129 (match_operand:X87MODEF 2 "register_operand" "")
16130 (match_operand:X87MODEF 3 "register_operand" "")))]
16131 "(TARGET_80387 && TARGET_CMOVE)
16132 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16133 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16134
16135 (define_insn "*movxfcc_1"
16136 [(set (match_operand:XF 0 "register_operand" "=f,f")
16137 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16138 [(reg FLAGS_REG) (const_int 0)])
16139 (match_operand:XF 2 "register_operand" "f,0")
16140 (match_operand:XF 3 "register_operand" "0,f")))]
16141 "TARGET_80387 && TARGET_CMOVE"
16142 "@
16143 fcmov%F1\t{%2, %0|%0, %2}
16144 fcmov%f1\t{%3, %0|%0, %3}"
16145 [(set_attr "type" "fcmov")
16146 (set_attr "mode" "XF")])
16147
16148 (define_insn "*movdfcc_1_rex64"
16149 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16150 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16151 [(reg FLAGS_REG) (const_int 0)])
16152 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16153 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16154 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16155 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16156 "@
16157 fcmov%F1\t{%2, %0|%0, %2}
16158 fcmov%f1\t{%3, %0|%0, %3}
16159 cmov%O2%C1\t{%2, %0|%0, %2}
16160 cmov%O2%c1\t{%3, %0|%0, %3}"
16161 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16162 (set_attr "mode" "DF,DF,DI,DI")])
16163
16164 (define_insn "*movdfcc_1"
16165 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16166 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16167 [(reg FLAGS_REG) (const_int 0)])
16168 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16169 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16170 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16171 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16172 "@
16173 fcmov%F1\t{%2, %0|%0, %2}
16174 fcmov%f1\t{%3, %0|%0, %3}
16175 #
16176 #"
16177 [(set_attr "type" "fcmov,fcmov,multi,multi")
16178 (set_attr "mode" "DF,DF,DI,DI")])
16179
16180 (define_split
16181 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16182 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16183 [(match_operand 4 "flags_reg_operand" "")
16184 (const_int 0)])
16185 (match_operand:DF 2 "nonimmediate_operand" "")
16186 (match_operand:DF 3 "nonimmediate_operand" "")))]
16187 "!TARGET_64BIT && reload_completed"
16188 [(set (match_dup 2)
16189 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16190 (match_dup 5)
16191 (match_dup 6)))
16192 (set (match_dup 3)
16193 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16194 (match_dup 7)
16195 (match_dup 8)))]
16196 {
16197 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16198 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16199 })
16200
16201 (define_insn "*movsfcc_1_387"
16202 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16203 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16204 [(reg FLAGS_REG) (const_int 0)])
16205 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16206 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16207 "TARGET_80387 && TARGET_CMOVE
16208 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16209 "@
16210 fcmov%F1\t{%2, %0|%0, %2}
16211 fcmov%f1\t{%3, %0|%0, %3}
16212 cmov%O2%C1\t{%2, %0|%0, %2}
16213 cmov%O2%c1\t{%3, %0|%0, %3}"
16214 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16215 (set_attr "mode" "SF,SF,SI,SI")])
16216
16217 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16218 ;; the scalar versions to have only XMM registers as operands.
16219
16220 ;; XOP conditional move
16221 (define_insn "*xop_pcmov_<mode>"
16222 [(set (match_operand:MODEF 0 "register_operand" "=x")
16223 (if_then_else:MODEF
16224 (match_operand:MODEF 1 "register_operand" "x")
16225 (match_operand:MODEF 2 "register_operand" "x")
16226 (match_operand:MODEF 3 "register_operand" "x")))]
16227 "TARGET_XOP"
16228 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16229 [(set_attr "type" "sse4arg")])
16230
16231 ;; These versions of the min/max patterns are intentionally ignorant of
16232 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16233 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16234 ;; are undefined in this condition, we're certain this is correct.
16235
16236 (define_insn "<code><mode>3"
16237 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16238 (smaxmin:MODEF
16239 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16240 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16241 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16242 "@
16243 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16244 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16245 [(set_attr "isa" "noavx,avx")
16246 (set_attr "prefix" "orig,vex")
16247 (set_attr "type" "sseadd")
16248 (set_attr "mode" "<MODE>")])
16249
16250 ;; These versions of the min/max patterns implement exactly the operations
16251 ;; min = (op1 < op2 ? op1 : op2)
16252 ;; max = (!(op1 < op2) ? op1 : op2)
16253 ;; Their operands are not commutative, and thus they may be used in the
16254 ;; presence of -0.0 and NaN.
16255
16256 (define_insn "*ieee_smin<mode>3"
16257 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16258 (unspec:MODEF
16259 [(match_operand:MODEF 1 "register_operand" "0,x")
16260 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16261 UNSPEC_IEEE_MIN))]
16262 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16263 "@
16264 min<ssemodesuffix>\t{%2, %0|%0, %2}
16265 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16266 [(set_attr "isa" "noavx,avx")
16267 (set_attr "prefix" "orig,vex")
16268 (set_attr "type" "sseadd")
16269 (set_attr "mode" "<MODE>")])
16270
16271 (define_insn "*ieee_smax<mode>3"
16272 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16273 (unspec:MODEF
16274 [(match_operand:MODEF 1 "register_operand" "0,x")
16275 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16276 UNSPEC_IEEE_MAX))]
16277 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16278 "@
16279 max<ssemodesuffix>\t{%2, %0|%0, %2}
16280 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16281 [(set_attr "isa" "noavx,avx")
16282 (set_attr "prefix" "orig,vex")
16283 (set_attr "type" "sseadd")
16284 (set_attr "mode" "<MODE>")])
16285
16286 ;; Make two stack loads independent:
16287 ;; fld aa fld aa
16288 ;; fld %st(0) -> fld bb
16289 ;; fmul bb fmul %st(1), %st
16290 ;;
16291 ;; Actually we only match the last two instructions for simplicity.
16292 (define_peephole2
16293 [(set (match_operand 0 "fp_register_operand" "")
16294 (match_operand 1 "fp_register_operand" ""))
16295 (set (match_dup 0)
16296 (match_operator 2 "binary_fp_operator"
16297 [(match_dup 0)
16298 (match_operand 3 "memory_operand" "")]))]
16299 "REGNO (operands[0]) != REGNO (operands[1])"
16300 [(set (match_dup 0) (match_dup 3))
16301 (set (match_dup 0) (match_dup 4))]
16302
16303 ;; The % modifier is not operational anymore in peephole2's, so we have to
16304 ;; swap the operands manually in the case of addition and multiplication.
16305 "if (COMMUTATIVE_ARITH_P (operands[2]))
16306 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16307 GET_MODE (operands[2]),
16308 operands[0], operands[1]);
16309 else
16310 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16311 GET_MODE (operands[2]),
16312 operands[1], operands[0]);")
16313
16314 ;; Conditional addition patterns
16315 (define_expand "add<mode>cc"
16316 [(match_operand:SWI 0 "register_operand" "")
16317 (match_operand 1 "ordered_comparison_operator" "")
16318 (match_operand:SWI 2 "register_operand" "")
16319 (match_operand:SWI 3 "const_int_operand" "")]
16320 ""
16321 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16322 \f
16323 ;; Misc patterns (?)
16324
16325 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16326 ;; Otherwise there will be nothing to keep
16327 ;;
16328 ;; [(set (reg ebp) (reg esp))]
16329 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16330 ;; (clobber (eflags)]
16331 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16332 ;;
16333 ;; in proper program order.
16334
16335 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16336 [(set (match_operand:P 0 "register_operand" "=r,r")
16337 (plus:P (match_operand:P 1 "register_operand" "0,r")
16338 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16339 (clobber (reg:CC FLAGS_REG))
16340 (clobber (mem:BLK (scratch)))]
16341 ""
16342 {
16343 switch (get_attr_type (insn))
16344 {
16345 case TYPE_IMOV:
16346 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16347
16348 case TYPE_ALU:
16349 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16350 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16351 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16352
16353 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16354
16355 default:
16356 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16357 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16358 }
16359 }
16360 [(set (attr "type")
16361 (cond [(and (eq_attr "alternative" "0")
16362 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16363 (const_string "alu")
16364 (match_operand:<MODE> 2 "const0_operand" "")
16365 (const_string "imov")
16366 ]
16367 (const_string "lea")))
16368 (set (attr "length_immediate")
16369 (cond [(eq_attr "type" "imov")
16370 (const_string "0")
16371 (and (eq_attr "type" "alu")
16372 (match_operand 2 "const128_operand" ""))
16373 (const_string "1")
16374 ]
16375 (const_string "*")))
16376 (set_attr "mode" "<MODE>")])
16377
16378 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16379 [(set (match_operand:P 0 "register_operand" "=r")
16380 (minus:P (match_operand:P 1 "register_operand" "0")
16381 (match_operand:P 2 "register_operand" "r")))
16382 (clobber (reg:CC FLAGS_REG))
16383 (clobber (mem:BLK (scratch)))]
16384 ""
16385 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16386 [(set_attr "type" "alu")
16387 (set_attr "mode" "<MODE>")])
16388
16389 (define_insn "allocate_stack_worker_probe_<mode>"
16390 [(set (match_operand:P 0 "register_operand" "=a")
16391 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16392 UNSPECV_STACK_PROBE))
16393 (clobber (reg:CC FLAGS_REG))]
16394 "ix86_target_stack_probe ()"
16395 "call\t___chkstk_ms"
16396 [(set_attr "type" "multi")
16397 (set_attr "length" "5")])
16398
16399 (define_expand "allocate_stack"
16400 [(match_operand 0 "register_operand" "")
16401 (match_operand 1 "general_operand" "")]
16402 "ix86_target_stack_probe ()"
16403 {
16404 rtx x;
16405
16406 #ifndef CHECK_STACK_LIMIT
16407 #define CHECK_STACK_LIMIT 0
16408 #endif
16409
16410 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16411 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16412 {
16413 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16414 stack_pointer_rtx, 0, OPTAB_DIRECT);
16415 if (x != stack_pointer_rtx)
16416 emit_move_insn (stack_pointer_rtx, x);
16417 }
16418 else
16419 {
16420 x = copy_to_mode_reg (Pmode, operands[1]);
16421 if (TARGET_64BIT)
16422 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16423 else
16424 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16425 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16426 stack_pointer_rtx, 0, OPTAB_DIRECT);
16427 if (x != stack_pointer_rtx)
16428 emit_move_insn (stack_pointer_rtx, x);
16429 }
16430
16431 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16432 DONE;
16433 })
16434
16435 ;; Use IOR for stack probes, this is shorter.
16436 (define_expand "probe_stack"
16437 [(match_operand 0 "memory_operand" "")]
16438 ""
16439 {
16440 rtx (*gen_ior3) (rtx, rtx, rtx);
16441
16442 gen_ior3 = (GET_MODE (operands[0]) == DImode
16443 ? gen_iordi3 : gen_iorsi3);
16444
16445 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16446 DONE;
16447 })
16448
16449 (define_insn "adjust_stack_and_probe<mode>"
16450 [(set (match_operand:P 0 "register_operand" "=r")
16451 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16452 UNSPECV_PROBE_STACK_RANGE))
16453 (set (reg:P SP_REG)
16454 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16455 (clobber (reg:CC FLAGS_REG))
16456 (clobber (mem:BLK (scratch)))]
16457 ""
16458 "* return output_adjust_stack_and_probe (operands[0]);"
16459 [(set_attr "type" "multi")])
16460
16461 (define_insn "probe_stack_range<mode>"
16462 [(set (match_operand:P 0 "register_operand" "=r")
16463 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16464 (match_operand:P 2 "const_int_operand" "n")]
16465 UNSPECV_PROBE_STACK_RANGE))
16466 (clobber (reg:CC FLAGS_REG))]
16467 ""
16468 "* return output_probe_stack_range (operands[0], operands[2]);"
16469 [(set_attr "type" "multi")])
16470
16471 (define_expand "builtin_setjmp_receiver"
16472 [(label_ref (match_operand 0 "" ""))]
16473 "!TARGET_64BIT && flag_pic"
16474 {
16475 #if TARGET_MACHO
16476 if (TARGET_MACHO)
16477 {
16478 rtx xops[3];
16479 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16480 rtx label_rtx = gen_label_rtx ();
16481 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16482 xops[0] = xops[1] = picreg;
16483 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16484 ix86_expand_binary_operator (MINUS, SImode, xops);
16485 }
16486 else
16487 #endif
16488 emit_insn (gen_set_got (pic_offset_table_rtx));
16489 DONE;
16490 })
16491 \f
16492 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16493
16494 (define_split
16495 [(set (match_operand 0 "register_operand" "")
16496 (match_operator 3 "promotable_binary_operator"
16497 [(match_operand 1 "register_operand" "")
16498 (match_operand 2 "aligned_operand" "")]))
16499 (clobber (reg:CC FLAGS_REG))]
16500 "! TARGET_PARTIAL_REG_STALL && reload_completed
16501 && ((GET_MODE (operands[0]) == HImode
16502 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16503 /* ??? next two lines just !satisfies_constraint_K (...) */
16504 || !CONST_INT_P (operands[2])
16505 || satisfies_constraint_K (operands[2])))
16506 || (GET_MODE (operands[0]) == QImode
16507 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16508 [(parallel [(set (match_dup 0)
16509 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16510 (clobber (reg:CC FLAGS_REG))])]
16511 "operands[0] = gen_lowpart (SImode, operands[0]);
16512 operands[1] = gen_lowpart (SImode, operands[1]);
16513 if (GET_CODE (operands[3]) != ASHIFT)
16514 operands[2] = gen_lowpart (SImode, operands[2]);
16515 PUT_MODE (operands[3], SImode);")
16516
16517 ; Promote the QImode tests, as i386 has encoding of the AND
16518 ; instruction with 32-bit sign-extended immediate and thus the
16519 ; instruction size is unchanged, except in the %eax case for
16520 ; which it is increased by one byte, hence the ! optimize_size.
16521 (define_split
16522 [(set (match_operand 0 "flags_reg_operand" "")
16523 (match_operator 2 "compare_operator"
16524 [(and (match_operand 3 "aligned_operand" "")
16525 (match_operand 4 "const_int_operand" ""))
16526 (const_int 0)]))
16527 (set (match_operand 1 "register_operand" "")
16528 (and (match_dup 3) (match_dup 4)))]
16529 "! TARGET_PARTIAL_REG_STALL && reload_completed
16530 && optimize_insn_for_speed_p ()
16531 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16532 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16533 /* Ensure that the operand will remain sign-extended immediate. */
16534 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16535 [(parallel [(set (match_dup 0)
16536 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16537 (const_int 0)]))
16538 (set (match_dup 1)
16539 (and:SI (match_dup 3) (match_dup 4)))])]
16540 {
16541 operands[4]
16542 = gen_int_mode (INTVAL (operands[4])
16543 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16544 operands[1] = gen_lowpart (SImode, operands[1]);
16545 operands[3] = gen_lowpart (SImode, operands[3]);
16546 })
16547
16548 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16549 ; the TEST instruction with 32-bit sign-extended immediate and thus
16550 ; the instruction size would at least double, which is not what we
16551 ; want even with ! optimize_size.
16552 (define_split
16553 [(set (match_operand 0 "flags_reg_operand" "")
16554 (match_operator 1 "compare_operator"
16555 [(and (match_operand:HI 2 "aligned_operand" "")
16556 (match_operand:HI 3 "const_int_operand" ""))
16557 (const_int 0)]))]
16558 "! TARGET_PARTIAL_REG_STALL && reload_completed
16559 && ! TARGET_FAST_PREFIX
16560 && optimize_insn_for_speed_p ()
16561 /* Ensure that the operand will remain sign-extended immediate. */
16562 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16563 [(set (match_dup 0)
16564 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16565 (const_int 0)]))]
16566 {
16567 operands[3]
16568 = gen_int_mode (INTVAL (operands[3])
16569 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16570 operands[2] = gen_lowpart (SImode, operands[2]);
16571 })
16572
16573 (define_split
16574 [(set (match_operand 0 "register_operand" "")
16575 (neg (match_operand 1 "register_operand" "")))
16576 (clobber (reg:CC FLAGS_REG))]
16577 "! TARGET_PARTIAL_REG_STALL && reload_completed
16578 && (GET_MODE (operands[0]) == HImode
16579 || (GET_MODE (operands[0]) == QImode
16580 && (TARGET_PROMOTE_QImode
16581 || optimize_insn_for_size_p ())))"
16582 [(parallel [(set (match_dup 0)
16583 (neg:SI (match_dup 1)))
16584 (clobber (reg:CC FLAGS_REG))])]
16585 "operands[0] = gen_lowpart (SImode, operands[0]);
16586 operands[1] = gen_lowpart (SImode, operands[1]);")
16587
16588 (define_split
16589 [(set (match_operand 0 "register_operand" "")
16590 (not (match_operand 1 "register_operand" "")))]
16591 "! TARGET_PARTIAL_REG_STALL && reload_completed
16592 && (GET_MODE (operands[0]) == HImode
16593 || (GET_MODE (operands[0]) == QImode
16594 && (TARGET_PROMOTE_QImode
16595 || optimize_insn_for_size_p ())))"
16596 [(set (match_dup 0)
16597 (not:SI (match_dup 1)))]
16598 "operands[0] = gen_lowpart (SImode, operands[0]);
16599 operands[1] = gen_lowpart (SImode, operands[1]);")
16600
16601 (define_split
16602 [(set (match_operand 0 "register_operand" "")
16603 (if_then_else (match_operator 1 "ordered_comparison_operator"
16604 [(reg FLAGS_REG) (const_int 0)])
16605 (match_operand 2 "register_operand" "")
16606 (match_operand 3 "register_operand" "")))]
16607 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16608 && (GET_MODE (operands[0]) == HImode
16609 || (GET_MODE (operands[0]) == QImode
16610 && (TARGET_PROMOTE_QImode
16611 || optimize_insn_for_size_p ())))"
16612 [(set (match_dup 0)
16613 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16614 "operands[0] = gen_lowpart (SImode, operands[0]);
16615 operands[2] = gen_lowpart (SImode, operands[2]);
16616 operands[3] = gen_lowpart (SImode, operands[3]);")
16617 \f
16618 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16619 ;; transform a complex memory operation into two memory to register operations.
16620
16621 ;; Don't push memory operands
16622 (define_peephole2
16623 [(set (match_operand:SWI 0 "push_operand" "")
16624 (match_operand:SWI 1 "memory_operand" ""))
16625 (match_scratch:SWI 2 "<r>")]
16626 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16627 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16628 [(set (match_dup 2) (match_dup 1))
16629 (set (match_dup 0) (match_dup 2))])
16630
16631 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16632 ;; SImode pushes.
16633 (define_peephole2
16634 [(set (match_operand:SF 0 "push_operand" "")
16635 (match_operand:SF 1 "memory_operand" ""))
16636 (match_scratch:SF 2 "r")]
16637 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16638 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16639 [(set (match_dup 2) (match_dup 1))
16640 (set (match_dup 0) (match_dup 2))])
16641
16642 ;; Don't move an immediate directly to memory when the instruction
16643 ;; gets too big.
16644 (define_peephole2
16645 [(match_scratch:SWI124 1 "<r>")
16646 (set (match_operand:SWI124 0 "memory_operand" "")
16647 (const_int 0))]
16648 "optimize_insn_for_speed_p ()
16649 && !TARGET_USE_MOV0
16650 && TARGET_SPLIT_LONG_MOVES
16651 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16652 && peep2_regno_dead_p (0, FLAGS_REG)"
16653 [(parallel [(set (match_dup 2) (const_int 0))
16654 (clobber (reg:CC FLAGS_REG))])
16655 (set (match_dup 0) (match_dup 1))]
16656 "operands[2] = gen_lowpart (SImode, operands[1]);")
16657
16658 (define_peephole2
16659 [(match_scratch:SWI124 2 "<r>")
16660 (set (match_operand:SWI124 0 "memory_operand" "")
16661 (match_operand:SWI124 1 "immediate_operand" ""))]
16662 "optimize_insn_for_speed_p ()
16663 && TARGET_SPLIT_LONG_MOVES
16664 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16665 [(set (match_dup 2) (match_dup 1))
16666 (set (match_dup 0) (match_dup 2))])
16667
16668 ;; Don't compare memory with zero, load and use a test instead.
16669 (define_peephole2
16670 [(set (match_operand 0 "flags_reg_operand" "")
16671 (match_operator 1 "compare_operator"
16672 [(match_operand:SI 2 "memory_operand" "")
16673 (const_int 0)]))
16674 (match_scratch:SI 3 "r")]
16675 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16676 [(set (match_dup 3) (match_dup 2))
16677 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16678
16679 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16680 ;; Don't split NOTs with a displacement operand, because resulting XOR
16681 ;; will not be pairable anyway.
16682 ;;
16683 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16684 ;; represented using a modRM byte. The XOR replacement is long decoded,
16685 ;; so this split helps here as well.
16686 ;;
16687 ;; Note: Can't do this as a regular split because we can't get proper
16688 ;; lifetime information then.
16689
16690 (define_peephole2
16691 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16692 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16693 "optimize_insn_for_speed_p ()
16694 && ((TARGET_NOT_UNPAIRABLE
16695 && (!MEM_P (operands[0])
16696 || !memory_displacement_operand (operands[0], <MODE>mode)))
16697 || (TARGET_NOT_VECTORMODE
16698 && long_memory_operand (operands[0], <MODE>mode)))
16699 && peep2_regno_dead_p (0, FLAGS_REG)"
16700 [(parallel [(set (match_dup 0)
16701 (xor:SWI124 (match_dup 1) (const_int -1)))
16702 (clobber (reg:CC FLAGS_REG))])])
16703
16704 ;; Non pairable "test imm, reg" instructions can be translated to
16705 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16706 ;; byte opcode instead of two, have a short form for byte operands),
16707 ;; so do it for other CPUs as well. Given that the value was dead,
16708 ;; this should not create any new dependencies. Pass on the sub-word
16709 ;; versions if we're concerned about partial register stalls.
16710
16711 (define_peephole2
16712 [(set (match_operand 0 "flags_reg_operand" "")
16713 (match_operator 1 "compare_operator"
16714 [(and:SI (match_operand:SI 2 "register_operand" "")
16715 (match_operand:SI 3 "immediate_operand" ""))
16716 (const_int 0)]))]
16717 "ix86_match_ccmode (insn, CCNOmode)
16718 && (true_regnum (operands[2]) != AX_REG
16719 || satisfies_constraint_K (operands[3]))
16720 && peep2_reg_dead_p (1, operands[2])"
16721 [(parallel
16722 [(set (match_dup 0)
16723 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16724 (const_int 0)]))
16725 (set (match_dup 2)
16726 (and:SI (match_dup 2) (match_dup 3)))])])
16727
16728 ;; We don't need to handle HImode case, because it will be promoted to SImode
16729 ;; on ! TARGET_PARTIAL_REG_STALL
16730
16731 (define_peephole2
16732 [(set (match_operand 0 "flags_reg_operand" "")
16733 (match_operator 1 "compare_operator"
16734 [(and:QI (match_operand:QI 2 "register_operand" "")
16735 (match_operand:QI 3 "immediate_operand" ""))
16736 (const_int 0)]))]
16737 "! TARGET_PARTIAL_REG_STALL
16738 && ix86_match_ccmode (insn, CCNOmode)
16739 && true_regnum (operands[2]) != AX_REG
16740 && peep2_reg_dead_p (1, operands[2])"
16741 [(parallel
16742 [(set (match_dup 0)
16743 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16744 (const_int 0)]))
16745 (set (match_dup 2)
16746 (and:QI (match_dup 2) (match_dup 3)))])])
16747
16748 (define_peephole2
16749 [(set (match_operand 0 "flags_reg_operand" "")
16750 (match_operator 1 "compare_operator"
16751 [(and:SI
16752 (zero_extract:SI
16753 (match_operand 2 "ext_register_operand" "")
16754 (const_int 8)
16755 (const_int 8))
16756 (match_operand 3 "const_int_operand" ""))
16757 (const_int 0)]))]
16758 "! TARGET_PARTIAL_REG_STALL
16759 && ix86_match_ccmode (insn, CCNOmode)
16760 && true_regnum (operands[2]) != AX_REG
16761 && peep2_reg_dead_p (1, operands[2])"
16762 [(parallel [(set (match_dup 0)
16763 (match_op_dup 1
16764 [(and:SI
16765 (zero_extract:SI
16766 (match_dup 2)
16767 (const_int 8)
16768 (const_int 8))
16769 (match_dup 3))
16770 (const_int 0)]))
16771 (set (zero_extract:SI (match_dup 2)
16772 (const_int 8)
16773 (const_int 8))
16774 (and:SI
16775 (zero_extract:SI
16776 (match_dup 2)
16777 (const_int 8)
16778 (const_int 8))
16779 (match_dup 3)))])])
16780
16781 ;; Don't do logical operations with memory inputs.
16782 (define_peephole2
16783 [(match_scratch:SI 2 "r")
16784 (parallel [(set (match_operand:SI 0 "register_operand" "")
16785 (match_operator:SI 3 "arith_or_logical_operator"
16786 [(match_dup 0)
16787 (match_operand:SI 1 "memory_operand" "")]))
16788 (clobber (reg:CC FLAGS_REG))])]
16789 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16790 [(set (match_dup 2) (match_dup 1))
16791 (parallel [(set (match_dup 0)
16792 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16793 (clobber (reg:CC FLAGS_REG))])])
16794
16795 (define_peephole2
16796 [(match_scratch:SI 2 "r")
16797 (parallel [(set (match_operand:SI 0 "register_operand" "")
16798 (match_operator:SI 3 "arith_or_logical_operator"
16799 [(match_operand:SI 1 "memory_operand" "")
16800 (match_dup 0)]))
16801 (clobber (reg:CC FLAGS_REG))])]
16802 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16803 [(set (match_dup 2) (match_dup 1))
16804 (parallel [(set (match_dup 0)
16805 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16806 (clobber (reg:CC FLAGS_REG))])])
16807
16808 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16809 ;; refers to the destination of the load!
16810
16811 (define_peephole2
16812 [(set (match_operand:SI 0 "register_operand" "")
16813 (match_operand:SI 1 "register_operand" ""))
16814 (parallel [(set (match_dup 0)
16815 (match_operator:SI 3 "commutative_operator"
16816 [(match_dup 0)
16817 (match_operand:SI 2 "memory_operand" "")]))
16818 (clobber (reg:CC FLAGS_REG))])]
16819 "REGNO (operands[0]) != REGNO (operands[1])
16820 && GENERAL_REGNO_P (REGNO (operands[0]))
16821 && GENERAL_REGNO_P (REGNO (operands[1]))"
16822 [(set (match_dup 0) (match_dup 4))
16823 (parallel [(set (match_dup 0)
16824 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16825 (clobber (reg:CC FLAGS_REG))])]
16826 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16827
16828 (define_peephole2
16829 [(set (match_operand 0 "register_operand" "")
16830 (match_operand 1 "register_operand" ""))
16831 (set (match_dup 0)
16832 (match_operator 3 "commutative_operator"
16833 [(match_dup 0)
16834 (match_operand 2 "memory_operand" "")]))]
16835 "REGNO (operands[0]) != REGNO (operands[1])
16836 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16837 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16838 [(set (match_dup 0) (match_dup 2))
16839 (set (match_dup 0)
16840 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16841
16842 ; Don't do logical operations with memory outputs
16843 ;
16844 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16845 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16846 ; the same decoder scheduling characteristics as the original.
16847
16848 (define_peephole2
16849 [(match_scratch:SI 2 "r")
16850 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16851 (match_operator:SI 3 "arith_or_logical_operator"
16852 [(match_dup 0)
16853 (match_operand:SI 1 "nonmemory_operand" "")]))
16854 (clobber (reg:CC FLAGS_REG))])]
16855 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16856 /* Do not split stack checking probes. */
16857 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16858 [(set (match_dup 2) (match_dup 0))
16859 (parallel [(set (match_dup 2)
16860 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16861 (clobber (reg:CC FLAGS_REG))])
16862 (set (match_dup 0) (match_dup 2))])
16863
16864 (define_peephole2
16865 [(match_scratch:SI 2 "r")
16866 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16867 (match_operator:SI 3 "arith_or_logical_operator"
16868 [(match_operand:SI 1 "nonmemory_operand" "")
16869 (match_dup 0)]))
16870 (clobber (reg:CC FLAGS_REG))])]
16871 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16872 /* Do not split stack checking probes. */
16873 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16874 [(set (match_dup 2) (match_dup 0))
16875 (parallel [(set (match_dup 2)
16876 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16877 (clobber (reg:CC FLAGS_REG))])
16878 (set (match_dup 0) (match_dup 2))])
16879
16880 ;; Attempt to use arith or logical operations with memory outputs with
16881 ;; setting of flags.
16882 (define_peephole2
16883 [(set (match_operand:SWI 0 "register_operand" "")
16884 (match_operand:SWI 1 "memory_operand" ""))
16885 (parallel [(set (match_dup 0)
16886 (match_operator:SWI 3 "plusminuslogic_operator"
16887 [(match_dup 0)
16888 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16889 (clobber (reg:CC FLAGS_REG))])
16890 (set (match_dup 1) (match_dup 0))
16891 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16892 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16893 && peep2_reg_dead_p (4, operands[0])
16894 && !reg_overlap_mentioned_p (operands[0], operands[1])
16895 && ix86_match_ccmode (peep2_next_insn (3),
16896 (GET_CODE (operands[3]) == PLUS
16897 || GET_CODE (operands[3]) == MINUS)
16898 ? CCGOCmode : CCNOmode)"
16899 [(parallel [(set (match_dup 4) (match_dup 5))
16900 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16901 (match_dup 2)]))])]
16902 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16903 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16904 copy_rtx (operands[1]),
16905 copy_rtx (operands[2]));
16906 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16907 operands[5], const0_rtx);")
16908
16909 (define_peephole2
16910 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16911 (match_operator:SWI 2 "plusminuslogic_operator"
16912 [(match_dup 0)
16913 (match_operand:SWI 1 "memory_operand" "")]))
16914 (clobber (reg:CC FLAGS_REG))])
16915 (set (match_dup 1) (match_dup 0))
16916 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16917 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16918 && GET_CODE (operands[2]) != MINUS
16919 && peep2_reg_dead_p (3, operands[0])
16920 && !reg_overlap_mentioned_p (operands[0], operands[1])
16921 && ix86_match_ccmode (peep2_next_insn (2),
16922 GET_CODE (operands[2]) == PLUS
16923 ? CCGOCmode : CCNOmode)"
16924 [(parallel [(set (match_dup 3) (match_dup 4))
16925 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16926 (match_dup 0)]))])]
16927 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16928 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16929 copy_rtx (operands[1]),
16930 copy_rtx (operands[0]));
16931 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16932 operands[4], const0_rtx);")
16933
16934 (define_peephole2
16935 [(set (match_operand:SWI12 0 "register_operand" "")
16936 (match_operand:SWI12 1 "memory_operand" ""))
16937 (parallel [(set (match_operand:SI 4 "register_operand" "")
16938 (match_operator:SI 3 "plusminuslogic_operator"
16939 [(match_dup 4)
16940 (match_operand:SI 2 "nonmemory_operand" "")]))
16941 (clobber (reg:CC FLAGS_REG))])
16942 (set (match_dup 1) (match_dup 0))
16943 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16944 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16945 && REG_P (operands[0]) && REG_P (operands[4])
16946 && REGNO (operands[0]) == REGNO (operands[4])
16947 && peep2_reg_dead_p (4, operands[0])
16948 && !reg_overlap_mentioned_p (operands[0], operands[1])
16949 && ix86_match_ccmode (peep2_next_insn (3),
16950 (GET_CODE (operands[3]) == PLUS
16951 || GET_CODE (operands[3]) == MINUS)
16952 ? CCGOCmode : CCNOmode)"
16953 [(parallel [(set (match_dup 4) (match_dup 5))
16954 (set (match_dup 1) (match_dup 6))])]
16955 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16956 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16957 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16958 copy_rtx (operands[1]), operands[2]);
16959 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16960 operands[5], const0_rtx);
16961 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16962 copy_rtx (operands[1]),
16963 copy_rtx (operands[2]));")
16964
16965 ;; Attempt to always use XOR for zeroing registers.
16966 (define_peephole2
16967 [(set (match_operand 0 "register_operand" "")
16968 (match_operand 1 "const0_operand" ""))]
16969 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16970 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16971 && GENERAL_REG_P (operands[0])
16972 && peep2_regno_dead_p (0, FLAGS_REG)"
16973 [(parallel [(set (match_dup 0) (const_int 0))
16974 (clobber (reg:CC FLAGS_REG))])]
16975 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16976
16977 (define_peephole2
16978 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16979 (const_int 0))]
16980 "(GET_MODE (operands[0]) == QImode
16981 || GET_MODE (operands[0]) == HImode)
16982 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16983 && peep2_regno_dead_p (0, FLAGS_REG)"
16984 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16985 (clobber (reg:CC FLAGS_REG))])])
16986
16987 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16988 (define_peephole2
16989 [(set (match_operand:SWI248 0 "register_operand" "")
16990 (const_int -1))]
16991 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16992 && peep2_regno_dead_p (0, FLAGS_REG)"
16993 [(parallel [(set (match_dup 0) (const_int -1))
16994 (clobber (reg:CC FLAGS_REG))])]
16995 {
16996 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16997 operands[0] = gen_lowpart (SImode, operands[0]);
16998 })
16999
17000 ;; Attempt to convert simple lea to add/shift.
17001 ;; These can be created by move expanders.
17002
17003 (define_peephole2
17004 [(set (match_operand:SWI48 0 "register_operand" "")
17005 (plus:SWI48 (match_dup 0)
17006 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17007 "peep2_regno_dead_p (0, FLAGS_REG)"
17008 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17009 (clobber (reg:CC FLAGS_REG))])])
17010
17011 (define_peephole2
17012 [(set (match_operand:SI 0 "register_operand" "")
17013 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17014 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17015 "TARGET_64BIT
17016 && peep2_regno_dead_p (0, FLAGS_REG)
17017 && REGNO (operands[0]) == REGNO (operands[1])"
17018 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17019 (clobber (reg:CC FLAGS_REG))])]
17020 "operands[2] = gen_lowpart (SImode, operands[2]);")
17021
17022 (define_peephole2
17023 [(set (match_operand:SWI48 0 "register_operand" "")
17024 (mult:SWI48 (match_dup 0)
17025 (match_operand:SWI48 1 "const_int_operand" "")))]
17026 "exact_log2 (INTVAL (operands[1])) >= 0
17027 && peep2_regno_dead_p (0, FLAGS_REG)"
17028 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17029 (clobber (reg:CC FLAGS_REG))])]
17030 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17031
17032 (define_peephole2
17033 [(set (match_operand:SI 0 "register_operand" "")
17034 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17035 (match_operand:DI 2 "const_int_operand" "")) 0))]
17036 "TARGET_64BIT
17037 && exact_log2 (INTVAL (operands[2])) >= 0
17038 && REGNO (operands[0]) == REGNO (operands[1])
17039 && peep2_regno_dead_p (0, FLAGS_REG)"
17040 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17041 (clobber (reg:CC FLAGS_REG))])]
17042 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17043
17044 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17045 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17046 ;; On many CPUs it is also faster, since special hardware to avoid esp
17047 ;; dependencies is present.
17048
17049 ;; While some of these conversions may be done using splitters, we use
17050 ;; peepholes in order to allow combine_stack_adjustments pass to see
17051 ;; nonobfuscated RTL.
17052
17053 ;; Convert prologue esp subtractions to push.
17054 ;; We need register to push. In order to keep verify_flow_info happy we have
17055 ;; two choices
17056 ;; - use scratch and clobber it in order to avoid dependencies
17057 ;; - use already live register
17058 ;; We can't use the second way right now, since there is no reliable way how to
17059 ;; verify that given register is live. First choice will also most likely in
17060 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17061 ;; call clobbered registers are dead. We may want to use base pointer as an
17062 ;; alternative when no register is available later.
17063
17064 (define_peephole2
17065 [(match_scratch:P 1 "r")
17066 (parallel [(set (reg:P SP_REG)
17067 (plus:P (reg:P SP_REG)
17068 (match_operand:P 0 "const_int_operand" "")))
17069 (clobber (reg:CC FLAGS_REG))
17070 (clobber (mem:BLK (scratch)))])]
17071 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17072 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17073 [(clobber (match_dup 1))
17074 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17075 (clobber (mem:BLK (scratch)))])])
17076
17077 (define_peephole2
17078 [(match_scratch:P 1 "r")
17079 (parallel [(set (reg:P SP_REG)
17080 (plus:P (reg:P SP_REG)
17081 (match_operand:P 0 "const_int_operand" "")))
17082 (clobber (reg:CC FLAGS_REG))
17083 (clobber (mem:BLK (scratch)))])]
17084 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17085 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17086 [(clobber (match_dup 1))
17087 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17088 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17089 (clobber (mem:BLK (scratch)))])])
17090
17091 ;; Convert esp subtractions to push.
17092 (define_peephole2
17093 [(match_scratch:P 1 "r")
17094 (parallel [(set (reg:P SP_REG)
17095 (plus:P (reg:P SP_REG)
17096 (match_operand:P 0 "const_int_operand" "")))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17099 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17100 [(clobber (match_dup 1))
17101 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17102
17103 (define_peephole2
17104 [(match_scratch:P 1 "r")
17105 (parallel [(set (reg:P SP_REG)
17106 (plus:P (reg:P SP_REG)
17107 (match_operand:P 0 "const_int_operand" "")))
17108 (clobber (reg:CC FLAGS_REG))])]
17109 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17110 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17111 [(clobber (match_dup 1))
17112 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17113 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17114
17115 ;; Convert epilogue deallocator to pop.
17116 (define_peephole2
17117 [(match_scratch:P 1 "r")
17118 (parallel [(set (reg:P SP_REG)
17119 (plus:P (reg:P SP_REG)
17120 (match_operand:P 0 "const_int_operand" "")))
17121 (clobber (reg:CC FLAGS_REG))
17122 (clobber (mem:BLK (scratch)))])]
17123 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17124 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17125 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17126 (clobber (mem:BLK (scratch)))])])
17127
17128 ;; Two pops case is tricky, since pop causes dependency
17129 ;; on destination register. We use two registers if available.
17130 (define_peephole2
17131 [(match_scratch:P 1 "r")
17132 (match_scratch:P 2 "r")
17133 (parallel [(set (reg:P SP_REG)
17134 (plus:P (reg:P SP_REG)
17135 (match_operand:P 0 "const_int_operand" "")))
17136 (clobber (reg:CC FLAGS_REG))
17137 (clobber (mem:BLK (scratch)))])]
17138 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17139 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17140 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17141 (clobber (mem:BLK (scratch)))])
17142 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17143
17144 (define_peephole2
17145 [(match_scratch:P 1 "r")
17146 (parallel [(set (reg:P SP_REG)
17147 (plus:P (reg:P SP_REG)
17148 (match_operand:P 0 "const_int_operand" "")))
17149 (clobber (reg:CC FLAGS_REG))
17150 (clobber (mem:BLK (scratch)))])]
17151 "optimize_insn_for_size_p ()
17152 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17153 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17154 (clobber (mem:BLK (scratch)))])
17155 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17156
17157 ;; Convert esp additions to pop.
17158 (define_peephole2
17159 [(match_scratch:P 1 "r")
17160 (parallel [(set (reg:P SP_REG)
17161 (plus:P (reg:P SP_REG)
17162 (match_operand:P 0 "const_int_operand" "")))
17163 (clobber (reg:CC FLAGS_REG))])]
17164 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17165 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17166
17167 ;; Two pops case is tricky, since pop causes dependency
17168 ;; on destination register. We use two registers if available.
17169 (define_peephole2
17170 [(match_scratch:P 1 "r")
17171 (match_scratch:P 2 "r")
17172 (parallel [(set (reg:P SP_REG)
17173 (plus:P (reg:P SP_REG)
17174 (match_operand:P 0 "const_int_operand" "")))
17175 (clobber (reg:CC FLAGS_REG))])]
17176 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17177 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17178 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17179
17180 (define_peephole2
17181 [(match_scratch:P 1 "r")
17182 (parallel [(set (reg:P SP_REG)
17183 (plus:P (reg:P SP_REG)
17184 (match_operand:P 0 "const_int_operand" "")))
17185 (clobber (reg:CC FLAGS_REG))])]
17186 "optimize_insn_for_size_p ()
17187 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17188 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17189 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17190 \f
17191 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17192 ;; required and register dies. Similarly for 128 to -128.
17193 (define_peephole2
17194 [(set (match_operand 0 "flags_reg_operand" "")
17195 (match_operator 1 "compare_operator"
17196 [(match_operand 2 "register_operand" "")
17197 (match_operand 3 "const_int_operand" "")]))]
17198 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17199 && incdec_operand (operands[3], GET_MODE (operands[3])))
17200 || (!TARGET_FUSE_CMP_AND_BRANCH
17201 && INTVAL (operands[3]) == 128))
17202 && ix86_match_ccmode (insn, CCGCmode)
17203 && peep2_reg_dead_p (1, operands[2])"
17204 [(parallel [(set (match_dup 0)
17205 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17206 (clobber (match_dup 2))])])
17207 \f
17208 ;; Convert imul by three, five and nine into lea
17209 (define_peephole2
17210 [(parallel
17211 [(set (match_operand:SWI48 0 "register_operand" "")
17212 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17213 (match_operand:SWI48 2 "const359_operand" "")))
17214 (clobber (reg:CC FLAGS_REG))])]
17215 "!TARGET_PARTIAL_REG_STALL
17216 || <MODE>mode == SImode
17217 || optimize_function_for_size_p (cfun)"
17218 [(set (match_dup 0)
17219 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17220 (match_dup 1)))]
17221 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17222
17223 (define_peephole2
17224 [(parallel
17225 [(set (match_operand:SWI48 0 "register_operand" "")
17226 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17227 (match_operand:SWI48 2 "const359_operand" "")))
17228 (clobber (reg:CC FLAGS_REG))])]
17229 "optimize_insn_for_speed_p ()
17230 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17231 [(set (match_dup 0) (match_dup 1))
17232 (set (match_dup 0)
17233 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17234 (match_dup 0)))]
17235 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17236
17237 ;; imul $32bit_imm, mem, reg is vector decoded, while
17238 ;; imul $32bit_imm, reg, reg is direct decoded.
17239 (define_peephole2
17240 [(match_scratch:SWI48 3 "r")
17241 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17242 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17243 (match_operand:SWI48 2 "immediate_operand" "")))
17244 (clobber (reg:CC FLAGS_REG))])]
17245 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17246 && !satisfies_constraint_K (operands[2])"
17247 [(set (match_dup 3) (match_dup 1))
17248 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17249 (clobber (reg:CC FLAGS_REG))])])
17250
17251 (define_peephole2
17252 [(match_scratch:SI 3 "r")
17253 (parallel [(set (match_operand:DI 0 "register_operand" "")
17254 (zero_extend:DI
17255 (mult:SI (match_operand:SI 1 "memory_operand" "")
17256 (match_operand:SI 2 "immediate_operand" ""))))
17257 (clobber (reg:CC FLAGS_REG))])]
17258 "TARGET_64BIT
17259 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17260 && !satisfies_constraint_K (operands[2])"
17261 [(set (match_dup 3) (match_dup 1))
17262 (parallel [(set (match_dup 0)
17263 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17264 (clobber (reg:CC FLAGS_REG))])])
17265
17266 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17267 ;; Convert it into imul reg, reg
17268 ;; It would be better to force assembler to encode instruction using long
17269 ;; immediate, but there is apparently no way to do so.
17270 (define_peephole2
17271 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17272 (mult:SWI248
17273 (match_operand:SWI248 1 "nonimmediate_operand" "")
17274 (match_operand:SWI248 2 "const_int_operand" "")))
17275 (clobber (reg:CC FLAGS_REG))])
17276 (match_scratch:SWI248 3 "r")]
17277 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17278 && satisfies_constraint_K (operands[2])"
17279 [(set (match_dup 3) (match_dup 2))
17280 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17281 (clobber (reg:CC FLAGS_REG))])]
17282 {
17283 if (!rtx_equal_p (operands[0], operands[1]))
17284 emit_move_insn (operands[0], operands[1]);
17285 })
17286
17287 ;; After splitting up read-modify operations, array accesses with memory
17288 ;; operands might end up in form:
17289 ;; sall $2, %eax
17290 ;; movl 4(%esp), %edx
17291 ;; addl %edx, %eax
17292 ;; instead of pre-splitting:
17293 ;; sall $2, %eax
17294 ;; addl 4(%esp), %eax
17295 ;; Turn it into:
17296 ;; movl 4(%esp), %edx
17297 ;; leal (%edx,%eax,4), %eax
17298
17299 (define_peephole2
17300 [(match_scratch:P 5 "r")
17301 (parallel [(set (match_operand 0 "register_operand" "")
17302 (ashift (match_operand 1 "register_operand" "")
17303 (match_operand 2 "const_int_operand" "")))
17304 (clobber (reg:CC FLAGS_REG))])
17305 (parallel [(set (match_operand 3 "register_operand" "")
17306 (plus (match_dup 0)
17307 (match_operand 4 "x86_64_general_operand" "")))
17308 (clobber (reg:CC FLAGS_REG))])]
17309 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17310 /* Validate MODE for lea. */
17311 && ((!TARGET_PARTIAL_REG_STALL
17312 && (GET_MODE (operands[0]) == QImode
17313 || GET_MODE (operands[0]) == HImode))
17314 || GET_MODE (operands[0]) == SImode
17315 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17316 && (rtx_equal_p (operands[0], operands[3])
17317 || peep2_reg_dead_p (2, operands[0]))
17318 /* We reorder load and the shift. */
17319 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17320 [(set (match_dup 5) (match_dup 4))
17321 (set (match_dup 0) (match_dup 1))]
17322 {
17323 enum machine_mode op1mode = GET_MODE (operands[1]);
17324 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17325 int scale = 1 << INTVAL (operands[2]);
17326 rtx index = gen_lowpart (Pmode, operands[1]);
17327 rtx base = gen_lowpart (Pmode, operands[5]);
17328 rtx dest = gen_lowpart (mode, operands[3]);
17329
17330 operands[1] = gen_rtx_PLUS (Pmode, base,
17331 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17332 operands[5] = base;
17333 if (mode != Pmode)
17334 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17335 if (op1mode != Pmode)
17336 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17337 operands[0] = dest;
17338 })
17339 \f
17340 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17341 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17342 ;; caught for use by garbage collectors and the like. Using an insn that
17343 ;; maps to SIGILL makes it more likely the program will rightfully die.
17344 ;; Keeping with tradition, "6" is in honor of #UD.
17345 (define_insn "trap"
17346 [(trap_if (const_int 1) (const_int 6))]
17347 ""
17348 { return ASM_SHORT "0x0b0f"; }
17349 [(set_attr "length" "2")])
17350
17351 (define_expand "prefetch"
17352 [(prefetch (match_operand 0 "address_operand" "")
17353 (match_operand:SI 1 "const_int_operand" "")
17354 (match_operand:SI 2 "const_int_operand" ""))]
17355 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17356 {
17357 int rw = INTVAL (operands[1]);
17358 int locality = INTVAL (operands[2]);
17359
17360 gcc_assert (rw == 0 || rw == 1);
17361 gcc_assert (locality >= 0 && locality <= 3);
17362 gcc_assert (GET_MODE (operands[0]) == Pmode
17363 || GET_MODE (operands[0]) == VOIDmode);
17364
17365 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17366 supported by SSE counterpart or the SSE prefetch is not available
17367 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17368 of locality. */
17369 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17370 operands[2] = GEN_INT (3);
17371 else
17372 operands[1] = const0_rtx;
17373 })
17374
17375 (define_insn "*prefetch_sse_<mode>"
17376 [(prefetch (match_operand:P 0 "address_operand" "p")
17377 (const_int 0)
17378 (match_operand:SI 1 "const_int_operand" ""))]
17379 "TARGET_PREFETCH_SSE"
17380 {
17381 static const char * const patterns[4] = {
17382 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17383 };
17384
17385 int locality = INTVAL (operands[1]);
17386 gcc_assert (locality >= 0 && locality <= 3);
17387
17388 return patterns[locality];
17389 }
17390 [(set_attr "type" "sse")
17391 (set_attr "atom_sse_attr" "prefetch")
17392 (set (attr "length_address")
17393 (symbol_ref "memory_address_length (operands[0])"))
17394 (set_attr "memory" "none")])
17395
17396 (define_insn "*prefetch_3dnow_<mode>"
17397 [(prefetch (match_operand:P 0 "address_operand" "p")
17398 (match_operand:SI 1 "const_int_operand" "n")
17399 (const_int 3))]
17400 "TARGET_3DNOW"
17401 {
17402 if (INTVAL (operands[1]) == 0)
17403 return "prefetch\t%a0";
17404 else
17405 return "prefetchw\t%a0";
17406 }
17407 [(set_attr "type" "mmx")
17408 (set (attr "length_address")
17409 (symbol_ref "memory_address_length (operands[0])"))
17410 (set_attr "memory" "none")])
17411
17412 (define_expand "stack_protect_set"
17413 [(match_operand 0 "memory_operand" "")
17414 (match_operand 1 "memory_operand" "")]
17415 ""
17416 {
17417 rtx (*insn)(rtx, rtx);
17418
17419 #ifdef TARGET_THREAD_SSP_OFFSET
17420 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17421 insn = (TARGET_64BIT
17422 ? gen_stack_tls_protect_set_di
17423 : gen_stack_tls_protect_set_si);
17424 #else
17425 insn = (TARGET_64BIT
17426 ? gen_stack_protect_set_di
17427 : gen_stack_protect_set_si);
17428 #endif
17429
17430 emit_insn (insn (operands[0], operands[1]));
17431 DONE;
17432 })
17433
17434 (define_insn "stack_protect_set_<mode>"
17435 [(set (match_operand:P 0 "memory_operand" "=m")
17436 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17437 (set (match_scratch:P 2 "=&r") (const_int 0))
17438 (clobber (reg:CC FLAGS_REG))]
17439 ""
17440 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17441 [(set_attr "type" "multi")])
17442
17443 (define_insn "stack_tls_protect_set_<mode>"
17444 [(set (match_operand:P 0 "memory_operand" "=m")
17445 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17446 UNSPEC_SP_TLS_SET))
17447 (set (match_scratch:P 2 "=&r") (const_int 0))
17448 (clobber (reg:CC FLAGS_REG))]
17449 ""
17450 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17451 [(set_attr "type" "multi")])
17452
17453 (define_expand "stack_protect_test"
17454 [(match_operand 0 "memory_operand" "")
17455 (match_operand 1 "memory_operand" "")
17456 (match_operand 2 "" "")]
17457 ""
17458 {
17459 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17460
17461 rtx (*insn)(rtx, rtx, rtx);
17462
17463 #ifdef TARGET_THREAD_SSP_OFFSET
17464 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17465 insn = (TARGET_64BIT
17466 ? gen_stack_tls_protect_test_di
17467 : gen_stack_tls_protect_test_si);
17468 #else
17469 insn = (TARGET_64BIT
17470 ? gen_stack_protect_test_di
17471 : gen_stack_protect_test_si);
17472 #endif
17473
17474 emit_insn (insn (flags, operands[0], operands[1]));
17475
17476 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17477 flags, const0_rtx, operands[2]));
17478 DONE;
17479 })
17480
17481 (define_insn "stack_protect_test_<mode>"
17482 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17483 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17484 (match_operand:P 2 "memory_operand" "m")]
17485 UNSPEC_SP_TEST))
17486 (clobber (match_scratch:P 3 "=&r"))]
17487 ""
17488 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17489 [(set_attr "type" "multi")])
17490
17491 (define_insn "stack_tls_protect_test_<mode>"
17492 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17493 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17494 (match_operand:P 2 "const_int_operand" "i")]
17495 UNSPEC_SP_TLS_TEST))
17496 (clobber (match_scratch:P 3 "=r"))]
17497 ""
17498 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17499 [(set_attr "type" "multi")])
17500
17501 (define_insn "sse4_2_crc32<mode>"
17502 [(set (match_operand:SI 0 "register_operand" "=r")
17503 (unspec:SI
17504 [(match_operand:SI 1 "register_operand" "0")
17505 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17506 UNSPEC_CRC32))]
17507 "TARGET_SSE4_2 || TARGET_CRC32"
17508 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17509 [(set_attr "type" "sselog1")
17510 (set_attr "prefix_rep" "1")
17511 (set_attr "prefix_extra" "1")
17512 (set (attr "prefix_data16")
17513 (if_then_else (match_operand:HI 2 "" "")
17514 (const_string "1")
17515 (const_string "*")))
17516 (set (attr "prefix_rex")
17517 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17518 (const_string "1")
17519 (const_string "*")))
17520 (set_attr "mode" "SI")])
17521
17522 (define_insn "sse4_2_crc32di"
17523 [(set (match_operand:DI 0 "register_operand" "=r")
17524 (unspec:DI
17525 [(match_operand:DI 1 "register_operand" "0")
17526 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17527 UNSPEC_CRC32))]
17528 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17529 "crc32{q}\t{%2, %0|%0, %2}"
17530 [(set_attr "type" "sselog1")
17531 (set_attr "prefix_rep" "1")
17532 (set_attr "prefix_extra" "1")
17533 (set_attr "mode" "DI")])
17534
17535 (define_expand "rdpmc"
17536 [(match_operand:DI 0 "register_operand" "")
17537 (match_operand:SI 1 "register_operand" "")]
17538 ""
17539 {
17540 rtx reg = gen_reg_rtx (DImode);
17541 rtx si;
17542
17543 /* Force operand 1 into ECX. */
17544 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17545 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17546 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17547 UNSPECV_RDPMC);
17548
17549 if (TARGET_64BIT)
17550 {
17551 rtvec vec = rtvec_alloc (2);
17552 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17553 rtx upper = gen_reg_rtx (DImode);
17554 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17555 gen_rtvec (1, const0_rtx),
17556 UNSPECV_RDPMC);
17557 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17558 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17559 emit_insn (load);
17560 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17561 NULL, 1, OPTAB_DIRECT);
17562 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17563 OPTAB_DIRECT);
17564 }
17565 else
17566 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17567 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17568 DONE;
17569 })
17570
17571 (define_insn "*rdpmc"
17572 [(set (match_operand:DI 0 "register_operand" "=A")
17573 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17574 UNSPECV_RDPMC))]
17575 "!TARGET_64BIT"
17576 "rdpmc"
17577 [(set_attr "type" "other")
17578 (set_attr "length" "2")])
17579
17580 (define_insn "*rdpmc_rex64"
17581 [(set (match_operand:DI 0 "register_operand" "=a")
17582 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17583 UNSPECV_RDPMC))
17584 (set (match_operand:DI 1 "register_operand" "=d")
17585 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17586 "TARGET_64BIT"
17587 "rdpmc"
17588 [(set_attr "type" "other")
17589 (set_attr "length" "2")])
17590
17591 (define_expand "rdtsc"
17592 [(set (match_operand:DI 0 "register_operand" "")
17593 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17594 ""
17595 {
17596 if (TARGET_64BIT)
17597 {
17598 rtvec vec = rtvec_alloc (2);
17599 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17600 rtx upper = gen_reg_rtx (DImode);
17601 rtx lower = gen_reg_rtx (DImode);
17602 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17603 gen_rtvec (1, const0_rtx),
17604 UNSPECV_RDTSC);
17605 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17606 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17607 emit_insn (load);
17608 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17609 NULL, 1, OPTAB_DIRECT);
17610 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17611 OPTAB_DIRECT);
17612 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17613 DONE;
17614 }
17615 })
17616
17617 (define_insn "*rdtsc"
17618 [(set (match_operand:DI 0 "register_operand" "=A")
17619 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17620 "!TARGET_64BIT"
17621 "rdtsc"
17622 [(set_attr "type" "other")
17623 (set_attr "length" "2")])
17624
17625 (define_insn "*rdtsc_rex64"
17626 [(set (match_operand:DI 0 "register_operand" "=a")
17627 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17628 (set (match_operand:DI 1 "register_operand" "=d")
17629 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17630 "TARGET_64BIT"
17631 "rdtsc"
17632 [(set_attr "type" "other")
17633 (set_attr "length" "2")])
17634
17635 (define_expand "rdtscp"
17636 [(match_operand:DI 0 "register_operand" "")
17637 (match_operand:SI 1 "memory_operand" "")]
17638 ""
17639 {
17640 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17641 gen_rtvec (1, const0_rtx),
17642 UNSPECV_RDTSCP);
17643 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17644 gen_rtvec (1, const0_rtx),
17645 UNSPECV_RDTSCP);
17646 rtx reg = gen_reg_rtx (DImode);
17647 rtx tmp = gen_reg_rtx (SImode);
17648
17649 if (TARGET_64BIT)
17650 {
17651 rtvec vec = rtvec_alloc (3);
17652 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17653 rtx upper = gen_reg_rtx (DImode);
17654 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17655 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17656 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17657 emit_insn (load);
17658 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17659 NULL, 1, OPTAB_DIRECT);
17660 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17661 OPTAB_DIRECT);
17662 }
17663 else
17664 {
17665 rtvec vec = rtvec_alloc (2);
17666 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17667 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17668 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17669 emit_insn (load);
17670 }
17671 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17672 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17673 DONE;
17674 })
17675
17676 (define_insn "*rdtscp"
17677 [(set (match_operand:DI 0 "register_operand" "=A")
17678 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17679 (set (match_operand:SI 1 "register_operand" "=c")
17680 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17681 "!TARGET_64BIT"
17682 "rdtscp"
17683 [(set_attr "type" "other")
17684 (set_attr "length" "3")])
17685
17686 (define_insn "*rdtscp_rex64"
17687 [(set (match_operand:DI 0 "register_operand" "=a")
17688 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17689 (set (match_operand:DI 1 "register_operand" "=d")
17690 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17691 (set (match_operand:SI 2 "register_operand" "=c")
17692 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17693 "TARGET_64BIT"
17694 "rdtscp"
17695 [(set_attr "type" "other")
17696 (set_attr "length" "3")])
17697
17698 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17699 ;;
17700 ;; LWP instructions
17701 ;;
17702 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17703
17704 (define_expand "lwp_llwpcb"
17705 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17706 UNSPECV_LLWP_INTRINSIC)]
17707 "TARGET_LWP")
17708
17709 (define_insn "*lwp_llwpcb<mode>1"
17710 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17711 UNSPECV_LLWP_INTRINSIC)]
17712 "TARGET_LWP"
17713 "llwpcb\t%0"
17714 [(set_attr "type" "lwp")
17715 (set_attr "mode" "<MODE>")
17716 (set_attr "length" "5")])
17717
17718 (define_expand "lwp_slwpcb"
17719 [(set (match_operand 0 "register_operand" "=r")
17720 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17721 "TARGET_LWP"
17722 {
17723 rtx (*insn)(rtx);
17724
17725 insn = (TARGET_64BIT
17726 ? gen_lwp_slwpcbdi
17727 : gen_lwp_slwpcbsi);
17728
17729 emit_insn (insn (operands[0]));
17730 DONE;
17731 })
17732
17733 (define_insn "lwp_slwpcb<mode>"
17734 [(set (match_operand:P 0 "register_operand" "=r")
17735 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17736 "TARGET_LWP"
17737 "slwpcb\t%0"
17738 [(set_attr "type" "lwp")
17739 (set_attr "mode" "<MODE>")
17740 (set_attr "length" "5")])
17741
17742 (define_expand "lwp_lwpval<mode>3"
17743 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17744 (match_operand:SI 2 "nonimmediate_operand" "rm")
17745 (match_operand:SI 3 "const_int_operand" "i")]
17746 UNSPECV_LWPVAL_INTRINSIC)]
17747 "TARGET_LWP"
17748 "/* Avoid unused variable warning. */
17749 (void) operand0;")
17750
17751 (define_insn "*lwp_lwpval<mode>3_1"
17752 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17753 (match_operand:SI 1 "nonimmediate_operand" "rm")
17754 (match_operand:SI 2 "const_int_operand" "i")]
17755 UNSPECV_LWPVAL_INTRINSIC)]
17756 "TARGET_LWP"
17757 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17758 [(set_attr "type" "lwp")
17759 (set_attr "mode" "<MODE>")
17760 (set (attr "length")
17761 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17762
17763 (define_expand "lwp_lwpins<mode>3"
17764 [(set (reg:CCC FLAGS_REG)
17765 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17766 (match_operand:SI 2 "nonimmediate_operand" "rm")
17767 (match_operand:SI 3 "const_int_operand" "i")]
17768 UNSPECV_LWPINS_INTRINSIC))
17769 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17770 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17771 "TARGET_LWP")
17772
17773 (define_insn "*lwp_lwpins<mode>3_1"
17774 [(set (reg:CCC FLAGS_REG)
17775 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17776 (match_operand:SI 1 "nonimmediate_operand" "rm")
17777 (match_operand:SI 2 "const_int_operand" "i")]
17778 UNSPECV_LWPINS_INTRINSIC))]
17779 "TARGET_LWP"
17780 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17781 [(set_attr "type" "lwp")
17782 (set_attr "mode" "<MODE>")
17783 (set (attr "length")
17784 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17785
17786 (define_insn "rdfsbase<mode>"
17787 [(set (match_operand:SWI48 0 "register_operand" "=r")
17788 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17789 "TARGET_64BIT && TARGET_FSGSBASE"
17790 "rdfsbase %0"
17791 [(set_attr "type" "other")
17792 (set_attr "prefix_extra" "2")])
17793
17794 (define_insn "rdgsbase<mode>"
17795 [(set (match_operand:SWI48 0 "register_operand" "=r")
17796 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17797 "TARGET_64BIT && TARGET_FSGSBASE"
17798 "rdgsbase %0"
17799 [(set_attr "type" "other")
17800 (set_attr "prefix_extra" "2")])
17801
17802 (define_insn "wrfsbase<mode>"
17803 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17804 UNSPECV_WRFSBASE)]
17805 "TARGET_64BIT && TARGET_FSGSBASE"
17806 "wrfsbase %0"
17807 [(set_attr "type" "other")
17808 (set_attr "prefix_extra" "2")])
17809
17810 (define_insn "wrgsbase<mode>"
17811 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17812 UNSPECV_WRGSBASE)]
17813 "TARGET_64BIT && TARGET_FSGSBASE"
17814 "wrgsbase %0"
17815 [(set_attr "type" "other")
17816 (set_attr "prefix_extra" "2")])
17817
17818 (define_insn "rdrand<mode>_1"
17819 [(set (match_operand:SWI248 0 "register_operand" "=r")
17820 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17821 (set (reg:CCC FLAGS_REG)
17822 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17823 "TARGET_RDRND"
17824 "rdrand\t%0"
17825 [(set_attr "type" "other")
17826 (set_attr "prefix_extra" "1")])
17827
17828 (define_expand "pause"
17829 [(set (match_dup 0)
17830 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17831 ""
17832 {
17833 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17834 MEM_VOLATILE_P (operands[0]) = 1;
17835 })
17836
17837 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17838 ;; They have the same encoding.
17839 (define_insn "*pause"
17840 [(set (match_operand:BLK 0 "" "")
17841 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17842 ""
17843 "rep; nop"
17844 [(set_attr "length" "2")
17845 (set_attr "memory" "unknown")])
17846
17847 (include "mmx.md")
17848 (include "sse.md")
17849 (include "sync.md")