5ff66ccf1e59e25a7765558cdc217ec5c9f5065c
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
21 ;;
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24 ;;
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;; otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;; delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
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 "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
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_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_STACK_CHECK
89
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
95 UNSPEC_TLS_IE_SUN
96
97 ;; Other random patterns
98 UNSPEC_SCAS
99 UNSPEC_FNSTSW
100 UNSPEC_SAHF
101 UNSPEC_PARITY
102 UNSPEC_FSTCW
103 UNSPEC_ADD_CARRY
104 UNSPEC_FLDCW
105 UNSPEC_REP
106 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_TRUNC_NOOP
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
110 UNSPEC_PAUSE
111 UNSPEC_LEA_ADDR
112 UNSPEC_XBEGIN_ABORT
113 UNSPEC_STOS
114
115 ;; For SSE/MMX support:
116 UNSPEC_FIX_NOTRUNC
117 UNSPEC_MASKMOV
118 UNSPEC_MOVMSK
119 UNSPEC_RCP
120 UNSPEC_RSQRT
121 UNSPEC_PSADBW
122
123 ;; Generic math support
124 UNSPEC_COPYSIGN
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
127
128 ;; x87 Floating point
129 UNSPEC_SIN
130 UNSPEC_COS
131 UNSPEC_FPATAN
132 UNSPEC_FYL2X
133 UNSPEC_FYL2XP1
134 UNSPEC_FRNDINT
135 UNSPEC_FIST
136 UNSPEC_F2XM1
137 UNSPEC_TAN
138 UNSPEC_FXAM
139
140 ;; x87 Rounding
141 UNSPEC_FRNDINT_FLOOR
142 UNSPEC_FRNDINT_CEIL
143 UNSPEC_FRNDINT_TRUNC
144 UNSPEC_FRNDINT_MASK_PM
145 UNSPEC_FIST_FLOOR
146 UNSPEC_FIST_CEIL
147
148 ;; x87 Double output FP
149 UNSPEC_SINCOS_COS
150 UNSPEC_SINCOS_SIN
151 UNSPEC_XTRACT_FRACT
152 UNSPEC_XTRACT_EXP
153 UNSPEC_FSCALE_FRACT
154 UNSPEC_FSCALE_EXP
155 UNSPEC_FPREM_F
156 UNSPEC_FPREM_U
157 UNSPEC_FPREM1_F
158 UNSPEC_FPREM1_U
159
160 UNSPEC_C2_FLAG
161 UNSPEC_FXAM_MEM
162
163 ;; SSP patterns
164 UNSPEC_SP_SET
165 UNSPEC_SP_TEST
166 UNSPEC_SP_TLS_SET
167 UNSPEC_SP_TLS_TEST
168
169 ;; For ROUND support
170 UNSPEC_ROUND
171
172 ;; For CRC32 support
173 UNSPEC_CRC32
174
175 ;; For BMI support
176 UNSPEC_BEXTR
177
178 ;; For BMI2 support
179 UNSPEC_PDEP
180 UNSPEC_PEXT
181 ])
182
183 (define_c_enum "unspecv" [
184 UNSPECV_BLOCKAGE
185 UNSPECV_STACK_PROBE
186 UNSPECV_PROBE_STACK_RANGE
187 UNSPECV_ALIGN
188 UNSPECV_PROLOGUE_USE
189 UNSPECV_SPLIT_STACK_RETURN
190 UNSPECV_CLD
191 UNSPECV_NOPS
192 UNSPECV_RDTSC
193 UNSPECV_RDTSCP
194 UNSPECV_RDPMC
195 UNSPECV_LLWP_INTRINSIC
196 UNSPECV_SLWP_INTRINSIC
197 UNSPECV_LWPVAL_INTRINSIC
198 UNSPECV_LWPINS_INTRINSIC
199 UNSPECV_RDFSBASE
200 UNSPECV_RDGSBASE
201 UNSPECV_WRFSBASE
202 UNSPECV_WRGSBASE
203 UNSPECV_FXSAVE
204 UNSPECV_FXRSTOR
205 UNSPECV_FXSAVE64
206 UNSPECV_FXRSTOR64
207 UNSPECV_XSAVE
208 UNSPECV_XRSTOR
209 UNSPECV_XSAVE64
210 UNSPECV_XRSTOR64
211 UNSPECV_XSAVEOPT
212 UNSPECV_XSAVEOPT64
213
214 ;; For atomic compound assignments.
215 UNSPECV_FNSTENV
216 UNSPECV_FLDENV
217 UNSPECV_FNSTSW
218 UNSPECV_FNCLEX
219
220 ;; For RDRAND support
221 UNSPECV_RDRAND
222
223 ;; For RDSEED support
224 UNSPECV_RDSEED
225
226 ;; For RTM support
227 UNSPECV_XBEGIN
228 UNSPECV_XEND
229 UNSPECV_XABORT
230 UNSPECV_XTEST
231
232 UNSPECV_NLGR
233 ])
234
235 ;; Constants to represent rounding modes in the ROUND instruction
236 (define_constants
237 [(ROUND_FLOOR 0x1)
238 (ROUND_CEIL 0x2)
239 (ROUND_TRUNC 0x3)
240 (ROUND_MXCSR 0x4)
241 (ROUND_NO_EXC 0x8)
242 ])
243
244 ;; Constants to represent pcomtrue/pcomfalse variants
245 (define_constants
246 [(PCOM_FALSE 0)
247 (PCOM_TRUE 1)
248 (COM_FALSE_S 2)
249 (COM_FALSE_P 3)
250 (COM_TRUE_S 4)
251 (COM_TRUE_P 5)
252 ])
253
254 ;; Constants used in the XOP pperm instruction
255 (define_constants
256 [(PPERM_SRC 0x00) /* copy source */
257 (PPERM_INVERT 0x20) /* invert source */
258 (PPERM_REVERSE 0x40) /* bit reverse source */
259 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
260 (PPERM_ZERO 0x80) /* all 0's */
261 (PPERM_ONES 0xa0) /* all 1's */
262 (PPERM_SIGN 0xc0) /* propagate sign bit */
263 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
264 (PPERM_SRC1 0x00) /* use first source byte */
265 (PPERM_SRC2 0x10) /* use second source byte */
266 ])
267
268 ;; Registers by name.
269 (define_constants
270 [(AX_REG 0)
271 (DX_REG 1)
272 (CX_REG 2)
273 (BX_REG 3)
274 (SI_REG 4)
275 (DI_REG 5)
276 (BP_REG 6)
277 (SP_REG 7)
278 (ST0_REG 8)
279 (ST1_REG 9)
280 (ST2_REG 10)
281 (ST3_REG 11)
282 (ST4_REG 12)
283 (ST5_REG 13)
284 (ST6_REG 14)
285 (ST7_REG 15)
286 (FLAGS_REG 17)
287 (FPSR_REG 18)
288 (FPCR_REG 19)
289 (XMM0_REG 21)
290 (XMM1_REG 22)
291 (XMM2_REG 23)
292 (XMM3_REG 24)
293 (XMM4_REG 25)
294 (XMM5_REG 26)
295 (XMM6_REG 27)
296 (XMM7_REG 28)
297 (MM0_REG 29)
298 (MM1_REG 30)
299 (MM2_REG 31)
300 (MM3_REG 32)
301 (MM4_REG 33)
302 (MM5_REG 34)
303 (MM6_REG 35)
304 (MM7_REG 36)
305 (R8_REG 37)
306 (R9_REG 38)
307 (R10_REG 39)
308 (R11_REG 40)
309 (R12_REG 41)
310 (R13_REG 42)
311 (R14_REG 43)
312 (R15_REG 44)
313 (XMM8_REG 45)
314 (XMM9_REG 46)
315 (XMM10_REG 47)
316 (XMM11_REG 48)
317 (XMM12_REG 49)
318 (XMM13_REG 50)
319 (XMM14_REG 51)
320 (XMM15_REG 52)
321 (XMM16_REG 53)
322 (XMM17_REG 54)
323 (XMM18_REG 55)
324 (XMM19_REG 56)
325 (XMM20_REG 57)
326 (XMM21_REG 58)
327 (XMM22_REG 59)
328 (XMM23_REG 60)
329 (XMM24_REG 61)
330 (XMM25_REG 62)
331 (XMM26_REG 63)
332 (XMM27_REG 64)
333 (XMM28_REG 65)
334 (XMM29_REG 66)
335 (XMM30_REG 67)
336 (XMM31_REG 68)
337 (MASK0_REG 69)
338 (MASK1_REG 70)
339 (MASK2_REG 71)
340 (MASK3_REG 72)
341 (MASK4_REG 73)
342 (MASK5_REG 74)
343 (MASK6_REG 75)
344 (MASK7_REG 76)
345 ])
346
347 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
348 ;; from i386.c.
349
350 ;; In C guard expressions, put expressions which may be compile-time
351 ;; constants first. This allows for better optimization. For
352 ;; example, write "TARGET_64BIT && reload_completed", not
353 ;; "reload_completed && TARGET_64BIT".
354
355 \f
356 ;; Processor type.
357 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
358 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
359 btver1,btver2"
360 (const (symbol_ref "ix86_schedule")))
361
362 ;; A basic instruction type. Refinements due to arguments to be
363 ;; provided in other attributes.
364 (define_attr "type"
365 "other,multi,
366 alu,alu1,negnot,imov,imovx,lea,
367 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
368 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
369 push,pop,call,callv,leave,
370 str,bitmanip,
371 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
372 fxch,fistp,fisttp,frndint,
373 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
374 ssemul,sseimul,ssediv,sselog,sselog1,
375 sseishft,sseishft1,ssecmp,ssecomi,
376 ssecvt,ssecvt1,sseicvt,sseins,
377 sseshuf,sseshuf1,ssemuladd,sse4arg,
378 lwp,mskmov,msklog,
379 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
380 (const_string "other"))
381
382 ;; Main data type used by the insn
383 (define_attr "mode"
384 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
385 V2DF,V2SF,V1DF,V8DF"
386 (const_string "unknown"))
387
388 ;; The CPU unit operations uses.
389 (define_attr "unit" "integer,i387,sse,mmx,unknown"
390 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
391 fxch,fistp,fisttp,frndint")
392 (const_string "i387")
393 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
394 ssemul,sseimul,ssediv,sselog,sselog1,
395 sseishft,sseishft1,ssecmp,ssecomi,
396 ssecvt,ssecvt1,sseicvt,sseins,
397 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
398 (const_string "sse")
399 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
400 (const_string "mmx")
401 (eq_attr "type" "other")
402 (const_string "unknown")]
403 (const_string "integer")))
404
405 ;; The minimum required alignment of vector mode memory operands of the SSE
406 ;; (non-VEX/EVEX) instruction in bits, if it is different from
407 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
408 ;; multiple alternatives, this should be conservative maximum of those minimum
409 ;; required alignments.
410 (define_attr "ssememalign" "" (const_int 0))
411
412 ;; The (bounding maximum) length of an instruction immediate.
413 (define_attr "length_immediate" ""
414 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415 bitmanip,imulx,msklog,mskmov")
416 (const_int 0)
417 (eq_attr "unit" "i387,sse,mmx")
418 (const_int 0)
419 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
420 rotate,rotatex,rotate1,imul,icmp,push,pop")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
422 (eq_attr "type" "imov,test")
423 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
424 (eq_attr "type" "call")
425 (if_then_else (match_operand 0 "constant_call_address_operand")
426 (const_int 4)
427 (const_int 0))
428 (eq_attr "type" "callv")
429 (if_then_else (match_operand 1 "constant_call_address_operand")
430 (const_int 4)
431 (const_int 0))
432 ;; We don't know the size before shorten_branches. Expect
433 ;; the instruction to fit for better scheduling.
434 (eq_attr "type" "ibr")
435 (const_int 1)
436 ]
437 (symbol_ref "/* Update immediate_length and other attributes! */
438 gcc_unreachable (),1")))
439
440 ;; The (bounding maximum) length of an instruction address.
441 (define_attr "length_address" ""
442 (cond [(eq_attr "type" "str,other,multi,fxch")
443 (const_int 0)
444 (and (eq_attr "type" "call")
445 (match_operand 0 "constant_call_address_operand"))
446 (const_int 0)
447 (and (eq_attr "type" "callv")
448 (match_operand 1 "constant_call_address_operand"))
449 (const_int 0)
450 ]
451 (symbol_ref "ix86_attr_length_address_default (insn)")))
452
453 ;; Set when length prefix is used.
454 (define_attr "prefix_data16" ""
455 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
456 (const_int 0)
457 (eq_attr "mode" "HI")
458 (const_int 1)
459 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
460 (const_int 1)
461 ]
462 (const_int 0)))
463
464 ;; Set when string REP prefix is used.
465 (define_attr "prefix_rep" ""
466 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
467 (const_int 0)
468 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
469 (const_int 1)
470 ]
471 (const_int 0)))
472
473 ;; Set when 0f opcode prefix is used.
474 (define_attr "prefix_0f" ""
475 (if_then_else
476 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
477 (eq_attr "unit" "sse,mmx"))
478 (const_int 1)
479 (const_int 0)))
480
481 ;; Set when REX opcode prefix is used.
482 (define_attr "prefix_rex" ""
483 (cond [(not (match_test "TARGET_64BIT"))
484 (const_int 0)
485 (and (eq_attr "mode" "DI")
486 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
487 (eq_attr "unit" "!mmx")))
488 (const_int 1)
489 (and (eq_attr "mode" "QI")
490 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
491 (const_int 1)
492 (match_test "x86_extended_reg_mentioned_p (insn)")
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,evex,maybe_evex"
514 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
515 (const_string "vex")
516 (eq_attr "mode" "XI,V16SF,V8DF")
517 (const_string "evex")
518 ]
519 (const_string "orig")))
520
521 ;; VEX W bit is used.
522 (define_attr "prefix_vex_w" "" (const_int 0))
523
524 ;; The length of VEX prefix
525 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
526 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
527 ;; still prefix_0f 1, with prefix_extra 1.
528 (define_attr "length_vex" ""
529 (if_then_else (and (eq_attr "prefix_0f" "1")
530 (eq_attr "prefix_extra" "0"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
534 (if_then_else (eq_attr "prefix_vex_w" "1")
535 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
536 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
537
538 ;; 4-bytes evex prefix and 1 byte opcode.
539 (define_attr "length_evex" "" (const_int 5))
540
541 ;; Set when modrm byte is used.
542 (define_attr "modrm" ""
543 (cond [(eq_attr "type" "str,leave")
544 (const_int 0)
545 (eq_attr "unit" "i387")
546 (const_int 0)
547 (and (eq_attr "type" "incdec")
548 (and (not (match_test "TARGET_64BIT"))
549 (ior (match_operand:SI 1 "register_operand")
550 (match_operand:HI 1 "register_operand"))))
551 (const_int 0)
552 (and (eq_attr "type" "push")
553 (not (match_operand 1 "memory_operand")))
554 (const_int 0)
555 (and (eq_attr "type" "pop")
556 (not (match_operand 0 "memory_operand")))
557 (const_int 0)
558 (and (eq_attr "type" "imov")
559 (and (not (eq_attr "mode" "DI"))
560 (ior (and (match_operand 0 "register_operand")
561 (match_operand 1 "immediate_operand"))
562 (ior (and (match_operand 0 "ax_reg_operand")
563 (match_operand 1 "memory_displacement_only_operand"))
564 (and (match_operand 0 "memory_displacement_only_operand")
565 (match_operand 1 "ax_reg_operand"))))))
566 (const_int 0)
567 (and (eq_attr "type" "call")
568 (match_operand 0 "constant_call_address_operand"))
569 (const_int 0)
570 (and (eq_attr "type" "callv")
571 (match_operand 1 "constant_call_address_operand"))
572 (const_int 0)
573 (and (eq_attr "type" "alu,alu1,icmp,test")
574 (match_operand 0 "ax_reg_operand"))
575 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
576 ]
577 (const_int 1)))
578
579 ;; The (bounding maximum) length of an instruction in bytes.
580 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
581 ;; Later we may want to split them and compute proper length as for
582 ;; other insns.
583 (define_attr "length" ""
584 (cond [(eq_attr "type" "other,multi,fistp,frndint")
585 (const_int 16)
586 (eq_attr "type" "fcmp")
587 (const_int 4)
588 (eq_attr "unit" "i387")
589 (plus (const_int 2)
590 (plus (attr "prefix_data16")
591 (attr "length_address")))
592 (ior (eq_attr "prefix" "evex")
593 (and (ior (eq_attr "prefix" "maybe_evex")
594 (eq_attr "prefix" "maybe_vex"))
595 (match_test "TARGET_AVX512F")))
596 (plus (attr "length_evex")
597 (plus (attr "length_immediate")
598 (plus (attr "modrm")
599 (attr "length_address"))))
600 (ior (eq_attr "prefix" "vex")
601 (and (ior (eq_attr "prefix" "maybe_vex")
602 (eq_attr "prefix" "maybe_evex"))
603 (match_test "TARGET_AVX")))
604 (plus (attr "length_vex")
605 (plus (attr "length_immediate")
606 (plus (attr "modrm")
607 (attr "length_address"))))]
608 (plus (plus (attr "modrm")
609 (plus (attr "prefix_0f")
610 (plus (attr "prefix_rex")
611 (plus (attr "prefix_extra")
612 (const_int 1)))))
613 (plus (attr "prefix_rep")
614 (plus (attr "prefix_data16")
615 (plus (attr "length_immediate")
616 (attr "length_address")))))))
617
618 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
619 ;; `store' if there is a simple memory reference therein, or `unknown'
620 ;; if the instruction is complex.
621
622 (define_attr "memory" "none,load,store,both,unknown"
623 (cond [(eq_attr "type" "other,multi,str,lwp")
624 (const_string "unknown")
625 (eq_attr "type" "lea,fcmov,fpspc")
626 (const_string "none")
627 (eq_attr "type" "fistp,leave")
628 (const_string "both")
629 (eq_attr "type" "frndint")
630 (const_string "load")
631 (eq_attr "type" "push")
632 (if_then_else (match_operand 1 "memory_operand")
633 (const_string "both")
634 (const_string "store"))
635 (eq_attr "type" "pop")
636 (if_then_else (match_operand 0 "memory_operand")
637 (const_string "both")
638 (const_string "load"))
639 (eq_attr "type" "setcc")
640 (if_then_else (match_operand 0 "memory_operand")
641 (const_string "store")
642 (const_string "none"))
643 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
644 (if_then_else (ior (match_operand 0 "memory_operand")
645 (match_operand 1 "memory_operand"))
646 (const_string "load")
647 (const_string "none"))
648 (eq_attr "type" "ibr")
649 (if_then_else (match_operand 0 "memory_operand")
650 (const_string "load")
651 (const_string "none"))
652 (eq_attr "type" "call")
653 (if_then_else (match_operand 0 "constant_call_address_operand")
654 (const_string "none")
655 (const_string "load"))
656 (eq_attr "type" "callv")
657 (if_then_else (match_operand 1 "constant_call_address_operand")
658 (const_string "none")
659 (const_string "load"))
660 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
661 (match_operand 1 "memory_operand"))
662 (const_string "both")
663 (and (match_operand 0 "memory_operand")
664 (match_operand 1 "memory_operand"))
665 (const_string "both")
666 (match_operand 0 "memory_operand")
667 (const_string "store")
668 (match_operand 1 "memory_operand")
669 (const_string "load")
670 (and (eq_attr "type"
671 "!alu1,negnot,ishift1,
672 imov,imovx,icmp,test,bitmanip,
673 fmov,fcmp,fsgn,
674 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
675 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
676 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
677 (match_operand 2 "memory_operand"))
678 (const_string "load")
679 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
680 (match_operand 3 "memory_operand"))
681 (const_string "load")
682 ]
683 (const_string "none")))
684
685 ;; Indicates if an instruction has both an immediate and a displacement.
686
687 (define_attr "imm_disp" "false,true,unknown"
688 (cond [(eq_attr "type" "other,multi")
689 (const_string "unknown")
690 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
691 (and (match_operand 0 "memory_displacement_operand")
692 (match_operand 1 "immediate_operand")))
693 (const_string "true")
694 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
695 (and (match_operand 0 "memory_displacement_operand")
696 (match_operand 2 "immediate_operand")))
697 (const_string "true")
698 ]
699 (const_string "false")))
700
701 ;; Indicates if an FP operation has an integer source.
702
703 (define_attr "fp_int_src" "false,true"
704 (const_string "false"))
705
706 ;; Defines rounding mode of an FP operation.
707
708 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
709 (const_string "any"))
710
711 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
712 (define_attr "use_carry" "0,1" (const_string "0"))
713
714 ;; Define attribute to indicate unaligned ssemov insns
715 (define_attr "movu" "0,1" (const_string "0"))
716
717 ;; Used to control the "enabled" attribute on a per-instruction basis.
718 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
719 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
720 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
721 (const_string "base"))
722
723 (define_attr "enabled" ""
724 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
725 (eq_attr "isa" "x64_sse4")
726 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
727 (eq_attr "isa" "x64_sse4_noavx")
728 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
729 (eq_attr "isa" "x64_avx")
730 (symbol_ref "TARGET_64BIT && TARGET_AVX")
731 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
732 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
733 (eq_attr "isa" "sse2_noavx")
734 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
735 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
736 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
737 (eq_attr "isa" "sse4_noavx")
738 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
739 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
740 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
741 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
742 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
743 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
744 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
745 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
746 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
747 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
748 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
749 (eq_attr "isa" "fma_avx512f")
750 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
751 ]
752 (const_int 1)))
753
754 ;; Describe a user's asm statement.
755 (define_asm_attributes
756 [(set_attr "length" "128")
757 (set_attr "type" "multi")])
758
759 (define_code_iterator plusminus [plus minus])
760
761 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
762
763 (define_code_iterator multdiv [mult div])
764
765 ;; Base name for define_insn
766 (define_code_attr plusminus_insn
767 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
768 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
769
770 ;; Base name for insn mnemonic.
771 (define_code_attr plusminus_mnemonic
772 [(plus "add") (ss_plus "adds") (us_plus "addus")
773 (minus "sub") (ss_minus "subs") (us_minus "subus")])
774 (define_code_attr plusminus_carry_mnemonic
775 [(plus "adc") (minus "sbb")])
776 (define_code_attr multdiv_mnemonic
777 [(mult "mul") (div "div")])
778
779 ;; Mark commutative operators as such in constraints.
780 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
781 (minus "") (ss_minus "") (us_minus "")])
782
783 ;; Mapping of max and min
784 (define_code_iterator maxmin [smax smin umax umin])
785
786 ;; Mapping of signed max and min
787 (define_code_iterator smaxmin [smax smin])
788
789 ;; Mapping of unsigned max and min
790 (define_code_iterator umaxmin [umax umin])
791
792 ;; Base name for integer and FP insn mnemonic
793 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
794 (umax "maxu") (umin "minu")])
795 (define_code_attr maxmin_float [(smax "max") (smin "min")])
796
797 ;; Mapping of logic operators
798 (define_code_iterator any_logic [and ior xor])
799 (define_code_iterator any_or [ior xor])
800 (define_code_iterator fpint_logic [and xor])
801
802 ;; Base name for insn mnemonic.
803 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
804
805 ;; Mapping of logic-shift operators
806 (define_code_iterator any_lshift [ashift lshiftrt])
807
808 ;; Mapping of shift-right operators
809 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
810
811 ;; Mapping of all shift operators
812 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
813
814 ;; Base name for define_insn
815 (define_code_attr shift_insn
816 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
817
818 ;; Base name for insn mnemonic.
819 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
820 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
821
822 ;; Mapping of rotate operators
823 (define_code_iterator any_rotate [rotate rotatert])
824
825 ;; Base name for define_insn
826 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
827
828 ;; Base name for insn mnemonic.
829 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
830
831 ;; Mapping of abs neg operators
832 (define_code_iterator absneg [abs neg])
833
834 ;; Base name for x87 insn mnemonic.
835 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
836
837 ;; Used in signed and unsigned widening multiplications.
838 (define_code_iterator any_extend [sign_extend zero_extend])
839
840 ;; Prefix for insn menmonic.
841 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
842
843 ;; Prefix for define_insn
844 (define_code_attr u [(sign_extend "") (zero_extend "u")])
845 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
846 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
847
848 ;; Used in signed and unsigned truncations.
849 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
850 ;; Instruction suffix for truncations.
851 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
852
853 ;; Used in signed and unsigned fix.
854 (define_code_iterator any_fix [fix unsigned_fix])
855 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
856
857 ;; All integer modes.
858 (define_mode_iterator SWI1248x [QI HI SI DI])
859
860 ;; All integer modes without QImode.
861 (define_mode_iterator SWI248x [HI SI DI])
862
863 ;; All integer modes without QImode and HImode.
864 (define_mode_iterator SWI48x [SI DI])
865
866 ;; All integer modes without SImode and DImode.
867 (define_mode_iterator SWI12 [QI HI])
868
869 ;; All integer modes without DImode.
870 (define_mode_iterator SWI124 [QI HI SI])
871
872 ;; All integer modes without QImode and DImode.
873 (define_mode_iterator SWI24 [HI SI])
874
875 ;; Single word integer modes.
876 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
877
878 ;; Single word integer modes without QImode.
879 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
880
881 ;; Single word integer modes without QImode and HImode.
882 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
883
884 ;; All math-dependant single and double word integer modes.
885 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
886 (HI "TARGET_HIMODE_MATH")
887 SI DI (TI "TARGET_64BIT")])
888
889 ;; Math-dependant single word integer modes.
890 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
891 (HI "TARGET_HIMODE_MATH")
892 SI (DI "TARGET_64BIT")])
893
894 ;; Math-dependant integer modes without DImode.
895 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
896 (HI "TARGET_HIMODE_MATH")
897 SI])
898
899 ;; Math-dependant single word integer modes without QImode.
900 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
901 SI (DI "TARGET_64BIT")])
902
903 ;; Double word integer modes.
904 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
905 (TI "TARGET_64BIT")])
906
907 ;; Double word integer modes as mode attribute.
908 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
909 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
910
911 ;; Half mode for double word integer modes.
912 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
913 (DI "TARGET_64BIT")])
914
915 ;; Instruction suffix for integer modes.
916 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
917
918 ;; Pointer size prefix for integer modes (Intel asm dialect)
919 (define_mode_attr iptrsize [(QI "BYTE")
920 (HI "WORD")
921 (SI "DWORD")
922 (DI "QWORD")])
923
924 ;; Register class for integer modes.
925 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
926
927 ;; Immediate operand constraint for integer modes.
928 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
929
930 ;; General operand constraint for word modes.
931 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
932
933 ;; Immediate operand constraint for double integer modes.
934 (define_mode_attr di [(SI "nF") (DI "e")])
935
936 ;; Immediate operand constraint for shifts.
937 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
938
939 ;; General operand predicate for integer modes.
940 (define_mode_attr general_operand
941 [(QI "general_operand")
942 (HI "general_operand")
943 (SI "x86_64_general_operand")
944 (DI "x86_64_general_operand")
945 (TI "x86_64_general_operand")])
946
947 ;; General sign/zero extend operand predicate for integer modes.
948 (define_mode_attr general_szext_operand
949 [(QI "general_operand")
950 (HI "general_operand")
951 (SI "x86_64_szext_general_operand")
952 (DI "x86_64_szext_general_operand")])
953
954 ;; Immediate operand predicate for integer modes.
955 (define_mode_attr immediate_operand
956 [(QI "immediate_operand")
957 (HI "immediate_operand")
958 (SI "x86_64_immediate_operand")
959 (DI "x86_64_immediate_operand")])
960
961 ;; Nonmemory operand predicate for integer modes.
962 (define_mode_attr nonmemory_operand
963 [(QI "nonmemory_operand")
964 (HI "nonmemory_operand")
965 (SI "x86_64_nonmemory_operand")
966 (DI "x86_64_nonmemory_operand")])
967
968 ;; Operand predicate for shifts.
969 (define_mode_attr shift_operand
970 [(QI "nonimmediate_operand")
971 (HI "nonimmediate_operand")
972 (SI "nonimmediate_operand")
973 (DI "shiftdi_operand")
974 (TI "register_operand")])
975
976 ;; Operand predicate for shift argument.
977 (define_mode_attr shift_immediate_operand
978 [(QI "const_1_to_31_operand")
979 (HI "const_1_to_31_operand")
980 (SI "const_1_to_31_operand")
981 (DI "const_1_to_63_operand")])
982
983 ;; Input operand predicate for arithmetic left shifts.
984 (define_mode_attr ashl_input_operand
985 [(QI "nonimmediate_operand")
986 (HI "nonimmediate_operand")
987 (SI "nonimmediate_operand")
988 (DI "ashldi_input_operand")
989 (TI "reg_or_pm1_operand")])
990
991 ;; SSE and x87 SFmode and DFmode floating point modes
992 (define_mode_iterator MODEF [SF DF])
993
994 ;; All x87 floating point modes
995 (define_mode_iterator X87MODEF [SF DF XF])
996
997 ;; SSE instruction suffix for various modes
998 (define_mode_attr ssemodesuffix
999 [(SF "ss") (DF "sd")
1000 (V16SF "ps") (V8DF "pd")
1001 (V8SF "ps") (V4DF "pd")
1002 (V4SF "ps") (V2DF "pd")
1003 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1004 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1005 (V64QI "b") (V16SI "d") (V8DI "q")])
1006
1007 ;; SSE vector suffix for floating point modes
1008 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1009
1010 ;; SSE vector mode corresponding to a scalar mode
1011 (define_mode_attr ssevecmode
1012 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1013 (define_mode_attr ssevecmodelower
1014 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1015
1016 ;; Instruction suffix for REX 64bit operators.
1017 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1018
1019 ;; This mode iterator allows :P to be used for patterns that operate on
1020 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1021 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1022
1023 ;; This mode iterator allows :W to be used for patterns that operate on
1024 ;; word_mode sized quantities.
1025 (define_mode_iterator W
1026 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1027
1028 ;; This mode iterator allows :PTR to be used for patterns that operate on
1029 ;; ptr_mode sized quantities.
1030 (define_mode_iterator PTR
1031 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1032 \f
1033 ;; Scheduling descriptions
1034
1035 (include "pentium.md")
1036 (include "ppro.md")
1037 (include "k6.md")
1038 (include "athlon.md")
1039 (include "bdver1.md")
1040 (include "bdver3.md")
1041 (include "btver2.md")
1042 (include "geode.md")
1043 (include "atom.md")
1044 (include "slm.md")
1045 (include "core2.md")
1046
1047 \f
1048 ;; Operand and operator predicates and constraints
1049
1050 (include "predicates.md")
1051 (include "constraints.md")
1052
1053 \f
1054 ;; Compare and branch/compare and store instructions.
1055
1056 (define_expand "cbranch<mode>4"
1057 [(set (reg:CC FLAGS_REG)
1058 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1059 (match_operand:SDWIM 2 "<general_operand>")))
1060 (set (pc) (if_then_else
1061 (match_operator 0 "ordered_comparison_operator"
1062 [(reg:CC FLAGS_REG) (const_int 0)])
1063 (label_ref (match_operand 3))
1064 (pc)))]
1065 ""
1066 {
1067 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1068 operands[1] = force_reg (<MODE>mode, operands[1]);
1069 ix86_expand_branch (GET_CODE (operands[0]),
1070 operands[1], operands[2], operands[3]);
1071 DONE;
1072 })
1073
1074 (define_expand "cstore<mode>4"
1075 [(set (reg:CC FLAGS_REG)
1076 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1077 (match_operand:SWIM 3 "<general_operand>")))
1078 (set (match_operand:QI 0 "register_operand")
1079 (match_operator 1 "ordered_comparison_operator"
1080 [(reg:CC FLAGS_REG) (const_int 0)]))]
1081 ""
1082 {
1083 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1084 operands[2] = force_reg (<MODE>mode, operands[2]);
1085 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1086 operands[2], operands[3]);
1087 DONE;
1088 })
1089
1090 (define_expand "cmp<mode>_1"
1091 [(set (reg:CC FLAGS_REG)
1092 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1093 (match_operand:SWI48 1 "<general_operand>")))])
1094
1095 (define_insn "*cmp<mode>_ccno_1"
1096 [(set (reg FLAGS_REG)
1097 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1098 (match_operand:SWI 1 "const0_operand")))]
1099 "ix86_match_ccmode (insn, CCNOmode)"
1100 "@
1101 test{<imodesuffix>}\t%0, %0
1102 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1103 [(set_attr "type" "test,icmp")
1104 (set_attr "length_immediate" "0,1")
1105 (set_attr "mode" "<MODE>")])
1106
1107 (define_insn "*cmp<mode>_1"
1108 [(set (reg FLAGS_REG)
1109 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1110 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1111 "ix86_match_ccmode (insn, CCmode)"
1112 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1113 [(set_attr "type" "icmp")
1114 (set_attr "mode" "<MODE>")])
1115
1116 (define_insn "*cmp<mode>_minus_1"
1117 [(set (reg FLAGS_REG)
1118 (compare
1119 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1120 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1121 (const_int 0)))]
1122 "ix86_match_ccmode (insn, CCGOCmode)"
1123 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1124 [(set_attr "type" "icmp")
1125 (set_attr "mode" "<MODE>")])
1126
1127 (define_insn "*cmpqi_ext_1"
1128 [(set (reg FLAGS_REG)
1129 (compare
1130 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1131 (subreg:QI
1132 (zero_extract:SI
1133 (match_operand 1 "ext_register_operand" "Q,Q")
1134 (const_int 8)
1135 (const_int 8)) 0)))]
1136 "ix86_match_ccmode (insn, CCmode)"
1137 "cmp{b}\t{%h1, %0|%0, %h1}"
1138 [(set_attr "isa" "*,nox64")
1139 (set_attr "type" "icmp")
1140 (set_attr "mode" "QI")])
1141
1142 (define_insn "*cmpqi_ext_2"
1143 [(set (reg FLAGS_REG)
1144 (compare
1145 (subreg:QI
1146 (zero_extract:SI
1147 (match_operand 0 "ext_register_operand" "Q")
1148 (const_int 8)
1149 (const_int 8)) 0)
1150 (match_operand:QI 1 "const0_operand")))]
1151 "ix86_match_ccmode (insn, CCNOmode)"
1152 "test{b}\t%h0, %h0"
1153 [(set_attr "type" "test")
1154 (set_attr "length_immediate" "0")
1155 (set_attr "mode" "QI")])
1156
1157 (define_expand "cmpqi_ext_3"
1158 [(set (reg:CC FLAGS_REG)
1159 (compare:CC
1160 (subreg:QI
1161 (zero_extract:SI
1162 (match_operand 0 "ext_register_operand")
1163 (const_int 8)
1164 (const_int 8)) 0)
1165 (match_operand:QI 1 "const_int_operand")))])
1166
1167 (define_insn "*cmpqi_ext_3"
1168 [(set (reg FLAGS_REG)
1169 (compare
1170 (subreg:QI
1171 (zero_extract:SI
1172 (match_operand 0 "ext_register_operand" "Q,Q")
1173 (const_int 8)
1174 (const_int 8)) 0)
1175 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1176 "ix86_match_ccmode (insn, CCmode)"
1177 "cmp{b}\t{%1, %h0|%h0, %1}"
1178 [(set_attr "isa" "*,nox64")
1179 (set_attr "type" "icmp")
1180 (set_attr "modrm" "1")
1181 (set_attr "mode" "QI")])
1182
1183 (define_insn "*cmpqi_ext_4"
1184 [(set (reg FLAGS_REG)
1185 (compare
1186 (subreg:QI
1187 (zero_extract:SI
1188 (match_operand 0 "ext_register_operand" "Q")
1189 (const_int 8)
1190 (const_int 8)) 0)
1191 (subreg:QI
1192 (zero_extract:SI
1193 (match_operand 1 "ext_register_operand" "Q")
1194 (const_int 8)
1195 (const_int 8)) 0)))]
1196 "ix86_match_ccmode (insn, CCmode)"
1197 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1198 [(set_attr "type" "icmp")
1199 (set_attr "mode" "QI")])
1200
1201 ;; These implement float point compares.
1202 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1203 ;; which would allow mix and match FP modes on the compares. Which is what
1204 ;; the old patterns did, but with many more of them.
1205
1206 (define_expand "cbranchxf4"
1207 [(set (reg:CC FLAGS_REG)
1208 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1209 (match_operand:XF 2 "nonmemory_operand")))
1210 (set (pc) (if_then_else
1211 (match_operator 0 "ix86_fp_comparison_operator"
1212 [(reg:CC FLAGS_REG)
1213 (const_int 0)])
1214 (label_ref (match_operand 3))
1215 (pc)))]
1216 "TARGET_80387"
1217 {
1218 ix86_expand_branch (GET_CODE (operands[0]),
1219 operands[1], operands[2], operands[3]);
1220 DONE;
1221 })
1222
1223 (define_expand "cstorexf4"
1224 [(set (reg:CC FLAGS_REG)
1225 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1226 (match_operand:XF 3 "nonmemory_operand")))
1227 (set (match_operand:QI 0 "register_operand")
1228 (match_operator 1 "ix86_fp_comparison_operator"
1229 [(reg:CC FLAGS_REG)
1230 (const_int 0)]))]
1231 "TARGET_80387"
1232 {
1233 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1234 operands[2], operands[3]);
1235 DONE;
1236 })
1237
1238 (define_expand "cbranch<mode>4"
1239 [(set (reg:CC FLAGS_REG)
1240 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1241 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1242 (set (pc) (if_then_else
1243 (match_operator 0 "ix86_fp_comparison_operator"
1244 [(reg:CC FLAGS_REG)
1245 (const_int 0)])
1246 (label_ref (match_operand 3))
1247 (pc)))]
1248 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1249 {
1250 ix86_expand_branch (GET_CODE (operands[0]),
1251 operands[1], operands[2], operands[3]);
1252 DONE;
1253 })
1254
1255 (define_expand "cstore<mode>4"
1256 [(set (reg:CC FLAGS_REG)
1257 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1258 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1259 (set (match_operand:QI 0 "register_operand")
1260 (match_operator 1 "ix86_fp_comparison_operator"
1261 [(reg:CC FLAGS_REG)
1262 (const_int 0)]))]
1263 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1264 {
1265 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1266 operands[2], operands[3]);
1267 DONE;
1268 })
1269
1270 (define_expand "cbranchcc4"
1271 [(set (pc) (if_then_else
1272 (match_operator 0 "comparison_operator"
1273 [(match_operand 1 "flags_reg_operand")
1274 (match_operand 2 "const0_operand")])
1275 (label_ref (match_operand 3))
1276 (pc)))]
1277 ""
1278 {
1279 ix86_expand_branch (GET_CODE (operands[0]),
1280 operands[1], operands[2], operands[3]);
1281 DONE;
1282 })
1283
1284 (define_expand "cstorecc4"
1285 [(set (match_operand:QI 0 "register_operand")
1286 (match_operator 1 "comparison_operator"
1287 [(match_operand 2 "flags_reg_operand")
1288 (match_operand 3 "const0_operand")]))]
1289 ""
1290 {
1291 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1292 operands[2], operands[3]);
1293 DONE;
1294 })
1295
1296
1297 ;; FP compares, step 1:
1298 ;; Set the FP condition codes.
1299 ;;
1300 ;; CCFPmode compare with exceptions
1301 ;; CCFPUmode compare with no exceptions
1302
1303 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1304 ;; used to manage the reg stack popping would not be preserved.
1305
1306 (define_insn "*cmp<mode>_0_i387"
1307 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (unspec:HI
1309 [(compare:CCFP
1310 (match_operand:X87MODEF 1 "register_operand" "f")
1311 (match_operand:X87MODEF 2 "const0_operand"))]
1312 UNSPEC_FNSTSW))]
1313 "TARGET_80387"
1314 "* return output_fp_compare (insn, operands, false, false);"
1315 [(set_attr "type" "multi")
1316 (set_attr "unit" "i387")
1317 (set_attr "mode" "<MODE>")])
1318
1319 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1320 [(set (reg:CCFP FLAGS_REG)
1321 (compare:CCFP
1322 (match_operand:X87MODEF 1 "register_operand" "f")
1323 (match_operand:X87MODEF 2 "const0_operand")))
1324 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1325 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1326 "#"
1327 "&& reload_completed"
1328 [(set (match_dup 0)
1329 (unspec:HI
1330 [(compare:CCFP (match_dup 1)(match_dup 2))]
1331 UNSPEC_FNSTSW))
1332 (set (reg:CC FLAGS_REG)
1333 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334 ""
1335 [(set_attr "type" "multi")
1336 (set_attr "unit" "i387")
1337 (set_attr "mode" "<MODE>")])
1338
1339 (define_insn "*cmpxf_i387"
1340 [(set (match_operand:HI 0 "register_operand" "=a")
1341 (unspec:HI
1342 [(compare:CCFP
1343 (match_operand:XF 1 "register_operand" "f")
1344 (match_operand:XF 2 "register_operand" "f"))]
1345 UNSPEC_FNSTSW))]
1346 "TARGET_80387"
1347 "* return output_fp_compare (insn, operands, false, false);"
1348 [(set_attr "type" "multi")
1349 (set_attr "unit" "i387")
1350 (set_attr "mode" "XF")])
1351
1352 (define_insn_and_split "*cmpxf_cc_i387"
1353 [(set (reg:CCFP FLAGS_REG)
1354 (compare:CCFP
1355 (match_operand:XF 1 "register_operand" "f")
1356 (match_operand:XF 2 "register_operand" "f")))
1357 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1358 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1359 "#"
1360 "&& reload_completed"
1361 [(set (match_dup 0)
1362 (unspec:HI
1363 [(compare:CCFP (match_dup 1)(match_dup 2))]
1364 UNSPEC_FNSTSW))
1365 (set (reg:CC FLAGS_REG)
1366 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1367 ""
1368 [(set_attr "type" "multi")
1369 (set_attr "unit" "i387")
1370 (set_attr "mode" "XF")])
1371
1372 (define_insn "*cmp<mode>_i387"
1373 [(set (match_operand:HI 0 "register_operand" "=a")
1374 (unspec:HI
1375 [(compare:CCFP
1376 (match_operand:MODEF 1 "register_operand" "f")
1377 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1378 UNSPEC_FNSTSW))]
1379 "TARGET_80387"
1380 "* return output_fp_compare (insn, operands, false, false);"
1381 [(set_attr "type" "multi")
1382 (set_attr "unit" "i387")
1383 (set_attr "mode" "<MODE>")])
1384
1385 (define_insn_and_split "*cmp<mode>_cc_i387"
1386 [(set (reg:CCFP FLAGS_REG)
1387 (compare:CCFP
1388 (match_operand:MODEF 1 "register_operand" "f")
1389 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1390 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1391 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1392 "#"
1393 "&& reload_completed"
1394 [(set (match_dup 0)
1395 (unspec:HI
1396 [(compare:CCFP (match_dup 1)(match_dup 2))]
1397 UNSPEC_FNSTSW))
1398 (set (reg:CC FLAGS_REG)
1399 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1400 ""
1401 [(set_attr "type" "multi")
1402 (set_attr "unit" "i387")
1403 (set_attr "mode" "<MODE>")])
1404
1405 (define_insn "*cmpu<mode>_i387"
1406 [(set (match_operand:HI 0 "register_operand" "=a")
1407 (unspec:HI
1408 [(compare:CCFPU
1409 (match_operand:X87MODEF 1 "register_operand" "f")
1410 (match_operand:X87MODEF 2 "register_operand" "f"))]
1411 UNSPEC_FNSTSW))]
1412 "TARGET_80387"
1413 "* return output_fp_compare (insn, operands, false, true);"
1414 [(set_attr "type" "multi")
1415 (set_attr "unit" "i387")
1416 (set_attr "mode" "<MODE>")])
1417
1418 (define_insn_and_split "*cmpu<mode>_cc_i387"
1419 [(set (reg:CCFPU FLAGS_REG)
1420 (compare:CCFPU
1421 (match_operand:X87MODEF 1 "register_operand" "f")
1422 (match_operand:X87MODEF 2 "register_operand" "f")))
1423 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1424 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1425 "#"
1426 "&& reload_completed"
1427 [(set (match_dup 0)
1428 (unspec:HI
1429 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1430 UNSPEC_FNSTSW))
1431 (set (reg:CC FLAGS_REG)
1432 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1433 ""
1434 [(set_attr "type" "multi")
1435 (set_attr "unit" "i387")
1436 (set_attr "mode" "<MODE>")])
1437
1438 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1439 [(set (match_operand:HI 0 "register_operand" "=a")
1440 (unspec:HI
1441 [(compare:CCFP
1442 (match_operand:X87MODEF 1 "register_operand" "f")
1443 (match_operator:X87MODEF 3 "float_operator"
1444 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1445 UNSPEC_FNSTSW))]
1446 "TARGET_80387
1447 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1448 || optimize_function_for_size_p (cfun))"
1449 "* return output_fp_compare (insn, operands, false, false);"
1450 [(set_attr "type" "multi")
1451 (set_attr "unit" "i387")
1452 (set_attr "fp_int_src" "true")
1453 (set_attr "mode" "<SWI24:MODE>")])
1454
1455 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1456 [(set (reg:CCFP FLAGS_REG)
1457 (compare:CCFP
1458 (match_operand:X87MODEF 1 "register_operand" "f")
1459 (match_operator:X87MODEF 3 "float_operator"
1460 [(match_operand:SWI24 2 "memory_operand" "m")])))
1461 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1462 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1463 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1464 || optimize_function_for_size_p (cfun))"
1465 "#"
1466 "&& reload_completed"
1467 [(set (match_dup 0)
1468 (unspec:HI
1469 [(compare:CCFP
1470 (match_dup 1)
1471 (match_op_dup 3 [(match_dup 2)]))]
1472 UNSPEC_FNSTSW))
1473 (set (reg:CC FLAGS_REG)
1474 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1475 ""
1476 [(set_attr "type" "multi")
1477 (set_attr "unit" "i387")
1478 (set_attr "fp_int_src" "true")
1479 (set_attr "mode" "<SWI24:MODE>")])
1480
1481 ;; FP compares, step 2
1482 ;; Move the fpsw to ax.
1483
1484 (define_insn "x86_fnstsw_1"
1485 [(set (match_operand:HI 0 "register_operand" "=a")
1486 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1487 "TARGET_80387"
1488 "fnstsw\t%0"
1489 [(set (attr "length")
1490 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1491 (set_attr "mode" "SI")
1492 (set_attr "unit" "i387")])
1493
1494 ;; FP compares, step 3
1495 ;; Get ax into flags, general case.
1496
1497 (define_insn "x86_sahf_1"
1498 [(set (reg:CC FLAGS_REG)
1499 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1500 UNSPEC_SAHF))]
1501 "TARGET_SAHF"
1502 {
1503 #ifndef HAVE_AS_IX86_SAHF
1504 if (TARGET_64BIT)
1505 return ASM_BYTE "0x9e";
1506 else
1507 #endif
1508 return "sahf";
1509 }
1510 [(set_attr "length" "1")
1511 (set_attr "athlon_decode" "vector")
1512 (set_attr "amdfam10_decode" "direct")
1513 (set_attr "bdver1_decode" "direct")
1514 (set_attr "mode" "SI")])
1515
1516 ;; Pentium Pro can do steps 1 through 3 in one go.
1517 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1518 ;; (these i387 instructions set flags directly)
1519
1520 (define_mode_iterator FPCMP [CCFP CCFPU])
1521 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1522
1523 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1524 [(set (reg:FPCMP FLAGS_REG)
1525 (compare:FPCMP
1526 (match_operand:MODEF 0 "register_operand" "f,x")
1527 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1528 "TARGET_MIX_SSE_I387
1529 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1530 "* return output_fp_compare (insn, operands, true,
1531 <FPCMP:MODE>mode == CCFPUmode);"
1532 [(set_attr "type" "fcmp,ssecomi")
1533 (set_attr "prefix" "orig,maybe_vex")
1534 (set_attr "mode" "<MODEF:MODE>")
1535 (set (attr "prefix_rep")
1536 (if_then_else (eq_attr "type" "ssecomi")
1537 (const_string "0")
1538 (const_string "*")))
1539 (set (attr "prefix_data16")
1540 (cond [(eq_attr "type" "fcmp")
1541 (const_string "*")
1542 (eq_attr "mode" "DF")
1543 (const_string "1")
1544 ]
1545 (const_string "0")))
1546 (set_attr "athlon_decode" "vector")
1547 (set_attr "amdfam10_decode" "direct")
1548 (set_attr "bdver1_decode" "double")])
1549
1550 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1551 [(set (reg:FPCMP FLAGS_REG)
1552 (compare:FPCMP
1553 (match_operand:MODEF 0 "register_operand" "x")
1554 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1555 "TARGET_SSE_MATH
1556 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1557 "* return output_fp_compare (insn, operands, true,
1558 <FPCMP:MODE>mode == CCFPUmode);"
1559 [(set_attr "type" "ssecomi")
1560 (set_attr "prefix" "maybe_vex")
1561 (set_attr "mode" "<MODEF:MODE>")
1562 (set_attr "prefix_rep" "0")
1563 (set (attr "prefix_data16")
1564 (if_then_else (eq_attr "mode" "DF")
1565 (const_string "1")
1566 (const_string "0")))
1567 (set_attr "athlon_decode" "vector")
1568 (set_attr "amdfam10_decode" "direct")
1569 (set_attr "bdver1_decode" "double")])
1570
1571 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1572 [(set (reg:FPCMP FLAGS_REG)
1573 (compare:FPCMP
1574 (match_operand:X87MODEF 0 "register_operand" "f")
1575 (match_operand:X87MODEF 1 "register_operand" "f")))]
1576 "TARGET_80387 && TARGET_CMOVE
1577 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1578 "* return output_fp_compare (insn, operands, true,
1579 <FPCMP:MODE>mode == CCFPUmode);"
1580 [(set_attr "type" "fcmp")
1581 (set_attr "mode" "<X87MODEF:MODE>")
1582 (set_attr "athlon_decode" "vector")
1583 (set_attr "amdfam10_decode" "direct")
1584 (set_attr "bdver1_decode" "double")])
1585 \f
1586 ;; Push/pop instructions.
1587
1588 (define_insn "*push<mode>2"
1589 [(set (match_operand:DWI 0 "push_operand" "=<")
1590 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1591 ""
1592 "#"
1593 [(set_attr "type" "multi")
1594 (set_attr "mode" "<MODE>")])
1595
1596 (define_split
1597 [(set (match_operand:TI 0 "push_operand")
1598 (match_operand:TI 1 "general_operand"))]
1599 "TARGET_64BIT && reload_completed
1600 && !SSE_REG_P (operands[1])"
1601 [(const_int 0)]
1602 "ix86_split_long_move (operands); DONE;")
1603
1604 (define_insn "*pushdi2_rex64"
1605 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1606 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1607 "TARGET_64BIT"
1608 "@
1609 push{q}\t%1
1610 #"
1611 [(set_attr "type" "push,multi")
1612 (set_attr "mode" "DI")])
1613
1614 ;; Convert impossible pushes of immediate to existing instructions.
1615 ;; First try to get scratch register and go through it. In case this
1616 ;; fails, push sign extended lower part first and then overwrite
1617 ;; upper part by 32bit move.
1618 (define_peephole2
1619 [(match_scratch:DI 2 "r")
1620 (set (match_operand:DI 0 "push_operand")
1621 (match_operand:DI 1 "immediate_operand"))]
1622 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1623 && !x86_64_immediate_operand (operands[1], DImode)"
1624 [(set (match_dup 2) (match_dup 1))
1625 (set (match_dup 0) (match_dup 2))])
1626
1627 ;; We need to define this as both peepholer and splitter for case
1628 ;; peephole2 pass is not run.
1629 ;; "&& 1" is needed to keep it from matching the previous pattern.
1630 (define_peephole2
1631 [(set (match_operand:DI 0 "push_operand")
1632 (match_operand:DI 1 "immediate_operand"))]
1633 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1634 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1635 [(set (match_dup 0) (match_dup 1))
1636 (set (match_dup 2) (match_dup 3))]
1637 {
1638 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1639
1640 operands[1] = gen_lowpart (DImode, operands[2]);
1641 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1642 GEN_INT (4)));
1643 })
1644
1645 (define_split
1646 [(set (match_operand:DI 0 "push_operand")
1647 (match_operand:DI 1 "immediate_operand"))]
1648 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1649 ? epilogue_completed : reload_completed)
1650 && !symbolic_operand (operands[1], DImode)
1651 && !x86_64_immediate_operand (operands[1], DImode)"
1652 [(set (match_dup 0) (match_dup 1))
1653 (set (match_dup 2) (match_dup 3))]
1654 {
1655 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1656
1657 operands[1] = gen_lowpart (DImode, operands[2]);
1658 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1659 GEN_INT (4)));
1660 })
1661
1662 (define_split
1663 [(set (match_operand:DI 0 "push_operand")
1664 (match_operand:DI 1 "general_operand"))]
1665 "!TARGET_64BIT && reload_completed
1666 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1667 [(const_int 0)]
1668 "ix86_split_long_move (operands); DONE;")
1669
1670 (define_insn "*pushsi2"
1671 [(set (match_operand:SI 0 "push_operand" "=<")
1672 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1673 "!TARGET_64BIT"
1674 "push{l}\t%1"
1675 [(set_attr "type" "push")
1676 (set_attr "mode" "SI")])
1677
1678 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1679 ;; "push a byte/word". But actually we use pushl, which has the effect
1680 ;; of rounding the amount pushed up to a word.
1681
1682 ;; For TARGET_64BIT we always round up to 8 bytes.
1683 (define_insn "*push<mode>2_rex64"
1684 [(set (match_operand:SWI124 0 "push_operand" "=X")
1685 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1686 "TARGET_64BIT"
1687 "push{q}\t%q1"
1688 [(set_attr "type" "push")
1689 (set_attr "mode" "DI")])
1690
1691 (define_insn "*push<mode>2"
1692 [(set (match_operand:SWI12 0 "push_operand" "=X")
1693 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1694 "!TARGET_64BIT"
1695 "push{l}\t%k1"
1696 [(set_attr "type" "push")
1697 (set_attr "mode" "SI")])
1698
1699 (define_insn "*push<mode>2_prologue"
1700 [(set (match_operand:W 0 "push_operand" "=<")
1701 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1702 (clobber (mem:BLK (scratch)))]
1703 ""
1704 "push{<imodesuffix>}\t%1"
1705 [(set_attr "type" "push")
1706 (set_attr "mode" "<MODE>")])
1707
1708 (define_insn "*pop<mode>1"
1709 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1710 (match_operand:W 1 "pop_operand" ">"))]
1711 ""
1712 "pop{<imodesuffix>}\t%0"
1713 [(set_attr "type" "pop")
1714 (set_attr "mode" "<MODE>")])
1715
1716 (define_insn "*pop<mode>1_epilogue"
1717 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1718 (match_operand:W 1 "pop_operand" ">"))
1719 (clobber (mem:BLK (scratch)))]
1720 ""
1721 "pop{<imodesuffix>}\t%0"
1722 [(set_attr "type" "pop")
1723 (set_attr "mode" "<MODE>")])
1724 \f
1725 ;; Move instructions.
1726
1727 (define_expand "movxi"
1728 [(set (match_operand:XI 0 "nonimmediate_operand")
1729 (match_operand:XI 1 "general_operand"))]
1730 "TARGET_AVX512F"
1731 "ix86_expand_move (XImode, operands); DONE;")
1732
1733 ;; Reload patterns to support multi-word load/store
1734 ;; with non-offsetable address.
1735 (define_expand "reload_noff_store"
1736 [(parallel [(match_operand 0 "memory_operand" "=m")
1737 (match_operand 1 "register_operand" "r")
1738 (match_operand:DI 2 "register_operand" "=&r")])]
1739 "TARGET_64BIT"
1740 {
1741 rtx mem = operands[0];
1742 rtx addr = XEXP (mem, 0);
1743
1744 emit_move_insn (operands[2], addr);
1745 mem = replace_equiv_address_nv (mem, operands[2]);
1746
1747 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1748 DONE;
1749 })
1750
1751 (define_expand "reload_noff_load"
1752 [(parallel [(match_operand 0 "register_operand" "=r")
1753 (match_operand 1 "memory_operand" "m")
1754 (match_operand:DI 2 "register_operand" "=r")])]
1755 "TARGET_64BIT"
1756 {
1757 rtx mem = operands[1];
1758 rtx addr = XEXP (mem, 0);
1759
1760 emit_move_insn (operands[2], addr);
1761 mem = replace_equiv_address_nv (mem, operands[2]);
1762
1763 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1764 DONE;
1765 })
1766
1767 (define_expand "movoi"
1768 [(set (match_operand:OI 0 "nonimmediate_operand")
1769 (match_operand:OI 1 "general_operand"))]
1770 "TARGET_AVX"
1771 "ix86_expand_move (OImode, operands); DONE;")
1772
1773 (define_expand "movti"
1774 [(set (match_operand:TI 0 "nonimmediate_operand")
1775 (match_operand:TI 1 "nonimmediate_operand"))]
1776 "TARGET_64BIT || TARGET_SSE"
1777 {
1778 if (TARGET_64BIT)
1779 ix86_expand_move (TImode, operands);
1780 else if (push_operand (operands[0], TImode))
1781 ix86_expand_push (TImode, operands[1]);
1782 else
1783 ix86_expand_vector_move (TImode, operands);
1784 DONE;
1785 })
1786
1787 ;; This expands to what emit_move_complex would generate if we didn't
1788 ;; have a movti pattern. Having this avoids problems with reload on
1789 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1790 ;; to have around all the time.
1791 (define_expand "movcdi"
1792 [(set (match_operand:CDI 0 "nonimmediate_operand")
1793 (match_operand:CDI 1 "general_operand"))]
1794 ""
1795 {
1796 if (push_operand (operands[0], CDImode))
1797 emit_move_complex_push (CDImode, operands[0], operands[1]);
1798 else
1799 emit_move_complex_parts (operands[0], operands[1]);
1800 DONE;
1801 })
1802
1803 (define_expand "mov<mode>"
1804 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1805 (match_operand:SWI1248x 1 "general_operand"))]
1806 ""
1807 "ix86_expand_move (<MODE>mode, operands); DONE;")
1808
1809 (define_insn "*mov<mode>_xor"
1810 [(set (match_operand:SWI48 0 "register_operand" "=r")
1811 (match_operand:SWI48 1 "const0_operand"))
1812 (clobber (reg:CC FLAGS_REG))]
1813 "reload_completed"
1814 "xor{l}\t%k0, %k0"
1815 [(set_attr "type" "alu1")
1816 (set_attr "mode" "SI")
1817 (set_attr "length_immediate" "0")])
1818
1819 (define_insn "*mov<mode>_or"
1820 [(set (match_operand:SWI48 0 "register_operand" "=r")
1821 (match_operand:SWI48 1 "const_int_operand"))
1822 (clobber (reg:CC FLAGS_REG))]
1823 "reload_completed
1824 && operands[1] == constm1_rtx"
1825 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1826 [(set_attr "type" "alu1")
1827 (set_attr "mode" "<MODE>")
1828 (set_attr "length_immediate" "1")])
1829
1830 (define_insn "*movxi_internal_avx512f"
1831 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1832 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1833 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1834 {
1835 switch (which_alternative)
1836 {
1837 case 0:
1838 return standard_sse_constant_opcode (insn, operands[1]);
1839 case 1:
1840 case 2:
1841 if (misaligned_operand (operands[0], XImode)
1842 || misaligned_operand (operands[1], XImode))
1843 return "vmovdqu32\t{%1, %0|%0, %1}";
1844 else
1845 return "vmovdqa32\t{%1, %0|%0, %1}";
1846 default:
1847 gcc_unreachable ();
1848 }
1849 }
1850 [(set_attr "type" "sselog1,ssemov,ssemov")
1851 (set_attr "prefix" "evex")
1852 (set_attr "mode" "XI")])
1853
1854 (define_insn "*movoi_internal_avx"
1855 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1856 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1857 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1858 {
1859 switch (get_attr_type (insn))
1860 {
1861 case TYPE_SSELOG1:
1862 return standard_sse_constant_opcode (insn, operands[1]);
1863
1864 case TYPE_SSEMOV:
1865 if (misaligned_operand (operands[0], OImode)
1866 || misaligned_operand (operands[1], OImode))
1867 {
1868 if (get_attr_mode (insn) == MODE_V8SF)
1869 return "vmovups\t{%1, %0|%0, %1}";
1870 else
1871 return "vmovdqu\t{%1, %0|%0, %1}";
1872 }
1873 else
1874 {
1875 if (get_attr_mode (insn) == MODE_V8SF)
1876 return "vmovaps\t{%1, %0|%0, %1}";
1877 else
1878 return "vmovdqa\t{%1, %0|%0, %1}";
1879 }
1880
1881 default:
1882 gcc_unreachable ();
1883 }
1884 }
1885 [(set_attr "type" "sselog1,ssemov,ssemov")
1886 (set_attr "prefix" "vex")
1887 (set (attr "mode")
1888 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1889 (const_string "V8SF")
1890 (and (eq_attr "alternative" "2")
1891 (match_test "TARGET_SSE_TYPELESS_STORES"))
1892 (const_string "V8SF")
1893 ]
1894 (const_string "OI")))])
1895
1896 (define_insn "*movti_internal"
1897 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1898 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1899 "(TARGET_64BIT || TARGET_SSE)
1900 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1901 {
1902 switch (get_attr_type (insn))
1903 {
1904 case TYPE_MULTI:
1905 return "#";
1906
1907 case TYPE_SSELOG1:
1908 return standard_sse_constant_opcode (insn, operands[1]);
1909
1910 case TYPE_SSEMOV:
1911 /* TDmode values are passed as TImode on the stack. Moving them
1912 to stack may result in unaligned memory access. */
1913 if (misaligned_operand (operands[0], TImode)
1914 || misaligned_operand (operands[1], TImode))
1915 {
1916 if (get_attr_mode (insn) == MODE_V4SF)
1917 return "%vmovups\t{%1, %0|%0, %1}";
1918 else
1919 return "%vmovdqu\t{%1, %0|%0, %1}";
1920 }
1921 else
1922 {
1923 if (get_attr_mode (insn) == MODE_V4SF)
1924 return "%vmovaps\t{%1, %0|%0, %1}";
1925 else
1926 return "%vmovdqa\t{%1, %0|%0, %1}";
1927 }
1928
1929 default:
1930 gcc_unreachable ();
1931 }
1932 }
1933 [(set_attr "isa" "x64,x64,*,*,*")
1934 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1935 (set (attr "prefix")
1936 (if_then_else (eq_attr "type" "sselog1,ssemov")
1937 (const_string "maybe_vex")
1938 (const_string "orig")))
1939 (set (attr "mode")
1940 (cond [(eq_attr "alternative" "0,1")
1941 (const_string "DI")
1942 (ior (not (match_test "TARGET_SSE2"))
1943 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1944 (const_string "V4SF")
1945 (and (eq_attr "alternative" "4")
1946 (match_test "TARGET_SSE_TYPELESS_STORES"))
1947 (const_string "V4SF")
1948 (match_test "TARGET_AVX")
1949 (const_string "TI")
1950 (match_test "optimize_function_for_size_p (cfun)")
1951 (const_string "V4SF")
1952 ]
1953 (const_string "TI")))])
1954
1955 (define_split
1956 [(set (match_operand:TI 0 "nonimmediate_operand")
1957 (match_operand:TI 1 "general_operand"))]
1958 "reload_completed
1959 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1960 [(const_int 0)]
1961 "ix86_split_long_move (operands); DONE;")
1962
1963 (define_insn "*movdi_internal"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1966 (match_operand:DI 1 "general_operand"
1967 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
1968 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969 {
1970 switch (get_attr_type (insn))
1971 {
1972 case TYPE_MULTI:
1973 return "#";
1974
1975 case TYPE_MMX:
1976 return "pxor\t%0, %0";
1977
1978 case TYPE_MMXMOV:
1979 /* Handle broken assemblers that require movd instead of movq. */
1980 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
1981 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
1982 return "movd\t{%1, %0|%0, %1}";
1983 return "movq\t{%1, %0|%0, %1}";
1984
1985 case TYPE_SSELOG1:
1986 if (GENERAL_REG_P (operands[0]))
1987 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
1988
1989 return standard_sse_constant_opcode (insn, operands[1]);
1990
1991 case TYPE_SSEMOV:
1992 switch (get_attr_mode (insn))
1993 {
1994 case MODE_DI:
1995 /* Handle broken assemblers that require movd instead of movq. */
1996 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
1997 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
1998 return "%vmovd\t{%1, %0|%0, %1}";
1999 return "%vmovq\t{%1, %0|%0, %1}";
2000 case MODE_TI:
2001 return "%vmovdqa\t{%1, %0|%0, %1}";
2002 case MODE_XI:
2003 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2004
2005 case MODE_V2SF:
2006 gcc_assert (!TARGET_AVX);
2007 return "movlps\t{%1, %0|%0, %1}";
2008 case MODE_V4SF:
2009 return "%vmovaps\t{%1, %0|%0, %1}";
2010
2011 default:
2012 gcc_unreachable ();
2013 }
2014
2015 case TYPE_SSECVT:
2016 if (SSE_REG_P (operands[0]))
2017 return "movq2dq\t{%1, %0|%0, %1}";
2018 else
2019 return "movdq2q\t{%1, %0|%0, %1}";
2020
2021 case TYPE_LEA:
2022 return "lea{q}\t{%E1, %0|%0, %E1}";
2023
2024 case TYPE_IMOV:
2025 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 4)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2030 else if (ix86_use_lea_for_mov (insn, operands))
2031 return "lea{q}\t{%E1, %0|%0, %E1}";
2032 else
2033 return "mov{q}\t{%1, %0|%0, %1}";
2034
2035 default:
2036 gcc_unreachable ();
2037 }
2038 }
2039 [(set (attr "isa")
2040 (cond [(eq_attr "alternative" "0,1")
2041 (const_string "nox64")
2042 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2043 (const_string "x64")
2044 (eq_attr "alternative" "17")
2045 (const_string "x64_sse4")
2046 ]
2047 (const_string "*")))
2048 (set (attr "type")
2049 (cond [(eq_attr "alternative" "0,1")
2050 (const_string "multi")
2051 (eq_attr "alternative" "6")
2052 (const_string "mmx")
2053 (eq_attr "alternative" "7,8,9,10,11")
2054 (const_string "mmxmov")
2055 (eq_attr "alternative" "12,17")
2056 (const_string "sselog1")
2057 (eq_attr "alternative" "13,14,15,16,18")
2058 (const_string "ssemov")
2059 (eq_attr "alternative" "19,20")
2060 (const_string "ssecvt")
2061 (match_operand 1 "pic_32bit_operand")
2062 (const_string "lea")
2063 ]
2064 (const_string "imov")))
2065 (set (attr "modrm")
2066 (if_then_else
2067 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2068 (const_string "0")
2069 (const_string "*")))
2070 (set (attr "length_immediate")
2071 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2072 (const_string "8")
2073 (eq_attr "alternative" "17")
2074 (const_string "1")
2075 ]
2076 (const_string "*")))
2077 (set (attr "prefix_rex")
2078 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2079 (const_string "1")
2080 (const_string "*")))
2081 (set (attr "prefix_extra")
2082 (if_then_else (eq_attr "alternative" "17")
2083 (const_string "1")
2084 (const_string "*")))
2085 (set (attr "prefix")
2086 (if_then_else (eq_attr "type" "sselog1,ssemov")
2087 (const_string "maybe_vex")
2088 (const_string "orig")))
2089 (set (attr "prefix_data16")
2090 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2091 (const_string "1")
2092 (const_string "*")))
2093 (set (attr "mode")
2094 (cond [(eq_attr "alternative" "2")
2095 (const_string "SI")
2096 (eq_attr "alternative" "12,13")
2097 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2098 (match_operand 1 "ext_sse_reg_operand"))
2099 (const_string "XI")
2100 (ior (not (match_test "TARGET_SSE2"))
2101 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2102 (const_string "V4SF")
2103 (match_test "TARGET_AVX")
2104 (const_string "TI")
2105 (match_test "optimize_function_for_size_p (cfun)")
2106 (const_string "V4SF")
2107 ]
2108 (const_string "TI"))
2109
2110 (and (eq_attr "alternative" "14,15")
2111 (not (match_test "TARGET_SSE2")))
2112 (const_string "V2SF")
2113 (eq_attr "alternative" "17")
2114 (const_string "TI")
2115 ]
2116 (const_string "DI")))])
2117
2118 (define_split
2119 [(set (match_operand:DI 0 "nonimmediate_operand")
2120 (match_operand:DI 1 "general_operand"))]
2121 "!TARGET_64BIT && reload_completed
2122 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2123 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2124 [(const_int 0)]
2125 "ix86_split_long_move (operands); DONE;")
2126
2127 (define_insn "*movsi_internal"
2128 [(set (match_operand:SI 0 "nonimmediate_operand"
2129 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2130 (match_operand:SI 1 "general_operand"
2131 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2132 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2133 {
2134 switch (get_attr_type (insn))
2135 {
2136 case TYPE_SSELOG1:
2137 if (GENERAL_REG_P (operands[0]))
2138 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2139
2140 return standard_sse_constant_opcode (insn, operands[1]);
2141
2142 case TYPE_SSEMOV:
2143 switch (get_attr_mode (insn))
2144 {
2145 case MODE_SI:
2146 return "%vmovd\t{%1, %0|%0, %1}";
2147 case MODE_TI:
2148 return "%vmovdqa\t{%1, %0|%0, %1}";
2149 case MODE_XI:
2150 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2151
2152 case MODE_V4SF:
2153 return "%vmovaps\t{%1, %0|%0, %1}";
2154
2155 case MODE_SF:
2156 gcc_assert (!TARGET_AVX);
2157 return "movss\t{%1, %0|%0, %1}";
2158
2159 default:
2160 gcc_unreachable ();
2161 }
2162
2163 case TYPE_MMX:
2164 return "pxor\t%0, %0";
2165
2166 case TYPE_MMXMOV:
2167 switch (get_attr_mode (insn))
2168 {
2169 case MODE_DI:
2170 return "movq\t{%1, %0|%0, %1}";
2171 case MODE_SI:
2172 return "movd\t{%1, %0|%0, %1}";
2173
2174 default:
2175 gcc_unreachable ();
2176 }
2177
2178 case TYPE_LEA:
2179 return "lea{l}\t{%E1, %0|%0, %E1}";
2180
2181 case TYPE_IMOV:
2182 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2183 if (ix86_use_lea_for_mov (insn, operands))
2184 return "lea{l}\t{%E1, %0|%0, %E1}";
2185 else
2186 return "mov{l}\t{%1, %0|%0, %1}";
2187
2188 default:
2189 gcc_unreachable ();
2190 }
2191 }
2192 [(set (attr "isa")
2193 (if_then_else (eq_attr "alternative" "11")
2194 (const_string "sse4")
2195 (const_string "*")))
2196 (set (attr "type")
2197 (cond [(eq_attr "alternative" "2")
2198 (const_string "mmx")
2199 (eq_attr "alternative" "3,4,5")
2200 (const_string "mmxmov")
2201 (eq_attr "alternative" "6,11")
2202 (const_string "sselog1")
2203 (eq_attr "alternative" "7,8,9,10,12")
2204 (const_string "ssemov")
2205 (match_operand 1 "pic_32bit_operand")
2206 (const_string "lea")
2207 ]
2208 (const_string "imov")))
2209 (set (attr "length_immediate")
2210 (if_then_else (eq_attr "alternative" "11")
2211 (const_string "1")
2212 (const_string "*")))
2213 (set (attr "prefix_extra")
2214 (if_then_else (eq_attr "alternative" "11")
2215 (const_string "1")
2216 (const_string "*")))
2217 (set (attr "prefix")
2218 (if_then_else (eq_attr "type" "sselog1,ssemov")
2219 (const_string "maybe_vex")
2220 (const_string "orig")))
2221 (set (attr "prefix_data16")
2222 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2223 (const_string "1")
2224 (const_string "*")))
2225 (set (attr "mode")
2226 (cond [(eq_attr "alternative" "2,3")
2227 (const_string "DI")
2228 (eq_attr "alternative" "6,7")
2229 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2230 (match_operand 1 "ext_sse_reg_operand"))
2231 (const_string "XI")
2232 (ior (not (match_test "TARGET_SSE2"))
2233 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2234 (const_string "V4SF")
2235 (match_test "TARGET_AVX")
2236 (const_string "TI")
2237 (match_test "optimize_function_for_size_p (cfun)")
2238 (const_string "V4SF")
2239 ]
2240 (const_string "TI"))
2241
2242 (and (eq_attr "alternative" "8,9")
2243 (not (match_test "TARGET_SSE2")))
2244 (const_string "SF")
2245 (eq_attr "alternative" "11")
2246 (const_string "TI")
2247 ]
2248 (const_string "SI")))])
2249
2250 (define_insn "*movhi_internal"
2251 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm")
2252 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,Yk,Yk"))]
2253 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2254 {
2255 switch (get_attr_type (insn))
2256 {
2257 case TYPE_IMOVX:
2258 /* movzwl is faster than movw on p2 due to partial word stalls,
2259 though not as fast as an aligned movl. */
2260 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2261
2262 case TYPE_MSKMOV:
2263 switch (which_alternative)
2264 {
2265 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2266 case 5: return "kmovw\t{%1, %0|%0, %1}";
2267 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2268 default: gcc_unreachable ();
2269 }
2270
2271 default:
2272 if (get_attr_mode (insn) == MODE_SI)
2273 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2274 else
2275 return "mov{w}\t{%1, %0|%0, %1}";
2276 }
2277 }
2278 [(set (attr "type")
2279 (cond [(match_test "optimize_function_for_size_p (cfun)")
2280 (const_string "imov")
2281 (and (eq_attr "alternative" "0")
2282 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2283 (not (match_test "TARGET_HIMODE_MATH"))))
2284 (const_string "imov")
2285 (and (eq_attr "alternative" "1,2")
2286 (match_operand:HI 1 "aligned_operand"))
2287 (const_string "imov")
2288 (eq_attr "alternative" "4,5,6")
2289 (const_string "mskmov")
2290 (and (match_test "TARGET_MOVX")
2291 (eq_attr "alternative" "0,2"))
2292 (const_string "imovx")
2293 ]
2294 (const_string "imov")))
2295 (set (attr "prefix")
2296 (if_then_else (eq_attr "alternative" "4,5,6")
2297 (const_string "vex")
2298 (const_string "orig")))
2299 (set (attr "mode")
2300 (cond [(eq_attr "type" "imovx")
2301 (const_string "SI")
2302 (and (eq_attr "alternative" "1,2")
2303 (match_operand:HI 1 "aligned_operand"))
2304 (const_string "SI")
2305 (and (eq_attr "alternative" "0")
2306 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2307 (not (match_test "TARGET_HIMODE_MATH"))))
2308 (const_string "SI")
2309 ]
2310 (const_string "HI")))])
2311
2312 ;; Situation is quite tricky about when to choose full sized (SImode) move
2313 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2314 ;; partial register dependency machines (such as AMD Athlon), where QImode
2315 ;; moves issue extra dependency and for partial register stalls machines
2316 ;; that don't use QImode patterns (and QImode move cause stall on the next
2317 ;; instruction).
2318 ;;
2319 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2320 ;; register stall machines with, where we use QImode instructions, since
2321 ;; partial register stall can be caused there. Then we use movzx.
2322
2323 (define_insn "*movqi_internal"
2324 [(set (match_operand:QI 0 "nonimmediate_operand"
2325 "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r")
2326 (match_operand:QI 1 "general_operand"
2327 "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))]
2328 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2329 {
2330 switch (get_attr_type (insn))
2331 {
2332 case TYPE_IMOVX:
2333 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2334 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2335
2336 case TYPE_MSKMOV:
2337 switch (which_alternative)
2338 {
2339 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2340 case 8: return "kmovw\t{%1, %0|%0, %1}";
2341 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2342 default: gcc_unreachable ();
2343 }
2344
2345 default:
2346 if (get_attr_mode (insn) == MODE_SI)
2347 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2348 else
2349 return "mov{b}\t{%1, %0|%0, %1}";
2350 }
2351 }
2352 [(set (attr "type")
2353 (cond [(and (eq_attr "alternative" "5")
2354 (not (match_operand:QI 1 "aligned_operand")))
2355 (const_string "imovx")
2356 (match_test "optimize_function_for_size_p (cfun)")
2357 (const_string "imov")
2358 (and (eq_attr "alternative" "3")
2359 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2360 (not (match_test "TARGET_QIMODE_MATH"))))
2361 (const_string "imov")
2362 (eq_attr "alternative" "3,5")
2363 (const_string "imovx")
2364 (eq_attr "alternative" "7,8,9")
2365 (const_string "mskmov")
2366 (and (match_test "TARGET_MOVX")
2367 (eq_attr "alternative" "2"))
2368 (const_string "imovx")
2369 ]
2370 (const_string "imov")))
2371 (set (attr "prefix")
2372 (if_then_else (eq_attr "alternative" "7,8,9")
2373 (const_string "vex")
2374 (const_string "orig")))
2375 (set (attr "mode")
2376 (cond [(eq_attr "alternative" "3,4,5")
2377 (const_string "SI")
2378 (eq_attr "alternative" "6")
2379 (const_string "QI")
2380 (eq_attr "type" "imovx")
2381 (const_string "SI")
2382 (and (eq_attr "type" "imov")
2383 (and (eq_attr "alternative" "0,1")
2384 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2385 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2386 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2387 (const_string "SI")
2388 ;; Avoid partial register stalls when not using QImode arithmetic
2389 (and (eq_attr "type" "imov")
2390 (and (eq_attr "alternative" "0,1")
2391 (and (match_test "TARGET_PARTIAL_REG_STALL")
2392 (not (match_test "TARGET_QIMODE_MATH")))))
2393 (const_string "SI")
2394 ]
2395 (const_string "QI")))])
2396
2397 ;; Stores and loads of ax to arbitrary constant address.
2398 ;; We fake an second form of instruction to force reload to load address
2399 ;; into register when rax is not available
2400 (define_insn "*movabs<mode>_1"
2401 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2402 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2403 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2404 "@
2405 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2406 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2407 [(set_attr "type" "imov")
2408 (set_attr "modrm" "0,*")
2409 (set_attr "length_address" "8,0")
2410 (set_attr "length_immediate" "0,*")
2411 (set_attr "memory" "store")
2412 (set_attr "mode" "<MODE>")])
2413
2414 (define_insn "*movabs<mode>_2"
2415 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2416 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2417 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2418 "@
2419 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2420 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2421 [(set_attr "type" "imov")
2422 (set_attr "modrm" "0,*")
2423 (set_attr "length_address" "8,0")
2424 (set_attr "length_immediate" "0")
2425 (set_attr "memory" "load")
2426 (set_attr "mode" "<MODE>")])
2427
2428 (define_insn "swap<mode>"
2429 [(set (match_operand:SWI48 0 "register_operand" "+r")
2430 (match_operand:SWI48 1 "register_operand" "+r"))
2431 (set (match_dup 1)
2432 (match_dup 0))]
2433 ""
2434 "xchg{<imodesuffix>}\t%1, %0"
2435 [(set_attr "type" "imov")
2436 (set_attr "mode" "<MODE>")
2437 (set_attr "pent_pair" "np")
2438 (set_attr "athlon_decode" "vector")
2439 (set_attr "amdfam10_decode" "double")
2440 (set_attr "bdver1_decode" "double")])
2441
2442 (define_insn "*swap<mode>_1"
2443 [(set (match_operand:SWI12 0 "register_operand" "+r")
2444 (match_operand:SWI12 1 "register_operand" "+r"))
2445 (set (match_dup 1)
2446 (match_dup 0))]
2447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2448 "xchg{l}\t%k1, %k0"
2449 [(set_attr "type" "imov")
2450 (set_attr "mode" "SI")
2451 (set_attr "pent_pair" "np")
2452 (set_attr "athlon_decode" "vector")
2453 (set_attr "amdfam10_decode" "double")
2454 (set_attr "bdver1_decode" "double")])
2455
2456 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2457 ;; is disabled for AMDFAM10
2458 (define_insn "*swap<mode>_2"
2459 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2460 (match_operand:SWI12 1 "register_operand" "+<r>"))
2461 (set (match_dup 1)
2462 (match_dup 0))]
2463 "TARGET_PARTIAL_REG_STALL"
2464 "xchg{<imodesuffix>}\t%1, %0"
2465 [(set_attr "type" "imov")
2466 (set_attr "mode" "<MODE>")
2467 (set_attr "pent_pair" "np")
2468 (set_attr "athlon_decode" "vector")])
2469
2470 (define_expand "movstrict<mode>"
2471 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2472 (match_operand:SWI12 1 "general_operand"))]
2473 ""
2474 {
2475 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2476 FAIL;
2477 if (GET_CODE (operands[0]) == SUBREG
2478 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2479 FAIL;
2480 /* Don't generate memory->memory moves, go through a register */
2481 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2482 operands[1] = force_reg (<MODE>mode, operands[1]);
2483 })
2484
2485 (define_insn "*movstrict<mode>_1"
2486 [(set (strict_low_part
2487 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2488 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2489 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2491 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2492 [(set_attr "type" "imov")
2493 (set_attr "mode" "<MODE>")])
2494
2495 (define_insn "*movstrict<mode>_xor"
2496 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2497 (match_operand:SWI12 1 "const0_operand"))
2498 (clobber (reg:CC FLAGS_REG))]
2499 "reload_completed"
2500 "xor{<imodesuffix>}\t%0, %0"
2501 [(set_attr "type" "alu1")
2502 (set_attr "mode" "<MODE>")
2503 (set_attr "length_immediate" "0")])
2504
2505 (define_insn "*mov<mode>_extv_1"
2506 [(set (match_operand:SWI24 0 "register_operand" "=R")
2507 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2508 (const_int 8)
2509 (const_int 8)))]
2510 ""
2511 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2512 [(set_attr "type" "imovx")
2513 (set_attr "mode" "SI")])
2514
2515 (define_insn "*movqi_extv_1"
2516 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2517 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2518 (const_int 8)
2519 (const_int 8)))]
2520 ""
2521 {
2522 switch (get_attr_type (insn))
2523 {
2524 case TYPE_IMOVX:
2525 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2526 default:
2527 return "mov{b}\t{%h1, %0|%0, %h1}";
2528 }
2529 }
2530 [(set_attr "isa" "*,*,nox64")
2531 (set (attr "type")
2532 (if_then_else (and (match_operand:QI 0 "register_operand")
2533 (ior (not (match_operand:QI 0 "QIreg_operand"))
2534 (match_test "TARGET_MOVX")))
2535 (const_string "imovx")
2536 (const_string "imov")))
2537 (set (attr "mode")
2538 (if_then_else (eq_attr "type" "imovx")
2539 (const_string "SI")
2540 (const_string "QI")))])
2541
2542 (define_insn "*mov<mode>_extzv_1"
2543 [(set (match_operand:SWI48 0 "register_operand" "=R")
2544 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2545 (const_int 8)
2546 (const_int 8)))]
2547 ""
2548 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2549 [(set_attr "type" "imovx")
2550 (set_attr "mode" "SI")])
2551
2552 (define_insn "*movqi_extzv_2"
2553 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2554 (subreg:QI
2555 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2556 (const_int 8)
2557 (const_int 8)) 0))]
2558 ""
2559 {
2560 switch (get_attr_type (insn))
2561 {
2562 case TYPE_IMOVX:
2563 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2564 default:
2565 return "mov{b}\t{%h1, %0|%0, %h1}";
2566 }
2567 }
2568 [(set_attr "isa" "*,*,nox64")
2569 (set (attr "type")
2570 (if_then_else (and (match_operand:QI 0 "register_operand")
2571 (ior (not (match_operand:QI 0 "QIreg_operand"))
2572 (match_test "TARGET_MOVX")))
2573 (const_string "imovx")
2574 (const_string "imov")))
2575 (set (attr "mode")
2576 (if_then_else (eq_attr "type" "imovx")
2577 (const_string "SI")
2578 (const_string "QI")))])
2579
2580 (define_insn "mov<mode>_insv_1"
2581 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2582 (const_int 8)
2583 (const_int 8))
2584 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2585 ""
2586 {
2587 if (CONST_INT_P (operands[1]))
2588 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2589 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2590 }
2591 [(set_attr "isa" "*,nox64")
2592 (set_attr "type" "imov")
2593 (set_attr "mode" "QI")])
2594
2595 (define_insn "*movqi_insv_2"
2596 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2597 (const_int 8)
2598 (const_int 8))
2599 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2600 (const_int 8)))]
2601 ""
2602 "mov{b}\t{%h1, %h0|%h0, %h1}"
2603 [(set_attr "type" "imov")
2604 (set_attr "mode" "QI")])
2605 \f
2606 ;; Floating point push instructions.
2607
2608 (define_insn "*pushtf"
2609 [(set (match_operand:TF 0 "push_operand" "=<,<")
2610 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2611 "TARGET_64BIT || TARGET_SSE"
2612 {
2613 /* This insn should be already split before reg-stack. */
2614 gcc_unreachable ();
2615 }
2616 [(set_attr "isa" "*,x64")
2617 (set_attr "type" "multi")
2618 (set_attr "unit" "sse,*")
2619 (set_attr "mode" "TF,DI")])
2620
2621 ;; %%% Kill this when call knows how to work this out.
2622 (define_split
2623 [(set (match_operand:TF 0 "push_operand")
2624 (match_operand:TF 1 "sse_reg_operand"))]
2625 "TARGET_SSE && reload_completed"
2626 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2627 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2628
2629 (define_insn "*pushxf"
2630 [(set (match_operand:XF 0 "push_operand" "=<,<")
2631 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2632 ""
2633 {
2634 /* This insn should be already split before reg-stack. */
2635 gcc_unreachable ();
2636 }
2637 [(set_attr "type" "multi")
2638 (set_attr "unit" "i387,*")
2639 (set (attr "mode")
2640 (cond [(eq_attr "alternative" "1")
2641 (if_then_else (match_test "TARGET_64BIT")
2642 (const_string "DI")
2643 (const_string "SI"))
2644 ]
2645 (const_string "XF")))])
2646
2647 ;; %%% Kill this when call knows how to work this out.
2648 (define_split
2649 [(set (match_operand:XF 0 "push_operand")
2650 (match_operand:XF 1 "fp_register_operand"))]
2651 "reload_completed"
2652 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2653 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2654 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2655
2656 (define_insn "*pushdf"
2657 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2658 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2659 ""
2660 {
2661 /* This insn should be already split before reg-stack. */
2662 gcc_unreachable ();
2663 }
2664 [(set_attr "isa" "*,nox64,x64,sse2")
2665 (set_attr "type" "multi")
2666 (set_attr "unit" "i387,*,*,sse")
2667 (set_attr "mode" "DF,SI,DI,DF")])
2668
2669 ;; %%% Kill this when call knows how to work this out.
2670 (define_split
2671 [(set (match_operand:DF 0 "push_operand")
2672 (match_operand:DF 1 "any_fp_register_operand"))]
2673 "reload_completed"
2674 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2675 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2676
2677 (define_insn "*pushsf_rex64"
2678 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2679 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2680 "TARGET_64BIT"
2681 {
2682 /* Anything else should be already split before reg-stack. */
2683 gcc_assert (which_alternative == 1);
2684 return "push{q}\t%q1";
2685 }
2686 [(set_attr "type" "multi,push,multi")
2687 (set_attr "unit" "i387,*,*")
2688 (set_attr "mode" "SF,DI,SF")])
2689
2690 (define_insn "*pushsf"
2691 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2692 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2693 "!TARGET_64BIT"
2694 {
2695 /* Anything else should be already split before reg-stack. */
2696 gcc_assert (which_alternative == 1);
2697 return "push{l}\t%1";
2698 }
2699 [(set_attr "type" "multi,push,multi")
2700 (set_attr "unit" "i387,*,*")
2701 (set_attr "mode" "SF,SI,SF")])
2702
2703 ;; %%% Kill this when call knows how to work this out.
2704 (define_split
2705 [(set (match_operand:SF 0 "push_operand")
2706 (match_operand:SF 1 "any_fp_register_operand"))]
2707 "reload_completed"
2708 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2709 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2710 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2711
2712 (define_split
2713 [(set (match_operand:SF 0 "push_operand")
2714 (match_operand:SF 1 "memory_operand"))]
2715 "reload_completed
2716 && (operands[2] = find_constant_src (insn))"
2717 [(set (match_dup 0) (match_dup 2))])
2718
2719 (define_split
2720 [(set (match_operand 0 "push_operand")
2721 (match_operand 1 "general_operand"))]
2722 "reload_completed
2723 && (GET_MODE (operands[0]) == TFmode
2724 || GET_MODE (operands[0]) == XFmode
2725 || GET_MODE (operands[0]) == DFmode)
2726 && !ANY_FP_REG_P (operands[1])"
2727 [(const_int 0)]
2728 "ix86_split_long_move (operands); DONE;")
2729 \f
2730 ;; Floating point move instructions.
2731
2732 (define_expand "movtf"
2733 [(set (match_operand:TF 0 "nonimmediate_operand")
2734 (match_operand:TF 1 "nonimmediate_operand"))]
2735 "TARGET_64BIT || TARGET_SSE"
2736 "ix86_expand_move (TFmode, operands); DONE;")
2737
2738 (define_expand "mov<mode>"
2739 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2740 (match_operand:X87MODEF 1 "general_operand"))]
2741 ""
2742 "ix86_expand_move (<MODE>mode, operands); DONE;")
2743
2744 (define_insn "*movtf_internal"
2745 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2746 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2747 "(TARGET_64BIT || TARGET_SSE)
2748 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2749 && (!can_create_pseudo_p ()
2750 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2751 || GET_CODE (operands[1]) != CONST_DOUBLE
2752 || (optimize_function_for_size_p (cfun)
2753 && standard_sse_constant_p (operands[1])
2754 && !memory_operand (operands[0], TFmode))
2755 || (!TARGET_MEMORY_MISMATCH_STALL
2756 && memory_operand (operands[0], TFmode)))"
2757 {
2758 switch (get_attr_type (insn))
2759 {
2760 case TYPE_SSELOG1:
2761 return standard_sse_constant_opcode (insn, operands[1]);
2762
2763 case TYPE_SSEMOV:
2764 /* Handle misaligned load/store since we
2765 don't have movmisaligntf pattern. */
2766 if (misaligned_operand (operands[0], TFmode)
2767 || misaligned_operand (operands[1], TFmode))
2768 {
2769 if (get_attr_mode (insn) == MODE_V4SF)
2770 return "%vmovups\t{%1, %0|%0, %1}";
2771 else
2772 return "%vmovdqu\t{%1, %0|%0, %1}";
2773 }
2774 else
2775 {
2776 if (get_attr_mode (insn) == MODE_V4SF)
2777 return "%vmovaps\t{%1, %0|%0, %1}";
2778 else
2779 return "%vmovdqa\t{%1, %0|%0, %1}";
2780 }
2781
2782 case TYPE_MULTI:
2783 return "#";
2784
2785 default:
2786 gcc_unreachable ();
2787 }
2788 }
2789 [(set_attr "isa" "*,*,*,x64,x64")
2790 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2791 (set (attr "prefix")
2792 (if_then_else (eq_attr "type" "sselog1,ssemov")
2793 (const_string "maybe_vex")
2794 (const_string "orig")))
2795 (set (attr "mode")
2796 (cond [(eq_attr "alternative" "3,4")
2797 (const_string "DI")
2798 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2799 (const_string "V4SF")
2800 (and (eq_attr "alternative" "2")
2801 (match_test "TARGET_SSE_TYPELESS_STORES"))
2802 (const_string "V4SF")
2803 (match_test "TARGET_AVX")
2804 (const_string "TI")
2805 (ior (not (match_test "TARGET_SSE2"))
2806 (match_test "optimize_function_for_size_p (cfun)"))
2807 (const_string "V4SF")
2808 ]
2809 (const_string "TI")))])
2810
2811 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2812 (define_insn "*movxf_internal"
2813 [(set (match_operand:XF 0 "nonimmediate_operand"
2814 "=f,m,f,?Yx*r ,!o ,!o")
2815 (match_operand:XF 1 "general_operand"
2816 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2817 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2818 && (!can_create_pseudo_p ()
2819 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2820 || GET_CODE (operands[1]) != CONST_DOUBLE
2821 || (optimize_function_for_size_p (cfun)
2822 && standard_80387_constant_p (operands[1]) > 0
2823 && !memory_operand (operands[0], XFmode))
2824 || (!TARGET_MEMORY_MISMATCH_STALL
2825 && memory_operand (operands[0], XFmode)))"
2826 {
2827 switch (get_attr_type (insn))
2828 {
2829 case TYPE_FMOV:
2830 if (which_alternative == 2)
2831 return standard_80387_constant_opcode (operands[1]);
2832 return output_387_reg_move (insn, operands);
2833
2834 case TYPE_MULTI:
2835 return "#";
2836
2837 default:
2838 gcc_unreachable ();
2839 }
2840 }
2841 [(set_attr "isa" "*,*,*,*,nox64,x64")
2842 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2843 (set (attr "mode")
2844 (cond [(eq_attr "alternative" "3,4,5")
2845 (if_then_else (match_test "TARGET_64BIT")
2846 (const_string "DI")
2847 (const_string "SI"))
2848 ]
2849 (const_string "XF")))])
2850
2851 ;; Possible store forwarding (partial memory) stall in alternative 4.
2852 (define_insn "*movdf_internal"
2853 [(set (match_operand:DF 0 "nonimmediate_operand"
2854 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2855 (match_operand:DF 1 "general_operand"
2856 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2857 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2858 && (!can_create_pseudo_p ()
2859 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2860 || GET_CODE (operands[1]) != CONST_DOUBLE
2861 || (optimize_function_for_size_p (cfun)
2862 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2863 && standard_80387_constant_p (operands[1]) > 0)
2864 || (TARGET_SSE2 && TARGET_SSE_MATH
2865 && standard_sse_constant_p (operands[1])))
2866 && !memory_operand (operands[0], DFmode))
2867 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2868 && memory_operand (operands[0], DFmode)))"
2869 {
2870 switch (get_attr_type (insn))
2871 {
2872 case TYPE_FMOV:
2873 if (which_alternative == 2)
2874 return standard_80387_constant_opcode (operands[1]);
2875 return output_387_reg_move (insn, operands);
2876
2877 case TYPE_MULTI:
2878 return "#";
2879
2880 case TYPE_IMOV:
2881 if (get_attr_mode (insn) == MODE_SI)
2882 return "mov{l}\t{%1, %k0|%k0, %1}";
2883 else if (which_alternative == 8)
2884 return "movabs{q}\t{%1, %0|%0, %1}";
2885 else
2886 return "mov{q}\t{%1, %0|%0, %1}";
2887
2888 case TYPE_SSELOG1:
2889 return standard_sse_constant_opcode (insn, operands[1]);
2890
2891 case TYPE_SSEMOV:
2892 switch (get_attr_mode (insn))
2893 {
2894 case MODE_DF:
2895 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2896 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2897 return "%vmovsd\t{%1, %0|%0, %1}";
2898
2899 case MODE_V4SF:
2900 return "%vmovaps\t{%1, %0|%0, %1}";
2901 case MODE_V8DF:
2902 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2903 case MODE_V2DF:
2904 return "%vmovapd\t{%1, %0|%0, %1}";
2905
2906 case MODE_V2SF:
2907 gcc_assert (!TARGET_AVX);
2908 return "movlps\t{%1, %0|%0, %1}";
2909 case MODE_V1DF:
2910 gcc_assert (!TARGET_AVX);
2911 return "movlpd\t{%1, %0|%0, %1}";
2912
2913 case MODE_DI:
2914 /* Handle broken assemblers that require movd instead of movq. */
2915 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2916 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2917 return "%vmovd\t{%1, %0|%0, %1}";
2918 return "%vmovq\t{%1, %0|%0, %1}";
2919
2920 default:
2921 gcc_unreachable ();
2922 }
2923
2924 default:
2925 gcc_unreachable ();
2926 }
2927 }
2928 [(set (attr "isa")
2929 (cond [(eq_attr "alternative" "3,4")
2930 (const_string "nox64")
2931 (eq_attr "alternative" "5,6,7,8,17,18")
2932 (const_string "x64")
2933 (eq_attr "alternative" "9,10,11,12")
2934 (const_string "sse2")
2935 ]
2936 (const_string "*")))
2937 (set (attr "type")
2938 (cond [(eq_attr "alternative" "0,1,2")
2939 (const_string "fmov")
2940 (eq_attr "alternative" "3,4")
2941 (const_string "multi")
2942 (eq_attr "alternative" "5,6,7,8")
2943 (const_string "imov")
2944 (eq_attr "alternative" "9,13")
2945 (const_string "sselog1")
2946 ]
2947 (const_string "ssemov")))
2948 (set (attr "modrm")
2949 (if_then_else (eq_attr "alternative" "8")
2950 (const_string "0")
2951 (const_string "*")))
2952 (set (attr "length_immediate")
2953 (if_then_else (eq_attr "alternative" "8")
2954 (const_string "8")
2955 (const_string "*")))
2956 (set (attr "prefix")
2957 (if_then_else (eq_attr "type" "sselog1,ssemov")
2958 (const_string "maybe_vex")
2959 (const_string "orig")))
2960 (set (attr "prefix_data16")
2961 (if_then_else
2962 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2963 (eq_attr "mode" "V1DF"))
2964 (const_string "1")
2965 (const_string "*")))
2966 (set (attr "mode")
2967 (cond [(eq_attr "alternative" "3,4,7")
2968 (const_string "SI")
2969 (eq_attr "alternative" "5,6,8,17,18")
2970 (const_string "DI")
2971
2972 /* xorps is one byte shorter for non-AVX targets. */
2973 (eq_attr "alternative" "9,13")
2974 (cond [(not (match_test "TARGET_SSE2"))
2975 (const_string "V4SF")
2976 (match_test "TARGET_AVX512F")
2977 (const_string "XI")
2978 (match_test "TARGET_AVX")
2979 (const_string "V2DF")
2980 (match_test "optimize_function_for_size_p (cfun)")
2981 (const_string "V4SF")
2982 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2983 (const_string "TI")
2984 ]
2985 (const_string "V2DF"))
2986
2987 /* For architectures resolving dependencies on
2988 whole SSE registers use movapd to break dependency
2989 chains, otherwise use short move to avoid extra work. */
2990
2991 /* movaps is one byte shorter for non-AVX targets. */
2992 (eq_attr "alternative" "10,14")
2993 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2994 (match_operand 1 "ext_sse_reg_operand"))
2995 (const_string "V8DF")
2996 (ior (not (match_test "TARGET_SSE2"))
2997 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2998 (const_string "V4SF")
2999 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3000 (const_string "V2DF")
3001 (match_test "TARGET_AVX")
3002 (const_string "DF")
3003 (match_test "optimize_function_for_size_p (cfun)")
3004 (const_string "V4SF")
3005 ]
3006 (const_string "DF"))
3007
3008 /* For architectures resolving dependencies on register
3009 parts we may avoid extra work to zero out upper part
3010 of register. */
3011 (eq_attr "alternative" "11,15")
3012 (cond [(not (match_test "TARGET_SSE2"))
3013 (const_string "V2SF")
3014 (match_test "TARGET_AVX")
3015 (const_string "DF")
3016 (match_test "TARGET_SSE_SPLIT_REGS")
3017 (const_string "V1DF")
3018 ]
3019 (const_string "DF"))
3020
3021 (and (eq_attr "alternative" "12,16")
3022 (not (match_test "TARGET_SSE2")))
3023 (const_string "V2SF")
3024 ]
3025 (const_string "DF")))])
3026
3027 (define_insn "*movsf_internal"
3028 [(set (match_operand:SF 0 "nonimmediate_operand"
3029 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3030 (match_operand:SF 1 "general_operand"
3031 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3032 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3033 && (!can_create_pseudo_p ()
3034 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3035 || GET_CODE (operands[1]) != CONST_DOUBLE
3036 || (optimize_function_for_size_p (cfun)
3037 && ((!TARGET_SSE_MATH
3038 && standard_80387_constant_p (operands[1]) > 0)
3039 || (TARGET_SSE_MATH
3040 && standard_sse_constant_p (operands[1]))))
3041 || memory_operand (operands[0], SFmode))"
3042 {
3043 switch (get_attr_type (insn))
3044 {
3045 case TYPE_FMOV:
3046 if (which_alternative == 2)
3047 return standard_80387_constant_opcode (operands[1]);
3048 return output_387_reg_move (insn, operands);
3049
3050 case TYPE_IMOV:
3051 return "mov{l}\t{%1, %0|%0, %1}";
3052
3053 case TYPE_SSELOG1:
3054 return standard_sse_constant_opcode (insn, operands[1]);
3055
3056 case TYPE_SSEMOV:
3057 switch (get_attr_mode (insn))
3058 {
3059 case MODE_SF:
3060 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3061 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3062 return "%vmovss\t{%1, %0|%0, %1}";
3063
3064 case MODE_V16SF:
3065 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3066 case MODE_V4SF:
3067 return "%vmovaps\t{%1, %0|%0, %1}";
3068
3069 case MODE_SI:
3070 return "%vmovd\t{%1, %0|%0, %1}";
3071
3072 default:
3073 gcc_unreachable ();
3074 }
3075
3076 case TYPE_MMXMOV:
3077 switch (get_attr_mode (insn))
3078 {
3079 case MODE_DI:
3080 return "movq\t{%1, %0|%0, %1}";
3081 case MODE_SI:
3082 return "movd\t{%1, %0|%0, %1}";
3083
3084 default:
3085 gcc_unreachable ();
3086 }
3087
3088 default:
3089 gcc_unreachable ();
3090 }
3091 }
3092 [(set (attr "type")
3093 (cond [(eq_attr "alternative" "0,1,2")
3094 (const_string "fmov")
3095 (eq_attr "alternative" "3,4")
3096 (const_string "imov")
3097 (eq_attr "alternative" "5")
3098 (const_string "sselog1")
3099 (eq_attr "alternative" "11,12,13,14,15")
3100 (const_string "mmxmov")
3101 ]
3102 (const_string "ssemov")))
3103 (set (attr "prefix")
3104 (if_then_else (eq_attr "type" "sselog1,ssemov")
3105 (const_string "maybe_vex")
3106 (const_string "orig")))
3107 (set (attr "prefix_data16")
3108 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3109 (const_string "1")
3110 (const_string "*")))
3111 (set (attr "mode")
3112 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
3113 (const_string "SI")
3114 (eq_attr "alternative" "11")
3115 (const_string "DI")
3116 (eq_attr "alternative" "5")
3117 (cond [(not (match_test "TARGET_SSE2"))
3118 (const_string "V4SF")
3119 (match_test "TARGET_AVX512F")
3120 (const_string "V16SF")
3121 (match_test "TARGET_AVX")
3122 (const_string "V4SF")
3123 (match_test "optimize_function_for_size_p (cfun)")
3124 (const_string "V4SF")
3125 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3126 (const_string "TI")
3127 ]
3128 (const_string "V4SF"))
3129
3130 /* For architectures resolving dependencies on
3131 whole SSE registers use APS move to break dependency
3132 chains, otherwise use short move to avoid extra work.
3133
3134 Do the same for architectures resolving dependencies on
3135 the parts. While in DF mode it is better to always handle
3136 just register parts, the SF mode is different due to lack
3137 of instructions to load just part of the register. It is
3138 better to maintain the whole registers in single format
3139 to avoid problems on using packed logical operations. */
3140 (eq_attr "alternative" "6")
3141 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3142 (match_operand 1 "ext_sse_reg_operand"))
3143 (const_string "V16SF")
3144 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3145 (match_test "TARGET_SSE_SPLIT_REGS"))
3146 (const_string "V4SF")
3147 ]
3148 (const_string "SF"))
3149 ]
3150 (const_string "SF")))])
3151
3152 (define_split
3153 [(set (match_operand 0 "any_fp_register_operand")
3154 (match_operand 1 "memory_operand"))]
3155 "reload_completed
3156 && (GET_MODE (operands[0]) == TFmode
3157 || GET_MODE (operands[0]) == XFmode
3158 || GET_MODE (operands[0]) == DFmode
3159 || GET_MODE (operands[0]) == SFmode)
3160 && (operands[2] = find_constant_src (insn))"
3161 [(set (match_dup 0) (match_dup 2))]
3162 {
3163 rtx c = operands[2];
3164 int r = REGNO (operands[0]);
3165
3166 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3167 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3168 FAIL;
3169 })
3170
3171 (define_split
3172 [(set (match_operand 0 "any_fp_register_operand")
3173 (float_extend (match_operand 1 "memory_operand")))]
3174 "reload_completed
3175 && (GET_MODE (operands[0]) == TFmode
3176 || GET_MODE (operands[0]) == XFmode
3177 || GET_MODE (operands[0]) == DFmode)
3178 && (operands[2] = find_constant_src (insn))"
3179 [(set (match_dup 0) (match_dup 2))]
3180 {
3181 rtx c = operands[2];
3182 int r = REGNO (operands[0]);
3183
3184 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3185 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3186 FAIL;
3187 })
3188
3189 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3190 (define_split
3191 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3192 (match_operand:X87MODEF 1 "immediate_operand"))]
3193 "reload_completed
3194 && (standard_80387_constant_p (operands[1]) == 8
3195 || standard_80387_constant_p (operands[1]) == 9)"
3196 [(set (match_dup 0)(match_dup 1))
3197 (set (match_dup 0)
3198 (neg:X87MODEF (match_dup 0)))]
3199 {
3200 REAL_VALUE_TYPE r;
3201
3202 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3203 if (real_isnegzero (&r))
3204 operands[1] = CONST0_RTX (<MODE>mode);
3205 else
3206 operands[1] = CONST1_RTX (<MODE>mode);
3207 })
3208
3209 (define_split
3210 [(set (match_operand 0 "nonimmediate_operand")
3211 (match_operand 1 "general_operand"))]
3212 "reload_completed
3213 && (GET_MODE (operands[0]) == TFmode
3214 || GET_MODE (operands[0]) == XFmode
3215 || GET_MODE (operands[0]) == DFmode)
3216 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3217 [(const_int 0)]
3218 "ix86_split_long_move (operands); DONE;")
3219
3220 (define_insn "swapxf"
3221 [(set (match_operand:XF 0 "register_operand" "+f")
3222 (match_operand:XF 1 "register_operand" "+f"))
3223 (set (match_dup 1)
3224 (match_dup 0))]
3225 "TARGET_80387"
3226 {
3227 if (STACK_TOP_P (operands[0]))
3228 return "fxch\t%1";
3229 else
3230 return "fxch\t%0";
3231 }
3232 [(set_attr "type" "fxch")
3233 (set_attr "mode" "XF")])
3234
3235 (define_insn "*swap<mode>"
3236 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3237 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3238 (set (match_dup 1)
3239 (match_dup 0))]
3240 "TARGET_80387 || reload_completed"
3241 {
3242 if (STACK_TOP_P (operands[0]))
3243 return "fxch\t%1";
3244 else
3245 return "fxch\t%0";
3246 }
3247 [(set_attr "type" "fxch")
3248 (set_attr "mode" "<MODE>")])
3249 \f
3250 ;; Zero extension instructions
3251
3252 (define_expand "zero_extendsidi2"
3253 [(set (match_operand:DI 0 "nonimmediate_operand")
3254 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3255
3256 (define_insn "*zero_extendsidi2"
3257 [(set (match_operand:DI 0 "nonimmediate_operand"
3258 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3259 (zero_extend:DI
3260 (match_operand:SI 1 "x86_64_zext_operand"
3261 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3262 ""
3263 {
3264 switch (get_attr_type (insn))
3265 {
3266 case TYPE_IMOVX:
3267 if (ix86_use_lea_for_mov (insn, operands))
3268 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3269 else
3270 return "mov{l}\t{%1, %k0|%k0, %1}";
3271
3272 case TYPE_MULTI:
3273 return "#";
3274
3275 case TYPE_MMXMOV:
3276 return "movd\t{%1, %0|%0, %1}";
3277
3278 case TYPE_SSELOG1:
3279 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3280
3281 case TYPE_SSEMOV:
3282 if (GENERAL_REG_P (operands[0]))
3283 return "%vmovd\t{%1, %k0|%k0, %1}";
3284
3285 return "%vmovd\t{%1, %0|%0, %1}";
3286
3287 default:
3288 gcc_unreachable ();
3289 }
3290 }
3291 [(set (attr "isa")
3292 (cond [(eq_attr "alternative" "0,1,2")
3293 (const_string "nox64")
3294 (eq_attr "alternative" "3,7")
3295 (const_string "x64")
3296 (eq_attr "alternative" "8")
3297 (const_string "x64_sse4")
3298 (eq_attr "alternative" "10")
3299 (const_string "sse2")
3300 ]
3301 (const_string "*")))
3302 (set (attr "type")
3303 (cond [(eq_attr "alternative" "0,1,2,4")
3304 (const_string "multi")
3305 (eq_attr "alternative" "5,6")
3306 (const_string "mmxmov")
3307 (eq_attr "alternative" "7,9,10")
3308 (const_string "ssemov")
3309 (eq_attr "alternative" "8")
3310 (const_string "sselog1")
3311 ]
3312 (const_string "imovx")))
3313 (set (attr "prefix_extra")
3314 (if_then_else (eq_attr "alternative" "8")
3315 (const_string "1")
3316 (const_string "*")))
3317 (set (attr "length_immediate")
3318 (if_then_else (eq_attr "alternative" "8")
3319 (const_string "1")
3320 (const_string "*")))
3321 (set (attr "prefix")
3322 (if_then_else (eq_attr "type" "ssemov,sselog1")
3323 (const_string "maybe_vex")
3324 (const_string "orig")))
3325 (set (attr "prefix_0f")
3326 (if_then_else (eq_attr "type" "imovx")
3327 (const_string "0")
3328 (const_string "*")))
3329 (set (attr "mode")
3330 (cond [(eq_attr "alternative" "5,6")
3331 (const_string "DI")
3332 (eq_attr "alternative" "7,8,9")
3333 (const_string "TI")
3334 ]
3335 (const_string "SI")))])
3336
3337 (define_split
3338 [(set (match_operand:DI 0 "memory_operand")
3339 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3340 "reload_completed"
3341 [(set (match_dup 4) (const_int 0))]
3342 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3343
3344 (define_split
3345 [(set (match_operand:DI 0 "register_operand")
3346 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3347 "!TARGET_64BIT && reload_completed
3348 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3349 && true_regnum (operands[0]) == true_regnum (operands[1])"
3350 [(set (match_dup 4) (const_int 0))]
3351 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3352
3353 (define_split
3354 [(set (match_operand:DI 0 "nonimmediate_operand")
3355 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3356 "!TARGET_64BIT && reload_completed
3357 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3358 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3359 [(set (match_dup 3) (match_dup 1))
3360 (set (match_dup 4) (const_int 0))]
3361 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3362
3363 (define_insn "zero_extend<mode>di2"
3364 [(set (match_operand:DI 0 "register_operand" "=r")
3365 (zero_extend:DI
3366 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3367 "TARGET_64BIT"
3368 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")])
3371
3372 (define_expand "zero_extend<mode>si2"
3373 [(set (match_operand:SI 0 "register_operand")
3374 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3375 ""
3376 {
3377 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3378 {
3379 operands[1] = force_reg (<MODE>mode, operands[1]);
3380 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3381 DONE;
3382 }
3383 })
3384
3385 (define_insn_and_split "zero_extend<mode>si2_and"
3386 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3387 (zero_extend:SI
3388 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3389 (clobber (reg:CC FLAGS_REG))]
3390 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3391 "#"
3392 "&& reload_completed"
3393 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3394 (clobber (reg:CC FLAGS_REG))])]
3395 {
3396 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3397 {
3398 ix86_expand_clear (operands[0]);
3399
3400 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3401 emit_insn (gen_movstrict<mode>
3402 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3403 DONE;
3404 }
3405
3406 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3407 }
3408 [(set_attr "type" "alu1")
3409 (set_attr "mode" "SI")])
3410
3411 (define_insn "*zero_extend<mode>si2"
3412 [(set (match_operand:SI 0 "register_operand" "=r")
3413 (zero_extend:SI
3414 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3415 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3416 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3417 [(set_attr "type" "imovx")
3418 (set_attr "mode" "SI")])
3419
3420 (define_expand "zero_extendqihi2"
3421 [(set (match_operand:HI 0 "register_operand")
3422 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3423 ""
3424 {
3425 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3426 {
3427 operands[1] = force_reg (QImode, operands[1]);
3428 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3429 DONE;
3430 }
3431 })
3432
3433 (define_insn_and_split "zero_extendqihi2_and"
3434 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3435 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3436 (clobber (reg:CC FLAGS_REG))]
3437 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3438 "#"
3439 "&& reload_completed"
3440 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3441 (clobber (reg:CC FLAGS_REG))])]
3442 {
3443 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3444 {
3445 ix86_expand_clear (operands[0]);
3446
3447 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3448 emit_insn (gen_movstrictqi
3449 (gen_lowpart (QImode, operands[0]), operands[1]));
3450 DONE;
3451 }
3452
3453 operands[0] = gen_lowpart (SImode, operands[0]);
3454 }
3455 [(set_attr "type" "alu1")
3456 (set_attr "mode" "SI")])
3457
3458 ; zero extend to SImode to avoid partial register stalls
3459 (define_insn "*zero_extendqihi2"
3460 [(set (match_operand:HI 0 "register_operand" "=r")
3461 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3462 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3463 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3464 [(set_attr "type" "imovx")
3465 (set_attr "mode" "SI")])
3466 \f
3467 ;; Sign extension instructions
3468
3469 (define_expand "extendsidi2"
3470 [(set (match_operand:DI 0 "register_operand")
3471 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3472 ""
3473 {
3474 if (!TARGET_64BIT)
3475 {
3476 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3477 DONE;
3478 }
3479 })
3480
3481 (define_insn "*extendsidi2_rex64"
3482 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3483 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3484 "TARGET_64BIT"
3485 "@
3486 {cltq|cdqe}
3487 movs{lq|x}\t{%1, %0|%0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "DI")
3490 (set_attr "prefix_0f" "0")
3491 (set_attr "modrm" "0,1")])
3492
3493 (define_insn "extendsidi2_1"
3494 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496 (clobber (reg:CC FLAGS_REG))
3497 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3498 "!TARGET_64BIT"
3499 "#")
3500
3501 ;; Split the memory case. If the source register doesn't die, it will stay
3502 ;; this way, if it does die, following peephole2s take care of it.
3503 (define_split
3504 [(set (match_operand:DI 0 "memory_operand")
3505 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3506 (clobber (reg:CC FLAGS_REG))
3507 (clobber (match_operand:SI 2 "register_operand"))]
3508 "reload_completed"
3509 [(const_int 0)]
3510 {
3511 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3512
3513 emit_move_insn (operands[3], operands[1]);
3514
3515 /* Generate a cltd if possible and doing so it profitable. */
3516 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3517 && true_regnum (operands[1]) == AX_REG
3518 && true_regnum (operands[2]) == DX_REG)
3519 {
3520 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3521 }
3522 else
3523 {
3524 emit_move_insn (operands[2], operands[1]);
3525 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3526 }
3527 emit_move_insn (operands[4], operands[2]);
3528 DONE;
3529 })
3530
3531 ;; Peepholes for the case where the source register does die, after
3532 ;; being split with the above splitter.
3533 (define_peephole2
3534 [(set (match_operand:SI 0 "memory_operand")
3535 (match_operand:SI 1 "register_operand"))
3536 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3537 (parallel [(set (match_dup 2)
3538 (ashiftrt:SI (match_dup 2) (const_int 31)))
3539 (clobber (reg:CC FLAGS_REG))])
3540 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3541 "REGNO (operands[1]) != REGNO (operands[2])
3542 && peep2_reg_dead_p (2, operands[1])
3543 && peep2_reg_dead_p (4, operands[2])
3544 && !reg_mentioned_p (operands[2], operands[3])"
3545 [(set (match_dup 0) (match_dup 1))
3546 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3547 (clobber (reg:CC FLAGS_REG))])
3548 (set (match_dup 3) (match_dup 1))])
3549
3550 (define_peephole2
3551 [(set (match_operand:SI 0 "memory_operand")
3552 (match_operand:SI 1 "register_operand"))
3553 (parallel [(set (match_operand:SI 2 "register_operand")
3554 (ashiftrt:SI (match_dup 1) (const_int 31)))
3555 (clobber (reg:CC FLAGS_REG))])
3556 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3557 "/* cltd is shorter than sarl $31, %eax */
3558 !optimize_function_for_size_p (cfun)
3559 && true_regnum (operands[1]) == AX_REG
3560 && true_regnum (operands[2]) == DX_REG
3561 && peep2_reg_dead_p (2, operands[1])
3562 && peep2_reg_dead_p (3, operands[2])
3563 && !reg_mentioned_p (operands[2], operands[3])"
3564 [(set (match_dup 0) (match_dup 1))
3565 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3566 (clobber (reg:CC FLAGS_REG))])
3567 (set (match_dup 3) (match_dup 1))])
3568
3569 ;; Extend to register case. Optimize case where source and destination
3570 ;; registers match and cases where we can use cltd.
3571 (define_split
3572 [(set (match_operand:DI 0 "register_operand")
3573 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3574 (clobber (reg:CC FLAGS_REG))
3575 (clobber (match_scratch:SI 2))]
3576 "reload_completed"
3577 [(const_int 0)]
3578 {
3579 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3580
3581 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3582 emit_move_insn (operands[3], operands[1]);
3583
3584 /* Generate a cltd if possible and doing so it profitable. */
3585 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3586 && true_regnum (operands[3]) == AX_REG
3587 && true_regnum (operands[4]) == DX_REG)
3588 {
3589 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3590 DONE;
3591 }
3592
3593 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3594 emit_move_insn (operands[4], operands[1]);
3595
3596 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3597 DONE;
3598 })
3599
3600 (define_insn "extend<mode>di2"
3601 [(set (match_operand:DI 0 "register_operand" "=r")
3602 (sign_extend:DI
3603 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3604 "TARGET_64BIT"
3605 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3606 [(set_attr "type" "imovx")
3607 (set_attr "mode" "DI")])
3608
3609 (define_insn "extendhisi2"
3610 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3611 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3612 ""
3613 {
3614 switch (get_attr_prefix_0f (insn))
3615 {
3616 case 0:
3617 return "{cwtl|cwde}";
3618 default:
3619 return "movs{wl|x}\t{%1, %0|%0, %1}";
3620 }
3621 }
3622 [(set_attr "type" "imovx")
3623 (set_attr "mode" "SI")
3624 (set (attr "prefix_0f")
3625 ;; movsx is short decodable while cwtl is vector decoded.
3626 (if_then_else (and (eq_attr "cpu" "!k6")
3627 (eq_attr "alternative" "0"))
3628 (const_string "0")
3629 (const_string "1")))
3630 (set (attr "modrm")
3631 (if_then_else (eq_attr "prefix_0f" "0")
3632 (const_string "0")
3633 (const_string "1")))])
3634
3635 (define_insn "*extendhisi2_zext"
3636 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3637 (zero_extend:DI
3638 (sign_extend:SI
3639 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3640 "TARGET_64BIT"
3641 {
3642 switch (get_attr_prefix_0f (insn))
3643 {
3644 case 0:
3645 return "{cwtl|cwde}";
3646 default:
3647 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3648 }
3649 }
3650 [(set_attr "type" "imovx")
3651 (set_attr "mode" "SI")
3652 (set (attr "prefix_0f")
3653 ;; movsx is short decodable while cwtl is vector decoded.
3654 (if_then_else (and (eq_attr "cpu" "!k6")
3655 (eq_attr "alternative" "0"))
3656 (const_string "0")
3657 (const_string "1")))
3658 (set (attr "modrm")
3659 (if_then_else (eq_attr "prefix_0f" "0")
3660 (const_string "0")
3661 (const_string "1")))])
3662
3663 (define_insn "extendqisi2"
3664 [(set (match_operand:SI 0 "register_operand" "=r")
3665 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3666 ""
3667 "movs{bl|x}\t{%1, %0|%0, %1}"
3668 [(set_attr "type" "imovx")
3669 (set_attr "mode" "SI")])
3670
3671 (define_insn "*extendqisi2_zext"
3672 [(set (match_operand:DI 0 "register_operand" "=r")
3673 (zero_extend:DI
3674 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3675 "TARGET_64BIT"
3676 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3677 [(set_attr "type" "imovx")
3678 (set_attr "mode" "SI")])
3679
3680 (define_insn "extendqihi2"
3681 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3682 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3683 ""
3684 {
3685 switch (get_attr_prefix_0f (insn))
3686 {
3687 case 0:
3688 return "{cbtw|cbw}";
3689 default:
3690 return "movs{bw|x}\t{%1, %0|%0, %1}";
3691 }
3692 }
3693 [(set_attr "type" "imovx")
3694 (set_attr "mode" "HI")
3695 (set (attr "prefix_0f")
3696 ;; movsx is short decodable while cwtl is vector decoded.
3697 (if_then_else (and (eq_attr "cpu" "!k6")
3698 (eq_attr "alternative" "0"))
3699 (const_string "0")
3700 (const_string "1")))
3701 (set (attr "modrm")
3702 (if_then_else (eq_attr "prefix_0f" "0")
3703 (const_string "0")
3704 (const_string "1")))])
3705 \f
3706 ;; Conversions between float and double.
3707
3708 ;; These are all no-ops in the model used for the 80387.
3709 ;; So just emit moves.
3710
3711 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3712 (define_split
3713 [(set (match_operand:DF 0 "push_operand")
3714 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3715 "reload_completed"
3716 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3717 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3718
3719 (define_split
3720 [(set (match_operand:XF 0 "push_operand")
3721 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3722 "reload_completed"
3723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3724 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3725 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3726
3727 (define_expand "extendsfdf2"
3728 [(set (match_operand:DF 0 "nonimmediate_operand")
3729 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3730 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3731 {
3732 /* ??? Needed for compress_float_constant since all fp constants
3733 are TARGET_LEGITIMATE_CONSTANT_P. */
3734 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3735 {
3736 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3737 && standard_80387_constant_p (operands[1]) > 0)
3738 {
3739 operands[1] = simplify_const_unary_operation
3740 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3741 emit_move_insn_1 (operands[0], operands[1]);
3742 DONE;
3743 }
3744 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3745 }
3746 })
3747
3748 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3749 cvtss2sd:
3750 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3751 cvtps2pd xmm2,xmm1
3752 We do the conversion post reload to avoid producing of 128bit spills
3753 that might lead to ICE on 32bit target. The sequence unlikely combine
3754 anyway. */
3755 (define_split
3756 [(set (match_operand:DF 0 "register_operand")
3757 (float_extend:DF
3758 (match_operand:SF 1 "nonimmediate_operand")))]
3759 "TARGET_USE_VECTOR_FP_CONVERTS
3760 && optimize_insn_for_speed_p ()
3761 && reload_completed && SSE_REG_P (operands[0])"
3762 [(set (match_dup 2)
3763 (float_extend:V2DF
3764 (vec_select:V2SF
3765 (match_dup 3)
3766 (parallel [(const_int 0) (const_int 1)]))))]
3767 {
3768 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3769 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3770 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3771 Try to avoid move when unpacking can be done in source. */
3772 if (REG_P (operands[1]))
3773 {
3774 /* If it is unsafe to overwrite upper half of source, we need
3775 to move to destination and unpack there. */
3776 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3777 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3778 && true_regnum (operands[0]) != true_regnum (operands[1]))
3779 {
3780 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3781 emit_move_insn (tmp, operands[1]);
3782 }
3783 else
3784 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3785 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3786 operands[3]));
3787 }
3788 else
3789 emit_insn (gen_vec_setv4sf_0 (operands[3],
3790 CONST0_RTX (V4SFmode), operands[1]));
3791 })
3792
3793 ;; It's more profitable to split and then extend in the same register.
3794 (define_peephole2
3795 [(set (match_operand:DF 0 "register_operand")
3796 (float_extend:DF
3797 (match_operand:SF 1 "memory_operand")))]
3798 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3799 && optimize_insn_for_speed_p ()
3800 && SSE_REG_P (operands[0])"
3801 [(set (match_dup 2) (match_dup 1))
3802 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3803 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3804
3805 (define_insn "*extendsfdf2_mixed"
3806 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3807 (float_extend:DF
3808 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3809 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3810 {
3811 switch (which_alternative)
3812 {
3813 case 0:
3814 case 1:
3815 return output_387_reg_move (insn, operands);
3816
3817 case 2:
3818 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3819
3820 default:
3821 gcc_unreachable ();
3822 }
3823 }
3824 [(set_attr "type" "fmov,fmov,ssecvt")
3825 (set_attr "prefix" "orig,orig,maybe_vex")
3826 (set_attr "mode" "SF,XF,DF")])
3827
3828 (define_insn "*extendsfdf2_sse"
3829 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3830 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3831 "TARGET_SSE2 && TARGET_SSE_MATH"
3832 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3833 [(set_attr "type" "ssecvt")
3834 (set_attr "prefix" "maybe_vex")
3835 (set_attr "mode" "DF")])
3836
3837 (define_insn "*extendsfdf2_i387"
3838 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3839 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3840 "TARGET_80387"
3841 "* return output_387_reg_move (insn, operands);"
3842 [(set_attr "type" "fmov")
3843 (set_attr "mode" "SF,XF")])
3844
3845 (define_expand "extend<mode>xf2"
3846 [(set (match_operand:XF 0 "nonimmediate_operand")
3847 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3848 "TARGET_80387"
3849 {
3850 /* ??? Needed for compress_float_constant since all fp constants
3851 are TARGET_LEGITIMATE_CONSTANT_P. */
3852 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3853 {
3854 if (standard_80387_constant_p (operands[1]) > 0)
3855 {
3856 operands[1] = simplify_const_unary_operation
3857 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3858 emit_move_insn_1 (operands[0], operands[1]);
3859 DONE;
3860 }
3861 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3862 }
3863 })
3864
3865 (define_insn "*extend<mode>xf2_i387"
3866 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3867 (float_extend:XF
3868 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3869 "TARGET_80387"
3870 "* return output_387_reg_move (insn, operands);"
3871 [(set_attr "type" "fmov")
3872 (set_attr "mode" "<MODE>,XF")])
3873
3874 ;; %%% This seems bad bad news.
3875 ;; This cannot output into an f-reg because there is no way to be sure
3876 ;; of truncating in that case. Otherwise this is just like a simple move
3877 ;; insn. So we pretend we can output to a reg in order to get better
3878 ;; register preferencing, but we really use a stack slot.
3879
3880 ;; Conversion from DFmode to SFmode.
3881
3882 (define_expand "truncdfsf2"
3883 [(set (match_operand:SF 0 "nonimmediate_operand")
3884 (float_truncate:SF
3885 (match_operand:DF 1 "nonimmediate_operand")))]
3886 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3887 {
3888 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3889 ;
3890 else if (flag_unsafe_math_optimizations)
3891 ;
3892 else
3893 {
3894 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3895 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3896 DONE;
3897 }
3898 })
3899
3900 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3901 cvtsd2ss:
3902 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3903 cvtpd2ps xmm2,xmm1
3904 We do the conversion post reload to avoid producing of 128bit spills
3905 that might lead to ICE on 32bit target. The sequence unlikely combine
3906 anyway. */
3907 (define_split
3908 [(set (match_operand:SF 0 "register_operand")
3909 (float_truncate:SF
3910 (match_operand:DF 1 "nonimmediate_operand")))]
3911 "TARGET_USE_VECTOR_FP_CONVERTS
3912 && optimize_insn_for_speed_p ()
3913 && reload_completed && SSE_REG_P (operands[0])"
3914 [(set (match_dup 2)
3915 (vec_concat:V4SF
3916 (float_truncate:V2SF
3917 (match_dup 4))
3918 (match_dup 3)))]
3919 {
3920 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3921 operands[3] = CONST0_RTX (V2SFmode);
3922 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3923 /* Use movsd for loading from memory, unpcklpd for registers.
3924 Try to avoid move when unpacking can be done in source, or SSE3
3925 movddup is available. */
3926 if (REG_P (operands[1]))
3927 {
3928 if (!TARGET_SSE3
3929 && true_regnum (operands[0]) != true_regnum (operands[1])
3930 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3931 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3932 {
3933 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3934 emit_move_insn (tmp, operands[1]);
3935 operands[1] = tmp;
3936 }
3937 else if (!TARGET_SSE3)
3938 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3939 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3940 }
3941 else
3942 emit_insn (gen_sse2_loadlpd (operands[4],
3943 CONST0_RTX (V2DFmode), operands[1]));
3944 })
3945
3946 ;; It's more profitable to split and then extend in the same register.
3947 (define_peephole2
3948 [(set (match_operand:SF 0 "register_operand")
3949 (float_truncate:SF
3950 (match_operand:DF 1 "memory_operand")))]
3951 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3952 && optimize_insn_for_speed_p ()
3953 && SSE_REG_P (operands[0])"
3954 [(set (match_dup 2) (match_dup 1))
3955 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3956 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3957
3958 (define_expand "truncdfsf2_with_temp"
3959 [(parallel [(set (match_operand:SF 0)
3960 (float_truncate:SF (match_operand:DF 1)))
3961 (clobber (match_operand:SF 2))])])
3962
3963 (define_insn "*truncdfsf_fast_mixed"
3964 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3965 (float_truncate:SF
3966 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3967 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3968 {
3969 switch (which_alternative)
3970 {
3971 case 0:
3972 return output_387_reg_move (insn, operands);
3973 case 1:
3974 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3975 default:
3976 gcc_unreachable ();
3977 }
3978 }
3979 [(set_attr "type" "fmov,ssecvt")
3980 (set_attr "prefix" "orig,maybe_vex")
3981 (set_attr "mode" "SF")])
3982
3983 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3984 ;; because nothing we do here is unsafe.
3985 (define_insn "*truncdfsf_fast_sse"
3986 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3987 (float_truncate:SF
3988 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3989 "TARGET_SSE2 && TARGET_SSE_MATH"
3990 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3991 [(set_attr "type" "ssecvt")
3992 (set_attr "prefix" "maybe_vex")
3993 (set_attr "mode" "SF")])
3994
3995 (define_insn "*truncdfsf_fast_i387"
3996 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3997 (float_truncate:SF
3998 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3999 "TARGET_80387 && flag_unsafe_math_optimizations"
4000 "* return output_387_reg_move (insn, operands);"
4001 [(set_attr "type" "fmov")
4002 (set_attr "mode" "SF")])
4003
4004 (define_insn "*truncdfsf_mixed"
4005 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4006 (float_truncate:SF
4007 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4008 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4009 "TARGET_MIX_SSE_I387"
4010 {
4011 switch (which_alternative)
4012 {
4013 case 0:
4014 return output_387_reg_move (insn, operands);
4015 case 1:
4016 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4017
4018 default:
4019 return "#";
4020 }
4021 }
4022 [(set_attr "isa" "*,sse2,*,*,*")
4023 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4024 (set_attr "unit" "*,*,i387,i387,i387")
4025 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4026 (set_attr "mode" "SF")])
4027
4028 (define_insn "*truncdfsf_i387"
4029 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4030 (float_truncate:SF
4031 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4032 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4033 "TARGET_80387"
4034 {
4035 switch (which_alternative)
4036 {
4037 case 0:
4038 return output_387_reg_move (insn, operands);
4039
4040 default:
4041 return "#";
4042 }
4043 }
4044 [(set_attr "type" "fmov,multi,multi,multi")
4045 (set_attr "unit" "*,i387,i387,i387")
4046 (set_attr "mode" "SF")])
4047
4048 (define_insn "*truncdfsf2_i387_1"
4049 [(set (match_operand:SF 0 "memory_operand" "=m")
4050 (float_truncate:SF
4051 (match_operand:DF 1 "register_operand" "f")))]
4052 "TARGET_80387
4053 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4054 && !TARGET_MIX_SSE_I387"
4055 "* return output_387_reg_move (insn, operands);"
4056 [(set_attr "type" "fmov")
4057 (set_attr "mode" "SF")])
4058
4059 (define_split
4060 [(set (match_operand:SF 0 "register_operand")
4061 (float_truncate:SF
4062 (match_operand:DF 1 "fp_register_operand")))
4063 (clobber (match_operand 2))]
4064 "reload_completed"
4065 [(set (match_dup 2) (match_dup 1))
4066 (set (match_dup 0) (match_dup 2))]
4067 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4068
4069 ;; Conversion from XFmode to {SF,DF}mode
4070
4071 (define_expand "truncxf<mode>2"
4072 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4073 (float_truncate:MODEF
4074 (match_operand:XF 1 "register_operand")))
4075 (clobber (match_dup 2))])]
4076 "TARGET_80387"
4077 {
4078 if (flag_unsafe_math_optimizations)
4079 {
4080 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4081 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4082 if (reg != operands[0])
4083 emit_move_insn (operands[0], reg);
4084 DONE;
4085 }
4086 else
4087 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4088 })
4089
4090 (define_insn "*truncxfsf2_mixed"
4091 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4092 (float_truncate:SF
4093 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4094 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4095 "TARGET_80387"
4096 {
4097 gcc_assert (!which_alternative);
4098 return output_387_reg_move (insn, operands);
4099 }
4100 [(set_attr "type" "fmov,multi,multi,multi")
4101 (set_attr "unit" "*,i387,i387,i387")
4102 (set_attr "mode" "SF")])
4103
4104 (define_insn "*truncxfdf2_mixed"
4105 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4106 (float_truncate:DF
4107 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4108 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4109 "TARGET_80387"
4110 {
4111 gcc_assert (!which_alternative);
4112 return output_387_reg_move (insn, operands);
4113 }
4114 [(set_attr "isa" "*,*,sse2,*")
4115 (set_attr "type" "fmov,multi,multi,multi")
4116 (set_attr "unit" "*,i387,i387,i387")
4117 (set_attr "mode" "DF")])
4118
4119 (define_insn "truncxf<mode>2_i387_noop"
4120 [(set (match_operand:MODEF 0 "register_operand" "=f")
4121 (float_truncate:MODEF
4122 (match_operand:XF 1 "register_operand" "f")))]
4123 "TARGET_80387 && flag_unsafe_math_optimizations"
4124 "* return output_387_reg_move (insn, operands);"
4125 [(set_attr "type" "fmov")
4126 (set_attr "mode" "<MODE>")])
4127
4128 (define_insn "*truncxf<mode>2_i387"
4129 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4130 (float_truncate:MODEF
4131 (match_operand:XF 1 "register_operand" "f")))]
4132 "TARGET_80387"
4133 "* return output_387_reg_move (insn, operands);"
4134 [(set_attr "type" "fmov")
4135 (set_attr "mode" "<MODE>")])
4136
4137 (define_split
4138 [(set (match_operand:MODEF 0 "register_operand")
4139 (float_truncate:MODEF
4140 (match_operand:XF 1 "register_operand")))
4141 (clobber (match_operand:MODEF 2 "memory_operand"))]
4142 "TARGET_80387 && reload_completed"
4143 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4144 (set (match_dup 0) (match_dup 2))])
4145
4146 (define_split
4147 [(set (match_operand:MODEF 0 "memory_operand")
4148 (float_truncate:MODEF
4149 (match_operand:XF 1 "register_operand")))
4150 (clobber (match_operand:MODEF 2 "memory_operand"))]
4151 "TARGET_80387"
4152 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4153 \f
4154 ;; Signed conversion to DImode.
4155
4156 (define_expand "fix_truncxfdi2"
4157 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4158 (fix:DI (match_operand:XF 1 "register_operand")))
4159 (clobber (reg:CC FLAGS_REG))])]
4160 "TARGET_80387"
4161 {
4162 if (TARGET_FISTTP)
4163 {
4164 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4165 DONE;
4166 }
4167 })
4168
4169 (define_expand "fix_trunc<mode>di2"
4170 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4171 (fix:DI (match_operand:MODEF 1 "register_operand")))
4172 (clobber (reg:CC FLAGS_REG))])]
4173 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4174 {
4175 if (TARGET_FISTTP
4176 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4177 {
4178 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4179 DONE;
4180 }
4181 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4182 {
4183 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4184 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4185 if (out != operands[0])
4186 emit_move_insn (operands[0], out);
4187 DONE;
4188 }
4189 })
4190
4191 ;; Signed conversion to SImode.
4192
4193 (define_expand "fix_truncxfsi2"
4194 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4195 (fix:SI (match_operand:XF 1 "register_operand")))
4196 (clobber (reg:CC FLAGS_REG))])]
4197 "TARGET_80387"
4198 {
4199 if (TARGET_FISTTP)
4200 {
4201 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4202 DONE;
4203 }
4204 })
4205
4206 (define_expand "fix_trunc<mode>si2"
4207 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4208 (fix:SI (match_operand:MODEF 1 "register_operand")))
4209 (clobber (reg:CC FLAGS_REG))])]
4210 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4211 {
4212 if (TARGET_FISTTP
4213 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4214 {
4215 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4216 DONE;
4217 }
4218 if (SSE_FLOAT_MODE_P (<MODE>mode))
4219 {
4220 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4221 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4222 if (out != operands[0])
4223 emit_move_insn (operands[0], out);
4224 DONE;
4225 }
4226 })
4227
4228 ;; Signed conversion to HImode.
4229
4230 (define_expand "fix_trunc<mode>hi2"
4231 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4232 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4233 (clobber (reg:CC FLAGS_REG))])]
4234 "TARGET_80387
4235 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4236 {
4237 if (TARGET_FISTTP)
4238 {
4239 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4240 DONE;
4241 }
4242 })
4243
4244 ;; Unsigned conversion to SImode.
4245
4246 (define_expand "fixuns_trunc<mode>si2"
4247 [(parallel
4248 [(set (match_operand:SI 0 "register_operand")
4249 (unsigned_fix:SI
4250 (match_operand:MODEF 1 "nonimmediate_operand")))
4251 (use (match_dup 2))
4252 (clobber (match_scratch:<ssevecmode> 3))
4253 (clobber (match_scratch:<ssevecmode> 4))])]
4254 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4255 {
4256 enum machine_mode mode = <MODE>mode;
4257 enum machine_mode vecmode = <ssevecmode>mode;
4258 REAL_VALUE_TYPE TWO31r;
4259 rtx two31;
4260
4261 if (optimize_insn_for_size_p ())
4262 FAIL;
4263
4264 real_ldexp (&TWO31r, &dconst1, 31);
4265 two31 = const_double_from_real_value (TWO31r, mode);
4266 two31 = ix86_build_const_vector (vecmode, true, two31);
4267 operands[2] = force_reg (vecmode, two31);
4268 })
4269
4270 (define_insn_and_split "*fixuns_trunc<mode>_1"
4271 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4272 (unsigned_fix:SI
4273 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4274 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4275 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4276 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4277 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4278 && optimize_function_for_speed_p (cfun)"
4279 "#"
4280 "&& reload_completed"
4281 [(const_int 0)]
4282 {
4283 ix86_split_convert_uns_si_sse (operands);
4284 DONE;
4285 })
4286
4287 ;; Unsigned conversion to HImode.
4288 ;; Without these patterns, we'll try the unsigned SI conversion which
4289 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4290
4291 (define_expand "fixuns_trunc<mode>hi2"
4292 [(set (match_dup 2)
4293 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4294 (set (match_operand:HI 0 "nonimmediate_operand")
4295 (subreg:HI (match_dup 2) 0))]
4296 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4297 "operands[2] = gen_reg_rtx (SImode);")
4298
4299 ;; When SSE is available, it is always faster to use it!
4300 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4301 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4302 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4303 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4304 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4305 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4306 [(set_attr "type" "sseicvt")
4307 (set_attr "prefix" "maybe_vex")
4308 (set (attr "prefix_rex")
4309 (if_then_else
4310 (match_test "<SWI48:MODE>mode == DImode")
4311 (const_string "1")
4312 (const_string "*")))
4313 (set_attr "mode" "<MODEF:MODE>")
4314 (set_attr "athlon_decode" "double,vector")
4315 (set_attr "amdfam10_decode" "double,double")
4316 (set_attr "bdver1_decode" "double,double")])
4317
4318 ;; Avoid vector decoded forms of the instruction.
4319 (define_peephole2
4320 [(match_scratch:MODEF 2 "x")
4321 (set (match_operand:SWI48 0 "register_operand")
4322 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4323 "TARGET_AVOID_VECTOR_DECODE
4324 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4325 && optimize_insn_for_speed_p ()"
4326 [(set (match_dup 2) (match_dup 1))
4327 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4328
4329 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4330 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4331 (fix:SWI248x (match_operand 1 "register_operand")))]
4332 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4333 && TARGET_FISTTP
4334 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4335 && (TARGET_64BIT || <MODE>mode != DImode))
4336 && TARGET_SSE_MATH)
4337 && can_create_pseudo_p ()"
4338 "#"
4339 "&& 1"
4340 [(const_int 0)]
4341 {
4342 if (memory_operand (operands[0], VOIDmode))
4343 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4344 else
4345 {
4346 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4347 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4348 operands[1],
4349 operands[2]));
4350 }
4351 DONE;
4352 }
4353 [(set_attr "type" "fisttp")
4354 (set_attr "mode" "<MODE>")])
4355
4356 (define_insn "fix_trunc<mode>_i387_fisttp"
4357 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4358 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4359 (clobber (match_scratch:XF 2 "=&1f"))]
4360 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4361 && TARGET_FISTTP
4362 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4363 && (TARGET_64BIT || <MODE>mode != DImode))
4364 && TARGET_SSE_MATH)"
4365 "* return output_fix_trunc (insn, operands, true);"
4366 [(set_attr "type" "fisttp")
4367 (set_attr "mode" "<MODE>")])
4368
4369 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4370 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4371 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4372 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4373 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4374 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4375 && TARGET_FISTTP
4376 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4377 && (TARGET_64BIT || <MODE>mode != DImode))
4378 && TARGET_SSE_MATH)"
4379 "#"
4380 [(set_attr "type" "fisttp")
4381 (set_attr "mode" "<MODE>")])
4382
4383 (define_split
4384 [(set (match_operand:SWI248x 0 "register_operand")
4385 (fix:SWI248x (match_operand 1 "register_operand")))
4386 (clobber (match_operand:SWI248x 2 "memory_operand"))
4387 (clobber (match_scratch 3))]
4388 "reload_completed"
4389 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4390 (clobber (match_dup 3))])
4391 (set (match_dup 0) (match_dup 2))])
4392
4393 (define_split
4394 [(set (match_operand:SWI248x 0 "memory_operand")
4395 (fix:SWI248x (match_operand 1 "register_operand")))
4396 (clobber (match_operand:SWI248x 2 "memory_operand"))
4397 (clobber (match_scratch 3))]
4398 "reload_completed"
4399 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4400 (clobber (match_dup 3))])])
4401
4402 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4403 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4404 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4405 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4406 ;; function in i386.c.
4407 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4408 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4409 (fix:SWI248x (match_operand 1 "register_operand")))
4410 (clobber (reg:CC FLAGS_REG))]
4411 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4412 && !TARGET_FISTTP
4413 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4414 && (TARGET_64BIT || <MODE>mode != DImode))
4415 && can_create_pseudo_p ()"
4416 "#"
4417 "&& 1"
4418 [(const_int 0)]
4419 {
4420 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4421
4422 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4423 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4424 if (memory_operand (operands[0], VOIDmode))
4425 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4426 operands[2], operands[3]));
4427 else
4428 {
4429 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4430 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4431 operands[2], operands[3],
4432 operands[4]));
4433 }
4434 DONE;
4435 }
4436 [(set_attr "type" "fistp")
4437 (set_attr "i387_cw" "trunc")
4438 (set_attr "mode" "<MODE>")])
4439
4440 (define_insn "fix_truncdi_i387"
4441 [(set (match_operand:DI 0 "memory_operand" "=m")
4442 (fix:DI (match_operand 1 "register_operand" "f")))
4443 (use (match_operand:HI 2 "memory_operand" "m"))
4444 (use (match_operand:HI 3 "memory_operand" "m"))
4445 (clobber (match_scratch:XF 4 "=&1f"))]
4446 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4447 && !TARGET_FISTTP
4448 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4449 "* return output_fix_trunc (insn, operands, false);"
4450 [(set_attr "type" "fistp")
4451 (set_attr "i387_cw" "trunc")
4452 (set_attr "mode" "DI")])
4453
4454 (define_insn "fix_truncdi_i387_with_temp"
4455 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4456 (fix:DI (match_operand 1 "register_operand" "f,f")))
4457 (use (match_operand:HI 2 "memory_operand" "m,m"))
4458 (use (match_operand:HI 3 "memory_operand" "m,m"))
4459 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4460 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4461 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4462 && !TARGET_FISTTP
4463 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4464 "#"
4465 [(set_attr "type" "fistp")
4466 (set_attr "i387_cw" "trunc")
4467 (set_attr "mode" "DI")])
4468
4469 (define_split
4470 [(set (match_operand:DI 0 "register_operand")
4471 (fix:DI (match_operand 1 "register_operand")))
4472 (use (match_operand:HI 2 "memory_operand"))
4473 (use (match_operand:HI 3 "memory_operand"))
4474 (clobber (match_operand:DI 4 "memory_operand"))
4475 (clobber (match_scratch 5))]
4476 "reload_completed"
4477 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4478 (use (match_dup 2))
4479 (use (match_dup 3))
4480 (clobber (match_dup 5))])
4481 (set (match_dup 0) (match_dup 4))])
4482
4483 (define_split
4484 [(set (match_operand:DI 0 "memory_operand")
4485 (fix:DI (match_operand 1 "register_operand")))
4486 (use (match_operand:HI 2 "memory_operand"))
4487 (use (match_operand:HI 3 "memory_operand"))
4488 (clobber (match_operand:DI 4 "memory_operand"))
4489 (clobber (match_scratch 5))]
4490 "reload_completed"
4491 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4492 (use (match_dup 2))
4493 (use (match_dup 3))
4494 (clobber (match_dup 5))])])
4495
4496 (define_insn "fix_trunc<mode>_i387"
4497 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4498 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4499 (use (match_operand:HI 2 "memory_operand" "m"))
4500 (use (match_operand:HI 3 "memory_operand" "m"))]
4501 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4502 && !TARGET_FISTTP
4503 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4504 "* return output_fix_trunc (insn, operands, false);"
4505 [(set_attr "type" "fistp")
4506 (set_attr "i387_cw" "trunc")
4507 (set_attr "mode" "<MODE>")])
4508
4509 (define_insn "fix_trunc<mode>_i387_with_temp"
4510 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4511 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4512 (use (match_operand:HI 2 "memory_operand" "m,m"))
4513 (use (match_operand:HI 3 "memory_operand" "m,m"))
4514 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4515 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4516 && !TARGET_FISTTP
4517 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4518 "#"
4519 [(set_attr "type" "fistp")
4520 (set_attr "i387_cw" "trunc")
4521 (set_attr "mode" "<MODE>")])
4522
4523 (define_split
4524 [(set (match_operand:SWI24 0 "register_operand")
4525 (fix:SWI24 (match_operand 1 "register_operand")))
4526 (use (match_operand:HI 2 "memory_operand"))
4527 (use (match_operand:HI 3 "memory_operand"))
4528 (clobber (match_operand:SWI24 4 "memory_operand"))]
4529 "reload_completed"
4530 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4531 (use (match_dup 2))
4532 (use (match_dup 3))])
4533 (set (match_dup 0) (match_dup 4))])
4534
4535 (define_split
4536 [(set (match_operand:SWI24 0 "memory_operand")
4537 (fix:SWI24 (match_operand 1 "register_operand")))
4538 (use (match_operand:HI 2 "memory_operand"))
4539 (use (match_operand:HI 3 "memory_operand"))
4540 (clobber (match_operand:SWI24 4 "memory_operand"))]
4541 "reload_completed"
4542 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4543 (use (match_dup 2))
4544 (use (match_dup 3))])])
4545
4546 (define_insn "x86_fnstcw_1"
4547 [(set (match_operand:HI 0 "memory_operand" "=m")
4548 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4549 "TARGET_80387"
4550 "fnstcw\t%0"
4551 [(set (attr "length")
4552 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4553 (set_attr "mode" "HI")
4554 (set_attr "unit" "i387")
4555 (set_attr "bdver1_decode" "vector")])
4556
4557 (define_insn "x86_fldcw_1"
4558 [(set (reg:HI FPCR_REG)
4559 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4560 "TARGET_80387"
4561 "fldcw\t%0"
4562 [(set (attr "length")
4563 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4564 (set_attr "mode" "HI")
4565 (set_attr "unit" "i387")
4566 (set_attr "athlon_decode" "vector")
4567 (set_attr "amdfam10_decode" "vector")
4568 (set_attr "bdver1_decode" "vector")])
4569 \f
4570 ;; Conversion between fixed point and floating point.
4571
4572 ;; Even though we only accept memory inputs, the backend _really_
4573 ;; wants to be able to do this between registers.
4574
4575 (define_expand "floathi<mode>2"
4576 [(set (match_operand:X87MODEF 0 "register_operand")
4577 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4578 "TARGET_80387
4579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4580 || TARGET_MIX_SSE_I387)")
4581
4582 ;; Pre-reload splitter to add memory clobber to the pattern.
4583 (define_insn_and_split "*floathi<mode>2_1"
4584 [(set (match_operand:X87MODEF 0 "register_operand")
4585 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4586 "TARGET_80387
4587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4588 || TARGET_MIX_SSE_I387)
4589 && can_create_pseudo_p ()"
4590 "#"
4591 "&& 1"
4592 [(parallel [(set (match_dup 0)
4593 (float:X87MODEF (match_dup 1)))
4594 (clobber (match_dup 2))])]
4595 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4596
4597 (define_insn "*floathi<mode>2_i387_with_temp"
4598 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4599 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4600 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4601 "TARGET_80387
4602 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4603 || TARGET_MIX_SSE_I387)"
4604 "#"
4605 [(set_attr "type" "fmov,multi")
4606 (set_attr "mode" "<MODE>")
4607 (set_attr "unit" "*,i387")
4608 (set_attr "fp_int_src" "true")])
4609
4610 (define_insn "*floathi<mode>2_i387"
4611 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4612 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4613 "TARGET_80387
4614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4615 || TARGET_MIX_SSE_I387)"
4616 "fild%Z1\t%1"
4617 [(set_attr "type" "fmov")
4618 (set_attr "mode" "<MODE>")
4619 (set_attr "fp_int_src" "true")])
4620
4621 (define_split
4622 [(set (match_operand:X87MODEF 0 "register_operand")
4623 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4624 (clobber (match_operand:HI 2 "memory_operand"))]
4625 "TARGET_80387
4626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4627 || TARGET_MIX_SSE_I387)
4628 && reload_completed"
4629 [(set (match_dup 2) (match_dup 1))
4630 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4631
4632 (define_split
4633 [(set (match_operand:X87MODEF 0 "register_operand")
4634 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4635 (clobber (match_operand:HI 2 "memory_operand"))]
4636 "TARGET_80387
4637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4638 || TARGET_MIX_SSE_I387)
4639 && reload_completed"
4640 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4641
4642 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4643 [(set (match_operand:X87MODEF 0 "register_operand")
4644 (float:X87MODEF
4645 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4646 "TARGET_80387
4647 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4648 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4649 {
4650 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4651 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4652 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4653 {
4654 rtx reg = gen_reg_rtx (XFmode);
4655 rtx (*insn)(rtx, rtx);
4656
4657 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4658
4659 if (<X87MODEF:MODE>mode == SFmode)
4660 insn = gen_truncxfsf2;
4661 else if (<X87MODEF:MODE>mode == DFmode)
4662 insn = gen_truncxfdf2;
4663 else
4664 gcc_unreachable ();
4665
4666 emit_insn (insn (operands[0], reg));
4667 DONE;
4668 }
4669 })
4670
4671 ;; Pre-reload splitter to add memory clobber to the pattern.
4672 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4673 [(set (match_operand:X87MODEF 0 "register_operand")
4674 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4675 "((TARGET_80387
4676 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4677 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4678 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4679 || TARGET_MIX_SSE_I387))
4680 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4681 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4682 && ((<SWI48x:MODE>mode == SImode
4683 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4684 && optimize_function_for_speed_p (cfun)
4685 && flag_trapping_math)
4686 || !(TARGET_INTER_UNIT_CONVERSIONS
4687 || optimize_function_for_size_p (cfun)))))
4688 && can_create_pseudo_p ()"
4689 "#"
4690 "&& 1"
4691 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4692 (clobber (match_dup 2))])]
4693 {
4694 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4695
4696 /* Avoid store forwarding (partial memory) stall penalty
4697 by passing DImode value through XMM registers. */
4698 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4699 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4700 && optimize_function_for_speed_p (cfun))
4701 {
4702 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4703 operands[1],
4704 operands[2]));
4705 DONE;
4706 }
4707 })
4708
4709 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4710 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4711 (float:MODEF
4712 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4713 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4714 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4715 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4716 "#"
4717 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4718 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4719 (set_attr "unit" "*,i387,*,*,*")
4720 (set_attr "athlon_decode" "*,*,double,direct,double")
4721 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4722 (set_attr "bdver1_decode" "*,*,double,direct,double")
4723 (set_attr "fp_int_src" "true")])
4724
4725 (define_insn "*floatsi<mode>2_vector_mixed"
4726 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4727 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4728 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4729 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4730 "@
4731 fild%Z1\t%1
4732 #"
4733 [(set_attr "type" "fmov,sseicvt")
4734 (set_attr "mode" "<MODE>,<ssevecmode>")
4735 (set_attr "unit" "i387,*")
4736 (set_attr "athlon_decode" "*,direct")
4737 (set_attr "amdfam10_decode" "*,double")
4738 (set_attr "bdver1_decode" "*,direct")
4739 (set_attr "fp_int_src" "true")])
4740
4741 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4742 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4743 (float:MODEF
4744 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4745 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4746 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4747 "#"
4748 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4749 (set_attr "mode" "<MODEF:MODE>")
4750 (set_attr "unit" "*,i387,*,*")
4751 (set_attr "athlon_decode" "*,*,double,direct")
4752 (set_attr "amdfam10_decode" "*,*,vector,double")
4753 (set_attr "bdver1_decode" "*,*,double,direct")
4754 (set_attr "fp_int_src" "true")])
4755
4756 (define_split
4757 [(set (match_operand:MODEF 0 "register_operand")
4758 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4759 (clobber (match_operand:SWI48 2 "memory_operand"))]
4760 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4761 && TARGET_INTER_UNIT_CONVERSIONS
4762 && reload_completed && SSE_REG_P (operands[0])"
4763 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4764
4765 (define_split
4766 [(set (match_operand:MODEF 0 "register_operand")
4767 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4768 (clobber (match_operand:SWI48 2 "memory_operand"))]
4769 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4770 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4771 && reload_completed && SSE_REG_P (operands[0])"
4772 [(set (match_dup 2) (match_dup 1))
4773 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4774
4775 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4776 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4777 (float:MODEF
4778 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4779 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4780 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4781 "@
4782 fild%Z1\t%1
4783 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4784 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4785 [(set_attr "type" "fmov,sseicvt,sseicvt")
4786 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4787 (set_attr "mode" "<MODEF:MODE>")
4788 (set (attr "prefix_rex")
4789 (if_then_else
4790 (and (eq_attr "prefix" "maybe_vex")
4791 (match_test "<SWI48:MODE>mode == DImode"))
4792 (const_string "1")
4793 (const_string "*")))
4794 (set_attr "unit" "i387,*,*")
4795 (set_attr "athlon_decode" "*,double,direct")
4796 (set_attr "amdfam10_decode" "*,vector,double")
4797 (set_attr "bdver1_decode" "*,double,direct")
4798 (set_attr "fp_int_src" "true")])
4799
4800 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4801 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4802 (float:MODEF
4803 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4804 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4805 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4806 "@
4807 fild%Z1\t%1
4808 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4809 [(set_attr "type" "fmov,sseicvt")
4810 (set_attr "prefix" "orig,maybe_vex")
4811 (set_attr "mode" "<MODEF:MODE>")
4812 (set (attr "prefix_rex")
4813 (if_then_else
4814 (and (eq_attr "prefix" "maybe_vex")
4815 (match_test "<SWI48:MODE>mode == DImode"))
4816 (const_string "1")
4817 (const_string "*")))
4818 (set_attr "athlon_decode" "*,direct")
4819 (set_attr "amdfam10_decode" "*,double")
4820 (set_attr "bdver1_decode" "*,direct")
4821 (set_attr "fp_int_src" "true")])
4822
4823 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4824 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4825 (float:MODEF
4826 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4827 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4828 "TARGET_SSE2 && TARGET_SSE_MATH
4829 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4830 "#"
4831 [(set_attr "type" "sseicvt")
4832 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4833 (set_attr "athlon_decode" "double,direct,double")
4834 (set_attr "amdfam10_decode" "vector,double,double")
4835 (set_attr "bdver1_decode" "double,direct,double")
4836 (set_attr "fp_int_src" "true")])
4837
4838 (define_insn "*floatsi<mode>2_vector_sse"
4839 [(set (match_operand:MODEF 0 "register_operand" "=x")
4840 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4841 "TARGET_SSE2 && TARGET_SSE_MATH
4842 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4843 "#"
4844 [(set_attr "type" "sseicvt")
4845 (set_attr "mode" "<MODE>")
4846 (set_attr "athlon_decode" "direct")
4847 (set_attr "amdfam10_decode" "double")
4848 (set_attr "bdver1_decode" "direct")
4849 (set_attr "fp_int_src" "true")])
4850
4851 (define_split
4852 [(set (match_operand:MODEF 0 "register_operand")
4853 (float:MODEF (match_operand:SI 1 "register_operand")))
4854 (clobber (match_operand:SI 2 "memory_operand"))]
4855 "TARGET_SSE2 && TARGET_SSE_MATH
4856 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4857 && reload_completed && SSE_REG_P (operands[0])"
4858 [(const_int 0)]
4859 {
4860 rtx op1 = operands[1];
4861
4862 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4863 <MODE>mode, 0);
4864 if (GET_CODE (op1) == SUBREG)
4865 op1 = SUBREG_REG (op1);
4866
4867 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4868 {
4869 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4870 emit_insn (gen_sse2_loadld (operands[4],
4871 CONST0_RTX (V4SImode), operands[1]));
4872 }
4873 /* We can ignore possible trapping value in the
4874 high part of SSE register for non-trapping math. */
4875 else if (SSE_REG_P (op1) && !flag_trapping_math)
4876 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4877 else
4878 {
4879 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4880 emit_move_insn (operands[2], operands[1]);
4881 emit_insn (gen_sse2_loadld (operands[4],
4882 CONST0_RTX (V4SImode), operands[2]));
4883 }
4884 if (<ssevecmode>mode == V4SFmode)
4885 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4886 else
4887 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4888 DONE;
4889 })
4890
4891 (define_split
4892 [(set (match_operand:MODEF 0 "register_operand")
4893 (float:MODEF (match_operand:SI 1 "memory_operand")))
4894 (clobber (match_operand:SI 2 "memory_operand"))]
4895 "TARGET_SSE2 && TARGET_SSE_MATH
4896 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4897 && reload_completed && SSE_REG_P (operands[0])"
4898 [(const_int 0)]
4899 {
4900 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4901 <MODE>mode, 0);
4902 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4903
4904 emit_insn (gen_sse2_loadld (operands[4],
4905 CONST0_RTX (V4SImode), operands[1]));
4906 if (<ssevecmode>mode == V4SFmode)
4907 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4908 else
4909 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4910 DONE;
4911 })
4912
4913 (define_split
4914 [(set (match_operand:MODEF 0 "register_operand")
4915 (float:MODEF (match_operand:SI 1 "register_operand")))]
4916 "TARGET_SSE2 && TARGET_SSE_MATH
4917 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4918 && reload_completed && SSE_REG_P (operands[0])"
4919 [(const_int 0)]
4920 {
4921 rtx op1 = operands[1];
4922
4923 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4924 <MODE>mode, 0);
4925 if (GET_CODE (op1) == SUBREG)
4926 op1 = SUBREG_REG (op1);
4927
4928 if (GENERAL_REG_P (op1))
4929 {
4930 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4931 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4932 emit_insn (gen_sse2_loadld (operands[4],
4933 CONST0_RTX (V4SImode), operands[1]));
4934 else
4935 {
4936 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4937 operands[1]);
4938 emit_insn (gen_sse2_loadld (operands[4],
4939 CONST0_RTX (V4SImode), operands[5]));
4940 ix86_free_from_memory (GET_MODE (operands[1]));
4941 }
4942 }
4943 /* We can ignore possible trapping value in the
4944 high part of SSE register for non-trapping math. */
4945 else if (SSE_REG_P (op1) && !flag_trapping_math)
4946 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4947 else
4948 gcc_unreachable ();
4949 if (<ssevecmode>mode == V4SFmode)
4950 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4951 else
4952 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4953 DONE;
4954 })
4955
4956 (define_split
4957 [(set (match_operand:MODEF 0 "register_operand")
4958 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4959 "TARGET_SSE2 && TARGET_SSE_MATH
4960 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4961 && reload_completed && SSE_REG_P (operands[0])"
4962 [(const_int 0)]
4963 {
4964 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4965 <MODE>mode, 0);
4966 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4967
4968 emit_insn (gen_sse2_loadld (operands[4],
4969 CONST0_RTX (V4SImode), operands[1]));
4970 if (<ssevecmode>mode == V4SFmode)
4971 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4972 else
4973 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4974 DONE;
4975 })
4976
4977 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4978 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4979 (float:MODEF
4980 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4981 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4982 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4983 "#"
4984 [(set_attr "type" "sseicvt")
4985 (set_attr "mode" "<MODEF:MODE>")
4986 (set_attr "athlon_decode" "double,direct")
4987 (set_attr "amdfam10_decode" "vector,double")
4988 (set_attr "bdver1_decode" "double,direct")
4989 (set_attr "btver2_decode" "double,double")
4990 (set_attr "fp_int_src" "true")])
4991
4992 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4993 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4994 (float:MODEF
4995 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4996 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4997 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4998 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4999 [(set_attr "type" "sseicvt")
5000 (set_attr "prefix" "maybe_vex")
5001 (set_attr "mode" "<MODEF:MODE>")
5002 (set (attr "prefix_rex")
5003 (if_then_else
5004 (and (eq_attr "prefix" "maybe_vex")
5005 (match_test "<SWI48:MODE>mode == DImode"))
5006 (const_string "1")
5007 (const_string "*")))
5008 (set_attr "athlon_decode" "double,direct")
5009 (set_attr "amdfam10_decode" "vector,double")
5010 (set_attr "bdver1_decode" "double,direct")
5011 (set_attr "btver2_decode" "double,double")
5012 (set_attr "fp_int_src" "true")])
5013
5014 (define_split
5015 [(set (match_operand:MODEF 0 "register_operand")
5016 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5017 (clobber (match_operand:SWI48 2 "memory_operand"))]
5018 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5019 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5020 && reload_completed && SSE_REG_P (operands[0])"
5021 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5022
5023 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5024 [(set (match_operand:MODEF 0 "register_operand" "=x")
5025 (float:MODEF
5026 (match_operand:SWI48 1 "memory_operand" "m")))]
5027 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5028 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5029 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5030 [(set_attr "type" "sseicvt")
5031 (set_attr "prefix" "maybe_vex")
5032 (set_attr "mode" "<MODEF:MODE>")
5033 (set (attr "prefix_rex")
5034 (if_then_else
5035 (and (eq_attr "prefix" "maybe_vex")
5036 (match_test "<SWI48:MODE>mode == DImode"))
5037 (const_string "1")
5038 (const_string "*")))
5039 (set_attr "athlon_decode" "direct")
5040 (set_attr "amdfam10_decode" "double")
5041 (set_attr "bdver1_decode" "direct")
5042 (set_attr "fp_int_src" "true")])
5043
5044 (define_split
5045 [(set (match_operand:MODEF 0 "register_operand")
5046 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5047 (clobber (match_operand:SWI48 2 "memory_operand"))]
5048 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5049 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5050 && reload_completed && SSE_REG_P (operands[0])"
5051 [(set (match_dup 2) (match_dup 1))
5052 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5053
5054 (define_split
5055 [(set (match_operand:MODEF 0 "register_operand")
5056 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5057 (clobber (match_operand:SWI48 2 "memory_operand"))]
5058 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5059 && reload_completed && SSE_REG_P (operands[0])"
5060 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5061
5062 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5063 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5064 (float:X87MODEF
5065 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5066 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5067 "TARGET_80387
5068 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5069 "@
5070 fild%Z1\t%1
5071 #"
5072 [(set_attr "type" "fmov,multi")
5073 (set_attr "mode" "<X87MODEF:MODE>")
5074 (set_attr "unit" "*,i387")
5075 (set_attr "fp_int_src" "true")])
5076
5077 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5078 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5079 (float:X87MODEF
5080 (match_operand:SWI48x 1 "memory_operand" "m")))]
5081 "TARGET_80387
5082 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5083 "fild%Z1\t%1"
5084 [(set_attr "type" "fmov")
5085 (set_attr "mode" "<X87MODEF:MODE>")
5086 (set_attr "fp_int_src" "true")])
5087
5088 (define_split
5089 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5090 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5091 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5092 "TARGET_80387
5093 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5094 && reload_completed"
5095 [(set (match_dup 2) (match_dup 1))
5096 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5097
5098 (define_split
5099 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5100 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5101 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5102 "TARGET_80387
5103 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5104 && reload_completed"
5105 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5106
5107 ;; Avoid partial SSE register dependency stalls
5108
5109 (define_split
5110 [(set (match_operand:MODEF 0 "register_operand")
5111 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5112 "TARGET_SSE2 && TARGET_SSE_MATH
5113 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5114 && optimize_function_for_speed_p (cfun)
5115 && reload_completed && SSE_REG_P (operands[0])"
5116 [(set (match_dup 0)
5117 (vec_merge:<ssevecmode>
5118 (vec_duplicate:<ssevecmode>
5119 (float:MODEF (match_dup 1)))
5120 (match_dup 0)
5121 (const_int 1)))]
5122 {
5123 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5124 <MODE>mode, 0);
5125 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5126 })
5127
5128 (define_split
5129 [(set (match_operand:MODEF 0 "register_operand")
5130 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5131 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5132 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5133 && optimize_function_for_speed_p (cfun)
5134 && reload_completed && SSE_REG_P (operands[0])"
5135 [(set (match_dup 0)
5136 (vec_merge:<ssevecmode>
5137 (vec_duplicate:<ssevecmode>
5138 (float:MODEF (match_dup 1)))
5139 (match_dup 0)
5140 (const_int 1)))]
5141 {
5142 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5143 <MODE>mode, 0);
5144 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5145 })
5146
5147 ;; Break partial reg stall for cvtsd2ss.
5148
5149 (define_peephole2
5150 [(set (match_operand:SF 0 "register_operand")
5151 (float_truncate:SF
5152 (match_operand:DF 1 "nonimmediate_operand")))]
5153 "TARGET_SSE2 && TARGET_SSE_MATH
5154 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5155 && optimize_function_for_speed_p (cfun)
5156 && SSE_REG_P (operands[0])
5157 && (!SSE_REG_P (operands[1])
5158 || REGNO (operands[0]) != REGNO (operands[1]))"
5159 [(set (match_dup 0)
5160 (vec_merge:V4SF
5161 (vec_duplicate:V4SF
5162 (float_truncate:V2SF
5163 (match_dup 1)))
5164 (match_dup 0)
5165 (const_int 1)))]
5166 {
5167 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5168 SFmode, 0);
5169 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5170 DFmode, 0);
5171 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5172 })
5173
5174 ;; Break partial reg stall for cvtss2sd.
5175
5176 (define_peephole2
5177 [(set (match_operand:DF 0 "register_operand")
5178 (float_extend:DF
5179 (match_operand:SF 1 "nonimmediate_operand")))]
5180 "TARGET_SSE2 && TARGET_SSE_MATH
5181 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5182 && optimize_function_for_speed_p (cfun)
5183 && SSE_REG_P (operands[0])
5184 && (!SSE_REG_P (operands[1])
5185 || REGNO (operands[0]) != REGNO (operands[1]))"
5186 [(set (match_dup 0)
5187 (vec_merge:V2DF
5188 (float_extend:V2DF
5189 (vec_select:V2SF
5190 (match_dup 1)
5191 (parallel [(const_int 0) (const_int 1)])))
5192 (match_dup 0)
5193 (const_int 1)))]
5194 {
5195 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5196 DFmode, 0);
5197 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5198 SFmode, 0);
5199 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5200 })
5201
5202 ;; Avoid store forwarding (partial memory) stall penalty
5203 ;; by passing DImode value through XMM registers. */
5204
5205 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5206 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5207 (float:X87MODEF
5208 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5209 (clobber (match_scratch:V4SI 3 "=X,x"))
5210 (clobber (match_scratch:V4SI 4 "=X,x"))
5211 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5212 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5213 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5214 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5215 "#"
5216 [(set_attr "type" "multi")
5217 (set_attr "mode" "<X87MODEF:MODE>")
5218 (set_attr "unit" "i387")
5219 (set_attr "fp_int_src" "true")])
5220
5221 (define_split
5222 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5223 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5224 (clobber (match_scratch:V4SI 3))
5225 (clobber (match_scratch:V4SI 4))
5226 (clobber (match_operand:DI 2 "memory_operand"))]
5227 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5228 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5229 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5230 && reload_completed"
5231 [(set (match_dup 2) (match_dup 3))
5232 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5233 {
5234 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5235 Assemble the 64-bit DImode value in an xmm register. */
5236 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5237 gen_rtx_SUBREG (SImode, operands[1], 0)));
5238 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5239 gen_rtx_SUBREG (SImode, operands[1], 4)));
5240 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5241 operands[4]));
5242
5243 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5244 })
5245
5246 (define_split
5247 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5248 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5249 (clobber (match_scratch:V4SI 3))
5250 (clobber (match_scratch:V4SI 4))
5251 (clobber (match_operand:DI 2 "memory_operand"))]
5252 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5253 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5254 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5255 && reload_completed"
5256 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5257
5258 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5259 [(set (match_operand:MODEF 0 "register_operand")
5260 (unsigned_float:MODEF
5261 (match_operand:SWI12 1 "nonimmediate_operand")))]
5262 "!TARGET_64BIT
5263 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5264 {
5265 operands[1] = convert_to_mode (SImode, operands[1], 1);
5266 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5267 DONE;
5268 })
5269
5270 ;; Avoid store forwarding (partial memory) stall penalty by extending
5271 ;; SImode value to DImode through XMM register instead of pushing two
5272 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5273 ;; targets benefit from this optimization. Also note that fild
5274 ;; loads from memory only.
5275
5276 (define_insn "*floatunssi<mode>2_1"
5277 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5278 (unsigned_float:X87MODEF
5279 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5280 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5281 (clobber (match_scratch:SI 3 "=X,x"))]
5282 "!TARGET_64BIT
5283 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5284 && TARGET_SSE"
5285 "#"
5286 [(set_attr "type" "multi")
5287 (set_attr "mode" "<MODE>")])
5288
5289 (define_split
5290 [(set (match_operand:X87MODEF 0 "register_operand")
5291 (unsigned_float:X87MODEF
5292 (match_operand:SI 1 "register_operand")))
5293 (clobber (match_operand:DI 2 "memory_operand"))
5294 (clobber (match_scratch:SI 3))]
5295 "!TARGET_64BIT
5296 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5297 && TARGET_SSE
5298 && reload_completed"
5299 [(set (match_dup 2) (match_dup 1))
5300 (set (match_dup 0)
5301 (float:X87MODEF (match_dup 2)))]
5302 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5303
5304 (define_split
5305 [(set (match_operand:X87MODEF 0 "register_operand")
5306 (unsigned_float:X87MODEF
5307 (match_operand:SI 1 "memory_operand")))
5308 (clobber (match_operand:DI 2 "memory_operand"))
5309 (clobber (match_scratch:SI 3))]
5310 "!TARGET_64BIT
5311 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5312 && TARGET_SSE
5313 && reload_completed"
5314 [(set (match_dup 2) (match_dup 3))
5315 (set (match_dup 0)
5316 (float:X87MODEF (match_dup 2)))]
5317 {
5318 emit_move_insn (operands[3], operands[1]);
5319 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5320 })
5321
5322 (define_expand "floatunssi<mode>2"
5323 [(parallel
5324 [(set (match_operand:X87MODEF 0 "register_operand")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "nonimmediate_operand")))
5327 (clobber (match_dup 2))
5328 (clobber (match_scratch:SI 3))])]
5329 "!TARGET_64BIT
5330 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5331 && TARGET_SSE)
5332 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5333 {
5334 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5335 {
5336 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5337 DONE;
5338 }
5339 else
5340 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5341 })
5342
5343 (define_expand "floatunsdisf2"
5344 [(use (match_operand:SF 0 "register_operand"))
5345 (use (match_operand:DI 1 "nonimmediate_operand"))]
5346 "TARGET_64BIT && TARGET_SSE_MATH"
5347 "x86_emit_floatuns (operands); DONE;")
5348
5349 (define_expand "floatunsdidf2"
5350 [(use (match_operand:DF 0 "register_operand"))
5351 (use (match_operand:DI 1 "nonimmediate_operand"))]
5352 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5353 && TARGET_SSE2 && TARGET_SSE_MATH"
5354 {
5355 if (TARGET_64BIT)
5356 x86_emit_floatuns (operands);
5357 else
5358 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5359 DONE;
5360 })
5361 \f
5362 ;; Load effective address instructions
5363
5364 (define_insn_and_split "*lea<mode>"
5365 [(set (match_operand:SWI48 0 "register_operand" "=r")
5366 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5367 ""
5368 {
5369 if (SImode_address_operand (operands[1], VOIDmode))
5370 {
5371 gcc_assert (TARGET_64BIT);
5372 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5373 }
5374 else
5375 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5376 }
5377 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5378 [(const_int 0)]
5379 {
5380 enum machine_mode mode = <MODE>mode;
5381 rtx pat;
5382
5383 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5384 change operands[] array behind our back. */
5385 pat = PATTERN (curr_insn);
5386
5387 operands[0] = SET_DEST (pat);
5388 operands[1] = SET_SRC (pat);
5389
5390 /* Emit all operations in SImode for zero-extended addresses. Recall
5391 that x86_64 inheretly zero-extends SImode operations to DImode. */
5392 if (SImode_address_operand (operands[1], VOIDmode))
5393 mode = SImode;
5394
5395 ix86_split_lea_for_addr (curr_insn, operands, mode);
5396 DONE;
5397 }
5398 [(set_attr "type" "lea")
5399 (set (attr "mode")
5400 (if_then_else
5401 (match_operand 1 "SImode_address_operand")
5402 (const_string "SI")
5403 (const_string "<MODE>")))])
5404 \f
5405 ;; Add instructions
5406
5407 (define_expand "add<mode>3"
5408 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5409 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5410 (match_operand:SDWIM 2 "<general_operand>")))]
5411 ""
5412 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5413
5414 (define_insn_and_split "*add<dwi>3_doubleword"
5415 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5416 (plus:<DWI>
5417 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5418 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5419 (clobber (reg:CC FLAGS_REG))]
5420 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5421 "#"
5422 "reload_completed"
5423 [(parallel [(set (reg:CC FLAGS_REG)
5424 (unspec:CC [(match_dup 1) (match_dup 2)]
5425 UNSPEC_ADD_CARRY))
5426 (set (match_dup 0)
5427 (plus:DWIH (match_dup 1) (match_dup 2)))])
5428 (parallel [(set (match_dup 3)
5429 (plus:DWIH
5430 (match_dup 4)
5431 (plus:DWIH
5432 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5433 (match_dup 5))))
5434 (clobber (reg:CC FLAGS_REG))])]
5435 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5436
5437 (define_insn "*add<mode>3_cc"
5438 [(set (reg:CC FLAGS_REG)
5439 (unspec:CC
5440 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5441 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5442 UNSPEC_ADD_CARRY))
5443 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5444 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5445 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5446 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5447 [(set_attr "type" "alu")
5448 (set_attr "mode" "<MODE>")])
5449
5450 (define_insn "addqi3_cc"
5451 [(set (reg:CC FLAGS_REG)
5452 (unspec:CC
5453 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5454 (match_operand:QI 2 "general_operand" "qn,qm")]
5455 UNSPEC_ADD_CARRY))
5456 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5457 (plus:QI (match_dup 1) (match_dup 2)))]
5458 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5459 "add{b}\t{%2, %0|%0, %2}"
5460 [(set_attr "type" "alu")
5461 (set_attr "mode" "QI")])
5462
5463 (define_insn "*add<mode>_1"
5464 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5465 (plus:SWI48
5466 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5467 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5468 (clobber (reg:CC FLAGS_REG))]
5469 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5470 {
5471 switch (get_attr_type (insn))
5472 {
5473 case TYPE_LEA:
5474 return "#";
5475
5476 case TYPE_INCDEC:
5477 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5478 if (operands[2] == const1_rtx)
5479 return "inc{<imodesuffix>}\t%0";
5480 else
5481 {
5482 gcc_assert (operands[2] == constm1_rtx);
5483 return "dec{<imodesuffix>}\t%0";
5484 }
5485
5486 default:
5487 /* For most processors, ADD is faster than LEA. This alternative
5488 was added to use ADD as much as possible. */
5489 if (which_alternative == 2)
5490 {
5491 rtx tmp;
5492 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5493 }
5494
5495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5496 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5497 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5498
5499 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5500 }
5501 }
5502 [(set (attr "type")
5503 (cond [(eq_attr "alternative" "3")
5504 (const_string "lea")
5505 (match_operand:SWI48 2 "incdec_operand")
5506 (const_string "incdec")
5507 ]
5508 (const_string "alu")))
5509 (set (attr "length_immediate")
5510 (if_then_else
5511 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5512 (const_string "1")
5513 (const_string "*")))
5514 (set_attr "mode" "<MODE>")])
5515
5516 ;; It may seem that nonimmediate operand is proper one for operand 1.
5517 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5518 ;; we take care in ix86_binary_operator_ok to not allow two memory
5519 ;; operands so proper swapping will be done in reload. This allow
5520 ;; patterns constructed from addsi_1 to match.
5521
5522 (define_insn "addsi_1_zext"
5523 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5524 (zero_extend:DI
5525 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5526 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5527 (clobber (reg:CC FLAGS_REG))]
5528 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5529 {
5530 switch (get_attr_type (insn))
5531 {
5532 case TYPE_LEA:
5533 return "#";
5534
5535 case TYPE_INCDEC:
5536 if (operands[2] == const1_rtx)
5537 return "inc{l}\t%k0";
5538 else
5539 {
5540 gcc_assert (operands[2] == constm1_rtx);
5541 return "dec{l}\t%k0";
5542 }
5543
5544 default:
5545 /* For most processors, ADD is faster than LEA. This alternative
5546 was added to use ADD as much as possible. */
5547 if (which_alternative == 1)
5548 {
5549 rtx tmp;
5550 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5551 }
5552
5553 if (x86_maybe_negate_const_int (&operands[2], SImode))
5554 return "sub{l}\t{%2, %k0|%k0, %2}";
5555
5556 return "add{l}\t{%2, %k0|%k0, %2}";
5557 }
5558 }
5559 [(set (attr "type")
5560 (cond [(eq_attr "alternative" "2")
5561 (const_string "lea")
5562 (match_operand:SI 2 "incdec_operand")
5563 (const_string "incdec")
5564 ]
5565 (const_string "alu")))
5566 (set (attr "length_immediate")
5567 (if_then_else
5568 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5569 (const_string "1")
5570 (const_string "*")))
5571 (set_attr "mode" "SI")])
5572
5573 (define_insn "*addhi_1"
5574 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5575 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5576 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5577 (clobber (reg:CC FLAGS_REG))]
5578 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5579 {
5580 switch (get_attr_type (insn))
5581 {
5582 case TYPE_LEA:
5583 return "#";
5584
5585 case TYPE_INCDEC:
5586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5587 if (operands[2] == const1_rtx)
5588 return "inc{w}\t%0";
5589 else
5590 {
5591 gcc_assert (operands[2] == constm1_rtx);
5592 return "dec{w}\t%0";
5593 }
5594
5595 default:
5596 /* For most processors, ADD is faster than LEA. This alternative
5597 was added to use ADD as much as possible. */
5598 if (which_alternative == 2)
5599 {
5600 rtx tmp;
5601 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5602 }
5603
5604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605 if (x86_maybe_negate_const_int (&operands[2], HImode))
5606 return "sub{w}\t{%2, %0|%0, %2}";
5607
5608 return "add{w}\t{%2, %0|%0, %2}";
5609 }
5610 }
5611 [(set (attr "type")
5612 (cond [(eq_attr "alternative" "3")
5613 (const_string "lea")
5614 (match_operand:HI 2 "incdec_operand")
5615 (const_string "incdec")
5616 ]
5617 (const_string "alu")))
5618 (set (attr "length_immediate")
5619 (if_then_else
5620 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5621 (const_string "1")
5622 (const_string "*")))
5623 (set_attr "mode" "HI,HI,HI,SI")])
5624
5625 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5626 (define_insn "*addqi_1"
5627 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5628 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5629 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5630 (clobber (reg:CC FLAGS_REG))]
5631 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5632 {
5633 bool widen = (which_alternative == 3 || which_alternative == 4);
5634
5635 switch (get_attr_type (insn))
5636 {
5637 case TYPE_LEA:
5638 return "#";
5639
5640 case TYPE_INCDEC:
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (operands[2] == const1_rtx)
5643 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5644 else
5645 {
5646 gcc_assert (operands[2] == constm1_rtx);
5647 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5648 }
5649
5650 default:
5651 /* For most processors, ADD is faster than LEA. These alternatives
5652 were added to use ADD as much as possible. */
5653 if (which_alternative == 2 || which_alternative == 4)
5654 {
5655 rtx tmp;
5656 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5657 }
5658
5659 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660 if (x86_maybe_negate_const_int (&operands[2], QImode))
5661 {
5662 if (widen)
5663 return "sub{l}\t{%2, %k0|%k0, %2}";
5664 else
5665 return "sub{b}\t{%2, %0|%0, %2}";
5666 }
5667 if (widen)
5668 return "add{l}\t{%k2, %k0|%k0, %k2}";
5669 else
5670 return "add{b}\t{%2, %0|%0, %2}";
5671 }
5672 }
5673 [(set (attr "type")
5674 (cond [(eq_attr "alternative" "5")
5675 (const_string "lea")
5676 (match_operand:QI 2 "incdec_operand")
5677 (const_string "incdec")
5678 ]
5679 (const_string "alu")))
5680 (set (attr "length_immediate")
5681 (if_then_else
5682 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5683 (const_string "1")
5684 (const_string "*")))
5685 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5686
5687 (define_insn "*addqi_1_slp"
5688 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5689 (plus:QI (match_dup 0)
5690 (match_operand:QI 1 "general_operand" "qn,qm")))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5693 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5694 {
5695 switch (get_attr_type (insn))
5696 {
5697 case TYPE_INCDEC:
5698 if (operands[1] == const1_rtx)
5699 return "inc{b}\t%0";
5700 else
5701 {
5702 gcc_assert (operands[1] == constm1_rtx);
5703 return "dec{b}\t%0";
5704 }
5705
5706 default:
5707 if (x86_maybe_negate_const_int (&operands[1], QImode))
5708 return "sub{b}\t{%1, %0|%0, %1}";
5709
5710 return "add{b}\t{%1, %0|%0, %1}";
5711 }
5712 }
5713 [(set (attr "type")
5714 (if_then_else (match_operand:QI 1 "incdec_operand")
5715 (const_string "incdec")
5716 (const_string "alu1")))
5717 (set (attr "memory")
5718 (if_then_else (match_operand 1 "memory_operand")
5719 (const_string "load")
5720 (const_string "none")))
5721 (set_attr "mode" "QI")])
5722
5723 ;; Split non destructive adds if we cannot use lea.
5724 (define_split
5725 [(set (match_operand:SWI48 0 "register_operand")
5726 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5727 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5728 (clobber (reg:CC FLAGS_REG))]
5729 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5730 [(set (match_dup 0) (match_dup 1))
5731 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5732 (clobber (reg:CC FLAGS_REG))])])
5733
5734 ;; Convert add to the lea pattern to avoid flags dependency.
5735 (define_split
5736 [(set (match_operand:SWI 0 "register_operand")
5737 (plus:SWI (match_operand:SWI 1 "register_operand")
5738 (match_operand:SWI 2 "<nonmemory_operand>")))
5739 (clobber (reg:CC FLAGS_REG))]
5740 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5741 [(const_int 0)]
5742 {
5743 enum machine_mode mode = <MODE>mode;
5744 rtx pat;
5745
5746 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5747 {
5748 mode = SImode;
5749 operands[0] = gen_lowpart (mode, operands[0]);
5750 operands[1] = gen_lowpart (mode, operands[1]);
5751 operands[2] = gen_lowpart (mode, operands[2]);
5752 }
5753
5754 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5755
5756 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5757 DONE;
5758 })
5759
5760 ;; Split non destructive adds if we cannot use lea.
5761 (define_split
5762 [(set (match_operand:DI 0 "register_operand")
5763 (zero_extend:DI
5764 (plus:SI (match_operand:SI 1 "register_operand")
5765 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5766 (clobber (reg:CC FLAGS_REG))]
5767 "TARGET_64BIT
5768 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5769 [(set (match_dup 3) (match_dup 1))
5770 (parallel [(set (match_dup 0)
5771 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5772 (clobber (reg:CC FLAGS_REG))])]
5773 "operands[3] = gen_lowpart (SImode, operands[0]);")
5774
5775 ;; Convert add to the lea pattern to avoid flags dependency.
5776 (define_split
5777 [(set (match_operand:DI 0 "register_operand")
5778 (zero_extend:DI
5779 (plus:SI (match_operand:SI 1 "register_operand")
5780 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5781 (clobber (reg:CC FLAGS_REG))]
5782 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5783 [(set (match_dup 0)
5784 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5785
5786 (define_insn "*add<mode>_2"
5787 [(set (reg FLAGS_REG)
5788 (compare
5789 (plus:SWI
5790 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5791 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5792 (const_int 0)))
5793 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5794 (plus:SWI (match_dup 1) (match_dup 2)))]
5795 "ix86_match_ccmode (insn, CCGOCmode)
5796 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5797 {
5798 switch (get_attr_type (insn))
5799 {
5800 case TYPE_INCDEC:
5801 if (operands[2] == const1_rtx)
5802 return "inc{<imodesuffix>}\t%0";
5803 else
5804 {
5805 gcc_assert (operands[2] == constm1_rtx);
5806 return "dec{<imodesuffix>}\t%0";
5807 }
5808
5809 default:
5810 if (which_alternative == 2)
5811 {
5812 rtx tmp;
5813 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5814 }
5815
5816 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5817 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5818 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5819
5820 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5821 }
5822 }
5823 [(set (attr "type")
5824 (if_then_else (match_operand:SWI 2 "incdec_operand")
5825 (const_string "incdec")
5826 (const_string "alu")))
5827 (set (attr "length_immediate")
5828 (if_then_else
5829 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5830 (const_string "1")
5831 (const_string "*")))
5832 (set_attr "mode" "<MODE>")])
5833
5834 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5835 (define_insn "*addsi_2_zext"
5836 [(set (reg FLAGS_REG)
5837 (compare
5838 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5839 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5840 (const_int 0)))
5841 (set (match_operand:DI 0 "register_operand" "=r,r")
5842 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5843 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5844 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5845 {
5846 switch (get_attr_type (insn))
5847 {
5848 case TYPE_INCDEC:
5849 if (operands[2] == const1_rtx)
5850 return "inc{l}\t%k0";
5851 else
5852 {
5853 gcc_assert (operands[2] == constm1_rtx);
5854 return "dec{l}\t%k0";
5855 }
5856
5857 default:
5858 if (which_alternative == 1)
5859 {
5860 rtx tmp;
5861 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5862 }
5863
5864 if (x86_maybe_negate_const_int (&operands[2], SImode))
5865 return "sub{l}\t{%2, %k0|%k0, %2}";
5866
5867 return "add{l}\t{%2, %k0|%k0, %2}";
5868 }
5869 }
5870 [(set (attr "type")
5871 (if_then_else (match_operand:SI 2 "incdec_operand")
5872 (const_string "incdec")
5873 (const_string "alu")))
5874 (set (attr "length_immediate")
5875 (if_then_else
5876 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5877 (const_string "1")
5878 (const_string "*")))
5879 (set_attr "mode" "SI")])
5880
5881 (define_insn "*add<mode>_3"
5882 [(set (reg FLAGS_REG)
5883 (compare
5884 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5885 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5886 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5887 "ix86_match_ccmode (insn, CCZmode)
5888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5889 {
5890 switch (get_attr_type (insn))
5891 {
5892 case TYPE_INCDEC:
5893 if (operands[2] == const1_rtx)
5894 return "inc{<imodesuffix>}\t%0";
5895 else
5896 {
5897 gcc_assert (operands[2] == constm1_rtx);
5898 return "dec{<imodesuffix>}\t%0";
5899 }
5900
5901 default:
5902 if (which_alternative == 1)
5903 {
5904 rtx tmp;
5905 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5906 }
5907
5908 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5910 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5911
5912 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5913 }
5914 }
5915 [(set (attr "type")
5916 (if_then_else (match_operand:SWI 2 "incdec_operand")
5917 (const_string "incdec")
5918 (const_string "alu")))
5919 (set (attr "length_immediate")
5920 (if_then_else
5921 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5922 (const_string "1")
5923 (const_string "*")))
5924 (set_attr "mode" "<MODE>")])
5925
5926 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5927 (define_insn "*addsi_3_zext"
5928 [(set (reg FLAGS_REG)
5929 (compare
5930 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5931 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5932 (set (match_operand:DI 0 "register_operand" "=r,r")
5933 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5934 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5935 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5936 {
5937 switch (get_attr_type (insn))
5938 {
5939 case TYPE_INCDEC:
5940 if (operands[2] == const1_rtx)
5941 return "inc{l}\t%k0";
5942 else
5943 {
5944 gcc_assert (operands[2] == constm1_rtx);
5945 return "dec{l}\t%k0";
5946 }
5947
5948 default:
5949 if (which_alternative == 1)
5950 {
5951 rtx tmp;
5952 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5953 }
5954
5955 if (x86_maybe_negate_const_int (&operands[2], SImode))
5956 return "sub{l}\t{%2, %k0|%k0, %2}";
5957
5958 return "add{l}\t{%2, %k0|%k0, %2}";
5959 }
5960 }
5961 [(set (attr "type")
5962 (if_then_else (match_operand:SI 2 "incdec_operand")
5963 (const_string "incdec")
5964 (const_string "alu")))
5965 (set (attr "length_immediate")
5966 (if_then_else
5967 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5968 (const_string "1")
5969 (const_string "*")))
5970 (set_attr "mode" "SI")])
5971
5972 ; For comparisons against 1, -1 and 128, we may generate better code
5973 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5974 ; is matched then. We can't accept general immediate, because for
5975 ; case of overflows, the result is messed up.
5976 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5977 ; only for comparisons not depending on it.
5978
5979 (define_insn "*adddi_4"
5980 [(set (reg FLAGS_REG)
5981 (compare
5982 (match_operand:DI 1 "nonimmediate_operand" "0")
5983 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5984 (clobber (match_scratch:DI 0 "=rm"))]
5985 "TARGET_64BIT
5986 && ix86_match_ccmode (insn, CCGCmode)"
5987 {
5988 switch (get_attr_type (insn))
5989 {
5990 case TYPE_INCDEC:
5991 if (operands[2] == constm1_rtx)
5992 return "inc{q}\t%0";
5993 else
5994 {
5995 gcc_assert (operands[2] == const1_rtx);
5996 return "dec{q}\t%0";
5997 }
5998
5999 default:
6000 if (x86_maybe_negate_const_int (&operands[2], DImode))
6001 return "add{q}\t{%2, %0|%0, %2}";
6002
6003 return "sub{q}\t{%2, %0|%0, %2}";
6004 }
6005 }
6006 [(set (attr "type")
6007 (if_then_else (match_operand:DI 2 "incdec_operand")
6008 (const_string "incdec")
6009 (const_string "alu")))
6010 (set (attr "length_immediate")
6011 (if_then_else
6012 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6013 (const_string "1")
6014 (const_string "*")))
6015 (set_attr "mode" "DI")])
6016
6017 ; For comparisons against 1, -1 and 128, we may generate better code
6018 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6019 ; is matched then. We can't accept general immediate, because for
6020 ; case of overflows, the result is messed up.
6021 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6022 ; only for comparisons not depending on it.
6023
6024 (define_insn "*add<mode>_4"
6025 [(set (reg FLAGS_REG)
6026 (compare
6027 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6028 (match_operand:SWI124 2 "const_int_operand" "n")))
6029 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6030 "ix86_match_ccmode (insn, CCGCmode)"
6031 {
6032 switch (get_attr_type (insn))
6033 {
6034 case TYPE_INCDEC:
6035 if (operands[2] == constm1_rtx)
6036 return "inc{<imodesuffix>}\t%0";
6037 else
6038 {
6039 gcc_assert (operands[2] == const1_rtx);
6040 return "dec{<imodesuffix>}\t%0";
6041 }
6042
6043 default:
6044 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6045 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6046
6047 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6048 }
6049 }
6050 [(set (attr "type")
6051 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6052 (const_string "incdec")
6053 (const_string "alu")))
6054 (set (attr "length_immediate")
6055 (if_then_else
6056 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6057 (const_string "1")
6058 (const_string "*")))
6059 (set_attr "mode" "<MODE>")])
6060
6061 (define_insn "*add<mode>_5"
6062 [(set (reg FLAGS_REG)
6063 (compare
6064 (plus:SWI
6065 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6066 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6067 (const_int 0)))
6068 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6069 "ix86_match_ccmode (insn, CCGOCmode)
6070 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6071 {
6072 switch (get_attr_type (insn))
6073 {
6074 case TYPE_INCDEC:
6075 if (operands[2] == const1_rtx)
6076 return "inc{<imodesuffix>}\t%0";
6077 else
6078 {
6079 gcc_assert (operands[2] == constm1_rtx);
6080 return "dec{<imodesuffix>}\t%0";
6081 }
6082
6083 default:
6084 if (which_alternative == 1)
6085 {
6086 rtx tmp;
6087 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6088 }
6089
6090 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6091 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6092 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6093
6094 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6095 }
6096 }
6097 [(set (attr "type")
6098 (if_then_else (match_operand:SWI 2 "incdec_operand")
6099 (const_string "incdec")
6100 (const_string "alu")))
6101 (set (attr "length_immediate")
6102 (if_then_else
6103 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6104 (const_string "1")
6105 (const_string "*")))
6106 (set_attr "mode" "<MODE>")])
6107
6108 (define_insn "addqi_ext_1"
6109 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6110 (const_int 8)
6111 (const_int 8))
6112 (plus:SI
6113 (zero_extract:SI
6114 (match_operand 1 "ext_register_operand" "0,0")
6115 (const_int 8)
6116 (const_int 8))
6117 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6118 (clobber (reg:CC FLAGS_REG))]
6119 ""
6120 {
6121 switch (get_attr_type (insn))
6122 {
6123 case TYPE_INCDEC:
6124 if (operands[2] == const1_rtx)
6125 return "inc{b}\t%h0";
6126 else
6127 {
6128 gcc_assert (operands[2] == constm1_rtx);
6129 return "dec{b}\t%h0";
6130 }
6131
6132 default:
6133 return "add{b}\t{%2, %h0|%h0, %2}";
6134 }
6135 }
6136 [(set_attr "isa" "*,nox64")
6137 (set (attr "type")
6138 (if_then_else (match_operand:QI 2 "incdec_operand")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set_attr "modrm" "1")
6142 (set_attr "mode" "QI")])
6143
6144 (define_insn "*addqi_ext_2"
6145 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6146 (const_int 8)
6147 (const_int 8))
6148 (plus:SI
6149 (zero_extract:SI
6150 (match_operand 1 "ext_register_operand" "%0")
6151 (const_int 8)
6152 (const_int 8))
6153 (zero_extract:SI
6154 (match_operand 2 "ext_register_operand" "Q")
6155 (const_int 8)
6156 (const_int 8))))
6157 (clobber (reg:CC FLAGS_REG))]
6158 ""
6159 "add{b}\t{%h2, %h0|%h0, %h2}"
6160 [(set_attr "type" "alu")
6161 (set_attr "mode" "QI")])
6162
6163 ;; Add with jump on overflow.
6164 (define_expand "addv<mode>4"
6165 [(parallel [(set (reg:CCO FLAGS_REG)
6166 (eq:CCO (plus:<DWI>
6167 (sign_extend:<DWI>
6168 (match_operand:SWI 1 "nonimmediate_operand"))
6169 (sign_extend:<DWI>
6170 (match_operand:SWI 2 "<general_operand>")))
6171 (sign_extend:<DWI>
6172 (plus:SWI (match_dup 1) (match_dup 2)))))
6173 (set (match_operand:SWI 0 "register_operand")
6174 (plus:SWI (match_dup 1) (match_dup 2)))])
6175 (set (pc) (if_then_else
6176 (eq (reg:CCO FLAGS_REG) (const_int 0))
6177 (label_ref (match_operand 3))
6178 (pc)))]
6179 ""
6180 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6181
6182 (define_insn "*addv<mode>4"
6183 [(set (reg:CCO FLAGS_REG)
6184 (eq:CCO (plus:<DWI>
6185 (sign_extend:<DWI>
6186 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6187 (sign_extend:<DWI>
6188 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")))
6189 (sign_extend:<DWI>
6190 (plus:SWI (match_dup 1) (match_dup 2)))))
6191 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6192 (plus:SWI (match_dup 1) (match_dup 2)))]
6193 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6194 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6195 [(set_attr "type" "alu")
6196 (set_attr "mode" "<MODE>")])
6197
6198 ;; The lea patterns for modes less than 32 bits need to be matched by
6199 ;; several insns converted to real lea by splitters.
6200
6201 (define_insn_and_split "*lea_general_1"
6202 [(set (match_operand 0 "register_operand" "=r")
6203 (plus (plus (match_operand 1 "index_register_operand" "l")
6204 (match_operand 2 "register_operand" "r"))
6205 (match_operand 3 "immediate_operand" "i")))]
6206 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6207 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6208 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6209 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6210 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6211 || GET_MODE (operands[3]) == VOIDmode)"
6212 "#"
6213 "&& reload_completed"
6214 [(const_int 0)]
6215 {
6216 enum machine_mode mode = SImode;
6217 rtx pat;
6218
6219 operands[0] = gen_lowpart (mode, operands[0]);
6220 operands[1] = gen_lowpart (mode, operands[1]);
6221 operands[2] = gen_lowpart (mode, operands[2]);
6222 operands[3] = gen_lowpart (mode, operands[3]);
6223
6224 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6225 operands[3]);
6226
6227 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6228 DONE;
6229 }
6230 [(set_attr "type" "lea")
6231 (set_attr "mode" "SI")])
6232
6233 (define_insn_and_split "*lea_general_2"
6234 [(set (match_operand 0 "register_operand" "=r")
6235 (plus (mult (match_operand 1 "index_register_operand" "l")
6236 (match_operand 2 "const248_operand" "n"))
6237 (match_operand 3 "nonmemory_operand" "ri")))]
6238 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6239 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6240 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6241 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6242 || GET_MODE (operands[3]) == VOIDmode)"
6243 "#"
6244 "&& reload_completed"
6245 [(const_int 0)]
6246 {
6247 enum machine_mode mode = SImode;
6248 rtx pat;
6249
6250 operands[0] = gen_lowpart (mode, operands[0]);
6251 operands[1] = gen_lowpart (mode, operands[1]);
6252 operands[3] = gen_lowpart (mode, operands[3]);
6253
6254 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6255 operands[3]);
6256
6257 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6258 DONE;
6259 }
6260 [(set_attr "type" "lea")
6261 (set_attr "mode" "SI")])
6262
6263 (define_insn_and_split "*lea_general_3"
6264 [(set (match_operand 0 "register_operand" "=r")
6265 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6266 (match_operand 2 "const248_operand" "n"))
6267 (match_operand 3 "register_operand" "r"))
6268 (match_operand 4 "immediate_operand" "i")))]
6269 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6270 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6271 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6272 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6273 "#"
6274 "&& reload_completed"
6275 [(const_int 0)]
6276 {
6277 enum machine_mode mode = SImode;
6278 rtx pat;
6279
6280 operands[0] = gen_lowpart (mode, operands[0]);
6281 operands[1] = gen_lowpart (mode, operands[1]);
6282 operands[3] = gen_lowpart (mode, operands[3]);
6283 operands[4] = gen_lowpart (mode, operands[4]);
6284
6285 pat = gen_rtx_PLUS (mode,
6286 gen_rtx_PLUS (mode,
6287 gen_rtx_MULT (mode, operands[1],
6288 operands[2]),
6289 operands[3]),
6290 operands[4]);
6291
6292 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6293 DONE;
6294 }
6295 [(set_attr "type" "lea")
6296 (set_attr "mode" "SI")])
6297
6298 (define_insn_and_split "*lea_general_4"
6299 [(set (match_operand 0 "register_operand" "=r")
6300 (any_or (ashift
6301 (match_operand 1 "index_register_operand" "l")
6302 (match_operand 2 "const_int_operand" "n"))
6303 (match_operand 3 "const_int_operand" "n")))]
6304 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6305 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6306 || GET_MODE (operands[0]) == SImode
6307 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6308 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6309 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6310 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6311 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6312 "#"
6313 "&& reload_completed"
6314 [(const_int 0)]
6315 {
6316 enum machine_mode mode = GET_MODE (operands[0]);
6317 rtx pat;
6318
6319 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6320 {
6321 mode = SImode;
6322 operands[0] = gen_lowpart (mode, operands[0]);
6323 operands[1] = gen_lowpart (mode, operands[1]);
6324 }
6325
6326 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6327
6328 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6329 INTVAL (operands[3]));
6330
6331 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6332 DONE;
6333 }
6334 [(set_attr "type" "lea")
6335 (set (attr "mode")
6336 (if_then_else (match_operand:DI 0)
6337 (const_string "DI")
6338 (const_string "SI")))])
6339 \f
6340 ;; Subtract instructions
6341
6342 (define_expand "sub<mode>3"
6343 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6344 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6345 (match_operand:SDWIM 2 "<general_operand>")))]
6346 ""
6347 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6348
6349 (define_insn_and_split "*sub<dwi>3_doubleword"
6350 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6351 (minus:<DWI>
6352 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6353 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6354 (clobber (reg:CC FLAGS_REG))]
6355 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6356 "#"
6357 "reload_completed"
6358 [(parallel [(set (reg:CC FLAGS_REG)
6359 (compare:CC (match_dup 1) (match_dup 2)))
6360 (set (match_dup 0)
6361 (minus:DWIH (match_dup 1) (match_dup 2)))])
6362 (parallel [(set (match_dup 3)
6363 (minus:DWIH
6364 (match_dup 4)
6365 (plus:DWIH
6366 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6367 (match_dup 5))))
6368 (clobber (reg:CC FLAGS_REG))])]
6369 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6370
6371 (define_insn "*sub<mode>_1"
6372 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6373 (minus:SWI
6374 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6375 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6376 (clobber (reg:CC FLAGS_REG))]
6377 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6378 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6379 [(set_attr "type" "alu")
6380 (set_attr "mode" "<MODE>")])
6381
6382 (define_insn "*subsi_1_zext"
6383 [(set (match_operand:DI 0 "register_operand" "=r")
6384 (zero_extend:DI
6385 (minus:SI (match_operand:SI 1 "register_operand" "0")
6386 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6387 (clobber (reg:CC FLAGS_REG))]
6388 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6389 "sub{l}\t{%2, %k0|%k0, %2}"
6390 [(set_attr "type" "alu")
6391 (set_attr "mode" "SI")])
6392
6393 (define_insn "*subqi_1_slp"
6394 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6395 (minus:QI (match_dup 0)
6396 (match_operand:QI 1 "general_operand" "qn,qm")))
6397 (clobber (reg:CC FLAGS_REG))]
6398 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6400 "sub{b}\t{%1, %0|%0, %1}"
6401 [(set_attr "type" "alu1")
6402 (set_attr "mode" "QI")])
6403
6404 (define_insn "*sub<mode>_2"
6405 [(set (reg FLAGS_REG)
6406 (compare
6407 (minus:SWI
6408 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6409 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6410 (const_int 0)))
6411 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6412 (minus:SWI (match_dup 1) (match_dup 2)))]
6413 "ix86_match_ccmode (insn, CCGOCmode)
6414 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6415 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "<MODE>")])
6418
6419 (define_insn "*subsi_2_zext"
6420 [(set (reg FLAGS_REG)
6421 (compare
6422 (minus:SI (match_operand:SI 1 "register_operand" "0")
6423 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6424 (const_int 0)))
6425 (set (match_operand:DI 0 "register_operand" "=r")
6426 (zero_extend:DI
6427 (minus:SI (match_dup 1)
6428 (match_dup 2))))]
6429 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6430 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6431 "sub{l}\t{%2, %k0|%k0, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "SI")])
6434
6435 ;; Subtract with jump on overflow.
6436 (define_expand "subv<mode>4"
6437 [(parallel [(set (reg:CCO FLAGS_REG)
6438 (eq:CCO (minus:<DWI>
6439 (sign_extend:<DWI>
6440 (match_operand:SWI 1 "nonimmediate_operand"))
6441 (sign_extend:<DWI>
6442 (match_operand:SWI 2 "<general_operand>")))
6443 (sign_extend:<DWI>
6444 (minus:SWI (match_dup 1) (match_dup 2)))))
6445 (set (match_operand:SWI 0 "register_operand")
6446 (minus:SWI (match_dup 1) (match_dup 2)))])
6447 (set (pc) (if_then_else
6448 (eq (reg:CCO FLAGS_REG) (const_int 0))
6449 (label_ref (match_operand 3))
6450 (pc)))]
6451 ""
6452 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6453
6454 (define_insn "*subv<mode>4"
6455 [(set (reg:CCO FLAGS_REG)
6456 (eq:CCO (minus:<DWI>
6457 (sign_extend:<DWI>
6458 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6459 (sign_extend:<DWI>
6460 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6461 (sign_extend:<DWI>
6462 (minus:SWI (match_dup 1) (match_dup 2)))))
6463 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6464 (minus:SWI (match_dup 1) (match_dup 2)))]
6465 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "<MODE>")])
6469
6470 (define_insn "*sub<mode>_3"
6471 [(set (reg FLAGS_REG)
6472 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6475 (minus:SWI (match_dup 1) (match_dup 2)))]
6476 "ix86_match_ccmode (insn, CCmode)
6477 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6478 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6479 [(set_attr "type" "alu")
6480 (set_attr "mode" "<MODE>")])
6481
6482 (define_insn "*subsi_3_zext"
6483 [(set (reg FLAGS_REG)
6484 (compare (match_operand:SI 1 "register_operand" "0")
6485 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6486 (set (match_operand:DI 0 "register_operand" "=r")
6487 (zero_extend:DI
6488 (minus:SI (match_dup 1)
6489 (match_dup 2))))]
6490 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6491 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6492 "sub{l}\t{%2, %1|%1, %2}"
6493 [(set_attr "type" "alu")
6494 (set_attr "mode" "SI")])
6495 \f
6496 ;; Add with carry and subtract with borrow
6497
6498 (define_expand "<plusminus_insn><mode>3_carry"
6499 [(parallel
6500 [(set (match_operand:SWI 0 "nonimmediate_operand")
6501 (plusminus:SWI
6502 (match_operand:SWI 1 "nonimmediate_operand")
6503 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6504 [(match_operand 3 "flags_reg_operand")
6505 (const_int 0)])
6506 (match_operand:SWI 2 "<general_operand>"))))
6507 (clobber (reg:CC FLAGS_REG))])]
6508 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6509
6510 (define_insn "*<plusminus_insn><mode>3_carry"
6511 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6512 (plusminus:SWI
6513 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6514 (plus:SWI
6515 (match_operator 3 "ix86_carry_flag_operator"
6516 [(reg FLAGS_REG) (const_int 0)])
6517 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6518 (clobber (reg:CC FLAGS_REG))]
6519 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6520 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "use_carry" "1")
6523 (set_attr "pent_pair" "pu")
6524 (set_attr "mode" "<MODE>")])
6525
6526 (define_insn "*addsi3_carry_zext"
6527 [(set (match_operand:DI 0 "register_operand" "=r")
6528 (zero_extend:DI
6529 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6530 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6531 [(reg FLAGS_REG) (const_int 0)])
6532 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6533 (clobber (reg:CC FLAGS_REG))]
6534 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6535 "adc{l}\t{%2, %k0|%k0, %2}"
6536 [(set_attr "type" "alu")
6537 (set_attr "use_carry" "1")
6538 (set_attr "pent_pair" "pu")
6539 (set_attr "mode" "SI")])
6540
6541 (define_insn "*subsi3_carry_zext"
6542 [(set (match_operand:DI 0 "register_operand" "=r")
6543 (zero_extend:DI
6544 (minus:SI (match_operand:SI 1 "register_operand" "0")
6545 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6546 [(reg FLAGS_REG) (const_int 0)])
6547 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6548 (clobber (reg:CC FLAGS_REG))]
6549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6550 "sbb{l}\t{%2, %k0|%k0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "pent_pair" "pu")
6553 (set_attr "mode" "SI")])
6554 \f
6555 ;; ADCX instruction
6556
6557 (define_insn "adcx<mode>3"
6558 [(set (reg:CCC FLAGS_REG)
6559 (compare:CCC
6560 (plus:SWI48
6561 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6562 (plus:SWI48
6563 (match_operator 4 "ix86_carry_flag_operator"
6564 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6565 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6566 (const_int 0)))
6567 (set (match_operand:SWI48 0 "register_operand" "=r")
6568 (plus:SWI48 (match_dup 1)
6569 (plus:SWI48 (match_op_dup 4
6570 [(match_dup 3) (const_int 0)])
6571 (match_dup 2))))]
6572 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6573 "adcx\t{%2, %0|%0, %2}"
6574 [(set_attr "type" "alu")
6575 (set_attr "use_carry" "1")
6576 (set_attr "mode" "<MODE>")])
6577 \f
6578 ;; Overflow setting add instructions
6579
6580 (define_insn "*add<mode>3_cconly_overflow"
6581 [(set (reg:CCC FLAGS_REG)
6582 (compare:CCC
6583 (plus:SWI
6584 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6585 (match_operand:SWI 2 "<general_operand>" "<g>"))
6586 (match_dup 1)))
6587 (clobber (match_scratch:SWI 0 "=<r>"))]
6588 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6589 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6590 [(set_attr "type" "alu")
6591 (set_attr "mode" "<MODE>")])
6592
6593 (define_insn "*add<mode>3_cc_overflow"
6594 [(set (reg:CCC FLAGS_REG)
6595 (compare:CCC
6596 (plus:SWI
6597 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6598 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6599 (match_dup 1)))
6600 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6601 (plus:SWI (match_dup 1) (match_dup 2)))]
6602 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6603 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6604 [(set_attr "type" "alu")
6605 (set_attr "mode" "<MODE>")])
6606
6607 (define_insn "*addsi3_zext_cc_overflow"
6608 [(set (reg:CCC FLAGS_REG)
6609 (compare:CCC
6610 (plus:SI
6611 (match_operand:SI 1 "nonimmediate_operand" "%0")
6612 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6613 (match_dup 1)))
6614 (set (match_operand:DI 0 "register_operand" "=r")
6615 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6616 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6617 "add{l}\t{%2, %k0|%k0, %2}"
6618 [(set_attr "type" "alu")
6619 (set_attr "mode" "SI")])
6620
6621 ;; The patterns that match these are at the end of this file.
6622
6623 (define_expand "<plusminus_insn>xf3"
6624 [(set (match_operand:XF 0 "register_operand")
6625 (plusminus:XF
6626 (match_operand:XF 1 "register_operand")
6627 (match_operand:XF 2 "register_operand")))]
6628 "TARGET_80387")
6629
6630 (define_expand "<plusminus_insn><mode>3"
6631 [(set (match_operand:MODEF 0 "register_operand")
6632 (plusminus:MODEF
6633 (match_operand:MODEF 1 "register_operand")
6634 (match_operand:MODEF 2 "nonimmediate_operand")))]
6635 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6636 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6637 \f
6638 ;; Multiply instructions
6639
6640 (define_expand "mul<mode>3"
6641 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6642 (mult:SWIM248
6643 (match_operand:SWIM248 1 "register_operand")
6644 (match_operand:SWIM248 2 "<general_operand>")))
6645 (clobber (reg:CC FLAGS_REG))])])
6646
6647 (define_expand "mulqi3"
6648 [(parallel [(set (match_operand:QI 0 "register_operand")
6649 (mult:QI
6650 (match_operand:QI 1 "register_operand")
6651 (match_operand:QI 2 "nonimmediate_operand")))
6652 (clobber (reg:CC FLAGS_REG))])]
6653 "TARGET_QIMODE_MATH")
6654
6655 ;; On AMDFAM10
6656 ;; IMUL reg32/64, reg32/64, imm8 Direct
6657 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6658 ;; IMUL reg32/64, reg32/64, imm32 Direct
6659 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6660 ;; IMUL reg32/64, reg32/64 Direct
6661 ;; IMUL reg32/64, mem32/64 Direct
6662 ;;
6663 ;; On BDVER1, all above IMULs use DirectPath
6664
6665 (define_insn "*mul<mode>3_1"
6666 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6667 (mult:SWI48
6668 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6669 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6670 (clobber (reg:CC FLAGS_REG))]
6671 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6672 "@
6673 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6674 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6675 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "imul")
6677 (set_attr "prefix_0f" "0,0,1")
6678 (set (attr "athlon_decode")
6679 (cond [(eq_attr "cpu" "athlon")
6680 (const_string "vector")
6681 (eq_attr "alternative" "1")
6682 (const_string "vector")
6683 (and (eq_attr "alternative" "2")
6684 (match_operand 1 "memory_operand"))
6685 (const_string "vector")]
6686 (const_string "direct")))
6687 (set (attr "amdfam10_decode")
6688 (cond [(and (eq_attr "alternative" "0,1")
6689 (match_operand 1 "memory_operand"))
6690 (const_string "vector")]
6691 (const_string "direct")))
6692 (set_attr "bdver1_decode" "direct")
6693 (set_attr "mode" "<MODE>")])
6694
6695 (define_insn "*mulsi3_1_zext"
6696 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6697 (zero_extend:DI
6698 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6699 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6700 (clobber (reg:CC FLAGS_REG))]
6701 "TARGET_64BIT
6702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6703 "@
6704 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6705 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6706 imul{l}\t{%2, %k0|%k0, %2}"
6707 [(set_attr "type" "imul")
6708 (set_attr "prefix_0f" "0,0,1")
6709 (set (attr "athlon_decode")
6710 (cond [(eq_attr "cpu" "athlon")
6711 (const_string "vector")
6712 (eq_attr "alternative" "1")
6713 (const_string "vector")
6714 (and (eq_attr "alternative" "2")
6715 (match_operand 1 "memory_operand"))
6716 (const_string "vector")]
6717 (const_string "direct")))
6718 (set (attr "amdfam10_decode")
6719 (cond [(and (eq_attr "alternative" "0,1")
6720 (match_operand 1 "memory_operand"))
6721 (const_string "vector")]
6722 (const_string "direct")))
6723 (set_attr "bdver1_decode" "direct")
6724 (set_attr "mode" "SI")])
6725
6726 ;; On AMDFAM10
6727 ;; IMUL reg16, reg16, imm8 VectorPath
6728 ;; IMUL reg16, mem16, imm8 VectorPath
6729 ;; IMUL reg16, reg16, imm16 VectorPath
6730 ;; IMUL reg16, mem16, imm16 VectorPath
6731 ;; IMUL reg16, reg16 Direct
6732 ;; IMUL reg16, mem16 Direct
6733 ;;
6734 ;; On BDVER1, all HI MULs use DoublePath
6735
6736 (define_insn "*mulhi3_1"
6737 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6738 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6739 (match_operand:HI 2 "general_operand" "K,n,mr")))
6740 (clobber (reg:CC FLAGS_REG))]
6741 "TARGET_HIMODE_MATH
6742 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6743 "@
6744 imul{w}\t{%2, %1, %0|%0, %1, %2}
6745 imul{w}\t{%2, %1, %0|%0, %1, %2}
6746 imul{w}\t{%2, %0|%0, %2}"
6747 [(set_attr "type" "imul")
6748 (set_attr "prefix_0f" "0,0,1")
6749 (set (attr "athlon_decode")
6750 (cond [(eq_attr "cpu" "athlon")
6751 (const_string "vector")
6752 (eq_attr "alternative" "1,2")
6753 (const_string "vector")]
6754 (const_string "direct")))
6755 (set (attr "amdfam10_decode")
6756 (cond [(eq_attr "alternative" "0,1")
6757 (const_string "vector")]
6758 (const_string "direct")))
6759 (set_attr "bdver1_decode" "double")
6760 (set_attr "mode" "HI")])
6761
6762 ;;On AMDFAM10 and BDVER1
6763 ;; MUL reg8 Direct
6764 ;; MUL mem8 Direct
6765
6766 (define_insn "*mulqi3_1"
6767 [(set (match_operand:QI 0 "register_operand" "=a")
6768 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6769 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "TARGET_QIMODE_MATH
6772 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6773 "mul{b}\t%2"
6774 [(set_attr "type" "imul")
6775 (set_attr "length_immediate" "0")
6776 (set (attr "athlon_decode")
6777 (if_then_else (eq_attr "cpu" "athlon")
6778 (const_string "vector")
6779 (const_string "direct")))
6780 (set_attr "amdfam10_decode" "direct")
6781 (set_attr "bdver1_decode" "direct")
6782 (set_attr "mode" "QI")])
6783
6784 ;; Multiply with jump on overflow.
6785 (define_expand "mulv<mode>4"
6786 [(parallel [(set (reg:CCO FLAGS_REG)
6787 (eq:CCO (mult:<DWI>
6788 (sign_extend:<DWI>
6789 (match_operand:SWI48 1 "register_operand"))
6790 (sign_extend:<DWI>
6791 (match_operand:SWI48 2 "<general_operand>")))
6792 (sign_extend:<DWI>
6793 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6794 (set (match_operand:SWI48 0 "register_operand")
6795 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6796 (set (pc) (if_then_else
6797 (eq (reg:CCO FLAGS_REG) (const_int 0))
6798 (label_ref (match_operand 3))
6799 (pc)))])
6800
6801 (define_insn "*mulv<mode>4"
6802 [(set (reg:CCO FLAGS_REG)
6803 (eq:CCO (mult:<DWI>
6804 (sign_extend:<DWI>
6805 (match_operand:SWI 1 "nonimmediate_operand" "%rm,rm,0"))
6806 (sign_extend:<DWI>
6807 (match_operand:SWI 2 "<general_operand>" "K,<i>,mr")))
6808 (sign_extend:<DWI>
6809 (mult:SWI (match_dup 1) (match_dup 2)))))
6810 (set (match_operand:SWI 0 "register_operand" "=r,r,r")
6811 (mult:SWI (match_dup 1) (match_dup 2)))]
6812 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6813 "@
6814 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6815 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6816 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6817 [(set_attr "type" "imul")
6818 (set_attr "prefix_0f" "0,0,1")
6819 (set (attr "athlon_decode")
6820 (cond [(eq_attr "cpu" "athlon")
6821 (const_string "vector")
6822 (eq_attr "alternative" "1")
6823 (const_string "vector")
6824 (and (eq_attr "alternative" "2")
6825 (match_operand 1 "memory_operand"))
6826 (const_string "vector")]
6827 (const_string "direct")))
6828 (set (attr "amdfam10_decode")
6829 (cond [(and (eq_attr "alternative" "0,1")
6830 (match_operand 1 "memory_operand"))
6831 (const_string "vector")]
6832 (const_string "direct")))
6833 (set_attr "bdver1_decode" "direct")
6834 (set_attr "mode" "<MODE>")])
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 "*bmi2_umulditi3_1"
6856 [(set (match_operand:DI 0 "register_operand" "=r")
6857 (mult:DI
6858 (match_operand:DI 2 "nonimmediate_operand" "%d")
6859 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6860 (set (match_operand:DI 1 "register_operand" "=r")
6861 (truncate:DI
6862 (lshiftrt:TI
6863 (mult:TI (zero_extend:TI (match_dup 2))
6864 (zero_extend:TI (match_dup 3)))
6865 (const_int 64))))]
6866 "TARGET_64BIT && TARGET_BMI2
6867 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6868 "mulx\t{%3, %0, %1|%1, %0, %3}"
6869 [(set_attr "type" "imulx")
6870 (set_attr "prefix" "vex")
6871 (set_attr "mode" "DI")])
6872
6873 (define_insn "*bmi2_umulsidi3_1"
6874 [(set (match_operand:SI 0 "register_operand" "=r")
6875 (mult:SI
6876 (match_operand:SI 2 "nonimmediate_operand" "%d")
6877 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6878 (set (match_operand:SI 1 "register_operand" "=r")
6879 (truncate:SI
6880 (lshiftrt:DI
6881 (mult:DI (zero_extend:DI (match_dup 2))
6882 (zero_extend:DI (match_dup 3)))
6883 (const_int 32))))]
6884 "!TARGET_64BIT && TARGET_BMI2
6885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886 "mulx\t{%3, %0, %1|%1, %0, %3}"
6887 [(set_attr "type" "imulx")
6888 (set_attr "prefix" "vex")
6889 (set_attr "mode" "SI")])
6890
6891 (define_insn "*umul<mode><dwi>3_1"
6892 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6893 (mult:<DWI>
6894 (zero_extend:<DWI>
6895 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6896 (zero_extend:<DWI>
6897 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6898 (clobber (reg:CC FLAGS_REG))]
6899 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6900 "@
6901 #
6902 mul{<imodesuffix>}\t%2"
6903 [(set_attr "isa" "bmi2,*")
6904 (set_attr "type" "imulx,imul")
6905 (set_attr "length_immediate" "*,0")
6906 (set (attr "athlon_decode")
6907 (cond [(eq_attr "alternative" "1")
6908 (if_then_else (eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (const_string "double"))]
6911 (const_string "*")))
6912 (set_attr "amdfam10_decode" "*,double")
6913 (set_attr "bdver1_decode" "*,direct")
6914 (set_attr "prefix" "vex,orig")
6915 (set_attr "mode" "<MODE>")])
6916
6917 ;; Convert mul to the mulx pattern to avoid flags dependency.
6918 (define_split
6919 [(set (match_operand:<DWI> 0 "register_operand")
6920 (mult:<DWI>
6921 (zero_extend:<DWI>
6922 (match_operand:DWIH 1 "register_operand"))
6923 (zero_extend:<DWI>
6924 (match_operand:DWIH 2 "nonimmediate_operand"))))
6925 (clobber (reg:CC FLAGS_REG))]
6926 "TARGET_BMI2 && reload_completed
6927 && true_regnum (operands[1]) == DX_REG"
6928 [(parallel [(set (match_dup 3)
6929 (mult:DWIH (match_dup 1) (match_dup 2)))
6930 (set (match_dup 4)
6931 (truncate:DWIH
6932 (lshiftrt:<DWI>
6933 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6934 (zero_extend:<DWI> (match_dup 2)))
6935 (match_dup 5))))])]
6936 {
6937 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6938
6939 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6940 })
6941
6942 (define_insn "*mul<mode><dwi>3_1"
6943 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6944 (mult:<DWI>
6945 (sign_extend:<DWI>
6946 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6947 (sign_extend:<DWI>
6948 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951 "imul{<imodesuffix>}\t%2"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "double")))
6958 (set_attr "amdfam10_decode" "double")
6959 (set_attr "bdver1_decode" "direct")
6960 (set_attr "mode" "<MODE>")])
6961
6962 (define_insn "*<u>mulqihi3_1"
6963 [(set (match_operand:HI 0 "register_operand" "=a")
6964 (mult:HI
6965 (any_extend:HI
6966 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6967 (any_extend:HI
6968 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6969 (clobber (reg:CC FLAGS_REG))]
6970 "TARGET_QIMODE_MATH
6971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6972 "<sgnprefix>mul{b}\t%2"
6973 [(set_attr "type" "imul")
6974 (set_attr "length_immediate" "0")
6975 (set (attr "athlon_decode")
6976 (if_then_else (eq_attr "cpu" "athlon")
6977 (const_string "vector")
6978 (const_string "direct")))
6979 (set_attr "amdfam10_decode" "direct")
6980 (set_attr "bdver1_decode" "direct")
6981 (set_attr "mode" "QI")])
6982
6983 (define_expand "<s>mul<mode>3_highpart"
6984 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6985 (truncate:SWI48
6986 (lshiftrt:<DWI>
6987 (mult:<DWI>
6988 (any_extend:<DWI>
6989 (match_operand:SWI48 1 "nonimmediate_operand"))
6990 (any_extend:<DWI>
6991 (match_operand:SWI48 2 "register_operand")))
6992 (match_dup 4))))
6993 (clobber (match_scratch:SWI48 3))
6994 (clobber (reg:CC FLAGS_REG))])]
6995 ""
6996 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6997
6998 (define_insn "*<s>muldi3_highpart_1"
6999 [(set (match_operand:DI 0 "register_operand" "=d")
7000 (truncate:DI
7001 (lshiftrt:TI
7002 (mult:TI
7003 (any_extend:TI
7004 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7005 (any_extend:TI
7006 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7007 (const_int 64))))
7008 (clobber (match_scratch:DI 3 "=1"))
7009 (clobber (reg:CC FLAGS_REG))]
7010 "TARGET_64BIT
7011 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7012 "<sgnprefix>mul{q}\t%2"
7013 [(set_attr "type" "imul")
7014 (set_attr "length_immediate" "0")
7015 (set (attr "athlon_decode")
7016 (if_then_else (eq_attr "cpu" "athlon")
7017 (const_string "vector")
7018 (const_string "double")))
7019 (set_attr "amdfam10_decode" "double")
7020 (set_attr "bdver1_decode" "direct")
7021 (set_attr "mode" "DI")])
7022
7023 (define_insn "*<s>mulsi3_highpart_1"
7024 [(set (match_operand:SI 0 "register_operand" "=d")
7025 (truncate:SI
7026 (lshiftrt:DI
7027 (mult:DI
7028 (any_extend:DI
7029 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7030 (any_extend:DI
7031 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7032 (const_int 32))))
7033 (clobber (match_scratch:SI 3 "=1"))
7034 (clobber (reg:CC FLAGS_REG))]
7035 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036 "<sgnprefix>mul{l}\t%2"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "double")))
7043 (set_attr "amdfam10_decode" "double")
7044 (set_attr "bdver1_decode" "direct")
7045 (set_attr "mode" "SI")])
7046
7047 (define_insn "*<s>mulsi3_highpart_zext"
7048 [(set (match_operand:DI 0 "register_operand" "=d")
7049 (zero_extend:DI (truncate:SI
7050 (lshiftrt:DI
7051 (mult:DI (any_extend:DI
7052 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7053 (any_extend:DI
7054 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7055 (const_int 32)))))
7056 (clobber (match_scratch:SI 3 "=1"))
7057 (clobber (reg:CC FLAGS_REG))]
7058 "TARGET_64BIT
7059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7060 "<sgnprefix>mul{l}\t%2"
7061 [(set_attr "type" "imul")
7062 (set_attr "length_immediate" "0")
7063 (set (attr "athlon_decode")
7064 (if_then_else (eq_attr "cpu" "athlon")
7065 (const_string "vector")
7066 (const_string "double")))
7067 (set_attr "amdfam10_decode" "double")
7068 (set_attr "bdver1_decode" "direct")
7069 (set_attr "mode" "SI")])
7070
7071 ;; The patterns that match these are at the end of this file.
7072
7073 (define_expand "mulxf3"
7074 [(set (match_operand:XF 0 "register_operand")
7075 (mult:XF (match_operand:XF 1 "register_operand")
7076 (match_operand:XF 2 "register_operand")))]
7077 "TARGET_80387")
7078
7079 (define_expand "mul<mode>3"
7080 [(set (match_operand:MODEF 0 "register_operand")
7081 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7082 (match_operand:MODEF 2 "nonimmediate_operand")))]
7083 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7084 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7085 \f
7086 ;; Divide instructions
7087
7088 ;; The patterns that match these are at the end of this file.
7089
7090 (define_expand "divxf3"
7091 [(set (match_operand:XF 0 "register_operand")
7092 (div:XF (match_operand:XF 1 "register_operand")
7093 (match_operand:XF 2 "register_operand")))]
7094 "TARGET_80387")
7095
7096 (define_expand "divdf3"
7097 [(set (match_operand:DF 0 "register_operand")
7098 (div:DF (match_operand:DF 1 "register_operand")
7099 (match_operand:DF 2 "nonimmediate_operand")))]
7100 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7101 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7102
7103 (define_expand "divsf3"
7104 [(set (match_operand:SF 0 "register_operand")
7105 (div:SF (match_operand:SF 1 "register_operand")
7106 (match_operand:SF 2 "nonimmediate_operand")))]
7107 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7108 || TARGET_SSE_MATH"
7109 {
7110 if (TARGET_SSE_MATH
7111 && TARGET_RECIP_DIV
7112 && optimize_insn_for_speed_p ()
7113 && flag_finite_math_only && !flag_trapping_math
7114 && flag_unsafe_math_optimizations)
7115 {
7116 ix86_emit_swdivsf (operands[0], operands[1],
7117 operands[2], SFmode);
7118 DONE;
7119 }
7120 })
7121 \f
7122 ;; Divmod instructions.
7123
7124 (define_expand "divmod<mode>4"
7125 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7126 (div:SWIM248
7127 (match_operand:SWIM248 1 "register_operand")
7128 (match_operand:SWIM248 2 "nonimmediate_operand")))
7129 (set (match_operand:SWIM248 3 "register_operand")
7130 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7131 (clobber (reg:CC FLAGS_REG))])])
7132
7133 ;; Split with 8bit unsigned divide:
7134 ;; if (dividend an divisor are in [0-255])
7135 ;; use 8bit unsigned integer divide
7136 ;; else
7137 ;; use original integer divide
7138 (define_split
7139 [(set (match_operand:SWI48 0 "register_operand")
7140 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7141 (match_operand:SWI48 3 "nonimmediate_operand")))
7142 (set (match_operand:SWI48 1 "register_operand")
7143 (mod:SWI48 (match_dup 2) (match_dup 3)))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "TARGET_USE_8BIT_IDIV
7146 && TARGET_QIMODE_MATH
7147 && can_create_pseudo_p ()
7148 && !optimize_insn_for_size_p ()"
7149 [(const_int 0)]
7150 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7151
7152 (define_insn_and_split "divmod<mode>4_1"
7153 [(set (match_operand:SWI48 0 "register_operand" "=a")
7154 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7155 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7156 (set (match_operand:SWI48 1 "register_operand" "=&d")
7157 (mod:SWI48 (match_dup 2) (match_dup 3)))
7158 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7159 (clobber (reg:CC FLAGS_REG))]
7160 ""
7161 "#"
7162 "reload_completed"
7163 [(parallel [(set (match_dup 1)
7164 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7165 (clobber (reg:CC FLAGS_REG))])
7166 (parallel [(set (match_dup 0)
7167 (div:SWI48 (match_dup 2) (match_dup 3)))
7168 (set (match_dup 1)
7169 (mod:SWI48 (match_dup 2) (match_dup 3)))
7170 (use (match_dup 1))
7171 (clobber (reg:CC FLAGS_REG))])]
7172 {
7173 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7174
7175 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7176 operands[4] = operands[2];
7177 else
7178 {
7179 /* Avoid use of cltd in favor of a mov+shift. */
7180 emit_move_insn (operands[1], operands[2]);
7181 operands[4] = operands[1];
7182 }
7183 }
7184 [(set_attr "type" "multi")
7185 (set_attr "mode" "<MODE>")])
7186
7187 (define_insn_and_split "*divmod<mode>4"
7188 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7189 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7190 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7191 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7192 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7193 (clobber (reg:CC FLAGS_REG))]
7194 ""
7195 "#"
7196 "reload_completed"
7197 [(parallel [(set (match_dup 1)
7198 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7199 (clobber (reg:CC FLAGS_REG))])
7200 (parallel [(set (match_dup 0)
7201 (div:SWIM248 (match_dup 2) (match_dup 3)))
7202 (set (match_dup 1)
7203 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7204 (use (match_dup 1))
7205 (clobber (reg:CC FLAGS_REG))])]
7206 {
7207 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7208
7209 if (<MODE>mode != HImode
7210 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7211 operands[4] = operands[2];
7212 else
7213 {
7214 /* Avoid use of cltd in favor of a mov+shift. */
7215 emit_move_insn (operands[1], operands[2]);
7216 operands[4] = operands[1];
7217 }
7218 }
7219 [(set_attr "type" "multi")
7220 (set_attr "mode" "<MODE>")])
7221
7222 (define_insn "*divmod<mode>4_noext"
7223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7224 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7225 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7226 (set (match_operand:SWIM248 1 "register_operand" "=d")
7227 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7228 (use (match_operand:SWIM248 4 "register_operand" "1"))
7229 (clobber (reg:CC FLAGS_REG))]
7230 ""
7231 "idiv{<imodesuffix>}\t%3"
7232 [(set_attr "type" "idiv")
7233 (set_attr "mode" "<MODE>")])
7234
7235 (define_expand "divmodqi4"
7236 [(parallel [(set (match_operand:QI 0 "register_operand")
7237 (div:QI
7238 (match_operand:QI 1 "register_operand")
7239 (match_operand:QI 2 "nonimmediate_operand")))
7240 (set (match_operand:QI 3 "register_operand")
7241 (mod:QI (match_dup 1) (match_dup 2)))
7242 (clobber (reg:CC FLAGS_REG))])]
7243 "TARGET_QIMODE_MATH"
7244 {
7245 rtx div, mod, insn;
7246 rtx tmp0, tmp1;
7247
7248 tmp0 = gen_reg_rtx (HImode);
7249 tmp1 = gen_reg_rtx (HImode);
7250
7251 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7252 in AX. */
7253 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7254 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7255
7256 /* Extract remainder from AH. */
7257 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7258 insn = emit_move_insn (operands[3], tmp1);
7259
7260 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7261 set_unique_reg_note (insn, REG_EQUAL, mod);
7262
7263 /* Extract quotient from AL. */
7264 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7265
7266 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7267 set_unique_reg_note (insn, REG_EQUAL, div);
7268
7269 DONE;
7270 })
7271
7272 ;; Divide AX by r/m8, with result stored in
7273 ;; AL <- Quotient
7274 ;; AH <- Remainder
7275 ;; Change div/mod to HImode and extend the second argument to HImode
7276 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7277 ;; combine may fail.
7278 (define_insn "divmodhiqi3"
7279 [(set (match_operand:HI 0 "register_operand" "=a")
7280 (ior:HI
7281 (ashift:HI
7282 (zero_extend:HI
7283 (truncate:QI
7284 (mod:HI (match_operand:HI 1 "register_operand" "0")
7285 (sign_extend:HI
7286 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7287 (const_int 8))
7288 (zero_extend:HI
7289 (truncate:QI
7290 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7291 (clobber (reg:CC FLAGS_REG))]
7292 "TARGET_QIMODE_MATH"
7293 "idiv{b}\t%2"
7294 [(set_attr "type" "idiv")
7295 (set_attr "mode" "QI")])
7296
7297 (define_expand "udivmod<mode>4"
7298 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7299 (udiv:SWIM248
7300 (match_operand:SWIM248 1 "register_operand")
7301 (match_operand:SWIM248 2 "nonimmediate_operand")))
7302 (set (match_operand:SWIM248 3 "register_operand")
7303 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7304 (clobber (reg:CC FLAGS_REG))])])
7305
7306 ;; Split with 8bit unsigned divide:
7307 ;; if (dividend an divisor are in [0-255])
7308 ;; use 8bit unsigned integer divide
7309 ;; else
7310 ;; use original integer divide
7311 (define_split
7312 [(set (match_operand:SWI48 0 "register_operand")
7313 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7314 (match_operand:SWI48 3 "nonimmediate_operand")))
7315 (set (match_operand:SWI48 1 "register_operand")
7316 (umod:SWI48 (match_dup 2) (match_dup 3)))
7317 (clobber (reg:CC FLAGS_REG))]
7318 "TARGET_USE_8BIT_IDIV
7319 && TARGET_QIMODE_MATH
7320 && can_create_pseudo_p ()
7321 && !optimize_insn_for_size_p ()"
7322 [(const_int 0)]
7323 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7324
7325 (define_insn_and_split "udivmod<mode>4_1"
7326 [(set (match_operand:SWI48 0 "register_operand" "=a")
7327 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7328 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7329 (set (match_operand:SWI48 1 "register_operand" "=&d")
7330 (umod:SWI48 (match_dup 2) (match_dup 3)))
7331 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7332 (clobber (reg:CC FLAGS_REG))]
7333 ""
7334 "#"
7335 "reload_completed"
7336 [(set (match_dup 1) (const_int 0))
7337 (parallel [(set (match_dup 0)
7338 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7339 (set (match_dup 1)
7340 (umod:SWI48 (match_dup 2) (match_dup 3)))
7341 (use (match_dup 1))
7342 (clobber (reg:CC FLAGS_REG))])]
7343 ""
7344 [(set_attr "type" "multi")
7345 (set_attr "mode" "<MODE>")])
7346
7347 (define_insn_and_split "*udivmod<mode>4"
7348 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7349 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7350 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7351 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7352 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7353 (clobber (reg:CC FLAGS_REG))]
7354 ""
7355 "#"
7356 "reload_completed"
7357 [(set (match_dup 1) (const_int 0))
7358 (parallel [(set (match_dup 0)
7359 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7360 (set (match_dup 1)
7361 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7362 (use (match_dup 1))
7363 (clobber (reg:CC FLAGS_REG))])]
7364 ""
7365 [(set_attr "type" "multi")
7366 (set_attr "mode" "<MODE>")])
7367
7368 (define_insn "*udivmod<mode>4_noext"
7369 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7370 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7371 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7372 (set (match_operand:SWIM248 1 "register_operand" "=d")
7373 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7374 (use (match_operand:SWIM248 4 "register_operand" "1"))
7375 (clobber (reg:CC FLAGS_REG))]
7376 ""
7377 "div{<imodesuffix>}\t%3"
7378 [(set_attr "type" "idiv")
7379 (set_attr "mode" "<MODE>")])
7380
7381 (define_expand "udivmodqi4"
7382 [(parallel [(set (match_operand:QI 0 "register_operand")
7383 (udiv:QI
7384 (match_operand:QI 1 "register_operand")
7385 (match_operand:QI 2 "nonimmediate_operand")))
7386 (set (match_operand:QI 3 "register_operand")
7387 (umod:QI (match_dup 1) (match_dup 2)))
7388 (clobber (reg:CC FLAGS_REG))])]
7389 "TARGET_QIMODE_MATH"
7390 {
7391 rtx div, mod, insn;
7392 rtx tmp0, tmp1;
7393
7394 tmp0 = gen_reg_rtx (HImode);
7395 tmp1 = gen_reg_rtx (HImode);
7396
7397 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7398 in AX. */
7399 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7400 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7401
7402 /* Extract remainder from AH. */
7403 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7404 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7405 insn = emit_move_insn (operands[3], tmp1);
7406
7407 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7408 set_unique_reg_note (insn, REG_EQUAL, mod);
7409
7410 /* Extract quotient from AL. */
7411 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7412
7413 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7414 set_unique_reg_note (insn, REG_EQUAL, div);
7415
7416 DONE;
7417 })
7418
7419 (define_insn "udivmodhiqi3"
7420 [(set (match_operand:HI 0 "register_operand" "=a")
7421 (ior:HI
7422 (ashift:HI
7423 (zero_extend:HI
7424 (truncate:QI
7425 (mod:HI (match_operand:HI 1 "register_operand" "0")
7426 (zero_extend:HI
7427 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7428 (const_int 8))
7429 (zero_extend:HI
7430 (truncate:QI
7431 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7432 (clobber (reg:CC FLAGS_REG))]
7433 "TARGET_QIMODE_MATH"
7434 "div{b}\t%2"
7435 [(set_attr "type" "idiv")
7436 (set_attr "mode" "QI")])
7437
7438 ;; We cannot use div/idiv for double division, because it causes
7439 ;; "division by zero" on the overflow and that's not what we expect
7440 ;; from truncate. Because true (non truncating) double division is
7441 ;; never generated, we can't create this insn anyway.
7442 ;
7443 ;(define_insn ""
7444 ; [(set (match_operand:SI 0 "register_operand" "=a")
7445 ; (truncate:SI
7446 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7447 ; (zero_extend:DI
7448 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7449 ; (set (match_operand:SI 3 "register_operand" "=d")
7450 ; (truncate:SI
7451 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7452 ; (clobber (reg:CC FLAGS_REG))]
7453 ; ""
7454 ; "div{l}\t{%2, %0|%0, %2}"
7455 ; [(set_attr "type" "idiv")])
7456 \f
7457 ;;- Logical AND instructions
7458
7459 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7460 ;; Note that this excludes ah.
7461
7462 (define_expand "testsi_ccno_1"
7463 [(set (reg:CCNO FLAGS_REG)
7464 (compare:CCNO
7465 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7466 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7467 (const_int 0)))])
7468
7469 (define_expand "testqi_ccz_1"
7470 [(set (reg:CCZ FLAGS_REG)
7471 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7472 (match_operand:QI 1 "nonmemory_operand"))
7473 (const_int 0)))])
7474
7475 (define_expand "testdi_ccno_1"
7476 [(set (reg:CCNO FLAGS_REG)
7477 (compare:CCNO
7478 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7479 (match_operand:DI 1 "x86_64_szext_general_operand"))
7480 (const_int 0)))]
7481 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7482
7483 (define_insn "*testdi_1"
7484 [(set (reg FLAGS_REG)
7485 (compare
7486 (and:DI
7487 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7488 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7489 (const_int 0)))]
7490 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7492 "@
7493 test{l}\t{%k1, %k0|%k0, %k1}
7494 test{l}\t{%k1, %k0|%k0, %k1}
7495 test{q}\t{%1, %0|%0, %1}
7496 test{q}\t{%1, %0|%0, %1}
7497 test{q}\t{%1, %0|%0, %1}"
7498 [(set_attr "type" "test")
7499 (set_attr "modrm" "0,1,0,1,1")
7500 (set_attr "mode" "SI,SI,DI,DI,DI")])
7501
7502 (define_insn "*testqi_1_maybe_si"
7503 [(set (reg FLAGS_REG)
7504 (compare
7505 (and:QI
7506 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7507 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7508 (const_int 0)))]
7509 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7510 && ix86_match_ccmode (insn,
7511 CONST_INT_P (operands[1])
7512 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7513 {
7514 if (which_alternative == 3)
7515 {
7516 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7517 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7518 return "test{l}\t{%1, %k0|%k0, %1}";
7519 }
7520 return "test{b}\t{%1, %0|%0, %1}";
7521 }
7522 [(set_attr "type" "test")
7523 (set_attr "modrm" "0,1,1,1")
7524 (set_attr "mode" "QI,QI,QI,SI")
7525 (set_attr "pent_pair" "uv,np,uv,np")])
7526
7527 (define_insn "*test<mode>_1"
7528 [(set (reg FLAGS_REG)
7529 (compare
7530 (and:SWI124
7531 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7532 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7533 (const_int 0)))]
7534 "ix86_match_ccmode (insn, CCNOmode)
7535 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7536 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7537 [(set_attr "type" "test")
7538 (set_attr "modrm" "0,1,1")
7539 (set_attr "mode" "<MODE>")
7540 (set_attr "pent_pair" "uv,np,uv")])
7541
7542 (define_expand "testqi_ext_ccno_0"
7543 [(set (reg:CCNO FLAGS_REG)
7544 (compare:CCNO
7545 (and:SI
7546 (zero_extract:SI
7547 (match_operand 0 "ext_register_operand")
7548 (const_int 8)
7549 (const_int 8))
7550 (match_operand 1 "const_int_operand"))
7551 (const_int 0)))])
7552
7553 (define_insn "*testqi_ext_0"
7554 [(set (reg FLAGS_REG)
7555 (compare
7556 (and:SI
7557 (zero_extract:SI
7558 (match_operand 0 "ext_register_operand" "Q")
7559 (const_int 8)
7560 (const_int 8))
7561 (match_operand 1 "const_int_operand" "n"))
7562 (const_int 0)))]
7563 "ix86_match_ccmode (insn, CCNOmode)"
7564 "test{b}\t{%1, %h0|%h0, %1}"
7565 [(set_attr "type" "test")
7566 (set_attr "mode" "QI")
7567 (set_attr "length_immediate" "1")
7568 (set_attr "modrm" "1")
7569 (set_attr "pent_pair" "np")])
7570
7571 (define_insn "*testqi_ext_1"
7572 [(set (reg FLAGS_REG)
7573 (compare
7574 (and:SI
7575 (zero_extract:SI
7576 (match_operand 0 "ext_register_operand" "Q,Q")
7577 (const_int 8)
7578 (const_int 8))
7579 (zero_extend:SI
7580 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7581 (const_int 0)))]
7582 "ix86_match_ccmode (insn, CCNOmode)"
7583 "test{b}\t{%1, %h0|%h0, %1}"
7584 [(set_attr "isa" "*,nox64")
7585 (set_attr "type" "test")
7586 (set_attr "mode" "QI")])
7587
7588 (define_insn "*testqi_ext_2"
7589 [(set (reg FLAGS_REG)
7590 (compare
7591 (and:SI
7592 (zero_extract:SI
7593 (match_operand 0 "ext_register_operand" "Q")
7594 (const_int 8)
7595 (const_int 8))
7596 (zero_extract:SI
7597 (match_operand 1 "ext_register_operand" "Q")
7598 (const_int 8)
7599 (const_int 8)))
7600 (const_int 0)))]
7601 "ix86_match_ccmode (insn, CCNOmode)"
7602 "test{b}\t{%h1, %h0|%h0, %h1}"
7603 [(set_attr "type" "test")
7604 (set_attr "mode" "QI")])
7605
7606 ;; Combine likes to form bit extractions for some tests. Humor it.
7607 (define_insn "*testqi_ext_3"
7608 [(set (reg FLAGS_REG)
7609 (compare (zero_extract:SWI48
7610 (match_operand 0 "nonimmediate_operand" "rm")
7611 (match_operand:SWI48 1 "const_int_operand")
7612 (match_operand:SWI48 2 "const_int_operand"))
7613 (const_int 0)))]
7614 "ix86_match_ccmode (insn, CCNOmode)
7615 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7616 || GET_MODE (operands[0]) == SImode
7617 || GET_MODE (operands[0]) == HImode
7618 || GET_MODE (operands[0]) == QImode)
7619 /* Ensure that resulting mask is zero or sign extended operand. */
7620 && INTVAL (operands[2]) >= 0
7621 && ((INTVAL (operands[1]) > 0
7622 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7623 || (<MODE>mode == DImode
7624 && INTVAL (operands[1]) > 32
7625 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7626 "#")
7627
7628 (define_split
7629 [(set (match_operand 0 "flags_reg_operand")
7630 (match_operator 1 "compare_operator"
7631 [(zero_extract
7632 (match_operand 2 "nonimmediate_operand")
7633 (match_operand 3 "const_int_operand")
7634 (match_operand 4 "const_int_operand"))
7635 (const_int 0)]))]
7636 "ix86_match_ccmode (insn, CCNOmode)"
7637 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7638 {
7639 rtx val = operands[2];
7640 HOST_WIDE_INT len = INTVAL (operands[3]);
7641 HOST_WIDE_INT pos = INTVAL (operands[4]);
7642 HOST_WIDE_INT mask;
7643 enum machine_mode mode, submode;
7644
7645 mode = GET_MODE (val);
7646 if (MEM_P (val))
7647 {
7648 /* ??? Combine likes to put non-volatile mem extractions in QImode
7649 no matter the size of the test. So find a mode that works. */
7650 if (! MEM_VOLATILE_P (val))
7651 {
7652 mode = smallest_mode_for_size (pos + len, MODE_INT);
7653 val = adjust_address (val, mode, 0);
7654 }
7655 }
7656 else if (GET_CODE (val) == SUBREG
7657 && (submode = GET_MODE (SUBREG_REG (val)),
7658 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7659 && pos + len <= GET_MODE_BITSIZE (submode)
7660 && GET_MODE_CLASS (submode) == MODE_INT)
7661 {
7662 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7663 mode = submode;
7664 val = SUBREG_REG (val);
7665 }
7666 else if (mode == HImode && pos + len <= 8)
7667 {
7668 /* Small HImode tests can be converted to QImode. */
7669 mode = QImode;
7670 val = gen_lowpart (QImode, val);
7671 }
7672
7673 if (len == HOST_BITS_PER_WIDE_INT)
7674 mask = -1;
7675 else
7676 mask = ((HOST_WIDE_INT)1 << len) - 1;
7677 mask <<= pos;
7678
7679 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7680 })
7681
7682 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7683 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7684 ;; this is relatively important trick.
7685 ;; Do the conversion only post-reload to avoid limiting of the register class
7686 ;; to QI regs.
7687 (define_split
7688 [(set (match_operand 0 "flags_reg_operand")
7689 (match_operator 1 "compare_operator"
7690 [(and (match_operand 2 "register_operand")
7691 (match_operand 3 "const_int_operand"))
7692 (const_int 0)]))]
7693 "reload_completed
7694 && QI_REG_P (operands[2])
7695 && GET_MODE (operands[2]) != QImode
7696 && ((ix86_match_ccmode (insn, CCZmode)
7697 && !(INTVAL (operands[3]) & ~(255 << 8)))
7698 || (ix86_match_ccmode (insn, CCNOmode)
7699 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7700 [(set (match_dup 0)
7701 (match_op_dup 1
7702 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7703 (match_dup 3))
7704 (const_int 0)]))]
7705 {
7706 operands[2] = gen_lowpart (SImode, operands[2]);
7707 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7708 })
7709
7710 (define_split
7711 [(set (match_operand 0 "flags_reg_operand")
7712 (match_operator 1 "compare_operator"
7713 [(and (match_operand 2 "nonimmediate_operand")
7714 (match_operand 3 "const_int_operand"))
7715 (const_int 0)]))]
7716 "reload_completed
7717 && GET_MODE (operands[2]) != QImode
7718 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7719 && ((ix86_match_ccmode (insn, CCZmode)
7720 && !(INTVAL (operands[3]) & ~255))
7721 || (ix86_match_ccmode (insn, CCNOmode)
7722 && !(INTVAL (operands[3]) & ~127)))"
7723 [(set (match_dup 0)
7724 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7725 (const_int 0)]))]
7726 {
7727 operands[2] = gen_lowpart (QImode, operands[2]);
7728 operands[3] = gen_lowpart (QImode, operands[3]);
7729 })
7730
7731 (define_split
7732 [(set (match_operand:SWI12 0 "mask_reg_operand")
7733 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7734 (match_operand:SWI12 2 "mask_reg_operand")))
7735 (clobber (reg:CC FLAGS_REG))]
7736 "TARGET_AVX512F && reload_completed"
7737 [(set (match_dup 0)
7738 (any_logic:SWI12 (match_dup 1)
7739 (match_dup 2)))])
7740
7741 (define_insn "*k<logic><mode>"
7742 [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk")
7743 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk")
7744 (match_operand:SWI12 2 "mask_reg_operand" "Yk")))]
7745 "TARGET_AVX512F"
7746 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7747 [(set_attr "mode" "<MODE>")
7748 (set_attr "type" "msklog")
7749 (set_attr "prefix" "vex")])
7750
7751 ;; %%% This used to optimize known byte-wide and operations to memory,
7752 ;; and sometimes to QImode registers. If this is considered useful,
7753 ;; it should be done with splitters.
7754
7755 (define_expand "and<mode>3"
7756 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7757 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7758 (match_operand:SWIM 2 "<general_szext_operand>")))]
7759 ""
7760 {
7761 enum machine_mode mode = <MODE>mode;
7762 rtx (*insn) (rtx, rtx);
7763
7764 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7765 {
7766 HOST_WIDE_INT ival = INTVAL (operands[2]);
7767
7768 if (ival == (HOST_WIDE_INT) 0xffffffff)
7769 mode = SImode;
7770 else if (ival == 0xffff)
7771 mode = HImode;
7772 else if (ival == 0xff)
7773 mode = QImode;
7774 }
7775
7776 if (mode == <MODE>mode)
7777 {
7778 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7779 DONE;
7780 }
7781
7782 if (<MODE>mode == DImode)
7783 insn = (mode == SImode)
7784 ? gen_zero_extendsidi2
7785 : (mode == HImode)
7786 ? gen_zero_extendhidi2
7787 : gen_zero_extendqidi2;
7788 else if (<MODE>mode == SImode)
7789 insn = (mode == HImode)
7790 ? gen_zero_extendhisi2
7791 : gen_zero_extendqisi2;
7792 else if (<MODE>mode == HImode)
7793 insn = gen_zero_extendqihi2;
7794 else
7795 gcc_unreachable ();
7796
7797 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7798 DONE;
7799 })
7800
7801 (define_insn "*anddi_1"
7802 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7803 (and:DI
7804 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7805 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7806 (clobber (reg:CC FLAGS_REG))]
7807 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7808 {
7809 switch (get_attr_type (insn))
7810 {
7811 case TYPE_IMOVX:
7812 return "#";
7813
7814 default:
7815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7816 if (get_attr_mode (insn) == MODE_SI)
7817 return "and{l}\t{%k2, %k0|%k0, %k2}";
7818 else
7819 return "and{q}\t{%2, %0|%0, %2}";
7820 }
7821 }
7822 [(set_attr "type" "alu,alu,alu,imovx")
7823 (set_attr "length_immediate" "*,*,*,0")
7824 (set (attr "prefix_rex")
7825 (if_then_else
7826 (and (eq_attr "type" "imovx")
7827 (and (match_test "INTVAL (operands[2]) == 0xff")
7828 (match_operand 1 "ext_QIreg_operand")))
7829 (const_string "1")
7830 (const_string "*")))
7831 (set_attr "mode" "SI,DI,DI,SI")])
7832
7833 (define_insn "*andsi_1"
7834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7835 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7836 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7837 (clobber (reg:CC FLAGS_REG))]
7838 "ix86_binary_operator_ok (AND, SImode, operands)"
7839 {
7840 switch (get_attr_type (insn))
7841 {
7842 case TYPE_IMOVX:
7843 return "#";
7844
7845 default:
7846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7847 return "and{l}\t{%2, %0|%0, %2}";
7848 }
7849 }
7850 [(set_attr "type" "alu,alu,imovx")
7851 (set (attr "prefix_rex")
7852 (if_then_else
7853 (and (eq_attr "type" "imovx")
7854 (and (match_test "INTVAL (operands[2]) == 0xff")
7855 (match_operand 1 "ext_QIreg_operand")))
7856 (const_string "1")
7857 (const_string "*")))
7858 (set_attr "length_immediate" "*,*,0")
7859 (set_attr "mode" "SI")])
7860
7861 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7862 (define_insn "*andsi_1_zext"
7863 [(set (match_operand:DI 0 "register_operand" "=r")
7864 (zero_extend:DI
7865 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7866 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7869 "and{l}\t{%2, %k0|%k0, %2}"
7870 [(set_attr "type" "alu")
7871 (set_attr "mode" "SI")])
7872
7873 (define_insn "*andhi_1"
7874 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk")
7875 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk")
7876 (match_operand:HI 2 "general_operand" "rn,rm,L,Yk")))
7877 (clobber (reg:CC FLAGS_REG))]
7878 "ix86_binary_operator_ok (AND, HImode, operands)"
7879 {
7880 switch (get_attr_type (insn))
7881 {
7882 case TYPE_IMOVX:
7883 return "#";
7884
7885 case TYPE_MSKLOG:
7886 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7887
7888 default:
7889 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7890 return "and{w}\t{%2, %0|%0, %2}";
7891 }
7892 }
7893 [(set_attr "type" "alu,alu,imovx,msklog")
7894 (set_attr "length_immediate" "*,*,0,*")
7895 (set (attr "prefix_rex")
7896 (if_then_else
7897 (and (eq_attr "type" "imovx")
7898 (match_operand 1 "ext_QIreg_operand"))
7899 (const_string "1")
7900 (const_string "*")))
7901 (set_attr "mode" "HI,HI,SI,HI")])
7902
7903 ;; %%% Potential partial reg stall on alternative 2. What to do?
7904 (define_insn "*andqi_1"
7905 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk")
7906 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
7907 (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk")))
7908 (clobber (reg:CC FLAGS_REG))]
7909 "ix86_binary_operator_ok (AND, QImode, operands)"
7910 "@
7911 and{b}\t{%2, %0|%0, %2}
7912 and{b}\t{%2, %0|%0, %2}
7913 and{l}\t{%k2, %k0|%k0, %k2}
7914 kandw\t{%2, %1, %0|%0, %1, %2}"
7915 [(set_attr "type" "alu,alu,alu,msklog")
7916 (set_attr "mode" "QI,QI,SI,HI")])
7917
7918 (define_insn "*andqi_1_slp"
7919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7920 (and:QI (match_dup 0)
7921 (match_operand:QI 1 "general_operand" "qn,qmn")))
7922 (clobber (reg:CC FLAGS_REG))]
7923 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7924 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7925 "and{b}\t{%1, %0|%0, %1}"
7926 [(set_attr "type" "alu1")
7927 (set_attr "mode" "QI")])
7928
7929 (define_insn "kandn<mode>"
7930 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk")
7931 (and:SWI12
7932 (not:SWI12
7933 (match_operand:SWI12 1 "register_operand" "r,0,Yk"))
7934 (match_operand:SWI12 2 "register_operand" "r,r,Yk")))
7935 (clobber (reg:CC FLAGS_REG))]
7936 "TARGET_AVX512F"
7937 "@
7938 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7939 #
7940 kandnw\t{%2, %1, %0|%0, %1, %2}"
7941 [(set_attr "isa" "bmi,*,avx512f")
7942 (set_attr "type" "bitmanip,*,msklog")
7943 (set_attr "prefix" "*,*,vex")
7944 (set_attr "btver2_decode" "direct,*,*")
7945 (set_attr "mode" "<MODE>")])
7946
7947 (define_split
7948 [(set (match_operand:SWI12 0 "general_reg_operand")
7949 (and:SWI12
7950 (not:SWI12
7951 (match_dup 0))
7952 (match_operand:SWI12 1 "general_reg_operand")))
7953 (clobber (reg:CC FLAGS_REG))]
7954 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7955 [(set (match_dup 0)
7956 (not:HI (match_dup 0)))
7957 (parallel [(set (match_dup 0)
7958 (and:HI (match_dup 0)
7959 (match_dup 1)))
7960 (clobber (reg:CC FLAGS_REG))])])
7961
7962 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7963 (define_split
7964 [(set (match_operand:DI 0 "register_operand")
7965 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7966 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7967 (clobber (reg:CC FLAGS_REG))]
7968 "TARGET_64BIT"
7969 [(parallel [(set (match_dup 0)
7970 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7971 (clobber (reg:CC FLAGS_REG))])]
7972 "operands[2] = gen_lowpart (SImode, operands[2]);")
7973
7974 (define_split
7975 [(set (match_operand:SWI248 0 "register_operand")
7976 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7977 (match_operand:SWI248 2 "const_int_operand")))
7978 (clobber (reg:CC FLAGS_REG))]
7979 "reload_completed
7980 && true_regnum (operands[0]) != true_regnum (operands[1])"
7981 [(const_int 0)]
7982 {
7983 HOST_WIDE_INT ival = INTVAL (operands[2]);
7984 enum machine_mode mode;
7985 rtx (*insn) (rtx, rtx);
7986
7987 if (ival == (HOST_WIDE_INT) 0xffffffff)
7988 mode = SImode;
7989 else if (ival == 0xffff)
7990 mode = HImode;
7991 else
7992 {
7993 gcc_assert (ival == 0xff);
7994 mode = QImode;
7995 }
7996
7997 if (<MODE>mode == DImode)
7998 insn = (mode == SImode)
7999 ? gen_zero_extendsidi2
8000 : (mode == HImode)
8001 ? gen_zero_extendhidi2
8002 : gen_zero_extendqidi2;
8003 else
8004 {
8005 if (<MODE>mode != SImode)
8006 /* Zero extend to SImode to avoid partial register stalls. */
8007 operands[0] = gen_lowpart (SImode, operands[0]);
8008
8009 insn = (mode == HImode)
8010 ? gen_zero_extendhisi2
8011 : gen_zero_extendqisi2;
8012 }
8013 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8014 DONE;
8015 })
8016
8017 (define_split
8018 [(set (match_operand 0 "register_operand")
8019 (and (match_dup 0)
8020 (const_int -65536)))
8021 (clobber (reg:CC FLAGS_REG))]
8022 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8023 || optimize_function_for_size_p (cfun)"
8024 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8025 "operands[1] = gen_lowpart (HImode, operands[0]);")
8026
8027 (define_split
8028 [(set (match_operand 0 "ext_register_operand")
8029 (and (match_dup 0)
8030 (const_int -256)))
8031 (clobber (reg:CC FLAGS_REG))]
8032 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8033 && reload_completed"
8034 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8035 "operands[1] = gen_lowpart (QImode, operands[0]);")
8036
8037 (define_split
8038 [(set (match_operand 0 "ext_register_operand")
8039 (and (match_dup 0)
8040 (const_int -65281)))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8043 && reload_completed"
8044 [(parallel [(set (zero_extract:SI (match_dup 0)
8045 (const_int 8)
8046 (const_int 8))
8047 (xor:SI
8048 (zero_extract:SI (match_dup 0)
8049 (const_int 8)
8050 (const_int 8))
8051 (zero_extract:SI (match_dup 0)
8052 (const_int 8)
8053 (const_int 8))))
8054 (clobber (reg:CC FLAGS_REG))])]
8055 "operands[0] = gen_lowpart (SImode, operands[0]);")
8056
8057 (define_insn "*anddi_2"
8058 [(set (reg FLAGS_REG)
8059 (compare
8060 (and:DI
8061 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8062 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8063 (const_int 0)))
8064 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8065 (and:DI (match_dup 1) (match_dup 2)))]
8066 "TARGET_64BIT
8067 && ix86_match_ccmode
8068 (insn,
8069 /* If we are going to emit andl instead of andq, and the operands[2]
8070 constant might have the SImode sign bit set, make sure the sign
8071 flag isn't tested, because the instruction will set the sign flag
8072 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8073 conservatively assume it might have bit 31 set. */
8074 (satisfies_constraint_Z (operands[2])
8075 && (!CONST_INT_P (operands[2])
8076 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8077 ? CCZmode : CCNOmode)
8078 && ix86_binary_operator_ok (AND, DImode, operands)"
8079 "@
8080 and{l}\t{%k2, %k0|%k0, %k2}
8081 and{q}\t{%2, %0|%0, %2}
8082 and{q}\t{%2, %0|%0, %2}"
8083 [(set_attr "type" "alu")
8084 (set_attr "mode" "SI,DI,DI")])
8085
8086 (define_insn "*andqi_2_maybe_si"
8087 [(set (reg FLAGS_REG)
8088 (compare (and:QI
8089 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8090 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8091 (const_int 0)))
8092 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8093 (and:QI (match_dup 1) (match_dup 2)))]
8094 "ix86_binary_operator_ok (AND, QImode, operands)
8095 && ix86_match_ccmode (insn,
8096 CONST_INT_P (operands[2])
8097 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8098 {
8099 if (which_alternative == 2)
8100 {
8101 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8102 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8103 return "and{l}\t{%2, %k0|%k0, %2}";
8104 }
8105 return "and{b}\t{%2, %0|%0, %2}";
8106 }
8107 [(set_attr "type" "alu")
8108 (set_attr "mode" "QI,QI,SI")])
8109
8110 (define_insn "*and<mode>_2"
8111 [(set (reg FLAGS_REG)
8112 (compare (and:SWI124
8113 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8114 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8115 (const_int 0)))
8116 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8117 (and:SWI124 (match_dup 1) (match_dup 2)))]
8118 "ix86_match_ccmode (insn, CCNOmode)
8119 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8120 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8121 [(set_attr "type" "alu")
8122 (set_attr "mode" "<MODE>")])
8123
8124 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8125 (define_insn "*andsi_2_zext"
8126 [(set (reg FLAGS_REG)
8127 (compare (and:SI
8128 (match_operand:SI 1 "nonimmediate_operand" "%0")
8129 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8130 (const_int 0)))
8131 (set (match_operand:DI 0 "register_operand" "=r")
8132 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8133 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8134 && ix86_binary_operator_ok (AND, SImode, operands)"
8135 "and{l}\t{%2, %k0|%k0, %2}"
8136 [(set_attr "type" "alu")
8137 (set_attr "mode" "SI")])
8138
8139 (define_insn "*andqi_2_slp"
8140 [(set (reg FLAGS_REG)
8141 (compare (and:QI
8142 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8143 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8144 (const_int 0)))
8145 (set (strict_low_part (match_dup 0))
8146 (and:QI (match_dup 0) (match_dup 1)))]
8147 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8148 && ix86_match_ccmode (insn, CCNOmode)
8149 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8150 "and{b}\t{%1, %0|%0, %1}"
8151 [(set_attr "type" "alu1")
8152 (set_attr "mode" "QI")])
8153
8154 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8155 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8156 ;; for a QImode operand, which of course failed.
8157 (define_insn "andqi_ext_0"
8158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8159 (const_int 8)
8160 (const_int 8))
8161 (and:SI
8162 (zero_extract:SI
8163 (match_operand 1 "ext_register_operand" "0")
8164 (const_int 8)
8165 (const_int 8))
8166 (match_operand 2 "const_int_operand" "n")))
8167 (clobber (reg:CC FLAGS_REG))]
8168 ""
8169 "and{b}\t{%2, %h0|%h0, %2}"
8170 [(set_attr "type" "alu")
8171 (set_attr "length_immediate" "1")
8172 (set_attr "modrm" "1")
8173 (set_attr "mode" "QI")])
8174
8175 ;; Generated by peephole translating test to and. This shows up
8176 ;; often in fp comparisons.
8177 (define_insn "*andqi_ext_0_cc"
8178 [(set (reg FLAGS_REG)
8179 (compare
8180 (and:SI
8181 (zero_extract:SI
8182 (match_operand 1 "ext_register_operand" "0")
8183 (const_int 8)
8184 (const_int 8))
8185 (match_operand 2 "const_int_operand" "n"))
8186 (const_int 0)))
8187 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8188 (const_int 8)
8189 (const_int 8))
8190 (and:SI
8191 (zero_extract:SI
8192 (match_dup 1)
8193 (const_int 8)
8194 (const_int 8))
8195 (match_dup 2)))]
8196 "ix86_match_ccmode (insn, CCNOmode)"
8197 "and{b}\t{%2, %h0|%h0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "length_immediate" "1")
8200 (set_attr "modrm" "1")
8201 (set_attr "mode" "QI")])
8202
8203 (define_insn "*andqi_ext_1"
8204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8205 (const_int 8)
8206 (const_int 8))
8207 (and:SI
8208 (zero_extract:SI
8209 (match_operand 1 "ext_register_operand" "0,0")
8210 (const_int 8)
8211 (const_int 8))
8212 (zero_extend:SI
8213 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8214 (clobber (reg:CC FLAGS_REG))]
8215 ""
8216 "and{b}\t{%2, %h0|%h0, %2}"
8217 [(set_attr "isa" "*,nox64")
8218 (set_attr "type" "alu")
8219 (set_attr "length_immediate" "0")
8220 (set_attr "mode" "QI")])
8221
8222 (define_insn "*andqi_ext_2"
8223 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8224 (const_int 8)
8225 (const_int 8))
8226 (and:SI
8227 (zero_extract:SI
8228 (match_operand 1 "ext_register_operand" "%0")
8229 (const_int 8)
8230 (const_int 8))
8231 (zero_extract:SI
8232 (match_operand 2 "ext_register_operand" "Q")
8233 (const_int 8)
8234 (const_int 8))))
8235 (clobber (reg:CC FLAGS_REG))]
8236 ""
8237 "and{b}\t{%h2, %h0|%h0, %h2}"
8238 [(set_attr "type" "alu")
8239 (set_attr "length_immediate" "0")
8240 (set_attr "mode" "QI")])
8241
8242 ;; Convert wide AND instructions with immediate operand to shorter QImode
8243 ;; equivalents when possible.
8244 ;; Don't do the splitting with memory operands, since it introduces risk
8245 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8246 ;; for size, but that can (should?) be handled by generic code instead.
8247 (define_split
8248 [(set (match_operand 0 "register_operand")
8249 (and (match_operand 1 "register_operand")
8250 (match_operand 2 "const_int_operand")))
8251 (clobber (reg:CC FLAGS_REG))]
8252 "reload_completed
8253 && QI_REG_P (operands[0])
8254 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8255 && !(~INTVAL (operands[2]) & ~(255 << 8))
8256 && GET_MODE (operands[0]) != QImode"
8257 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8258 (and:SI (zero_extract:SI (match_dup 1)
8259 (const_int 8) (const_int 8))
8260 (match_dup 2)))
8261 (clobber (reg:CC FLAGS_REG))])]
8262 {
8263 operands[0] = gen_lowpart (SImode, operands[0]);
8264 operands[1] = gen_lowpart (SImode, operands[1]);
8265 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8266 })
8267
8268 ;; Since AND can be encoded with sign extended immediate, this is only
8269 ;; profitable when 7th bit is not set.
8270 (define_split
8271 [(set (match_operand 0 "register_operand")
8272 (and (match_operand 1 "general_operand")
8273 (match_operand 2 "const_int_operand")))
8274 (clobber (reg:CC FLAGS_REG))]
8275 "reload_completed
8276 && ANY_QI_REG_P (operands[0])
8277 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8278 && !(~INTVAL (operands[2]) & ~255)
8279 && !(INTVAL (operands[2]) & 128)
8280 && GET_MODE (operands[0]) != QImode"
8281 [(parallel [(set (strict_low_part (match_dup 0))
8282 (and:QI (match_dup 1)
8283 (match_dup 2)))
8284 (clobber (reg:CC FLAGS_REG))])]
8285 {
8286 operands[0] = gen_lowpart (QImode, operands[0]);
8287 operands[1] = gen_lowpart (QImode, operands[1]);
8288 operands[2] = gen_lowpart (QImode, operands[2]);
8289 })
8290 \f
8291 ;; Logical inclusive and exclusive OR instructions
8292
8293 ;; %%% This used to optimize known byte-wide and operations to memory.
8294 ;; If this is considered useful, it should be done with splitters.
8295
8296 (define_expand "<code><mode>3"
8297 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8298 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8299 (match_operand:SWIM 2 "<general_operand>")))]
8300 ""
8301 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8302
8303 (define_insn "*<code><mode>_1"
8304 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8305 (any_or:SWI48
8306 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8307 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8310 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "mode" "<MODE>")])
8313
8314 (define_insn "*<code>hi_1"
8315 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk")
8316 (any_or:HI
8317 (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk")
8318 (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk")))
8319 (clobber (reg:CC FLAGS_REG))]
8320 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8321 "@
8322 <logic>{w}\t{%2, %0|%0, %2}
8323 <logic>{w}\t{%2, %0|%0, %2}
8324 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8325 [(set_attr "type" "alu,alu,msklog")
8326 (set_attr "mode" "HI")])
8327
8328 ;; %%% Potential partial reg stall on alternative 2. What to do?
8329 (define_insn "*<code>qi_1"
8330 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk")
8331 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
8332 (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk")))
8333 (clobber (reg:CC FLAGS_REG))]
8334 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8335 "@
8336 <logic>{b}\t{%2, %0|%0, %2}
8337 <logic>{b}\t{%2, %0|%0, %2}
8338 <logic>{l}\t{%k2, %k0|%k0, %k2}
8339 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8340 [(set_attr "type" "alu,alu,alu,msklog")
8341 (set_attr "mode" "QI,QI,SI,HI")])
8342
8343 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8344 (define_insn "*<code>si_1_zext"
8345 [(set (match_operand:DI 0 "register_operand" "=r")
8346 (zero_extend:DI
8347 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8348 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8349 (clobber (reg:CC FLAGS_REG))]
8350 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8351 "<logic>{l}\t{%2, %k0|%k0, %2}"
8352 [(set_attr "type" "alu")
8353 (set_attr "mode" "SI")])
8354
8355 (define_insn "*<code>si_1_zext_imm"
8356 [(set (match_operand:DI 0 "register_operand" "=r")
8357 (any_or:DI
8358 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8359 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8360 (clobber (reg:CC FLAGS_REG))]
8361 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8362 "<logic>{l}\t{%2, %k0|%k0, %2}"
8363 [(set_attr "type" "alu")
8364 (set_attr "mode" "SI")])
8365
8366 (define_insn "*<code>qi_1_slp"
8367 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8368 (any_or:QI (match_dup 0)
8369 (match_operand:QI 1 "general_operand" "qmn,qn")))
8370 (clobber (reg:CC FLAGS_REG))]
8371 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8372 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8373 "<logic>{b}\t{%1, %0|%0, %1}"
8374 [(set_attr "type" "alu1")
8375 (set_attr "mode" "QI")])
8376
8377 (define_insn "*<code><mode>_2"
8378 [(set (reg FLAGS_REG)
8379 (compare (any_or:SWI
8380 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8381 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8382 (const_int 0)))
8383 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8384 (any_or:SWI (match_dup 1) (match_dup 2)))]
8385 "ix86_match_ccmode (insn, CCNOmode)
8386 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8387 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "mode" "<MODE>")])
8390
8391 (define_insn "kxnor<mode>"
8392 [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk")
8393 (not:SWI12
8394 (xor:SWI12
8395 (match_operand:SWI12 1 "register_operand" "0,Yk")
8396 (match_operand:SWI12 2 "register_operand" "r,Yk"))))
8397 (clobber (reg:CC FLAGS_REG))]
8398 "TARGET_AVX512F"
8399 "@
8400 #
8401 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8402 [(set_attr "type" "*,msklog")
8403 (set_attr "prefix" "*,vex")
8404 (set_attr "mode" "<MODE>")])
8405
8406 (define_split
8407 [(set (match_operand:SWI12 0 "general_reg_operand")
8408 (not:SWI12
8409 (xor:SWI12
8410 (match_dup 0)
8411 (match_operand:SWI12 1 "general_reg_operand"))))
8412 (clobber (reg:CC FLAGS_REG))]
8413 "TARGET_AVX512F && reload_completed"
8414 [(parallel [(set (match_dup 0)
8415 (xor:HI (match_dup 0)
8416 (match_dup 1)))
8417 (clobber (reg:CC FLAGS_REG))])
8418 (set (match_dup 0)
8419 (not:HI (match_dup 0)))])
8420
8421 (define_insn "kortestzhi"
8422 [(set (reg:CCZ FLAGS_REG)
8423 (compare:CCZ
8424 (ior:HI
8425 (match_operand:HI 0 "register_operand" "Yk")
8426 (match_operand:HI 1 "register_operand" "Yk"))
8427 (const_int 0)))]
8428 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8429 "kortestw\t{%1, %0|%0, %1}"
8430 [(set_attr "mode" "HI")
8431 (set_attr "type" "msklog")
8432 (set_attr "prefix" "vex")])
8433
8434 (define_insn "kortestchi"
8435 [(set (reg:CCC FLAGS_REG)
8436 (compare:CCC
8437 (ior:HI
8438 (match_operand:HI 0 "register_operand" "Yk")
8439 (match_operand:HI 1 "register_operand" "Yk"))
8440 (const_int -1)))]
8441 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8442 "kortestw\t{%1, %0|%0, %1}"
8443 [(set_attr "mode" "HI")
8444 (set_attr "type" "msklog")
8445 (set_attr "prefix" "vex")])
8446
8447 (define_insn "kunpckhi"
8448 [(set (match_operand:HI 0 "register_operand" "=Yk")
8449 (ior:HI
8450 (ashift:HI
8451 (match_operand:HI 1 "register_operand" "Yk")
8452 (const_int 8))
8453 (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))]
8454 "TARGET_AVX512F"
8455 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8456 [(set_attr "mode" "HI")
8457 (set_attr "type" "msklog")
8458 (set_attr "prefix" "vex")])
8459
8460 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8461 ;; ??? Special case for immediate operand is missing - it is tricky.
8462 (define_insn "*<code>si_2_zext"
8463 [(set (reg FLAGS_REG)
8464 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8465 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8466 (const_int 0)))
8467 (set (match_operand:DI 0 "register_operand" "=r")
8468 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8469 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8470 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8471 "<logic>{l}\t{%2, %k0|%k0, %2}"
8472 [(set_attr "type" "alu")
8473 (set_attr "mode" "SI")])
8474
8475 (define_insn "*<code>si_2_zext_imm"
8476 [(set (reg FLAGS_REG)
8477 (compare (any_or:SI
8478 (match_operand:SI 1 "nonimmediate_operand" "%0")
8479 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8480 (const_int 0)))
8481 (set (match_operand:DI 0 "register_operand" "=r")
8482 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8483 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8484 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8485 "<logic>{l}\t{%2, %k0|%k0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "mode" "SI")])
8488
8489 (define_insn "*<code>qi_2_slp"
8490 [(set (reg FLAGS_REG)
8491 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8492 (match_operand:QI 1 "general_operand" "qmn,qn"))
8493 (const_int 0)))
8494 (set (strict_low_part (match_dup 0))
8495 (any_or:QI (match_dup 0) (match_dup 1)))]
8496 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8497 && ix86_match_ccmode (insn, CCNOmode)
8498 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8499 "<logic>{b}\t{%1, %0|%0, %1}"
8500 [(set_attr "type" "alu1")
8501 (set_attr "mode" "QI")])
8502
8503 (define_insn "*<code><mode>_3"
8504 [(set (reg FLAGS_REG)
8505 (compare (any_or:SWI
8506 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8507 (match_operand:SWI 2 "<general_operand>" "<g>"))
8508 (const_int 0)))
8509 (clobber (match_scratch:SWI 0 "=<r>"))]
8510 "ix86_match_ccmode (insn, CCNOmode)
8511 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8512 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "mode" "<MODE>")])
8515
8516 (define_insn "*<code>qi_ext_0"
8517 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8518 (const_int 8)
8519 (const_int 8))
8520 (any_or:SI
8521 (zero_extract:SI
8522 (match_operand 1 "ext_register_operand" "0")
8523 (const_int 8)
8524 (const_int 8))
8525 (match_operand 2 "const_int_operand" "n")))
8526 (clobber (reg:CC FLAGS_REG))]
8527 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8528 "<logic>{b}\t{%2, %h0|%h0, %2}"
8529 [(set_attr "type" "alu")
8530 (set_attr "length_immediate" "1")
8531 (set_attr "modrm" "1")
8532 (set_attr "mode" "QI")])
8533
8534 (define_insn "*<code>qi_ext_1"
8535 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8536 (const_int 8)
8537 (const_int 8))
8538 (any_or:SI
8539 (zero_extract:SI
8540 (match_operand 1 "ext_register_operand" "0,0")
8541 (const_int 8)
8542 (const_int 8))
8543 (zero_extend:SI
8544 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8547 "<logic>{b}\t{%2, %h0|%h0, %2}"
8548 [(set_attr "isa" "*,nox64")
8549 (set_attr "type" "alu")
8550 (set_attr "length_immediate" "0")
8551 (set_attr "mode" "QI")])
8552
8553 (define_insn "*<code>qi_ext_2"
8554 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8555 (const_int 8)
8556 (const_int 8))
8557 (any_or:SI
8558 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8559 (const_int 8)
8560 (const_int 8))
8561 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8562 (const_int 8)
8563 (const_int 8))))
8564 (clobber (reg:CC FLAGS_REG))]
8565 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8566 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "length_immediate" "0")
8569 (set_attr "mode" "QI")])
8570
8571 (define_split
8572 [(set (match_operand 0 "register_operand")
8573 (any_or (match_operand 1 "register_operand")
8574 (match_operand 2 "const_int_operand")))
8575 (clobber (reg:CC FLAGS_REG))]
8576 "reload_completed
8577 && QI_REG_P (operands[0])
8578 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8579 && !(INTVAL (operands[2]) & ~(255 << 8))
8580 && GET_MODE (operands[0]) != QImode"
8581 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8582 (any_or:SI (zero_extract:SI (match_dup 1)
8583 (const_int 8) (const_int 8))
8584 (match_dup 2)))
8585 (clobber (reg:CC FLAGS_REG))])]
8586 {
8587 operands[0] = gen_lowpart (SImode, operands[0]);
8588 operands[1] = gen_lowpart (SImode, operands[1]);
8589 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8590 })
8591
8592 ;; Since OR can be encoded with sign extended immediate, this is only
8593 ;; profitable when 7th bit is set.
8594 (define_split
8595 [(set (match_operand 0 "register_operand")
8596 (any_or (match_operand 1 "general_operand")
8597 (match_operand 2 "const_int_operand")))
8598 (clobber (reg:CC FLAGS_REG))]
8599 "reload_completed
8600 && ANY_QI_REG_P (operands[0])
8601 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8602 && !(INTVAL (operands[2]) & ~255)
8603 && (INTVAL (operands[2]) & 128)
8604 && GET_MODE (operands[0]) != QImode"
8605 [(parallel [(set (strict_low_part (match_dup 0))
8606 (any_or:QI (match_dup 1)
8607 (match_dup 2)))
8608 (clobber (reg:CC FLAGS_REG))])]
8609 {
8610 operands[0] = gen_lowpart (QImode, operands[0]);
8611 operands[1] = gen_lowpart (QImode, operands[1]);
8612 operands[2] = gen_lowpart (QImode, operands[2]);
8613 })
8614
8615 (define_expand "xorqi_cc_ext_1"
8616 [(parallel [
8617 (set (reg:CCNO FLAGS_REG)
8618 (compare:CCNO
8619 (xor:SI
8620 (zero_extract:SI
8621 (match_operand 1 "ext_register_operand")
8622 (const_int 8)
8623 (const_int 8))
8624 (match_operand:QI 2 "const_int_operand"))
8625 (const_int 0)))
8626 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8627 (const_int 8)
8628 (const_int 8))
8629 (xor:SI
8630 (zero_extract:SI
8631 (match_dup 1)
8632 (const_int 8)
8633 (const_int 8))
8634 (match_dup 2)))])])
8635
8636 (define_insn "*xorqi_cc_ext_1"
8637 [(set (reg FLAGS_REG)
8638 (compare
8639 (xor:SI
8640 (zero_extract:SI
8641 (match_operand 1 "ext_register_operand" "0,0")
8642 (const_int 8)
8643 (const_int 8))
8644 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8645 (const_int 0)))
8646 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8647 (const_int 8)
8648 (const_int 8))
8649 (xor:SI
8650 (zero_extract:SI
8651 (match_dup 1)
8652 (const_int 8)
8653 (const_int 8))
8654 (match_dup 2)))]
8655 "ix86_match_ccmode (insn, CCNOmode)"
8656 "xor{b}\t{%2, %h0|%h0, %2}"
8657 [(set_attr "isa" "*,nox64")
8658 (set_attr "type" "alu")
8659 (set_attr "modrm" "1")
8660 (set_attr "mode" "QI")])
8661 \f
8662 ;; Negation instructions
8663
8664 (define_expand "neg<mode>2"
8665 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8666 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8667 ""
8668 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8669
8670 (define_insn_and_split "*neg<dwi>2_doubleword"
8671 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8672 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8673 (clobber (reg:CC FLAGS_REG))]
8674 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8675 "#"
8676 "reload_completed"
8677 [(parallel
8678 [(set (reg:CCZ FLAGS_REG)
8679 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8680 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8681 (parallel
8682 [(set (match_dup 2)
8683 (plus:DWIH (match_dup 3)
8684 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8685 (const_int 0))))
8686 (clobber (reg:CC FLAGS_REG))])
8687 (parallel
8688 [(set (match_dup 2)
8689 (neg:DWIH (match_dup 2)))
8690 (clobber (reg:CC FLAGS_REG))])]
8691 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8692
8693 (define_insn "*neg<mode>2_1"
8694 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8695 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8698 "neg{<imodesuffix>}\t%0"
8699 [(set_attr "type" "negnot")
8700 (set_attr "mode" "<MODE>")])
8701
8702 ;; Combine is quite creative about this pattern.
8703 (define_insn "*negsi2_1_zext"
8704 [(set (match_operand:DI 0 "register_operand" "=r")
8705 (lshiftrt:DI
8706 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8707 (const_int 32)))
8708 (const_int 32)))
8709 (clobber (reg:CC FLAGS_REG))]
8710 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8711 "neg{l}\t%k0"
8712 [(set_attr "type" "negnot")
8713 (set_attr "mode" "SI")])
8714
8715 ;; The problem with neg is that it does not perform (compare x 0),
8716 ;; it really performs (compare 0 x), which leaves us with the zero
8717 ;; flag being the only useful item.
8718
8719 (define_insn "*neg<mode>2_cmpz"
8720 [(set (reg:CCZ FLAGS_REG)
8721 (compare:CCZ
8722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8723 (const_int 0)))
8724 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8725 (neg:SWI (match_dup 1)))]
8726 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8727 "neg{<imodesuffix>}\t%0"
8728 [(set_attr "type" "negnot")
8729 (set_attr "mode" "<MODE>")])
8730
8731 (define_insn "*negsi2_cmpz_zext"
8732 [(set (reg:CCZ FLAGS_REG)
8733 (compare:CCZ
8734 (lshiftrt:DI
8735 (neg:DI (ashift:DI
8736 (match_operand:DI 1 "register_operand" "0")
8737 (const_int 32)))
8738 (const_int 32))
8739 (const_int 0)))
8740 (set (match_operand:DI 0 "register_operand" "=r")
8741 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8742 (const_int 32)))
8743 (const_int 32)))]
8744 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8745 "neg{l}\t%k0"
8746 [(set_attr "type" "negnot")
8747 (set_attr "mode" "SI")])
8748
8749 ;; Negate with jump on overflow.
8750 (define_expand "negv<mode>3"
8751 [(parallel [(set (reg:CCO FLAGS_REG)
8752 (ne:CCO (match_operand:SWI 1 "register_operand")
8753 (match_dup 3)))
8754 (set (match_operand:SWI 0 "register_operand")
8755 (neg:SWI (match_dup 1)))])
8756 (set (pc) (if_then_else
8757 (eq (reg:CCO FLAGS_REG) (const_int 0))
8758 (label_ref (match_operand 2))
8759 (pc)))]
8760 ""
8761 {
8762 operands[3]
8763 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8764 <MODE>mode);
8765 })
8766
8767 (define_insn "*negv<mode>3"
8768 [(set (reg:CCO FLAGS_REG)
8769 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8770 (match_operand:SWI 2 "const_int_operand")))
8771 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8772 (neg:SWI (match_dup 1)))]
8773 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8774 && mode_signbit_p (<MODE>mode, operands[2])"
8775 "neg{<imodesuffix>}\t%0"
8776 [(set_attr "type" "negnot")
8777 (set_attr "mode" "<MODE>")])
8778
8779 ;; Changing of sign for FP values is doable using integer unit too.
8780
8781 (define_expand "<code><mode>2"
8782 [(set (match_operand:X87MODEF 0 "register_operand")
8783 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8784 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8785 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8786
8787 (define_insn "*absneg<mode>2_mixed"
8788 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8789 (match_operator:MODEF 3 "absneg_operator"
8790 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8791 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8792 (clobber (reg:CC FLAGS_REG))]
8793 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8794 "#")
8795
8796 (define_insn "*absneg<mode>2_sse"
8797 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8798 (match_operator:MODEF 3 "absneg_operator"
8799 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8800 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8801 (clobber (reg:CC FLAGS_REG))]
8802 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8803 "#")
8804
8805 (define_insn "*absneg<mode>2_i387"
8806 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8807 (match_operator:X87MODEF 3 "absneg_operator"
8808 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8809 (use (match_operand 2))
8810 (clobber (reg:CC FLAGS_REG))]
8811 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8812 "#")
8813
8814 (define_expand "<code>tf2"
8815 [(set (match_operand:TF 0 "register_operand")
8816 (absneg:TF (match_operand:TF 1 "register_operand")))]
8817 "TARGET_SSE"
8818 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8819
8820 (define_insn "*absnegtf2_sse"
8821 [(set (match_operand:TF 0 "register_operand" "=x,x")
8822 (match_operator:TF 3 "absneg_operator"
8823 [(match_operand:TF 1 "register_operand" "0,x")]))
8824 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8825 (clobber (reg:CC FLAGS_REG))]
8826 "TARGET_SSE"
8827 "#")
8828
8829 ;; Splitters for fp abs and neg.
8830
8831 (define_split
8832 [(set (match_operand 0 "fp_register_operand")
8833 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8834 (use (match_operand 2))
8835 (clobber (reg:CC FLAGS_REG))]
8836 "reload_completed"
8837 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8838
8839 (define_split
8840 [(set (match_operand 0 "register_operand")
8841 (match_operator 3 "absneg_operator"
8842 [(match_operand 1 "register_operand")]))
8843 (use (match_operand 2 "nonimmediate_operand"))
8844 (clobber (reg:CC FLAGS_REG))]
8845 "reload_completed && SSE_REG_P (operands[0])"
8846 [(set (match_dup 0) (match_dup 3))]
8847 {
8848 enum machine_mode mode = GET_MODE (operands[0]);
8849 enum machine_mode vmode = GET_MODE (operands[2]);
8850 rtx tmp;
8851
8852 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8853 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8854 if (operands_match_p (operands[0], operands[2]))
8855 {
8856 tmp = operands[1];
8857 operands[1] = operands[2];
8858 operands[2] = tmp;
8859 }
8860 if (GET_CODE (operands[3]) == ABS)
8861 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8862 else
8863 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8864 operands[3] = tmp;
8865 })
8866
8867 (define_split
8868 [(set (match_operand:SF 0 "register_operand")
8869 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8870 (use (match_operand:V4SF 2))
8871 (clobber (reg:CC FLAGS_REG))]
8872 "reload_completed"
8873 [(parallel [(set (match_dup 0) (match_dup 1))
8874 (clobber (reg:CC FLAGS_REG))])]
8875 {
8876 rtx tmp;
8877 operands[0] = gen_lowpart (SImode, operands[0]);
8878 if (GET_CODE (operands[1]) == ABS)
8879 {
8880 tmp = gen_int_mode (0x7fffffff, SImode);
8881 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8882 }
8883 else
8884 {
8885 tmp = gen_int_mode (0x80000000, SImode);
8886 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8887 }
8888 operands[1] = tmp;
8889 })
8890
8891 (define_split
8892 [(set (match_operand:DF 0 "register_operand")
8893 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8894 (use (match_operand 2))
8895 (clobber (reg:CC FLAGS_REG))]
8896 "reload_completed"
8897 [(parallel [(set (match_dup 0) (match_dup 1))
8898 (clobber (reg:CC FLAGS_REG))])]
8899 {
8900 rtx tmp;
8901 if (TARGET_64BIT)
8902 {
8903 tmp = gen_lowpart (DImode, operands[0]);
8904 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8905 operands[0] = tmp;
8906
8907 if (GET_CODE (operands[1]) == ABS)
8908 tmp = const0_rtx;
8909 else
8910 tmp = gen_rtx_NOT (DImode, tmp);
8911 }
8912 else
8913 {
8914 operands[0] = gen_highpart (SImode, operands[0]);
8915 if (GET_CODE (operands[1]) == ABS)
8916 {
8917 tmp = gen_int_mode (0x7fffffff, SImode);
8918 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8919 }
8920 else
8921 {
8922 tmp = gen_int_mode (0x80000000, SImode);
8923 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8924 }
8925 }
8926 operands[1] = tmp;
8927 })
8928
8929 (define_split
8930 [(set (match_operand:XF 0 "register_operand")
8931 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8932 (use (match_operand 2))
8933 (clobber (reg:CC FLAGS_REG))]
8934 "reload_completed"
8935 [(parallel [(set (match_dup 0) (match_dup 1))
8936 (clobber (reg:CC FLAGS_REG))])]
8937 {
8938 rtx tmp;
8939 operands[0] = gen_rtx_REG (SImode,
8940 true_regnum (operands[0])
8941 + (TARGET_64BIT ? 1 : 2));
8942 if (GET_CODE (operands[1]) == ABS)
8943 {
8944 tmp = GEN_INT (0x7fff);
8945 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8946 }
8947 else
8948 {
8949 tmp = GEN_INT (0x8000);
8950 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8951 }
8952 operands[1] = tmp;
8953 })
8954
8955 ;; Conditionalize these after reload. If they match before reload, we
8956 ;; lose the clobber and ability to use integer instructions.
8957
8958 (define_insn "*<code><mode>2_1"
8959 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8960 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8961 "TARGET_80387
8962 && (reload_completed
8963 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8964 "f<absneg_mnemonic>"
8965 [(set_attr "type" "fsgn")
8966 (set_attr "mode" "<MODE>")])
8967
8968 (define_insn "*<code>extendsfdf2"
8969 [(set (match_operand:DF 0 "register_operand" "=f")
8970 (absneg:DF (float_extend:DF
8971 (match_operand:SF 1 "register_operand" "0"))))]
8972 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8973 "f<absneg_mnemonic>"
8974 [(set_attr "type" "fsgn")
8975 (set_attr "mode" "DF")])
8976
8977 (define_insn "*<code>extendsfxf2"
8978 [(set (match_operand:XF 0 "register_operand" "=f")
8979 (absneg:XF (float_extend:XF
8980 (match_operand:SF 1 "register_operand" "0"))))]
8981 "TARGET_80387"
8982 "f<absneg_mnemonic>"
8983 [(set_attr "type" "fsgn")
8984 (set_attr "mode" "XF")])
8985
8986 (define_insn "*<code>extenddfxf2"
8987 [(set (match_operand:XF 0 "register_operand" "=f")
8988 (absneg:XF (float_extend:XF
8989 (match_operand:DF 1 "register_operand" "0"))))]
8990 "TARGET_80387"
8991 "f<absneg_mnemonic>"
8992 [(set_attr "type" "fsgn")
8993 (set_attr "mode" "XF")])
8994
8995 ;; Copysign instructions
8996
8997 (define_mode_iterator CSGNMODE [SF DF TF])
8998 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8999
9000 (define_expand "copysign<mode>3"
9001 [(match_operand:CSGNMODE 0 "register_operand")
9002 (match_operand:CSGNMODE 1 "nonmemory_operand")
9003 (match_operand:CSGNMODE 2 "register_operand")]
9004 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9005 || (TARGET_SSE && (<MODE>mode == TFmode))"
9006 "ix86_expand_copysign (operands); DONE;")
9007
9008 (define_insn_and_split "copysign<mode>3_const"
9009 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9010 (unspec:CSGNMODE
9011 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9012 (match_operand:CSGNMODE 2 "register_operand" "0")
9013 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9014 UNSPEC_COPYSIGN))]
9015 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9016 || (TARGET_SSE && (<MODE>mode == TFmode))"
9017 "#"
9018 "&& reload_completed"
9019 [(const_int 0)]
9020 "ix86_split_copysign_const (operands); DONE;")
9021
9022 (define_insn "copysign<mode>3_var"
9023 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9024 (unspec:CSGNMODE
9025 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9026 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9027 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9028 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9029 UNSPEC_COPYSIGN))
9030 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9031 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9032 || (TARGET_SSE && (<MODE>mode == TFmode))"
9033 "#")
9034
9035 (define_split
9036 [(set (match_operand:CSGNMODE 0 "register_operand")
9037 (unspec:CSGNMODE
9038 [(match_operand:CSGNMODE 2 "register_operand")
9039 (match_operand:CSGNMODE 3 "register_operand")
9040 (match_operand:<CSGNVMODE> 4)
9041 (match_operand:<CSGNVMODE> 5)]
9042 UNSPEC_COPYSIGN))
9043 (clobber (match_scratch:<CSGNVMODE> 1))]
9044 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9045 || (TARGET_SSE && (<MODE>mode == TFmode)))
9046 && reload_completed"
9047 [(const_int 0)]
9048 "ix86_split_copysign_var (operands); DONE;")
9049 \f
9050 ;; One complement instructions
9051
9052 (define_expand "one_cmpl<mode>2"
9053 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9054 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9055 ""
9056 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9057
9058 (define_insn "*one_cmpl<mode>2_1"
9059 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9060 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
9061 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9062 "not{<imodesuffix>}\t%0"
9063 [(set_attr "type" "negnot")
9064 (set_attr "mode" "<MODE>")])
9065
9066 (define_insn "*one_cmplhi2_1"
9067 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk")
9068 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))]
9069 "ix86_unary_operator_ok (NOT, HImode, operands)"
9070 "@
9071 not{w}\t%0
9072 knotw\t{%1, %0|%0, %1}"
9073 [(set_attr "isa" "*,avx512f")
9074 (set_attr "type" "negnot,msklog")
9075 (set_attr "prefix" "*,vex")
9076 (set_attr "mode" "HI")])
9077
9078 ;; %%% Potential partial reg stall on alternative 1. What to do?
9079 (define_insn "*one_cmplqi2_1"
9080 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk")
9081 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))]
9082 "ix86_unary_operator_ok (NOT, QImode, operands)"
9083 "@
9084 not{b}\t%0
9085 not{l}\t%k0
9086 knotw\t{%1, %0|%0, %1}"
9087 [(set_attr "isa" "*,*,avx512f")
9088 (set_attr "type" "negnot,negnot,msklog")
9089 (set_attr "prefix" "*,*,vex")
9090 (set_attr "mode" "QI,SI,QI")])
9091
9092 ;; ??? Currently never generated - xor is used instead.
9093 (define_insn "*one_cmplsi2_1_zext"
9094 [(set (match_operand:DI 0 "register_operand" "=r")
9095 (zero_extend:DI
9096 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9097 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9098 "not{l}\t%k0"
9099 [(set_attr "type" "negnot")
9100 (set_attr "mode" "SI")])
9101
9102 (define_insn "*one_cmpl<mode>2_2"
9103 [(set (reg FLAGS_REG)
9104 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9105 (const_int 0)))
9106 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9107 (not:SWI (match_dup 1)))]
9108 "ix86_match_ccmode (insn, CCNOmode)
9109 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9110 "#"
9111 [(set_attr "type" "alu1")
9112 (set_attr "mode" "<MODE>")])
9113
9114 (define_split
9115 [(set (match_operand 0 "flags_reg_operand")
9116 (match_operator 2 "compare_operator"
9117 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9118 (const_int 0)]))
9119 (set (match_operand:SWI 1 "nonimmediate_operand")
9120 (not:SWI (match_dup 3)))]
9121 "ix86_match_ccmode (insn, CCNOmode)"
9122 [(parallel [(set (match_dup 0)
9123 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9124 (const_int 0)]))
9125 (set (match_dup 1)
9126 (xor:SWI (match_dup 3) (const_int -1)))])])
9127
9128 ;; ??? Currently never generated - xor is used instead.
9129 (define_insn "*one_cmplsi2_2_zext"
9130 [(set (reg FLAGS_REG)
9131 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9132 (const_int 0)))
9133 (set (match_operand:DI 0 "register_operand" "=r")
9134 (zero_extend:DI (not:SI (match_dup 1))))]
9135 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9136 && ix86_unary_operator_ok (NOT, SImode, operands)"
9137 "#"
9138 [(set_attr "type" "alu1")
9139 (set_attr "mode" "SI")])
9140
9141 (define_split
9142 [(set (match_operand 0 "flags_reg_operand")
9143 (match_operator 2 "compare_operator"
9144 [(not:SI (match_operand:SI 3 "register_operand"))
9145 (const_int 0)]))
9146 (set (match_operand:DI 1 "register_operand")
9147 (zero_extend:DI (not:SI (match_dup 3))))]
9148 "ix86_match_ccmode (insn, CCNOmode)"
9149 [(parallel [(set (match_dup 0)
9150 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9151 (const_int 0)]))
9152 (set (match_dup 1)
9153 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9154 \f
9155 ;; Shift instructions
9156
9157 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9158 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9159 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9160 ;; from the assembler input.
9161 ;;
9162 ;; This instruction shifts the target reg/mem as usual, but instead of
9163 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9164 ;; is a left shift double, bits are taken from the high order bits of
9165 ;; reg, else if the insn is a shift right double, bits are taken from the
9166 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9167 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9168 ;;
9169 ;; Since sh[lr]d does not change the `reg' operand, that is done
9170 ;; separately, making all shifts emit pairs of shift double and normal
9171 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9172 ;; support a 63 bit shift, each shift where the count is in a reg expands
9173 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9174 ;;
9175 ;; If the shift count is a constant, we need never emit more than one
9176 ;; shift pair, instead using moves and sign extension for counts greater
9177 ;; than 31.
9178
9179 (define_expand "ashl<mode>3"
9180 [(set (match_operand:SDWIM 0 "<shift_operand>")
9181 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9182 (match_operand:QI 2 "nonmemory_operand")))]
9183 ""
9184 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9185
9186 (define_insn "*ashl<mode>3_doubleword"
9187 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9188 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9189 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9190 (clobber (reg:CC FLAGS_REG))]
9191 ""
9192 "#"
9193 [(set_attr "type" "multi")])
9194
9195 (define_split
9196 [(set (match_operand:DWI 0 "register_operand")
9197 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9198 (match_operand:QI 2 "nonmemory_operand")))
9199 (clobber (reg:CC FLAGS_REG))]
9200 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9201 [(const_int 0)]
9202 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9203
9204 ;; By default we don't ask for a scratch register, because when DWImode
9205 ;; values are manipulated, registers are already at a premium. But if
9206 ;; we have one handy, we won't turn it away.
9207
9208 (define_peephole2
9209 [(match_scratch:DWIH 3 "r")
9210 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9211 (ashift:<DWI>
9212 (match_operand:<DWI> 1 "nonmemory_operand")
9213 (match_operand:QI 2 "nonmemory_operand")))
9214 (clobber (reg:CC FLAGS_REG))])
9215 (match_dup 3)]
9216 "TARGET_CMOVE"
9217 [(const_int 0)]
9218 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9219
9220 (define_insn "x86_64_shld"
9221 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9222 (ior:DI (ashift:DI (match_dup 0)
9223 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9224 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9225 (minus:QI (const_int 64) (match_dup 2)))))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "TARGET_64BIT"
9228 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9229 [(set_attr "type" "ishift")
9230 (set_attr "prefix_0f" "1")
9231 (set_attr "mode" "DI")
9232 (set_attr "athlon_decode" "vector")
9233 (set_attr "amdfam10_decode" "vector")
9234 (set_attr "bdver1_decode" "vector")])
9235
9236 (define_insn "x86_shld"
9237 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9238 (ior:SI (ashift:SI (match_dup 0)
9239 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9240 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9241 (minus:QI (const_int 32) (match_dup 2)))))
9242 (clobber (reg:CC FLAGS_REG))]
9243 ""
9244 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9245 [(set_attr "type" "ishift")
9246 (set_attr "prefix_0f" "1")
9247 (set_attr "mode" "SI")
9248 (set_attr "pent_pair" "np")
9249 (set_attr "athlon_decode" "vector")
9250 (set_attr "amdfam10_decode" "vector")
9251 (set_attr "bdver1_decode" "vector")])
9252
9253 (define_expand "x86_shift<mode>_adj_1"
9254 [(set (reg:CCZ FLAGS_REG)
9255 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9256 (match_dup 4))
9257 (const_int 0)))
9258 (set (match_operand:SWI48 0 "register_operand")
9259 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9260 (match_operand:SWI48 1 "register_operand")
9261 (match_dup 0)))
9262 (set (match_dup 1)
9263 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9264 (match_operand:SWI48 3 "register_operand")
9265 (match_dup 1)))]
9266 "TARGET_CMOVE"
9267 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9268
9269 (define_expand "x86_shift<mode>_adj_2"
9270 [(use (match_operand:SWI48 0 "register_operand"))
9271 (use (match_operand:SWI48 1 "register_operand"))
9272 (use (match_operand:QI 2 "register_operand"))]
9273 ""
9274 {
9275 rtx label = gen_label_rtx ();
9276 rtx tmp;
9277
9278 emit_insn (gen_testqi_ccz_1 (operands[2],
9279 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9280
9281 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9282 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9283 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9284 gen_rtx_LABEL_REF (VOIDmode, label),
9285 pc_rtx);
9286 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9287 JUMP_LABEL (tmp) = label;
9288
9289 emit_move_insn (operands[0], operands[1]);
9290 ix86_expand_clear (operands[1]);
9291
9292 emit_label (label);
9293 LABEL_NUSES (label) = 1;
9294
9295 DONE;
9296 })
9297
9298 ;; Avoid useless masking of count operand.
9299 (define_insn "*ashl<mode>3_mask"
9300 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9301 (ashift:SWI48
9302 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9303 (subreg:QI
9304 (and:SI
9305 (match_operand:SI 2 "register_operand" "c")
9306 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9307 (clobber (reg:CC FLAGS_REG))]
9308 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9309 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9310 == GET_MODE_BITSIZE (<MODE>mode)-1"
9311 {
9312 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9313 }
9314 [(set_attr "type" "ishift")
9315 (set_attr "mode" "<MODE>")])
9316
9317 (define_insn "*bmi2_ashl<mode>3_1"
9318 [(set (match_operand:SWI48 0 "register_operand" "=r")
9319 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9320 (match_operand:SWI48 2 "register_operand" "r")))]
9321 "TARGET_BMI2"
9322 "shlx\t{%2, %1, %0|%0, %1, %2}"
9323 [(set_attr "type" "ishiftx")
9324 (set_attr "mode" "<MODE>")])
9325
9326 (define_insn "*ashl<mode>3_1"
9327 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9328 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9329 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9330 (clobber (reg:CC FLAGS_REG))]
9331 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9332 {
9333 switch (get_attr_type (insn))
9334 {
9335 case TYPE_LEA:
9336 case TYPE_ISHIFTX:
9337 return "#";
9338
9339 case TYPE_ALU:
9340 gcc_assert (operands[2] == const1_rtx);
9341 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9342 return "add{<imodesuffix>}\t%0, %0";
9343
9344 default:
9345 if (operands[2] == const1_rtx
9346 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9347 return "sal{<imodesuffix>}\t%0";
9348 else
9349 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9350 }
9351 }
9352 [(set_attr "isa" "*,*,bmi2")
9353 (set (attr "type")
9354 (cond [(eq_attr "alternative" "1")
9355 (const_string "lea")
9356 (eq_attr "alternative" "2")
9357 (const_string "ishiftx")
9358 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9359 (match_operand 0 "register_operand"))
9360 (match_operand 2 "const1_operand"))
9361 (const_string "alu")
9362 ]
9363 (const_string "ishift")))
9364 (set (attr "length_immediate")
9365 (if_then_else
9366 (ior (eq_attr "type" "alu")
9367 (and (eq_attr "type" "ishift")
9368 (and (match_operand 2 "const1_operand")
9369 (ior (match_test "TARGET_SHIFT1")
9370 (match_test "optimize_function_for_size_p (cfun)")))))
9371 (const_string "0")
9372 (const_string "*")))
9373 (set_attr "mode" "<MODE>")])
9374
9375 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9376 (define_split
9377 [(set (match_operand:SWI48 0 "register_operand")
9378 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9379 (match_operand:QI 2 "register_operand")))
9380 (clobber (reg:CC FLAGS_REG))]
9381 "TARGET_BMI2 && reload_completed"
9382 [(set (match_dup 0)
9383 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9384 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9385
9386 (define_insn "*bmi2_ashlsi3_1_zext"
9387 [(set (match_operand:DI 0 "register_operand" "=r")
9388 (zero_extend:DI
9389 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9390 (match_operand:SI 2 "register_operand" "r"))))]
9391 "TARGET_64BIT && TARGET_BMI2"
9392 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9393 [(set_attr "type" "ishiftx")
9394 (set_attr "mode" "SI")])
9395
9396 (define_insn "*ashlsi3_1_zext"
9397 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9398 (zero_extend:DI
9399 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9400 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9401 (clobber (reg:CC FLAGS_REG))]
9402 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9403 {
9404 switch (get_attr_type (insn))
9405 {
9406 case TYPE_LEA:
9407 case TYPE_ISHIFTX:
9408 return "#";
9409
9410 case TYPE_ALU:
9411 gcc_assert (operands[2] == const1_rtx);
9412 return "add{l}\t%k0, %k0";
9413
9414 default:
9415 if (operands[2] == const1_rtx
9416 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9417 return "sal{l}\t%k0";
9418 else
9419 return "sal{l}\t{%2, %k0|%k0, %2}";
9420 }
9421 }
9422 [(set_attr "isa" "*,*,bmi2")
9423 (set (attr "type")
9424 (cond [(eq_attr "alternative" "1")
9425 (const_string "lea")
9426 (eq_attr "alternative" "2")
9427 (const_string "ishiftx")
9428 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9429 (match_operand 2 "const1_operand"))
9430 (const_string "alu")
9431 ]
9432 (const_string "ishift")))
9433 (set (attr "length_immediate")
9434 (if_then_else
9435 (ior (eq_attr "type" "alu")
9436 (and (eq_attr "type" "ishift")
9437 (and (match_operand 2 "const1_operand")
9438 (ior (match_test "TARGET_SHIFT1")
9439 (match_test "optimize_function_for_size_p (cfun)")))))
9440 (const_string "0")
9441 (const_string "*")))
9442 (set_attr "mode" "SI")])
9443
9444 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9445 (define_split
9446 [(set (match_operand:DI 0 "register_operand")
9447 (zero_extend:DI
9448 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9449 (match_operand:QI 2 "register_operand"))))
9450 (clobber (reg:CC FLAGS_REG))]
9451 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9452 [(set (match_dup 0)
9453 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9454 "operands[2] = gen_lowpart (SImode, operands[2]);")
9455
9456 (define_insn "*ashlhi3_1"
9457 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9458 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9459 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9460 (clobber (reg:CC FLAGS_REG))]
9461 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9462 {
9463 switch (get_attr_type (insn))
9464 {
9465 case TYPE_LEA:
9466 return "#";
9467
9468 case TYPE_ALU:
9469 gcc_assert (operands[2] == const1_rtx);
9470 return "add{w}\t%0, %0";
9471
9472 default:
9473 if (operands[2] == const1_rtx
9474 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9475 return "sal{w}\t%0";
9476 else
9477 return "sal{w}\t{%2, %0|%0, %2}";
9478 }
9479 }
9480 [(set (attr "type")
9481 (cond [(eq_attr "alternative" "1")
9482 (const_string "lea")
9483 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9484 (match_operand 0 "register_operand"))
9485 (match_operand 2 "const1_operand"))
9486 (const_string "alu")
9487 ]
9488 (const_string "ishift")))
9489 (set (attr "length_immediate")
9490 (if_then_else
9491 (ior (eq_attr "type" "alu")
9492 (and (eq_attr "type" "ishift")
9493 (and (match_operand 2 "const1_operand")
9494 (ior (match_test "TARGET_SHIFT1")
9495 (match_test "optimize_function_for_size_p (cfun)")))))
9496 (const_string "0")
9497 (const_string "*")))
9498 (set_attr "mode" "HI,SI")])
9499
9500 ;; %%% Potential partial reg stall on alternative 1. What to do?
9501 (define_insn "*ashlqi3_1"
9502 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9503 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9504 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9505 (clobber (reg:CC FLAGS_REG))]
9506 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9507 {
9508 switch (get_attr_type (insn))
9509 {
9510 case TYPE_LEA:
9511 return "#";
9512
9513 case TYPE_ALU:
9514 gcc_assert (operands[2] == const1_rtx);
9515 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9516 return "add{l}\t%k0, %k0";
9517 else
9518 return "add{b}\t%0, %0";
9519
9520 default:
9521 if (operands[2] == const1_rtx
9522 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9523 {
9524 if (get_attr_mode (insn) == MODE_SI)
9525 return "sal{l}\t%k0";
9526 else
9527 return "sal{b}\t%0";
9528 }
9529 else
9530 {
9531 if (get_attr_mode (insn) == MODE_SI)
9532 return "sal{l}\t{%2, %k0|%k0, %2}";
9533 else
9534 return "sal{b}\t{%2, %0|%0, %2}";
9535 }
9536 }
9537 }
9538 [(set (attr "type")
9539 (cond [(eq_attr "alternative" "2")
9540 (const_string "lea")
9541 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9542 (match_operand 0 "register_operand"))
9543 (match_operand 2 "const1_operand"))
9544 (const_string "alu")
9545 ]
9546 (const_string "ishift")))
9547 (set (attr "length_immediate")
9548 (if_then_else
9549 (ior (eq_attr "type" "alu")
9550 (and (eq_attr "type" "ishift")
9551 (and (match_operand 2 "const1_operand")
9552 (ior (match_test "TARGET_SHIFT1")
9553 (match_test "optimize_function_for_size_p (cfun)")))))
9554 (const_string "0")
9555 (const_string "*")))
9556 (set_attr "mode" "QI,SI,SI")])
9557
9558 (define_insn "*ashlqi3_1_slp"
9559 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9560 (ashift:QI (match_dup 0)
9561 (match_operand:QI 1 "nonmemory_operand" "cI")))
9562 (clobber (reg:CC FLAGS_REG))]
9563 "(optimize_function_for_size_p (cfun)
9564 || !TARGET_PARTIAL_FLAG_REG_STALL
9565 || (operands[1] == const1_rtx
9566 && (TARGET_SHIFT1
9567 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9568 {
9569 switch (get_attr_type (insn))
9570 {
9571 case TYPE_ALU:
9572 gcc_assert (operands[1] == const1_rtx);
9573 return "add{b}\t%0, %0";
9574
9575 default:
9576 if (operands[1] == const1_rtx
9577 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9578 return "sal{b}\t%0";
9579 else
9580 return "sal{b}\t{%1, %0|%0, %1}";
9581 }
9582 }
9583 [(set (attr "type")
9584 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9585 (match_operand 0 "register_operand"))
9586 (match_operand 1 "const1_operand"))
9587 (const_string "alu")
9588 ]
9589 (const_string "ishift1")))
9590 (set (attr "length_immediate")
9591 (if_then_else
9592 (ior (eq_attr "type" "alu")
9593 (and (eq_attr "type" "ishift1")
9594 (and (match_operand 1 "const1_operand")
9595 (ior (match_test "TARGET_SHIFT1")
9596 (match_test "optimize_function_for_size_p (cfun)")))))
9597 (const_string "0")
9598 (const_string "*")))
9599 (set_attr "mode" "QI")])
9600
9601 ;; Convert ashift to the lea pattern to avoid flags dependency.
9602 (define_split
9603 [(set (match_operand 0 "register_operand")
9604 (ashift (match_operand 1 "index_register_operand")
9605 (match_operand:QI 2 "const_int_operand")))
9606 (clobber (reg:CC FLAGS_REG))]
9607 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9608 && reload_completed
9609 && true_regnum (operands[0]) != true_regnum (operands[1])"
9610 [(const_int 0)]
9611 {
9612 enum machine_mode mode = GET_MODE (operands[0]);
9613 rtx pat;
9614
9615 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9616 {
9617 mode = SImode;
9618 operands[0] = gen_lowpart (mode, operands[0]);
9619 operands[1] = gen_lowpart (mode, operands[1]);
9620 }
9621
9622 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9623
9624 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9625
9626 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9627 DONE;
9628 })
9629
9630 ;; Convert ashift to the lea pattern to avoid flags dependency.
9631 (define_split
9632 [(set (match_operand:DI 0 "register_operand")
9633 (zero_extend:DI
9634 (ashift:SI (match_operand:SI 1 "index_register_operand")
9635 (match_operand:QI 2 "const_int_operand"))))
9636 (clobber (reg:CC FLAGS_REG))]
9637 "TARGET_64BIT && reload_completed
9638 && true_regnum (operands[0]) != true_regnum (operands[1])"
9639 [(set (match_dup 0)
9640 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9641 {
9642 operands[1] = gen_lowpart (SImode, operands[1]);
9643 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9644 })
9645
9646 ;; This pattern can't accept a variable shift count, since shifts by
9647 ;; zero don't affect the flags. We assume that shifts by constant
9648 ;; zero are optimized away.
9649 (define_insn "*ashl<mode>3_cmp"
9650 [(set (reg FLAGS_REG)
9651 (compare
9652 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9653 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9654 (const_int 0)))
9655 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9656 (ashift:SWI (match_dup 1) (match_dup 2)))]
9657 "(optimize_function_for_size_p (cfun)
9658 || !TARGET_PARTIAL_FLAG_REG_STALL
9659 || (operands[2] == const1_rtx
9660 && (TARGET_SHIFT1
9661 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9662 && ix86_match_ccmode (insn, CCGOCmode)
9663 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9664 {
9665 switch (get_attr_type (insn))
9666 {
9667 case TYPE_ALU:
9668 gcc_assert (operands[2] == const1_rtx);
9669 return "add{<imodesuffix>}\t%0, %0";
9670
9671 default:
9672 if (operands[2] == const1_rtx
9673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9674 return "sal{<imodesuffix>}\t%0";
9675 else
9676 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9677 }
9678 }
9679 [(set (attr "type")
9680 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9681 (match_operand 0 "register_operand"))
9682 (match_operand 2 "const1_operand"))
9683 (const_string "alu")
9684 ]
9685 (const_string "ishift")))
9686 (set (attr "length_immediate")
9687 (if_then_else
9688 (ior (eq_attr "type" "alu")
9689 (and (eq_attr "type" "ishift")
9690 (and (match_operand 2 "const1_operand")
9691 (ior (match_test "TARGET_SHIFT1")
9692 (match_test "optimize_function_for_size_p (cfun)")))))
9693 (const_string "0")
9694 (const_string "*")))
9695 (set_attr "mode" "<MODE>")])
9696
9697 (define_insn "*ashlsi3_cmp_zext"
9698 [(set (reg FLAGS_REG)
9699 (compare
9700 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9701 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9702 (const_int 0)))
9703 (set (match_operand:DI 0 "register_operand" "=r")
9704 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9705 "TARGET_64BIT
9706 && (optimize_function_for_size_p (cfun)
9707 || !TARGET_PARTIAL_FLAG_REG_STALL
9708 || (operands[2] == const1_rtx
9709 && (TARGET_SHIFT1
9710 || TARGET_DOUBLE_WITH_ADD)))
9711 && ix86_match_ccmode (insn, CCGOCmode)
9712 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9713 {
9714 switch (get_attr_type (insn))
9715 {
9716 case TYPE_ALU:
9717 gcc_assert (operands[2] == const1_rtx);
9718 return "add{l}\t%k0, %k0";
9719
9720 default:
9721 if (operands[2] == const1_rtx
9722 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9723 return "sal{l}\t%k0";
9724 else
9725 return "sal{l}\t{%2, %k0|%k0, %2}";
9726 }
9727 }
9728 [(set (attr "type")
9729 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9730 (match_operand 2 "const1_operand"))
9731 (const_string "alu")
9732 ]
9733 (const_string "ishift")))
9734 (set (attr "length_immediate")
9735 (if_then_else
9736 (ior (eq_attr "type" "alu")
9737 (and (eq_attr "type" "ishift")
9738 (and (match_operand 2 "const1_operand")
9739 (ior (match_test "TARGET_SHIFT1")
9740 (match_test "optimize_function_for_size_p (cfun)")))))
9741 (const_string "0")
9742 (const_string "*")))
9743 (set_attr "mode" "SI")])
9744
9745 (define_insn "*ashl<mode>3_cconly"
9746 [(set (reg FLAGS_REG)
9747 (compare
9748 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9749 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9750 (const_int 0)))
9751 (clobber (match_scratch:SWI 0 "=<r>"))]
9752 "(optimize_function_for_size_p (cfun)
9753 || !TARGET_PARTIAL_FLAG_REG_STALL
9754 || (operands[2] == const1_rtx
9755 && (TARGET_SHIFT1
9756 || TARGET_DOUBLE_WITH_ADD)))
9757 && ix86_match_ccmode (insn, CCGOCmode)"
9758 {
9759 switch (get_attr_type (insn))
9760 {
9761 case TYPE_ALU:
9762 gcc_assert (operands[2] == const1_rtx);
9763 return "add{<imodesuffix>}\t%0, %0";
9764
9765 default:
9766 if (operands[2] == const1_rtx
9767 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9768 return "sal{<imodesuffix>}\t%0";
9769 else
9770 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9771 }
9772 }
9773 [(set (attr "type")
9774 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9775 (match_operand 0 "register_operand"))
9776 (match_operand 2 "const1_operand"))
9777 (const_string "alu")
9778 ]
9779 (const_string "ishift")))
9780 (set (attr "length_immediate")
9781 (if_then_else
9782 (ior (eq_attr "type" "alu")
9783 (and (eq_attr "type" "ishift")
9784 (and (match_operand 2 "const1_operand")
9785 (ior (match_test "TARGET_SHIFT1")
9786 (match_test "optimize_function_for_size_p (cfun)")))))
9787 (const_string "0")
9788 (const_string "*")))
9789 (set_attr "mode" "<MODE>")])
9790
9791 ;; See comment above `ashl<mode>3' about how this works.
9792
9793 (define_expand "<shift_insn><mode>3"
9794 [(set (match_operand:SDWIM 0 "<shift_operand>")
9795 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9796 (match_operand:QI 2 "nonmemory_operand")))]
9797 ""
9798 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9799
9800 ;; Avoid useless masking of count operand.
9801 (define_insn "*<shift_insn><mode>3_mask"
9802 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9803 (any_shiftrt:SWI48
9804 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9805 (subreg:QI
9806 (and:SI
9807 (match_operand:SI 2 "register_operand" "c")
9808 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9809 (clobber (reg:CC FLAGS_REG))]
9810 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9811 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9812 == GET_MODE_BITSIZE (<MODE>mode)-1"
9813 {
9814 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9815 }
9816 [(set_attr "type" "ishift")
9817 (set_attr "mode" "<MODE>")])
9818
9819 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9820 [(set (match_operand:DWI 0 "register_operand" "=r")
9821 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9822 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9823 (clobber (reg:CC FLAGS_REG))]
9824 ""
9825 "#"
9826 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9827 [(const_int 0)]
9828 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9829 [(set_attr "type" "multi")])
9830
9831 ;; By default we don't ask for a scratch register, because when DWImode
9832 ;; values are manipulated, registers are already at a premium. But if
9833 ;; we have one handy, we won't turn it away.
9834
9835 (define_peephole2
9836 [(match_scratch:DWIH 3 "r")
9837 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9838 (any_shiftrt:<DWI>
9839 (match_operand:<DWI> 1 "register_operand")
9840 (match_operand:QI 2 "nonmemory_operand")))
9841 (clobber (reg:CC FLAGS_REG))])
9842 (match_dup 3)]
9843 "TARGET_CMOVE"
9844 [(const_int 0)]
9845 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9846
9847 (define_insn "x86_64_shrd"
9848 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9849 (ior:DI (ashiftrt:DI (match_dup 0)
9850 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9851 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9852 (minus:QI (const_int 64) (match_dup 2)))))
9853 (clobber (reg:CC FLAGS_REG))]
9854 "TARGET_64BIT"
9855 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9856 [(set_attr "type" "ishift")
9857 (set_attr "prefix_0f" "1")
9858 (set_attr "mode" "DI")
9859 (set_attr "athlon_decode" "vector")
9860 (set_attr "amdfam10_decode" "vector")
9861 (set_attr "bdver1_decode" "vector")])
9862
9863 (define_insn "x86_shrd"
9864 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9865 (ior:SI (ashiftrt:SI (match_dup 0)
9866 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9867 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9868 (minus:QI (const_int 32) (match_dup 2)))))
9869 (clobber (reg:CC FLAGS_REG))]
9870 ""
9871 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9872 [(set_attr "type" "ishift")
9873 (set_attr "prefix_0f" "1")
9874 (set_attr "mode" "SI")
9875 (set_attr "pent_pair" "np")
9876 (set_attr "athlon_decode" "vector")
9877 (set_attr "amdfam10_decode" "vector")
9878 (set_attr "bdver1_decode" "vector")])
9879
9880 (define_insn "ashrdi3_cvt"
9881 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9882 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9883 (match_operand:QI 2 "const_int_operand")))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "TARGET_64BIT && INTVAL (operands[2]) == 63
9886 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9887 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9888 "@
9889 {cqto|cqo}
9890 sar{q}\t{%2, %0|%0, %2}"
9891 [(set_attr "type" "imovx,ishift")
9892 (set_attr "prefix_0f" "0,*")
9893 (set_attr "length_immediate" "0,*")
9894 (set_attr "modrm" "0,1")
9895 (set_attr "mode" "DI")])
9896
9897 (define_insn "ashrsi3_cvt"
9898 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9899 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9900 (match_operand:QI 2 "const_int_operand")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "INTVAL (operands[2]) == 31
9903 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9904 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9905 "@
9906 {cltd|cdq}
9907 sar{l}\t{%2, %0|%0, %2}"
9908 [(set_attr "type" "imovx,ishift")
9909 (set_attr "prefix_0f" "0,*")
9910 (set_attr "length_immediate" "0,*")
9911 (set_attr "modrm" "0,1")
9912 (set_attr "mode" "SI")])
9913
9914 (define_insn "*ashrsi3_cvt_zext"
9915 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9916 (zero_extend:DI
9917 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9918 (match_operand:QI 2 "const_int_operand"))))
9919 (clobber (reg:CC FLAGS_REG))]
9920 "TARGET_64BIT && INTVAL (operands[2]) == 31
9921 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9922 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9923 "@
9924 {cltd|cdq}
9925 sar{l}\t{%2, %k0|%k0, %2}"
9926 [(set_attr "type" "imovx,ishift")
9927 (set_attr "prefix_0f" "0,*")
9928 (set_attr "length_immediate" "0,*")
9929 (set_attr "modrm" "0,1")
9930 (set_attr "mode" "SI")])
9931
9932 (define_expand "x86_shift<mode>_adj_3"
9933 [(use (match_operand:SWI48 0 "register_operand"))
9934 (use (match_operand:SWI48 1 "register_operand"))
9935 (use (match_operand:QI 2 "register_operand"))]
9936 ""
9937 {
9938 rtx label = gen_label_rtx ();
9939 rtx tmp;
9940
9941 emit_insn (gen_testqi_ccz_1 (operands[2],
9942 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9943
9944 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9945 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9946 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9947 gen_rtx_LABEL_REF (VOIDmode, label),
9948 pc_rtx);
9949 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9950 JUMP_LABEL (tmp) = label;
9951
9952 emit_move_insn (operands[0], operands[1]);
9953 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9954 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9955 emit_label (label);
9956 LABEL_NUSES (label) = 1;
9957
9958 DONE;
9959 })
9960
9961 (define_insn "*bmi2_<shift_insn><mode>3_1"
9962 [(set (match_operand:SWI48 0 "register_operand" "=r")
9963 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9964 (match_operand:SWI48 2 "register_operand" "r")))]
9965 "TARGET_BMI2"
9966 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9967 [(set_attr "type" "ishiftx")
9968 (set_attr "mode" "<MODE>")])
9969
9970 (define_insn "*<shift_insn><mode>3_1"
9971 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9972 (any_shiftrt:SWI48
9973 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9974 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9975 (clobber (reg:CC FLAGS_REG))]
9976 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9977 {
9978 switch (get_attr_type (insn))
9979 {
9980 case TYPE_ISHIFTX:
9981 return "#";
9982
9983 default:
9984 if (operands[2] == const1_rtx
9985 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9986 return "<shift>{<imodesuffix>}\t%0";
9987 else
9988 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9989 }
9990 }
9991 [(set_attr "isa" "*,bmi2")
9992 (set_attr "type" "ishift,ishiftx")
9993 (set (attr "length_immediate")
9994 (if_then_else
9995 (and (match_operand 2 "const1_operand")
9996 (ior (match_test "TARGET_SHIFT1")
9997 (match_test "optimize_function_for_size_p (cfun)")))
9998 (const_string "0")
9999 (const_string "*")))
10000 (set_attr "mode" "<MODE>")])
10001
10002 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10003 (define_split
10004 [(set (match_operand:SWI48 0 "register_operand")
10005 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10006 (match_operand:QI 2 "register_operand")))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "TARGET_BMI2 && reload_completed"
10009 [(set (match_dup 0)
10010 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10011 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10012
10013 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10014 [(set (match_operand:DI 0 "register_operand" "=r")
10015 (zero_extend:DI
10016 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10017 (match_operand:SI 2 "register_operand" "r"))))]
10018 "TARGET_64BIT && TARGET_BMI2"
10019 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10020 [(set_attr "type" "ishiftx")
10021 (set_attr "mode" "SI")])
10022
10023 (define_insn "*<shift_insn>si3_1_zext"
10024 [(set (match_operand:DI 0 "register_operand" "=r,r")
10025 (zero_extend:DI
10026 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10027 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10028 (clobber (reg:CC FLAGS_REG))]
10029 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10030 {
10031 switch (get_attr_type (insn))
10032 {
10033 case TYPE_ISHIFTX:
10034 return "#";
10035
10036 default:
10037 if (operands[2] == const1_rtx
10038 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10039 return "<shift>{l}\t%k0";
10040 else
10041 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10042 }
10043 }
10044 [(set_attr "isa" "*,bmi2")
10045 (set_attr "type" "ishift,ishiftx")
10046 (set (attr "length_immediate")
10047 (if_then_else
10048 (and (match_operand 2 "const1_operand")
10049 (ior (match_test "TARGET_SHIFT1")
10050 (match_test "optimize_function_for_size_p (cfun)")))
10051 (const_string "0")
10052 (const_string "*")))
10053 (set_attr "mode" "SI")])
10054
10055 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10056 (define_split
10057 [(set (match_operand:DI 0 "register_operand")
10058 (zero_extend:DI
10059 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10060 (match_operand:QI 2 "register_operand"))))
10061 (clobber (reg:CC FLAGS_REG))]
10062 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10063 [(set (match_dup 0)
10064 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10065 "operands[2] = gen_lowpart (SImode, operands[2]);")
10066
10067 (define_insn "*<shift_insn><mode>3_1"
10068 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10069 (any_shiftrt:SWI12
10070 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10071 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10072 (clobber (reg:CC FLAGS_REG))]
10073 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10074 {
10075 if (operands[2] == const1_rtx
10076 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10077 return "<shift>{<imodesuffix>}\t%0";
10078 else
10079 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10080 }
10081 [(set_attr "type" "ishift")
10082 (set (attr "length_immediate")
10083 (if_then_else
10084 (and (match_operand 2 "const1_operand")
10085 (ior (match_test "TARGET_SHIFT1")
10086 (match_test "optimize_function_for_size_p (cfun)")))
10087 (const_string "0")
10088 (const_string "*")))
10089 (set_attr "mode" "<MODE>")])
10090
10091 (define_insn "*<shift_insn>qi3_1_slp"
10092 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10093 (any_shiftrt:QI (match_dup 0)
10094 (match_operand:QI 1 "nonmemory_operand" "cI")))
10095 (clobber (reg:CC FLAGS_REG))]
10096 "(optimize_function_for_size_p (cfun)
10097 || !TARGET_PARTIAL_REG_STALL
10098 || (operands[1] == const1_rtx
10099 && TARGET_SHIFT1))"
10100 {
10101 if (operands[1] == const1_rtx
10102 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10103 return "<shift>{b}\t%0";
10104 else
10105 return "<shift>{b}\t{%1, %0|%0, %1}";
10106 }
10107 [(set_attr "type" "ishift1")
10108 (set (attr "length_immediate")
10109 (if_then_else
10110 (and (match_operand 1 "const1_operand")
10111 (ior (match_test "TARGET_SHIFT1")
10112 (match_test "optimize_function_for_size_p (cfun)")))
10113 (const_string "0")
10114 (const_string "*")))
10115 (set_attr "mode" "QI")])
10116
10117 ;; This pattern can't accept a variable shift count, since shifts by
10118 ;; zero don't affect the flags. We assume that shifts by constant
10119 ;; zero are optimized away.
10120 (define_insn "*<shift_insn><mode>3_cmp"
10121 [(set (reg FLAGS_REG)
10122 (compare
10123 (any_shiftrt:SWI
10124 (match_operand:SWI 1 "nonimmediate_operand" "0")
10125 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10126 (const_int 0)))
10127 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10128 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10129 "(optimize_function_for_size_p (cfun)
10130 || !TARGET_PARTIAL_FLAG_REG_STALL
10131 || (operands[2] == const1_rtx
10132 && TARGET_SHIFT1))
10133 && ix86_match_ccmode (insn, CCGOCmode)
10134 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10135 {
10136 if (operands[2] == const1_rtx
10137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10138 return "<shift>{<imodesuffix>}\t%0";
10139 else
10140 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10141 }
10142 [(set_attr "type" "ishift")
10143 (set (attr "length_immediate")
10144 (if_then_else
10145 (and (match_operand 2 "const1_operand")
10146 (ior (match_test "TARGET_SHIFT1")
10147 (match_test "optimize_function_for_size_p (cfun)")))
10148 (const_string "0")
10149 (const_string "*")))
10150 (set_attr "mode" "<MODE>")])
10151
10152 (define_insn "*<shift_insn>si3_cmp_zext"
10153 [(set (reg FLAGS_REG)
10154 (compare
10155 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10156 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10157 (const_int 0)))
10158 (set (match_operand:DI 0 "register_operand" "=r")
10159 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10160 "TARGET_64BIT
10161 && (optimize_function_for_size_p (cfun)
10162 || !TARGET_PARTIAL_FLAG_REG_STALL
10163 || (operands[2] == const1_rtx
10164 && TARGET_SHIFT1))
10165 && ix86_match_ccmode (insn, CCGOCmode)
10166 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10167 {
10168 if (operands[2] == const1_rtx
10169 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10170 return "<shift>{l}\t%k0";
10171 else
10172 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10173 }
10174 [(set_attr "type" "ishift")
10175 (set (attr "length_immediate")
10176 (if_then_else
10177 (and (match_operand 2 "const1_operand")
10178 (ior (match_test "TARGET_SHIFT1")
10179 (match_test "optimize_function_for_size_p (cfun)")))
10180 (const_string "0")
10181 (const_string "*")))
10182 (set_attr "mode" "SI")])
10183
10184 (define_insn "*<shift_insn><mode>3_cconly"
10185 [(set (reg FLAGS_REG)
10186 (compare
10187 (any_shiftrt:SWI
10188 (match_operand:SWI 1 "register_operand" "0")
10189 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10190 (const_int 0)))
10191 (clobber (match_scratch:SWI 0 "=<r>"))]
10192 "(optimize_function_for_size_p (cfun)
10193 || !TARGET_PARTIAL_FLAG_REG_STALL
10194 || (operands[2] == const1_rtx
10195 && TARGET_SHIFT1))
10196 && ix86_match_ccmode (insn, CCGOCmode)"
10197 {
10198 if (operands[2] == const1_rtx
10199 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10200 return "<shift>{<imodesuffix>}\t%0";
10201 else
10202 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10203 }
10204 [(set_attr "type" "ishift")
10205 (set (attr "length_immediate")
10206 (if_then_else
10207 (and (match_operand 2 "const1_operand")
10208 (ior (match_test "TARGET_SHIFT1")
10209 (match_test "optimize_function_for_size_p (cfun)")))
10210 (const_string "0")
10211 (const_string "*")))
10212 (set_attr "mode" "<MODE>")])
10213 \f
10214 ;; Rotate instructions
10215
10216 (define_expand "<rotate_insn>ti3"
10217 [(set (match_operand:TI 0 "register_operand")
10218 (any_rotate:TI (match_operand:TI 1 "register_operand")
10219 (match_operand:QI 2 "nonmemory_operand")))]
10220 "TARGET_64BIT"
10221 {
10222 if (const_1_to_63_operand (operands[2], VOIDmode))
10223 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10224 (operands[0], operands[1], operands[2]));
10225 else
10226 FAIL;
10227
10228 DONE;
10229 })
10230
10231 (define_expand "<rotate_insn>di3"
10232 [(set (match_operand:DI 0 "shiftdi_operand")
10233 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10234 (match_operand:QI 2 "nonmemory_operand")))]
10235 ""
10236 {
10237 if (TARGET_64BIT)
10238 ix86_expand_binary_operator (<CODE>, DImode, operands);
10239 else if (const_1_to_31_operand (operands[2], VOIDmode))
10240 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10241 (operands[0], operands[1], operands[2]));
10242 else
10243 FAIL;
10244
10245 DONE;
10246 })
10247
10248 (define_expand "<rotate_insn><mode>3"
10249 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10250 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10251 (match_operand:QI 2 "nonmemory_operand")))]
10252 ""
10253 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10254
10255 ;; Avoid useless masking of count operand.
10256 (define_insn "*<rotate_insn><mode>3_mask"
10257 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10258 (any_rotate:SWI48
10259 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10260 (subreg:QI
10261 (and:SI
10262 (match_operand:SI 2 "register_operand" "c")
10263 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10266 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10267 == GET_MODE_BITSIZE (<MODE>mode)-1"
10268 {
10269 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10270 }
10271 [(set_attr "type" "rotate")
10272 (set_attr "mode" "<MODE>")])
10273
10274 ;; Implement rotation using two double-precision
10275 ;; shift instructions and a scratch register.
10276
10277 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10278 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10279 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10280 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10281 (clobber (reg:CC FLAGS_REG))
10282 (clobber (match_scratch:DWIH 3 "=&r"))]
10283 ""
10284 "#"
10285 "reload_completed"
10286 [(set (match_dup 3) (match_dup 4))
10287 (parallel
10288 [(set (match_dup 4)
10289 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10290 (lshiftrt:DWIH (match_dup 5)
10291 (minus:QI (match_dup 6) (match_dup 2)))))
10292 (clobber (reg:CC FLAGS_REG))])
10293 (parallel
10294 [(set (match_dup 5)
10295 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10296 (lshiftrt:DWIH (match_dup 3)
10297 (minus:QI (match_dup 6) (match_dup 2)))))
10298 (clobber (reg:CC FLAGS_REG))])]
10299 {
10300 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10301
10302 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10303 })
10304
10305 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10306 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10307 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10308 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10309 (clobber (reg:CC FLAGS_REG))
10310 (clobber (match_scratch:DWIH 3 "=&r"))]
10311 ""
10312 "#"
10313 "reload_completed"
10314 [(set (match_dup 3) (match_dup 4))
10315 (parallel
10316 [(set (match_dup 4)
10317 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10318 (ashift:DWIH (match_dup 5)
10319 (minus:QI (match_dup 6) (match_dup 2)))))
10320 (clobber (reg:CC FLAGS_REG))])
10321 (parallel
10322 [(set (match_dup 5)
10323 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10324 (ashift:DWIH (match_dup 3)
10325 (minus:QI (match_dup 6) (match_dup 2)))))
10326 (clobber (reg:CC FLAGS_REG))])]
10327 {
10328 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10329
10330 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10331 })
10332
10333 (define_insn "*bmi2_rorx<mode>3_1"
10334 [(set (match_operand:SWI48 0 "register_operand" "=r")
10335 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10336 (match_operand:QI 2 "immediate_operand" "<S>")))]
10337 "TARGET_BMI2"
10338 "rorx\t{%2, %1, %0|%0, %1, %2}"
10339 [(set_attr "type" "rotatex")
10340 (set_attr "mode" "<MODE>")])
10341
10342 (define_insn "*<rotate_insn><mode>3_1"
10343 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10344 (any_rotate:SWI48
10345 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10346 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10349 {
10350 switch (get_attr_type (insn))
10351 {
10352 case TYPE_ROTATEX:
10353 return "#";
10354
10355 default:
10356 if (operands[2] == const1_rtx
10357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10358 return "<rotate>{<imodesuffix>}\t%0";
10359 else
10360 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10361 }
10362 }
10363 [(set_attr "isa" "*,bmi2")
10364 (set_attr "type" "rotate,rotatex")
10365 (set (attr "length_immediate")
10366 (if_then_else
10367 (and (eq_attr "type" "rotate")
10368 (and (match_operand 2 "const1_operand")
10369 (ior (match_test "TARGET_SHIFT1")
10370 (match_test "optimize_function_for_size_p (cfun)"))))
10371 (const_string "0")
10372 (const_string "*")))
10373 (set_attr "mode" "<MODE>")])
10374
10375 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10376 (define_split
10377 [(set (match_operand:SWI48 0 "register_operand")
10378 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10379 (match_operand:QI 2 "immediate_operand")))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "TARGET_BMI2 && reload_completed"
10382 [(set (match_dup 0)
10383 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10384 {
10385 operands[2]
10386 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10387 })
10388
10389 (define_split
10390 [(set (match_operand:SWI48 0 "register_operand")
10391 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10392 (match_operand:QI 2 "immediate_operand")))
10393 (clobber (reg:CC FLAGS_REG))]
10394 "TARGET_BMI2 && reload_completed"
10395 [(set (match_dup 0)
10396 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10397
10398 (define_insn "*bmi2_rorxsi3_1_zext"
10399 [(set (match_operand:DI 0 "register_operand" "=r")
10400 (zero_extend:DI
10401 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10402 (match_operand:QI 2 "immediate_operand" "I"))))]
10403 "TARGET_64BIT && TARGET_BMI2"
10404 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10405 [(set_attr "type" "rotatex")
10406 (set_attr "mode" "SI")])
10407
10408 (define_insn "*<rotate_insn>si3_1_zext"
10409 [(set (match_operand:DI 0 "register_operand" "=r,r")
10410 (zero_extend:DI
10411 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10412 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10413 (clobber (reg:CC FLAGS_REG))]
10414 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10415 {
10416 switch (get_attr_type (insn))
10417 {
10418 case TYPE_ROTATEX:
10419 return "#";
10420
10421 default:
10422 if (operands[2] == const1_rtx
10423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10424 return "<rotate>{l}\t%k0";
10425 else
10426 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10427 }
10428 }
10429 [(set_attr "isa" "*,bmi2")
10430 (set_attr "type" "rotate,rotatex")
10431 (set (attr "length_immediate")
10432 (if_then_else
10433 (and (eq_attr "type" "rotate")
10434 (and (match_operand 2 "const1_operand")
10435 (ior (match_test "TARGET_SHIFT1")
10436 (match_test "optimize_function_for_size_p (cfun)"))))
10437 (const_string "0")
10438 (const_string "*")))
10439 (set_attr "mode" "SI")])
10440
10441 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10442 (define_split
10443 [(set (match_operand:DI 0 "register_operand")
10444 (zero_extend:DI
10445 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10446 (match_operand:QI 2 "immediate_operand"))))
10447 (clobber (reg:CC FLAGS_REG))]
10448 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10449 [(set (match_dup 0)
10450 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10451 {
10452 operands[2]
10453 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10454 })
10455
10456 (define_split
10457 [(set (match_operand:DI 0 "register_operand")
10458 (zero_extend:DI
10459 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10460 (match_operand:QI 2 "immediate_operand"))))
10461 (clobber (reg:CC FLAGS_REG))]
10462 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10463 [(set (match_dup 0)
10464 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10465
10466 (define_insn "*<rotate_insn><mode>3_1"
10467 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10468 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10469 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10470 (clobber (reg:CC FLAGS_REG))]
10471 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10472 {
10473 if (operands[2] == const1_rtx
10474 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10475 return "<rotate>{<imodesuffix>}\t%0";
10476 else
10477 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10478 }
10479 [(set_attr "type" "rotate")
10480 (set (attr "length_immediate")
10481 (if_then_else
10482 (and (match_operand 2 "const1_operand")
10483 (ior (match_test "TARGET_SHIFT1")
10484 (match_test "optimize_function_for_size_p (cfun)")))
10485 (const_string "0")
10486 (const_string "*")))
10487 (set_attr "mode" "<MODE>")])
10488
10489 (define_insn "*<rotate_insn>qi3_1_slp"
10490 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10491 (any_rotate:QI (match_dup 0)
10492 (match_operand:QI 1 "nonmemory_operand" "cI")))
10493 (clobber (reg:CC FLAGS_REG))]
10494 "(optimize_function_for_size_p (cfun)
10495 || !TARGET_PARTIAL_REG_STALL
10496 || (operands[1] == const1_rtx
10497 && TARGET_SHIFT1))"
10498 {
10499 if (operands[1] == const1_rtx
10500 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10501 return "<rotate>{b}\t%0";
10502 else
10503 return "<rotate>{b}\t{%1, %0|%0, %1}";
10504 }
10505 [(set_attr "type" "rotate1")
10506 (set (attr "length_immediate")
10507 (if_then_else
10508 (and (match_operand 1 "const1_operand")
10509 (ior (match_test "TARGET_SHIFT1")
10510 (match_test "optimize_function_for_size_p (cfun)")))
10511 (const_string "0")
10512 (const_string "*")))
10513 (set_attr "mode" "QI")])
10514
10515 (define_split
10516 [(set (match_operand:HI 0 "register_operand")
10517 (any_rotate:HI (match_dup 0) (const_int 8)))
10518 (clobber (reg:CC FLAGS_REG))]
10519 "reload_completed
10520 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10521 [(parallel [(set (strict_low_part (match_dup 0))
10522 (bswap:HI (match_dup 0)))
10523 (clobber (reg:CC FLAGS_REG))])])
10524 \f
10525 ;; Bit set / bit test instructions
10526
10527 (define_expand "extv"
10528 [(set (match_operand:SI 0 "register_operand")
10529 (sign_extract:SI (match_operand:SI 1 "register_operand")
10530 (match_operand:SI 2 "const8_operand")
10531 (match_operand:SI 3 "const8_operand")))]
10532 ""
10533 {
10534 /* Handle extractions from %ah et al. */
10535 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10536 FAIL;
10537
10538 /* From mips.md: extract_bit_field doesn't verify that our source
10539 matches the predicate, so check it again here. */
10540 if (! ext_register_operand (operands[1], VOIDmode))
10541 FAIL;
10542 })
10543
10544 (define_expand "extzv"
10545 [(set (match_operand:SI 0 "register_operand")
10546 (zero_extract:SI (match_operand 1 "ext_register_operand")
10547 (match_operand:SI 2 "const8_operand")
10548 (match_operand:SI 3 "const8_operand")))]
10549 ""
10550 {
10551 /* Handle extractions from %ah et al. */
10552 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10553 FAIL;
10554
10555 /* From mips.md: extract_bit_field doesn't verify that our source
10556 matches the predicate, so check it again here. */
10557 if (! ext_register_operand (operands[1], VOIDmode))
10558 FAIL;
10559 })
10560
10561 (define_expand "insv"
10562 [(set (zero_extract (match_operand 0 "register_operand")
10563 (match_operand 1 "const_int_operand")
10564 (match_operand 2 "const_int_operand"))
10565 (match_operand 3 "register_operand"))]
10566 ""
10567 {
10568 rtx (*gen_mov_insv_1) (rtx, rtx);
10569
10570 if (ix86_expand_pinsr (operands))
10571 DONE;
10572
10573 /* Handle insertions to %ah et al. */
10574 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10575 FAIL;
10576
10577 /* From mips.md: insert_bit_field doesn't verify that our source
10578 matches the predicate, so check it again here. */
10579 if (! ext_register_operand (operands[0], VOIDmode))
10580 FAIL;
10581
10582 gen_mov_insv_1 = (TARGET_64BIT
10583 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10584
10585 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10586 DONE;
10587 })
10588
10589 ;; %%% bts, btr, btc, bt.
10590 ;; In general these instructions are *slow* when applied to memory,
10591 ;; since they enforce atomic operation. When applied to registers,
10592 ;; it depends on the cpu implementation. They're never faster than
10593 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10594 ;; no point. But in 64-bit, we can't hold the relevant immediates
10595 ;; within the instruction itself, so operating on bits in the high
10596 ;; 32-bits of a register becomes easier.
10597 ;;
10598 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10599 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10600 ;; negdf respectively, so they can never be disabled entirely.
10601
10602 (define_insn "*btsq"
10603 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10604 (const_int 1)
10605 (match_operand:DI 1 "const_0_to_63_operand"))
10606 (const_int 1))
10607 (clobber (reg:CC FLAGS_REG))]
10608 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10609 "bts{q}\t{%1, %0|%0, %1}"
10610 [(set_attr "type" "alu1")
10611 (set_attr "prefix_0f" "1")
10612 (set_attr "mode" "DI")])
10613
10614 (define_insn "*btrq"
10615 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10616 (const_int 1)
10617 (match_operand:DI 1 "const_0_to_63_operand"))
10618 (const_int 0))
10619 (clobber (reg:CC FLAGS_REG))]
10620 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10621 "btr{q}\t{%1, %0|%0, %1}"
10622 [(set_attr "type" "alu1")
10623 (set_attr "prefix_0f" "1")
10624 (set_attr "mode" "DI")])
10625
10626 (define_insn "*btcq"
10627 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10628 (const_int 1)
10629 (match_operand:DI 1 "const_0_to_63_operand"))
10630 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10631 (clobber (reg:CC FLAGS_REG))]
10632 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10633 "btc{q}\t{%1, %0|%0, %1}"
10634 [(set_attr "type" "alu1")
10635 (set_attr "prefix_0f" "1")
10636 (set_attr "mode" "DI")])
10637
10638 ;; Allow Nocona to avoid these instructions if a register is available.
10639
10640 (define_peephole2
10641 [(match_scratch:DI 2 "r")
10642 (parallel [(set (zero_extract:DI
10643 (match_operand:DI 0 "register_operand")
10644 (const_int 1)
10645 (match_operand:DI 1 "const_0_to_63_operand"))
10646 (const_int 1))
10647 (clobber (reg:CC FLAGS_REG))])]
10648 "TARGET_64BIT && !TARGET_USE_BT"
10649 [(const_int 0)]
10650 {
10651 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10652 rtx op1;
10653
10654 if (HOST_BITS_PER_WIDE_INT >= 64)
10655 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10656 else if (i < HOST_BITS_PER_WIDE_INT)
10657 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10658 else
10659 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10660
10661 op1 = immed_double_const (lo, hi, DImode);
10662 if (i >= 31)
10663 {
10664 emit_move_insn (operands[2], op1);
10665 op1 = operands[2];
10666 }
10667
10668 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10669 DONE;
10670 })
10671
10672 (define_peephole2
10673 [(match_scratch:DI 2 "r")
10674 (parallel [(set (zero_extract:DI
10675 (match_operand:DI 0 "register_operand")
10676 (const_int 1)
10677 (match_operand:DI 1 "const_0_to_63_operand"))
10678 (const_int 0))
10679 (clobber (reg:CC FLAGS_REG))])]
10680 "TARGET_64BIT && !TARGET_USE_BT"
10681 [(const_int 0)]
10682 {
10683 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10684 rtx op1;
10685
10686 if (HOST_BITS_PER_WIDE_INT >= 64)
10687 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10688 else if (i < HOST_BITS_PER_WIDE_INT)
10689 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10690 else
10691 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10692
10693 op1 = immed_double_const (~lo, ~hi, DImode);
10694 if (i >= 32)
10695 {
10696 emit_move_insn (operands[2], op1);
10697 op1 = operands[2];
10698 }
10699
10700 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10701 DONE;
10702 })
10703
10704 (define_peephole2
10705 [(match_scratch:DI 2 "r")
10706 (parallel [(set (zero_extract:DI
10707 (match_operand:DI 0 "register_operand")
10708 (const_int 1)
10709 (match_operand:DI 1 "const_0_to_63_operand"))
10710 (not:DI (zero_extract:DI
10711 (match_dup 0) (const_int 1) (match_dup 1))))
10712 (clobber (reg:CC FLAGS_REG))])]
10713 "TARGET_64BIT && !TARGET_USE_BT"
10714 [(const_int 0)]
10715 {
10716 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10717 rtx op1;
10718
10719 if (HOST_BITS_PER_WIDE_INT >= 64)
10720 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10721 else if (i < HOST_BITS_PER_WIDE_INT)
10722 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10723 else
10724 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10725
10726 op1 = immed_double_const (lo, hi, DImode);
10727 if (i >= 31)
10728 {
10729 emit_move_insn (operands[2], op1);
10730 op1 = operands[2];
10731 }
10732
10733 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10734 DONE;
10735 })
10736
10737 (define_insn "*bt<mode>"
10738 [(set (reg:CCC FLAGS_REG)
10739 (compare:CCC
10740 (zero_extract:SWI48
10741 (match_operand:SWI48 0 "register_operand" "r")
10742 (const_int 1)
10743 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10744 (const_int 0)))]
10745 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10746 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10747 [(set_attr "type" "alu1")
10748 (set_attr "prefix_0f" "1")
10749 (set_attr "mode" "<MODE>")])
10750 \f
10751 ;; Store-flag instructions.
10752
10753 ;; For all sCOND expanders, also expand the compare or test insn that
10754 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10755
10756 (define_insn_and_split "*setcc_di_1"
10757 [(set (match_operand:DI 0 "register_operand" "=q")
10758 (match_operator:DI 1 "ix86_comparison_operator"
10759 [(reg FLAGS_REG) (const_int 0)]))]
10760 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10761 "#"
10762 "&& reload_completed"
10763 [(set (match_dup 2) (match_dup 1))
10764 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10765 {
10766 PUT_MODE (operands[1], QImode);
10767 operands[2] = gen_lowpart (QImode, operands[0]);
10768 })
10769
10770 (define_insn_and_split "*setcc_si_1_and"
10771 [(set (match_operand:SI 0 "register_operand" "=q")
10772 (match_operator:SI 1 "ix86_comparison_operator"
10773 [(reg FLAGS_REG) (const_int 0)]))
10774 (clobber (reg:CC FLAGS_REG))]
10775 "!TARGET_PARTIAL_REG_STALL
10776 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10777 "#"
10778 "&& reload_completed"
10779 [(set (match_dup 2) (match_dup 1))
10780 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10781 (clobber (reg:CC FLAGS_REG))])]
10782 {
10783 PUT_MODE (operands[1], QImode);
10784 operands[2] = gen_lowpart (QImode, operands[0]);
10785 })
10786
10787 (define_insn_and_split "*setcc_si_1_movzbl"
10788 [(set (match_operand:SI 0 "register_operand" "=q")
10789 (match_operator:SI 1 "ix86_comparison_operator"
10790 [(reg FLAGS_REG) (const_int 0)]))]
10791 "!TARGET_PARTIAL_REG_STALL
10792 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10793 "#"
10794 "&& reload_completed"
10795 [(set (match_dup 2) (match_dup 1))
10796 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10797 {
10798 PUT_MODE (operands[1], QImode);
10799 operands[2] = gen_lowpart (QImode, operands[0]);
10800 })
10801
10802 (define_insn "*setcc_qi"
10803 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10804 (match_operator:QI 1 "ix86_comparison_operator"
10805 [(reg FLAGS_REG) (const_int 0)]))]
10806 ""
10807 "set%C1\t%0"
10808 [(set_attr "type" "setcc")
10809 (set_attr "mode" "QI")])
10810
10811 (define_insn "*setcc_qi_slp"
10812 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10813 (match_operator:QI 1 "ix86_comparison_operator"
10814 [(reg FLAGS_REG) (const_int 0)]))]
10815 ""
10816 "set%C1\t%0"
10817 [(set_attr "type" "setcc")
10818 (set_attr "mode" "QI")])
10819
10820 ;; In general it is not safe to assume too much about CCmode registers,
10821 ;; so simplify-rtx stops when it sees a second one. Under certain
10822 ;; conditions this is safe on x86, so help combine not create
10823 ;;
10824 ;; seta %al
10825 ;; testb %al, %al
10826 ;; sete %al
10827
10828 (define_split
10829 [(set (match_operand:QI 0 "nonimmediate_operand")
10830 (ne:QI (match_operator 1 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)])
10832 (const_int 0)))]
10833 ""
10834 [(set (match_dup 0) (match_dup 1))]
10835 "PUT_MODE (operands[1], QImode);")
10836
10837 (define_split
10838 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10839 (ne:QI (match_operator 1 "ix86_comparison_operator"
10840 [(reg FLAGS_REG) (const_int 0)])
10841 (const_int 0)))]
10842 ""
10843 [(set (match_dup 0) (match_dup 1))]
10844 "PUT_MODE (operands[1], QImode);")
10845
10846 (define_split
10847 [(set (match_operand:QI 0 "nonimmediate_operand")
10848 (eq:QI (match_operator 1 "ix86_comparison_operator"
10849 [(reg FLAGS_REG) (const_int 0)])
10850 (const_int 0)))]
10851 ""
10852 [(set (match_dup 0) (match_dup 1))]
10853 {
10854 rtx new_op1 = copy_rtx (operands[1]);
10855 operands[1] = new_op1;
10856 PUT_MODE (new_op1, QImode);
10857 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10858 GET_MODE (XEXP (new_op1, 0))));
10859
10860 /* Make sure that (a) the CCmode we have for the flags is strong
10861 enough for the reversed compare or (b) we have a valid FP compare. */
10862 if (! ix86_comparison_operator (new_op1, VOIDmode))
10863 FAIL;
10864 })
10865
10866 (define_split
10867 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10868 (eq:QI (match_operator 1 "ix86_comparison_operator"
10869 [(reg FLAGS_REG) (const_int 0)])
10870 (const_int 0)))]
10871 ""
10872 [(set (match_dup 0) (match_dup 1))]
10873 {
10874 rtx new_op1 = copy_rtx (operands[1]);
10875 operands[1] = new_op1;
10876 PUT_MODE (new_op1, QImode);
10877 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10878 GET_MODE (XEXP (new_op1, 0))));
10879
10880 /* Make sure that (a) the CCmode we have for the flags is strong
10881 enough for the reversed compare or (b) we have a valid FP compare. */
10882 if (! ix86_comparison_operator (new_op1, VOIDmode))
10883 FAIL;
10884 })
10885
10886 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10887 ;; subsequent logical operations are used to imitate conditional moves.
10888 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10889 ;; it directly.
10890
10891 (define_insn "setcc_<mode>_sse"
10892 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10893 (match_operator:MODEF 3 "sse_comparison_operator"
10894 [(match_operand:MODEF 1 "register_operand" "0,x")
10895 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10896 "SSE_FLOAT_MODE_P (<MODE>mode)"
10897 "@
10898 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10899 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10900 [(set_attr "isa" "noavx,avx")
10901 (set_attr "type" "ssecmp")
10902 (set_attr "length_immediate" "1")
10903 (set_attr "prefix" "orig,vex")
10904 (set_attr "mode" "<MODE>")])
10905 \f
10906 ;; Basic conditional jump instructions.
10907 ;; We ignore the overflow flag for signed branch instructions.
10908
10909 (define_insn "*jcc_1"
10910 [(set (pc)
10911 (if_then_else (match_operator 1 "ix86_comparison_operator"
10912 [(reg FLAGS_REG) (const_int 0)])
10913 (label_ref (match_operand 0))
10914 (pc)))]
10915 ""
10916 "%+j%C1\t%l0"
10917 [(set_attr "type" "ibr")
10918 (set_attr "modrm" "0")
10919 (set (attr "length")
10920 (if_then_else (and (ge (minus (match_dup 0) (pc))
10921 (const_int -126))
10922 (lt (minus (match_dup 0) (pc))
10923 (const_int 128)))
10924 (const_int 2)
10925 (const_int 6)))])
10926
10927 (define_insn "*jcc_2"
10928 [(set (pc)
10929 (if_then_else (match_operator 1 "ix86_comparison_operator"
10930 [(reg FLAGS_REG) (const_int 0)])
10931 (pc)
10932 (label_ref (match_operand 0))))]
10933 ""
10934 "%+j%c1\t%l0"
10935 [(set_attr "type" "ibr")
10936 (set_attr "modrm" "0")
10937 (set (attr "length")
10938 (if_then_else (and (ge (minus (match_dup 0) (pc))
10939 (const_int -126))
10940 (lt (minus (match_dup 0) (pc))
10941 (const_int 128)))
10942 (const_int 2)
10943 (const_int 6)))])
10944
10945 ;; In general it is not safe to assume too much about CCmode registers,
10946 ;; so simplify-rtx stops when it sees a second one. Under certain
10947 ;; conditions this is safe on x86, so help combine not create
10948 ;;
10949 ;; seta %al
10950 ;; testb %al, %al
10951 ;; je Lfoo
10952
10953 (define_split
10954 [(set (pc)
10955 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10956 [(reg FLAGS_REG) (const_int 0)])
10957 (const_int 0))
10958 (label_ref (match_operand 1))
10959 (pc)))]
10960 ""
10961 [(set (pc)
10962 (if_then_else (match_dup 0)
10963 (label_ref (match_dup 1))
10964 (pc)))]
10965 "PUT_MODE (operands[0], VOIDmode);")
10966
10967 (define_split
10968 [(set (pc)
10969 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10970 [(reg FLAGS_REG) (const_int 0)])
10971 (const_int 0))
10972 (label_ref (match_operand 1))
10973 (pc)))]
10974 ""
10975 [(set (pc)
10976 (if_then_else (match_dup 0)
10977 (label_ref (match_dup 1))
10978 (pc)))]
10979 {
10980 rtx new_op0 = copy_rtx (operands[0]);
10981 operands[0] = new_op0;
10982 PUT_MODE (new_op0, VOIDmode);
10983 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10984 GET_MODE (XEXP (new_op0, 0))));
10985
10986 /* Make sure that (a) the CCmode we have for the flags is strong
10987 enough for the reversed compare or (b) we have a valid FP compare. */
10988 if (! ix86_comparison_operator (new_op0, VOIDmode))
10989 FAIL;
10990 })
10991
10992 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10993 ;; pass generates from shift insn with QImode operand. Actually, the mode
10994 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10995 ;; appropriate modulo of the bit offset value.
10996
10997 (define_insn_and_split "*jcc_bt<mode>"
10998 [(set (pc)
10999 (if_then_else (match_operator 0 "bt_comparison_operator"
11000 [(zero_extract:SWI48
11001 (match_operand:SWI48 1 "register_operand" "r")
11002 (const_int 1)
11003 (zero_extend:SI
11004 (match_operand:QI 2 "register_operand" "r")))
11005 (const_int 0)])
11006 (label_ref (match_operand 3))
11007 (pc)))
11008 (clobber (reg:CC FLAGS_REG))]
11009 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11010 "#"
11011 "&& 1"
11012 [(set (reg:CCC FLAGS_REG)
11013 (compare:CCC
11014 (zero_extract:SWI48
11015 (match_dup 1)
11016 (const_int 1)
11017 (match_dup 2))
11018 (const_int 0)))
11019 (set (pc)
11020 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11021 (label_ref (match_dup 3))
11022 (pc)))]
11023 {
11024 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11025
11026 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11027 })
11028
11029 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11030 ;; zero extended to SImode.
11031 (define_insn_and_split "*jcc_bt<mode>_1"
11032 [(set (pc)
11033 (if_then_else (match_operator 0 "bt_comparison_operator"
11034 [(zero_extract:SWI48
11035 (match_operand:SWI48 1 "register_operand" "r")
11036 (const_int 1)
11037 (match_operand:SI 2 "register_operand" "r"))
11038 (const_int 0)])
11039 (label_ref (match_operand 3))
11040 (pc)))
11041 (clobber (reg:CC FLAGS_REG))]
11042 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11043 "#"
11044 "&& 1"
11045 [(set (reg:CCC FLAGS_REG)
11046 (compare:CCC
11047 (zero_extract:SWI48
11048 (match_dup 1)
11049 (const_int 1)
11050 (match_dup 2))
11051 (const_int 0)))
11052 (set (pc)
11053 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11054 (label_ref (match_dup 3))
11055 (pc)))]
11056 {
11057 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11058
11059 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11060 })
11061
11062 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11063 ;; also for DImode, this is what combine produces.
11064 (define_insn_and_split "*jcc_bt<mode>_mask"
11065 [(set (pc)
11066 (if_then_else (match_operator 0 "bt_comparison_operator"
11067 [(zero_extract:SWI48
11068 (match_operand:SWI48 1 "register_operand" "r")
11069 (const_int 1)
11070 (and:SI
11071 (match_operand:SI 2 "register_operand" "r")
11072 (match_operand:SI 3 "const_int_operand" "n")))])
11073 (label_ref (match_operand 4))
11074 (pc)))
11075 (clobber (reg:CC FLAGS_REG))]
11076 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11077 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11078 == GET_MODE_BITSIZE (<MODE>mode)-1"
11079 "#"
11080 "&& 1"
11081 [(set (reg:CCC FLAGS_REG)
11082 (compare:CCC
11083 (zero_extract:SWI48
11084 (match_dup 1)
11085 (const_int 1)
11086 (match_dup 2))
11087 (const_int 0)))
11088 (set (pc)
11089 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11090 (label_ref (match_dup 4))
11091 (pc)))]
11092 {
11093 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11094
11095 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11096 })
11097
11098 (define_insn_and_split "*jcc_btsi_1"
11099 [(set (pc)
11100 (if_then_else (match_operator 0 "bt_comparison_operator"
11101 [(and:SI
11102 (lshiftrt:SI
11103 (match_operand:SI 1 "register_operand" "r")
11104 (match_operand:QI 2 "register_operand" "r"))
11105 (const_int 1))
11106 (const_int 0)])
11107 (label_ref (match_operand 3))
11108 (pc)))
11109 (clobber (reg:CC FLAGS_REG))]
11110 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11111 "#"
11112 "&& 1"
11113 [(set (reg:CCC FLAGS_REG)
11114 (compare:CCC
11115 (zero_extract:SI
11116 (match_dup 1)
11117 (const_int 1)
11118 (match_dup 2))
11119 (const_int 0)))
11120 (set (pc)
11121 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11122 (label_ref (match_dup 3))
11123 (pc)))]
11124 {
11125 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11126
11127 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11128 })
11129
11130 ;; avoid useless masking of bit offset operand
11131 (define_insn_and_split "*jcc_btsi_mask_1"
11132 [(set (pc)
11133 (if_then_else
11134 (match_operator 0 "bt_comparison_operator"
11135 [(and:SI
11136 (lshiftrt:SI
11137 (match_operand:SI 1 "register_operand" "r")
11138 (subreg:QI
11139 (and:SI
11140 (match_operand:SI 2 "register_operand" "r")
11141 (match_operand:SI 3 "const_int_operand" "n")) 0))
11142 (const_int 1))
11143 (const_int 0)])
11144 (label_ref (match_operand 4))
11145 (pc)))
11146 (clobber (reg:CC FLAGS_REG))]
11147 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11148 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11149 "#"
11150 "&& 1"
11151 [(set (reg:CCC FLAGS_REG)
11152 (compare:CCC
11153 (zero_extract:SI
11154 (match_dup 1)
11155 (const_int 1)
11156 (match_dup 2))
11157 (const_int 0)))
11158 (set (pc)
11159 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11160 (label_ref (match_dup 4))
11161 (pc)))]
11162 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11163
11164 ;; Define combination compare-and-branch fp compare instructions to help
11165 ;; combine.
11166
11167 (define_insn "*jcc<mode>_0_i387"
11168 [(set (pc)
11169 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11170 [(match_operand:X87MODEF 1 "register_operand" "f")
11171 (match_operand:X87MODEF 2 "const0_operand")])
11172 (label_ref (match_operand 3))
11173 (pc)))
11174 (clobber (reg:CCFP FPSR_REG))
11175 (clobber (reg:CCFP FLAGS_REG))
11176 (clobber (match_scratch:HI 4 "=a"))]
11177 "TARGET_80387 && !TARGET_CMOVE"
11178 "#")
11179
11180 (define_insn "*jcc<mode>_0_r_i387"
11181 [(set (pc)
11182 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11183 [(match_operand:X87MODEF 1 "register_operand" "f")
11184 (match_operand:X87MODEF 2 "const0_operand")])
11185 (pc)
11186 (label_ref (match_operand 3))))
11187 (clobber (reg:CCFP FPSR_REG))
11188 (clobber (reg:CCFP FLAGS_REG))
11189 (clobber (match_scratch:HI 4 "=a"))]
11190 "TARGET_80387 && !TARGET_CMOVE"
11191 "#")
11192
11193 (define_insn "*jccxf_i387"
11194 [(set (pc)
11195 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11196 [(match_operand:XF 1 "register_operand" "f")
11197 (match_operand:XF 2 "register_operand" "f")])
11198 (label_ref (match_operand 3))
11199 (pc)))
11200 (clobber (reg:CCFP FPSR_REG))
11201 (clobber (reg:CCFP FLAGS_REG))
11202 (clobber (match_scratch:HI 4 "=a"))]
11203 "TARGET_80387 && !TARGET_CMOVE"
11204 "#")
11205
11206 (define_insn "*jccxf_r_i387"
11207 [(set (pc)
11208 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11209 [(match_operand:XF 1 "register_operand" "f")
11210 (match_operand:XF 2 "register_operand" "f")])
11211 (pc)
11212 (label_ref (match_operand 3))))
11213 (clobber (reg:CCFP FPSR_REG))
11214 (clobber (reg:CCFP FLAGS_REG))
11215 (clobber (match_scratch:HI 4 "=a"))]
11216 "TARGET_80387 && !TARGET_CMOVE"
11217 "#")
11218
11219 (define_insn "*jcc<mode>_i387"
11220 [(set (pc)
11221 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11222 [(match_operand:MODEF 1 "register_operand" "f")
11223 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11224 (label_ref (match_operand 3))
11225 (pc)))
11226 (clobber (reg:CCFP FPSR_REG))
11227 (clobber (reg:CCFP FLAGS_REG))
11228 (clobber (match_scratch:HI 4 "=a"))]
11229 "TARGET_80387 && !TARGET_CMOVE"
11230 "#")
11231
11232 (define_insn "*jcc<mode>_r_i387"
11233 [(set (pc)
11234 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11235 [(match_operand:MODEF 1 "register_operand" "f")
11236 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11237 (pc)
11238 (label_ref (match_operand 3))))
11239 (clobber (reg:CCFP FPSR_REG))
11240 (clobber (reg:CCFP FLAGS_REG))
11241 (clobber (match_scratch:HI 4 "=a"))]
11242 "TARGET_80387 && !TARGET_CMOVE"
11243 "#")
11244
11245 (define_insn "*jccu<mode>_i387"
11246 [(set (pc)
11247 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11248 [(match_operand:X87MODEF 1 "register_operand" "f")
11249 (match_operand:X87MODEF 2 "register_operand" "f")])
11250 (label_ref (match_operand 3))
11251 (pc)))
11252 (clobber (reg:CCFP FPSR_REG))
11253 (clobber (reg:CCFP FLAGS_REG))
11254 (clobber (match_scratch:HI 4 "=a"))]
11255 "TARGET_80387 && !TARGET_CMOVE"
11256 "#")
11257
11258 (define_insn "*jccu<mode>_r_i387"
11259 [(set (pc)
11260 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11261 [(match_operand:X87MODEF 1 "register_operand" "f")
11262 (match_operand:X87MODEF 2 "register_operand" "f")])
11263 (pc)
11264 (label_ref (match_operand 3))))
11265 (clobber (reg:CCFP FPSR_REG))
11266 (clobber (reg:CCFP FLAGS_REG))
11267 (clobber (match_scratch:HI 4 "=a"))]
11268 "TARGET_80387 && !TARGET_CMOVE"
11269 "#")
11270
11271 (define_split
11272 [(set (pc)
11273 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11274 [(match_operand:X87MODEF 1 "register_operand")
11275 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11276 (match_operand 3)
11277 (match_operand 4)))
11278 (clobber (reg:CCFP FPSR_REG))
11279 (clobber (reg:CCFP FLAGS_REG))]
11280 "TARGET_80387 && !TARGET_CMOVE
11281 && reload_completed"
11282 [(const_int 0)]
11283 {
11284 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11285 operands[3], operands[4], NULL_RTX, NULL_RTX);
11286 DONE;
11287 })
11288
11289 (define_split
11290 [(set (pc)
11291 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11292 [(match_operand:X87MODEF 1 "register_operand")
11293 (match_operand:X87MODEF 2 "general_operand")])
11294 (match_operand 3)
11295 (match_operand 4)))
11296 (clobber (reg:CCFP FPSR_REG))
11297 (clobber (reg:CCFP FLAGS_REG))
11298 (clobber (match_scratch:HI 5))]
11299 "TARGET_80387 && !TARGET_CMOVE
11300 && reload_completed"
11301 [(const_int 0)]
11302 {
11303 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11304 operands[3], operands[4], operands[5], NULL_RTX);
11305 DONE;
11306 })
11307
11308 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11309 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11310 ;; with a precedence over other operators and is always put in the first
11311 ;; place. Swap condition and operands to match ficom instruction.
11312
11313 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11314 [(set (pc)
11315 (if_then_else
11316 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11317 [(match_operator:X87MODEF 1 "float_operator"
11318 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11319 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11320 (label_ref (match_operand 4))
11321 (pc)))
11322 (clobber (reg:CCFP FPSR_REG))
11323 (clobber (reg:CCFP FLAGS_REG))
11324 (clobber (match_scratch:HI 5 "=a,a"))]
11325 "TARGET_80387 && !TARGET_CMOVE
11326 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11327 || optimize_function_for_size_p (cfun))"
11328 "#")
11329
11330 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11331 [(set (pc)
11332 (if_then_else
11333 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11334 [(match_operator:X87MODEF 1 "float_operator"
11335 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11336 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11337 (pc)
11338 (label_ref (match_operand 4))))
11339 (clobber (reg:CCFP FPSR_REG))
11340 (clobber (reg:CCFP FLAGS_REG))
11341 (clobber (match_scratch:HI 5 "=a,a"))]
11342 "TARGET_80387 && !TARGET_CMOVE
11343 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11344 || optimize_function_for_size_p (cfun))"
11345 "#")
11346
11347 (define_split
11348 [(set (pc)
11349 (if_then_else
11350 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11351 [(match_operator:X87MODEF 1 "float_operator"
11352 [(match_operand:SWI24 2 "memory_operand")])
11353 (match_operand:X87MODEF 3 "register_operand")])
11354 (match_operand 4)
11355 (match_operand 5)))
11356 (clobber (reg:CCFP FPSR_REG))
11357 (clobber (reg:CCFP FLAGS_REG))
11358 (clobber (match_scratch:HI 6))]
11359 "TARGET_80387 && !TARGET_CMOVE
11360 && reload_completed"
11361 [(const_int 0)]
11362 {
11363 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11364 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11365 operands[4], operands[5], operands[6], NULL_RTX);
11366 DONE;
11367 })
11368
11369 ;; %%% Kill this when reload knows how to do it.
11370 (define_split
11371 [(set (pc)
11372 (if_then_else
11373 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11374 [(match_operator:X87MODEF 1 "float_operator"
11375 [(match_operand:SWI24 2 "register_operand")])
11376 (match_operand:X87MODEF 3 "register_operand")])
11377 (match_operand 4)
11378 (match_operand 5)))
11379 (clobber (reg:CCFP FPSR_REG))
11380 (clobber (reg:CCFP FLAGS_REG))
11381 (clobber (match_scratch:HI 6))]
11382 "TARGET_80387 && !TARGET_CMOVE
11383 && reload_completed"
11384 [(const_int 0)]
11385 {
11386 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11387
11388 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11389 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11390 operands[4], operands[5], operands[6], operands[2]);
11391 DONE;
11392 })
11393 \f
11394 ;; Unconditional and other jump instructions
11395
11396 (define_insn "jump"
11397 [(set (pc)
11398 (label_ref (match_operand 0)))]
11399 ""
11400 "jmp\t%l0"
11401 [(set_attr "type" "ibr")
11402 (set (attr "length")
11403 (if_then_else (and (ge (minus (match_dup 0) (pc))
11404 (const_int -126))
11405 (lt (minus (match_dup 0) (pc))
11406 (const_int 128)))
11407 (const_int 2)
11408 (const_int 5)))
11409 (set_attr "modrm" "0")])
11410
11411 (define_expand "indirect_jump"
11412 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11413 ""
11414 {
11415 if (TARGET_X32)
11416 operands[0] = convert_memory_address (word_mode, operands[0]);
11417 })
11418
11419 (define_insn "*indirect_jump"
11420 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11421 ""
11422 "jmp\t%A0"
11423 [(set_attr "type" "ibr")
11424 (set_attr "length_immediate" "0")])
11425
11426 (define_expand "tablejump"
11427 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11428 (use (label_ref (match_operand 1)))])]
11429 ""
11430 {
11431 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11432 relative. Convert the relative address to an absolute address. */
11433 if (flag_pic)
11434 {
11435 rtx op0, op1;
11436 enum rtx_code code;
11437
11438 /* We can't use @GOTOFF for text labels on VxWorks;
11439 see gotoff_operand. */
11440 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11441 {
11442 code = PLUS;
11443 op0 = operands[0];
11444 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11445 }
11446 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11447 {
11448 code = PLUS;
11449 op0 = operands[0];
11450 op1 = pic_offset_table_rtx;
11451 }
11452 else
11453 {
11454 code = MINUS;
11455 op0 = pic_offset_table_rtx;
11456 op1 = operands[0];
11457 }
11458
11459 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11460 OPTAB_DIRECT);
11461 }
11462
11463 if (TARGET_X32)
11464 operands[0] = convert_memory_address (word_mode, operands[0]);
11465 })
11466
11467 (define_insn "*tablejump_1"
11468 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11469 (use (label_ref (match_operand 1)))]
11470 ""
11471 "jmp\t%A0"
11472 [(set_attr "type" "ibr")
11473 (set_attr "length_immediate" "0")])
11474 \f
11475 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11476
11477 (define_peephole2
11478 [(set (reg FLAGS_REG) (match_operand 0))
11479 (set (match_operand:QI 1 "register_operand")
11480 (match_operator:QI 2 "ix86_comparison_operator"
11481 [(reg FLAGS_REG) (const_int 0)]))
11482 (set (match_operand 3 "q_regs_operand")
11483 (zero_extend (match_dup 1)))]
11484 "(peep2_reg_dead_p (3, operands[1])
11485 || operands_match_p (operands[1], operands[3]))
11486 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11487 [(set (match_dup 4) (match_dup 0))
11488 (set (strict_low_part (match_dup 5))
11489 (match_dup 2))]
11490 {
11491 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11492 operands[5] = gen_lowpart (QImode, operands[3]);
11493 ix86_expand_clear (operands[3]);
11494 })
11495
11496 (define_peephole2
11497 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11498 (match_operand 4)])
11499 (set (match_operand:QI 1 "register_operand")
11500 (match_operator:QI 2 "ix86_comparison_operator"
11501 [(reg FLAGS_REG) (const_int 0)]))
11502 (set (match_operand 3 "q_regs_operand")
11503 (zero_extend (match_dup 1)))]
11504 "(peep2_reg_dead_p (3, operands[1])
11505 || operands_match_p (operands[1], operands[3]))
11506 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11507 [(parallel [(set (match_dup 5) (match_dup 0))
11508 (match_dup 4)])
11509 (set (strict_low_part (match_dup 6))
11510 (match_dup 2))]
11511 {
11512 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11513 operands[6] = gen_lowpart (QImode, operands[3]);
11514 ix86_expand_clear (operands[3]);
11515 })
11516
11517 ;; Similar, but match zero extend with andsi3.
11518
11519 (define_peephole2
11520 [(set (reg FLAGS_REG) (match_operand 0))
11521 (set (match_operand:QI 1 "register_operand")
11522 (match_operator:QI 2 "ix86_comparison_operator"
11523 [(reg FLAGS_REG) (const_int 0)]))
11524 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11525 (and:SI (match_dup 3) (const_int 255)))
11526 (clobber (reg:CC FLAGS_REG))])]
11527 "REGNO (operands[1]) == REGNO (operands[3])
11528 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11529 [(set (match_dup 4) (match_dup 0))
11530 (set (strict_low_part (match_dup 5))
11531 (match_dup 2))]
11532 {
11533 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11534 operands[5] = gen_lowpart (QImode, operands[3]);
11535 ix86_expand_clear (operands[3]);
11536 })
11537
11538 (define_peephole2
11539 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11540 (match_operand 4)])
11541 (set (match_operand:QI 1 "register_operand")
11542 (match_operator:QI 2 "ix86_comparison_operator"
11543 [(reg FLAGS_REG) (const_int 0)]))
11544 (parallel [(set (match_operand 3 "q_regs_operand")
11545 (zero_extend (match_dup 1)))
11546 (clobber (reg:CC FLAGS_REG))])]
11547 "(peep2_reg_dead_p (3, operands[1])
11548 || operands_match_p (operands[1], operands[3]))
11549 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11550 [(parallel [(set (match_dup 5) (match_dup 0))
11551 (match_dup 4)])
11552 (set (strict_low_part (match_dup 6))
11553 (match_dup 2))]
11554 {
11555 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11556 operands[6] = gen_lowpart (QImode, operands[3]);
11557 ix86_expand_clear (operands[3]);
11558 })
11559 \f
11560 ;; Call instructions.
11561
11562 ;; The predicates normally associated with named expanders are not properly
11563 ;; checked for calls. This is a bug in the generic code, but it isn't that
11564 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11565
11566 ;; P6 processors will jump to the address after the decrement when %esp
11567 ;; is used as a call operand, so they will execute return address as a code.
11568 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11569
11570 ;; Register constraint for call instruction.
11571 (define_mode_attr c [(SI "l") (DI "r")])
11572
11573 ;; Call subroutine returning no value.
11574
11575 (define_expand "call"
11576 [(call (match_operand:QI 0)
11577 (match_operand 1))
11578 (use (match_operand 2))]
11579 ""
11580 {
11581 ix86_expand_call (NULL, operands[0], operands[1],
11582 operands[2], NULL, false);
11583 DONE;
11584 })
11585
11586 (define_expand "sibcall"
11587 [(call (match_operand:QI 0)
11588 (match_operand 1))
11589 (use (match_operand 2))]
11590 ""
11591 {
11592 ix86_expand_call (NULL, operands[0], operands[1],
11593 operands[2], NULL, true);
11594 DONE;
11595 })
11596
11597 (define_insn "*call"
11598 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11599 (match_operand 1))]
11600 "!SIBLING_CALL_P (insn)"
11601 "* return ix86_output_call_insn (insn, operands[0]);"
11602 [(set_attr "type" "call")])
11603
11604 (define_insn "*call_rex64_ms_sysv"
11605 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11606 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11607 (match_operand 1))
11608 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11609 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11610 "* return ix86_output_call_insn (insn, operands[0]);"
11611 [(set_attr "type" "call")])
11612
11613 (define_insn "*sibcall"
11614 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11615 (match_operand 1))]
11616 "SIBLING_CALL_P (insn)"
11617 "* return ix86_output_call_insn (insn, operands[0]);"
11618 [(set_attr "type" "call")])
11619
11620 (define_expand "call_pop"
11621 [(parallel [(call (match_operand:QI 0)
11622 (match_operand:SI 1))
11623 (set (reg:SI SP_REG)
11624 (plus:SI (reg:SI SP_REG)
11625 (match_operand:SI 3)))])]
11626 "!TARGET_64BIT"
11627 {
11628 ix86_expand_call (NULL, operands[0], operands[1],
11629 operands[2], operands[3], false);
11630 DONE;
11631 })
11632
11633 (define_insn "*call_pop"
11634 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11635 (match_operand 1))
11636 (set (reg:SI SP_REG)
11637 (plus:SI (reg:SI SP_REG)
11638 (match_operand:SI 2 "immediate_operand" "i")))]
11639 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11640 "* return ix86_output_call_insn (insn, operands[0]);"
11641 [(set_attr "type" "call")])
11642
11643 (define_insn "*sibcall_pop"
11644 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11645 (match_operand 1))
11646 (set (reg:SI SP_REG)
11647 (plus:SI (reg:SI SP_REG)
11648 (match_operand:SI 2 "immediate_operand" "i")))]
11649 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11650 "* return ix86_output_call_insn (insn, operands[0]);"
11651 [(set_attr "type" "call")])
11652
11653 ;; Call subroutine, returning value in operand 0
11654
11655 (define_expand "call_value"
11656 [(set (match_operand 0)
11657 (call (match_operand:QI 1)
11658 (match_operand 2)))
11659 (use (match_operand 3))]
11660 ""
11661 {
11662 ix86_expand_call (operands[0], operands[1], operands[2],
11663 operands[3], NULL, false);
11664 DONE;
11665 })
11666
11667 (define_expand "sibcall_value"
11668 [(set (match_operand 0)
11669 (call (match_operand:QI 1)
11670 (match_operand 2)))
11671 (use (match_operand 3))]
11672 ""
11673 {
11674 ix86_expand_call (operands[0], operands[1], operands[2],
11675 operands[3], NULL, true);
11676 DONE;
11677 })
11678
11679 (define_insn "*call_value"
11680 [(set (match_operand 0)
11681 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11682 (match_operand 2)))]
11683 "!SIBLING_CALL_P (insn)"
11684 "* return ix86_output_call_insn (insn, operands[1]);"
11685 [(set_attr "type" "callv")])
11686
11687 (define_insn "*sibcall_value"
11688 [(set (match_operand 0)
11689 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11690 (match_operand 2)))]
11691 "SIBLING_CALL_P (insn)"
11692 "* return ix86_output_call_insn (insn, operands[1]);"
11693 [(set_attr "type" "callv")])
11694
11695 (define_insn "*call_value_rex64_ms_sysv"
11696 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11697 [(set (match_operand 0)
11698 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11699 (match_operand 2)))
11700 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11701 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11702 "* return ix86_output_call_insn (insn, operands[1]);"
11703 [(set_attr "type" "callv")])
11704
11705 (define_expand "call_value_pop"
11706 [(parallel [(set (match_operand 0)
11707 (call (match_operand:QI 1)
11708 (match_operand:SI 2)))
11709 (set (reg:SI SP_REG)
11710 (plus:SI (reg:SI SP_REG)
11711 (match_operand:SI 4)))])]
11712 "!TARGET_64BIT"
11713 {
11714 ix86_expand_call (operands[0], operands[1], operands[2],
11715 operands[3], operands[4], false);
11716 DONE;
11717 })
11718
11719 (define_insn "*call_value_pop"
11720 [(set (match_operand 0)
11721 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11722 (match_operand 2)))
11723 (set (reg:SI SP_REG)
11724 (plus:SI (reg:SI SP_REG)
11725 (match_operand:SI 3 "immediate_operand" "i")))]
11726 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11727 "* return ix86_output_call_insn (insn, operands[1]);"
11728 [(set_attr "type" "callv")])
11729
11730 (define_insn "*sibcall_value_pop"
11731 [(set (match_operand 0)
11732 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11733 (match_operand 2)))
11734 (set (reg:SI SP_REG)
11735 (plus:SI (reg:SI SP_REG)
11736 (match_operand:SI 3 "immediate_operand" "i")))]
11737 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11738 "* return ix86_output_call_insn (insn, operands[1]);"
11739 [(set_attr "type" "callv")])
11740
11741 ;; Call subroutine returning any type.
11742
11743 (define_expand "untyped_call"
11744 [(parallel [(call (match_operand 0)
11745 (const_int 0))
11746 (match_operand 1)
11747 (match_operand 2)])]
11748 ""
11749 {
11750 int i;
11751
11752 /* In order to give reg-stack an easier job in validating two
11753 coprocessor registers as containing a possible return value,
11754 simply pretend the untyped call returns a complex long double
11755 value.
11756
11757 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11758 and should have the default ABI. */
11759
11760 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11761 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11762 operands[0], const0_rtx,
11763 GEN_INT ((TARGET_64BIT
11764 ? (ix86_abi == SYSV_ABI
11765 ? X86_64_SSE_REGPARM_MAX
11766 : X86_64_MS_SSE_REGPARM_MAX)
11767 : X86_32_SSE_REGPARM_MAX)
11768 - 1),
11769 NULL, false);
11770
11771 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11772 {
11773 rtx set = XVECEXP (operands[2], 0, i);
11774 emit_move_insn (SET_DEST (set), SET_SRC (set));
11775 }
11776
11777 /* The optimizer does not know that the call sets the function value
11778 registers we stored in the result block. We avoid problems by
11779 claiming that all hard registers are used and clobbered at this
11780 point. */
11781 emit_insn (gen_blockage ());
11782
11783 DONE;
11784 })
11785 \f
11786 ;; Prologue and epilogue instructions
11787
11788 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11789 ;; all of memory. This blocks insns from being moved across this point.
11790
11791 (define_insn "blockage"
11792 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11793 ""
11794 ""
11795 [(set_attr "length" "0")])
11796
11797 ;; Do not schedule instructions accessing memory across this point.
11798
11799 (define_expand "memory_blockage"
11800 [(set (match_dup 0)
11801 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11802 ""
11803 {
11804 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11805 MEM_VOLATILE_P (operands[0]) = 1;
11806 })
11807
11808 (define_insn "*memory_blockage"
11809 [(set (match_operand:BLK 0)
11810 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11811 ""
11812 ""
11813 [(set_attr "length" "0")])
11814
11815 ;; As USE insns aren't meaningful after reload, this is used instead
11816 ;; to prevent deleting instructions setting registers for PIC code
11817 (define_insn "prologue_use"
11818 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11819 ""
11820 ""
11821 [(set_attr "length" "0")])
11822
11823 ;; Insn emitted into the body of a function to return from a function.
11824 ;; This is only done if the function's epilogue is known to be simple.
11825 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11826
11827 (define_expand "return"
11828 [(simple_return)]
11829 "ix86_can_use_return_insn_p ()"
11830 {
11831 if (crtl->args.pops_args)
11832 {
11833 rtx popc = GEN_INT (crtl->args.pops_args);
11834 emit_jump_insn (gen_simple_return_pop_internal (popc));
11835 DONE;
11836 }
11837 })
11838
11839 ;; We need to disable this for TARGET_SEH, as otherwise
11840 ;; shrink-wrapped prologue gets enabled too. This might exceed
11841 ;; the maximum size of prologue in unwind information.
11842
11843 (define_expand "simple_return"
11844 [(simple_return)]
11845 "!TARGET_SEH"
11846 {
11847 if (crtl->args.pops_args)
11848 {
11849 rtx popc = GEN_INT (crtl->args.pops_args);
11850 emit_jump_insn (gen_simple_return_pop_internal (popc));
11851 DONE;
11852 }
11853 })
11854
11855 (define_insn "simple_return_internal"
11856 [(simple_return)]
11857 "reload_completed"
11858 "ret"
11859 [(set_attr "length" "1")
11860 (set_attr "atom_unit" "jeu")
11861 (set_attr "length_immediate" "0")
11862 (set_attr "modrm" "0")])
11863
11864 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11865 ;; instruction Athlon and K8 have.
11866
11867 (define_insn "simple_return_internal_long"
11868 [(simple_return)
11869 (unspec [(const_int 0)] UNSPEC_REP)]
11870 "reload_completed"
11871 "rep%; ret"
11872 [(set_attr "length" "2")
11873 (set_attr "atom_unit" "jeu")
11874 (set_attr "length_immediate" "0")
11875 (set_attr "prefix_rep" "1")
11876 (set_attr "modrm" "0")])
11877
11878 (define_insn "simple_return_pop_internal"
11879 [(simple_return)
11880 (use (match_operand:SI 0 "const_int_operand"))]
11881 "reload_completed"
11882 "ret\t%0"
11883 [(set_attr "length" "3")
11884 (set_attr "atom_unit" "jeu")
11885 (set_attr "length_immediate" "2")
11886 (set_attr "modrm" "0")])
11887
11888 (define_insn "simple_return_indirect_internal"
11889 [(simple_return)
11890 (use (match_operand:SI 0 "register_operand" "r"))]
11891 "reload_completed"
11892 "jmp\t%A0"
11893 [(set_attr "type" "ibr")
11894 (set_attr "length_immediate" "0")])
11895
11896 (define_insn "nop"
11897 [(const_int 0)]
11898 ""
11899 "nop"
11900 [(set_attr "length" "1")
11901 (set_attr "length_immediate" "0")
11902 (set_attr "modrm" "0")])
11903
11904 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11905 (define_insn "nops"
11906 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11907 UNSPECV_NOPS)]
11908 "reload_completed"
11909 {
11910 int num = INTVAL (operands[0]);
11911
11912 gcc_assert (IN_RANGE (num, 1, 8));
11913
11914 while (num--)
11915 fputs ("\tnop\n", asm_out_file);
11916
11917 return "";
11918 }
11919 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11920 (set_attr "length_immediate" "0")
11921 (set_attr "modrm" "0")])
11922
11923 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11924 ;; branch prediction penalty for the third jump in a 16-byte
11925 ;; block on K8.
11926
11927 (define_insn "pad"
11928 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11929 ""
11930 {
11931 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11932 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11933 #else
11934 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11935 The align insn is used to avoid 3 jump instructions in the row to improve
11936 branch prediction and the benefits hardly outweigh the cost of extra 8
11937 nops on the average inserted by full alignment pseudo operation. */
11938 #endif
11939 return "";
11940 }
11941 [(set_attr "length" "16")])
11942
11943 (define_expand "prologue"
11944 [(const_int 0)]
11945 ""
11946 "ix86_expand_prologue (); DONE;")
11947
11948 (define_insn "set_got"
11949 [(set (match_operand:SI 0 "register_operand" "=r")
11950 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11951 (clobber (reg:CC FLAGS_REG))]
11952 "!TARGET_64BIT"
11953 "* return output_set_got (operands[0], NULL_RTX);"
11954 [(set_attr "type" "multi")
11955 (set_attr "length" "12")])
11956
11957 (define_insn "set_got_labelled"
11958 [(set (match_operand:SI 0 "register_operand" "=r")
11959 (unspec:SI [(label_ref (match_operand 1))]
11960 UNSPEC_SET_GOT))
11961 (clobber (reg:CC FLAGS_REG))]
11962 "!TARGET_64BIT"
11963 "* return output_set_got (operands[0], operands[1]);"
11964 [(set_attr "type" "multi")
11965 (set_attr "length" "12")])
11966
11967 (define_insn "set_got_rex64"
11968 [(set (match_operand:DI 0 "register_operand" "=r")
11969 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11970 "TARGET_64BIT"
11971 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11972 [(set_attr "type" "lea")
11973 (set_attr "length_address" "4")
11974 (set_attr "mode" "DI")])
11975
11976 (define_insn "set_rip_rex64"
11977 [(set (match_operand:DI 0 "register_operand" "=r")
11978 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11979 "TARGET_64BIT"
11980 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11981 [(set_attr "type" "lea")
11982 (set_attr "length_address" "4")
11983 (set_attr "mode" "DI")])
11984
11985 (define_insn "set_got_offset_rex64"
11986 [(set (match_operand:DI 0 "register_operand" "=r")
11987 (unspec:DI
11988 [(label_ref (match_operand 1))]
11989 UNSPEC_SET_GOT_OFFSET))]
11990 "TARGET_LP64"
11991 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11992 [(set_attr "type" "imov")
11993 (set_attr "length_immediate" "0")
11994 (set_attr "length_address" "8")
11995 (set_attr "mode" "DI")])
11996
11997 (define_expand "epilogue"
11998 [(const_int 0)]
11999 ""
12000 "ix86_expand_epilogue (1); DONE;")
12001
12002 (define_expand "sibcall_epilogue"
12003 [(const_int 0)]
12004 ""
12005 "ix86_expand_epilogue (0); DONE;")
12006
12007 (define_expand "eh_return"
12008 [(use (match_operand 0 "register_operand"))]
12009 ""
12010 {
12011 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12012
12013 /* Tricky bit: we write the address of the handler to which we will
12014 be returning into someone else's stack frame, one word below the
12015 stack address we wish to restore. */
12016 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12017 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12018 tmp = gen_rtx_MEM (Pmode, tmp);
12019 emit_move_insn (tmp, ra);
12020
12021 emit_jump_insn (gen_eh_return_internal ());
12022 emit_barrier ();
12023 DONE;
12024 })
12025
12026 (define_insn_and_split "eh_return_internal"
12027 [(eh_return)]
12028 ""
12029 "#"
12030 "epilogue_completed"
12031 [(const_int 0)]
12032 "ix86_expand_epilogue (2); DONE;")
12033
12034 (define_insn "leave"
12035 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12036 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12037 (clobber (mem:BLK (scratch)))]
12038 "!TARGET_64BIT"
12039 "leave"
12040 [(set_attr "type" "leave")])
12041
12042 (define_insn "leave_rex64"
12043 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12044 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12045 (clobber (mem:BLK (scratch)))]
12046 "TARGET_64BIT"
12047 "leave"
12048 [(set_attr "type" "leave")])
12049 \f
12050 ;; Handle -fsplit-stack.
12051
12052 (define_expand "split_stack_prologue"
12053 [(const_int 0)]
12054 ""
12055 {
12056 ix86_expand_split_stack_prologue ();
12057 DONE;
12058 })
12059
12060 ;; In order to support the call/return predictor, we use a return
12061 ;; instruction which the middle-end doesn't see.
12062 (define_insn "split_stack_return"
12063 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12064 UNSPECV_SPLIT_STACK_RETURN)]
12065 ""
12066 {
12067 if (operands[0] == const0_rtx)
12068 return "ret";
12069 else
12070 return "ret\t%0";
12071 }
12072 [(set_attr "atom_unit" "jeu")
12073 (set_attr "modrm" "0")
12074 (set (attr "length")
12075 (if_then_else (match_operand:SI 0 "const0_operand")
12076 (const_int 1)
12077 (const_int 3)))
12078 (set (attr "length_immediate")
12079 (if_then_else (match_operand:SI 0 "const0_operand")
12080 (const_int 0)
12081 (const_int 2)))])
12082
12083 ;; If there are operand 0 bytes available on the stack, jump to
12084 ;; operand 1.
12085
12086 (define_expand "split_stack_space_check"
12087 [(set (pc) (if_then_else
12088 (ltu (minus (reg SP_REG)
12089 (match_operand 0 "register_operand"))
12090 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12091 (label_ref (match_operand 1))
12092 (pc)))]
12093 ""
12094 {
12095 rtx reg, size, limit;
12096
12097 reg = gen_reg_rtx (Pmode);
12098 size = force_reg (Pmode, operands[0]);
12099 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12100 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12101 UNSPEC_STACK_CHECK);
12102 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12103 ix86_expand_branch (GEU, reg, limit, operands[1]);
12104
12105 DONE;
12106 })
12107 \f
12108 ;; Bit manipulation instructions.
12109
12110 (define_expand "ffs<mode>2"
12111 [(set (match_dup 2) (const_int -1))
12112 (parallel [(set (match_dup 3) (match_dup 4))
12113 (set (match_operand:SWI48 0 "register_operand")
12114 (ctz:SWI48
12115 (match_operand:SWI48 1 "nonimmediate_operand")))])
12116 (set (match_dup 0) (if_then_else:SWI48
12117 (eq (match_dup 3) (const_int 0))
12118 (match_dup 2)
12119 (match_dup 0)))
12120 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12121 (clobber (reg:CC FLAGS_REG))])]
12122 ""
12123 {
12124 enum machine_mode flags_mode;
12125
12126 if (<MODE>mode == SImode && !TARGET_CMOVE)
12127 {
12128 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12129 DONE;
12130 }
12131
12132 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12133
12134 operands[2] = gen_reg_rtx (<MODE>mode);
12135 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12136 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12137 })
12138
12139 (define_insn_and_split "ffssi2_no_cmove"
12140 [(set (match_operand:SI 0 "register_operand" "=r")
12141 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12142 (clobber (match_scratch:SI 2 "=&q"))
12143 (clobber (reg:CC FLAGS_REG))]
12144 "!TARGET_CMOVE"
12145 "#"
12146 "&& reload_completed"
12147 [(parallel [(set (match_dup 4) (match_dup 5))
12148 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12149 (set (strict_low_part (match_dup 3))
12150 (eq:QI (match_dup 4) (const_int 0)))
12151 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12152 (clobber (reg:CC FLAGS_REG))])
12153 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12154 (clobber (reg:CC FLAGS_REG))])
12155 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12156 (clobber (reg:CC FLAGS_REG))])]
12157 {
12158 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12159
12160 operands[3] = gen_lowpart (QImode, operands[2]);
12161 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12162 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12163
12164 ix86_expand_clear (operands[2]);
12165 })
12166
12167 (define_insn "*tzcnt<mode>_1"
12168 [(set (reg:CCC FLAGS_REG)
12169 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12170 (const_int 0)))
12171 (set (match_operand:SWI48 0 "register_operand" "=r")
12172 (ctz:SWI48 (match_dup 1)))]
12173 "TARGET_BMI"
12174 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12175 [(set_attr "type" "alu1")
12176 (set_attr "prefix_0f" "1")
12177 (set_attr "prefix_rep" "1")
12178 (set_attr "btver2_decode" "double")
12179 (set_attr "mode" "<MODE>")])
12180
12181 (define_insn "*bsf<mode>_1"
12182 [(set (reg:CCZ FLAGS_REG)
12183 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12184 (const_int 0)))
12185 (set (match_operand:SWI48 0 "register_operand" "=r")
12186 (ctz:SWI48 (match_dup 1)))]
12187 ""
12188 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12189 [(set_attr "type" "alu1")
12190 (set_attr "prefix_0f" "1")
12191 (set_attr "btver2_decode" "double")
12192 (set_attr "mode" "<MODE>")])
12193
12194 (define_insn "ctz<mode>2"
12195 [(set (match_operand:SWI248 0 "register_operand" "=r")
12196 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12197 (clobber (reg:CC FLAGS_REG))]
12198 ""
12199 {
12200 if (TARGET_BMI)
12201 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12202 else if (optimize_function_for_size_p (cfun))
12203 ;
12204 else if (TARGET_GENERIC)
12205 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12206 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12207
12208 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12209 }
12210 [(set_attr "type" "alu1")
12211 (set_attr "prefix_0f" "1")
12212 (set (attr "prefix_rep")
12213 (if_then_else
12214 (ior (match_test "TARGET_BMI")
12215 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12216 (match_test "TARGET_GENERIC")))
12217 (const_string "1")
12218 (const_string "0")))
12219 (set_attr "mode" "<MODE>")])
12220
12221 (define_expand "clz<mode>2"
12222 [(parallel
12223 [(set (match_operand:SWI248 0 "register_operand")
12224 (minus:SWI248
12225 (match_dup 2)
12226 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12227 (clobber (reg:CC FLAGS_REG))])
12228 (parallel
12229 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12230 (clobber (reg:CC FLAGS_REG))])]
12231 ""
12232 {
12233 if (TARGET_LZCNT)
12234 {
12235 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12236 DONE;
12237 }
12238 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12239 })
12240
12241 (define_insn "clz<mode>2_lzcnt"
12242 [(set (match_operand:SWI248 0 "register_operand" "=r")
12243 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12244 (clobber (reg:CC FLAGS_REG))]
12245 "TARGET_LZCNT"
12246 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12247 [(set_attr "prefix_rep" "1")
12248 (set_attr "type" "bitmanip")
12249 (set_attr "mode" "<MODE>")])
12250
12251 ;; BMI instructions.
12252 (define_insn "*bmi_andn_<mode>"
12253 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12254 (and:SWI48
12255 (not:SWI48
12256 (match_operand:SWI48 1 "register_operand" "r,r"))
12257 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12258 (clobber (reg:CC FLAGS_REG))]
12259 "TARGET_BMI"
12260 "andn\t{%2, %1, %0|%0, %1, %2}"
12261 [(set_attr "type" "bitmanip")
12262 (set_attr "btver2_decode" "direct, double")
12263 (set_attr "mode" "<MODE>")])
12264
12265 (define_insn "bmi_bextr_<mode>"
12266 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12267 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12268 (match_operand:SWI48 2 "register_operand" "r,r")]
12269 UNSPEC_BEXTR))
12270 (clobber (reg:CC FLAGS_REG))]
12271 "TARGET_BMI"
12272 "bextr\t{%2, %1, %0|%0, %1, %2}"
12273 [(set_attr "type" "bitmanip")
12274 (set_attr "btver2_decode" "direct, double")
12275 (set_attr "mode" "<MODE>")])
12276
12277 (define_insn "*bmi_blsi_<mode>"
12278 [(set (match_operand:SWI48 0 "register_operand" "=r")
12279 (and:SWI48
12280 (neg:SWI48
12281 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12282 (match_dup 1)))
12283 (clobber (reg:CC FLAGS_REG))]
12284 "TARGET_BMI"
12285 "blsi\t{%1, %0|%0, %1}"
12286 [(set_attr "type" "bitmanip")
12287 (set_attr "btver2_decode" "double")
12288 (set_attr "mode" "<MODE>")])
12289
12290 (define_insn "*bmi_blsmsk_<mode>"
12291 [(set (match_operand:SWI48 0 "register_operand" "=r")
12292 (xor:SWI48
12293 (plus:SWI48
12294 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12295 (const_int -1))
12296 (match_dup 1)))
12297 (clobber (reg:CC FLAGS_REG))]
12298 "TARGET_BMI"
12299 "blsmsk\t{%1, %0|%0, %1}"
12300 [(set_attr "type" "bitmanip")
12301 (set_attr "btver2_decode" "double")
12302 (set_attr "mode" "<MODE>")])
12303
12304 (define_insn "*bmi_blsr_<mode>"
12305 [(set (match_operand:SWI48 0 "register_operand" "=r")
12306 (and:SWI48
12307 (plus:SWI48
12308 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12309 (const_int -1))
12310 (match_dup 1)))
12311 (clobber (reg:CC FLAGS_REG))]
12312 "TARGET_BMI"
12313 "blsr\t{%1, %0|%0, %1}"
12314 [(set_attr "type" "bitmanip")
12315 (set_attr "btver2_decode" "double")
12316 (set_attr "mode" "<MODE>")])
12317
12318 ;; BMI2 instructions.
12319 (define_insn "bmi2_bzhi_<mode>3"
12320 [(set (match_operand:SWI48 0 "register_operand" "=r")
12321 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12322 (match_operand:SWI48 2 "register_operand" "r"))
12323 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12324 (clobber (reg:CC FLAGS_REG))]
12325 "TARGET_BMI2"
12326 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12327 [(set_attr "type" "bitmanip")
12328 (set_attr "prefix" "vex")
12329 (set_attr "mode" "<MODE>")])
12330
12331 (define_insn "bmi2_pdep_<mode>3"
12332 [(set (match_operand:SWI48 0 "register_operand" "=r")
12333 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12334 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12335 UNSPEC_PDEP))]
12336 "TARGET_BMI2"
12337 "pdep\t{%2, %1, %0|%0, %1, %2}"
12338 [(set_attr "type" "bitmanip")
12339 (set_attr "prefix" "vex")
12340 (set_attr "mode" "<MODE>")])
12341
12342 (define_insn "bmi2_pext_<mode>3"
12343 [(set (match_operand:SWI48 0 "register_operand" "=r")
12344 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12345 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12346 UNSPEC_PEXT))]
12347 "TARGET_BMI2"
12348 "pext\t{%2, %1, %0|%0, %1, %2}"
12349 [(set_attr "type" "bitmanip")
12350 (set_attr "prefix" "vex")
12351 (set_attr "mode" "<MODE>")])
12352
12353 ;; TBM instructions.
12354 (define_insn "tbm_bextri_<mode>"
12355 [(set (match_operand:SWI48 0 "register_operand" "=r")
12356 (zero_extract:SWI48
12357 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12358 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12359 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12360 (clobber (reg:CC FLAGS_REG))]
12361 "TARGET_TBM"
12362 {
12363 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12364 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12365 }
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "mode" "<MODE>")])
12368
12369 (define_insn "*tbm_blcfill_<mode>"
12370 [(set (match_operand:SWI48 0 "register_operand" "=r")
12371 (and:SWI48
12372 (plus:SWI48
12373 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12374 (const_int 1))
12375 (match_dup 1)))
12376 (clobber (reg:CC FLAGS_REG))]
12377 "TARGET_TBM"
12378 "blcfill\t{%1, %0|%0, %1}"
12379 [(set_attr "type" "bitmanip")
12380 (set_attr "mode" "<MODE>")])
12381
12382 (define_insn "*tbm_blci_<mode>"
12383 [(set (match_operand:SWI48 0 "register_operand" "=r")
12384 (ior:SWI48
12385 (not:SWI48
12386 (plus:SWI48
12387 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12388 (const_int 1)))
12389 (match_dup 1)))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "TARGET_TBM"
12392 "blci\t{%1, %0|%0, %1}"
12393 [(set_attr "type" "bitmanip")
12394 (set_attr "mode" "<MODE>")])
12395
12396 (define_insn "*tbm_blcic_<mode>"
12397 [(set (match_operand:SWI48 0 "register_operand" "=r")
12398 (and:SWI48
12399 (plus:SWI48
12400 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12401 (const_int 1))
12402 (not:SWI48
12403 (match_dup 1))))
12404 (clobber (reg:CC FLAGS_REG))]
12405 "TARGET_TBM"
12406 "blcic\t{%1, %0|%0, %1}"
12407 [(set_attr "type" "bitmanip")
12408 (set_attr "mode" "<MODE>")])
12409
12410 (define_insn "*tbm_blcmsk_<mode>"
12411 [(set (match_operand:SWI48 0 "register_operand" "=r")
12412 (xor:SWI48
12413 (plus:SWI48
12414 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12415 (const_int 1))
12416 (match_dup 1)))
12417 (clobber (reg:CC FLAGS_REG))]
12418 "TARGET_TBM"
12419 "blcmsk\t{%1, %0|%0, %1}"
12420 [(set_attr "type" "bitmanip")
12421 (set_attr "mode" "<MODE>")])
12422
12423 (define_insn "*tbm_blcs_<mode>"
12424 [(set (match_operand:SWI48 0 "register_operand" "=r")
12425 (ior:SWI48
12426 (plus:SWI48
12427 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12428 (const_int 1))
12429 (match_dup 1)))
12430 (clobber (reg:CC FLAGS_REG))]
12431 "TARGET_TBM"
12432 "blcs\t{%1, %0|%0, %1}"
12433 [(set_attr "type" "bitmanip")
12434 (set_attr "mode" "<MODE>")])
12435
12436 (define_insn "*tbm_blsfill_<mode>"
12437 [(set (match_operand:SWI48 0 "register_operand" "=r")
12438 (ior:SWI48
12439 (plus:SWI48
12440 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12441 (const_int -1))
12442 (match_dup 1)))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "TARGET_TBM"
12445 "blsfill\t{%1, %0|%0, %1}"
12446 [(set_attr "type" "bitmanip")
12447 (set_attr "mode" "<MODE>")])
12448
12449 (define_insn "*tbm_blsic_<mode>"
12450 [(set (match_operand:SWI48 0 "register_operand" "=r")
12451 (ior:SWI48
12452 (plus:SWI48
12453 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12454 (const_int -1))
12455 (not:SWI48
12456 (match_dup 1))))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "TARGET_TBM"
12459 "blsic\t{%1, %0|%0, %1}"
12460 [(set_attr "type" "bitmanip")
12461 (set_attr "mode" "<MODE>")])
12462
12463 (define_insn "*tbm_t1mskc_<mode>"
12464 [(set (match_operand:SWI48 0 "register_operand" "=r")
12465 (ior:SWI48
12466 (plus:SWI48
12467 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12468 (const_int 1))
12469 (not:SWI48
12470 (match_dup 1))))
12471 (clobber (reg:CC FLAGS_REG))]
12472 "TARGET_TBM"
12473 "t1mskc\t{%1, %0|%0, %1}"
12474 [(set_attr "type" "bitmanip")
12475 (set_attr "mode" "<MODE>")])
12476
12477 (define_insn "*tbm_tzmsk_<mode>"
12478 [(set (match_operand:SWI48 0 "register_operand" "=r")
12479 (and:SWI48
12480 (plus:SWI48
12481 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12482 (const_int -1))
12483 (not:SWI48
12484 (match_dup 1))))
12485 (clobber (reg:CC FLAGS_REG))]
12486 "TARGET_TBM"
12487 "tzmsk\t{%1, %0|%0, %1}"
12488 [(set_attr "type" "bitmanip")
12489 (set_attr "mode" "<MODE>")])
12490
12491 (define_insn "bsr_rex64"
12492 [(set (match_operand:DI 0 "register_operand" "=r")
12493 (minus:DI (const_int 63)
12494 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "TARGET_64BIT"
12497 "bsr{q}\t{%1, %0|%0, %1}"
12498 [(set_attr "type" "alu1")
12499 (set_attr "prefix_0f" "1")
12500 (set_attr "mode" "DI")])
12501
12502 (define_insn "bsr"
12503 [(set (match_operand:SI 0 "register_operand" "=r")
12504 (minus:SI (const_int 31)
12505 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12506 (clobber (reg:CC FLAGS_REG))]
12507 ""
12508 "bsr{l}\t{%1, %0|%0, %1}"
12509 [(set_attr "type" "alu1")
12510 (set_attr "prefix_0f" "1")
12511 (set_attr "mode" "SI")])
12512
12513 (define_insn "*bsrhi"
12514 [(set (match_operand:HI 0 "register_operand" "=r")
12515 (minus:HI (const_int 15)
12516 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12517 (clobber (reg:CC FLAGS_REG))]
12518 ""
12519 "bsr{w}\t{%1, %0|%0, %1}"
12520 [(set_attr "type" "alu1")
12521 (set_attr "prefix_0f" "1")
12522 (set_attr "mode" "HI")])
12523
12524 (define_insn "popcount<mode>2"
12525 [(set (match_operand:SWI248 0 "register_operand" "=r")
12526 (popcount:SWI248
12527 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12528 (clobber (reg:CC FLAGS_REG))]
12529 "TARGET_POPCNT"
12530 {
12531 #if TARGET_MACHO
12532 return "popcnt\t{%1, %0|%0, %1}";
12533 #else
12534 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12535 #endif
12536 }
12537 [(set_attr "prefix_rep" "1")
12538 (set_attr "type" "bitmanip")
12539 (set_attr "mode" "<MODE>")])
12540
12541 (define_insn "*popcount<mode>2_cmp"
12542 [(set (reg FLAGS_REG)
12543 (compare
12544 (popcount:SWI248
12545 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12546 (const_int 0)))
12547 (set (match_operand:SWI248 0 "register_operand" "=r")
12548 (popcount:SWI248 (match_dup 1)))]
12549 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12550 {
12551 #if TARGET_MACHO
12552 return "popcnt\t{%1, %0|%0, %1}";
12553 #else
12554 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12555 #endif
12556 }
12557 [(set_attr "prefix_rep" "1")
12558 (set_attr "type" "bitmanip")
12559 (set_attr "mode" "<MODE>")])
12560
12561 (define_insn "*popcountsi2_cmp_zext"
12562 [(set (reg FLAGS_REG)
12563 (compare
12564 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12565 (const_int 0)))
12566 (set (match_operand:DI 0 "register_operand" "=r")
12567 (zero_extend:DI(popcount:SI (match_dup 1))))]
12568 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12569 {
12570 #if TARGET_MACHO
12571 return "popcnt\t{%1, %0|%0, %1}";
12572 #else
12573 return "popcnt{l}\t{%1, %0|%0, %1}";
12574 #endif
12575 }
12576 [(set_attr "prefix_rep" "1")
12577 (set_attr "type" "bitmanip")
12578 (set_attr "mode" "SI")])
12579
12580 (define_expand "bswapdi2"
12581 [(set (match_operand:DI 0 "register_operand")
12582 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12583 "TARGET_64BIT"
12584 {
12585 if (!TARGET_MOVBE)
12586 operands[1] = force_reg (DImode, operands[1]);
12587 })
12588
12589 (define_expand "bswapsi2"
12590 [(set (match_operand:SI 0 "register_operand")
12591 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12592 ""
12593 {
12594 if (TARGET_MOVBE)
12595 ;
12596 else if (TARGET_BSWAP)
12597 operands[1] = force_reg (SImode, operands[1]);
12598 else
12599 {
12600 rtx x = operands[0];
12601
12602 emit_move_insn (x, operands[1]);
12603 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12604 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12605 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12606 DONE;
12607 }
12608 })
12609
12610 (define_insn "*bswap<mode>2_movbe"
12611 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12612 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12613 "TARGET_MOVBE
12614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12615 "@
12616 bswap\t%0
12617 movbe\t{%1, %0|%0, %1}
12618 movbe\t{%1, %0|%0, %1}"
12619 [(set_attr "type" "bitmanip,imov,imov")
12620 (set_attr "modrm" "0,1,1")
12621 (set_attr "prefix_0f" "*,1,1")
12622 (set_attr "prefix_extra" "*,1,1")
12623 (set_attr "mode" "<MODE>")])
12624
12625 (define_insn "*bswap<mode>2"
12626 [(set (match_operand:SWI48 0 "register_operand" "=r")
12627 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12628 "TARGET_BSWAP"
12629 "bswap\t%0"
12630 [(set_attr "type" "bitmanip")
12631 (set_attr "modrm" "0")
12632 (set_attr "mode" "<MODE>")])
12633
12634 (define_insn "*bswaphi_lowpart_1"
12635 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12636 (bswap:HI (match_dup 0)))
12637 (clobber (reg:CC FLAGS_REG))]
12638 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12639 "@
12640 xchg{b}\t{%h0, %b0|%b0, %h0}
12641 rol{w}\t{$8, %0|%0, 8}"
12642 [(set_attr "length" "2,4")
12643 (set_attr "mode" "QI,HI")])
12644
12645 (define_insn "bswaphi_lowpart"
12646 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12647 (bswap:HI (match_dup 0)))
12648 (clobber (reg:CC FLAGS_REG))]
12649 ""
12650 "rol{w}\t{$8, %0|%0, 8}"
12651 [(set_attr "length" "4")
12652 (set_attr "mode" "HI")])
12653
12654 (define_expand "paritydi2"
12655 [(set (match_operand:DI 0 "register_operand")
12656 (parity:DI (match_operand:DI 1 "register_operand")))]
12657 "! TARGET_POPCNT"
12658 {
12659 rtx scratch = gen_reg_rtx (QImode);
12660 rtx cond;
12661
12662 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12663 NULL_RTX, operands[1]));
12664
12665 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12666 gen_rtx_REG (CCmode, FLAGS_REG),
12667 const0_rtx);
12668 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12669
12670 if (TARGET_64BIT)
12671 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12672 else
12673 {
12674 rtx tmp = gen_reg_rtx (SImode);
12675
12676 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12677 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12678 }
12679 DONE;
12680 })
12681
12682 (define_expand "paritysi2"
12683 [(set (match_operand:SI 0 "register_operand")
12684 (parity:SI (match_operand:SI 1 "register_operand")))]
12685 "! TARGET_POPCNT"
12686 {
12687 rtx scratch = gen_reg_rtx (QImode);
12688 rtx cond;
12689
12690 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12691
12692 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12693 gen_rtx_REG (CCmode, FLAGS_REG),
12694 const0_rtx);
12695 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12696
12697 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12698 DONE;
12699 })
12700
12701 (define_insn_and_split "paritydi2_cmp"
12702 [(set (reg:CC FLAGS_REG)
12703 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12704 UNSPEC_PARITY))
12705 (clobber (match_scratch:DI 0 "=r"))
12706 (clobber (match_scratch:SI 1 "=&r"))
12707 (clobber (match_scratch:HI 2 "=Q"))]
12708 "! TARGET_POPCNT"
12709 "#"
12710 "&& reload_completed"
12711 [(parallel
12712 [(set (match_dup 1)
12713 (xor:SI (match_dup 1) (match_dup 4)))
12714 (clobber (reg:CC FLAGS_REG))])
12715 (parallel
12716 [(set (reg:CC FLAGS_REG)
12717 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12718 (clobber (match_dup 1))
12719 (clobber (match_dup 2))])]
12720 {
12721 operands[4] = gen_lowpart (SImode, operands[3]);
12722
12723 if (TARGET_64BIT)
12724 {
12725 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12726 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12727 }
12728 else
12729 operands[1] = gen_highpart (SImode, operands[3]);
12730 })
12731
12732 (define_insn_and_split "paritysi2_cmp"
12733 [(set (reg:CC FLAGS_REG)
12734 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12735 UNSPEC_PARITY))
12736 (clobber (match_scratch:SI 0 "=r"))
12737 (clobber (match_scratch:HI 1 "=&Q"))]
12738 "! TARGET_POPCNT"
12739 "#"
12740 "&& reload_completed"
12741 [(parallel
12742 [(set (match_dup 1)
12743 (xor:HI (match_dup 1) (match_dup 3)))
12744 (clobber (reg:CC FLAGS_REG))])
12745 (parallel
12746 [(set (reg:CC FLAGS_REG)
12747 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12748 (clobber (match_dup 1))])]
12749 {
12750 operands[3] = gen_lowpart (HImode, operands[2]);
12751
12752 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12753 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12754 })
12755
12756 (define_insn "*parityhi2_cmp"
12757 [(set (reg:CC FLAGS_REG)
12758 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12759 UNSPEC_PARITY))
12760 (clobber (match_scratch:HI 0 "=Q"))]
12761 "! TARGET_POPCNT"
12762 "xor{b}\t{%h0, %b0|%b0, %h0}"
12763 [(set_attr "length" "2")
12764 (set_attr "mode" "HI")])
12765
12766 \f
12767 ;; Thread-local storage patterns for ELF.
12768 ;;
12769 ;; Note that these code sequences must appear exactly as shown
12770 ;; in order to allow linker relaxation.
12771
12772 (define_insn "*tls_global_dynamic_32_gnu"
12773 [(set (match_operand:SI 0 "register_operand" "=a")
12774 (unspec:SI
12775 [(match_operand:SI 1 "register_operand" "b")
12776 (match_operand 2 "tls_symbolic_operand")
12777 (match_operand 3 "constant_call_address_operand" "z")]
12778 UNSPEC_TLS_GD))
12779 (clobber (match_scratch:SI 4 "=d"))
12780 (clobber (match_scratch:SI 5 "=c"))
12781 (clobber (reg:CC FLAGS_REG))]
12782 "!TARGET_64BIT && TARGET_GNU_TLS"
12783 {
12784 output_asm_insn
12785 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12786 if (TARGET_SUN_TLS)
12787 #ifdef HAVE_AS_IX86_TLSGDPLT
12788 return "call\t%a2@tlsgdplt";
12789 #else
12790 return "call\t%p3@plt";
12791 #endif
12792 return "call\t%P3";
12793 }
12794 [(set_attr "type" "multi")
12795 (set_attr "length" "12")])
12796
12797 (define_expand "tls_global_dynamic_32"
12798 [(parallel
12799 [(set (match_operand:SI 0 "register_operand")
12800 (unspec:SI [(match_operand:SI 2 "register_operand")
12801 (match_operand 1 "tls_symbolic_operand")
12802 (match_operand 3 "constant_call_address_operand")]
12803 UNSPEC_TLS_GD))
12804 (clobber (match_scratch:SI 4))
12805 (clobber (match_scratch:SI 5))
12806 (clobber (reg:CC FLAGS_REG))])])
12807
12808 (define_insn "*tls_global_dynamic_64_<mode>"
12809 [(set (match_operand:P 0 "register_operand" "=a")
12810 (call:P
12811 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12812 (match_operand 3)))
12813 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12814 UNSPEC_TLS_GD)]
12815 "TARGET_64BIT"
12816 {
12817 if (!TARGET_X32)
12818 fputs (ASM_BYTE "0x66\n", asm_out_file);
12819 output_asm_insn
12820 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12821 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12822 fputs ("\trex64\n", asm_out_file);
12823 if (TARGET_SUN_TLS)
12824 return "call\t%p2@plt";
12825 return "call\t%P2";
12826 }
12827 [(set_attr "type" "multi")
12828 (set (attr "length")
12829 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12830
12831 (define_insn "*tls_global_dynamic_64_largepic"
12832 [(set (match_operand:DI 0 "register_operand" "=a")
12833 (call:DI
12834 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12835 (match_operand:DI 3 "immediate_operand" "i")))
12836 (match_operand 4)))
12837 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12838 UNSPEC_TLS_GD)]
12839 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12840 && GET_CODE (operands[3]) == CONST
12841 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12842 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12843 {
12844 output_asm_insn
12845 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12846 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12847 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12848 return "call\t{*%%rax|rax}";
12849 }
12850 [(set_attr "type" "multi")
12851 (set_attr "length" "22")])
12852
12853 (define_expand "tls_global_dynamic_64_<mode>"
12854 [(parallel
12855 [(set (match_operand:P 0 "register_operand")
12856 (call:P
12857 (mem:QI (match_operand 2))
12858 (const_int 0)))
12859 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12860 UNSPEC_TLS_GD)])]
12861 "TARGET_64BIT")
12862
12863 (define_insn "*tls_local_dynamic_base_32_gnu"
12864 [(set (match_operand:SI 0 "register_operand" "=a")
12865 (unspec:SI
12866 [(match_operand:SI 1 "register_operand" "b")
12867 (match_operand 2 "constant_call_address_operand" "z")]
12868 UNSPEC_TLS_LD_BASE))
12869 (clobber (match_scratch:SI 3 "=d"))
12870 (clobber (match_scratch:SI 4 "=c"))
12871 (clobber (reg:CC FLAGS_REG))]
12872 "!TARGET_64BIT && TARGET_GNU_TLS"
12873 {
12874 output_asm_insn
12875 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12876 if (TARGET_SUN_TLS)
12877 #ifdef HAVE_AS_IX86_TLSLDMPLT
12878 return "call\t%&@tlsldmplt";
12879 #else
12880 return "call\t%p2@plt";
12881 #endif
12882 return "call\t%P2";
12883 }
12884 [(set_attr "type" "multi")
12885 (set_attr "length" "11")])
12886
12887 (define_expand "tls_local_dynamic_base_32"
12888 [(parallel
12889 [(set (match_operand:SI 0 "register_operand")
12890 (unspec:SI
12891 [(match_operand:SI 1 "register_operand")
12892 (match_operand 2 "constant_call_address_operand")]
12893 UNSPEC_TLS_LD_BASE))
12894 (clobber (match_scratch:SI 3))
12895 (clobber (match_scratch:SI 4))
12896 (clobber (reg:CC FLAGS_REG))])])
12897
12898 (define_insn "*tls_local_dynamic_base_64_<mode>"
12899 [(set (match_operand:P 0 "register_operand" "=a")
12900 (call:P
12901 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12902 (match_operand 2)))
12903 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12904 "TARGET_64BIT"
12905 {
12906 output_asm_insn
12907 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12908 if (TARGET_SUN_TLS)
12909 return "call\t%p1@plt";
12910 return "call\t%P1";
12911 }
12912 [(set_attr "type" "multi")
12913 (set_attr "length" "12")])
12914
12915 (define_insn "*tls_local_dynamic_base_64_largepic"
12916 [(set (match_operand:DI 0 "register_operand" "=a")
12917 (call:DI
12918 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12919 (match_operand:DI 2 "immediate_operand" "i")))
12920 (match_operand 3)))
12921 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12922 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12923 && GET_CODE (operands[2]) == CONST
12924 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12925 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12926 {
12927 output_asm_insn
12928 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12929 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12930 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12931 return "call\t{*%%rax|rax}";
12932 }
12933 [(set_attr "type" "multi")
12934 (set_attr "length" "22")])
12935
12936 (define_expand "tls_local_dynamic_base_64_<mode>"
12937 [(parallel
12938 [(set (match_operand:P 0 "register_operand")
12939 (call:P
12940 (mem:QI (match_operand 1))
12941 (const_int 0)))
12942 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12943 "TARGET_64BIT")
12944
12945 ;; Local dynamic of a single variable is a lose. Show combine how
12946 ;; to convert that back to global dynamic.
12947
12948 (define_insn_and_split "*tls_local_dynamic_32_once"
12949 [(set (match_operand:SI 0 "register_operand" "=a")
12950 (plus:SI
12951 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12952 (match_operand 2 "constant_call_address_operand" "z")]
12953 UNSPEC_TLS_LD_BASE)
12954 (const:SI (unspec:SI
12955 [(match_operand 3 "tls_symbolic_operand")]
12956 UNSPEC_DTPOFF))))
12957 (clobber (match_scratch:SI 4 "=d"))
12958 (clobber (match_scratch:SI 5 "=c"))
12959 (clobber (reg:CC FLAGS_REG))]
12960 ""
12961 "#"
12962 ""
12963 [(parallel
12964 [(set (match_dup 0)
12965 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12966 UNSPEC_TLS_GD))
12967 (clobber (match_dup 4))
12968 (clobber (match_dup 5))
12969 (clobber (reg:CC FLAGS_REG))])])
12970
12971 ;; Segment register for the thread base ptr load
12972 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12973
12974 ;; Load and add the thread base pointer from %<tp_seg>:0.
12975 (define_insn "*load_tp_x32"
12976 [(set (match_operand:SI 0 "register_operand" "=r")
12977 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12978 "TARGET_X32"
12979 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12980 [(set_attr "type" "imov")
12981 (set_attr "modrm" "0")
12982 (set_attr "length" "7")
12983 (set_attr "memory" "load")
12984 (set_attr "imm_disp" "false")])
12985
12986 (define_insn "*load_tp_x32_zext"
12987 [(set (match_operand:DI 0 "register_operand" "=r")
12988 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12989 "TARGET_X32"
12990 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12991 [(set_attr "type" "imov")
12992 (set_attr "modrm" "0")
12993 (set_attr "length" "7")
12994 (set_attr "memory" "load")
12995 (set_attr "imm_disp" "false")])
12996
12997 (define_insn "*load_tp_<mode>"
12998 [(set (match_operand:P 0 "register_operand" "=r")
12999 (unspec:P [(const_int 0)] UNSPEC_TP))]
13000 "!TARGET_X32"
13001 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13002 [(set_attr "type" "imov")
13003 (set_attr "modrm" "0")
13004 (set_attr "length" "7")
13005 (set_attr "memory" "load")
13006 (set_attr "imm_disp" "false")])
13007
13008 (define_insn "*add_tp_x32"
13009 [(set (match_operand:SI 0 "register_operand" "=r")
13010 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13011 (match_operand:SI 1 "register_operand" "0")))
13012 (clobber (reg:CC FLAGS_REG))]
13013 "TARGET_X32"
13014 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13015 [(set_attr "type" "alu")
13016 (set_attr "modrm" "0")
13017 (set_attr "length" "7")
13018 (set_attr "memory" "load")
13019 (set_attr "imm_disp" "false")])
13020
13021 (define_insn "*add_tp_x32_zext"
13022 [(set (match_operand:DI 0 "register_operand" "=r")
13023 (zero_extend:DI
13024 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13025 (match_operand:SI 1 "register_operand" "0"))))
13026 (clobber (reg:CC FLAGS_REG))]
13027 "TARGET_X32"
13028 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13029 [(set_attr "type" "alu")
13030 (set_attr "modrm" "0")
13031 (set_attr "length" "7")
13032 (set_attr "memory" "load")
13033 (set_attr "imm_disp" "false")])
13034
13035 (define_insn "*add_tp_<mode>"
13036 [(set (match_operand:P 0 "register_operand" "=r")
13037 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13038 (match_operand:P 1 "register_operand" "0")))
13039 (clobber (reg:CC FLAGS_REG))]
13040 "!TARGET_X32"
13041 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13042 [(set_attr "type" "alu")
13043 (set_attr "modrm" "0")
13044 (set_attr "length" "7")
13045 (set_attr "memory" "load")
13046 (set_attr "imm_disp" "false")])
13047
13048 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13049 ;; %rax as destination of the initial executable code sequence.
13050 (define_insn "tls_initial_exec_64_sun"
13051 [(set (match_operand:DI 0 "register_operand" "=a")
13052 (unspec:DI
13053 [(match_operand 1 "tls_symbolic_operand")]
13054 UNSPEC_TLS_IE_SUN))
13055 (clobber (reg:CC FLAGS_REG))]
13056 "TARGET_64BIT && TARGET_SUN_TLS"
13057 {
13058 output_asm_insn
13059 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13060 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13061 }
13062 [(set_attr "type" "multi")])
13063
13064 ;; GNU2 TLS patterns can be split.
13065
13066 (define_expand "tls_dynamic_gnu2_32"
13067 [(set (match_dup 3)
13068 (plus:SI (match_operand:SI 2 "register_operand")
13069 (const:SI
13070 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13071 UNSPEC_TLSDESC))))
13072 (parallel
13073 [(set (match_operand:SI 0 "register_operand")
13074 (unspec:SI [(match_dup 1) (match_dup 3)
13075 (match_dup 2) (reg:SI SP_REG)]
13076 UNSPEC_TLSDESC))
13077 (clobber (reg:CC FLAGS_REG))])]
13078 "!TARGET_64BIT && TARGET_GNU2_TLS"
13079 {
13080 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13081 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13082 })
13083
13084 (define_insn "*tls_dynamic_gnu2_lea_32"
13085 [(set (match_operand:SI 0 "register_operand" "=r")
13086 (plus:SI (match_operand:SI 1 "register_operand" "b")
13087 (const:SI
13088 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13089 UNSPEC_TLSDESC))))]
13090 "!TARGET_64BIT && TARGET_GNU2_TLS"
13091 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13092 [(set_attr "type" "lea")
13093 (set_attr "mode" "SI")
13094 (set_attr "length" "6")
13095 (set_attr "length_address" "4")])
13096
13097 (define_insn "*tls_dynamic_gnu2_call_32"
13098 [(set (match_operand:SI 0 "register_operand" "=a")
13099 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13100 (match_operand:SI 2 "register_operand" "0")
13101 ;; we have to make sure %ebx still points to the GOT
13102 (match_operand:SI 3 "register_operand" "b")
13103 (reg:SI SP_REG)]
13104 UNSPEC_TLSDESC))
13105 (clobber (reg:CC FLAGS_REG))]
13106 "!TARGET_64BIT && TARGET_GNU2_TLS"
13107 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13108 [(set_attr "type" "call")
13109 (set_attr "length" "2")
13110 (set_attr "length_address" "0")])
13111
13112 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13113 [(set (match_operand:SI 0 "register_operand" "=&a")
13114 (plus:SI
13115 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13116 (match_operand:SI 4)
13117 (match_operand:SI 2 "register_operand" "b")
13118 (reg:SI SP_REG)]
13119 UNSPEC_TLSDESC)
13120 (const:SI (unspec:SI
13121 [(match_operand 1 "tls_symbolic_operand")]
13122 UNSPEC_DTPOFF))))
13123 (clobber (reg:CC FLAGS_REG))]
13124 "!TARGET_64BIT && TARGET_GNU2_TLS"
13125 "#"
13126 ""
13127 [(set (match_dup 0) (match_dup 5))]
13128 {
13129 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13130 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13131 })
13132
13133 (define_expand "tls_dynamic_gnu2_64"
13134 [(set (match_dup 2)
13135 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13136 UNSPEC_TLSDESC))
13137 (parallel
13138 [(set (match_operand:DI 0 "register_operand")
13139 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13140 UNSPEC_TLSDESC))
13141 (clobber (reg:CC FLAGS_REG))])]
13142 "TARGET_64BIT && TARGET_GNU2_TLS"
13143 {
13144 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13145 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13146 })
13147
13148 (define_insn "*tls_dynamic_gnu2_lea_64"
13149 [(set (match_operand:DI 0 "register_operand" "=r")
13150 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13151 UNSPEC_TLSDESC))]
13152 "TARGET_64BIT && TARGET_GNU2_TLS"
13153 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13154 [(set_attr "type" "lea")
13155 (set_attr "mode" "DI")
13156 (set_attr "length" "7")
13157 (set_attr "length_address" "4")])
13158
13159 (define_insn "*tls_dynamic_gnu2_call_64"
13160 [(set (match_operand:DI 0 "register_operand" "=a")
13161 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13162 (match_operand:DI 2 "register_operand" "0")
13163 (reg:DI SP_REG)]
13164 UNSPEC_TLSDESC))
13165 (clobber (reg:CC FLAGS_REG))]
13166 "TARGET_64BIT && TARGET_GNU2_TLS"
13167 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13168 [(set_attr "type" "call")
13169 (set_attr "length" "2")
13170 (set_attr "length_address" "0")])
13171
13172 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13173 [(set (match_operand:DI 0 "register_operand" "=&a")
13174 (plus:DI
13175 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13176 (match_operand:DI 3)
13177 (reg:DI SP_REG)]
13178 UNSPEC_TLSDESC)
13179 (const:DI (unspec:DI
13180 [(match_operand 1 "tls_symbolic_operand")]
13181 UNSPEC_DTPOFF))))
13182 (clobber (reg:CC FLAGS_REG))]
13183 "TARGET_64BIT && TARGET_GNU2_TLS"
13184 "#"
13185 ""
13186 [(set (match_dup 0) (match_dup 4))]
13187 {
13188 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13189 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13190 })
13191 \f
13192 ;; These patterns match the binary 387 instructions for addM3, subM3,
13193 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13194 ;; SFmode. The first is the normal insn, the second the same insn but
13195 ;; with one operand a conversion, and the third the same insn but with
13196 ;; the other operand a conversion. The conversion may be SFmode or
13197 ;; SImode if the target mode DFmode, but only SImode if the target mode
13198 ;; is SFmode.
13199
13200 ;; Gcc is slightly more smart about handling normal two address instructions
13201 ;; so use special patterns for add and mull.
13202
13203 (define_insn "*fop_<mode>_comm_mixed"
13204 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13205 (match_operator:MODEF 3 "binary_fp_operator"
13206 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13207 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13208 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13209 && COMMUTATIVE_ARITH_P (operands[3])
13210 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13211 "* return output_387_binary_op (insn, operands);"
13212 [(set (attr "type")
13213 (if_then_else (eq_attr "alternative" "1,2")
13214 (if_then_else (match_operand:MODEF 3 "mult_operator")
13215 (const_string "ssemul")
13216 (const_string "sseadd"))
13217 (if_then_else (match_operand:MODEF 3 "mult_operator")
13218 (const_string "fmul")
13219 (const_string "fop"))))
13220 (set_attr "isa" "*,noavx,avx")
13221 (set_attr "prefix" "orig,orig,vex")
13222 (set_attr "mode" "<MODE>")])
13223
13224 (define_insn "*fop_<mode>_comm_sse"
13225 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13226 (match_operator:MODEF 3 "binary_fp_operator"
13227 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13228 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13229 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13230 && COMMUTATIVE_ARITH_P (operands[3])
13231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13232 "* return output_387_binary_op (insn, operands);"
13233 [(set (attr "type")
13234 (if_then_else (match_operand:MODEF 3 "mult_operator")
13235 (const_string "ssemul")
13236 (const_string "sseadd")))
13237 (set_attr "isa" "noavx,avx")
13238 (set_attr "prefix" "orig,vex")
13239 (set_attr "mode" "<MODE>")])
13240
13241 (define_insn "*fop_<mode>_comm_i387"
13242 [(set (match_operand:MODEF 0 "register_operand" "=f")
13243 (match_operator:MODEF 3 "binary_fp_operator"
13244 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13245 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13246 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13247 && COMMUTATIVE_ARITH_P (operands[3])
13248 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13249 "* return output_387_binary_op (insn, operands);"
13250 [(set (attr "type")
13251 (if_then_else (match_operand:MODEF 3 "mult_operator")
13252 (const_string "fmul")
13253 (const_string "fop")))
13254 (set_attr "mode" "<MODE>")])
13255
13256 (define_insn "*fop_<mode>_1_mixed"
13257 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13258 (match_operator:MODEF 3 "binary_fp_operator"
13259 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13260 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13261 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13262 && !COMMUTATIVE_ARITH_P (operands[3])
13263 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13264 "* return output_387_binary_op (insn, operands);"
13265 [(set (attr "type")
13266 (cond [(and (eq_attr "alternative" "2,3")
13267 (match_operand:MODEF 3 "mult_operator"))
13268 (const_string "ssemul")
13269 (and (eq_attr "alternative" "2,3")
13270 (match_operand:MODEF 3 "div_operator"))
13271 (const_string "ssediv")
13272 (eq_attr "alternative" "2,3")
13273 (const_string "sseadd")
13274 (match_operand:MODEF 3 "mult_operator")
13275 (const_string "fmul")
13276 (match_operand:MODEF 3 "div_operator")
13277 (const_string "fdiv")
13278 ]
13279 (const_string "fop")))
13280 (set_attr "isa" "*,*,noavx,avx")
13281 (set_attr "prefix" "orig,orig,orig,vex")
13282 (set_attr "mode" "<MODE>")])
13283
13284 (define_insn "*rcpsf2_sse"
13285 [(set (match_operand:SF 0 "register_operand" "=x")
13286 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13287 UNSPEC_RCP))]
13288 "TARGET_SSE_MATH"
13289 "%vrcpss\t{%1, %d0|%d0, %1}"
13290 [(set_attr "type" "sse")
13291 (set_attr "atom_sse_attr" "rcp")
13292 (set_attr "btver2_sse_attr" "rcp")
13293 (set_attr "prefix" "maybe_vex")
13294 (set_attr "mode" "SF")])
13295
13296 (define_insn "*fop_<mode>_1_sse"
13297 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13298 (match_operator:MODEF 3 "binary_fp_operator"
13299 [(match_operand:MODEF 1 "register_operand" "0,x")
13300 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13301 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13302 && !COMMUTATIVE_ARITH_P (operands[3])"
13303 "* return output_387_binary_op (insn, operands);"
13304 [(set (attr "type")
13305 (cond [(match_operand:MODEF 3 "mult_operator")
13306 (const_string "ssemul")
13307 (match_operand:MODEF 3 "div_operator")
13308 (const_string "ssediv")
13309 ]
13310 (const_string "sseadd")))
13311 (set_attr "isa" "noavx,avx")
13312 (set_attr "prefix" "orig,vex")
13313 (set_attr "mode" "<MODE>")])
13314
13315 ;; This pattern is not fully shadowed by the pattern above.
13316 (define_insn "*fop_<mode>_1_i387"
13317 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13318 (match_operator:MODEF 3 "binary_fp_operator"
13319 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13320 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13321 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13322 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13323 && !COMMUTATIVE_ARITH_P (operands[3])
13324 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13325 "* return output_387_binary_op (insn, operands);"
13326 [(set (attr "type")
13327 (cond [(match_operand:MODEF 3 "mult_operator")
13328 (const_string "fmul")
13329 (match_operand:MODEF 3 "div_operator")
13330 (const_string "fdiv")
13331 ]
13332 (const_string "fop")))
13333 (set_attr "mode" "<MODE>")])
13334
13335 ;; ??? Add SSE splitters for these!
13336 (define_insn "*fop_<MODEF:mode>_2_i387"
13337 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13338 (match_operator:MODEF 3 "binary_fp_operator"
13339 [(float:MODEF
13340 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13341 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13342 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13343 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13344 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13345 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13346 [(set (attr "type")
13347 (cond [(match_operand:MODEF 3 "mult_operator")
13348 (const_string "fmul")
13349 (match_operand:MODEF 3 "div_operator")
13350 (const_string "fdiv")
13351 ]
13352 (const_string "fop")))
13353 (set_attr "fp_int_src" "true")
13354 (set_attr "mode" "<SWI24:MODE>")])
13355
13356 (define_insn "*fop_<MODEF:mode>_3_i387"
13357 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13358 (match_operator:MODEF 3 "binary_fp_operator"
13359 [(match_operand:MODEF 1 "register_operand" "0,0")
13360 (float:MODEF
13361 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13362 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13363 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13364 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13365 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13366 [(set (attr "type")
13367 (cond [(match_operand:MODEF 3 "mult_operator")
13368 (const_string "fmul")
13369 (match_operand:MODEF 3 "div_operator")
13370 (const_string "fdiv")
13371 ]
13372 (const_string "fop")))
13373 (set_attr "fp_int_src" "true")
13374 (set_attr "mode" "<MODE>")])
13375
13376 (define_insn "*fop_df_4_i387"
13377 [(set (match_operand:DF 0 "register_operand" "=f,f")
13378 (match_operator:DF 3 "binary_fp_operator"
13379 [(float_extend:DF
13380 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13381 (match_operand:DF 2 "register_operand" "0,f")]))]
13382 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13383 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13384 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13385 "* return output_387_binary_op (insn, operands);"
13386 [(set (attr "type")
13387 (cond [(match_operand:DF 3 "mult_operator")
13388 (const_string "fmul")
13389 (match_operand:DF 3 "div_operator")
13390 (const_string "fdiv")
13391 ]
13392 (const_string "fop")))
13393 (set_attr "mode" "SF")])
13394
13395 (define_insn "*fop_df_5_i387"
13396 [(set (match_operand:DF 0 "register_operand" "=f,f")
13397 (match_operator:DF 3 "binary_fp_operator"
13398 [(match_operand:DF 1 "register_operand" "0,f")
13399 (float_extend:DF
13400 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13401 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13402 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13403 "* return output_387_binary_op (insn, operands);"
13404 [(set (attr "type")
13405 (cond [(match_operand:DF 3 "mult_operator")
13406 (const_string "fmul")
13407 (match_operand:DF 3 "div_operator")
13408 (const_string "fdiv")
13409 ]
13410 (const_string "fop")))
13411 (set_attr "mode" "SF")])
13412
13413 (define_insn "*fop_df_6_i387"
13414 [(set (match_operand:DF 0 "register_operand" "=f,f")
13415 (match_operator:DF 3 "binary_fp_operator"
13416 [(float_extend:DF
13417 (match_operand:SF 1 "register_operand" "0,f"))
13418 (float_extend:DF
13419 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13420 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13421 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13422 "* return output_387_binary_op (insn, operands);"
13423 [(set (attr "type")
13424 (cond [(match_operand:DF 3 "mult_operator")
13425 (const_string "fmul")
13426 (match_operand:DF 3 "div_operator")
13427 (const_string "fdiv")
13428 ]
13429 (const_string "fop")))
13430 (set_attr "mode" "SF")])
13431
13432 (define_insn "*fop_xf_comm_i387"
13433 [(set (match_operand:XF 0 "register_operand" "=f")
13434 (match_operator:XF 3 "binary_fp_operator"
13435 [(match_operand:XF 1 "register_operand" "%0")
13436 (match_operand:XF 2 "register_operand" "f")]))]
13437 "TARGET_80387
13438 && COMMUTATIVE_ARITH_P (operands[3])"
13439 "* return output_387_binary_op (insn, operands);"
13440 [(set (attr "type")
13441 (if_then_else (match_operand:XF 3 "mult_operator")
13442 (const_string "fmul")
13443 (const_string "fop")))
13444 (set_attr "mode" "XF")])
13445
13446 (define_insn "*fop_xf_1_i387"
13447 [(set (match_operand:XF 0 "register_operand" "=f,f")
13448 (match_operator:XF 3 "binary_fp_operator"
13449 [(match_operand:XF 1 "register_operand" "0,f")
13450 (match_operand:XF 2 "register_operand" "f,0")]))]
13451 "TARGET_80387
13452 && !COMMUTATIVE_ARITH_P (operands[3])"
13453 "* return output_387_binary_op (insn, operands);"
13454 [(set (attr "type")
13455 (cond [(match_operand:XF 3 "mult_operator")
13456 (const_string "fmul")
13457 (match_operand:XF 3 "div_operator")
13458 (const_string "fdiv")
13459 ]
13460 (const_string "fop")))
13461 (set_attr "mode" "XF")])
13462
13463 (define_insn "*fop_xf_2_i387"
13464 [(set (match_operand:XF 0 "register_operand" "=f,f")
13465 (match_operator:XF 3 "binary_fp_operator"
13466 [(float:XF
13467 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13468 (match_operand:XF 2 "register_operand" "0,0")]))]
13469 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13470 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13471 [(set (attr "type")
13472 (cond [(match_operand:XF 3 "mult_operator")
13473 (const_string "fmul")
13474 (match_operand:XF 3 "div_operator")
13475 (const_string "fdiv")
13476 ]
13477 (const_string "fop")))
13478 (set_attr "fp_int_src" "true")
13479 (set_attr "mode" "<MODE>")])
13480
13481 (define_insn "*fop_xf_3_i387"
13482 [(set (match_operand:XF 0 "register_operand" "=f,f")
13483 (match_operator:XF 3 "binary_fp_operator"
13484 [(match_operand:XF 1 "register_operand" "0,0")
13485 (float:XF
13486 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13487 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13488 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13489 [(set (attr "type")
13490 (cond [(match_operand:XF 3 "mult_operator")
13491 (const_string "fmul")
13492 (match_operand:XF 3 "div_operator")
13493 (const_string "fdiv")
13494 ]
13495 (const_string "fop")))
13496 (set_attr "fp_int_src" "true")
13497 (set_attr "mode" "<MODE>")])
13498
13499 (define_insn "*fop_xf_4_i387"
13500 [(set (match_operand:XF 0 "register_operand" "=f,f")
13501 (match_operator:XF 3 "binary_fp_operator"
13502 [(float_extend:XF
13503 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13504 (match_operand:XF 2 "register_operand" "0,f")]))]
13505 "TARGET_80387"
13506 "* return output_387_binary_op (insn, operands);"
13507 [(set (attr "type")
13508 (cond [(match_operand:XF 3 "mult_operator")
13509 (const_string "fmul")
13510 (match_operand:XF 3 "div_operator")
13511 (const_string "fdiv")
13512 ]
13513 (const_string "fop")))
13514 (set_attr "mode" "<MODE>")])
13515
13516 (define_insn "*fop_xf_5_i387"
13517 [(set (match_operand:XF 0 "register_operand" "=f,f")
13518 (match_operator:XF 3 "binary_fp_operator"
13519 [(match_operand:XF 1 "register_operand" "0,f")
13520 (float_extend:XF
13521 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13522 "TARGET_80387"
13523 "* return output_387_binary_op (insn, operands);"
13524 [(set (attr "type")
13525 (cond [(match_operand:XF 3 "mult_operator")
13526 (const_string "fmul")
13527 (match_operand:XF 3 "div_operator")
13528 (const_string "fdiv")
13529 ]
13530 (const_string "fop")))
13531 (set_attr "mode" "<MODE>")])
13532
13533 (define_insn "*fop_xf_6_i387"
13534 [(set (match_operand:XF 0 "register_operand" "=f,f")
13535 (match_operator:XF 3 "binary_fp_operator"
13536 [(float_extend:XF
13537 (match_operand:MODEF 1 "register_operand" "0,f"))
13538 (float_extend:XF
13539 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13540 "TARGET_80387"
13541 "* return output_387_binary_op (insn, operands);"
13542 [(set (attr "type")
13543 (cond [(match_operand:XF 3 "mult_operator")
13544 (const_string "fmul")
13545 (match_operand:XF 3 "div_operator")
13546 (const_string "fdiv")
13547 ]
13548 (const_string "fop")))
13549 (set_attr "mode" "<MODE>")])
13550
13551 (define_split
13552 [(set (match_operand 0 "register_operand")
13553 (match_operator 3 "binary_fp_operator"
13554 [(float (match_operand:SWI24 1 "register_operand"))
13555 (match_operand 2 "register_operand")]))]
13556 "reload_completed
13557 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13558 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13559 [(const_int 0)]
13560 {
13561 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13562 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13563 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13564 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13565 GET_MODE (operands[3]),
13566 operands[4],
13567 operands[2])));
13568 ix86_free_from_memory (GET_MODE (operands[1]));
13569 DONE;
13570 })
13571
13572 (define_split
13573 [(set (match_operand 0 "register_operand")
13574 (match_operator 3 "binary_fp_operator"
13575 [(match_operand 1 "register_operand")
13576 (float (match_operand:SWI24 2 "register_operand"))]))]
13577 "reload_completed
13578 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13579 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13580 [(const_int 0)]
13581 {
13582 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13583 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13584 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13585 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13586 GET_MODE (operands[3]),
13587 operands[1],
13588 operands[4])));
13589 ix86_free_from_memory (GET_MODE (operands[2]));
13590 DONE;
13591 })
13592 \f
13593 ;; FPU special functions.
13594
13595 ;; This pattern implements a no-op XFmode truncation for
13596 ;; all fancy i386 XFmode math functions.
13597
13598 (define_insn "truncxf<mode>2_i387_noop_unspec"
13599 [(set (match_operand:MODEF 0 "register_operand" "=f")
13600 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13601 UNSPEC_TRUNC_NOOP))]
13602 "TARGET_USE_FANCY_MATH_387"
13603 "* return output_387_reg_move (insn, operands);"
13604 [(set_attr "type" "fmov")
13605 (set_attr "mode" "<MODE>")])
13606
13607 (define_insn "sqrtxf2"
13608 [(set (match_operand:XF 0 "register_operand" "=f")
13609 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13610 "TARGET_USE_FANCY_MATH_387"
13611 "fsqrt"
13612 [(set_attr "type" "fpspc")
13613 (set_attr "mode" "XF")
13614 (set_attr "athlon_decode" "direct")
13615 (set_attr "amdfam10_decode" "direct")
13616 (set_attr "bdver1_decode" "direct")])
13617
13618 (define_insn "sqrt_extend<mode>xf2_i387"
13619 [(set (match_operand:XF 0 "register_operand" "=f")
13620 (sqrt:XF
13621 (float_extend:XF
13622 (match_operand:MODEF 1 "register_operand" "0"))))]
13623 "TARGET_USE_FANCY_MATH_387"
13624 "fsqrt"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")
13627 (set_attr "athlon_decode" "direct")
13628 (set_attr "amdfam10_decode" "direct")
13629 (set_attr "bdver1_decode" "direct")])
13630
13631 (define_insn "*rsqrtsf2_sse"
13632 [(set (match_operand:SF 0 "register_operand" "=x")
13633 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13634 UNSPEC_RSQRT))]
13635 "TARGET_SSE_MATH"
13636 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13637 [(set_attr "type" "sse")
13638 (set_attr "atom_sse_attr" "rcp")
13639 (set_attr "btver2_sse_attr" "rcp")
13640 (set_attr "prefix" "maybe_vex")
13641 (set_attr "mode" "SF")])
13642
13643 (define_expand "rsqrtsf2"
13644 [(set (match_operand:SF 0 "register_operand")
13645 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13646 UNSPEC_RSQRT))]
13647 "TARGET_SSE_MATH"
13648 {
13649 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13650 DONE;
13651 })
13652
13653 (define_insn "*sqrt<mode>2_sse"
13654 [(set (match_operand:MODEF 0 "register_operand" "=x")
13655 (sqrt:MODEF
13656 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13657 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13658 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13659 [(set_attr "type" "sse")
13660 (set_attr "atom_sse_attr" "sqrt")
13661 (set_attr "btver2_sse_attr" "sqrt")
13662 (set_attr "prefix" "maybe_vex")
13663 (set_attr "mode" "<MODE>")
13664 (set_attr "athlon_decode" "*")
13665 (set_attr "amdfam10_decode" "*")
13666 (set_attr "bdver1_decode" "*")])
13667
13668 (define_expand "sqrt<mode>2"
13669 [(set (match_operand:MODEF 0 "register_operand")
13670 (sqrt:MODEF
13671 (match_operand:MODEF 1 "nonimmediate_operand")))]
13672 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13673 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13674 {
13675 if (<MODE>mode == SFmode
13676 && TARGET_SSE_MATH
13677 && TARGET_RECIP_SQRT
13678 && !optimize_function_for_size_p (cfun)
13679 && flag_finite_math_only && !flag_trapping_math
13680 && flag_unsafe_math_optimizations)
13681 {
13682 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13683 DONE;
13684 }
13685
13686 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13687 {
13688 rtx op0 = gen_reg_rtx (XFmode);
13689 rtx op1 = force_reg (<MODE>mode, operands[1]);
13690
13691 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13692 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13693 DONE;
13694 }
13695 })
13696
13697 (define_insn "fpremxf4_i387"
13698 [(set (match_operand:XF 0 "register_operand" "=f")
13699 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13700 (match_operand:XF 3 "register_operand" "1")]
13701 UNSPEC_FPREM_F))
13702 (set (match_operand:XF 1 "register_operand" "=u")
13703 (unspec:XF [(match_dup 2) (match_dup 3)]
13704 UNSPEC_FPREM_U))
13705 (set (reg:CCFP FPSR_REG)
13706 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13707 UNSPEC_C2_FLAG))]
13708 "TARGET_USE_FANCY_MATH_387"
13709 "fprem"
13710 [(set_attr "type" "fpspc")
13711 (set_attr "mode" "XF")])
13712
13713 (define_expand "fmodxf3"
13714 [(use (match_operand:XF 0 "register_operand"))
13715 (use (match_operand:XF 1 "general_operand"))
13716 (use (match_operand:XF 2 "general_operand"))]
13717 "TARGET_USE_FANCY_MATH_387"
13718 {
13719 rtx label = gen_label_rtx ();
13720
13721 rtx op1 = gen_reg_rtx (XFmode);
13722 rtx op2 = gen_reg_rtx (XFmode);
13723
13724 emit_move_insn (op2, operands[2]);
13725 emit_move_insn (op1, operands[1]);
13726
13727 emit_label (label);
13728 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13729 ix86_emit_fp_unordered_jump (label);
13730 LABEL_NUSES (label) = 1;
13731
13732 emit_move_insn (operands[0], op1);
13733 DONE;
13734 })
13735
13736 (define_expand "fmod<mode>3"
13737 [(use (match_operand:MODEF 0 "register_operand"))
13738 (use (match_operand:MODEF 1 "general_operand"))
13739 (use (match_operand:MODEF 2 "general_operand"))]
13740 "TARGET_USE_FANCY_MATH_387"
13741 {
13742 rtx (*gen_truncxf) (rtx, rtx);
13743
13744 rtx label = gen_label_rtx ();
13745
13746 rtx op1 = gen_reg_rtx (XFmode);
13747 rtx op2 = gen_reg_rtx (XFmode);
13748
13749 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13750 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13751
13752 emit_label (label);
13753 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13754 ix86_emit_fp_unordered_jump (label);
13755 LABEL_NUSES (label) = 1;
13756
13757 /* Truncate the result properly for strict SSE math. */
13758 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13759 && !TARGET_MIX_SSE_I387)
13760 gen_truncxf = gen_truncxf<mode>2;
13761 else
13762 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13763
13764 emit_insn (gen_truncxf (operands[0], op1));
13765 DONE;
13766 })
13767
13768 (define_insn "fprem1xf4_i387"
13769 [(set (match_operand:XF 0 "register_operand" "=f")
13770 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13771 (match_operand:XF 3 "register_operand" "1")]
13772 UNSPEC_FPREM1_F))
13773 (set (match_operand:XF 1 "register_operand" "=u")
13774 (unspec:XF [(match_dup 2) (match_dup 3)]
13775 UNSPEC_FPREM1_U))
13776 (set (reg:CCFP FPSR_REG)
13777 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13778 UNSPEC_C2_FLAG))]
13779 "TARGET_USE_FANCY_MATH_387"
13780 "fprem1"
13781 [(set_attr "type" "fpspc")
13782 (set_attr "mode" "XF")])
13783
13784 (define_expand "remainderxf3"
13785 [(use (match_operand:XF 0 "register_operand"))
13786 (use (match_operand:XF 1 "general_operand"))
13787 (use (match_operand:XF 2 "general_operand"))]
13788 "TARGET_USE_FANCY_MATH_387"
13789 {
13790 rtx label = gen_label_rtx ();
13791
13792 rtx op1 = gen_reg_rtx (XFmode);
13793 rtx op2 = gen_reg_rtx (XFmode);
13794
13795 emit_move_insn (op2, operands[2]);
13796 emit_move_insn (op1, operands[1]);
13797
13798 emit_label (label);
13799 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13800 ix86_emit_fp_unordered_jump (label);
13801 LABEL_NUSES (label) = 1;
13802
13803 emit_move_insn (operands[0], op1);
13804 DONE;
13805 })
13806
13807 (define_expand "remainder<mode>3"
13808 [(use (match_operand:MODEF 0 "register_operand"))
13809 (use (match_operand:MODEF 1 "general_operand"))
13810 (use (match_operand:MODEF 2 "general_operand"))]
13811 "TARGET_USE_FANCY_MATH_387"
13812 {
13813 rtx (*gen_truncxf) (rtx, rtx);
13814
13815 rtx label = gen_label_rtx ();
13816
13817 rtx op1 = gen_reg_rtx (XFmode);
13818 rtx op2 = gen_reg_rtx (XFmode);
13819
13820 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13821 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13822
13823 emit_label (label);
13824
13825 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13826 ix86_emit_fp_unordered_jump (label);
13827 LABEL_NUSES (label) = 1;
13828
13829 /* Truncate the result properly for strict SSE math. */
13830 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13831 && !TARGET_MIX_SSE_I387)
13832 gen_truncxf = gen_truncxf<mode>2;
13833 else
13834 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13835
13836 emit_insn (gen_truncxf (operands[0], op1));
13837 DONE;
13838 })
13839
13840 (define_int_iterator SINCOS
13841 [UNSPEC_SIN
13842 UNSPEC_COS])
13843
13844 (define_int_attr sincos
13845 [(UNSPEC_SIN "sin")
13846 (UNSPEC_COS "cos")])
13847
13848 (define_insn "*<sincos>xf2_i387"
13849 [(set (match_operand:XF 0 "register_operand" "=f")
13850 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13851 SINCOS))]
13852 "TARGET_USE_FANCY_MATH_387
13853 && flag_unsafe_math_optimizations"
13854 "f<sincos>"
13855 [(set_attr "type" "fpspc")
13856 (set_attr "mode" "XF")])
13857
13858 (define_insn "*<sincos>_extend<mode>xf2_i387"
13859 [(set (match_operand:XF 0 "register_operand" "=f")
13860 (unspec:XF [(float_extend:XF
13861 (match_operand:MODEF 1 "register_operand" "0"))]
13862 SINCOS))]
13863 "TARGET_USE_FANCY_MATH_387
13864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13865 || TARGET_MIX_SSE_I387)
13866 && flag_unsafe_math_optimizations"
13867 "f<sincos>"
13868 [(set_attr "type" "fpspc")
13869 (set_attr "mode" "XF")])
13870
13871 ;; When sincos pattern is defined, sin and cos builtin functions will be
13872 ;; expanded to sincos pattern with one of its outputs left unused.
13873 ;; CSE pass will figure out if two sincos patterns can be combined,
13874 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13875 ;; depending on the unused output.
13876
13877 (define_insn "sincosxf3"
13878 [(set (match_operand:XF 0 "register_operand" "=f")
13879 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13880 UNSPEC_SINCOS_COS))
13881 (set (match_operand:XF 1 "register_operand" "=u")
13882 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13883 "TARGET_USE_FANCY_MATH_387
13884 && flag_unsafe_math_optimizations"
13885 "fsincos"
13886 [(set_attr "type" "fpspc")
13887 (set_attr "mode" "XF")])
13888
13889 (define_split
13890 [(set (match_operand:XF 0 "register_operand")
13891 (unspec:XF [(match_operand:XF 2 "register_operand")]
13892 UNSPEC_SINCOS_COS))
13893 (set (match_operand:XF 1 "register_operand")
13894 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13895 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13896 && can_create_pseudo_p ()"
13897 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13898
13899 (define_split
13900 [(set (match_operand:XF 0 "register_operand")
13901 (unspec:XF [(match_operand:XF 2 "register_operand")]
13902 UNSPEC_SINCOS_COS))
13903 (set (match_operand:XF 1 "register_operand")
13904 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13905 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13906 && can_create_pseudo_p ()"
13907 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13908
13909 (define_insn "sincos_extend<mode>xf3_i387"
13910 [(set (match_operand:XF 0 "register_operand" "=f")
13911 (unspec:XF [(float_extend:XF
13912 (match_operand:MODEF 2 "register_operand" "0"))]
13913 UNSPEC_SINCOS_COS))
13914 (set (match_operand:XF 1 "register_operand" "=u")
13915 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13916 "TARGET_USE_FANCY_MATH_387
13917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13918 || TARGET_MIX_SSE_I387)
13919 && flag_unsafe_math_optimizations"
13920 "fsincos"
13921 [(set_attr "type" "fpspc")
13922 (set_attr "mode" "XF")])
13923
13924 (define_split
13925 [(set (match_operand:XF 0 "register_operand")
13926 (unspec:XF [(float_extend:XF
13927 (match_operand:MODEF 2 "register_operand"))]
13928 UNSPEC_SINCOS_COS))
13929 (set (match_operand:XF 1 "register_operand")
13930 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13931 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13932 && can_create_pseudo_p ()"
13933 [(set (match_dup 1)
13934 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13935
13936 (define_split
13937 [(set (match_operand:XF 0 "register_operand")
13938 (unspec:XF [(float_extend:XF
13939 (match_operand:MODEF 2 "register_operand"))]
13940 UNSPEC_SINCOS_COS))
13941 (set (match_operand:XF 1 "register_operand")
13942 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13943 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13944 && can_create_pseudo_p ()"
13945 [(set (match_dup 0)
13946 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13947
13948 (define_expand "sincos<mode>3"
13949 [(use (match_operand:MODEF 0 "register_operand"))
13950 (use (match_operand:MODEF 1 "register_operand"))
13951 (use (match_operand:MODEF 2 "register_operand"))]
13952 "TARGET_USE_FANCY_MATH_387
13953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13954 || TARGET_MIX_SSE_I387)
13955 && flag_unsafe_math_optimizations"
13956 {
13957 rtx op0 = gen_reg_rtx (XFmode);
13958 rtx op1 = gen_reg_rtx (XFmode);
13959
13960 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13961 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13962 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13963 DONE;
13964 })
13965
13966 (define_insn "fptanxf4_i387"
13967 [(set (match_operand:XF 0 "register_operand" "=f")
13968 (match_operand:XF 3 "const_double_operand" "F"))
13969 (set (match_operand:XF 1 "register_operand" "=u")
13970 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13971 UNSPEC_TAN))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && flag_unsafe_math_optimizations
13974 && standard_80387_constant_p (operands[3]) == 2"
13975 "fptan"
13976 [(set_attr "type" "fpspc")
13977 (set_attr "mode" "XF")])
13978
13979 (define_insn "fptan_extend<mode>xf4_i387"
13980 [(set (match_operand:MODEF 0 "register_operand" "=f")
13981 (match_operand:MODEF 3 "const_double_operand" "F"))
13982 (set (match_operand:XF 1 "register_operand" "=u")
13983 (unspec:XF [(float_extend:XF
13984 (match_operand:MODEF 2 "register_operand" "0"))]
13985 UNSPEC_TAN))]
13986 "TARGET_USE_FANCY_MATH_387
13987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13988 || TARGET_MIX_SSE_I387)
13989 && flag_unsafe_math_optimizations
13990 && standard_80387_constant_p (operands[3]) == 2"
13991 "fptan"
13992 [(set_attr "type" "fpspc")
13993 (set_attr "mode" "XF")])
13994
13995 (define_expand "tanxf2"
13996 [(use (match_operand:XF 0 "register_operand"))
13997 (use (match_operand:XF 1 "register_operand"))]
13998 "TARGET_USE_FANCY_MATH_387
13999 && flag_unsafe_math_optimizations"
14000 {
14001 rtx one = gen_reg_rtx (XFmode);
14002 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14003
14004 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14005 DONE;
14006 })
14007
14008 (define_expand "tan<mode>2"
14009 [(use (match_operand:MODEF 0 "register_operand"))
14010 (use (match_operand:MODEF 1 "register_operand"))]
14011 "TARGET_USE_FANCY_MATH_387
14012 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14013 || TARGET_MIX_SSE_I387)
14014 && flag_unsafe_math_optimizations"
14015 {
14016 rtx op0 = gen_reg_rtx (XFmode);
14017
14018 rtx one = gen_reg_rtx (<MODE>mode);
14019 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14020
14021 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14022 operands[1], op2));
14023 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14024 DONE;
14025 })
14026
14027 (define_insn "*fpatanxf3_i387"
14028 [(set (match_operand:XF 0 "register_operand" "=f")
14029 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14030 (match_operand:XF 2 "register_operand" "u")]
14031 UNSPEC_FPATAN))
14032 (clobber (match_scratch:XF 3 "=2"))]
14033 "TARGET_USE_FANCY_MATH_387
14034 && flag_unsafe_math_optimizations"
14035 "fpatan"
14036 [(set_attr "type" "fpspc")
14037 (set_attr "mode" "XF")])
14038
14039 (define_insn "fpatan_extend<mode>xf3_i387"
14040 [(set (match_operand:XF 0 "register_operand" "=f")
14041 (unspec:XF [(float_extend:XF
14042 (match_operand:MODEF 1 "register_operand" "0"))
14043 (float_extend:XF
14044 (match_operand:MODEF 2 "register_operand" "u"))]
14045 UNSPEC_FPATAN))
14046 (clobber (match_scratch:XF 3 "=2"))]
14047 "TARGET_USE_FANCY_MATH_387
14048 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14049 || TARGET_MIX_SSE_I387)
14050 && flag_unsafe_math_optimizations"
14051 "fpatan"
14052 [(set_attr "type" "fpspc")
14053 (set_attr "mode" "XF")])
14054
14055 (define_expand "atan2xf3"
14056 [(parallel [(set (match_operand:XF 0 "register_operand")
14057 (unspec:XF [(match_operand:XF 2 "register_operand")
14058 (match_operand:XF 1 "register_operand")]
14059 UNSPEC_FPATAN))
14060 (clobber (match_scratch:XF 3))])]
14061 "TARGET_USE_FANCY_MATH_387
14062 && flag_unsafe_math_optimizations")
14063
14064 (define_expand "atan2<mode>3"
14065 [(use (match_operand:MODEF 0 "register_operand"))
14066 (use (match_operand:MODEF 1 "register_operand"))
14067 (use (match_operand:MODEF 2 "register_operand"))]
14068 "TARGET_USE_FANCY_MATH_387
14069 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14070 || TARGET_MIX_SSE_I387)
14071 && flag_unsafe_math_optimizations"
14072 {
14073 rtx op0 = gen_reg_rtx (XFmode);
14074
14075 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14077 DONE;
14078 })
14079
14080 (define_expand "atanxf2"
14081 [(parallel [(set (match_operand:XF 0 "register_operand")
14082 (unspec:XF [(match_dup 2)
14083 (match_operand:XF 1 "register_operand")]
14084 UNSPEC_FPATAN))
14085 (clobber (match_scratch:XF 3))])]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_unsafe_math_optimizations"
14088 {
14089 operands[2] = gen_reg_rtx (XFmode);
14090 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14091 })
14092
14093 (define_expand "atan<mode>2"
14094 [(use (match_operand:MODEF 0 "register_operand"))
14095 (use (match_operand:MODEF 1 "register_operand"))]
14096 "TARGET_USE_FANCY_MATH_387
14097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14098 || TARGET_MIX_SSE_I387)
14099 && flag_unsafe_math_optimizations"
14100 {
14101 rtx op0 = gen_reg_rtx (XFmode);
14102
14103 rtx op2 = gen_reg_rtx (<MODE>mode);
14104 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14105
14106 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14107 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14108 DONE;
14109 })
14110
14111 (define_expand "asinxf2"
14112 [(set (match_dup 2)
14113 (mult:XF (match_operand:XF 1 "register_operand")
14114 (match_dup 1)))
14115 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14116 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14117 (parallel [(set (match_operand:XF 0 "register_operand")
14118 (unspec:XF [(match_dup 5) (match_dup 1)]
14119 UNSPEC_FPATAN))
14120 (clobber (match_scratch:XF 6))])]
14121 "TARGET_USE_FANCY_MATH_387
14122 && flag_unsafe_math_optimizations"
14123 {
14124 int i;
14125
14126 if (optimize_insn_for_size_p ())
14127 FAIL;
14128
14129 for (i = 2; i < 6; i++)
14130 operands[i] = gen_reg_rtx (XFmode);
14131
14132 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14133 })
14134
14135 (define_expand "asin<mode>2"
14136 [(use (match_operand:MODEF 0 "register_operand"))
14137 (use (match_operand:MODEF 1 "general_operand"))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14140 || TARGET_MIX_SSE_I387)
14141 && flag_unsafe_math_optimizations"
14142 {
14143 rtx op0 = gen_reg_rtx (XFmode);
14144 rtx op1 = gen_reg_rtx (XFmode);
14145
14146 if (optimize_insn_for_size_p ())
14147 FAIL;
14148
14149 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14150 emit_insn (gen_asinxf2 (op0, op1));
14151 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14152 DONE;
14153 })
14154
14155 (define_expand "acosxf2"
14156 [(set (match_dup 2)
14157 (mult:XF (match_operand:XF 1 "register_operand")
14158 (match_dup 1)))
14159 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14160 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14161 (parallel [(set (match_operand:XF 0 "register_operand")
14162 (unspec:XF [(match_dup 1) (match_dup 5)]
14163 UNSPEC_FPATAN))
14164 (clobber (match_scratch:XF 6))])]
14165 "TARGET_USE_FANCY_MATH_387
14166 && flag_unsafe_math_optimizations"
14167 {
14168 int i;
14169
14170 if (optimize_insn_for_size_p ())
14171 FAIL;
14172
14173 for (i = 2; i < 6; i++)
14174 operands[i] = gen_reg_rtx (XFmode);
14175
14176 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14177 })
14178
14179 (define_expand "acos<mode>2"
14180 [(use (match_operand:MODEF 0 "register_operand"))
14181 (use (match_operand:MODEF 1 "general_operand"))]
14182 "TARGET_USE_FANCY_MATH_387
14183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14184 || TARGET_MIX_SSE_I387)
14185 && flag_unsafe_math_optimizations"
14186 {
14187 rtx op0 = gen_reg_rtx (XFmode);
14188 rtx op1 = gen_reg_rtx (XFmode);
14189
14190 if (optimize_insn_for_size_p ())
14191 FAIL;
14192
14193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14194 emit_insn (gen_acosxf2 (op0, op1));
14195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14196 DONE;
14197 })
14198
14199 (define_insn "fyl2xxf3_i387"
14200 [(set (match_operand:XF 0 "register_operand" "=f")
14201 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14202 (match_operand:XF 2 "register_operand" "u")]
14203 UNSPEC_FYL2X))
14204 (clobber (match_scratch:XF 3 "=2"))]
14205 "TARGET_USE_FANCY_MATH_387
14206 && flag_unsafe_math_optimizations"
14207 "fyl2x"
14208 [(set_attr "type" "fpspc")
14209 (set_attr "mode" "XF")])
14210
14211 (define_insn "fyl2x_extend<mode>xf3_i387"
14212 [(set (match_operand:XF 0 "register_operand" "=f")
14213 (unspec:XF [(float_extend:XF
14214 (match_operand:MODEF 1 "register_operand" "0"))
14215 (match_operand:XF 2 "register_operand" "u")]
14216 UNSPEC_FYL2X))
14217 (clobber (match_scratch:XF 3 "=2"))]
14218 "TARGET_USE_FANCY_MATH_387
14219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14220 || TARGET_MIX_SSE_I387)
14221 && flag_unsafe_math_optimizations"
14222 "fyl2x"
14223 [(set_attr "type" "fpspc")
14224 (set_attr "mode" "XF")])
14225
14226 (define_expand "logxf2"
14227 [(parallel [(set (match_operand:XF 0 "register_operand")
14228 (unspec:XF [(match_operand:XF 1 "register_operand")
14229 (match_dup 2)] UNSPEC_FYL2X))
14230 (clobber (match_scratch:XF 3))])]
14231 "TARGET_USE_FANCY_MATH_387
14232 && flag_unsafe_math_optimizations"
14233 {
14234 operands[2] = gen_reg_rtx (XFmode);
14235 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14236 })
14237
14238 (define_expand "log<mode>2"
14239 [(use (match_operand:MODEF 0 "register_operand"))
14240 (use (match_operand:MODEF 1 "register_operand"))]
14241 "TARGET_USE_FANCY_MATH_387
14242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14243 || TARGET_MIX_SSE_I387)
14244 && flag_unsafe_math_optimizations"
14245 {
14246 rtx op0 = gen_reg_rtx (XFmode);
14247
14248 rtx op2 = gen_reg_rtx (XFmode);
14249 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14250
14251 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14252 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14253 DONE;
14254 })
14255
14256 (define_expand "log10xf2"
14257 [(parallel [(set (match_operand:XF 0 "register_operand")
14258 (unspec:XF [(match_operand:XF 1 "register_operand")
14259 (match_dup 2)] UNSPEC_FYL2X))
14260 (clobber (match_scratch:XF 3))])]
14261 "TARGET_USE_FANCY_MATH_387
14262 && flag_unsafe_math_optimizations"
14263 {
14264 operands[2] = gen_reg_rtx (XFmode);
14265 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14266 })
14267
14268 (define_expand "log10<mode>2"
14269 [(use (match_operand:MODEF 0 "register_operand"))
14270 (use (match_operand:MODEF 1 "register_operand"))]
14271 "TARGET_USE_FANCY_MATH_387
14272 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14273 || TARGET_MIX_SSE_I387)
14274 && flag_unsafe_math_optimizations"
14275 {
14276 rtx op0 = gen_reg_rtx (XFmode);
14277
14278 rtx op2 = gen_reg_rtx (XFmode);
14279 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14280
14281 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14282 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14283 DONE;
14284 })
14285
14286 (define_expand "log2xf2"
14287 [(parallel [(set (match_operand:XF 0 "register_operand")
14288 (unspec:XF [(match_operand:XF 1 "register_operand")
14289 (match_dup 2)] UNSPEC_FYL2X))
14290 (clobber (match_scratch:XF 3))])]
14291 "TARGET_USE_FANCY_MATH_387
14292 && flag_unsafe_math_optimizations"
14293 {
14294 operands[2] = gen_reg_rtx (XFmode);
14295 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14296 })
14297
14298 (define_expand "log2<mode>2"
14299 [(use (match_operand:MODEF 0 "register_operand"))
14300 (use (match_operand:MODEF 1 "register_operand"))]
14301 "TARGET_USE_FANCY_MATH_387
14302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14303 || TARGET_MIX_SSE_I387)
14304 && flag_unsafe_math_optimizations"
14305 {
14306 rtx op0 = gen_reg_rtx (XFmode);
14307
14308 rtx op2 = gen_reg_rtx (XFmode);
14309 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14310
14311 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14312 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14313 DONE;
14314 })
14315
14316 (define_insn "fyl2xp1xf3_i387"
14317 [(set (match_operand:XF 0 "register_operand" "=f")
14318 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14319 (match_operand:XF 2 "register_operand" "u")]
14320 UNSPEC_FYL2XP1))
14321 (clobber (match_scratch:XF 3 "=2"))]
14322 "TARGET_USE_FANCY_MATH_387
14323 && flag_unsafe_math_optimizations"
14324 "fyl2xp1"
14325 [(set_attr "type" "fpspc")
14326 (set_attr "mode" "XF")])
14327
14328 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14329 [(set (match_operand:XF 0 "register_operand" "=f")
14330 (unspec:XF [(float_extend:XF
14331 (match_operand:MODEF 1 "register_operand" "0"))
14332 (match_operand:XF 2 "register_operand" "u")]
14333 UNSPEC_FYL2XP1))
14334 (clobber (match_scratch:XF 3 "=2"))]
14335 "TARGET_USE_FANCY_MATH_387
14336 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14337 || TARGET_MIX_SSE_I387)
14338 && flag_unsafe_math_optimizations"
14339 "fyl2xp1"
14340 [(set_attr "type" "fpspc")
14341 (set_attr "mode" "XF")])
14342
14343 (define_expand "log1pxf2"
14344 [(use (match_operand:XF 0 "register_operand"))
14345 (use (match_operand:XF 1 "register_operand"))]
14346 "TARGET_USE_FANCY_MATH_387
14347 && flag_unsafe_math_optimizations"
14348 {
14349 if (optimize_insn_for_size_p ())
14350 FAIL;
14351
14352 ix86_emit_i387_log1p (operands[0], operands[1]);
14353 DONE;
14354 })
14355
14356 (define_expand "log1p<mode>2"
14357 [(use (match_operand:MODEF 0 "register_operand"))
14358 (use (match_operand:MODEF 1 "register_operand"))]
14359 "TARGET_USE_FANCY_MATH_387
14360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14361 || TARGET_MIX_SSE_I387)
14362 && flag_unsafe_math_optimizations"
14363 {
14364 rtx op0;
14365
14366 if (optimize_insn_for_size_p ())
14367 FAIL;
14368
14369 op0 = gen_reg_rtx (XFmode);
14370
14371 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14372
14373 ix86_emit_i387_log1p (op0, operands[1]);
14374 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14375 DONE;
14376 })
14377
14378 (define_insn "fxtractxf3_i387"
14379 [(set (match_operand:XF 0 "register_operand" "=f")
14380 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14381 UNSPEC_XTRACT_FRACT))
14382 (set (match_operand:XF 1 "register_operand" "=u")
14383 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14386 "fxtract"
14387 [(set_attr "type" "fpspc")
14388 (set_attr "mode" "XF")])
14389
14390 (define_insn "fxtract_extend<mode>xf3_i387"
14391 [(set (match_operand:XF 0 "register_operand" "=f")
14392 (unspec:XF [(float_extend:XF
14393 (match_operand:MODEF 2 "register_operand" "0"))]
14394 UNSPEC_XTRACT_FRACT))
14395 (set (match_operand:XF 1 "register_operand" "=u")
14396 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14397 "TARGET_USE_FANCY_MATH_387
14398 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14399 || TARGET_MIX_SSE_I387)
14400 && flag_unsafe_math_optimizations"
14401 "fxtract"
14402 [(set_attr "type" "fpspc")
14403 (set_attr "mode" "XF")])
14404
14405 (define_expand "logbxf2"
14406 [(parallel [(set (match_dup 2)
14407 (unspec:XF [(match_operand:XF 1 "register_operand")]
14408 UNSPEC_XTRACT_FRACT))
14409 (set (match_operand:XF 0 "register_operand")
14410 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14411 "TARGET_USE_FANCY_MATH_387
14412 && flag_unsafe_math_optimizations"
14413 "operands[2] = gen_reg_rtx (XFmode);")
14414
14415 (define_expand "logb<mode>2"
14416 [(use (match_operand:MODEF 0 "register_operand"))
14417 (use (match_operand:MODEF 1 "register_operand"))]
14418 "TARGET_USE_FANCY_MATH_387
14419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420 || TARGET_MIX_SSE_I387)
14421 && flag_unsafe_math_optimizations"
14422 {
14423 rtx op0 = gen_reg_rtx (XFmode);
14424 rtx op1 = gen_reg_rtx (XFmode);
14425
14426 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14427 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14428 DONE;
14429 })
14430
14431 (define_expand "ilogbxf2"
14432 [(use (match_operand:SI 0 "register_operand"))
14433 (use (match_operand:XF 1 "register_operand"))]
14434 "TARGET_USE_FANCY_MATH_387
14435 && flag_unsafe_math_optimizations"
14436 {
14437 rtx op0, op1;
14438
14439 if (optimize_insn_for_size_p ())
14440 FAIL;
14441
14442 op0 = gen_reg_rtx (XFmode);
14443 op1 = gen_reg_rtx (XFmode);
14444
14445 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14446 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14447 DONE;
14448 })
14449
14450 (define_expand "ilogb<mode>2"
14451 [(use (match_operand:SI 0 "register_operand"))
14452 (use (match_operand:MODEF 1 "register_operand"))]
14453 "TARGET_USE_FANCY_MATH_387
14454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14455 || TARGET_MIX_SSE_I387)
14456 && flag_unsafe_math_optimizations"
14457 {
14458 rtx op0, op1;
14459
14460 if (optimize_insn_for_size_p ())
14461 FAIL;
14462
14463 op0 = gen_reg_rtx (XFmode);
14464 op1 = gen_reg_rtx (XFmode);
14465
14466 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14467 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14468 DONE;
14469 })
14470
14471 (define_insn "*f2xm1xf2_i387"
14472 [(set (match_operand:XF 0 "register_operand" "=f")
14473 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14474 UNSPEC_F2XM1))]
14475 "TARGET_USE_FANCY_MATH_387
14476 && flag_unsafe_math_optimizations"
14477 "f2xm1"
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "XF")])
14480
14481 (define_insn "*fscalexf4_i387"
14482 [(set (match_operand:XF 0 "register_operand" "=f")
14483 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14484 (match_operand:XF 3 "register_operand" "1")]
14485 UNSPEC_FSCALE_FRACT))
14486 (set (match_operand:XF 1 "register_operand" "=u")
14487 (unspec:XF [(match_dup 2) (match_dup 3)]
14488 UNSPEC_FSCALE_EXP))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && flag_unsafe_math_optimizations"
14491 "fscale"
14492 [(set_attr "type" "fpspc")
14493 (set_attr "mode" "XF")])
14494
14495 (define_expand "expNcorexf3"
14496 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14497 (match_operand:XF 2 "register_operand")))
14498 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14499 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14500 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14501 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14502 (parallel [(set (match_operand:XF 0 "register_operand")
14503 (unspec:XF [(match_dup 8) (match_dup 4)]
14504 UNSPEC_FSCALE_FRACT))
14505 (set (match_dup 9)
14506 (unspec:XF [(match_dup 8) (match_dup 4)]
14507 UNSPEC_FSCALE_EXP))])]
14508 "TARGET_USE_FANCY_MATH_387
14509 && flag_unsafe_math_optimizations"
14510 {
14511 int i;
14512
14513 if (optimize_insn_for_size_p ())
14514 FAIL;
14515
14516 for (i = 3; i < 10; i++)
14517 operands[i] = gen_reg_rtx (XFmode);
14518
14519 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14520 })
14521
14522 (define_expand "expxf2"
14523 [(use (match_operand:XF 0 "register_operand"))
14524 (use (match_operand:XF 1 "register_operand"))]
14525 "TARGET_USE_FANCY_MATH_387
14526 && flag_unsafe_math_optimizations"
14527 {
14528 rtx op2;
14529
14530 if (optimize_insn_for_size_p ())
14531 FAIL;
14532
14533 op2 = gen_reg_rtx (XFmode);
14534 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14535
14536 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14537 DONE;
14538 })
14539
14540 (define_expand "exp<mode>2"
14541 [(use (match_operand:MODEF 0 "register_operand"))
14542 (use (match_operand:MODEF 1 "general_operand"))]
14543 "TARGET_USE_FANCY_MATH_387
14544 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14545 || TARGET_MIX_SSE_I387)
14546 && flag_unsafe_math_optimizations"
14547 {
14548 rtx op0, op1;
14549
14550 if (optimize_insn_for_size_p ())
14551 FAIL;
14552
14553 op0 = gen_reg_rtx (XFmode);
14554 op1 = gen_reg_rtx (XFmode);
14555
14556 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14557 emit_insn (gen_expxf2 (op0, op1));
14558 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14559 DONE;
14560 })
14561
14562 (define_expand "exp10xf2"
14563 [(use (match_operand:XF 0 "register_operand"))
14564 (use (match_operand:XF 1 "register_operand"))]
14565 "TARGET_USE_FANCY_MATH_387
14566 && flag_unsafe_math_optimizations"
14567 {
14568 rtx op2;
14569
14570 if (optimize_insn_for_size_p ())
14571 FAIL;
14572
14573 op2 = gen_reg_rtx (XFmode);
14574 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14575
14576 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14577 DONE;
14578 })
14579
14580 (define_expand "exp10<mode>2"
14581 [(use (match_operand:MODEF 0 "register_operand"))
14582 (use (match_operand:MODEF 1 "general_operand"))]
14583 "TARGET_USE_FANCY_MATH_387
14584 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14585 || TARGET_MIX_SSE_I387)
14586 && flag_unsafe_math_optimizations"
14587 {
14588 rtx op0, op1;
14589
14590 if (optimize_insn_for_size_p ())
14591 FAIL;
14592
14593 op0 = gen_reg_rtx (XFmode);
14594 op1 = gen_reg_rtx (XFmode);
14595
14596 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14597 emit_insn (gen_exp10xf2 (op0, op1));
14598 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14599 DONE;
14600 })
14601
14602 (define_expand "exp2xf2"
14603 [(use (match_operand:XF 0 "register_operand"))
14604 (use (match_operand:XF 1 "register_operand"))]
14605 "TARGET_USE_FANCY_MATH_387
14606 && flag_unsafe_math_optimizations"
14607 {
14608 rtx op2;
14609
14610 if (optimize_insn_for_size_p ())
14611 FAIL;
14612
14613 op2 = gen_reg_rtx (XFmode);
14614 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14615
14616 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14617 DONE;
14618 })
14619
14620 (define_expand "exp2<mode>2"
14621 [(use (match_operand:MODEF 0 "register_operand"))
14622 (use (match_operand:MODEF 1 "general_operand"))]
14623 "TARGET_USE_FANCY_MATH_387
14624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14625 || TARGET_MIX_SSE_I387)
14626 && flag_unsafe_math_optimizations"
14627 {
14628 rtx op0, op1;
14629
14630 if (optimize_insn_for_size_p ())
14631 FAIL;
14632
14633 op0 = gen_reg_rtx (XFmode);
14634 op1 = gen_reg_rtx (XFmode);
14635
14636 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14637 emit_insn (gen_exp2xf2 (op0, op1));
14638 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14639 DONE;
14640 })
14641
14642 (define_expand "expm1xf2"
14643 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14644 (match_dup 2)))
14645 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14646 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14647 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14648 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14649 (parallel [(set (match_dup 7)
14650 (unspec:XF [(match_dup 6) (match_dup 4)]
14651 UNSPEC_FSCALE_FRACT))
14652 (set (match_dup 8)
14653 (unspec:XF [(match_dup 6) (match_dup 4)]
14654 UNSPEC_FSCALE_EXP))])
14655 (parallel [(set (match_dup 10)
14656 (unspec:XF [(match_dup 9) (match_dup 8)]
14657 UNSPEC_FSCALE_FRACT))
14658 (set (match_dup 11)
14659 (unspec:XF [(match_dup 9) (match_dup 8)]
14660 UNSPEC_FSCALE_EXP))])
14661 (set (match_dup 12) (minus:XF (match_dup 10)
14662 (float_extend:XF (match_dup 13))))
14663 (set (match_operand:XF 0 "register_operand")
14664 (plus:XF (match_dup 12) (match_dup 7)))]
14665 "TARGET_USE_FANCY_MATH_387
14666 && flag_unsafe_math_optimizations"
14667 {
14668 int i;
14669
14670 if (optimize_insn_for_size_p ())
14671 FAIL;
14672
14673 for (i = 2; i < 13; i++)
14674 operands[i] = gen_reg_rtx (XFmode);
14675
14676 operands[13]
14677 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14678
14679 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14680 })
14681
14682 (define_expand "expm1<mode>2"
14683 [(use (match_operand:MODEF 0 "register_operand"))
14684 (use (match_operand:MODEF 1 "general_operand"))]
14685 "TARGET_USE_FANCY_MATH_387
14686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14687 || TARGET_MIX_SSE_I387)
14688 && flag_unsafe_math_optimizations"
14689 {
14690 rtx op0, op1;
14691
14692 if (optimize_insn_for_size_p ())
14693 FAIL;
14694
14695 op0 = gen_reg_rtx (XFmode);
14696 op1 = gen_reg_rtx (XFmode);
14697
14698 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14699 emit_insn (gen_expm1xf2 (op0, op1));
14700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14701 DONE;
14702 })
14703
14704 (define_expand "ldexpxf3"
14705 [(set (match_dup 3)
14706 (float:XF (match_operand:SI 2 "register_operand")))
14707 (parallel [(set (match_operand:XF 0 " register_operand")
14708 (unspec:XF [(match_operand:XF 1 "register_operand")
14709 (match_dup 3)]
14710 UNSPEC_FSCALE_FRACT))
14711 (set (match_dup 4)
14712 (unspec:XF [(match_dup 1) (match_dup 3)]
14713 UNSPEC_FSCALE_EXP))])]
14714 "TARGET_USE_FANCY_MATH_387
14715 && flag_unsafe_math_optimizations"
14716 {
14717 if (optimize_insn_for_size_p ())
14718 FAIL;
14719
14720 operands[3] = gen_reg_rtx (XFmode);
14721 operands[4] = gen_reg_rtx (XFmode);
14722 })
14723
14724 (define_expand "ldexp<mode>3"
14725 [(use (match_operand:MODEF 0 "register_operand"))
14726 (use (match_operand:MODEF 1 "general_operand"))
14727 (use (match_operand:SI 2 "register_operand"))]
14728 "TARGET_USE_FANCY_MATH_387
14729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14730 || TARGET_MIX_SSE_I387)
14731 && flag_unsafe_math_optimizations"
14732 {
14733 rtx op0, op1;
14734
14735 if (optimize_insn_for_size_p ())
14736 FAIL;
14737
14738 op0 = gen_reg_rtx (XFmode);
14739 op1 = gen_reg_rtx (XFmode);
14740
14741 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14742 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14744 DONE;
14745 })
14746
14747 (define_expand "scalbxf3"
14748 [(parallel [(set (match_operand:XF 0 " register_operand")
14749 (unspec:XF [(match_operand:XF 1 "register_operand")
14750 (match_operand:XF 2 "register_operand")]
14751 UNSPEC_FSCALE_FRACT))
14752 (set (match_dup 3)
14753 (unspec:XF [(match_dup 1) (match_dup 2)]
14754 UNSPEC_FSCALE_EXP))])]
14755 "TARGET_USE_FANCY_MATH_387
14756 && flag_unsafe_math_optimizations"
14757 {
14758 if (optimize_insn_for_size_p ())
14759 FAIL;
14760
14761 operands[3] = gen_reg_rtx (XFmode);
14762 })
14763
14764 (define_expand "scalb<mode>3"
14765 [(use (match_operand:MODEF 0 "register_operand"))
14766 (use (match_operand:MODEF 1 "general_operand"))
14767 (use (match_operand:MODEF 2 "general_operand"))]
14768 "TARGET_USE_FANCY_MATH_387
14769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14770 || TARGET_MIX_SSE_I387)
14771 && flag_unsafe_math_optimizations"
14772 {
14773 rtx op0, op1, op2;
14774
14775 if (optimize_insn_for_size_p ())
14776 FAIL;
14777
14778 op0 = gen_reg_rtx (XFmode);
14779 op1 = gen_reg_rtx (XFmode);
14780 op2 = gen_reg_rtx (XFmode);
14781
14782 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14783 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14784 emit_insn (gen_scalbxf3 (op0, op1, op2));
14785 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14786 DONE;
14787 })
14788
14789 (define_expand "significandxf2"
14790 [(parallel [(set (match_operand:XF 0 "register_operand")
14791 (unspec:XF [(match_operand:XF 1 "register_operand")]
14792 UNSPEC_XTRACT_FRACT))
14793 (set (match_dup 2)
14794 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14797 "operands[2] = gen_reg_rtx (XFmode);")
14798
14799 (define_expand "significand<mode>2"
14800 [(use (match_operand:MODEF 0 "register_operand"))
14801 (use (match_operand:MODEF 1 "register_operand"))]
14802 "TARGET_USE_FANCY_MATH_387
14803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14804 || TARGET_MIX_SSE_I387)
14805 && flag_unsafe_math_optimizations"
14806 {
14807 rtx op0 = gen_reg_rtx (XFmode);
14808 rtx op1 = gen_reg_rtx (XFmode);
14809
14810 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14811 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14812 DONE;
14813 })
14814 \f
14815
14816 (define_insn "sse4_1_round<mode>2"
14817 [(set (match_operand:MODEF 0 "register_operand" "=x")
14818 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14819 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14820 UNSPEC_ROUND))]
14821 "TARGET_ROUND"
14822 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14823 [(set_attr "type" "ssecvt")
14824 (set_attr "prefix_extra" "1")
14825 (set_attr "prefix" "maybe_vex")
14826 (set_attr "mode" "<MODE>")])
14827
14828 (define_insn "rintxf2"
14829 [(set (match_operand:XF 0 "register_operand" "=f")
14830 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14831 UNSPEC_FRNDINT))]
14832 "TARGET_USE_FANCY_MATH_387
14833 && flag_unsafe_math_optimizations"
14834 "frndint"
14835 [(set_attr "type" "fpspc")
14836 (set_attr "mode" "XF")])
14837
14838 (define_expand "rint<mode>2"
14839 [(use (match_operand:MODEF 0 "register_operand"))
14840 (use (match_operand:MODEF 1 "register_operand"))]
14841 "(TARGET_USE_FANCY_MATH_387
14842 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14843 || TARGET_MIX_SSE_I387)
14844 && flag_unsafe_math_optimizations)
14845 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846 && !flag_trapping_math)"
14847 {
14848 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14849 && !flag_trapping_math)
14850 {
14851 if (TARGET_ROUND)
14852 emit_insn (gen_sse4_1_round<mode>2
14853 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14854 else if (optimize_insn_for_size_p ())
14855 FAIL;
14856 else
14857 ix86_expand_rint (operands[0], operands[1]);
14858 }
14859 else
14860 {
14861 rtx op0 = gen_reg_rtx (XFmode);
14862 rtx op1 = gen_reg_rtx (XFmode);
14863
14864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14865 emit_insn (gen_rintxf2 (op0, op1));
14866
14867 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14868 }
14869 DONE;
14870 })
14871
14872 (define_expand "round<mode>2"
14873 [(match_operand:X87MODEF 0 "register_operand")
14874 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14875 "(TARGET_USE_FANCY_MATH_387
14876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14877 || TARGET_MIX_SSE_I387)
14878 && flag_unsafe_math_optimizations)
14879 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14880 && !flag_trapping_math && !flag_rounding_math)"
14881 {
14882 if (optimize_insn_for_size_p ())
14883 FAIL;
14884
14885 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14886 && !flag_trapping_math && !flag_rounding_math)
14887 {
14888 if (TARGET_ROUND)
14889 {
14890 operands[1] = force_reg (<MODE>mode, operands[1]);
14891 ix86_expand_round_sse4 (operands[0], operands[1]);
14892 }
14893 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14894 ix86_expand_round (operands[0], operands[1]);
14895 else
14896 ix86_expand_rounddf_32 (operands[0], operands[1]);
14897 }
14898 else
14899 {
14900 operands[1] = force_reg (<MODE>mode, operands[1]);
14901 ix86_emit_i387_round (operands[0], operands[1]);
14902 }
14903 DONE;
14904 })
14905
14906 (define_insn_and_split "*fistdi2_1"
14907 [(set (match_operand:DI 0 "nonimmediate_operand")
14908 (unspec:DI [(match_operand:XF 1 "register_operand")]
14909 UNSPEC_FIST))]
14910 "TARGET_USE_FANCY_MATH_387
14911 && can_create_pseudo_p ()"
14912 "#"
14913 "&& 1"
14914 [(const_int 0)]
14915 {
14916 if (memory_operand (operands[0], VOIDmode))
14917 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14918 else
14919 {
14920 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14921 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14922 operands[2]));
14923 }
14924 DONE;
14925 }
14926 [(set_attr "type" "fpspc")
14927 (set_attr "mode" "DI")])
14928
14929 (define_insn "fistdi2"
14930 [(set (match_operand:DI 0 "memory_operand" "=m")
14931 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14932 UNSPEC_FIST))
14933 (clobber (match_scratch:XF 2 "=&1f"))]
14934 "TARGET_USE_FANCY_MATH_387"
14935 "* return output_fix_trunc (insn, operands, false);"
14936 [(set_attr "type" "fpspc")
14937 (set_attr "mode" "DI")])
14938
14939 (define_insn "fistdi2_with_temp"
14940 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14941 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14942 UNSPEC_FIST))
14943 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14944 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14945 "TARGET_USE_FANCY_MATH_387"
14946 "#"
14947 [(set_attr "type" "fpspc")
14948 (set_attr "mode" "DI")])
14949
14950 (define_split
14951 [(set (match_operand:DI 0 "register_operand")
14952 (unspec:DI [(match_operand:XF 1 "register_operand")]
14953 UNSPEC_FIST))
14954 (clobber (match_operand:DI 2 "memory_operand"))
14955 (clobber (match_scratch 3))]
14956 "reload_completed"
14957 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14958 (clobber (match_dup 3))])
14959 (set (match_dup 0) (match_dup 2))])
14960
14961 (define_split
14962 [(set (match_operand:DI 0 "memory_operand")
14963 (unspec:DI [(match_operand:XF 1 "register_operand")]
14964 UNSPEC_FIST))
14965 (clobber (match_operand:DI 2 "memory_operand"))
14966 (clobber (match_scratch 3))]
14967 "reload_completed"
14968 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14969 (clobber (match_dup 3))])])
14970
14971 (define_insn_and_split "*fist<mode>2_1"
14972 [(set (match_operand:SWI24 0 "register_operand")
14973 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14974 UNSPEC_FIST))]
14975 "TARGET_USE_FANCY_MATH_387
14976 && can_create_pseudo_p ()"
14977 "#"
14978 "&& 1"
14979 [(const_int 0)]
14980 {
14981 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14982 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14983 operands[2]));
14984 DONE;
14985 }
14986 [(set_attr "type" "fpspc")
14987 (set_attr "mode" "<MODE>")])
14988
14989 (define_insn "fist<mode>2"
14990 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14991 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14992 UNSPEC_FIST))]
14993 "TARGET_USE_FANCY_MATH_387"
14994 "* return output_fix_trunc (insn, operands, false);"
14995 [(set_attr "type" "fpspc")
14996 (set_attr "mode" "<MODE>")])
14997
14998 (define_insn "fist<mode>2_with_temp"
14999 [(set (match_operand:SWI24 0 "register_operand" "=r")
15000 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15001 UNSPEC_FIST))
15002 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15003 "TARGET_USE_FANCY_MATH_387"
15004 "#"
15005 [(set_attr "type" "fpspc")
15006 (set_attr "mode" "<MODE>")])
15007
15008 (define_split
15009 [(set (match_operand:SWI24 0 "register_operand")
15010 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15011 UNSPEC_FIST))
15012 (clobber (match_operand:SWI24 2 "memory_operand"))]
15013 "reload_completed"
15014 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15015 (set (match_dup 0) (match_dup 2))])
15016
15017 (define_split
15018 [(set (match_operand:SWI24 0 "memory_operand")
15019 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15020 UNSPEC_FIST))
15021 (clobber (match_operand:SWI24 2 "memory_operand"))]
15022 "reload_completed"
15023 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15024
15025 (define_expand "lrintxf<mode>2"
15026 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15027 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15028 UNSPEC_FIST))]
15029 "TARGET_USE_FANCY_MATH_387")
15030
15031 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15032 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15033 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15034 UNSPEC_FIX_NOTRUNC))]
15035 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15036
15037 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15038 [(match_operand:SWI248x 0 "nonimmediate_operand")
15039 (match_operand:X87MODEF 1 "register_operand")]
15040 "(TARGET_USE_FANCY_MATH_387
15041 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15042 || TARGET_MIX_SSE_I387)
15043 && flag_unsafe_math_optimizations)
15044 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15045 && <SWI248x:MODE>mode != HImode
15046 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15047 && !flag_trapping_math && !flag_rounding_math)"
15048 {
15049 if (optimize_insn_for_size_p ())
15050 FAIL;
15051
15052 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15053 && <SWI248x:MODE>mode != HImode
15054 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15055 && !flag_trapping_math && !flag_rounding_math)
15056 ix86_expand_lround (operands[0], operands[1]);
15057 else
15058 ix86_emit_i387_round (operands[0], operands[1]);
15059 DONE;
15060 })
15061
15062 (define_int_iterator FRNDINT_ROUNDING
15063 [UNSPEC_FRNDINT_FLOOR
15064 UNSPEC_FRNDINT_CEIL
15065 UNSPEC_FRNDINT_TRUNC])
15066
15067 (define_int_iterator FIST_ROUNDING
15068 [UNSPEC_FIST_FLOOR
15069 UNSPEC_FIST_CEIL])
15070
15071 ;; Base name for define_insn
15072 (define_int_attr rounding_insn
15073 [(UNSPEC_FRNDINT_FLOOR "floor")
15074 (UNSPEC_FRNDINT_CEIL "ceil")
15075 (UNSPEC_FRNDINT_TRUNC "btrunc")
15076 (UNSPEC_FIST_FLOOR "floor")
15077 (UNSPEC_FIST_CEIL "ceil")])
15078
15079 (define_int_attr rounding
15080 [(UNSPEC_FRNDINT_FLOOR "floor")
15081 (UNSPEC_FRNDINT_CEIL "ceil")
15082 (UNSPEC_FRNDINT_TRUNC "trunc")
15083 (UNSPEC_FIST_FLOOR "floor")
15084 (UNSPEC_FIST_CEIL "ceil")])
15085
15086 (define_int_attr ROUNDING
15087 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15088 (UNSPEC_FRNDINT_CEIL "CEIL")
15089 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15090 (UNSPEC_FIST_FLOOR "FLOOR")
15091 (UNSPEC_FIST_CEIL "CEIL")])
15092
15093 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15094 (define_insn_and_split "frndintxf2_<rounding>"
15095 [(set (match_operand:XF 0 "register_operand")
15096 (unspec:XF [(match_operand:XF 1 "register_operand")]
15097 FRNDINT_ROUNDING))
15098 (clobber (reg:CC FLAGS_REG))]
15099 "TARGET_USE_FANCY_MATH_387
15100 && flag_unsafe_math_optimizations
15101 && can_create_pseudo_p ()"
15102 "#"
15103 "&& 1"
15104 [(const_int 0)]
15105 {
15106 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15107
15108 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15109 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15110
15111 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15112 operands[2], operands[3]));
15113 DONE;
15114 }
15115 [(set_attr "type" "frndint")
15116 (set_attr "i387_cw" "<rounding>")
15117 (set_attr "mode" "XF")])
15118
15119 (define_insn "frndintxf2_<rounding>_i387"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15122 FRNDINT_ROUNDING))
15123 (use (match_operand:HI 2 "memory_operand" "m"))
15124 (use (match_operand:HI 3 "memory_operand" "m"))]
15125 "TARGET_USE_FANCY_MATH_387
15126 && flag_unsafe_math_optimizations"
15127 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15128 [(set_attr "type" "frndint")
15129 (set_attr "i387_cw" "<rounding>")
15130 (set_attr "mode" "XF")])
15131
15132 (define_expand "<rounding_insn>xf2"
15133 [(parallel [(set (match_operand:XF 0 "register_operand")
15134 (unspec:XF [(match_operand:XF 1 "register_operand")]
15135 FRNDINT_ROUNDING))
15136 (clobber (reg:CC FLAGS_REG))])]
15137 "TARGET_USE_FANCY_MATH_387
15138 && flag_unsafe_math_optimizations
15139 && !optimize_insn_for_size_p ()")
15140
15141 (define_expand "<rounding_insn><mode>2"
15142 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15143 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15144 FRNDINT_ROUNDING))
15145 (clobber (reg:CC FLAGS_REG))])]
15146 "(TARGET_USE_FANCY_MATH_387
15147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15148 || TARGET_MIX_SSE_I387)
15149 && flag_unsafe_math_optimizations)
15150 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15151 && !flag_trapping_math)"
15152 {
15153 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15154 && !flag_trapping_math)
15155 {
15156 if (TARGET_ROUND)
15157 emit_insn (gen_sse4_1_round<mode>2
15158 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15159 else if (optimize_insn_for_size_p ())
15160 FAIL;
15161 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15162 {
15163 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15164 ix86_expand_floorceil (operands[0], operands[1], true);
15165 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15166 ix86_expand_floorceil (operands[0], operands[1], false);
15167 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15168 ix86_expand_trunc (operands[0], operands[1]);
15169 else
15170 gcc_unreachable ();
15171 }
15172 else
15173 {
15174 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15175 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15176 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15177 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15178 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15179 ix86_expand_truncdf_32 (operands[0], operands[1]);
15180 else
15181 gcc_unreachable ();
15182 }
15183 }
15184 else
15185 {
15186 rtx op0, op1;
15187
15188 if (optimize_insn_for_size_p ())
15189 FAIL;
15190
15191 op0 = gen_reg_rtx (XFmode);
15192 op1 = gen_reg_rtx (XFmode);
15193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15194 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15195
15196 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15197 }
15198 DONE;
15199 })
15200
15201 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15202 (define_insn_and_split "frndintxf2_mask_pm"
15203 [(set (match_operand:XF 0 "register_operand")
15204 (unspec:XF [(match_operand:XF 1 "register_operand")]
15205 UNSPEC_FRNDINT_MASK_PM))
15206 (clobber (reg:CC FLAGS_REG))]
15207 "TARGET_USE_FANCY_MATH_387
15208 && flag_unsafe_math_optimizations
15209 && can_create_pseudo_p ()"
15210 "#"
15211 "&& 1"
15212 [(const_int 0)]
15213 {
15214 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15215
15216 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15217 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15218
15219 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15220 operands[2], operands[3]));
15221 DONE;
15222 }
15223 [(set_attr "type" "frndint")
15224 (set_attr "i387_cw" "mask_pm")
15225 (set_attr "mode" "XF")])
15226
15227 (define_insn "frndintxf2_mask_pm_i387"
15228 [(set (match_operand:XF 0 "register_operand" "=f")
15229 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15230 UNSPEC_FRNDINT_MASK_PM))
15231 (use (match_operand:HI 2 "memory_operand" "m"))
15232 (use (match_operand:HI 3 "memory_operand" "m"))]
15233 "TARGET_USE_FANCY_MATH_387
15234 && flag_unsafe_math_optimizations"
15235 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15236 [(set_attr "type" "frndint")
15237 (set_attr "i387_cw" "mask_pm")
15238 (set_attr "mode" "XF")])
15239
15240 (define_expand "nearbyintxf2"
15241 [(parallel [(set (match_operand:XF 0 "register_operand")
15242 (unspec:XF [(match_operand:XF 1 "register_operand")]
15243 UNSPEC_FRNDINT_MASK_PM))
15244 (clobber (reg:CC FLAGS_REG))])]
15245 "TARGET_USE_FANCY_MATH_387
15246 && flag_unsafe_math_optimizations")
15247
15248 (define_expand "nearbyint<mode>2"
15249 [(use (match_operand:MODEF 0 "register_operand"))
15250 (use (match_operand:MODEF 1 "register_operand"))]
15251 "TARGET_USE_FANCY_MATH_387
15252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15253 || TARGET_MIX_SSE_I387)
15254 && flag_unsafe_math_optimizations"
15255 {
15256 rtx op0 = gen_reg_rtx (XFmode);
15257 rtx op1 = gen_reg_rtx (XFmode);
15258
15259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15260 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15261
15262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15263 DONE;
15264 })
15265
15266 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15267 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15268 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15269 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15270 FIST_ROUNDING))
15271 (clobber (reg:CC FLAGS_REG))]
15272 "TARGET_USE_FANCY_MATH_387
15273 && flag_unsafe_math_optimizations
15274 && can_create_pseudo_p ()"
15275 "#"
15276 "&& 1"
15277 [(const_int 0)]
15278 {
15279 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15280
15281 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15282 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15283 if (memory_operand (operands[0], VOIDmode))
15284 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15285 operands[2], operands[3]));
15286 else
15287 {
15288 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15289 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15290 (operands[0], operands[1], operands[2],
15291 operands[3], operands[4]));
15292 }
15293 DONE;
15294 }
15295 [(set_attr "type" "fistp")
15296 (set_attr "i387_cw" "<rounding>")
15297 (set_attr "mode" "<MODE>")])
15298
15299 (define_insn "fistdi2_<rounding>"
15300 [(set (match_operand:DI 0 "memory_operand" "=m")
15301 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15302 FIST_ROUNDING))
15303 (use (match_operand:HI 2 "memory_operand" "m"))
15304 (use (match_operand:HI 3 "memory_operand" "m"))
15305 (clobber (match_scratch:XF 4 "=&1f"))]
15306 "TARGET_USE_FANCY_MATH_387
15307 && flag_unsafe_math_optimizations"
15308 "* return output_fix_trunc (insn, operands, false);"
15309 [(set_attr "type" "fistp")
15310 (set_attr "i387_cw" "<rounding>")
15311 (set_attr "mode" "DI")])
15312
15313 (define_insn "fistdi2_<rounding>_with_temp"
15314 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15315 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15316 FIST_ROUNDING))
15317 (use (match_operand:HI 2 "memory_operand" "m,m"))
15318 (use (match_operand:HI 3 "memory_operand" "m,m"))
15319 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15320 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15321 "TARGET_USE_FANCY_MATH_387
15322 && flag_unsafe_math_optimizations"
15323 "#"
15324 [(set_attr "type" "fistp")
15325 (set_attr "i387_cw" "<rounding>")
15326 (set_attr "mode" "DI")])
15327
15328 (define_split
15329 [(set (match_operand:DI 0 "register_operand")
15330 (unspec:DI [(match_operand:XF 1 "register_operand")]
15331 FIST_ROUNDING))
15332 (use (match_operand:HI 2 "memory_operand"))
15333 (use (match_operand:HI 3 "memory_operand"))
15334 (clobber (match_operand:DI 4 "memory_operand"))
15335 (clobber (match_scratch 5))]
15336 "reload_completed"
15337 [(parallel [(set (match_dup 4)
15338 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15339 (use (match_dup 2))
15340 (use (match_dup 3))
15341 (clobber (match_dup 5))])
15342 (set (match_dup 0) (match_dup 4))])
15343
15344 (define_split
15345 [(set (match_operand:DI 0 "memory_operand")
15346 (unspec:DI [(match_operand:XF 1 "register_operand")]
15347 FIST_ROUNDING))
15348 (use (match_operand:HI 2 "memory_operand"))
15349 (use (match_operand:HI 3 "memory_operand"))
15350 (clobber (match_operand:DI 4 "memory_operand"))
15351 (clobber (match_scratch 5))]
15352 "reload_completed"
15353 [(parallel [(set (match_dup 0)
15354 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15355 (use (match_dup 2))
15356 (use (match_dup 3))
15357 (clobber (match_dup 5))])])
15358
15359 (define_insn "fist<mode>2_<rounding>"
15360 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15361 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15362 FIST_ROUNDING))
15363 (use (match_operand:HI 2 "memory_operand" "m"))
15364 (use (match_operand:HI 3 "memory_operand" "m"))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && flag_unsafe_math_optimizations"
15367 "* return output_fix_trunc (insn, operands, false);"
15368 [(set_attr "type" "fistp")
15369 (set_attr "i387_cw" "<rounding>")
15370 (set_attr "mode" "<MODE>")])
15371
15372 (define_insn "fist<mode>2_<rounding>_with_temp"
15373 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15374 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15375 FIST_ROUNDING))
15376 (use (match_operand:HI 2 "memory_operand" "m,m"))
15377 (use (match_operand:HI 3 "memory_operand" "m,m"))
15378 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15379 "TARGET_USE_FANCY_MATH_387
15380 && flag_unsafe_math_optimizations"
15381 "#"
15382 [(set_attr "type" "fistp")
15383 (set_attr "i387_cw" "<rounding>")
15384 (set_attr "mode" "<MODE>")])
15385
15386 (define_split
15387 [(set (match_operand:SWI24 0 "register_operand")
15388 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15389 FIST_ROUNDING))
15390 (use (match_operand:HI 2 "memory_operand"))
15391 (use (match_operand:HI 3 "memory_operand"))
15392 (clobber (match_operand:SWI24 4 "memory_operand"))]
15393 "reload_completed"
15394 [(parallel [(set (match_dup 4)
15395 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15396 (use (match_dup 2))
15397 (use (match_dup 3))])
15398 (set (match_dup 0) (match_dup 4))])
15399
15400 (define_split
15401 [(set (match_operand:SWI24 0 "memory_operand")
15402 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15403 FIST_ROUNDING))
15404 (use (match_operand:HI 2 "memory_operand"))
15405 (use (match_operand:HI 3 "memory_operand"))
15406 (clobber (match_operand:SWI24 4 "memory_operand"))]
15407 "reload_completed"
15408 [(parallel [(set (match_dup 0)
15409 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15410 (use (match_dup 2))
15411 (use (match_dup 3))])])
15412
15413 (define_expand "l<rounding_insn>xf<mode>2"
15414 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15415 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15416 FIST_ROUNDING))
15417 (clobber (reg:CC FLAGS_REG))])]
15418 "TARGET_USE_FANCY_MATH_387
15419 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15420 && flag_unsafe_math_optimizations")
15421
15422 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15423 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15424 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15425 FIST_ROUNDING))
15426 (clobber (reg:CC FLAGS_REG))])]
15427 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15428 && !flag_trapping_math"
15429 {
15430 if (TARGET_64BIT && optimize_insn_for_size_p ())
15431 FAIL;
15432
15433 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15434 ix86_expand_lfloorceil (operands[0], operands[1], true);
15435 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15436 ix86_expand_lfloorceil (operands[0], operands[1], false);
15437 else
15438 gcc_unreachable ();
15439
15440 DONE;
15441 })
15442
15443 (define_insn "fxam<mode>2_i387"
15444 [(set (match_operand:HI 0 "register_operand" "=a")
15445 (unspec:HI
15446 [(match_operand:X87MODEF 1 "register_operand" "f")]
15447 UNSPEC_FXAM))]
15448 "TARGET_USE_FANCY_MATH_387"
15449 "fxam\n\tfnstsw\t%0"
15450 [(set_attr "type" "multi")
15451 (set_attr "length" "4")
15452 (set_attr "unit" "i387")
15453 (set_attr "mode" "<MODE>")])
15454
15455 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15456 [(set (match_operand:HI 0 "register_operand")
15457 (unspec:HI
15458 [(match_operand:MODEF 1 "memory_operand")]
15459 UNSPEC_FXAM_MEM))]
15460 "TARGET_USE_FANCY_MATH_387
15461 && can_create_pseudo_p ()"
15462 "#"
15463 "&& 1"
15464 [(set (match_dup 2)(match_dup 1))
15465 (set (match_dup 0)
15466 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15467 {
15468 operands[2] = gen_reg_rtx (<MODE>mode);
15469
15470 MEM_VOLATILE_P (operands[1]) = 1;
15471 }
15472 [(set_attr "type" "multi")
15473 (set_attr "unit" "i387")
15474 (set_attr "mode" "<MODE>")])
15475
15476 (define_expand "isinfxf2"
15477 [(use (match_operand:SI 0 "register_operand"))
15478 (use (match_operand:XF 1 "register_operand"))]
15479 "TARGET_USE_FANCY_MATH_387
15480 && ix86_libc_has_function (function_c99_misc)"
15481 {
15482 rtx mask = GEN_INT (0x45);
15483 rtx val = GEN_INT (0x05);
15484
15485 rtx cond;
15486
15487 rtx scratch = gen_reg_rtx (HImode);
15488 rtx res = gen_reg_rtx (QImode);
15489
15490 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15491
15492 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15493 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15494 cond = gen_rtx_fmt_ee (EQ, QImode,
15495 gen_rtx_REG (CCmode, FLAGS_REG),
15496 const0_rtx);
15497 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15498 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15499 DONE;
15500 })
15501
15502 (define_expand "isinf<mode>2"
15503 [(use (match_operand:SI 0 "register_operand"))
15504 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15505 "TARGET_USE_FANCY_MATH_387
15506 && ix86_libc_has_function (function_c99_misc)
15507 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15508 {
15509 rtx mask = GEN_INT (0x45);
15510 rtx val = GEN_INT (0x05);
15511
15512 rtx cond;
15513
15514 rtx scratch = gen_reg_rtx (HImode);
15515 rtx res = gen_reg_rtx (QImode);
15516
15517 /* Remove excess precision by forcing value through memory. */
15518 if (memory_operand (operands[1], VOIDmode))
15519 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15520 else
15521 {
15522 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15523
15524 emit_move_insn (temp, operands[1]);
15525 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15526 }
15527
15528 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15529 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15530 cond = gen_rtx_fmt_ee (EQ, QImode,
15531 gen_rtx_REG (CCmode, FLAGS_REG),
15532 const0_rtx);
15533 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15534 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15535 DONE;
15536 })
15537
15538 (define_expand "signbitxf2"
15539 [(use (match_operand:SI 0 "register_operand"))
15540 (use (match_operand:XF 1 "register_operand"))]
15541 "TARGET_USE_FANCY_MATH_387"
15542 {
15543 rtx scratch = gen_reg_rtx (HImode);
15544
15545 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15546 emit_insn (gen_andsi3 (operands[0],
15547 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15548 DONE;
15549 })
15550
15551 (define_insn "movmsk_df"
15552 [(set (match_operand:SI 0 "register_operand" "=r")
15553 (unspec:SI
15554 [(match_operand:DF 1 "register_operand" "x")]
15555 UNSPEC_MOVMSK))]
15556 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15557 "%vmovmskpd\t{%1, %0|%0, %1}"
15558 [(set_attr "type" "ssemov")
15559 (set_attr "prefix" "maybe_vex")
15560 (set_attr "mode" "DF")])
15561
15562 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15563 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15564 (define_expand "signbitdf2"
15565 [(use (match_operand:SI 0 "register_operand"))
15566 (use (match_operand:DF 1 "register_operand"))]
15567 "TARGET_USE_FANCY_MATH_387
15568 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15569 {
15570 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15571 {
15572 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15573 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15574 }
15575 else
15576 {
15577 rtx scratch = gen_reg_rtx (HImode);
15578
15579 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15580 emit_insn (gen_andsi3 (operands[0],
15581 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15582 }
15583 DONE;
15584 })
15585
15586 (define_expand "signbitsf2"
15587 [(use (match_operand:SI 0 "register_operand"))
15588 (use (match_operand:SF 1 "register_operand"))]
15589 "TARGET_USE_FANCY_MATH_387
15590 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15591 {
15592 rtx scratch = gen_reg_rtx (HImode);
15593
15594 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15595 emit_insn (gen_andsi3 (operands[0],
15596 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15597 DONE;
15598 })
15599 \f
15600 ;; Block operation instructions
15601
15602 (define_insn "cld"
15603 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15604 ""
15605 "cld"
15606 [(set_attr "length" "1")
15607 (set_attr "length_immediate" "0")
15608 (set_attr "modrm" "0")])
15609
15610 (define_expand "movmem<mode>"
15611 [(use (match_operand:BLK 0 "memory_operand"))
15612 (use (match_operand:BLK 1 "memory_operand"))
15613 (use (match_operand:SWI48 2 "nonmemory_operand"))
15614 (use (match_operand:SWI48 3 "const_int_operand"))
15615 (use (match_operand:SI 4 "const_int_operand"))
15616 (use (match_operand:SI 5 "const_int_operand"))
15617 (use (match_operand:SI 6 ""))
15618 (use (match_operand:SI 7 ""))
15619 (use (match_operand:SI 8 ""))]
15620 ""
15621 {
15622 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15623 operands[2], NULL, operands[3],
15624 operands[4], operands[5],
15625 operands[6], operands[7],
15626 operands[8], false))
15627 DONE;
15628 else
15629 FAIL;
15630 })
15631
15632 ;; Most CPUs don't like single string operations
15633 ;; Handle this case here to simplify previous expander.
15634
15635 (define_expand "strmov"
15636 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15637 (set (match_operand 1 "memory_operand") (match_dup 4))
15638 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15639 (clobber (reg:CC FLAGS_REG))])
15640 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15641 (clobber (reg:CC FLAGS_REG))])]
15642 ""
15643 {
15644 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15645
15646 /* If .md ever supports :P for Pmode, these can be directly
15647 in the pattern above. */
15648 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15649 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15650
15651 /* Can't use this if the user has appropriated esi or edi. */
15652 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15653 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15654 {
15655 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15656 operands[2], operands[3],
15657 operands[5], operands[6]));
15658 DONE;
15659 }
15660
15661 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15662 })
15663
15664 (define_expand "strmov_singleop"
15665 [(parallel [(set (match_operand 1 "memory_operand")
15666 (match_operand 3 "memory_operand"))
15667 (set (match_operand 0 "register_operand")
15668 (match_operand 4))
15669 (set (match_operand 2 "register_operand")
15670 (match_operand 5))])]
15671 ""
15672 "ix86_current_function_needs_cld = 1;")
15673
15674 (define_insn "*strmovdi_rex_1"
15675 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15676 (mem:DI (match_operand:P 3 "register_operand" "1")))
15677 (set (match_operand:P 0 "register_operand" "=D")
15678 (plus:P (match_dup 2)
15679 (const_int 8)))
15680 (set (match_operand:P 1 "register_operand" "=S")
15681 (plus:P (match_dup 3)
15682 (const_int 8)))]
15683 "TARGET_64BIT
15684 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15685 "%^movsq"
15686 [(set_attr "type" "str")
15687 (set_attr "memory" "both")
15688 (set_attr "mode" "DI")])
15689
15690 (define_insn "*strmovsi_1"
15691 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15692 (mem:SI (match_operand:P 3 "register_operand" "1")))
15693 (set (match_operand:P 0 "register_operand" "=D")
15694 (plus:P (match_dup 2)
15695 (const_int 4)))
15696 (set (match_operand:P 1 "register_operand" "=S")
15697 (plus:P (match_dup 3)
15698 (const_int 4)))]
15699 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15700 "%^movs{l|d}"
15701 [(set_attr "type" "str")
15702 (set_attr "memory" "both")
15703 (set_attr "mode" "SI")])
15704
15705 (define_insn "*strmovhi_1"
15706 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15707 (mem:HI (match_operand:P 3 "register_operand" "1")))
15708 (set (match_operand:P 0 "register_operand" "=D")
15709 (plus:P (match_dup 2)
15710 (const_int 2)))
15711 (set (match_operand:P 1 "register_operand" "=S")
15712 (plus:P (match_dup 3)
15713 (const_int 2)))]
15714 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15715 "%^movsw"
15716 [(set_attr "type" "str")
15717 (set_attr "memory" "both")
15718 (set_attr "mode" "HI")])
15719
15720 (define_insn "*strmovqi_1"
15721 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15722 (mem:QI (match_operand:P 3 "register_operand" "1")))
15723 (set (match_operand:P 0 "register_operand" "=D")
15724 (plus:P (match_dup 2)
15725 (const_int 1)))
15726 (set (match_operand:P 1 "register_operand" "=S")
15727 (plus:P (match_dup 3)
15728 (const_int 1)))]
15729 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15730 "%^movsb"
15731 [(set_attr "type" "str")
15732 (set_attr "memory" "both")
15733 (set (attr "prefix_rex")
15734 (if_then_else
15735 (match_test "<P:MODE>mode == DImode")
15736 (const_string "0")
15737 (const_string "*")))
15738 (set_attr "mode" "QI")])
15739
15740 (define_expand "rep_mov"
15741 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15742 (set (match_operand 0 "register_operand")
15743 (match_operand 5))
15744 (set (match_operand 2 "register_operand")
15745 (match_operand 6))
15746 (set (match_operand 1 "memory_operand")
15747 (match_operand 3 "memory_operand"))
15748 (use (match_dup 4))])]
15749 ""
15750 "ix86_current_function_needs_cld = 1;")
15751
15752 (define_insn "*rep_movdi_rex64"
15753 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15754 (set (match_operand:P 0 "register_operand" "=D")
15755 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15756 (const_int 3))
15757 (match_operand:P 3 "register_operand" "0")))
15758 (set (match_operand:P 1 "register_operand" "=S")
15759 (plus:P (ashift:P (match_dup 5) (const_int 3))
15760 (match_operand:P 4 "register_operand" "1")))
15761 (set (mem:BLK (match_dup 3))
15762 (mem:BLK (match_dup 4)))
15763 (use (match_dup 5))]
15764 "TARGET_64BIT
15765 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15766 "%^rep{%;} movsq"
15767 [(set_attr "type" "str")
15768 (set_attr "prefix_rep" "1")
15769 (set_attr "memory" "both")
15770 (set_attr "mode" "DI")])
15771
15772 (define_insn "*rep_movsi"
15773 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15774 (set (match_operand:P 0 "register_operand" "=D")
15775 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15776 (const_int 2))
15777 (match_operand:P 3 "register_operand" "0")))
15778 (set (match_operand:P 1 "register_operand" "=S")
15779 (plus:P (ashift:P (match_dup 5) (const_int 2))
15780 (match_operand:P 4 "register_operand" "1")))
15781 (set (mem:BLK (match_dup 3))
15782 (mem:BLK (match_dup 4)))
15783 (use (match_dup 5))]
15784 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15785 "%^rep{%;} movs{l|d}"
15786 [(set_attr "type" "str")
15787 (set_attr "prefix_rep" "1")
15788 (set_attr "memory" "both")
15789 (set_attr "mode" "SI")])
15790
15791 (define_insn "*rep_movqi"
15792 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15793 (set (match_operand:P 0 "register_operand" "=D")
15794 (plus:P (match_operand:P 3 "register_operand" "0")
15795 (match_operand:P 5 "register_operand" "2")))
15796 (set (match_operand:P 1 "register_operand" "=S")
15797 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15798 (set (mem:BLK (match_dup 3))
15799 (mem:BLK (match_dup 4)))
15800 (use (match_dup 5))]
15801 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15802 "%^rep{%;} movsb"
15803 [(set_attr "type" "str")
15804 (set_attr "prefix_rep" "1")
15805 (set_attr "memory" "both")
15806 (set_attr "mode" "QI")])
15807
15808 (define_expand "setmem<mode>"
15809 [(use (match_operand:BLK 0 "memory_operand"))
15810 (use (match_operand:SWI48 1 "nonmemory_operand"))
15811 (use (match_operand:QI 2 "nonmemory_operand"))
15812 (use (match_operand 3 "const_int_operand"))
15813 (use (match_operand:SI 4 "const_int_operand"))
15814 (use (match_operand:SI 5 "const_int_operand"))
15815 (use (match_operand:SI 6 ""))
15816 (use (match_operand:SI 7 ""))
15817 (use (match_operand:SI 8 ""))]
15818 ""
15819 {
15820 if (ix86_expand_set_or_movmem (operands[0], NULL,
15821 operands[1], operands[2],
15822 operands[3], operands[4],
15823 operands[5], operands[6],
15824 operands[7], operands[8], true))
15825 DONE;
15826 else
15827 FAIL;
15828 })
15829
15830 ;; Most CPUs don't like single string operations
15831 ;; Handle this case here to simplify previous expander.
15832
15833 (define_expand "strset"
15834 [(set (match_operand 1 "memory_operand")
15835 (match_operand 2 "register_operand"))
15836 (parallel [(set (match_operand 0 "register_operand")
15837 (match_dup 3))
15838 (clobber (reg:CC FLAGS_REG))])]
15839 ""
15840 {
15841 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15842 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15843
15844 /* If .md ever supports :P for Pmode, this can be directly
15845 in the pattern above. */
15846 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15847 GEN_INT (GET_MODE_SIZE (GET_MODE
15848 (operands[2]))));
15849 /* Can't use this if the user has appropriated eax or edi. */
15850 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15851 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15852 {
15853 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15854 operands[3]));
15855 DONE;
15856 }
15857 })
15858
15859 (define_expand "strset_singleop"
15860 [(parallel [(set (match_operand 1 "memory_operand")
15861 (match_operand 2 "register_operand"))
15862 (set (match_operand 0 "register_operand")
15863 (match_operand 3))
15864 (unspec [(const_int 0)] UNSPEC_STOS)])]
15865 ""
15866 "ix86_current_function_needs_cld = 1;")
15867
15868 (define_insn "*strsetdi_rex_1"
15869 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15870 (match_operand:DI 2 "register_operand" "a"))
15871 (set (match_operand:P 0 "register_operand" "=D")
15872 (plus:P (match_dup 1)
15873 (const_int 8)))
15874 (unspec [(const_int 0)] UNSPEC_STOS)]
15875 "TARGET_64BIT
15876 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15877 "%^stosq"
15878 [(set_attr "type" "str")
15879 (set_attr "memory" "store")
15880 (set_attr "mode" "DI")])
15881
15882 (define_insn "*strsetsi_1"
15883 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15884 (match_operand:SI 2 "register_operand" "a"))
15885 (set (match_operand:P 0 "register_operand" "=D")
15886 (plus:P (match_dup 1)
15887 (const_int 4)))
15888 (unspec [(const_int 0)] UNSPEC_STOS)]
15889 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15890 "%^stos{l|d}"
15891 [(set_attr "type" "str")
15892 (set_attr "memory" "store")
15893 (set_attr "mode" "SI")])
15894
15895 (define_insn "*strsethi_1"
15896 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15897 (match_operand:HI 2 "register_operand" "a"))
15898 (set (match_operand:P 0 "register_operand" "=D")
15899 (plus:P (match_dup 1)
15900 (const_int 2)))
15901 (unspec [(const_int 0)] UNSPEC_STOS)]
15902 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15903 "%^stosw"
15904 [(set_attr "type" "str")
15905 (set_attr "memory" "store")
15906 (set_attr "mode" "HI")])
15907
15908 (define_insn "*strsetqi_1"
15909 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15910 (match_operand:QI 2 "register_operand" "a"))
15911 (set (match_operand:P 0 "register_operand" "=D")
15912 (plus:P (match_dup 1)
15913 (const_int 1)))
15914 (unspec [(const_int 0)] UNSPEC_STOS)]
15915 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15916 "%^stosb"
15917 [(set_attr "type" "str")
15918 (set_attr "memory" "store")
15919 (set (attr "prefix_rex")
15920 (if_then_else
15921 (match_test "<P:MODE>mode == DImode")
15922 (const_string "0")
15923 (const_string "*")))
15924 (set_attr "mode" "QI")])
15925
15926 (define_expand "rep_stos"
15927 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15928 (set (match_operand 0 "register_operand")
15929 (match_operand 4))
15930 (set (match_operand 2 "memory_operand") (const_int 0))
15931 (use (match_operand 3 "register_operand"))
15932 (use (match_dup 1))])]
15933 ""
15934 "ix86_current_function_needs_cld = 1;")
15935
15936 (define_insn "*rep_stosdi_rex64"
15937 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15938 (set (match_operand:P 0 "register_operand" "=D")
15939 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15940 (const_int 3))
15941 (match_operand:P 3 "register_operand" "0")))
15942 (set (mem:BLK (match_dup 3))
15943 (const_int 0))
15944 (use (match_operand:DI 2 "register_operand" "a"))
15945 (use (match_dup 4))]
15946 "TARGET_64BIT
15947 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15948 "%^rep{%;} stosq"
15949 [(set_attr "type" "str")
15950 (set_attr "prefix_rep" "1")
15951 (set_attr "memory" "store")
15952 (set_attr "mode" "DI")])
15953
15954 (define_insn "*rep_stossi"
15955 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15956 (set (match_operand:P 0 "register_operand" "=D")
15957 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15958 (const_int 2))
15959 (match_operand:P 3 "register_operand" "0")))
15960 (set (mem:BLK (match_dup 3))
15961 (const_int 0))
15962 (use (match_operand:SI 2 "register_operand" "a"))
15963 (use (match_dup 4))]
15964 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15965 "%^rep{%;} stos{l|d}"
15966 [(set_attr "type" "str")
15967 (set_attr "prefix_rep" "1")
15968 (set_attr "memory" "store")
15969 (set_attr "mode" "SI")])
15970
15971 (define_insn "*rep_stosqi"
15972 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15973 (set (match_operand:P 0 "register_operand" "=D")
15974 (plus:P (match_operand:P 3 "register_operand" "0")
15975 (match_operand:P 4 "register_operand" "1")))
15976 (set (mem:BLK (match_dup 3))
15977 (const_int 0))
15978 (use (match_operand:QI 2 "register_operand" "a"))
15979 (use (match_dup 4))]
15980 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15981 "%^rep{%;} stosb"
15982 [(set_attr "type" "str")
15983 (set_attr "prefix_rep" "1")
15984 (set_attr "memory" "store")
15985 (set (attr "prefix_rex")
15986 (if_then_else
15987 (match_test "<P:MODE>mode == DImode")
15988 (const_string "0")
15989 (const_string "*")))
15990 (set_attr "mode" "QI")])
15991
15992 (define_expand "cmpstrnsi"
15993 [(set (match_operand:SI 0 "register_operand")
15994 (compare:SI (match_operand:BLK 1 "general_operand")
15995 (match_operand:BLK 2 "general_operand")))
15996 (use (match_operand 3 "general_operand"))
15997 (use (match_operand 4 "immediate_operand"))]
15998 ""
15999 {
16000 rtx addr1, addr2, out, outlow, count, countreg, align;
16001
16002 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16003 FAIL;
16004
16005 /* Can't use this if the user has appropriated ecx, esi or edi. */
16006 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16007 FAIL;
16008
16009 out = operands[0];
16010 if (!REG_P (out))
16011 out = gen_reg_rtx (SImode);
16012
16013 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16014 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16015 if (addr1 != XEXP (operands[1], 0))
16016 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16017 if (addr2 != XEXP (operands[2], 0))
16018 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16019
16020 count = operands[3];
16021 countreg = ix86_zero_extend_to_Pmode (count);
16022
16023 /* %%% Iff we are testing strict equality, we can use known alignment
16024 to good advantage. This may be possible with combine, particularly
16025 once cc0 is dead. */
16026 align = operands[4];
16027
16028 if (CONST_INT_P (count))
16029 {
16030 if (INTVAL (count) == 0)
16031 {
16032 emit_move_insn (operands[0], const0_rtx);
16033 DONE;
16034 }
16035 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16036 operands[1], operands[2]));
16037 }
16038 else
16039 {
16040 rtx (*gen_cmp) (rtx, rtx);
16041
16042 gen_cmp = (TARGET_64BIT
16043 ? gen_cmpdi_1 : gen_cmpsi_1);
16044
16045 emit_insn (gen_cmp (countreg, countreg));
16046 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16047 operands[1], operands[2]));
16048 }
16049
16050 outlow = gen_lowpart (QImode, out);
16051 emit_insn (gen_cmpintqi (outlow));
16052 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16053
16054 if (operands[0] != out)
16055 emit_move_insn (operands[0], out);
16056
16057 DONE;
16058 })
16059
16060 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16061
16062 (define_expand "cmpintqi"
16063 [(set (match_dup 1)
16064 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16065 (set (match_dup 2)
16066 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16067 (parallel [(set (match_operand:QI 0 "register_operand")
16068 (minus:QI (match_dup 1)
16069 (match_dup 2)))
16070 (clobber (reg:CC FLAGS_REG))])]
16071 ""
16072 {
16073 operands[1] = gen_reg_rtx (QImode);
16074 operands[2] = gen_reg_rtx (QImode);
16075 })
16076
16077 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16078 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16079
16080 (define_expand "cmpstrnqi_nz_1"
16081 [(parallel [(set (reg:CC FLAGS_REG)
16082 (compare:CC (match_operand 4 "memory_operand")
16083 (match_operand 5 "memory_operand")))
16084 (use (match_operand 2 "register_operand"))
16085 (use (match_operand:SI 3 "immediate_operand"))
16086 (clobber (match_operand 0 "register_operand"))
16087 (clobber (match_operand 1 "register_operand"))
16088 (clobber (match_dup 2))])]
16089 ""
16090 "ix86_current_function_needs_cld = 1;")
16091
16092 (define_insn "*cmpstrnqi_nz_1"
16093 [(set (reg:CC FLAGS_REG)
16094 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16095 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16096 (use (match_operand:P 6 "register_operand" "2"))
16097 (use (match_operand:SI 3 "immediate_operand" "i"))
16098 (clobber (match_operand:P 0 "register_operand" "=S"))
16099 (clobber (match_operand:P 1 "register_operand" "=D"))
16100 (clobber (match_operand:P 2 "register_operand" "=c"))]
16101 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16102 "%^repz{%;} cmpsb"
16103 [(set_attr "type" "str")
16104 (set_attr "mode" "QI")
16105 (set (attr "prefix_rex")
16106 (if_then_else
16107 (match_test "<P:MODE>mode == DImode")
16108 (const_string "0")
16109 (const_string "*")))
16110 (set_attr "prefix_rep" "1")])
16111
16112 ;; The same, but the count is not known to not be zero.
16113
16114 (define_expand "cmpstrnqi_1"
16115 [(parallel [(set (reg:CC FLAGS_REG)
16116 (if_then_else:CC (ne (match_operand 2 "register_operand")
16117 (const_int 0))
16118 (compare:CC (match_operand 4 "memory_operand")
16119 (match_operand 5 "memory_operand"))
16120 (const_int 0)))
16121 (use (match_operand:SI 3 "immediate_operand"))
16122 (use (reg:CC FLAGS_REG))
16123 (clobber (match_operand 0 "register_operand"))
16124 (clobber (match_operand 1 "register_operand"))
16125 (clobber (match_dup 2))])]
16126 ""
16127 "ix86_current_function_needs_cld = 1;")
16128
16129 (define_insn "*cmpstrnqi_1"
16130 [(set (reg:CC FLAGS_REG)
16131 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16132 (const_int 0))
16133 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16134 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16135 (const_int 0)))
16136 (use (match_operand:SI 3 "immediate_operand" "i"))
16137 (use (reg:CC FLAGS_REG))
16138 (clobber (match_operand:P 0 "register_operand" "=S"))
16139 (clobber (match_operand:P 1 "register_operand" "=D"))
16140 (clobber (match_operand:P 2 "register_operand" "=c"))]
16141 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16142 "%^repz{%;} cmpsb"
16143 [(set_attr "type" "str")
16144 (set_attr "mode" "QI")
16145 (set (attr "prefix_rex")
16146 (if_then_else
16147 (match_test "<P:MODE>mode == DImode")
16148 (const_string "0")
16149 (const_string "*")))
16150 (set_attr "prefix_rep" "1")])
16151
16152 (define_expand "strlen<mode>"
16153 [(set (match_operand:P 0 "register_operand")
16154 (unspec:P [(match_operand:BLK 1 "general_operand")
16155 (match_operand:QI 2 "immediate_operand")
16156 (match_operand 3 "immediate_operand")]
16157 UNSPEC_SCAS))]
16158 ""
16159 {
16160 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16161 DONE;
16162 else
16163 FAIL;
16164 })
16165
16166 (define_expand "strlenqi_1"
16167 [(parallel [(set (match_operand 0 "register_operand")
16168 (match_operand 2))
16169 (clobber (match_operand 1 "register_operand"))
16170 (clobber (reg:CC FLAGS_REG))])]
16171 ""
16172 "ix86_current_function_needs_cld = 1;")
16173
16174 (define_insn "*strlenqi_1"
16175 [(set (match_operand:P 0 "register_operand" "=&c")
16176 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16177 (match_operand:QI 2 "register_operand" "a")
16178 (match_operand:P 3 "immediate_operand" "i")
16179 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16180 (clobber (match_operand:P 1 "register_operand" "=D"))
16181 (clobber (reg:CC FLAGS_REG))]
16182 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16183 "%^repnz{%;} scasb"
16184 [(set_attr "type" "str")
16185 (set_attr "mode" "QI")
16186 (set (attr "prefix_rex")
16187 (if_then_else
16188 (match_test "<P:MODE>mode == DImode")
16189 (const_string "0")
16190 (const_string "*")))
16191 (set_attr "prefix_rep" "1")])
16192
16193 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16194 ;; handled in combine, but it is not currently up to the task.
16195 ;; When used for their truth value, the cmpstrn* expanders generate
16196 ;; code like this:
16197 ;;
16198 ;; repz cmpsb
16199 ;; seta %al
16200 ;; setb %dl
16201 ;; cmpb %al, %dl
16202 ;; jcc label
16203 ;;
16204 ;; The intermediate three instructions are unnecessary.
16205
16206 ;; This one handles cmpstrn*_nz_1...
16207 (define_peephole2
16208 [(parallel[
16209 (set (reg:CC FLAGS_REG)
16210 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16211 (mem:BLK (match_operand 5 "register_operand"))))
16212 (use (match_operand 6 "register_operand"))
16213 (use (match_operand:SI 3 "immediate_operand"))
16214 (clobber (match_operand 0 "register_operand"))
16215 (clobber (match_operand 1 "register_operand"))
16216 (clobber (match_operand 2 "register_operand"))])
16217 (set (match_operand:QI 7 "register_operand")
16218 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16219 (set (match_operand:QI 8 "register_operand")
16220 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16221 (set (reg FLAGS_REG)
16222 (compare (match_dup 7) (match_dup 8)))
16223 ]
16224 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16225 [(parallel[
16226 (set (reg:CC FLAGS_REG)
16227 (compare:CC (mem:BLK (match_dup 4))
16228 (mem:BLK (match_dup 5))))
16229 (use (match_dup 6))
16230 (use (match_dup 3))
16231 (clobber (match_dup 0))
16232 (clobber (match_dup 1))
16233 (clobber (match_dup 2))])])
16234
16235 ;; ...and this one handles cmpstrn*_1.
16236 (define_peephole2
16237 [(parallel[
16238 (set (reg:CC FLAGS_REG)
16239 (if_then_else:CC (ne (match_operand 6 "register_operand")
16240 (const_int 0))
16241 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16242 (mem:BLK (match_operand 5 "register_operand")))
16243 (const_int 0)))
16244 (use (match_operand:SI 3 "immediate_operand"))
16245 (use (reg:CC FLAGS_REG))
16246 (clobber (match_operand 0 "register_operand"))
16247 (clobber (match_operand 1 "register_operand"))
16248 (clobber (match_operand 2 "register_operand"))])
16249 (set (match_operand:QI 7 "register_operand")
16250 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16251 (set (match_operand:QI 8 "register_operand")
16252 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16253 (set (reg FLAGS_REG)
16254 (compare (match_dup 7) (match_dup 8)))
16255 ]
16256 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16257 [(parallel[
16258 (set (reg:CC FLAGS_REG)
16259 (if_then_else:CC (ne (match_dup 6)
16260 (const_int 0))
16261 (compare:CC (mem:BLK (match_dup 4))
16262 (mem:BLK (match_dup 5)))
16263 (const_int 0)))
16264 (use (match_dup 3))
16265 (use (reg:CC FLAGS_REG))
16266 (clobber (match_dup 0))
16267 (clobber (match_dup 1))
16268 (clobber (match_dup 2))])])
16269 \f
16270 ;; Conditional move instructions.
16271
16272 (define_expand "mov<mode>cc"
16273 [(set (match_operand:SWIM 0 "register_operand")
16274 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16275 (match_operand:SWIM 2 "<general_operand>")
16276 (match_operand:SWIM 3 "<general_operand>")))]
16277 ""
16278 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16279
16280 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16281 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16282 ;; So just document what we're doing explicitly.
16283
16284 (define_expand "x86_mov<mode>cc_0_m1"
16285 [(parallel
16286 [(set (match_operand:SWI48 0 "register_operand")
16287 (if_then_else:SWI48
16288 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16289 [(match_operand 1 "flags_reg_operand")
16290 (const_int 0)])
16291 (const_int -1)
16292 (const_int 0)))
16293 (clobber (reg:CC FLAGS_REG))])])
16294
16295 (define_insn "*x86_mov<mode>cc_0_m1"
16296 [(set (match_operand:SWI48 0 "register_operand" "=r")
16297 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16298 [(reg FLAGS_REG) (const_int 0)])
16299 (const_int -1)
16300 (const_int 0)))
16301 (clobber (reg:CC FLAGS_REG))]
16302 ""
16303 "sbb{<imodesuffix>}\t%0, %0"
16304 ; Since we don't have the proper number of operands for an alu insn,
16305 ; fill in all the blanks.
16306 [(set_attr "type" "alu")
16307 (set_attr "use_carry" "1")
16308 (set_attr "pent_pair" "pu")
16309 (set_attr "memory" "none")
16310 (set_attr "imm_disp" "false")
16311 (set_attr "mode" "<MODE>")
16312 (set_attr "length_immediate" "0")])
16313
16314 (define_insn "*x86_mov<mode>cc_0_m1_se"
16315 [(set (match_operand:SWI48 0 "register_operand" "=r")
16316 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16317 [(reg FLAGS_REG) (const_int 0)])
16318 (const_int 1)
16319 (const_int 0)))
16320 (clobber (reg:CC FLAGS_REG))]
16321 ""
16322 "sbb{<imodesuffix>}\t%0, %0"
16323 [(set_attr "type" "alu")
16324 (set_attr "use_carry" "1")
16325 (set_attr "pent_pair" "pu")
16326 (set_attr "memory" "none")
16327 (set_attr "imm_disp" "false")
16328 (set_attr "mode" "<MODE>")
16329 (set_attr "length_immediate" "0")])
16330
16331 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16332 [(set (match_operand:SWI48 0 "register_operand" "=r")
16333 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16334 [(reg FLAGS_REG) (const_int 0)])))
16335 (clobber (reg:CC FLAGS_REG))]
16336 ""
16337 "sbb{<imodesuffix>}\t%0, %0"
16338 [(set_attr "type" "alu")
16339 (set_attr "use_carry" "1")
16340 (set_attr "pent_pair" "pu")
16341 (set_attr "memory" "none")
16342 (set_attr "imm_disp" "false")
16343 (set_attr "mode" "<MODE>")
16344 (set_attr "length_immediate" "0")])
16345
16346 (define_insn "*mov<mode>cc_noc"
16347 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16348 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16349 [(reg FLAGS_REG) (const_int 0)])
16350 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16351 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16352 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16353 "@
16354 cmov%O2%C1\t{%2, %0|%0, %2}
16355 cmov%O2%c1\t{%3, %0|%0, %3}"
16356 [(set_attr "type" "icmov")
16357 (set_attr "mode" "<MODE>")])
16358
16359 ;; Don't do conditional moves with memory inputs. This splitter helps
16360 ;; register starved x86_32 by forcing inputs into registers before reload.
16361 (define_split
16362 [(set (match_operand:SWI248 0 "register_operand")
16363 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16364 [(reg FLAGS_REG) (const_int 0)])
16365 (match_operand:SWI248 2 "nonimmediate_operand")
16366 (match_operand:SWI248 3 "nonimmediate_operand")))]
16367 "!TARGET_64BIT && TARGET_CMOVE
16368 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16369 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16370 && can_create_pseudo_p ()
16371 && optimize_insn_for_speed_p ()"
16372 [(set (match_dup 0)
16373 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16374 {
16375 if (MEM_P (operands[2]))
16376 operands[2] = force_reg (<MODE>mode, operands[2]);
16377 if (MEM_P (operands[3]))
16378 operands[3] = force_reg (<MODE>mode, operands[3]);
16379 })
16380
16381 (define_insn "*movqicc_noc"
16382 [(set (match_operand:QI 0 "register_operand" "=r,r")
16383 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16384 [(reg FLAGS_REG) (const_int 0)])
16385 (match_operand:QI 2 "register_operand" "r,0")
16386 (match_operand:QI 3 "register_operand" "0,r")))]
16387 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16388 "#"
16389 [(set_attr "type" "icmov")
16390 (set_attr "mode" "QI")])
16391
16392 (define_split
16393 [(set (match_operand:SWI12 0 "register_operand")
16394 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16395 [(reg FLAGS_REG) (const_int 0)])
16396 (match_operand:SWI12 2 "register_operand")
16397 (match_operand:SWI12 3 "register_operand")))]
16398 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16399 && reload_completed"
16400 [(set (match_dup 0)
16401 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16402 {
16403 operands[0] = gen_lowpart (SImode, operands[0]);
16404 operands[2] = gen_lowpart (SImode, operands[2]);
16405 operands[3] = gen_lowpart (SImode, operands[3]);
16406 })
16407
16408 ;; Don't do conditional moves with memory inputs
16409 (define_peephole2
16410 [(match_scratch:SWI248 2 "r")
16411 (set (match_operand:SWI248 0 "register_operand")
16412 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16413 [(reg FLAGS_REG) (const_int 0)])
16414 (match_dup 0)
16415 (match_operand:SWI248 3 "memory_operand")))]
16416 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16417 && optimize_insn_for_speed_p ()"
16418 [(set (match_dup 2) (match_dup 3))
16419 (set (match_dup 0)
16420 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16421
16422 (define_peephole2
16423 [(match_scratch:SWI248 2 "r")
16424 (set (match_operand:SWI248 0 "register_operand")
16425 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16426 [(reg FLAGS_REG) (const_int 0)])
16427 (match_operand:SWI248 3 "memory_operand")
16428 (match_dup 0)))]
16429 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16430 && optimize_insn_for_speed_p ()"
16431 [(set (match_dup 2) (match_dup 3))
16432 (set (match_dup 0)
16433 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16434
16435 (define_expand "mov<mode>cc"
16436 [(set (match_operand:X87MODEF 0 "register_operand")
16437 (if_then_else:X87MODEF
16438 (match_operand 1 "comparison_operator")
16439 (match_operand:X87MODEF 2 "register_operand")
16440 (match_operand:X87MODEF 3 "register_operand")))]
16441 "(TARGET_80387 && TARGET_CMOVE)
16442 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16443 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16444
16445 (define_insn "*movxfcc_1"
16446 [(set (match_operand:XF 0 "register_operand" "=f,f")
16447 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16448 [(reg FLAGS_REG) (const_int 0)])
16449 (match_operand:XF 2 "register_operand" "f,0")
16450 (match_operand:XF 3 "register_operand" "0,f")))]
16451 "TARGET_80387 && TARGET_CMOVE"
16452 "@
16453 fcmov%F1\t{%2, %0|%0, %2}
16454 fcmov%f1\t{%3, %0|%0, %3}"
16455 [(set_attr "type" "fcmov")
16456 (set_attr "mode" "XF")])
16457
16458 (define_insn "*movdfcc_1"
16459 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16460 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16461 [(reg FLAGS_REG) (const_int 0)])
16462 (match_operand:DF 2 "nonimmediate_operand"
16463 "f ,0,rm,0 ,rm,0")
16464 (match_operand:DF 3 "nonimmediate_operand"
16465 "0 ,f,0 ,rm,0, rm")))]
16466 "TARGET_80387 && TARGET_CMOVE
16467 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16468 "@
16469 fcmov%F1\t{%2, %0|%0, %2}
16470 fcmov%f1\t{%3, %0|%0, %3}
16471 #
16472 #
16473 cmov%O2%C1\t{%2, %0|%0, %2}
16474 cmov%O2%c1\t{%3, %0|%0, %3}"
16475 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16476 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16477 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16478
16479 (define_split
16480 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16481 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16482 [(reg FLAGS_REG) (const_int 0)])
16483 (match_operand:DF 2 "nonimmediate_operand")
16484 (match_operand:DF 3 "nonimmediate_operand")))]
16485 "!TARGET_64BIT && reload_completed"
16486 [(set (match_dup 2)
16487 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16488 (set (match_dup 3)
16489 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16490 {
16491 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16492 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16493 })
16494
16495 (define_insn "*movsfcc_1_387"
16496 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16497 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16498 [(reg FLAGS_REG) (const_int 0)])
16499 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16500 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16501 "TARGET_80387 && TARGET_CMOVE
16502 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16503 "@
16504 fcmov%F1\t{%2, %0|%0, %2}
16505 fcmov%f1\t{%3, %0|%0, %3}
16506 cmov%O2%C1\t{%2, %0|%0, %2}
16507 cmov%O2%c1\t{%3, %0|%0, %3}"
16508 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16509 (set_attr "mode" "SF,SF,SI,SI")])
16510
16511 ;; Don't do conditional moves with memory inputs. This splitter helps
16512 ;; register starved x86_32 by forcing inputs into registers before reload.
16513 (define_split
16514 [(set (match_operand:MODEF 0 "register_operand")
16515 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16516 [(reg FLAGS_REG) (const_int 0)])
16517 (match_operand:MODEF 2 "nonimmediate_operand")
16518 (match_operand:MODEF 3 "nonimmediate_operand")))]
16519 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16520 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16521 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16522 && can_create_pseudo_p ()
16523 && optimize_insn_for_speed_p ()"
16524 [(set (match_dup 0)
16525 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16526 {
16527 if (MEM_P (operands[2]))
16528 operands[2] = force_reg (<MODE>mode, operands[2]);
16529 if (MEM_P (operands[3]))
16530 operands[3] = force_reg (<MODE>mode, operands[3]);
16531 })
16532
16533 ;; Don't do conditional moves with memory inputs
16534 (define_peephole2
16535 [(match_scratch:MODEF 2 "r")
16536 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16537 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16538 [(reg FLAGS_REG) (const_int 0)])
16539 (match_dup 0)
16540 (match_operand:MODEF 3 "memory_operand")))]
16541 "(<MODE>mode != DFmode || TARGET_64BIT)
16542 && TARGET_80387 && TARGET_CMOVE
16543 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16544 && optimize_insn_for_speed_p ()"
16545 [(set (match_dup 2) (match_dup 3))
16546 (set (match_dup 0)
16547 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16548
16549 (define_peephole2
16550 [(match_scratch:MODEF 2 "r")
16551 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16552 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16553 [(reg FLAGS_REG) (const_int 0)])
16554 (match_operand:MODEF 3 "memory_operand")
16555 (match_dup 0)))]
16556 "(<MODE>mode != DFmode || TARGET_64BIT)
16557 && TARGET_80387 && TARGET_CMOVE
16558 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16559 && optimize_insn_for_speed_p ()"
16560 [(set (match_dup 2) (match_dup 3))
16561 (set (match_dup 0)
16562 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16563
16564 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16565 ;; the scalar versions to have only XMM registers as operands.
16566
16567 ;; XOP conditional move
16568 (define_insn "*xop_pcmov_<mode>"
16569 [(set (match_operand:MODEF 0 "register_operand" "=x")
16570 (if_then_else:MODEF
16571 (match_operand:MODEF 1 "register_operand" "x")
16572 (match_operand:MODEF 2 "register_operand" "x")
16573 (match_operand:MODEF 3 "register_operand" "x")))]
16574 "TARGET_XOP"
16575 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16576 [(set_attr "type" "sse4arg")])
16577
16578 ;; These versions of the min/max patterns are intentionally ignorant of
16579 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16580 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16581 ;; are undefined in this condition, we're certain this is correct.
16582
16583 (define_insn "<code><mode>3"
16584 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16585 (smaxmin:MODEF
16586 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16587 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16588 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16589 "@
16590 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16591 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16592 [(set_attr "isa" "noavx,avx")
16593 (set_attr "prefix" "orig,vex")
16594 (set_attr "type" "sseadd")
16595 (set_attr "mode" "<MODE>")])
16596
16597 ;; These versions of the min/max patterns implement exactly the operations
16598 ;; min = (op1 < op2 ? op1 : op2)
16599 ;; max = (!(op1 < op2) ? op1 : op2)
16600 ;; Their operands are not commutative, and thus they may be used in the
16601 ;; presence of -0.0 and NaN.
16602
16603 (define_int_iterator IEEE_MAXMIN
16604 [UNSPEC_IEEE_MAX
16605 UNSPEC_IEEE_MIN])
16606
16607 (define_int_attr ieee_maxmin
16608 [(UNSPEC_IEEE_MAX "max")
16609 (UNSPEC_IEEE_MIN "min")])
16610
16611 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16612 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16613 (unspec:MODEF
16614 [(match_operand:MODEF 1 "register_operand" "0,x")
16615 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16616 IEEE_MAXMIN))]
16617 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16618 "@
16619 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16620 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16621 [(set_attr "isa" "noavx,avx")
16622 (set_attr "prefix" "orig,vex")
16623 (set_attr "type" "sseadd")
16624 (set_attr "mode" "<MODE>")])
16625
16626 ;; Make two stack loads independent:
16627 ;; fld aa fld aa
16628 ;; fld %st(0) -> fld bb
16629 ;; fmul bb fmul %st(1), %st
16630 ;;
16631 ;; Actually we only match the last two instructions for simplicity.
16632 (define_peephole2
16633 [(set (match_operand 0 "fp_register_operand")
16634 (match_operand 1 "fp_register_operand"))
16635 (set (match_dup 0)
16636 (match_operator 2 "binary_fp_operator"
16637 [(match_dup 0)
16638 (match_operand 3 "memory_operand")]))]
16639 "REGNO (operands[0]) != REGNO (operands[1])"
16640 [(set (match_dup 0) (match_dup 3))
16641 (set (match_dup 0) (match_dup 4))]
16642
16643 ;; The % modifier is not operational anymore in peephole2's, so we have to
16644 ;; swap the operands manually in the case of addition and multiplication.
16645 {
16646 rtx op0, op1;
16647
16648 if (COMMUTATIVE_ARITH_P (operands[2]))
16649 op0 = operands[0], op1 = operands[1];
16650 else
16651 op0 = operands[1], op1 = operands[0];
16652
16653 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16654 GET_MODE (operands[2]),
16655 op0, op1);
16656 })
16657
16658 ;; Conditional addition patterns
16659 (define_expand "add<mode>cc"
16660 [(match_operand:SWI 0 "register_operand")
16661 (match_operand 1 "ordered_comparison_operator")
16662 (match_operand:SWI 2 "register_operand")
16663 (match_operand:SWI 3 "const_int_operand")]
16664 ""
16665 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16666 \f
16667 ;; Misc patterns (?)
16668
16669 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16670 ;; Otherwise there will be nothing to keep
16671 ;;
16672 ;; [(set (reg ebp) (reg esp))]
16673 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16674 ;; (clobber (eflags)]
16675 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16676 ;;
16677 ;; in proper program order.
16678
16679 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16680 [(set (match_operand:P 0 "register_operand" "=r,r")
16681 (plus:P (match_operand:P 1 "register_operand" "0,r")
16682 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16683 (clobber (reg:CC FLAGS_REG))
16684 (clobber (mem:BLK (scratch)))]
16685 ""
16686 {
16687 switch (get_attr_type (insn))
16688 {
16689 case TYPE_IMOV:
16690 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16691
16692 case TYPE_ALU:
16693 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16694 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16695 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16696
16697 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16698
16699 default:
16700 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16701 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16702 }
16703 }
16704 [(set (attr "type")
16705 (cond [(and (eq_attr "alternative" "0")
16706 (not (match_test "TARGET_OPT_AGU")))
16707 (const_string "alu")
16708 (match_operand:<MODE> 2 "const0_operand")
16709 (const_string "imov")
16710 ]
16711 (const_string "lea")))
16712 (set (attr "length_immediate")
16713 (cond [(eq_attr "type" "imov")
16714 (const_string "0")
16715 (and (eq_attr "type" "alu")
16716 (match_operand 2 "const128_operand"))
16717 (const_string "1")
16718 ]
16719 (const_string "*")))
16720 (set_attr "mode" "<MODE>")])
16721
16722 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16723 [(set (match_operand:P 0 "register_operand" "=r")
16724 (minus:P (match_operand:P 1 "register_operand" "0")
16725 (match_operand:P 2 "register_operand" "r")))
16726 (clobber (reg:CC FLAGS_REG))
16727 (clobber (mem:BLK (scratch)))]
16728 ""
16729 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16730 [(set_attr "type" "alu")
16731 (set_attr "mode" "<MODE>")])
16732
16733 (define_insn "allocate_stack_worker_probe_<mode>"
16734 [(set (match_operand:P 0 "register_operand" "=a")
16735 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16736 UNSPECV_STACK_PROBE))
16737 (clobber (reg:CC FLAGS_REG))]
16738 "ix86_target_stack_probe ()"
16739 "call\t___chkstk_ms"
16740 [(set_attr "type" "multi")
16741 (set_attr "length" "5")])
16742
16743 (define_expand "allocate_stack"
16744 [(match_operand 0 "register_operand")
16745 (match_operand 1 "general_operand")]
16746 "ix86_target_stack_probe ()"
16747 {
16748 rtx x;
16749
16750 #ifndef CHECK_STACK_LIMIT
16751 #define CHECK_STACK_LIMIT 0
16752 #endif
16753
16754 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16755 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16756 x = operands[1];
16757 else
16758 {
16759 rtx (*insn) (rtx, rtx);
16760
16761 x = copy_to_mode_reg (Pmode, operands[1]);
16762
16763 insn = (TARGET_64BIT
16764 ? gen_allocate_stack_worker_probe_di
16765 : gen_allocate_stack_worker_probe_si);
16766
16767 emit_insn (insn (x, x));
16768 }
16769
16770 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16771 stack_pointer_rtx, 0, OPTAB_DIRECT);
16772
16773 if (x != stack_pointer_rtx)
16774 emit_move_insn (stack_pointer_rtx, x);
16775
16776 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16777 DONE;
16778 })
16779
16780 ;; Use IOR for stack probes, this is shorter.
16781 (define_expand "probe_stack"
16782 [(match_operand 0 "memory_operand")]
16783 ""
16784 {
16785 rtx (*gen_ior3) (rtx, rtx, rtx);
16786
16787 gen_ior3 = (GET_MODE (operands[0]) == DImode
16788 ? gen_iordi3 : gen_iorsi3);
16789
16790 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16791 DONE;
16792 })
16793
16794 (define_insn "adjust_stack_and_probe<mode>"
16795 [(set (match_operand:P 0 "register_operand" "=r")
16796 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16797 UNSPECV_PROBE_STACK_RANGE))
16798 (set (reg:P SP_REG)
16799 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16800 (clobber (reg:CC FLAGS_REG))
16801 (clobber (mem:BLK (scratch)))]
16802 ""
16803 "* return output_adjust_stack_and_probe (operands[0]);"
16804 [(set_attr "type" "multi")])
16805
16806 (define_insn "probe_stack_range<mode>"
16807 [(set (match_operand:P 0 "register_operand" "=r")
16808 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16809 (match_operand:P 2 "const_int_operand" "n")]
16810 UNSPECV_PROBE_STACK_RANGE))
16811 (clobber (reg:CC FLAGS_REG))]
16812 ""
16813 "* return output_probe_stack_range (operands[0], operands[2]);"
16814 [(set_attr "type" "multi")])
16815
16816 (define_expand "builtin_setjmp_receiver"
16817 [(label_ref (match_operand 0))]
16818 "!TARGET_64BIT && flag_pic"
16819 {
16820 #if TARGET_MACHO
16821 if (TARGET_MACHO)
16822 {
16823 rtx xops[3];
16824 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16825 rtx label_rtx = gen_label_rtx ();
16826 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16827 xops[0] = xops[1] = picreg;
16828 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16829 ix86_expand_binary_operator (MINUS, SImode, xops);
16830 }
16831 else
16832 #endif
16833 emit_insn (gen_set_got (pic_offset_table_rtx));
16834 DONE;
16835 })
16836
16837 (define_insn_and_split "nonlocal_goto_receiver"
16838 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16839 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16840 "#"
16841 "&& reload_completed"
16842 [(const_int 0)]
16843 {
16844 if (crtl->uses_pic_offset_table)
16845 {
16846 rtx xops[3];
16847 rtx label_rtx = gen_label_rtx ();
16848 rtx tmp;
16849
16850 /* Get a new pic base. */
16851 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16852 /* Correct this with the offset from the new to the old. */
16853 xops[0] = xops[1] = pic_offset_table_rtx;
16854 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16855 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16856 UNSPEC_MACHOPIC_OFFSET);
16857 xops[2] = gen_rtx_CONST (Pmode, tmp);
16858 ix86_expand_binary_operator (MINUS, SImode, xops);
16859 }
16860 else
16861 /* No pic reg restore needed. */
16862 emit_note (NOTE_INSN_DELETED);
16863
16864 DONE;
16865 })
16866
16867 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16868 ;; Do not split instructions with mask registers.
16869 (define_split
16870 [(set (match_operand 0 "general_reg_operand")
16871 (match_operator 3 "promotable_binary_operator"
16872 [(match_operand 1 "general_reg_operand")
16873 (match_operand 2 "aligned_operand")]))
16874 (clobber (reg:CC FLAGS_REG))]
16875 "! TARGET_PARTIAL_REG_STALL && reload_completed
16876 && ((GET_MODE (operands[0]) == HImode
16877 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16878 /* ??? next two lines just !satisfies_constraint_K (...) */
16879 || !CONST_INT_P (operands[2])
16880 || satisfies_constraint_K (operands[2])))
16881 || (GET_MODE (operands[0]) == QImode
16882 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16883 [(parallel [(set (match_dup 0)
16884 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16885 (clobber (reg:CC FLAGS_REG))])]
16886 {
16887 operands[0] = gen_lowpart (SImode, operands[0]);
16888 operands[1] = gen_lowpart (SImode, operands[1]);
16889 if (GET_CODE (operands[3]) != ASHIFT)
16890 operands[2] = gen_lowpart (SImode, operands[2]);
16891 PUT_MODE (operands[3], SImode);
16892 })
16893
16894 ; Promote the QImode tests, as i386 has encoding of the AND
16895 ; instruction with 32-bit sign-extended immediate and thus the
16896 ; instruction size is unchanged, except in the %eax case for
16897 ; which it is increased by one byte, hence the ! optimize_size.
16898 (define_split
16899 [(set (match_operand 0 "flags_reg_operand")
16900 (match_operator 2 "compare_operator"
16901 [(and (match_operand 3 "aligned_operand")
16902 (match_operand 4 "const_int_operand"))
16903 (const_int 0)]))
16904 (set (match_operand 1 "register_operand")
16905 (and (match_dup 3) (match_dup 4)))]
16906 "! TARGET_PARTIAL_REG_STALL && reload_completed
16907 && optimize_insn_for_speed_p ()
16908 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16909 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16910 /* Ensure that the operand will remain sign-extended immediate. */
16911 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16912 [(parallel [(set (match_dup 0)
16913 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16914 (const_int 0)]))
16915 (set (match_dup 1)
16916 (and:SI (match_dup 3) (match_dup 4)))])]
16917 {
16918 operands[4]
16919 = gen_int_mode (INTVAL (operands[4])
16920 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16921 operands[1] = gen_lowpart (SImode, operands[1]);
16922 operands[3] = gen_lowpart (SImode, operands[3]);
16923 })
16924
16925 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16926 ; the TEST instruction with 32-bit sign-extended immediate and thus
16927 ; the instruction size would at least double, which is not what we
16928 ; want even with ! optimize_size.
16929 (define_split
16930 [(set (match_operand 0 "flags_reg_operand")
16931 (match_operator 1 "compare_operator"
16932 [(and (match_operand:HI 2 "aligned_operand")
16933 (match_operand:HI 3 "const_int_operand"))
16934 (const_int 0)]))]
16935 "! TARGET_PARTIAL_REG_STALL && reload_completed
16936 && ! TARGET_FAST_PREFIX
16937 && optimize_insn_for_speed_p ()
16938 /* Ensure that the operand will remain sign-extended immediate. */
16939 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16940 [(set (match_dup 0)
16941 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16942 (const_int 0)]))]
16943 {
16944 operands[3]
16945 = gen_int_mode (INTVAL (operands[3])
16946 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16947 operands[2] = gen_lowpart (SImode, operands[2]);
16948 })
16949
16950 (define_split
16951 [(set (match_operand 0 "register_operand")
16952 (neg (match_operand 1 "register_operand")))
16953 (clobber (reg:CC FLAGS_REG))]
16954 "! TARGET_PARTIAL_REG_STALL && reload_completed
16955 && (GET_MODE (operands[0]) == HImode
16956 || (GET_MODE (operands[0]) == QImode
16957 && (TARGET_PROMOTE_QImode
16958 || optimize_insn_for_size_p ())))"
16959 [(parallel [(set (match_dup 0)
16960 (neg:SI (match_dup 1)))
16961 (clobber (reg:CC FLAGS_REG))])]
16962 {
16963 operands[0] = gen_lowpart (SImode, operands[0]);
16964 operands[1] = gen_lowpart (SImode, operands[1]);
16965 })
16966
16967 ;; Do not split instructions with mask regs.
16968 (define_split
16969 [(set (match_operand 0 "general_reg_operand")
16970 (not (match_operand 1 "general_reg_operand")))]
16971 "! TARGET_PARTIAL_REG_STALL && reload_completed
16972 && (GET_MODE (operands[0]) == HImode
16973 || (GET_MODE (operands[0]) == QImode
16974 && (TARGET_PROMOTE_QImode
16975 || optimize_insn_for_size_p ())))"
16976 [(set (match_dup 0)
16977 (not:SI (match_dup 1)))]
16978 {
16979 operands[0] = gen_lowpart (SImode, operands[0]);
16980 operands[1] = gen_lowpart (SImode, operands[1]);
16981 })
16982 \f
16983 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16984 ;; transform a complex memory operation into two memory to register operations.
16985
16986 ;; Don't push memory operands
16987 (define_peephole2
16988 [(set (match_operand:SWI 0 "push_operand")
16989 (match_operand:SWI 1 "memory_operand"))
16990 (match_scratch:SWI 2 "<r>")]
16991 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16992 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16993 [(set (match_dup 2) (match_dup 1))
16994 (set (match_dup 0) (match_dup 2))])
16995
16996 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16997 ;; SImode pushes.
16998 (define_peephole2
16999 [(set (match_operand:SF 0 "push_operand")
17000 (match_operand:SF 1 "memory_operand"))
17001 (match_scratch:SF 2 "r")]
17002 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17003 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17004 [(set (match_dup 2) (match_dup 1))
17005 (set (match_dup 0) (match_dup 2))])
17006
17007 ;; Don't move an immediate directly to memory when the instruction
17008 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17009 (define_peephole2
17010 [(match_scratch:SWI124 1 "<r>")
17011 (set (match_operand:SWI124 0 "memory_operand")
17012 (const_int 0))]
17013 "optimize_insn_for_speed_p ()
17014 && ((<MODE>mode == HImode
17015 && TARGET_LCP_STALL)
17016 || (!TARGET_USE_MOV0
17017 && TARGET_SPLIT_LONG_MOVES
17018 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17019 && peep2_regno_dead_p (0, FLAGS_REG)"
17020 [(parallel [(set (match_dup 2) (const_int 0))
17021 (clobber (reg:CC FLAGS_REG))])
17022 (set (match_dup 0) (match_dup 1))]
17023 "operands[2] = gen_lowpart (SImode, operands[1]);")
17024
17025 (define_peephole2
17026 [(match_scratch:SWI124 2 "<r>")
17027 (set (match_operand:SWI124 0 "memory_operand")
17028 (match_operand:SWI124 1 "immediate_operand"))]
17029 "optimize_insn_for_speed_p ()
17030 && ((<MODE>mode == HImode
17031 && TARGET_LCP_STALL)
17032 || (TARGET_SPLIT_LONG_MOVES
17033 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17034 [(set (match_dup 2) (match_dup 1))
17035 (set (match_dup 0) (match_dup 2))])
17036
17037 ;; Don't compare memory with zero, load and use a test instead.
17038 (define_peephole2
17039 [(set (match_operand 0 "flags_reg_operand")
17040 (match_operator 1 "compare_operator"
17041 [(match_operand:SI 2 "memory_operand")
17042 (const_int 0)]))
17043 (match_scratch:SI 3 "r")]
17044 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17045 [(set (match_dup 3) (match_dup 2))
17046 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17047
17048 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17049 ;; Don't split NOTs with a displacement operand, because resulting XOR
17050 ;; will not be pairable anyway.
17051 ;;
17052 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17053 ;; represented using a modRM byte. The XOR replacement is long decoded,
17054 ;; so this split helps here as well.
17055 ;;
17056 ;; Note: Can't do this as a regular split because we can't get proper
17057 ;; lifetime information then.
17058
17059 (define_peephole2
17060 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17061 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17062 "optimize_insn_for_speed_p ()
17063 && ((TARGET_NOT_UNPAIRABLE
17064 && (!MEM_P (operands[0])
17065 || !memory_displacement_operand (operands[0], <MODE>mode)))
17066 || (TARGET_NOT_VECTORMODE
17067 && long_memory_operand (operands[0], <MODE>mode)))
17068 && peep2_regno_dead_p (0, FLAGS_REG)"
17069 [(parallel [(set (match_dup 0)
17070 (xor:SWI124 (match_dup 1) (const_int -1)))
17071 (clobber (reg:CC FLAGS_REG))])])
17072
17073 ;; Non pairable "test imm, reg" instructions can be translated to
17074 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17075 ;; byte opcode instead of two, have a short form for byte operands),
17076 ;; so do it for other CPUs as well. Given that the value was dead,
17077 ;; this should not create any new dependencies. Pass on the sub-word
17078 ;; versions if we're concerned about partial register stalls.
17079
17080 (define_peephole2
17081 [(set (match_operand 0 "flags_reg_operand")
17082 (match_operator 1 "compare_operator"
17083 [(and:SI (match_operand:SI 2 "register_operand")
17084 (match_operand:SI 3 "immediate_operand"))
17085 (const_int 0)]))]
17086 "ix86_match_ccmode (insn, CCNOmode)
17087 && (true_regnum (operands[2]) != AX_REG
17088 || satisfies_constraint_K (operands[3]))
17089 && peep2_reg_dead_p (1, operands[2])"
17090 [(parallel
17091 [(set (match_dup 0)
17092 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17093 (const_int 0)]))
17094 (set (match_dup 2)
17095 (and:SI (match_dup 2) (match_dup 3)))])])
17096
17097 ;; We don't need to handle HImode case, because it will be promoted to SImode
17098 ;; on ! TARGET_PARTIAL_REG_STALL
17099
17100 (define_peephole2
17101 [(set (match_operand 0 "flags_reg_operand")
17102 (match_operator 1 "compare_operator"
17103 [(and:QI (match_operand:QI 2 "register_operand")
17104 (match_operand:QI 3 "immediate_operand"))
17105 (const_int 0)]))]
17106 "! TARGET_PARTIAL_REG_STALL
17107 && ix86_match_ccmode (insn, CCNOmode)
17108 && true_regnum (operands[2]) != AX_REG
17109 && peep2_reg_dead_p (1, operands[2])"
17110 [(parallel
17111 [(set (match_dup 0)
17112 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17113 (const_int 0)]))
17114 (set (match_dup 2)
17115 (and:QI (match_dup 2) (match_dup 3)))])])
17116
17117 (define_peephole2
17118 [(set (match_operand 0 "flags_reg_operand")
17119 (match_operator 1 "compare_operator"
17120 [(and:SI
17121 (zero_extract:SI
17122 (match_operand 2 "ext_register_operand")
17123 (const_int 8)
17124 (const_int 8))
17125 (match_operand 3 "const_int_operand"))
17126 (const_int 0)]))]
17127 "! TARGET_PARTIAL_REG_STALL
17128 && ix86_match_ccmode (insn, CCNOmode)
17129 && true_regnum (operands[2]) != AX_REG
17130 && peep2_reg_dead_p (1, operands[2])"
17131 [(parallel [(set (match_dup 0)
17132 (match_op_dup 1
17133 [(and:SI
17134 (zero_extract:SI
17135 (match_dup 2)
17136 (const_int 8)
17137 (const_int 8))
17138 (match_dup 3))
17139 (const_int 0)]))
17140 (set (zero_extract:SI (match_dup 2)
17141 (const_int 8)
17142 (const_int 8))
17143 (and:SI
17144 (zero_extract:SI
17145 (match_dup 2)
17146 (const_int 8)
17147 (const_int 8))
17148 (match_dup 3)))])])
17149
17150 ;; Don't do logical operations with memory inputs.
17151 (define_peephole2
17152 [(match_scratch:SI 2 "r")
17153 (parallel [(set (match_operand:SI 0 "register_operand")
17154 (match_operator:SI 3 "arith_or_logical_operator"
17155 [(match_dup 0)
17156 (match_operand:SI 1 "memory_operand")]))
17157 (clobber (reg:CC FLAGS_REG))])]
17158 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17159 [(set (match_dup 2) (match_dup 1))
17160 (parallel [(set (match_dup 0)
17161 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17162 (clobber (reg:CC FLAGS_REG))])])
17163
17164 (define_peephole2
17165 [(match_scratch:SI 2 "r")
17166 (parallel [(set (match_operand:SI 0 "register_operand")
17167 (match_operator:SI 3 "arith_or_logical_operator"
17168 [(match_operand:SI 1 "memory_operand")
17169 (match_dup 0)]))
17170 (clobber (reg:CC FLAGS_REG))])]
17171 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17172 [(set (match_dup 2) (match_dup 1))
17173 (parallel [(set (match_dup 0)
17174 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17175 (clobber (reg:CC FLAGS_REG))])])
17176
17177 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17178 ;; refers to the destination of the load!
17179
17180 (define_peephole2
17181 [(set (match_operand:SI 0 "register_operand")
17182 (match_operand:SI 1 "register_operand"))
17183 (parallel [(set (match_dup 0)
17184 (match_operator:SI 3 "commutative_operator"
17185 [(match_dup 0)
17186 (match_operand:SI 2 "memory_operand")]))
17187 (clobber (reg:CC FLAGS_REG))])]
17188 "REGNO (operands[0]) != REGNO (operands[1])
17189 && GENERAL_REGNO_P (REGNO (operands[0]))
17190 && GENERAL_REGNO_P (REGNO (operands[1]))"
17191 [(set (match_dup 0) (match_dup 4))
17192 (parallel [(set (match_dup 0)
17193 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17194 (clobber (reg:CC FLAGS_REG))])]
17195 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17196
17197 (define_peephole2
17198 [(set (match_operand 0 "register_operand")
17199 (match_operand 1 "register_operand"))
17200 (set (match_dup 0)
17201 (match_operator 3 "commutative_operator"
17202 [(match_dup 0)
17203 (match_operand 2 "memory_operand")]))]
17204 "REGNO (operands[0]) != REGNO (operands[1])
17205 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17206 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17207 [(set (match_dup 0) (match_dup 2))
17208 (set (match_dup 0)
17209 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17210
17211 ; Don't do logical operations with memory outputs
17212 ;
17213 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17214 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17215 ; the same decoder scheduling characteristics as the original.
17216
17217 (define_peephole2
17218 [(match_scratch:SI 2 "r")
17219 (parallel [(set (match_operand:SI 0 "memory_operand")
17220 (match_operator:SI 3 "arith_or_logical_operator"
17221 [(match_dup 0)
17222 (match_operand:SI 1 "nonmemory_operand")]))
17223 (clobber (reg:CC FLAGS_REG))])]
17224 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17225 /* Do not split stack checking probes. */
17226 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17227 [(set (match_dup 2) (match_dup 0))
17228 (parallel [(set (match_dup 2)
17229 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17230 (clobber (reg:CC FLAGS_REG))])
17231 (set (match_dup 0) (match_dup 2))])
17232
17233 (define_peephole2
17234 [(match_scratch:SI 2 "r")
17235 (parallel [(set (match_operand:SI 0 "memory_operand")
17236 (match_operator:SI 3 "arith_or_logical_operator"
17237 [(match_operand:SI 1 "nonmemory_operand")
17238 (match_dup 0)]))
17239 (clobber (reg:CC FLAGS_REG))])]
17240 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17241 /* Do not split stack checking probes. */
17242 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17243 [(set (match_dup 2) (match_dup 0))
17244 (parallel [(set (match_dup 2)
17245 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17246 (clobber (reg:CC FLAGS_REG))])
17247 (set (match_dup 0) (match_dup 2))])
17248
17249 ;; Attempt to use arith or logical operations with memory outputs with
17250 ;; setting of flags.
17251 (define_peephole2
17252 [(set (match_operand:SWI 0 "register_operand")
17253 (match_operand:SWI 1 "memory_operand"))
17254 (parallel [(set (match_dup 0)
17255 (match_operator:SWI 3 "plusminuslogic_operator"
17256 [(match_dup 0)
17257 (match_operand:SWI 2 "<nonmemory_operand>")]))
17258 (clobber (reg:CC FLAGS_REG))])
17259 (set (match_dup 1) (match_dup 0))
17260 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17261 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17262 && peep2_reg_dead_p (4, operands[0])
17263 && !reg_overlap_mentioned_p (operands[0], operands[1])
17264 && !reg_overlap_mentioned_p (operands[0], operands[2])
17265 && (<MODE>mode != QImode
17266 || immediate_operand (operands[2], QImode)
17267 || q_regs_operand (operands[2], QImode))
17268 && ix86_match_ccmode (peep2_next_insn (3),
17269 (GET_CODE (operands[3]) == PLUS
17270 || GET_CODE (operands[3]) == MINUS)
17271 ? CCGOCmode : CCNOmode)"
17272 [(parallel [(set (match_dup 4) (match_dup 5))
17273 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17274 (match_dup 2)]))])]
17275 {
17276 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17277 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17278 copy_rtx (operands[1]),
17279 copy_rtx (operands[2]));
17280 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17281 operands[5], const0_rtx);
17282 })
17283
17284 (define_peephole2
17285 [(parallel [(set (match_operand:SWI 0 "register_operand")
17286 (match_operator:SWI 2 "plusminuslogic_operator"
17287 [(match_dup 0)
17288 (match_operand:SWI 1 "memory_operand")]))
17289 (clobber (reg:CC FLAGS_REG))])
17290 (set (match_dup 1) (match_dup 0))
17291 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17292 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17293 && GET_CODE (operands[2]) != MINUS
17294 && peep2_reg_dead_p (3, operands[0])
17295 && !reg_overlap_mentioned_p (operands[0], operands[1])
17296 && ix86_match_ccmode (peep2_next_insn (2),
17297 GET_CODE (operands[2]) == PLUS
17298 ? CCGOCmode : CCNOmode)"
17299 [(parallel [(set (match_dup 3) (match_dup 4))
17300 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17301 (match_dup 0)]))])]
17302 {
17303 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17304 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17305 copy_rtx (operands[1]),
17306 copy_rtx (operands[0]));
17307 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17308 operands[4], const0_rtx);
17309 })
17310
17311 (define_peephole2
17312 [(set (match_operand:SWI12 0 "register_operand")
17313 (match_operand:SWI12 1 "memory_operand"))
17314 (parallel [(set (match_operand:SI 4 "register_operand")
17315 (match_operator:SI 3 "plusminuslogic_operator"
17316 [(match_dup 4)
17317 (match_operand:SI 2 "nonmemory_operand")]))
17318 (clobber (reg:CC FLAGS_REG))])
17319 (set (match_dup 1) (match_dup 0))
17320 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17321 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17322 && REG_P (operands[0]) && REG_P (operands[4])
17323 && REGNO (operands[0]) == REGNO (operands[4])
17324 && peep2_reg_dead_p (4, operands[0])
17325 && (<MODE>mode != QImode
17326 || immediate_operand (operands[2], SImode)
17327 || q_regs_operand (operands[2], SImode))
17328 && !reg_overlap_mentioned_p (operands[0], operands[1])
17329 && !reg_overlap_mentioned_p (operands[0], operands[2])
17330 && ix86_match_ccmode (peep2_next_insn (3),
17331 (GET_CODE (operands[3]) == PLUS
17332 || GET_CODE (operands[3]) == MINUS)
17333 ? CCGOCmode : CCNOmode)"
17334 [(parallel [(set (match_dup 4) (match_dup 5))
17335 (set (match_dup 1) (match_dup 6))])]
17336 {
17337 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17338 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17339 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17340 copy_rtx (operands[1]), operands[2]);
17341 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17342 operands[5], const0_rtx);
17343 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17344 copy_rtx (operands[1]),
17345 copy_rtx (operands[2]));
17346 })
17347
17348 ;; Attempt to always use XOR for zeroing registers.
17349 (define_peephole2
17350 [(set (match_operand 0 "register_operand")
17351 (match_operand 1 "const0_operand"))]
17352 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17353 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17354 && GENERAL_REG_P (operands[0])
17355 && peep2_regno_dead_p (0, FLAGS_REG)"
17356 [(parallel [(set (match_dup 0) (const_int 0))
17357 (clobber (reg:CC FLAGS_REG))])]
17358 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17359
17360 (define_peephole2
17361 [(set (strict_low_part (match_operand 0 "register_operand"))
17362 (const_int 0))]
17363 "(GET_MODE (operands[0]) == QImode
17364 || GET_MODE (operands[0]) == HImode)
17365 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17366 && peep2_regno_dead_p (0, FLAGS_REG)"
17367 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17368 (clobber (reg:CC FLAGS_REG))])])
17369
17370 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17371 (define_peephole2
17372 [(set (match_operand:SWI248 0 "register_operand")
17373 (const_int -1))]
17374 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17375 && peep2_regno_dead_p (0, FLAGS_REG)"
17376 [(parallel [(set (match_dup 0) (const_int -1))
17377 (clobber (reg:CC FLAGS_REG))])]
17378 {
17379 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17380 operands[0] = gen_lowpart (SImode, operands[0]);
17381 })
17382
17383 ;; Attempt to convert simple lea to add/shift.
17384 ;; These can be created by move expanders.
17385 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17386 ;; relevant lea instructions were already split.
17387
17388 (define_peephole2
17389 [(set (match_operand:SWI48 0 "register_operand")
17390 (plus:SWI48 (match_dup 0)
17391 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17392 "!TARGET_OPT_AGU
17393 && peep2_regno_dead_p (0, FLAGS_REG)"
17394 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17395 (clobber (reg:CC FLAGS_REG))])])
17396
17397 (define_peephole2
17398 [(set (match_operand:SWI48 0 "register_operand")
17399 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17400 (match_dup 0)))]
17401 "!TARGET_OPT_AGU
17402 && peep2_regno_dead_p (0, FLAGS_REG)"
17403 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17404 (clobber (reg:CC FLAGS_REG))])])
17405
17406 (define_peephole2
17407 [(set (match_operand:DI 0 "register_operand")
17408 (zero_extend:DI
17409 (plus:SI (match_operand:SI 1 "register_operand")
17410 (match_operand:SI 2 "nonmemory_operand"))))]
17411 "TARGET_64BIT && !TARGET_OPT_AGU
17412 && REGNO (operands[0]) == REGNO (operands[1])
17413 && peep2_regno_dead_p (0, FLAGS_REG)"
17414 [(parallel [(set (match_dup 0)
17415 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17416 (clobber (reg:CC FLAGS_REG))])])
17417
17418 (define_peephole2
17419 [(set (match_operand:DI 0 "register_operand")
17420 (zero_extend:DI
17421 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17422 (match_operand:SI 2 "register_operand"))))]
17423 "TARGET_64BIT && !TARGET_OPT_AGU
17424 && REGNO (operands[0]) == REGNO (operands[2])
17425 && peep2_regno_dead_p (0, FLAGS_REG)"
17426 [(parallel [(set (match_dup 0)
17427 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17428 (clobber (reg:CC FLAGS_REG))])])
17429
17430 (define_peephole2
17431 [(set (match_operand:SWI48 0 "register_operand")
17432 (mult:SWI48 (match_dup 0)
17433 (match_operand:SWI48 1 "const_int_operand")))]
17434 "exact_log2 (INTVAL (operands[1])) >= 0
17435 && peep2_regno_dead_p (0, FLAGS_REG)"
17436 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17437 (clobber (reg:CC FLAGS_REG))])]
17438 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17439
17440 (define_peephole2
17441 [(set (match_operand:DI 0 "register_operand")
17442 (zero_extend:DI
17443 (mult:SI (match_operand:SI 1 "register_operand")
17444 (match_operand:SI 2 "const_int_operand"))))]
17445 "TARGET_64BIT
17446 && exact_log2 (INTVAL (operands[2])) >= 0
17447 && REGNO (operands[0]) == REGNO (operands[1])
17448 && peep2_regno_dead_p (0, FLAGS_REG)"
17449 [(parallel [(set (match_dup 0)
17450 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17451 (clobber (reg:CC FLAGS_REG))])]
17452 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17453
17454 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17455 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17456 ;; On many CPUs it is also faster, since special hardware to avoid esp
17457 ;; dependencies is present.
17458
17459 ;; While some of these conversions may be done using splitters, we use
17460 ;; peepholes in order to allow combine_stack_adjustments pass to see
17461 ;; nonobfuscated RTL.
17462
17463 ;; Convert prologue esp subtractions to push.
17464 ;; We need register to push. In order to keep verify_flow_info happy we have
17465 ;; two choices
17466 ;; - use scratch and clobber it in order to avoid dependencies
17467 ;; - use already live register
17468 ;; We can't use the second way right now, since there is no reliable way how to
17469 ;; verify that given register is live. First choice will also most likely in
17470 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17471 ;; call clobbered registers are dead. We may want to use base pointer as an
17472 ;; alternative when no register is available later.
17473
17474 (define_peephole2
17475 [(match_scratch:W 1 "r")
17476 (parallel [(set (reg:P SP_REG)
17477 (plus:P (reg:P SP_REG)
17478 (match_operand:P 0 "const_int_operand")))
17479 (clobber (reg:CC FLAGS_REG))
17480 (clobber (mem:BLK (scratch)))])]
17481 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17482 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17483 [(clobber (match_dup 1))
17484 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17485 (clobber (mem:BLK (scratch)))])])
17486
17487 (define_peephole2
17488 [(match_scratch:W 1 "r")
17489 (parallel [(set (reg:P SP_REG)
17490 (plus:P (reg:P SP_REG)
17491 (match_operand:P 0 "const_int_operand")))
17492 (clobber (reg:CC FLAGS_REG))
17493 (clobber (mem:BLK (scratch)))])]
17494 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17495 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17496 [(clobber (match_dup 1))
17497 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17498 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17499 (clobber (mem:BLK (scratch)))])])
17500
17501 ;; Convert esp subtractions to push.
17502 (define_peephole2
17503 [(match_scratch:W 1 "r")
17504 (parallel [(set (reg:P SP_REG)
17505 (plus:P (reg:P SP_REG)
17506 (match_operand:P 0 "const_int_operand")))
17507 (clobber (reg:CC FLAGS_REG))])]
17508 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17509 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17510 [(clobber (match_dup 1))
17511 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17512
17513 (define_peephole2
17514 [(match_scratch:W 1 "r")
17515 (parallel [(set (reg:P SP_REG)
17516 (plus:P (reg:P SP_REG)
17517 (match_operand:P 0 "const_int_operand")))
17518 (clobber (reg:CC FLAGS_REG))])]
17519 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17520 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17521 [(clobber (match_dup 1))
17522 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17523 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17524
17525 ;; Convert epilogue deallocator to pop.
17526 (define_peephole2
17527 [(match_scratch:W 1 "r")
17528 (parallel [(set (reg:P SP_REG)
17529 (plus:P (reg:P SP_REG)
17530 (match_operand:P 0 "const_int_operand")))
17531 (clobber (reg:CC FLAGS_REG))
17532 (clobber (mem:BLK (scratch)))])]
17533 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17534 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17535 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17536 (clobber (mem:BLK (scratch)))])])
17537
17538 ;; Two pops case is tricky, since pop causes dependency
17539 ;; on destination register. We use two registers if available.
17540 (define_peephole2
17541 [(match_scratch:W 1 "r")
17542 (match_scratch:W 2 "r")
17543 (parallel [(set (reg:P SP_REG)
17544 (plus:P (reg:P SP_REG)
17545 (match_operand:P 0 "const_int_operand")))
17546 (clobber (reg:CC FLAGS_REG))
17547 (clobber (mem:BLK (scratch)))])]
17548 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17549 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17550 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17551 (clobber (mem:BLK (scratch)))])
17552 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17553
17554 (define_peephole2
17555 [(match_scratch:W 1 "r")
17556 (parallel [(set (reg:P SP_REG)
17557 (plus:P (reg:P SP_REG)
17558 (match_operand:P 0 "const_int_operand")))
17559 (clobber (reg:CC FLAGS_REG))
17560 (clobber (mem:BLK (scratch)))])]
17561 "optimize_insn_for_size_p ()
17562 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17563 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17564 (clobber (mem:BLK (scratch)))])
17565 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17566
17567 ;; Convert esp additions to pop.
17568 (define_peephole2
17569 [(match_scratch:W 1 "r")
17570 (parallel [(set (reg:P SP_REG)
17571 (plus:P (reg:P SP_REG)
17572 (match_operand:P 0 "const_int_operand")))
17573 (clobber (reg:CC FLAGS_REG))])]
17574 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17575 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17576
17577 ;; Two pops case is tricky, since pop causes dependency
17578 ;; on destination register. We use two registers if available.
17579 (define_peephole2
17580 [(match_scratch:W 1 "r")
17581 (match_scratch:W 2 "r")
17582 (parallel [(set (reg:P SP_REG)
17583 (plus:P (reg:P SP_REG)
17584 (match_operand:P 0 "const_int_operand")))
17585 (clobber (reg:CC FLAGS_REG))])]
17586 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17587 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17588 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17589
17590 (define_peephole2
17591 [(match_scratch:W 1 "r")
17592 (parallel [(set (reg:P SP_REG)
17593 (plus:P (reg:P SP_REG)
17594 (match_operand:P 0 "const_int_operand")))
17595 (clobber (reg:CC FLAGS_REG))])]
17596 "optimize_insn_for_size_p ()
17597 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17598 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17599 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17600 \f
17601 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17602 ;; required and register dies. Similarly for 128 to -128.
17603 (define_peephole2
17604 [(set (match_operand 0 "flags_reg_operand")
17605 (match_operator 1 "compare_operator"
17606 [(match_operand 2 "register_operand")
17607 (match_operand 3 "const_int_operand")]))]
17608 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17609 && incdec_operand (operands[3], GET_MODE (operands[3])))
17610 || (!TARGET_FUSE_CMP_AND_BRANCH
17611 && INTVAL (operands[3]) == 128))
17612 && ix86_match_ccmode (insn, CCGCmode)
17613 && peep2_reg_dead_p (1, operands[2])"
17614 [(parallel [(set (match_dup 0)
17615 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17616 (clobber (match_dup 2))])])
17617 \f
17618 ;; Convert imul by three, five and nine into lea
17619 (define_peephole2
17620 [(parallel
17621 [(set (match_operand:SWI48 0 "register_operand")
17622 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17623 (match_operand:SWI48 2 "const359_operand")))
17624 (clobber (reg:CC FLAGS_REG))])]
17625 "!TARGET_PARTIAL_REG_STALL
17626 || <MODE>mode == SImode
17627 || optimize_function_for_size_p (cfun)"
17628 [(set (match_dup 0)
17629 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17630 (match_dup 1)))]
17631 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17632
17633 (define_peephole2
17634 [(parallel
17635 [(set (match_operand:SWI48 0 "register_operand")
17636 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17637 (match_operand:SWI48 2 "const359_operand")))
17638 (clobber (reg:CC FLAGS_REG))])]
17639 "optimize_insn_for_speed_p ()
17640 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17641 [(set (match_dup 0) (match_dup 1))
17642 (set (match_dup 0)
17643 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17644 (match_dup 0)))]
17645 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17646
17647 ;; imul $32bit_imm, mem, reg is vector decoded, while
17648 ;; imul $32bit_imm, reg, reg is direct decoded.
17649 (define_peephole2
17650 [(match_scratch:SWI48 3 "r")
17651 (parallel [(set (match_operand:SWI48 0 "register_operand")
17652 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17653 (match_operand:SWI48 2 "immediate_operand")))
17654 (clobber (reg:CC FLAGS_REG))])]
17655 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17656 && !satisfies_constraint_K (operands[2])"
17657 [(set (match_dup 3) (match_dup 1))
17658 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17659 (clobber (reg:CC FLAGS_REG))])])
17660
17661 (define_peephole2
17662 [(match_scratch:SI 3 "r")
17663 (parallel [(set (match_operand:DI 0 "register_operand")
17664 (zero_extend:DI
17665 (mult:SI (match_operand:SI 1 "memory_operand")
17666 (match_operand:SI 2 "immediate_operand"))))
17667 (clobber (reg:CC FLAGS_REG))])]
17668 "TARGET_64BIT
17669 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17670 && !satisfies_constraint_K (operands[2])"
17671 [(set (match_dup 3) (match_dup 1))
17672 (parallel [(set (match_dup 0)
17673 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17674 (clobber (reg:CC FLAGS_REG))])])
17675
17676 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17677 ;; Convert it into imul reg, reg
17678 ;; It would be better to force assembler to encode instruction using long
17679 ;; immediate, but there is apparently no way to do so.
17680 (define_peephole2
17681 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17682 (mult:SWI248
17683 (match_operand:SWI248 1 "nonimmediate_operand")
17684 (match_operand:SWI248 2 "const_int_operand")))
17685 (clobber (reg:CC FLAGS_REG))])
17686 (match_scratch:SWI248 3 "r")]
17687 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17688 && satisfies_constraint_K (operands[2])"
17689 [(set (match_dup 3) (match_dup 2))
17690 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17691 (clobber (reg:CC FLAGS_REG))])]
17692 {
17693 if (!rtx_equal_p (operands[0], operands[1]))
17694 emit_move_insn (operands[0], operands[1]);
17695 })
17696
17697 ;; After splitting up read-modify operations, array accesses with memory
17698 ;; operands might end up in form:
17699 ;; sall $2, %eax
17700 ;; movl 4(%esp), %edx
17701 ;; addl %edx, %eax
17702 ;; instead of pre-splitting:
17703 ;; sall $2, %eax
17704 ;; addl 4(%esp), %eax
17705 ;; Turn it into:
17706 ;; movl 4(%esp), %edx
17707 ;; leal (%edx,%eax,4), %eax
17708
17709 (define_peephole2
17710 [(match_scratch:W 5 "r")
17711 (parallel [(set (match_operand 0 "register_operand")
17712 (ashift (match_operand 1 "register_operand")
17713 (match_operand 2 "const_int_operand")))
17714 (clobber (reg:CC FLAGS_REG))])
17715 (parallel [(set (match_operand 3 "register_operand")
17716 (plus (match_dup 0)
17717 (match_operand 4 "x86_64_general_operand")))
17718 (clobber (reg:CC FLAGS_REG))])]
17719 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17720 /* Validate MODE for lea. */
17721 && ((!TARGET_PARTIAL_REG_STALL
17722 && (GET_MODE (operands[0]) == QImode
17723 || GET_MODE (operands[0]) == HImode))
17724 || GET_MODE (operands[0]) == SImode
17725 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17726 && (rtx_equal_p (operands[0], operands[3])
17727 || peep2_reg_dead_p (2, operands[0]))
17728 /* We reorder load and the shift. */
17729 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17730 [(set (match_dup 5) (match_dup 4))
17731 (set (match_dup 0) (match_dup 1))]
17732 {
17733 enum machine_mode op1mode = GET_MODE (operands[1]);
17734 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17735 int scale = 1 << INTVAL (operands[2]);
17736 rtx index = gen_lowpart (word_mode, operands[1]);
17737 rtx base = gen_lowpart (word_mode, operands[5]);
17738 rtx dest = gen_lowpart (mode, operands[3]);
17739
17740 operands[1] = gen_rtx_PLUS (word_mode, base,
17741 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17742 operands[5] = base;
17743 if (mode != word_mode)
17744 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17745 if (op1mode != word_mode)
17746 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17747 operands[0] = dest;
17748 })
17749 \f
17750 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17751 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17752 ;; caught for use by garbage collectors and the like. Using an insn that
17753 ;; maps to SIGILL makes it more likely the program will rightfully die.
17754 ;; Keeping with tradition, "6" is in honor of #UD.
17755 (define_insn "trap"
17756 [(trap_if (const_int 1) (const_int 6))]
17757 ""
17758 { return ASM_SHORT "0x0b0f"; }
17759 [(set_attr "length" "2")])
17760
17761 (define_expand "prefetch"
17762 [(prefetch (match_operand 0 "address_operand")
17763 (match_operand:SI 1 "const_int_operand")
17764 (match_operand:SI 2 "const_int_operand"))]
17765 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_AVX512PF"
17766 {
17767 bool write = INTVAL (operands[1]) != 0;
17768 int locality = INTVAL (operands[2]);
17769
17770 gcc_assert (IN_RANGE (locality, 0, 3));
17771
17772 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17773 supported by SSE counterpart or the SSE prefetch is not available
17774 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17775 of locality. */
17776 if (TARGET_AVX512PF && write)
17777 operands[2] = const1_rtx;
17778 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17779 operands[2] = GEN_INT (3);
17780 else
17781 operands[1] = const0_rtx;
17782 })
17783
17784 (define_insn "*prefetch_sse"
17785 [(prefetch (match_operand 0 "address_operand" "p")
17786 (const_int 0)
17787 (match_operand:SI 1 "const_int_operand"))]
17788 "TARGET_PREFETCH_SSE"
17789 {
17790 static const char * const patterns[4] = {
17791 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17792 };
17793
17794 int locality = INTVAL (operands[1]);
17795 gcc_assert (IN_RANGE (locality, 0, 3));
17796
17797 return patterns[locality];
17798 }
17799 [(set_attr "type" "sse")
17800 (set_attr "atom_sse_attr" "prefetch")
17801 (set (attr "length_address")
17802 (symbol_ref "memory_address_length (operands[0], false)"))
17803 (set_attr "memory" "none")])
17804
17805 (define_insn "*prefetch_3dnow"
17806 [(prefetch (match_operand 0 "address_operand" "p")
17807 (match_operand:SI 1 "const_int_operand" "n")
17808 (const_int 3))]
17809 "TARGET_PRFCHW"
17810 {
17811 if (INTVAL (operands[1]) == 0)
17812 return "prefetch\t%a0";
17813 else
17814 return "prefetchw\t%a0";
17815 }
17816 [(set_attr "type" "mmx")
17817 (set (attr "length_address")
17818 (symbol_ref "memory_address_length (operands[0], false)"))
17819 (set_attr "memory" "none")])
17820
17821 (define_insn "*prefetch_avx512pf_<mode>"
17822 [(prefetch (match_operand:P 0 "address_operand" "p")
17823 (const_int 1)
17824 (const_int 1))]
17825 "TARGET_AVX512PF"
17826 "prefetchwt1\t%a0";
17827 [(set_attr "type" "sse")
17828 (set_attr "prefix" "evex")
17829 (set (attr "length_address")
17830 (symbol_ref "memory_address_length (operands[0], false)"))
17831 (set_attr "memory" "none")])
17832
17833 (define_expand "stack_protect_set"
17834 [(match_operand 0 "memory_operand")
17835 (match_operand 1 "memory_operand")]
17836 "TARGET_SSP_TLS_GUARD"
17837 {
17838 rtx (*insn)(rtx, rtx);
17839
17840 #ifdef TARGET_THREAD_SSP_OFFSET
17841 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17842 insn = (TARGET_LP64
17843 ? gen_stack_tls_protect_set_di
17844 : gen_stack_tls_protect_set_si);
17845 #else
17846 insn = (TARGET_LP64
17847 ? gen_stack_protect_set_di
17848 : gen_stack_protect_set_si);
17849 #endif
17850
17851 emit_insn (insn (operands[0], operands[1]));
17852 DONE;
17853 })
17854
17855 (define_insn "stack_protect_set_<mode>"
17856 [(set (match_operand:PTR 0 "memory_operand" "=m")
17857 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17858 UNSPEC_SP_SET))
17859 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17860 (clobber (reg:CC FLAGS_REG))]
17861 "TARGET_SSP_TLS_GUARD"
17862 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17863 [(set_attr "type" "multi")])
17864
17865 (define_insn "stack_tls_protect_set_<mode>"
17866 [(set (match_operand:PTR 0 "memory_operand" "=m")
17867 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17868 UNSPEC_SP_TLS_SET))
17869 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17870 (clobber (reg:CC FLAGS_REG))]
17871 ""
17872 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17873 [(set_attr "type" "multi")])
17874
17875 (define_expand "stack_protect_test"
17876 [(match_operand 0 "memory_operand")
17877 (match_operand 1 "memory_operand")
17878 (match_operand 2)]
17879 "TARGET_SSP_TLS_GUARD"
17880 {
17881 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17882
17883 rtx (*insn)(rtx, rtx, rtx);
17884
17885 #ifdef TARGET_THREAD_SSP_OFFSET
17886 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17887 insn = (TARGET_LP64
17888 ? gen_stack_tls_protect_test_di
17889 : gen_stack_tls_protect_test_si);
17890 #else
17891 insn = (TARGET_LP64
17892 ? gen_stack_protect_test_di
17893 : gen_stack_protect_test_si);
17894 #endif
17895
17896 emit_insn (insn (flags, operands[0], operands[1]));
17897
17898 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17899 flags, const0_rtx, operands[2]));
17900 DONE;
17901 })
17902
17903 (define_insn "stack_protect_test_<mode>"
17904 [(set (match_operand:CCZ 0 "flags_reg_operand")
17905 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17906 (match_operand:PTR 2 "memory_operand" "m")]
17907 UNSPEC_SP_TEST))
17908 (clobber (match_scratch:PTR 3 "=&r"))]
17909 "TARGET_SSP_TLS_GUARD"
17910 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17911 [(set_attr "type" "multi")])
17912
17913 (define_insn "stack_tls_protect_test_<mode>"
17914 [(set (match_operand:CCZ 0 "flags_reg_operand")
17915 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17916 (match_operand:PTR 2 "const_int_operand" "i")]
17917 UNSPEC_SP_TLS_TEST))
17918 (clobber (match_scratch:PTR 3 "=r"))]
17919 ""
17920 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17921 [(set_attr "type" "multi")])
17922
17923 (define_insn "sse4_2_crc32<mode>"
17924 [(set (match_operand:SI 0 "register_operand" "=r")
17925 (unspec:SI
17926 [(match_operand:SI 1 "register_operand" "0")
17927 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17928 UNSPEC_CRC32))]
17929 "TARGET_SSE4_2 || TARGET_CRC32"
17930 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17931 [(set_attr "type" "sselog1")
17932 (set_attr "prefix_rep" "1")
17933 (set_attr "prefix_extra" "1")
17934 (set (attr "prefix_data16")
17935 (if_then_else (match_operand:HI 2)
17936 (const_string "1")
17937 (const_string "*")))
17938 (set (attr "prefix_rex")
17939 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17940 (const_string "1")
17941 (const_string "*")))
17942 (set_attr "mode" "SI")])
17943
17944 (define_insn "sse4_2_crc32di"
17945 [(set (match_operand:DI 0 "register_operand" "=r")
17946 (unspec:DI
17947 [(match_operand:DI 1 "register_operand" "0")
17948 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17949 UNSPEC_CRC32))]
17950 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17951 "crc32{q}\t{%2, %0|%0, %2}"
17952 [(set_attr "type" "sselog1")
17953 (set_attr "prefix_rep" "1")
17954 (set_attr "prefix_extra" "1")
17955 (set_attr "mode" "DI")])
17956
17957 (define_insn "rdpmc"
17958 [(set (match_operand:DI 0 "register_operand" "=A")
17959 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17960 UNSPECV_RDPMC))]
17961 "!TARGET_64BIT"
17962 "rdpmc"
17963 [(set_attr "type" "other")
17964 (set_attr "length" "2")])
17965
17966 (define_insn "rdpmc_rex64"
17967 [(set (match_operand:DI 0 "register_operand" "=a")
17968 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17969 UNSPECV_RDPMC))
17970 (set (match_operand:DI 1 "register_operand" "=d")
17971 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17972 "TARGET_64BIT"
17973 "rdpmc"
17974 [(set_attr "type" "other")
17975 (set_attr "length" "2")])
17976
17977 (define_insn "rdtsc"
17978 [(set (match_operand:DI 0 "register_operand" "=A")
17979 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17980 "!TARGET_64BIT"
17981 "rdtsc"
17982 [(set_attr "type" "other")
17983 (set_attr "length" "2")])
17984
17985 (define_insn "rdtsc_rex64"
17986 [(set (match_operand:DI 0 "register_operand" "=a")
17987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17988 (set (match_operand:DI 1 "register_operand" "=d")
17989 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17990 "TARGET_64BIT"
17991 "rdtsc"
17992 [(set_attr "type" "other")
17993 (set_attr "length" "2")])
17994
17995 (define_insn "rdtscp"
17996 [(set (match_operand:DI 0 "register_operand" "=A")
17997 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17998 (set (match_operand:SI 1 "register_operand" "=c")
17999 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18000 "!TARGET_64BIT"
18001 "rdtscp"
18002 [(set_attr "type" "other")
18003 (set_attr "length" "3")])
18004
18005 (define_insn "rdtscp_rex64"
18006 [(set (match_operand:DI 0 "register_operand" "=a")
18007 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18008 (set (match_operand:DI 1 "register_operand" "=d")
18009 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18010 (set (match_operand:SI 2 "register_operand" "=c")
18011 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18012 "TARGET_64BIT"
18013 "rdtscp"
18014 [(set_attr "type" "other")
18015 (set_attr "length" "3")])
18016
18017 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18018 ;;
18019 ;; FXSR, XSAVE and XSAVEOPT instructions
18020 ;;
18021 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18022
18023 (define_insn "fxsave"
18024 [(set (match_operand:BLK 0 "memory_operand" "=m")
18025 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18026 "TARGET_FXSR"
18027 "fxsave\t%0"
18028 [(set_attr "type" "other")
18029 (set_attr "memory" "store")
18030 (set (attr "length")
18031 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18032
18033 (define_insn "fxsave64"
18034 [(set (match_operand:BLK 0 "memory_operand" "=m")
18035 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18036 "TARGET_64BIT && TARGET_FXSR"
18037 "fxsave64\t%0"
18038 [(set_attr "type" "other")
18039 (set_attr "memory" "store")
18040 (set (attr "length")
18041 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18042
18043 (define_insn "fxrstor"
18044 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18045 UNSPECV_FXRSTOR)]
18046 "TARGET_FXSR"
18047 "fxrstor\t%0"
18048 [(set_attr "type" "other")
18049 (set_attr "memory" "load")
18050 (set (attr "length")
18051 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18052
18053 (define_insn "fxrstor64"
18054 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18055 UNSPECV_FXRSTOR64)]
18056 "TARGET_64BIT && TARGET_FXSR"
18057 "fxrstor64\t%0"
18058 [(set_attr "type" "other")
18059 (set_attr "memory" "load")
18060 (set (attr "length")
18061 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18062
18063 (define_int_iterator ANY_XSAVE
18064 [UNSPECV_XSAVE
18065 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
18066
18067 (define_int_iterator ANY_XSAVE64
18068 [UNSPECV_XSAVE64
18069 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
18070
18071 (define_int_attr xsave
18072 [(UNSPECV_XSAVE "xsave")
18073 (UNSPECV_XSAVE64 "xsave64")
18074 (UNSPECV_XSAVEOPT "xsaveopt")
18075 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
18076
18077 (define_insn "<xsave>"
18078 [(set (match_operand:BLK 0 "memory_operand" "=m")
18079 (unspec_volatile:BLK
18080 [(match_operand:DI 1 "register_operand" "A")]
18081 ANY_XSAVE))]
18082 "!TARGET_64BIT && TARGET_XSAVE"
18083 "<xsave>\t%0"
18084 [(set_attr "type" "other")
18085 (set_attr "memory" "store")
18086 (set (attr "length")
18087 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18088
18089 (define_insn "<xsave>_rex64"
18090 [(set (match_operand:BLK 0 "memory_operand" "=m")
18091 (unspec_volatile:BLK
18092 [(match_operand:SI 1 "register_operand" "a")
18093 (match_operand:SI 2 "register_operand" "d")]
18094 ANY_XSAVE))]
18095 "TARGET_64BIT && TARGET_XSAVE"
18096 "<xsave>\t%0"
18097 [(set_attr "type" "other")
18098 (set_attr "memory" "store")
18099 (set (attr "length")
18100 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18101
18102 (define_insn "<xsave>"
18103 [(set (match_operand:BLK 0 "memory_operand" "=m")
18104 (unspec_volatile:BLK
18105 [(match_operand:SI 1 "register_operand" "a")
18106 (match_operand:SI 2 "register_operand" "d")]
18107 ANY_XSAVE64))]
18108 "TARGET_64BIT && TARGET_XSAVE"
18109 "<xsave>\t%0"
18110 [(set_attr "type" "other")
18111 (set_attr "memory" "store")
18112 (set (attr "length")
18113 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18114
18115 (define_insn "xrstor"
18116 [(unspec_volatile:BLK
18117 [(match_operand:BLK 0 "memory_operand" "m")
18118 (match_operand:DI 1 "register_operand" "A")]
18119 UNSPECV_XRSTOR)]
18120 "!TARGET_64BIT && TARGET_XSAVE"
18121 "xrstor\t%0"
18122 [(set_attr "type" "other")
18123 (set_attr "memory" "load")
18124 (set (attr "length")
18125 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18126
18127 (define_insn "xrstor_rex64"
18128 [(unspec_volatile:BLK
18129 [(match_operand:BLK 0 "memory_operand" "m")
18130 (match_operand:SI 1 "register_operand" "a")
18131 (match_operand:SI 2 "register_operand" "d")]
18132 UNSPECV_XRSTOR)]
18133 "TARGET_64BIT && TARGET_XSAVE"
18134 "xrstor\t%0"
18135 [(set_attr "type" "other")
18136 (set_attr "memory" "load")
18137 (set (attr "length")
18138 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18139
18140 (define_insn "xrstor64"
18141 [(unspec_volatile:BLK
18142 [(match_operand:BLK 0 "memory_operand" "m")
18143 (match_operand:SI 1 "register_operand" "a")
18144 (match_operand:SI 2 "register_operand" "d")]
18145 UNSPECV_XRSTOR64)]
18146 "TARGET_64BIT && TARGET_XSAVE"
18147 "xrstor64\t%0"
18148 [(set_attr "type" "other")
18149 (set_attr "memory" "load")
18150 (set (attr "length")
18151 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18152
18153 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18154 ;;
18155 ;; Floating-point instructions for atomic compound assignments
18156 ;;
18157 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18158
18159 ; Clobber all floating-point registers on environment save and restore
18160 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18161 (define_insn "fnstenv"
18162 [(set (match_operand:BLK 0 "memory_operand" "=m")
18163 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18164 (clobber (reg:HI FPCR_REG))
18165 (clobber (reg:XF ST0_REG))
18166 (clobber (reg:XF ST1_REG))
18167 (clobber (reg:XF ST2_REG))
18168 (clobber (reg:XF ST3_REG))
18169 (clobber (reg:XF ST4_REG))
18170 (clobber (reg:XF ST5_REG))
18171 (clobber (reg:XF ST6_REG))
18172 (clobber (reg:XF ST7_REG))]
18173 "TARGET_80387"
18174 "fnstenv\t%0"
18175 [(set_attr "type" "other")
18176 (set_attr "memory" "store")
18177 (set (attr "length")
18178 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18179
18180 (define_insn "fldenv"
18181 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18182 UNSPECV_FLDENV)
18183 (clobber (reg:CCFP FPSR_REG))
18184 (clobber (reg:HI FPCR_REG))
18185 (clobber (reg:XF ST0_REG))
18186 (clobber (reg:XF ST1_REG))
18187 (clobber (reg:XF ST2_REG))
18188 (clobber (reg:XF ST3_REG))
18189 (clobber (reg:XF ST4_REG))
18190 (clobber (reg:XF ST5_REG))
18191 (clobber (reg:XF ST6_REG))
18192 (clobber (reg:XF ST7_REG))]
18193 "TARGET_80387"
18194 "fldenv\t%0"
18195 [(set_attr "type" "other")
18196 (set_attr "memory" "load")
18197 (set (attr "length")
18198 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18199
18200 (define_insn "fnstsw"
18201 [(set (match_operand:HI 0 "memory_operand" "=m")
18202 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18203 "TARGET_80387"
18204 "fnstsw\t%0"
18205 [(set_attr "type" "other")
18206 (set_attr "memory" "store")
18207 (set (attr "length")
18208 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18209
18210 (define_insn "fnclex"
18211 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18212 "TARGET_80387"
18213 "fnclex"
18214 [(set_attr "type" "other")
18215 (set_attr "memory" "none")
18216 (set_attr "length" "2")])
18217
18218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18219 ;;
18220 ;; LWP instructions
18221 ;;
18222 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18223
18224 (define_expand "lwp_llwpcb"
18225 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18226 UNSPECV_LLWP_INTRINSIC)]
18227 "TARGET_LWP")
18228
18229 (define_insn "*lwp_llwpcb<mode>1"
18230 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18231 UNSPECV_LLWP_INTRINSIC)]
18232 "TARGET_LWP"
18233 "llwpcb\t%0"
18234 [(set_attr "type" "lwp")
18235 (set_attr "mode" "<MODE>")
18236 (set_attr "length" "5")])
18237
18238 (define_expand "lwp_slwpcb"
18239 [(set (match_operand 0 "register_operand" "=r")
18240 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18241 "TARGET_LWP"
18242 {
18243 rtx (*insn)(rtx);
18244
18245 insn = (Pmode == DImode
18246 ? gen_lwp_slwpcbdi
18247 : gen_lwp_slwpcbsi);
18248
18249 emit_insn (insn (operands[0]));
18250 DONE;
18251 })
18252
18253 (define_insn "lwp_slwpcb<mode>"
18254 [(set (match_operand:P 0 "register_operand" "=r")
18255 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18256 "TARGET_LWP"
18257 "slwpcb\t%0"
18258 [(set_attr "type" "lwp")
18259 (set_attr "mode" "<MODE>")
18260 (set_attr "length" "5")])
18261
18262 (define_expand "lwp_lwpval<mode>3"
18263 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18264 (match_operand:SI 2 "nonimmediate_operand" "rm")
18265 (match_operand:SI 3 "const_int_operand" "i")]
18266 UNSPECV_LWPVAL_INTRINSIC)]
18267 "TARGET_LWP"
18268 ;; Avoid unused variable warning.
18269 "(void) operands[0];")
18270
18271 (define_insn "*lwp_lwpval<mode>3_1"
18272 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18273 (match_operand:SI 1 "nonimmediate_operand" "rm")
18274 (match_operand:SI 2 "const_int_operand" "i")]
18275 UNSPECV_LWPVAL_INTRINSIC)]
18276 "TARGET_LWP"
18277 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18278 [(set_attr "type" "lwp")
18279 (set_attr "mode" "<MODE>")
18280 (set (attr "length")
18281 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18282
18283 (define_expand "lwp_lwpins<mode>3"
18284 [(set (reg:CCC FLAGS_REG)
18285 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18286 (match_operand:SI 2 "nonimmediate_operand" "rm")
18287 (match_operand:SI 3 "const_int_operand" "i")]
18288 UNSPECV_LWPINS_INTRINSIC))
18289 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18290 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18291 "TARGET_LWP")
18292
18293 (define_insn "*lwp_lwpins<mode>3_1"
18294 [(set (reg:CCC FLAGS_REG)
18295 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18296 (match_operand:SI 1 "nonimmediate_operand" "rm")
18297 (match_operand:SI 2 "const_int_operand" "i")]
18298 UNSPECV_LWPINS_INTRINSIC))]
18299 "TARGET_LWP"
18300 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18301 [(set_attr "type" "lwp")
18302 (set_attr "mode" "<MODE>")
18303 (set (attr "length")
18304 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18305
18306 (define_int_iterator RDFSGSBASE
18307 [UNSPECV_RDFSBASE
18308 UNSPECV_RDGSBASE])
18309
18310 (define_int_iterator WRFSGSBASE
18311 [UNSPECV_WRFSBASE
18312 UNSPECV_WRGSBASE])
18313
18314 (define_int_attr fsgs
18315 [(UNSPECV_RDFSBASE "fs")
18316 (UNSPECV_RDGSBASE "gs")
18317 (UNSPECV_WRFSBASE "fs")
18318 (UNSPECV_WRGSBASE "gs")])
18319
18320 (define_insn "rd<fsgs>base<mode>"
18321 [(set (match_operand:SWI48 0 "register_operand" "=r")
18322 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18323 "TARGET_64BIT && TARGET_FSGSBASE"
18324 "rd<fsgs>base\t%0"
18325 [(set_attr "type" "other")
18326 (set_attr "prefix_extra" "2")])
18327
18328 (define_insn "wr<fsgs>base<mode>"
18329 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18330 WRFSGSBASE)]
18331 "TARGET_64BIT && TARGET_FSGSBASE"
18332 "wr<fsgs>base\t%0"
18333 [(set_attr "type" "other")
18334 (set_attr "prefix_extra" "2")])
18335
18336 (define_insn "rdrand<mode>_1"
18337 [(set (match_operand:SWI248 0 "register_operand" "=r")
18338 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18339 (set (reg:CCC FLAGS_REG)
18340 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18341 "TARGET_RDRND"
18342 "rdrand\t%0"
18343 [(set_attr "type" "other")
18344 (set_attr "prefix_extra" "1")])
18345
18346 (define_insn "rdseed<mode>_1"
18347 [(set (match_operand:SWI248 0 "register_operand" "=r")
18348 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18349 (set (reg:CCC FLAGS_REG)
18350 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18351 "TARGET_RDSEED"
18352 "rdseed\t%0"
18353 [(set_attr "type" "other")
18354 (set_attr "prefix_extra" "1")])
18355
18356 (define_expand "pause"
18357 [(set (match_dup 0)
18358 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18359 ""
18360 {
18361 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18362 MEM_VOLATILE_P (operands[0]) = 1;
18363 })
18364
18365 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18366 ;; They have the same encoding.
18367 (define_insn "*pause"
18368 [(set (match_operand:BLK 0)
18369 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18370 ""
18371 "rep%; nop"
18372 [(set_attr "length" "2")
18373 (set_attr "memory" "unknown")])
18374
18375 (define_expand "xbegin"
18376 [(set (match_operand:SI 0 "register_operand")
18377 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18378 "TARGET_RTM"
18379 {
18380 rtx label = gen_label_rtx ();
18381
18382 /* xbegin is emitted as jump_insn, so reload won't be able
18383 to reload its operand. Force the value into AX hard register. */
18384 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18385 emit_move_insn (ax_reg, constm1_rtx);
18386
18387 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18388
18389 emit_label (label);
18390 LABEL_NUSES (label) = 1;
18391
18392 emit_move_insn (operands[0], ax_reg);
18393
18394 DONE;
18395 })
18396
18397 (define_insn "xbegin_1"
18398 [(set (pc)
18399 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18400 (const_int 0))
18401 (label_ref (match_operand 1))
18402 (pc)))
18403 (set (match_operand:SI 0 "register_operand" "+a")
18404 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18405 "TARGET_RTM"
18406 "xbegin\t%l1"
18407 [(set_attr "type" "other")
18408 (set_attr "length" "6")])
18409
18410 (define_insn "xend"
18411 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18412 "TARGET_RTM"
18413 "xend"
18414 [(set_attr "type" "other")
18415 (set_attr "length" "3")])
18416
18417 (define_insn "xabort"
18418 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18419 UNSPECV_XABORT)]
18420 "TARGET_RTM"
18421 "xabort\t%0"
18422 [(set_attr "type" "other")
18423 (set_attr "length" "3")])
18424
18425 (define_expand "xtest"
18426 [(set (match_operand:QI 0 "register_operand")
18427 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18428 "TARGET_RTM"
18429 {
18430 emit_insn (gen_xtest_1 ());
18431
18432 ix86_expand_setcc (operands[0], NE,
18433 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18434 DONE;
18435 })
18436
18437 (define_insn "xtest_1"
18438 [(set (reg:CCZ FLAGS_REG)
18439 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18440 "TARGET_RTM"
18441 "xtest"
18442 [(set_attr "type" "other")
18443 (set_attr "length" "3")])
18444
18445 (include "mmx.md")
18446 (include "sse.md")
18447 (include "sync.md")