]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
97b1ca318006dc1baf3caa7ea719a8728dd3c84d
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2018 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 addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print MPX or NOTRACK prefix for jxx/call/ret instructions if required.
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 UNSPEC_SIZEOF
82
83 ;; Prologue support
84 UNSPEC_STACK_ALLOC
85 UNSPEC_SET_GOT
86 UNSPEC_SET_RIP
87 UNSPEC_SET_GOT_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
89 UNSPEC_PROBE_STACK
90
91 ;; TLS support
92 UNSPEC_TP
93 UNSPEC_TLS_GD
94 UNSPEC_TLS_LD_BASE
95 UNSPEC_TLSDESC
96 UNSPEC_TLS_IE_SUN
97
98 ;; Other random patterns
99 UNSPEC_SCAS
100 UNSPEC_FNSTSW
101 UNSPEC_SAHF
102 UNSPEC_NOTRAP
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_FLDCW
106 UNSPEC_REP
107 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_TRUNC_NOOP
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_PAUSE
111 UNSPEC_LEA_ADDR
112 UNSPEC_XBEGIN_ABORT
113 UNSPEC_STOS
114 UNSPEC_PEEPSIB
115 UNSPEC_INSN_FALSE_DEP
116 UNSPEC_SBB
117
118 ;; For SSE/MMX support:
119 UNSPEC_FIX_NOTRUNC
120 UNSPEC_MASKMOV
121 UNSPEC_MOVMSK
122 UNSPEC_RCP
123 UNSPEC_RSQRT
124 UNSPEC_PSADBW
125
126 ;; Generic math support
127 UNSPEC_COPYSIGN
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
130
131 ;; x87 Floating point
132 UNSPEC_SIN
133 UNSPEC_COS
134 UNSPEC_FPATAN
135 UNSPEC_FYL2X
136 UNSPEC_FYL2XP1
137 UNSPEC_FRNDINT
138 UNSPEC_FIST
139 UNSPEC_F2XM1
140 UNSPEC_TAN
141 UNSPEC_FXAM
142
143 ;; x87 Rounding
144 UNSPEC_FRNDINT_FLOOR
145 UNSPEC_FRNDINT_CEIL
146 UNSPEC_FRNDINT_TRUNC
147 UNSPEC_FRNDINT_MASK_PM
148 UNSPEC_FIST_FLOOR
149 UNSPEC_FIST_CEIL
150
151 ;; x87 Double output FP
152 UNSPEC_SINCOS_COS
153 UNSPEC_SINCOS_SIN
154 UNSPEC_XTRACT_FRACT
155 UNSPEC_XTRACT_EXP
156 UNSPEC_FSCALE_FRACT
157 UNSPEC_FSCALE_EXP
158 UNSPEC_FPREM_F
159 UNSPEC_FPREM_U
160 UNSPEC_FPREM1_F
161 UNSPEC_FPREM1_U
162
163 UNSPEC_C2_FLAG
164 UNSPEC_FXAM_MEM
165
166 ;; SSP patterns
167 UNSPEC_SP_SET
168 UNSPEC_SP_TEST
169
170 ;; For ROUND support
171 UNSPEC_ROUND
172
173 ;; For CRC32 support
174 UNSPEC_CRC32
175
176 ;; For LZCNT suppoprt
177 UNSPEC_LZCNT
178
179 ;; For BMI support
180 UNSPEC_TZCNT
181 UNSPEC_BEXTR
182
183 ;; For BMI2 support
184 UNSPEC_PDEP
185 UNSPEC_PEXT
186
187 UNSPEC_BNDMK
188 UNSPEC_BNDMK_ADDR
189 UNSPEC_BNDSTX
190 UNSPEC_BNDLDX
191 UNSPEC_BNDLDX_ADDR
192 UNSPEC_BNDCL
193 UNSPEC_BNDCU
194 UNSPEC_BNDCN
195 UNSPEC_MPX_FENCE
196
197 ;; IRET support
198 UNSPEC_INTERRUPT_RETURN
199 ])
200
201 (define_c_enum "unspecv" [
202 UNSPECV_UD2
203 UNSPECV_BLOCKAGE
204 UNSPECV_STACK_PROBE
205 UNSPECV_PROBE_STACK_RANGE
206 UNSPECV_ALIGN
207 UNSPECV_PROLOGUE_USE
208 UNSPECV_SPLIT_STACK_RETURN
209 UNSPECV_CLD
210 UNSPECV_NOPS
211 UNSPECV_RDTSC
212 UNSPECV_RDTSCP
213 UNSPECV_RDPMC
214 UNSPECV_LLWP_INTRINSIC
215 UNSPECV_SLWP_INTRINSIC
216 UNSPECV_LWPVAL_INTRINSIC
217 UNSPECV_LWPINS_INTRINSIC
218 UNSPECV_RDFSBASE
219 UNSPECV_RDGSBASE
220 UNSPECV_WRFSBASE
221 UNSPECV_WRGSBASE
222 UNSPECV_FXSAVE
223 UNSPECV_FXRSTOR
224 UNSPECV_FXSAVE64
225 UNSPECV_FXRSTOR64
226 UNSPECV_XSAVE
227 UNSPECV_XRSTOR
228 UNSPECV_XSAVE64
229 UNSPECV_XRSTOR64
230 UNSPECV_XSAVEOPT
231 UNSPECV_XSAVEOPT64
232 UNSPECV_XSAVES
233 UNSPECV_XRSTORS
234 UNSPECV_XSAVES64
235 UNSPECV_XRSTORS64
236 UNSPECV_XSAVEC
237 UNSPECV_XSAVEC64
238 UNSPECV_XGETBV
239 UNSPECV_XSETBV
240 UNSPECV_WBINVD
241 UNSPECV_WBNOINVD
242
243 ;; For atomic compound assignments.
244 UNSPECV_FNSTENV
245 UNSPECV_FLDENV
246 UNSPECV_FNSTSW
247 UNSPECV_FNCLEX
248
249 ;; For RDRAND support
250 UNSPECV_RDRAND
251
252 ;; For RDSEED support
253 UNSPECV_RDSEED
254
255 ;; For RTM support
256 UNSPECV_XBEGIN
257 UNSPECV_XEND
258 UNSPECV_XABORT
259 UNSPECV_XTEST
260
261 UNSPECV_NLGR
262
263 ;; For CLWB support
264 UNSPECV_CLWB
265
266 ;; For CLFLUSHOPT support
267 UNSPECV_CLFLUSHOPT
268
269 ;; For MONITORX and MWAITX support
270 UNSPECV_MONITORX
271 UNSPECV_MWAITX
272
273 ;; For CLZERO support
274 UNSPECV_CLZERO
275
276 ;; For RDPKRU and WRPKRU support
277 UNSPECV_PKU
278
279 ;; For RDPID support
280 UNSPECV_RDPID
281
282 ;; For CET support
283 UNSPECV_NOP_ENDBR
284 UNSPECV_NOP_RDSSP
285 UNSPECV_INCSSP
286 UNSPECV_SAVEPREVSSP
287 UNSPECV_RSTORSSP
288 UNSPECV_WRSS
289 UNSPECV_WRUSS
290 UNSPECV_SETSSBSY
291 UNSPECV_CLRSSBSY
292 UNSPECV_MOVDIRI
293 UNSPECV_MOVDIR64B
294 ])
295
296 ;; Constants to represent rounding modes in the ROUND instruction
297 (define_constants
298 [(ROUND_FLOOR 0x1)
299 (ROUND_CEIL 0x2)
300 (ROUND_TRUNC 0x3)
301 (ROUND_MXCSR 0x4)
302 (ROUND_NO_EXC 0x8)
303 ])
304
305 ;; Constants to represent AVX512F embeded rounding
306 (define_constants
307 [(ROUND_NEAREST_INT 0)
308 (ROUND_NEG_INF 1)
309 (ROUND_POS_INF 2)
310 (ROUND_ZERO 3)
311 (NO_ROUND 4)
312 (ROUND_SAE 8)
313 ])
314
315 ;; Constants to represent pcomtrue/pcomfalse variants
316 (define_constants
317 [(PCOM_FALSE 0)
318 (PCOM_TRUE 1)
319 (COM_FALSE_S 2)
320 (COM_FALSE_P 3)
321 (COM_TRUE_S 4)
322 (COM_TRUE_P 5)
323 ])
324
325 ;; Constants used in the XOP pperm instruction
326 (define_constants
327 [(PPERM_SRC 0x00) /* copy source */
328 (PPERM_INVERT 0x20) /* invert source */
329 (PPERM_REVERSE 0x40) /* bit reverse source */
330 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
331 (PPERM_ZERO 0x80) /* all 0's */
332 (PPERM_ONES 0xa0) /* all 1's */
333 (PPERM_SIGN 0xc0) /* propagate sign bit */
334 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
335 (PPERM_SRC1 0x00) /* use first source byte */
336 (PPERM_SRC2 0x10) /* use second source byte */
337 ])
338
339 ;; Registers by name.
340 (define_constants
341 [(AX_REG 0)
342 (DX_REG 1)
343 (CX_REG 2)
344 (BX_REG 3)
345 (SI_REG 4)
346 (DI_REG 5)
347 (BP_REG 6)
348 (SP_REG 7)
349 (ST0_REG 8)
350 (ST1_REG 9)
351 (ST2_REG 10)
352 (ST3_REG 11)
353 (ST4_REG 12)
354 (ST5_REG 13)
355 (ST6_REG 14)
356 (ST7_REG 15)
357 (ARGP_REG 16)
358 (FLAGS_REG 17)
359 (FPSR_REG 18)
360 (FPCR_REG 19)
361 (FRAME_REG 20)
362 (XMM0_REG 21)
363 (XMM1_REG 22)
364 (XMM2_REG 23)
365 (XMM3_REG 24)
366 (XMM4_REG 25)
367 (XMM5_REG 26)
368 (XMM6_REG 27)
369 (XMM7_REG 28)
370 (MM0_REG 29)
371 (MM1_REG 30)
372 (MM2_REG 31)
373 (MM3_REG 32)
374 (MM4_REG 33)
375 (MM5_REG 34)
376 (MM6_REG 35)
377 (MM7_REG 36)
378 (R8_REG 37)
379 (R9_REG 38)
380 (R10_REG 39)
381 (R11_REG 40)
382 (R12_REG 41)
383 (R13_REG 42)
384 (R14_REG 43)
385 (R15_REG 44)
386 (XMM8_REG 45)
387 (XMM9_REG 46)
388 (XMM10_REG 47)
389 (XMM11_REG 48)
390 (XMM12_REG 49)
391 (XMM13_REG 50)
392 (XMM14_REG 51)
393 (XMM15_REG 52)
394 (XMM16_REG 53)
395 (XMM17_REG 54)
396 (XMM18_REG 55)
397 (XMM19_REG 56)
398 (XMM20_REG 57)
399 (XMM21_REG 58)
400 (XMM22_REG 59)
401 (XMM23_REG 60)
402 (XMM24_REG 61)
403 (XMM25_REG 62)
404 (XMM26_REG 63)
405 (XMM27_REG 64)
406 (XMM28_REG 65)
407 (XMM29_REG 66)
408 (XMM30_REG 67)
409 (XMM31_REG 68)
410 (MASK0_REG 69)
411 (MASK1_REG 70)
412 (MASK2_REG 71)
413 (MASK3_REG 72)
414 (MASK4_REG 73)
415 (MASK5_REG 74)
416 (MASK6_REG 75)
417 (MASK7_REG 76)
418 (BND0_REG 77)
419 (BND1_REG 78)
420 (BND2_REG 79)
421 (BND3_REG 80)
422 (FIRST_PSEUDO_REG 81)
423 ])
424
425 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
426 ;; from i386.c.
427
428 ;; In C guard expressions, put expressions which may be compile-time
429 ;; constants first. This allows for better optimization. For
430 ;; example, write "TARGET_64BIT && reload_completed", not
431 ;; "reload_completed && TARGET_64BIT".
432
433 \f
434 ;; Processor type.
435 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
436 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
437 bdver4,btver2,znver1"
438 (const (symbol_ref "ix86_schedule")))
439
440 ;; A basic instruction type. Refinements due to arguments to be
441 ;; provided in other attributes.
442 (define_attr "type"
443 "other,multi,
444 alu,alu1,negnot,imov,imovx,lea,
445 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
446 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
447 push,pop,call,callv,leave,
448 str,bitmanip,
449 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
450 fxch,fistp,fisttp,frndint,
451 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
452 ssemul,sseimul,ssediv,sselog,sselog1,
453 sseishft,sseishft1,ssecmp,ssecomi,
454 ssecvt,ssecvt1,sseicvt,sseins,
455 sseshuf,sseshuf1,ssemuladd,sse4arg,
456 lwp,mskmov,msklog,
457 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
458 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
459 (const_string "other"))
460
461 ;; Main data type used by the insn
462 (define_attr "mode"
463 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
464 V2DF,V2SF,V1DF,V8DF"
465 (const_string "unknown"))
466
467 ;; The CPU unit operations uses.
468 (define_attr "unit" "integer,i387,sse,mmx,unknown"
469 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
470 fxch,fistp,fisttp,frndint")
471 (const_string "i387")
472 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
473 ssemul,sseimul,ssediv,sselog,sselog1,
474 sseishft,sseishft1,ssecmp,ssecomi,
475 ssecvt,ssecvt1,sseicvt,sseins,
476 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
477 (const_string "sse")
478 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
479 (const_string "mmx")
480 (eq_attr "type" "other")
481 (const_string "unknown")]
482 (const_string "integer")))
483
484 ;; The (bounding maximum) length of an instruction immediate.
485 (define_attr "length_immediate" ""
486 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
487 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
488 mpxld,mpxst")
489 (const_int 0)
490 (eq_attr "unit" "i387,sse,mmx")
491 (const_int 0)
492 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
493 rotate,rotatex,rotate1,imul,icmp,push,pop")
494 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
495 (eq_attr "type" "imov,test")
496 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
497 (eq_attr "type" "call")
498 (if_then_else (match_operand 0 "constant_call_address_operand")
499 (const_int 4)
500 (const_int 0))
501 (eq_attr "type" "callv")
502 (if_then_else (match_operand 1 "constant_call_address_operand")
503 (const_int 4)
504 (const_int 0))
505 ;; We don't know the size before shorten_branches. Expect
506 ;; the instruction to fit for better scheduling.
507 (eq_attr "type" "ibr")
508 (const_int 1)
509 ]
510 (symbol_ref "/* Update immediate_length and other attributes! */
511 gcc_unreachable (),1")))
512
513 ;; The (bounding maximum) length of an instruction address.
514 (define_attr "length_address" ""
515 (cond [(eq_attr "type" "str,other,multi,fxch")
516 (const_int 0)
517 (and (eq_attr "type" "call")
518 (match_operand 0 "constant_call_address_operand"))
519 (const_int 0)
520 (and (eq_attr "type" "callv")
521 (match_operand 1 "constant_call_address_operand"))
522 (const_int 0)
523 ]
524 (symbol_ref "ix86_attr_length_address_default (insn)")))
525
526 ;; Set when length prefix is used.
527 (define_attr "prefix_data16" ""
528 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
529 (const_int 0)
530 (eq_attr "mode" "HI")
531 (const_int 1)
532 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
533 (const_int 1)
534 ]
535 (const_int 0)))
536
537 ;; Set when string REP prefix is used.
538 (define_attr "prefix_rep" ""
539 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
540 (const_int 0)
541 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
542 (const_int 1)
543 (and (eq_attr "type" "ibr,call,callv")
544 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
545 (const_int 1)
546 ]
547 (const_int 0)))
548
549 ;; Set when 0f opcode prefix is used.
550 (define_attr "prefix_0f" ""
551 (if_then_else
552 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
553 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
554 (eq_attr "unit" "sse,mmx"))
555 (const_int 1)
556 (const_int 0)))
557
558 ;; Set when REX opcode prefix is used.
559 (define_attr "prefix_rex" ""
560 (cond [(not (match_test "TARGET_64BIT"))
561 (const_int 0)
562 (and (eq_attr "mode" "DI")
563 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
564 (eq_attr "unit" "!mmx")))
565 (const_int 1)
566 (and (eq_attr "mode" "QI")
567 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
568 (const_int 1)
569 (match_test "x86_extended_reg_mentioned_p (insn)")
570 (const_int 1)
571 (and (eq_attr "type" "imovx")
572 (match_operand:QI 1 "ext_QIreg_operand"))
573 (const_int 1)
574 ]
575 (const_int 0)))
576
577 ;; There are also additional prefixes in 3DNOW, SSSE3.
578 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
579 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
580 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
581 (define_attr "prefix_extra" ""
582 (cond [(eq_attr "type" "ssemuladd,sse4arg")
583 (const_int 2)
584 (eq_attr "type" "sseiadd1,ssecvt1")
585 (const_int 1)
586 ]
587 (const_int 0)))
588
589 ;; Set when BND opcode prefix may be used.
590 (define_attr "maybe_prefix_bnd" "" (const_int 0))
591
592 ;; Prefix used: original, VEX or maybe VEX.
593 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
594 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
595 (const_string "vex")
596 (eq_attr "mode" "XI,V16SF,V8DF")
597 (const_string "evex")
598 ]
599 (const_string "orig")))
600
601 ;; VEX W bit is used.
602 (define_attr "prefix_vex_w" "" (const_int 0))
603
604 ;; The length of VEX prefix
605 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
606 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
607 ;; still prefix_0f 1, with prefix_extra 1.
608 (define_attr "length_vex" ""
609 (if_then_else (and (eq_attr "prefix_0f" "1")
610 (eq_attr "prefix_extra" "0"))
611 (if_then_else (eq_attr "prefix_vex_w" "1")
612 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
613 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
614 (if_then_else (eq_attr "prefix_vex_w" "1")
615 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
616 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
617
618 ;; 4-bytes evex prefix and 1 byte opcode.
619 (define_attr "length_evex" "" (const_int 5))
620
621 ;; Set when modrm byte is used.
622 (define_attr "modrm" ""
623 (cond [(eq_attr "type" "str,leave")
624 (const_int 0)
625 (eq_attr "unit" "i387")
626 (const_int 0)
627 (and (eq_attr "type" "incdec")
628 (and (not (match_test "TARGET_64BIT"))
629 (ior (match_operand:SI 1 "register_operand")
630 (match_operand:HI 1 "register_operand"))))
631 (const_int 0)
632 (and (eq_attr "type" "push")
633 (not (match_operand 1 "memory_operand")))
634 (const_int 0)
635 (and (eq_attr "type" "pop")
636 (not (match_operand 0 "memory_operand")))
637 (const_int 0)
638 (and (eq_attr "type" "imov")
639 (and (not (eq_attr "mode" "DI"))
640 (ior (and (match_operand 0 "register_operand")
641 (match_operand 1 "immediate_operand"))
642 (ior (and (match_operand 0 "ax_reg_operand")
643 (match_operand 1 "memory_displacement_only_operand"))
644 (and (match_operand 0 "memory_displacement_only_operand")
645 (match_operand 1 "ax_reg_operand"))))))
646 (const_int 0)
647 (and (eq_attr "type" "call")
648 (match_operand 0 "constant_call_address_operand"))
649 (const_int 0)
650 (and (eq_attr "type" "callv")
651 (match_operand 1 "constant_call_address_operand"))
652 (const_int 0)
653 (and (eq_attr "type" "alu,alu1,icmp,test")
654 (match_operand 0 "ax_reg_operand"))
655 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
656 ]
657 (const_int 1)))
658
659 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
660 (cond [(eq_attr "modrm" "0")
661 (const_string "none")
662 (eq_attr "type" "alu,imul,ishift")
663 (const_string "op02")
664 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
665 (const_string "op01")
666 (eq_attr "type" "incdec")
667 (const_string "incdec")
668 (eq_attr "type" "push,pop")
669 (const_string "pushpop")]
670 (const_string "unknown")))
671
672 ;; The (bounding maximum) length of an instruction in bytes.
673 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
674 ;; Later we may want to split them and compute proper length as for
675 ;; other insns.
676 (define_attr "length" ""
677 (cond [(eq_attr "type" "other,multi,fistp,frndint")
678 (const_int 16)
679 (eq_attr "type" "fcmp")
680 (const_int 4)
681 (eq_attr "unit" "i387")
682 (plus (const_int 2)
683 (plus (attr "prefix_data16")
684 (attr "length_address")))
685 (ior (eq_attr "prefix" "evex")
686 (and (ior (eq_attr "prefix" "maybe_evex")
687 (eq_attr "prefix" "maybe_vex"))
688 (match_test "TARGET_AVX512F")))
689 (plus (attr "length_evex")
690 (plus (attr "length_immediate")
691 (plus (attr "modrm")
692 (attr "length_address"))))
693 (ior (eq_attr "prefix" "vex")
694 (and (ior (eq_attr "prefix" "maybe_vex")
695 (eq_attr "prefix" "maybe_evex"))
696 (match_test "TARGET_AVX")))
697 (plus (attr "length_vex")
698 (plus (attr "length_immediate")
699 (plus (attr "modrm")
700 (attr "length_address"))))]
701 (plus (plus (attr "modrm")
702 (plus (attr "prefix_0f")
703 (plus (attr "prefix_rex")
704 (plus (attr "prefix_extra")
705 (const_int 1)))))
706 (plus (attr "prefix_rep")
707 (plus (attr "prefix_data16")
708 (plus (attr "length_immediate")
709 (attr "length_address")))))))
710
711 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
712 ;; `store' if there is a simple memory reference therein, or `unknown'
713 ;; if the instruction is complex.
714
715 (define_attr "memory" "none,load,store,both,unknown"
716 (cond [(eq_attr "type" "other,multi,str,lwp")
717 (const_string "unknown")
718 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
719 (const_string "none")
720 (eq_attr "type" "fistp,leave")
721 (const_string "both")
722 (eq_attr "type" "frndint")
723 (const_string "load")
724 (eq_attr "type" "mpxld")
725 (const_string "load")
726 (eq_attr "type" "mpxst")
727 (const_string "store")
728 (eq_attr "type" "push")
729 (if_then_else (match_operand 1 "memory_operand")
730 (const_string "both")
731 (const_string "store"))
732 (eq_attr "type" "pop")
733 (if_then_else (match_operand 0 "memory_operand")
734 (const_string "both")
735 (const_string "load"))
736 (eq_attr "type" "setcc")
737 (if_then_else (match_operand 0 "memory_operand")
738 (const_string "store")
739 (const_string "none"))
740 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
741 (if_then_else (ior (match_operand 0 "memory_operand")
742 (match_operand 1 "memory_operand"))
743 (const_string "load")
744 (const_string "none"))
745 (eq_attr "type" "ibr")
746 (if_then_else (match_operand 0 "memory_operand")
747 (const_string "load")
748 (const_string "none"))
749 (eq_attr "type" "call")
750 (if_then_else (match_operand 0 "constant_call_address_operand")
751 (const_string "none")
752 (const_string "load"))
753 (eq_attr "type" "callv")
754 (if_then_else (match_operand 1 "constant_call_address_operand")
755 (const_string "none")
756 (const_string "load"))
757 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
758 (match_operand 1 "memory_operand"))
759 (const_string "both")
760 (and (match_operand 0 "memory_operand")
761 (match_operand 1 "memory_operand"))
762 (const_string "both")
763 (match_operand 0 "memory_operand")
764 (const_string "store")
765 (match_operand 1 "memory_operand")
766 (const_string "load")
767 (and (eq_attr "type"
768 "!alu1,negnot,ishift1,rotate1,
769 imov,imovx,icmp,test,bitmanip,
770 fmov,fcmp,fsgn,
771 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
772 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
773 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
774 (match_operand 2 "memory_operand"))
775 (const_string "load")
776 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
777 (match_operand 3 "memory_operand"))
778 (const_string "load")
779 ]
780 (const_string "none")))
781
782 ;; Indicates if an instruction has both an immediate and a displacement.
783
784 (define_attr "imm_disp" "false,true,unknown"
785 (cond [(eq_attr "type" "other,multi")
786 (const_string "unknown")
787 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
788 (and (match_operand 0 "memory_displacement_operand")
789 (match_operand 1 "immediate_operand")))
790 (const_string "true")
791 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
792 (and (match_operand 0 "memory_displacement_operand")
793 (match_operand 2 "immediate_operand")))
794 (const_string "true")
795 ]
796 (const_string "false")))
797
798 ;; Indicates if an FP operation has an integer source.
799
800 (define_attr "fp_int_src" "false,true"
801 (const_string "false"))
802
803 ;; Defines rounding mode of an FP operation.
804
805 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
806 (const_string "any"))
807
808 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
809 (define_attr "use_carry" "0,1" (const_string "0"))
810
811 ;; Define attribute to indicate unaligned ssemov insns
812 (define_attr "movu" "0,1" (const_string "0"))
813
814 ;; Used to control the "enabled" attribute on a per-instruction basis.
815 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
816 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
817 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
818 avx512bw,noavx512bw,avx512dq,noavx512dq,
819 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
820 (const_string "base"))
821
822 (define_attr "enabled" ""
823 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
824 (eq_attr "isa" "x64_sse2")
825 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
826 (eq_attr "isa" "x64_sse4")
827 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
828 (eq_attr "isa" "x64_sse4_noavx")
829 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
830 (eq_attr "isa" "x64_avx")
831 (symbol_ref "TARGET_64BIT && TARGET_AVX")
832 (eq_attr "isa" "x64_avx512dq")
833 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
834 (eq_attr "isa" "x64_avx512bw")
835 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
836 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
837 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
838 (eq_attr "isa" "sse2_noavx")
839 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
840 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
841 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
842 (eq_attr "isa" "sse4_noavx")
843 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
844 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
845 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
846 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
847 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
848 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
849 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
850 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
851 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
852 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
853 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
854 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
855 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
856 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
857 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
858 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
859 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
860 ]
861 (const_int 1)))
862
863 (define_attr "preferred_for_size" "" (const_int 1))
864 (define_attr "preferred_for_speed" "" (const_int 1))
865
866 ;; Describe a user's asm statement.
867 (define_asm_attributes
868 [(set_attr "length" "128")
869 (set_attr "type" "multi")])
870
871 (define_code_iterator plusminus [plus minus])
872
873 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
874
875 (define_code_iterator multdiv [mult div])
876
877 ;; Base name for define_insn
878 (define_code_attr plusminus_insn
879 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
880 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
881
882 ;; Base name for insn mnemonic.
883 (define_code_attr plusminus_mnemonic
884 [(plus "add") (ss_plus "adds") (us_plus "addus")
885 (minus "sub") (ss_minus "subs") (us_minus "subus")])
886 (define_code_attr multdiv_mnemonic
887 [(mult "mul") (div "div")])
888
889 ;; Mark commutative operators as such in constraints.
890 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
891 (minus "") (ss_minus "") (us_minus "")])
892
893 ;; Mapping of max and min
894 (define_code_iterator maxmin [smax smin umax umin])
895
896 ;; Mapping of signed max and min
897 (define_code_iterator smaxmin [smax smin])
898
899 ;; Mapping of unsigned max and min
900 (define_code_iterator umaxmin [umax umin])
901
902 ;; Base name for integer and FP insn mnemonic
903 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
904 (umax "maxu") (umin "minu")])
905 (define_code_attr maxmin_float [(smax "max") (smin "min")])
906
907 (define_int_iterator IEEE_MAXMIN
908 [UNSPEC_IEEE_MAX
909 UNSPEC_IEEE_MIN])
910
911 (define_int_attr ieee_maxmin
912 [(UNSPEC_IEEE_MAX "max")
913 (UNSPEC_IEEE_MIN "min")])
914
915 ;; Mapping of logic operators
916 (define_code_iterator any_logic [and ior xor])
917 (define_code_iterator any_or [ior xor])
918 (define_code_iterator fpint_logic [and xor])
919
920 ;; Base name for insn mnemonic.
921 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
922
923 ;; Mapping of logic-shift operators
924 (define_code_iterator any_lshift [ashift lshiftrt])
925
926 ;; Mapping of shift-right operators
927 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
928
929 ;; Mapping of all shift operators
930 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
931
932 ;; Base name for define_insn
933 (define_code_attr shift_insn
934 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
935
936 ;; Base name for insn mnemonic.
937 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
938 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
939
940 ;; Mapping of rotate operators
941 (define_code_iterator any_rotate [rotate rotatert])
942
943 ;; Base name for define_insn
944 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
945
946 ;; Base name for insn mnemonic.
947 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
948
949 ;; Mapping of abs neg operators
950 (define_code_iterator absneg [abs neg])
951
952 ;; Base name for x87 insn mnemonic.
953 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
954
955 ;; Used in signed and unsigned widening multiplications.
956 (define_code_iterator any_extend [sign_extend zero_extend])
957
958 ;; Prefix for insn menmonic.
959 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
960
961 ;; Prefix for define_insn
962 (define_code_attr u [(sign_extend "") (zero_extend "u")])
963 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
964 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
965
966 ;; Used in signed and unsigned truncations.
967 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
968 ;; Instruction suffix for truncations.
969 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
970
971 ;; Used in signed and unsigned fix.
972 (define_code_iterator any_fix [fix unsigned_fix])
973 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
974
975 ;; Used in signed and unsigned float.
976 (define_code_iterator any_float [float unsigned_float])
977 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
978
979 ;; All integer modes.
980 (define_mode_iterator SWI1248x [QI HI SI DI])
981
982 ;; All integer modes without QImode.
983 (define_mode_iterator SWI248x [HI SI DI])
984
985 ;; All integer modes without QImode and HImode.
986 (define_mode_iterator SWI48x [SI DI])
987
988 ;; All integer modes without SImode and DImode.
989 (define_mode_iterator SWI12 [QI HI])
990
991 ;; All integer modes without DImode.
992 (define_mode_iterator SWI124 [QI HI SI])
993
994 ;; All integer modes without QImode and DImode.
995 (define_mode_iterator SWI24 [HI SI])
996
997 ;; Single word integer modes.
998 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
999
1000 ;; Single word integer modes without QImode.
1001 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1002
1003 ;; Single word integer modes without QImode and HImode.
1004 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1005
1006 ;; All math-dependant single and double word integer modes.
1007 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1008 (HI "TARGET_HIMODE_MATH")
1009 SI DI (TI "TARGET_64BIT")])
1010
1011 ;; Math-dependant single word integer modes.
1012 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1013 (HI "TARGET_HIMODE_MATH")
1014 SI (DI "TARGET_64BIT")])
1015
1016 ;; Math-dependant integer modes without DImode.
1017 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1018 (HI "TARGET_HIMODE_MATH")
1019 SI])
1020
1021 ;; Math-dependant integer modes with DImode.
1022 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1023 (HI "TARGET_HIMODE_MATH")
1024 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1025
1026 ;; Math-dependant single word integer modes without QImode.
1027 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1028 SI (DI "TARGET_64BIT")])
1029
1030 ;; Double word integer modes.
1031 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1032 (TI "TARGET_64BIT")])
1033
1034 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1035 ;; compile time constant, it is faster to use <MODE_SIZE> than
1036 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1037 ;; command line options just use GET_MODE_SIZE macro.
1038 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1039 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1040 (V16QI "16") (V32QI "32") (V64QI "64")
1041 (V8HI "16") (V16HI "32") (V32HI "64")
1042 (V4SI "16") (V8SI "32") (V16SI "64")
1043 (V2DI "16") (V4DI "32") (V8DI "64")
1044 (V1TI "16") (V2TI "32") (V4TI "64")
1045 (V2DF "16") (V4DF "32") (V8DF "64")
1046 (V4SF "16") (V8SF "32") (V16SF "64")])
1047
1048 ;; Double word integer modes as mode attribute.
1049 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1050 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1051
1052 ;; LEA mode corresponding to an integer mode
1053 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1054
1055 ;; Half mode for double word integer modes.
1056 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1057 (DI "TARGET_64BIT")])
1058
1059 ;; Bound modes.
1060 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1061 (BND64 "TARGET_LP64")])
1062
1063 ;; Pointer mode corresponding to bound mode.
1064 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1065
1066 ;; MPX check types
1067 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1068
1069 ;; Check name
1070 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1071 (UNSPEC_BNDCU "cu")
1072 (UNSPEC_BNDCN "cn")])
1073
1074 ;; Instruction suffix for integer modes.
1075 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1076
1077 ;; Instruction suffix for masks.
1078 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1079
1080 ;; Pointer size prefix for integer modes (Intel asm dialect)
1081 (define_mode_attr iptrsize [(QI "BYTE")
1082 (HI "WORD")
1083 (SI "DWORD")
1084 (DI "QWORD")])
1085
1086 ;; Register class for integer modes.
1087 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1088
1089 ;; Immediate operand constraint for integer modes.
1090 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1091
1092 ;; General operand constraint for word modes.
1093 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1094
1095 ;; Immediate operand constraint for double integer modes.
1096 (define_mode_attr di [(SI "nF") (DI "Wd")])
1097
1098 ;; Immediate operand constraint for shifts.
1099 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1100
1101 ;; Print register name in the specified mode.
1102 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1103
1104 ;; General operand predicate for integer modes.
1105 (define_mode_attr general_operand
1106 [(QI "general_operand")
1107 (HI "general_operand")
1108 (SI "x86_64_general_operand")
1109 (DI "x86_64_general_operand")
1110 (TI "x86_64_general_operand")])
1111
1112 ;; General operand predicate for integer modes, where for TImode
1113 ;; we need both words of the operand to be general operands.
1114 (define_mode_attr general_hilo_operand
1115 [(QI "general_operand")
1116 (HI "general_operand")
1117 (SI "x86_64_general_operand")
1118 (DI "x86_64_general_operand")
1119 (TI "x86_64_hilo_general_operand")])
1120
1121 ;; General sign extend operand predicate for integer modes,
1122 ;; which disallows VOIDmode operands and thus it is suitable
1123 ;; for use inside sign_extend.
1124 (define_mode_attr general_sext_operand
1125 [(QI "sext_operand")
1126 (HI "sext_operand")
1127 (SI "x86_64_sext_operand")
1128 (DI "x86_64_sext_operand")])
1129
1130 ;; General sign/zero extend operand predicate for integer modes.
1131 (define_mode_attr general_szext_operand
1132 [(QI "general_operand")
1133 (HI "general_operand")
1134 (SI "x86_64_szext_general_operand")
1135 (DI "x86_64_szext_general_operand")])
1136
1137 ;; Immediate operand predicate for integer modes.
1138 (define_mode_attr immediate_operand
1139 [(QI "immediate_operand")
1140 (HI "immediate_operand")
1141 (SI "x86_64_immediate_operand")
1142 (DI "x86_64_immediate_operand")])
1143
1144 ;; Nonmemory operand predicate for integer modes.
1145 (define_mode_attr nonmemory_operand
1146 [(QI "nonmemory_operand")
1147 (HI "nonmemory_operand")
1148 (SI "x86_64_nonmemory_operand")
1149 (DI "x86_64_nonmemory_operand")])
1150
1151 ;; Operand predicate for shifts.
1152 (define_mode_attr shift_operand
1153 [(QI "nonimmediate_operand")
1154 (HI "nonimmediate_operand")
1155 (SI "nonimmediate_operand")
1156 (DI "shiftdi_operand")
1157 (TI "register_operand")])
1158
1159 ;; Operand predicate for shift argument.
1160 (define_mode_attr shift_immediate_operand
1161 [(QI "const_1_to_31_operand")
1162 (HI "const_1_to_31_operand")
1163 (SI "const_1_to_31_operand")
1164 (DI "const_1_to_63_operand")])
1165
1166 ;; Input operand predicate for arithmetic left shifts.
1167 (define_mode_attr ashl_input_operand
1168 [(QI "nonimmediate_operand")
1169 (HI "nonimmediate_operand")
1170 (SI "nonimmediate_operand")
1171 (DI "ashldi_input_operand")
1172 (TI "reg_or_pm1_operand")])
1173
1174 ;; SSE and x87 SFmode and DFmode floating point modes
1175 (define_mode_iterator MODEF [SF DF])
1176
1177 ;; All x87 floating point modes
1178 (define_mode_iterator X87MODEF [SF DF XF])
1179
1180 ;; SSE instruction suffix for various modes
1181 (define_mode_attr ssemodesuffix
1182 [(SF "ss") (DF "sd")
1183 (V16SF "ps") (V8DF "pd")
1184 (V8SF "ps") (V4DF "pd")
1185 (V4SF "ps") (V2DF "pd")
1186 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1187 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1188 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1189
1190 ;; SSE vector suffix for floating point modes
1191 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1192
1193 ;; SSE vector mode corresponding to a scalar mode
1194 (define_mode_attr ssevecmode
1195 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1196 (define_mode_attr ssevecmodelower
1197 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1198
1199 ;; AVX512F vector mode corresponding to a scalar mode
1200 (define_mode_attr avx512fvecmode
1201 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1202
1203 ;; Instruction suffix for REX 64bit operators.
1204 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1205
1206 ;; This mode iterator allows :P to be used for patterns that operate on
1207 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1208 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1209
1210 ;; This mode iterator allows :W to be used for patterns that operate on
1211 ;; word_mode sized quantities.
1212 (define_mode_iterator W
1213 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1214
1215 ;; This mode iterator allows :PTR to be used for patterns that operate on
1216 ;; ptr_mode sized quantities.
1217 (define_mode_iterator PTR
1218 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1219 \f
1220 ;; Scheduling descriptions
1221
1222 (include "pentium.md")
1223 (include "ppro.md")
1224 (include "k6.md")
1225 (include "athlon.md")
1226 (include "bdver1.md")
1227 (include "bdver3.md")
1228 (include "btver2.md")
1229 (include "znver1.md")
1230 (include "geode.md")
1231 (include "atom.md")
1232 (include "slm.md")
1233 (include "glm.md")
1234 (include "core2.md")
1235 (include "haswell.md")
1236
1237 \f
1238 ;; Operand and operator predicates and constraints
1239
1240 (include "predicates.md")
1241 (include "constraints.md")
1242
1243 \f
1244 ;; Compare and branch/compare and store instructions.
1245
1246 (define_expand "cbranch<mode>4"
1247 [(set (reg:CC FLAGS_REG)
1248 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1249 (match_operand:SDWIM 2 "<general_operand>")))
1250 (set (pc) (if_then_else
1251 (match_operator 0 "ordered_comparison_operator"
1252 [(reg:CC FLAGS_REG) (const_int 0)])
1253 (label_ref (match_operand 3))
1254 (pc)))]
1255 ""
1256 {
1257 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1258 operands[1] = force_reg (<MODE>mode, operands[1]);
1259 ix86_expand_branch (GET_CODE (operands[0]),
1260 operands[1], operands[2], operands[3]);
1261 DONE;
1262 })
1263
1264 (define_expand "cstore<mode>4"
1265 [(set (reg:CC FLAGS_REG)
1266 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1267 (match_operand:SWIM 3 "<general_operand>")))
1268 (set (match_operand:QI 0 "register_operand")
1269 (match_operator 1 "ordered_comparison_operator"
1270 [(reg:CC FLAGS_REG) (const_int 0)]))]
1271 ""
1272 {
1273 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1274 operands[2] = force_reg (<MODE>mode, operands[2]);
1275 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1276 operands[2], operands[3]);
1277 DONE;
1278 })
1279
1280 (define_expand "cmp<mode>_1"
1281 [(set (reg:CC FLAGS_REG)
1282 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1283 (match_operand:SWI48 1 "<general_operand>")))])
1284
1285 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1286 [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1287 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1288
1289 (define_insn "*cmp<mode>_ccz_1"
1290 [(set (reg FLAGS_REG)
1291 (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1292 "nonimmediate_operand" "<r>,?m<r>,$k")
1293 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1294 "ix86_match_ccmode (insn, CCZmode)"
1295 "@
1296 test{<imodesuffix>}\t%0, %0
1297 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1298 ktest<mskmodesuffix>\t%0, %0"
1299 [(set_attr "type" "test,icmp,msklog")
1300 (set_attr "length_immediate" "0,1,*")
1301 (set_attr "modrm_class" "op0,unknown,*")
1302 (set_attr "prefix" "*,*,vex")
1303 (set_attr "mode" "<MODE>")])
1304
1305 (define_insn "*cmp<mode>_ccno_1"
1306 [(set (reg FLAGS_REG)
1307 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1308 (match_operand:SWI 1 "const0_operand")))]
1309 "ix86_match_ccmode (insn, CCNOmode)"
1310 "@
1311 test{<imodesuffix>}\t%0, %0
1312 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1313 [(set_attr "type" "test,icmp")
1314 (set_attr "length_immediate" "0,1")
1315 (set_attr "modrm_class" "op0,unknown")
1316 (set_attr "mode" "<MODE>")])
1317
1318 (define_insn "*cmp<mode>_1"
1319 [(set (reg FLAGS_REG)
1320 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1321 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1322 "ix86_match_ccmode (insn, CCmode)"
1323 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1324 [(set_attr "type" "icmp")
1325 (set_attr "mode" "<MODE>")])
1326
1327 (define_insn "*cmp<mode>_minus_1"
1328 [(set (reg FLAGS_REG)
1329 (compare
1330 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1331 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1332 (const_int 0)))]
1333 "ix86_match_ccmode (insn, CCGOCmode)"
1334 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1335 [(set_attr "type" "icmp")
1336 (set_attr "mode" "<MODE>")])
1337
1338 (define_insn "*cmpqi_ext_1"
1339 [(set (reg FLAGS_REG)
1340 (compare
1341 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1342 (subreg:QI
1343 (zero_extract:SI
1344 (match_operand 1 "ext_register_operand" "Q,Q")
1345 (const_int 8)
1346 (const_int 8)) 0)))]
1347 "ix86_match_ccmode (insn, CCmode)"
1348 "cmp{b}\t{%h1, %0|%0, %h1}"
1349 [(set_attr "isa" "*,nox64")
1350 (set_attr "type" "icmp")
1351 (set_attr "mode" "QI")])
1352
1353 (define_insn "*cmpqi_ext_2"
1354 [(set (reg FLAGS_REG)
1355 (compare
1356 (subreg:QI
1357 (zero_extract:SI
1358 (match_operand 0 "ext_register_operand" "Q")
1359 (const_int 8)
1360 (const_int 8)) 0)
1361 (match_operand:QI 1 "const0_operand")))]
1362 "ix86_match_ccmode (insn, CCNOmode)"
1363 "test{b}\t%h0, %h0"
1364 [(set_attr "type" "test")
1365 (set_attr "length_immediate" "0")
1366 (set_attr "mode" "QI")])
1367
1368 (define_expand "cmpqi_ext_3"
1369 [(set (reg:CC FLAGS_REG)
1370 (compare:CC
1371 (subreg:QI
1372 (zero_extract:SI
1373 (match_operand 0 "ext_register_operand")
1374 (const_int 8)
1375 (const_int 8)) 0)
1376 (match_operand:QI 1 "const_int_operand")))])
1377
1378 (define_insn "*cmpqi_ext_3"
1379 [(set (reg FLAGS_REG)
1380 (compare
1381 (subreg:QI
1382 (zero_extract:SI
1383 (match_operand 0 "ext_register_operand" "Q,Q")
1384 (const_int 8)
1385 (const_int 8)) 0)
1386 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1387 "ix86_match_ccmode (insn, CCmode)"
1388 "cmp{b}\t{%1, %h0|%h0, %1}"
1389 [(set_attr "isa" "*,nox64")
1390 (set_attr "type" "icmp")
1391 (set_attr "mode" "QI")])
1392
1393 (define_insn "*cmpqi_ext_4"
1394 [(set (reg FLAGS_REG)
1395 (compare
1396 (subreg:QI
1397 (zero_extract:SI
1398 (match_operand 0 "ext_register_operand" "Q")
1399 (const_int 8)
1400 (const_int 8)) 0)
1401 (subreg:QI
1402 (zero_extract:SI
1403 (match_operand 1 "ext_register_operand" "Q")
1404 (const_int 8)
1405 (const_int 8)) 0)))]
1406 "ix86_match_ccmode (insn, CCmode)"
1407 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1408 [(set_attr "type" "icmp")
1409 (set_attr "mode" "QI")])
1410
1411 ;; These implement float point compares.
1412 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1413 ;; which would allow mix and match FP modes on the compares. Which is what
1414 ;; the old patterns did, but with many more of them.
1415
1416 (define_expand "cbranchxf4"
1417 [(set (reg:CC FLAGS_REG)
1418 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1419 (match_operand:XF 2 "nonmemory_operand")))
1420 (set (pc) (if_then_else
1421 (match_operator 0 "ix86_fp_comparison_operator"
1422 [(reg:CC FLAGS_REG)
1423 (const_int 0)])
1424 (label_ref (match_operand 3))
1425 (pc)))]
1426 "TARGET_80387"
1427 {
1428 ix86_expand_branch (GET_CODE (operands[0]),
1429 operands[1], operands[2], operands[3]);
1430 DONE;
1431 })
1432
1433 (define_expand "cstorexf4"
1434 [(set (reg:CC FLAGS_REG)
1435 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1436 (match_operand:XF 3 "nonmemory_operand")))
1437 (set (match_operand:QI 0 "register_operand")
1438 (match_operator 1 "ix86_fp_comparison_operator"
1439 [(reg:CC FLAGS_REG)
1440 (const_int 0)]))]
1441 "TARGET_80387"
1442 {
1443 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1444 operands[2], operands[3]);
1445 DONE;
1446 })
1447
1448 (define_expand "cbranch<mode>4"
1449 [(set (reg:CC FLAGS_REG)
1450 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1451 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1452 (set (pc) (if_then_else
1453 (match_operator 0 "ix86_fp_comparison_operator"
1454 [(reg:CC FLAGS_REG)
1455 (const_int 0)])
1456 (label_ref (match_operand 3))
1457 (pc)))]
1458 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1459 {
1460 ix86_expand_branch (GET_CODE (operands[0]),
1461 operands[1], operands[2], operands[3]);
1462 DONE;
1463 })
1464
1465 (define_expand "cstore<mode>4"
1466 [(set (reg:CC FLAGS_REG)
1467 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1468 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1469 (set (match_operand:QI 0 "register_operand")
1470 (match_operator 1 "ix86_fp_comparison_operator"
1471 [(reg:CC FLAGS_REG)
1472 (const_int 0)]))]
1473 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1474 {
1475 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1476 operands[2], operands[3]);
1477 DONE;
1478 })
1479
1480 (define_expand "cbranchcc4"
1481 [(set (pc) (if_then_else
1482 (match_operator 0 "comparison_operator"
1483 [(match_operand 1 "flags_reg_operand")
1484 (match_operand 2 "const0_operand")])
1485 (label_ref (match_operand 3))
1486 (pc)))]
1487 ""
1488 {
1489 ix86_expand_branch (GET_CODE (operands[0]),
1490 operands[1], operands[2], operands[3]);
1491 DONE;
1492 })
1493
1494 (define_expand "cstorecc4"
1495 [(set (match_operand:QI 0 "register_operand")
1496 (match_operator 1 "comparison_operator"
1497 [(match_operand 2 "flags_reg_operand")
1498 (match_operand 3 "const0_operand")]))]
1499 ""
1500 {
1501 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1502 operands[2], operands[3]);
1503 DONE;
1504 })
1505
1506
1507 ;; FP compares, step 1:
1508 ;; Set the FP condition codes.
1509
1510 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1511 ;; used to manage the reg stack popping would not be preserved.
1512
1513 (define_insn "*cmp<mode>_0_i387"
1514 [(set (match_operand:HI 0 "register_operand" "=a")
1515 (unspec:HI
1516 [(compare:CCFP
1517 (match_operand:X87MODEF 1 "register_operand" "f")
1518 (match_operand:X87MODEF 2 "const0_operand"))]
1519 UNSPEC_FNSTSW))]
1520 "TARGET_80387"
1521 "* return output_fp_compare (insn, operands, false, false);"
1522 [(set_attr "type" "multi")
1523 (set_attr "unit" "i387")
1524 (set_attr "mode" "<MODE>")])
1525
1526 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1527 [(set (reg:CCFP FLAGS_REG)
1528 (compare:CCFP
1529 (match_operand:X87MODEF 1 "register_operand" "f")
1530 (match_operand:X87MODEF 2 "const0_operand")))
1531 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1532 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1533 "#"
1534 "&& reload_completed"
1535 [(set (match_dup 0)
1536 (unspec:HI
1537 [(compare:CCFP (match_dup 1)(match_dup 2))]
1538 UNSPEC_FNSTSW))
1539 (set (reg:CC FLAGS_REG)
1540 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1541 ""
1542 [(set_attr "type" "multi")
1543 (set_attr "unit" "i387")
1544 (set_attr "mode" "<MODE>")])
1545
1546 (define_insn "*cmpxf_i387"
1547 [(set (match_operand:HI 0 "register_operand" "=a")
1548 (unspec:HI
1549 [(compare:CCFP
1550 (match_operand:XF 1 "register_operand" "f")
1551 (match_operand:XF 2 "register_operand" "f"))]
1552 UNSPEC_FNSTSW))]
1553 "TARGET_80387"
1554 "* return output_fp_compare (insn, operands, false, false);"
1555 [(set_attr "type" "multi")
1556 (set_attr "unit" "i387")
1557 (set_attr "mode" "XF")])
1558
1559 (define_insn_and_split "*cmpxf_cc_i387"
1560 [(set (reg:CCFP FLAGS_REG)
1561 (compare:CCFP
1562 (match_operand:XF 1 "register_operand" "f")
1563 (match_operand:XF 2 "register_operand" "f")))
1564 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1565 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1566 "#"
1567 "&& reload_completed"
1568 [(set (match_dup 0)
1569 (unspec:HI
1570 [(compare:CCFP (match_dup 1)(match_dup 2))]
1571 UNSPEC_FNSTSW))
1572 (set (reg:CC FLAGS_REG)
1573 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1574 ""
1575 [(set_attr "type" "multi")
1576 (set_attr "unit" "i387")
1577 (set_attr "mode" "XF")])
1578
1579 (define_insn "*cmp<mode>_i387"
1580 [(set (match_operand:HI 0 "register_operand" "=a")
1581 (unspec:HI
1582 [(compare:CCFP
1583 (match_operand:MODEF 1 "register_operand" "f")
1584 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1585 UNSPEC_FNSTSW))]
1586 "TARGET_80387"
1587 "* return output_fp_compare (insn, operands, false, false);"
1588 [(set_attr "type" "multi")
1589 (set_attr "unit" "i387")
1590 (set_attr "mode" "<MODE>")])
1591
1592 (define_insn_and_split "*cmp<mode>_cc_i387"
1593 [(set (reg:CCFP FLAGS_REG)
1594 (compare:CCFP
1595 (match_operand:MODEF 1 "register_operand" "f")
1596 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1597 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1598 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1599 "#"
1600 "&& reload_completed"
1601 [(set (match_dup 0)
1602 (unspec:HI
1603 [(compare:CCFP (match_dup 1)(match_dup 2))]
1604 UNSPEC_FNSTSW))
1605 (set (reg:CC FLAGS_REG)
1606 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1607 ""
1608 [(set_attr "type" "multi")
1609 (set_attr "unit" "i387")
1610 (set_attr "mode" "<MODE>")])
1611
1612 (define_insn "*cmpu<mode>_i387"
1613 [(set (match_operand:HI 0 "register_operand" "=a")
1614 (unspec:HI
1615 [(unspec:CCFP
1616 [(compare:CCFP
1617 (match_operand:X87MODEF 1 "register_operand" "f")
1618 (match_operand:X87MODEF 2 "register_operand" "f"))]
1619 UNSPEC_NOTRAP)]
1620 UNSPEC_FNSTSW))]
1621 "TARGET_80387"
1622 "* return output_fp_compare (insn, operands, false, true);"
1623 [(set_attr "type" "multi")
1624 (set_attr "unit" "i387")
1625 (set_attr "mode" "<MODE>")])
1626
1627 (define_insn_and_split "*cmpu<mode>_cc_i387"
1628 [(set (reg:CCFP FLAGS_REG)
1629 (unspec:CCFP
1630 [(compare:CCFP
1631 (match_operand:X87MODEF 1 "register_operand" "f")
1632 (match_operand:X87MODEF 2 "register_operand" "f"))]
1633 UNSPEC_NOTRAP))
1634 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1635 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1636 "#"
1637 "&& reload_completed"
1638 [(set (match_dup 0)
1639 (unspec:HI
1640 [(unspec:CCFP
1641 [(compare:CCFP (match_dup 1)(match_dup 2))]
1642 UNSPEC_NOTRAP)]
1643 UNSPEC_FNSTSW))
1644 (set (reg:CC FLAGS_REG)
1645 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1646 ""
1647 [(set_attr "type" "multi")
1648 (set_attr "unit" "i387")
1649 (set_attr "mode" "<MODE>")])
1650
1651 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1652 [(set (match_operand:HI 0 "register_operand" "=a")
1653 (unspec:HI
1654 [(compare:CCFP
1655 (match_operand:X87MODEF 1 "register_operand" "f")
1656 (float:X87MODEF
1657 (match_operand:SWI24 2 "memory_operand" "m")))]
1658 UNSPEC_FNSTSW))]
1659 "TARGET_80387
1660 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1661 || optimize_function_for_size_p (cfun))"
1662 "* return output_fp_compare (insn, operands, false, false);"
1663 [(set_attr "type" "multi")
1664 (set_attr "unit" "i387")
1665 (set_attr "fp_int_src" "true")
1666 (set_attr "mode" "<SWI24:MODE>")])
1667
1668 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1669 [(set (reg:CCFP FLAGS_REG)
1670 (compare:CCFP
1671 (match_operand:X87MODEF 1 "register_operand" "f")
1672 (float:X87MODEF
1673 (match_operand:SWI24 2 "memory_operand" "m"))))
1674 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1675 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1676 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1677 || optimize_function_for_size_p (cfun))"
1678 "#"
1679 "&& reload_completed"
1680 [(set (match_dup 0)
1681 (unspec:HI
1682 [(compare:CCFP
1683 (match_dup 1)
1684 (float:X87MODEF (match_dup 2)))]
1685 UNSPEC_FNSTSW))
1686 (set (reg:CC FLAGS_REG)
1687 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1688 ""
1689 [(set_attr "type" "multi")
1690 (set_attr "unit" "i387")
1691 (set_attr "fp_int_src" "true")
1692 (set_attr "mode" "<SWI24:MODE>")])
1693
1694 ;; FP compares, step 2
1695 ;; Move the fpsw to ax.
1696
1697 (define_insn "x86_fnstsw_1"
1698 [(set (match_operand:HI 0 "register_operand" "=a")
1699 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1700 "TARGET_80387"
1701 "fnstsw\t%0"
1702 [(set_attr "length" "2")
1703 (set_attr "mode" "SI")
1704 (set_attr "unit" "i387")])
1705
1706 ;; FP compares, step 3
1707 ;; Get ax into flags, general case.
1708
1709 (define_insn "x86_sahf_1"
1710 [(set (reg:CC FLAGS_REG)
1711 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1712 UNSPEC_SAHF))]
1713 "TARGET_SAHF"
1714 {
1715 #ifndef HAVE_AS_IX86_SAHF
1716 if (TARGET_64BIT)
1717 return ASM_BYTE "0x9e";
1718 else
1719 #endif
1720 return "sahf";
1721 }
1722 [(set_attr "length" "1")
1723 (set_attr "athlon_decode" "vector")
1724 (set_attr "amdfam10_decode" "direct")
1725 (set_attr "bdver1_decode" "direct")
1726 (set_attr "mode" "SI")])
1727
1728 ;; Pentium Pro can do steps 1 through 3 in one go.
1729 ;; (these instructions set flags directly)
1730
1731 (define_subst_attr "unord" "unord_subst" "" "u")
1732 (define_subst_attr "unordered" "unord_subst" "false" "true")
1733
1734 (define_subst "unord_subst"
1735 [(set (match_operand:CCFP 0)
1736 (match_operand:CCFP 1))]
1737 ""
1738 [(set (match_dup 0)
1739 (unspec:CCFP
1740 [(match_dup 1)]
1741 UNSPEC_NOTRAP))])
1742
1743 (define_insn "*cmpi<unord><MODEF:mode>"
1744 [(set (reg:CCFP FLAGS_REG)
1745 (compare:CCFP
1746 (match_operand:MODEF 0 "register_operand" "f,v")
1747 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1748 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1749 || (TARGET_80387 && TARGET_CMOVE)"
1750 "@
1751 * return output_fp_compare (insn, operands, true, <unordered>);
1752 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1753 [(set_attr "type" "fcmp,ssecomi")
1754 (set_attr "prefix" "orig,maybe_vex")
1755 (set_attr "mode" "<MODEF:MODE>")
1756 (set_attr "prefix_rep" "*,0")
1757 (set (attr "prefix_data16")
1758 (cond [(eq_attr "alternative" "0")
1759 (const_string "*")
1760 (eq_attr "mode" "DF")
1761 (const_string "1")
1762 ]
1763 (const_string "0")))
1764 (set_attr "athlon_decode" "vector")
1765 (set_attr "amdfam10_decode" "direct")
1766 (set_attr "bdver1_decode" "double")
1767 (set_attr "znver1_decode" "double")
1768 (set (attr "enabled")
1769 (if_then_else
1770 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1771 (if_then_else
1772 (eq_attr "alternative" "0")
1773 (symbol_ref "TARGET_MIX_SSE_I387")
1774 (symbol_ref "true"))
1775 (if_then_else
1776 (eq_attr "alternative" "0")
1777 (symbol_ref "true")
1778 (symbol_ref "false"))))])
1779
1780 (define_insn "*cmpi<unord>xf_i387"
1781 [(set (reg:CCFP FLAGS_REG)
1782 (compare:CCFP
1783 (match_operand:XF 0 "register_operand" "f")
1784 (match_operand:XF 1 "register_operand" "f")))]
1785 "TARGET_80387 && TARGET_CMOVE"
1786 "* return output_fp_compare (insn, operands, true, <unordered>);"
1787 [(set_attr "type" "fcmp")
1788 (set_attr "mode" "XF")
1789 (set_attr "athlon_decode" "vector")
1790 (set_attr "amdfam10_decode" "direct")
1791 (set_attr "bdver1_decode" "double")
1792 (set_attr "znver1_decode" "double")])
1793 \f
1794 ;; Push/pop instructions.
1795
1796 (define_insn "*push<mode>2"
1797 [(set (match_operand:DWI 0 "push_operand" "=<")
1798 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1799 ""
1800 "#"
1801 [(set_attr "type" "multi")
1802 (set_attr "mode" "<MODE>")])
1803
1804 (define_split
1805 [(set (match_operand:DWI 0 "push_operand")
1806 (match_operand:DWI 1 "general_gr_operand"))]
1807 "reload_completed"
1808 [(const_int 0)]
1809 "ix86_split_long_move (operands); DONE;")
1810
1811 (define_insn "*pushdi2_rex64"
1812 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1813 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1814 "TARGET_64BIT"
1815 "@
1816 push{q}\t%1
1817 #"
1818 [(set_attr "type" "push,multi")
1819 (set_attr "mode" "DI")])
1820
1821 ;; Convert impossible pushes of immediate to existing instructions.
1822 ;; First try to get scratch register and go through it. In case this
1823 ;; fails, push sign extended lower part first and then overwrite
1824 ;; upper part by 32bit move.
1825 (define_peephole2
1826 [(match_scratch:DI 2 "r")
1827 (set (match_operand:DI 0 "push_operand")
1828 (match_operand:DI 1 "immediate_operand"))]
1829 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1830 && !x86_64_immediate_operand (operands[1], DImode)"
1831 [(set (match_dup 2) (match_dup 1))
1832 (set (match_dup 0) (match_dup 2))])
1833
1834 ;; We need to define this as both peepholer and splitter for case
1835 ;; peephole2 pass is not run.
1836 ;; "&& 1" is needed to keep it from matching the previous pattern.
1837 (define_peephole2
1838 [(set (match_operand:DI 0 "push_operand")
1839 (match_operand:DI 1 "immediate_operand"))]
1840 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1842 [(set (match_dup 0) (match_dup 1))
1843 (set (match_dup 2) (match_dup 3))]
1844 {
1845 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1846
1847 operands[1] = gen_lowpart (DImode, operands[2]);
1848 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1849 GEN_INT (4)));
1850 })
1851
1852 (define_split
1853 [(set (match_operand:DI 0 "push_operand")
1854 (match_operand:DI 1 "immediate_operand"))]
1855 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1856 ? epilogue_completed : reload_completed)
1857 && !symbolic_operand (operands[1], DImode)
1858 && !x86_64_immediate_operand (operands[1], DImode)"
1859 [(set (match_dup 0) (match_dup 1))
1860 (set (match_dup 2) (match_dup 3))]
1861 {
1862 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1863
1864 operands[1] = gen_lowpart (DImode, operands[2]);
1865 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1866 GEN_INT (4)));
1867 })
1868
1869 (define_insn "*pushsi2"
1870 [(set (match_operand:SI 0 "push_operand" "=<")
1871 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1872 "!TARGET_64BIT"
1873 "push{l}\t%1"
1874 [(set_attr "type" "push")
1875 (set_attr "mode" "SI")])
1876
1877 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1878 ;; "push a byte/word". But actually we use pushl, which has the effect
1879 ;; of rounding the amount pushed up to a word.
1880
1881 ;; For TARGET_64BIT we always round up to 8 bytes.
1882 (define_insn "*push<mode>2_rex64"
1883 [(set (match_operand:SWI124 0 "push_operand" "=X")
1884 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1885 "TARGET_64BIT"
1886 "push{q}\t%q1"
1887 [(set_attr "type" "push")
1888 (set_attr "mode" "DI")])
1889
1890 (define_insn "*push<mode>2"
1891 [(set (match_operand:SWI12 0 "push_operand" "=X")
1892 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1893 "!TARGET_64BIT"
1894 "push{l}\t%k1"
1895 [(set_attr "type" "push")
1896 (set_attr "mode" "SI")])
1897
1898 (define_insn "*push<mode>2_prologue"
1899 [(set (match_operand:W 0 "push_operand" "=<")
1900 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1901 (clobber (mem:BLK (scratch)))]
1902 ""
1903 "push{<imodesuffix>}\t%1"
1904 [(set_attr "type" "push")
1905 (set_attr "mode" "<MODE>")])
1906
1907 (define_insn "*pop<mode>1"
1908 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1909 (match_operand:W 1 "pop_operand" ">"))]
1910 ""
1911 "pop{<imodesuffix>}\t%0"
1912 [(set_attr "type" "pop")
1913 (set_attr "mode" "<MODE>")])
1914
1915 (define_insn "*pop<mode>1_epilogue"
1916 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1917 (match_operand:W 1 "pop_operand" ">"))
1918 (clobber (mem:BLK (scratch)))]
1919 ""
1920 "pop{<imodesuffix>}\t%0"
1921 [(set_attr "type" "pop")
1922 (set_attr "mode" "<MODE>")])
1923
1924 (define_insn "*pushfl<mode>2"
1925 [(set (match_operand:W 0 "push_operand" "=<")
1926 (match_operand:W 1 "flags_reg_operand"))]
1927 ""
1928 "pushf{<imodesuffix>}"
1929 [(set_attr "type" "push")
1930 (set_attr "mode" "<MODE>")])
1931
1932 (define_insn "*popfl<mode>1"
1933 [(set (match_operand:W 0 "flags_reg_operand")
1934 (match_operand:W 1 "pop_operand" ">"))]
1935 ""
1936 "popf{<imodesuffix>}"
1937 [(set_attr "type" "pop")
1938 (set_attr "mode" "<MODE>")])
1939
1940 \f
1941 ;; Reload patterns to support multi-word load/store
1942 ;; with non-offsetable address.
1943 (define_expand "reload_noff_store"
1944 [(parallel [(match_operand 0 "memory_operand" "=m")
1945 (match_operand 1 "register_operand" "r")
1946 (match_operand:DI 2 "register_operand" "=&r")])]
1947 "TARGET_64BIT"
1948 {
1949 rtx mem = operands[0];
1950 rtx addr = XEXP (mem, 0);
1951
1952 emit_move_insn (operands[2], addr);
1953 mem = replace_equiv_address_nv (mem, operands[2]);
1954
1955 emit_insn (gen_rtx_SET (mem, operands[1]));
1956 DONE;
1957 })
1958
1959 (define_expand "reload_noff_load"
1960 [(parallel [(match_operand 0 "register_operand" "=r")
1961 (match_operand 1 "memory_operand" "m")
1962 (match_operand:DI 2 "register_operand" "=r")])]
1963 "TARGET_64BIT"
1964 {
1965 rtx mem = operands[1];
1966 rtx addr = XEXP (mem, 0);
1967
1968 emit_move_insn (operands[2], addr);
1969 mem = replace_equiv_address_nv (mem, operands[2]);
1970
1971 emit_insn (gen_rtx_SET (operands[0], mem));
1972 DONE;
1973 })
1974
1975 ;; Move instructions.
1976
1977 (define_expand "movxi"
1978 [(set (match_operand:XI 0 "nonimmediate_operand")
1979 (match_operand:XI 1 "general_operand"))]
1980 "TARGET_AVX512F"
1981 "ix86_expand_vector_move (XImode, operands); DONE;")
1982
1983 (define_expand "movoi"
1984 [(set (match_operand:OI 0 "nonimmediate_operand")
1985 (match_operand:OI 1 "general_operand"))]
1986 "TARGET_AVX"
1987 "ix86_expand_vector_move (OImode, operands); DONE;")
1988
1989 (define_expand "movti"
1990 [(set (match_operand:TI 0 "nonimmediate_operand")
1991 (match_operand:TI 1 "general_operand"))]
1992 "TARGET_64BIT || TARGET_SSE"
1993 {
1994 if (TARGET_64BIT)
1995 ix86_expand_move (TImode, operands);
1996 else
1997 ix86_expand_vector_move (TImode, operands);
1998 DONE;
1999 })
2000
2001 ;; This expands to what emit_move_complex would generate if we didn't
2002 ;; have a movti pattern. Having this avoids problems with reload on
2003 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2004 ;; to have around all the time.
2005 (define_expand "movcdi"
2006 [(set (match_operand:CDI 0 "nonimmediate_operand")
2007 (match_operand:CDI 1 "general_operand"))]
2008 ""
2009 {
2010 if (push_operand (operands[0], CDImode))
2011 emit_move_complex_push (CDImode, operands[0], operands[1]);
2012 else
2013 emit_move_complex_parts (operands[0], operands[1]);
2014 DONE;
2015 })
2016
2017 (define_expand "mov<mode>"
2018 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2019 (match_operand:SWI1248x 1 "general_operand"))]
2020 ""
2021 "ix86_expand_move (<MODE>mode, operands); DONE;")
2022
2023 (define_insn "*mov<mode>_xor"
2024 [(set (match_operand:SWI48 0 "register_operand" "=r")
2025 (match_operand:SWI48 1 "const0_operand"))
2026 (clobber (reg:CC FLAGS_REG))]
2027 "reload_completed"
2028 "xor{l}\t%k0, %k0"
2029 [(set_attr "type" "alu1")
2030 (set_attr "modrm_class" "op0")
2031 (set_attr "mode" "SI")
2032 (set_attr "length_immediate" "0")])
2033
2034 (define_insn "*mov<mode>_or"
2035 [(set (match_operand:SWI48 0 "register_operand" "=r")
2036 (match_operand:SWI48 1 "constm1_operand"))
2037 (clobber (reg:CC FLAGS_REG))]
2038 "reload_completed"
2039 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2040 [(set_attr "type" "alu1")
2041 (set_attr "mode" "<MODE>")
2042 (set_attr "length_immediate" "1")])
2043
2044 (define_insn "*movxi_internal_avx512f"
2045 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2046 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2047 "TARGET_AVX512F
2048 && (register_operand (operands[0], XImode)
2049 || register_operand (operands[1], XImode))"
2050 {
2051 switch (get_attr_type (insn))
2052 {
2053 case TYPE_SSELOG1:
2054 return standard_sse_constant_opcode (insn, operands);
2055
2056 case TYPE_SSEMOV:
2057 if (misaligned_operand (operands[0], XImode)
2058 || misaligned_operand (operands[1], XImode))
2059 return "vmovdqu32\t{%1, %0|%0, %1}";
2060 else
2061 return "vmovdqa32\t{%1, %0|%0, %1}";
2062
2063 default:
2064 gcc_unreachable ();
2065 }
2066 }
2067 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2068 (set_attr "prefix" "evex")
2069 (set_attr "mode" "XI")])
2070
2071 (define_insn "*movoi_internal_avx"
2072 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2073 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2074 "TARGET_AVX
2075 && (register_operand (operands[0], OImode)
2076 || register_operand (operands[1], OImode))"
2077 {
2078 switch (get_attr_type (insn))
2079 {
2080 case TYPE_SSELOG1:
2081 return standard_sse_constant_opcode (insn, operands);
2082
2083 case TYPE_SSEMOV:
2084 if (misaligned_operand (operands[0], OImode)
2085 || misaligned_operand (operands[1], OImode))
2086 {
2087 if (get_attr_mode (insn) == MODE_V8SF)
2088 return "vmovups\t{%1, %0|%0, %1}";
2089 else if (get_attr_mode (insn) == MODE_XI)
2090 return "vmovdqu32\t{%1, %0|%0, %1}";
2091 else
2092 return "vmovdqu\t{%1, %0|%0, %1}";
2093 }
2094 else
2095 {
2096 if (get_attr_mode (insn) == MODE_V8SF)
2097 return "vmovaps\t{%1, %0|%0, %1}";
2098 else if (get_attr_mode (insn) == MODE_XI)
2099 return "vmovdqa32\t{%1, %0|%0, %1}";
2100 else
2101 return "vmovdqa\t{%1, %0|%0, %1}";
2102 }
2103
2104 default:
2105 gcc_unreachable ();
2106 }
2107 }
2108 [(set_attr "isa" "*,avx2,*,*")
2109 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2110 (set_attr "prefix" "vex")
2111 (set (attr "mode")
2112 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2113 (match_operand 1 "ext_sse_reg_operand"))
2114 (const_string "XI")
2115 (and (eq_attr "alternative" "1")
2116 (match_test "TARGET_AVX512VL"))
2117 (const_string "XI")
2118 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2119 (and (eq_attr "alternative" "3")
2120 (match_test "TARGET_SSE_TYPELESS_STORES")))
2121 (const_string "V8SF")
2122 ]
2123 (const_string "OI")))])
2124
2125 (define_insn "*movti_internal"
2126 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2127 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2128 "(TARGET_64BIT
2129 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2130 || (TARGET_SSE
2131 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2132 && (register_operand (operands[0], TImode)
2133 || register_operand (operands[1], TImode)))"
2134 {
2135 switch (get_attr_type (insn))
2136 {
2137 case TYPE_MULTI:
2138 return "#";
2139
2140 case TYPE_SSELOG1:
2141 return standard_sse_constant_opcode (insn, operands);
2142
2143 case TYPE_SSEMOV:
2144 /* TDmode values are passed as TImode on the stack. Moving them
2145 to stack may result in unaligned memory access. */
2146 if (misaligned_operand (operands[0], TImode)
2147 || misaligned_operand (operands[1], TImode))
2148 {
2149 if (get_attr_mode (insn) == MODE_V4SF)
2150 return "%vmovups\t{%1, %0|%0, %1}";
2151 else if (get_attr_mode (insn) == MODE_XI)
2152 return "vmovdqu32\t{%1, %0|%0, %1}";
2153 else
2154 return "%vmovdqu\t{%1, %0|%0, %1}";
2155 }
2156 else
2157 {
2158 if (get_attr_mode (insn) == MODE_V4SF)
2159 return "%vmovaps\t{%1, %0|%0, %1}";
2160 else if (get_attr_mode (insn) == MODE_XI)
2161 return "vmovdqa32\t{%1, %0|%0, %1}";
2162 else
2163 return "%vmovdqa\t{%1, %0|%0, %1}";
2164 }
2165
2166 default:
2167 gcc_unreachable ();
2168 }
2169 }
2170 [(set (attr "isa")
2171 (cond [(eq_attr "alternative" "0,1,6,7")
2172 (const_string "x64")
2173 (eq_attr "alternative" "3")
2174 (const_string "sse2")
2175 ]
2176 (const_string "*")))
2177 (set (attr "type")
2178 (cond [(eq_attr "alternative" "0,1,6,7")
2179 (const_string "multi")
2180 (eq_attr "alternative" "2,3")
2181 (const_string "sselog1")
2182 ]
2183 (const_string "ssemov")))
2184 (set (attr "prefix")
2185 (if_then_else (eq_attr "type" "sselog1,ssemov")
2186 (const_string "maybe_vex")
2187 (const_string "orig")))
2188 (set (attr "mode")
2189 (cond [(eq_attr "alternative" "0,1")
2190 (const_string "DI")
2191 (ior (match_operand 0 "ext_sse_reg_operand")
2192 (match_operand 1 "ext_sse_reg_operand"))
2193 (const_string "XI")
2194 (and (eq_attr "alternative" "3")
2195 (match_test "TARGET_AVX512VL"))
2196 (const_string "XI")
2197 (ior (not (match_test "TARGET_SSE2"))
2198 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2199 (and (eq_attr "alternative" "5")
2200 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2201 (const_string "V4SF")
2202 (match_test "TARGET_AVX")
2203 (const_string "TI")
2204 (match_test "optimize_function_for_size_p (cfun)")
2205 (const_string "V4SF")
2206 ]
2207 (const_string "TI")))
2208 (set (attr "preferred_for_speed")
2209 (cond [(eq_attr "alternative" "6")
2210 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2211 (eq_attr "alternative" "7")
2212 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2213 ]
2214 (symbol_ref "true")))])
2215
2216 (define_split
2217 [(set (match_operand:TI 0 "sse_reg_operand")
2218 (match_operand:TI 1 "general_reg_operand"))]
2219 "TARGET_64BIT && TARGET_SSE4_1
2220 && reload_completed"
2221 [(set (match_dup 2)
2222 (vec_merge:V2DI
2223 (vec_duplicate:V2DI (match_dup 3))
2224 (match_dup 2)
2225 (const_int 2)))]
2226 {
2227 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2228 operands[3] = gen_highpart (DImode, operands[1]);
2229
2230 emit_move_insn (gen_lowpart (DImode, operands[0]),
2231 gen_lowpart (DImode, operands[1]));
2232 })
2233
2234 (define_insn "*movdi_internal"
2235 [(set (match_operand:DI 0 "nonimmediate_operand"
2236 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m")
2237 (match_operand:DI 1 "general_operand"
2238 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k"))]
2239 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2240 {
2241 switch (get_attr_type (insn))
2242 {
2243 case TYPE_MSKMOV:
2244 return "kmovq\t{%1, %0|%0, %1}";
2245
2246 case TYPE_MULTI:
2247 return "#";
2248
2249 case TYPE_MMX:
2250 return "pxor\t%0, %0";
2251
2252 case TYPE_MMXMOV:
2253 /* Handle broken assemblers that require movd instead of movq. */
2254 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2255 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2256 return "movd\t{%1, %0|%0, %1}";
2257 return "movq\t{%1, %0|%0, %1}";
2258
2259 case TYPE_SSELOG1:
2260 return standard_sse_constant_opcode (insn, operands);
2261
2262 case TYPE_SSEMOV:
2263 switch (get_attr_mode (insn))
2264 {
2265 case MODE_DI:
2266 /* Handle broken assemblers that require movd instead of movq. */
2267 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2268 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2269 return "%vmovd\t{%1, %0|%0, %1}";
2270 return "%vmovq\t{%1, %0|%0, %1}";
2271
2272 case MODE_TI:
2273 /* Handle AVX512 registers set. */
2274 if (EXT_REX_SSE_REG_P (operands[0])
2275 || EXT_REX_SSE_REG_P (operands[1]))
2276 return "vmovdqa64\t{%1, %0|%0, %1}";
2277 return "%vmovdqa\t{%1, %0|%0, %1}";
2278
2279 case MODE_V2SF:
2280 gcc_assert (!TARGET_AVX);
2281 return "movlps\t{%1, %0|%0, %1}";
2282 case MODE_V4SF:
2283 return "%vmovaps\t{%1, %0|%0, %1}";
2284
2285 default:
2286 gcc_unreachable ();
2287 }
2288
2289 case TYPE_SSECVT:
2290 if (SSE_REG_P (operands[0]))
2291 return "movq2dq\t{%1, %0|%0, %1}";
2292 else
2293 return "movdq2q\t{%1, %0|%0, %1}";
2294
2295 case TYPE_LEA:
2296 return "lea{q}\t{%E1, %0|%0, %E1}";
2297
2298 case TYPE_IMOV:
2299 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2300 if (get_attr_mode (insn) == MODE_SI)
2301 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2302 else if (which_alternative == 4)
2303 return "movabs{q}\t{%1, %0|%0, %1}";
2304 else if (ix86_use_lea_for_mov (insn, operands))
2305 return "lea{q}\t{%E1, %0|%0, %E1}";
2306 else
2307 return "mov{q}\t{%1, %0|%0, %1}";
2308
2309 default:
2310 gcc_unreachable ();
2311 }
2312 }
2313 [(set (attr "isa")
2314 (cond [(eq_attr "alternative" "0,1,17,18")
2315 (const_string "nox64")
2316 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2317 (const_string "x64")
2318 (eq_attr "alternative" "19,20")
2319 (const_string "x64_sse2")
2320 (eq_attr "alternative" "21,22")
2321 (const_string "sse2")
2322 ]
2323 (const_string "*")))
2324 (set (attr "type")
2325 (cond [(eq_attr "alternative" "0,1,17,18")
2326 (const_string "multi")
2327 (eq_attr "alternative" "6")
2328 (const_string "mmx")
2329 (eq_attr "alternative" "7,8,9,10,11")
2330 (const_string "mmxmov")
2331 (eq_attr "alternative" "12")
2332 (const_string "sselog1")
2333 (eq_attr "alternative" "13,14,15,16,19,20")
2334 (const_string "ssemov")
2335 (eq_attr "alternative" "21,22")
2336 (const_string "ssecvt")
2337 (eq_attr "alternative" "23,24,25,26")
2338 (const_string "mskmov")
2339 (and (match_operand 0 "register_operand")
2340 (match_operand 1 "pic_32bit_operand"))
2341 (const_string "lea")
2342 ]
2343 (const_string "imov")))
2344 (set (attr "modrm")
2345 (if_then_else
2346 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2347 (const_string "0")
2348 (const_string "*")))
2349 (set (attr "length_immediate")
2350 (if_then_else
2351 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2352 (const_string "8")
2353 (const_string "*")))
2354 (set (attr "prefix_rex")
2355 (if_then_else
2356 (eq_attr "alternative" "10,11,19,20")
2357 (const_string "1")
2358 (const_string "*")))
2359 (set (attr "prefix")
2360 (if_then_else (eq_attr "type" "sselog1,ssemov")
2361 (const_string "maybe_vex")
2362 (const_string "orig")))
2363 (set (attr "prefix_data16")
2364 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2365 (const_string "1")
2366 (const_string "*")))
2367 (set (attr "mode")
2368 (cond [(eq_attr "alternative" "2")
2369 (const_string "SI")
2370 (eq_attr "alternative" "12,13")
2371 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2372 (match_operand 1 "ext_sse_reg_operand"))
2373 (const_string "TI")
2374 (ior (not (match_test "TARGET_SSE2"))
2375 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2376 (const_string "V4SF")
2377 (match_test "TARGET_AVX")
2378 (const_string "TI")
2379 (match_test "optimize_function_for_size_p (cfun)")
2380 (const_string "V4SF")
2381 ]
2382 (const_string "TI"))
2383
2384 (and (eq_attr "alternative" "14,15,16")
2385 (not (match_test "TARGET_SSE2")))
2386 (const_string "V2SF")
2387 ]
2388 (const_string "DI")))
2389 (set (attr "preferred_for_speed")
2390 (cond [(eq_attr "alternative" "10,17,19")
2391 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2392 (eq_attr "alternative" "11,18,20")
2393 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2394 ]
2395 (symbol_ref "true")))
2396 (set (attr "enabled")
2397 (cond [(eq_attr "alternative" "15")
2398 (if_then_else
2399 (match_test "TARGET_STV && TARGET_SSE2")
2400 (symbol_ref "false")
2401 (const_string "*"))
2402 (eq_attr "alternative" "16")
2403 (if_then_else
2404 (match_test "TARGET_STV && TARGET_SSE2")
2405 (symbol_ref "true")
2406 (symbol_ref "false"))
2407 ]
2408 (const_string "*")))])
2409
2410 (define_split
2411 [(set (match_operand:<DWI> 0 "general_reg_operand")
2412 (match_operand:<DWI> 1 "sse_reg_operand"))]
2413 "TARGET_SSE4_1
2414 && reload_completed"
2415 [(set (match_dup 2)
2416 (vec_select:DWIH
2417 (match_dup 3)
2418 (parallel [(const_int 1)])))]
2419 {
2420 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2421 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2422
2423 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2424 gen_lowpart (<MODE>mode, operands[1]));
2425 })
2426
2427 (define_split
2428 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2429 (match_operand:DWI 1 "general_gr_operand"))]
2430 "reload_completed"
2431 [(const_int 0)]
2432 "ix86_split_long_move (operands); DONE;")
2433
2434 (define_split
2435 [(set (match_operand:DI 0 "sse_reg_operand")
2436 (match_operand:DI 1 "general_reg_operand"))]
2437 "!TARGET_64BIT && TARGET_SSE4_1
2438 && reload_completed"
2439 [(set (match_dup 2)
2440 (vec_merge:V4SI
2441 (vec_duplicate:V4SI (match_dup 3))
2442 (match_dup 2)
2443 (const_int 2)))]
2444 {
2445 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2446 operands[3] = gen_highpart (SImode, operands[1]);
2447
2448 emit_move_insn (gen_lowpart (SImode, operands[0]),
2449 gen_lowpart (SImode, operands[1]));
2450 })
2451
2452 ;; movabsq $0x0012345678000000, %rax is longer
2453 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2454 (define_peephole2
2455 [(set (match_operand:DI 0 "register_operand")
2456 (match_operand:DI 1 "const_int_operand"))]
2457 "TARGET_64BIT
2458 && optimize_insn_for_size_p ()
2459 && LEGACY_INT_REG_P (operands[0])
2460 && !x86_64_immediate_operand (operands[1], DImode)
2461 && !x86_64_zext_immediate_operand (operands[1], DImode)
2462 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2463 & ~(HOST_WIDE_INT) 0xffffffff)
2464 && peep2_regno_dead_p (0, FLAGS_REG)"
2465 [(set (match_dup 0) (match_dup 1))
2466 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2467 (clobber (reg:CC FLAGS_REG))])]
2468 {
2469 int shift = ctz_hwi (UINTVAL (operands[1]));
2470 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2471 operands[2] = gen_int_mode (shift, QImode);
2472 })
2473
2474 (define_insn "*movsi_internal"
2475 [(set (match_operand:SI 0 "nonimmediate_operand"
2476 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm")
2477 (match_operand:SI 1 "general_operand"
2478 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k"))]
2479 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2480 {
2481 switch (get_attr_type (insn))
2482 {
2483 case TYPE_SSELOG1:
2484 return standard_sse_constant_opcode (insn, operands);
2485
2486 case TYPE_MSKMOV:
2487 return "kmovd\t{%1, %0|%0, %1}";
2488
2489 case TYPE_SSEMOV:
2490 switch (get_attr_mode (insn))
2491 {
2492 case MODE_SI:
2493 return "%vmovd\t{%1, %0|%0, %1}";
2494 case MODE_TI:
2495 return "%vmovdqa\t{%1, %0|%0, %1}";
2496 case MODE_XI:
2497 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2498
2499 case MODE_V4SF:
2500 return "%vmovaps\t{%1, %0|%0, %1}";
2501
2502 case MODE_SF:
2503 gcc_assert (!TARGET_AVX);
2504 return "movss\t{%1, %0|%0, %1}";
2505
2506 default:
2507 gcc_unreachable ();
2508 }
2509
2510 case TYPE_MMX:
2511 return "pxor\t%0, %0";
2512
2513 case TYPE_MMXMOV:
2514 switch (get_attr_mode (insn))
2515 {
2516 case MODE_DI:
2517 return "movq\t{%1, %0|%0, %1}";
2518 case MODE_SI:
2519 return "movd\t{%1, %0|%0, %1}";
2520
2521 default:
2522 gcc_unreachable ();
2523 }
2524
2525 case TYPE_LEA:
2526 return "lea{l}\t{%E1, %0|%0, %E1}";
2527
2528 case TYPE_IMOV:
2529 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2530 if (ix86_use_lea_for_mov (insn, operands))
2531 return "lea{l}\t{%E1, %0|%0, %E1}";
2532 else
2533 return "mov{l}\t{%1, %0|%0, %1}";
2534
2535 default:
2536 gcc_unreachable ();
2537 }
2538 }
2539 [(set (attr "isa")
2540 (cond [(eq_attr "alternative" "12,13")
2541 (const_string "sse2")
2542 ]
2543 (const_string "*")))
2544 (set (attr "type")
2545 (cond [(eq_attr "alternative" "2")
2546 (const_string "mmx")
2547 (eq_attr "alternative" "3,4,5,6,7")
2548 (const_string "mmxmov")
2549 (eq_attr "alternative" "8")
2550 (const_string "sselog1")
2551 (eq_attr "alternative" "9,10,11,12,13")
2552 (const_string "ssemov")
2553 (eq_attr "alternative" "14,15,16")
2554 (const_string "mskmov")
2555 (and (match_operand 0 "register_operand")
2556 (match_operand 1 "pic_32bit_operand"))
2557 (const_string "lea")
2558 ]
2559 (const_string "imov")))
2560 (set (attr "prefix")
2561 (if_then_else (eq_attr "type" "sselog1,ssemov")
2562 (const_string "maybe_vex")
2563 (const_string "orig")))
2564 (set (attr "prefix_data16")
2565 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2566 (const_string "1")
2567 (const_string "*")))
2568 (set (attr "mode")
2569 (cond [(eq_attr "alternative" "2,3")
2570 (const_string "DI")
2571 (eq_attr "alternative" "8,9")
2572 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2573 (match_operand 1 "ext_sse_reg_operand"))
2574 (const_string "XI")
2575 (ior (not (match_test "TARGET_SSE2"))
2576 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2577 (const_string "V4SF")
2578 (match_test "TARGET_AVX")
2579 (const_string "TI")
2580 (match_test "optimize_function_for_size_p (cfun)")
2581 (const_string "V4SF")
2582 ]
2583 (const_string "TI"))
2584
2585 (and (eq_attr "alternative" "10,11")
2586 (not (match_test "TARGET_SSE2")))
2587 (const_string "SF")
2588 ]
2589 (const_string "SI")))
2590 (set (attr "preferred_for_speed")
2591 (cond [(eq_attr "alternative" "6,12")
2592 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2593 (eq_attr "alternative" "7,13")
2594 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2595 ]
2596 (symbol_ref "true")))])
2597
2598 (define_insn "*movhi_internal"
2599 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2600 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2601 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2602 {
2603 switch (get_attr_type (insn))
2604 {
2605 case TYPE_IMOVX:
2606 /* movzwl is faster than movw on p2 due to partial word stalls,
2607 though not as fast as an aligned movl. */
2608 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2609
2610 case TYPE_MSKMOV:
2611 switch (which_alternative)
2612 {
2613 case 4:
2614 return "kmovw\t{%k1, %0|%0, %k1}";
2615 case 6:
2616 return "kmovw\t{%1, %k0|%k0, %1}";
2617 case 5:
2618 case 7:
2619 return "kmovw\t{%1, %0|%0, %1}";
2620 default:
2621 gcc_unreachable ();
2622 }
2623
2624 default:
2625 if (get_attr_mode (insn) == MODE_SI)
2626 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2627 else
2628 return "mov{w}\t{%1, %0|%0, %1}";
2629 }
2630 }
2631 [(set (attr "type")
2632 (cond [(eq_attr "alternative" "4,5,6,7")
2633 (const_string "mskmov")
2634 (match_test "optimize_function_for_size_p (cfun)")
2635 (const_string "imov")
2636 (and (eq_attr "alternative" "0")
2637 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2638 (not (match_test "TARGET_HIMODE_MATH"))))
2639 (const_string "imov")
2640 (and (eq_attr "alternative" "1,2")
2641 (match_operand:HI 1 "aligned_operand"))
2642 (const_string "imov")
2643 (and (match_test "TARGET_MOVX")
2644 (eq_attr "alternative" "0,2"))
2645 (const_string "imovx")
2646 ]
2647 (const_string "imov")))
2648 (set (attr "prefix")
2649 (if_then_else (eq_attr "alternative" "4,5,6,7")
2650 (const_string "vex")
2651 (const_string "orig")))
2652 (set (attr "mode")
2653 (cond [(eq_attr "type" "imovx")
2654 (const_string "SI")
2655 (and (eq_attr "alternative" "1,2")
2656 (match_operand:HI 1 "aligned_operand"))
2657 (const_string "SI")
2658 (and (eq_attr "alternative" "0")
2659 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2660 (not (match_test "TARGET_HIMODE_MATH"))))
2661 (const_string "SI")
2662 ]
2663 (const_string "HI")))])
2664
2665 ;; Situation is quite tricky about when to choose full sized (SImode) move
2666 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2667 ;; partial register dependency machines (such as AMD Athlon), where QImode
2668 ;; moves issue extra dependency and for partial register stalls machines
2669 ;; that don't use QImode patterns (and QImode move cause stall on the next
2670 ;; instruction).
2671 ;;
2672 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2673 ;; register stall machines with, where we use QImode instructions, since
2674 ;; partial register stall can be caused there. Then we use movzx.
2675
2676 (define_insn "*movqi_internal"
2677 [(set (match_operand:QI 0 "nonimmediate_operand"
2678 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2679 (match_operand:QI 1 "general_operand"
2680 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2681 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2682 {
2683 static char buf[128];
2684 const char *ops;
2685 const char *suffix;
2686
2687 switch (get_attr_type (insn))
2688 {
2689 case TYPE_IMOVX:
2690 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2691 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2692
2693 case TYPE_MSKMOV:
2694 switch (which_alternative)
2695 {
2696 case 9:
2697 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2698 break;
2699 case 11:
2700 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2701 break;
2702 case 12:
2703 case 13:
2704 gcc_assert (TARGET_AVX512DQ);
2705 /* FALLTHRU */
2706 case 10:
2707 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2708 break;
2709 default:
2710 gcc_unreachable ();
2711 }
2712
2713 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2714
2715 snprintf (buf, sizeof (buf), ops, suffix);
2716 return buf;
2717
2718 default:
2719 if (get_attr_mode (insn) == MODE_SI)
2720 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2721 else
2722 return "mov{b}\t{%1, %0|%0, %1}";
2723 }
2724 }
2725 [(set (attr "isa")
2726 (cond [(eq_attr "alternative" "1,2")
2727 (const_string "x64")
2728 (eq_attr "alternative" "12,13")
2729 (const_string "avx512dq")
2730 ]
2731 (const_string "*")))
2732 (set (attr "type")
2733 (cond [(eq_attr "alternative" "9,10,11,12,13")
2734 (const_string "mskmov")
2735 (and (eq_attr "alternative" "7")
2736 (not (match_operand:QI 1 "aligned_operand")))
2737 (const_string "imovx")
2738 (match_test "optimize_function_for_size_p (cfun)")
2739 (const_string "imov")
2740 (and (eq_attr "alternative" "5")
2741 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2742 (not (match_test "TARGET_QIMODE_MATH"))))
2743 (const_string "imov")
2744 (eq_attr "alternative" "5,7")
2745 (const_string "imovx")
2746 (and (match_test "TARGET_MOVX")
2747 (eq_attr "alternative" "4"))
2748 (const_string "imovx")
2749 ]
2750 (const_string "imov")))
2751 (set (attr "prefix")
2752 (if_then_else (eq_attr "alternative" "9,10,11")
2753 (const_string "vex")
2754 (const_string "orig")))
2755 (set (attr "mode")
2756 (cond [(eq_attr "alternative" "5,6,7")
2757 (const_string "SI")
2758 (eq_attr "alternative" "8")
2759 (const_string "QI")
2760 (and (eq_attr "alternative" "9,10,11")
2761 (not (match_test "TARGET_AVX512DQ")))
2762 (const_string "HI")
2763 (eq_attr "type" "imovx")
2764 (const_string "SI")
2765 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2766 ;; ones.
2767 (and (eq_attr "type" "imov")
2768 (and (eq_attr "alternative" "3")
2769 (match_test "optimize_function_for_size_p (cfun)")))
2770 (const_string "QI")
2771 ;; For -Os, movl where one or both operands are NON_Q_REGS
2772 ;; and both are LEGACY_REGS is shorter than movb.
2773 ;; Otherwise movb and movl sizes are the same, so decide purely
2774 ;; based on speed factors.
2775 (and (eq_attr "type" "imov")
2776 (and (eq_attr "alternative" "1")
2777 (match_test "optimize_function_for_size_p (cfun)")))
2778 (const_string "SI")
2779 (and (eq_attr "type" "imov")
2780 (and (eq_attr "alternative" "0,1,2,3")
2781 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2782 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2783 (const_string "SI")
2784 ;; Avoid partial register stalls when not using QImode arithmetic
2785 (and (eq_attr "type" "imov")
2786 (and (eq_attr "alternative" "0,1,2,3")
2787 (and (match_test "TARGET_PARTIAL_REG_STALL")
2788 (not (match_test "TARGET_QIMODE_MATH")))))
2789 (const_string "SI")
2790 ]
2791 (const_string "QI")))])
2792
2793 ;; Stores and loads of ax to arbitrary constant address.
2794 ;; We fake an second form of instruction to force reload to load address
2795 ;; into register when rax is not available
2796 (define_insn "*movabs<mode>_1"
2797 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2798 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2799 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2800 {
2801 /* Recover the full memory rtx. */
2802 operands[0] = SET_DEST (PATTERN (insn));
2803 switch (which_alternative)
2804 {
2805 case 0:
2806 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2807 case 1:
2808 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2809 default:
2810 gcc_unreachable ();
2811 }
2812 }
2813 [(set_attr "type" "imov")
2814 (set_attr "modrm" "0,*")
2815 (set_attr "length_address" "8,0")
2816 (set_attr "length_immediate" "0,*")
2817 (set_attr "memory" "store")
2818 (set_attr "mode" "<MODE>")])
2819
2820 (define_insn "*movabs<mode>_2"
2821 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2822 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2823 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2824 {
2825 /* Recover the full memory rtx. */
2826 operands[1] = SET_SRC (PATTERN (insn));
2827 switch (which_alternative)
2828 {
2829 case 0:
2830 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2831 case 1:
2832 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2833 default:
2834 gcc_unreachable ();
2835 }
2836 }
2837 [(set_attr "type" "imov")
2838 (set_attr "modrm" "0,*")
2839 (set_attr "length_address" "8,0")
2840 (set_attr "length_immediate" "0")
2841 (set_attr "memory" "load")
2842 (set_attr "mode" "<MODE>")])
2843
2844 (define_insn "*swap<mode>"
2845 [(set (match_operand:SWI48 0 "register_operand" "+r")
2846 (match_operand:SWI48 1 "register_operand" "+r"))
2847 (set (match_dup 1)
2848 (match_dup 0))]
2849 ""
2850 "xchg{<imodesuffix>}\t%1, %0"
2851 [(set_attr "type" "imov")
2852 (set_attr "mode" "<MODE>")
2853 (set_attr "pent_pair" "np")
2854 (set_attr "athlon_decode" "vector")
2855 (set_attr "amdfam10_decode" "double")
2856 (set_attr "bdver1_decode" "double")])
2857
2858 (define_insn "*swap<mode>"
2859 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2860 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2861 (set (match_dup 1)
2862 (match_dup 0))]
2863 ""
2864 "@
2865 xchg{<imodesuffix>}\t%1, %0
2866 xchg{l}\t%k1, %k0"
2867 [(set_attr "type" "imov")
2868 (set_attr "mode" "<MODE>,SI")
2869 (set (attr "preferred_for_size")
2870 (cond [(eq_attr "alternative" "0")
2871 (symbol_ref "false")]
2872 (symbol_ref "true")))
2873 ;; Potential partial reg stall on alternative 1.
2874 (set (attr "preferred_for_speed")
2875 (cond [(eq_attr "alternative" "1")
2876 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2877 (symbol_ref "true")))
2878 (set_attr "pent_pair" "np")
2879 (set_attr "athlon_decode" "vector")
2880 (set_attr "amdfam10_decode" "double")
2881 (set_attr "bdver1_decode" "double")])
2882
2883 (define_expand "movstrict<mode>"
2884 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2885 (match_operand:SWI12 1 "general_operand"))]
2886 ""
2887 {
2888 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2889 FAIL;
2890 if (SUBREG_P (operands[0])
2891 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2892 FAIL;
2893 /* Don't generate memory->memory moves, go through a register */
2894 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2895 operands[1] = force_reg (<MODE>mode, operands[1]);
2896 })
2897
2898 (define_insn "*movstrict<mode>_1"
2899 [(set (strict_low_part
2900 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2901 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2903 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2904 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2905 [(set_attr "type" "imov")
2906 (set_attr "mode" "<MODE>")])
2907
2908 (define_insn "*movstrict<mode>_xor"
2909 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2910 (match_operand:SWI12 1 "const0_operand"))
2911 (clobber (reg:CC FLAGS_REG))]
2912 "reload_completed"
2913 "xor{<imodesuffix>}\t%0, %0"
2914 [(set_attr "type" "alu1")
2915 (set_attr "modrm_class" "op0")
2916 (set_attr "mode" "<MODE>")
2917 (set_attr "length_immediate" "0")])
2918
2919 (define_expand "extv<mode>"
2920 [(set (match_operand:SWI24 0 "register_operand")
2921 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2922 (match_operand:SI 2 "const_int_operand")
2923 (match_operand:SI 3 "const_int_operand")))]
2924 ""
2925 {
2926 /* Handle extractions from %ah et al. */
2927 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2928 FAIL;
2929
2930 unsigned int regno = reg_or_subregno (operands[1]);
2931
2932 /* Be careful to expand only with registers having upper parts. */
2933 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2934 operands[1] = copy_to_reg (operands[1]);
2935 })
2936
2937 (define_insn "*extv<mode>"
2938 [(set (match_operand:SWI24 0 "register_operand" "=R")
2939 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2940 (const_int 8)
2941 (const_int 8)))]
2942 ""
2943 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2944 [(set_attr "type" "imovx")
2945 (set_attr "mode" "SI")])
2946
2947 (define_expand "extzv<mode>"
2948 [(set (match_operand:SWI248 0 "register_operand")
2949 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2950 (match_operand:SI 2 "const_int_operand")
2951 (match_operand:SI 3 "const_int_operand")))]
2952 ""
2953 {
2954 if (ix86_expand_pextr (operands))
2955 DONE;
2956
2957 /* Handle extractions from %ah et al. */
2958 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2959 FAIL;
2960
2961 unsigned int regno = reg_or_subregno (operands[1]);
2962
2963 /* Be careful to expand only with registers having upper parts. */
2964 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2965 operands[1] = copy_to_reg (operands[1]);
2966 })
2967
2968 (define_insn "*extzvqi_mem_rex64"
2969 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2970 (subreg:QI
2971 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2972 (const_int 8)
2973 (const_int 8)) 0))]
2974 "TARGET_64BIT && reload_completed"
2975 "mov{b}\t{%h1, %0|%0, %h1}"
2976 [(set_attr "type" "imov")
2977 (set_attr "mode" "QI")])
2978
2979 (define_insn "*extzv<mode>"
2980 [(set (match_operand:SWI248 0 "register_operand" "=R")
2981 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2982 (const_int 8)
2983 (const_int 8)))]
2984 ""
2985 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2986 [(set_attr "type" "imovx")
2987 (set_attr "mode" "SI")])
2988
2989 (define_insn "*extzvqi"
2990 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2991 (subreg:QI
2992 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2993 (const_int 8)
2994 (const_int 8)) 0))]
2995 ""
2996 {
2997 switch (get_attr_type (insn))
2998 {
2999 case TYPE_IMOVX:
3000 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3001 default:
3002 return "mov{b}\t{%h1, %0|%0, %h1}";
3003 }
3004 }
3005 [(set_attr "isa" "*,*,nox64")
3006 (set (attr "type")
3007 (if_then_else (and (match_operand:QI 0 "register_operand")
3008 (ior (not (match_operand:QI 0 "QIreg_operand"))
3009 (match_test "TARGET_MOVX")))
3010 (const_string "imovx")
3011 (const_string "imov")))
3012 (set (attr "mode")
3013 (if_then_else (eq_attr "type" "imovx")
3014 (const_string "SI")
3015 (const_string "QI")))])
3016
3017 (define_peephole2
3018 [(set (match_operand:QI 0 "register_operand")
3019 (subreg:QI
3020 (zero_extract:SI (match_operand 1 "ext_register_operand")
3021 (const_int 8)
3022 (const_int 8)) 0))
3023 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3024 "TARGET_64BIT
3025 && peep2_reg_dead_p (2, operands[0])"
3026 [(set (match_dup 2)
3027 (subreg:QI
3028 (zero_extract:SI (match_dup 1)
3029 (const_int 8)
3030 (const_int 8)) 0))])
3031
3032 (define_expand "insv<mode>"
3033 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3034 (match_operand:SI 1 "const_int_operand")
3035 (match_operand:SI 2 "const_int_operand"))
3036 (match_operand:SWI248 3 "register_operand"))]
3037 ""
3038 {
3039 rtx dst;
3040
3041 if (ix86_expand_pinsr (operands))
3042 DONE;
3043
3044 /* Handle insertions to %ah et al. */
3045 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3046 FAIL;
3047
3048 unsigned int regno = reg_or_subregno (operands[0]);
3049
3050 /* Be careful to expand only with registers having upper parts. */
3051 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3052 dst = copy_to_reg (operands[0]);
3053 else
3054 dst = operands[0];
3055
3056 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3057
3058 /* Fix up the destination if needed. */
3059 if (dst != operands[0])
3060 emit_move_insn (operands[0], dst);
3061
3062 DONE;
3063 })
3064
3065 (define_insn "*insvqi_1_mem_rex64"
3066 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3067 (const_int 8)
3068 (const_int 8))
3069 (subreg:SI
3070 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3071 "TARGET_64BIT && reload_completed"
3072 "mov{b}\t{%1, %h0|%h0, %1}"
3073 [(set_attr "type" "imov")
3074 (set_attr "mode" "QI")])
3075
3076 (define_insn "insv<mode>_1"
3077 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3078 (const_int 8)
3079 (const_int 8))
3080 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3081 ""
3082 {
3083 if (CONST_INT_P (operands[1]))
3084 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3085 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3086 }
3087 [(set_attr "isa" "*,nox64")
3088 (set_attr "type" "imov")
3089 (set_attr "mode" "QI")])
3090
3091 (define_insn "*insvqi_1"
3092 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3093 (const_int 8)
3094 (const_int 8))
3095 (subreg:SI
3096 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3097 ""
3098 "mov{b}\t{%1, %h0|%h0, %1}"
3099 [(set_attr "isa" "*,nox64")
3100 (set_attr "type" "imov")
3101 (set_attr "mode" "QI")])
3102
3103 (define_peephole2
3104 [(set (match_operand:QI 0 "register_operand")
3105 (match_operand:QI 1 "norex_memory_operand"))
3106 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3107 (const_int 8)
3108 (const_int 8))
3109 (subreg:SI (match_dup 0) 0))]
3110 "TARGET_64BIT
3111 && peep2_reg_dead_p (2, operands[0])"
3112 [(set (zero_extract:SI (match_dup 2)
3113 (const_int 8)
3114 (const_int 8))
3115 (subreg:SI (match_dup 1) 0))])
3116
3117 (define_code_iterator any_extract [sign_extract zero_extract])
3118
3119 (define_insn "*insvqi_2"
3120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3121 (const_int 8)
3122 (const_int 8))
3123 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3124 (const_int 8)
3125 (const_int 8)))]
3126 ""
3127 "mov{b}\t{%h1, %h0|%h0, %h1}"
3128 [(set_attr "type" "imov")
3129 (set_attr "mode" "QI")])
3130
3131 (define_insn "*insvqi_3"
3132 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3133 (const_int 8)
3134 (const_int 8))
3135 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3136 (const_int 8)))]
3137 ""
3138 "mov{b}\t{%h1, %h0|%h0, %h1}"
3139 [(set_attr "type" "imov")
3140 (set_attr "mode" "QI")])
3141 \f
3142 ;; Floating point push instructions.
3143
3144 (define_insn "*pushtf"
3145 [(set (match_operand:TF 0 "push_operand" "=<,<")
3146 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3147 "TARGET_64BIT || TARGET_SSE"
3148 {
3149 /* This insn should be already split before reg-stack. */
3150 gcc_unreachable ();
3151 }
3152 [(set_attr "isa" "*,x64")
3153 (set_attr "type" "multi")
3154 (set_attr "unit" "sse,*")
3155 (set_attr "mode" "TF,DI")])
3156
3157 ;; %%% Kill this when call knows how to work this out.
3158 (define_split
3159 [(set (match_operand:TF 0 "push_operand")
3160 (match_operand:TF 1 "sse_reg_operand"))]
3161 "TARGET_SSE && reload_completed"
3162 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3163 (set (match_dup 0) (match_dup 1))]
3164 {
3165 /* Preserve memory attributes. */
3166 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3167 })
3168
3169 (define_insn_and_split "*pushxf_rounded"
3170 [(set (mem:XF
3171 (pre_modify:P
3172 (reg:P SP_REG)
3173 (plus:P (reg:P SP_REG) (const_int -16))))
3174 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3175 "TARGET_64BIT"
3176 "#"
3177 "&& 1"
3178 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3179 (set (match_dup 1) (match_dup 0))]
3180 {
3181 rtx pat = PATTERN (curr_insn);
3182 operands[1] = SET_DEST (pat);
3183
3184 /* Preserve memory attributes. */
3185 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3186 }
3187 [(set_attr "type" "multi")
3188 (set_attr "unit" "i387,*,*,*")
3189 (set (attr "mode")
3190 (cond [(eq_attr "alternative" "1,2,3")
3191 (const_string "DI")
3192 ]
3193 (const_string "XF")))
3194 (set (attr "preferred_for_size")
3195 (cond [(eq_attr "alternative" "1")
3196 (symbol_ref "false")]
3197 (symbol_ref "true")))])
3198
3199 (define_insn "*pushxf"
3200 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3201 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3202 ""
3203 {
3204 /* This insn should be already split before reg-stack. */
3205 gcc_unreachable ();
3206 }
3207 [(set_attr "isa" "*,*,*,nox64,x64")
3208 (set_attr "type" "multi")
3209 (set_attr "unit" "i387,*,*,*,*")
3210 (set (attr "mode")
3211 (cond [(eq_attr "alternative" "1,2,3,4")
3212 (if_then_else (match_test "TARGET_64BIT")
3213 (const_string "DI")
3214 (const_string "SI"))
3215 ]
3216 (const_string "XF")))
3217 (set (attr "preferred_for_size")
3218 (cond [(eq_attr "alternative" "1")
3219 (symbol_ref "false")]
3220 (symbol_ref "true")))])
3221
3222 ;; %%% Kill this when call knows how to work this out.
3223 (define_split
3224 [(set (match_operand:XF 0 "push_operand")
3225 (match_operand:XF 1 "fp_register_operand"))]
3226 "reload_completed"
3227 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3228 (set (match_dup 0) (match_dup 1))]
3229 {
3230 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3231 /* Preserve memory attributes. */
3232 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3233 })
3234
3235 (define_insn "*pushdf"
3236 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3237 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3238 ""
3239 {
3240 /* This insn should be already split before reg-stack. */
3241 gcc_unreachable ();
3242 }
3243 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3244 (set_attr "type" "multi")
3245 (set_attr "unit" "i387,*,*,*,*,sse")
3246 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3247 (set (attr "preferred_for_size")
3248 (cond [(eq_attr "alternative" "1")
3249 (symbol_ref "false")]
3250 (symbol_ref "true")))
3251 (set (attr "preferred_for_speed")
3252 (cond [(eq_attr "alternative" "1")
3253 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3254 (symbol_ref "true")))])
3255
3256 ;; %%% Kill this when call knows how to work this out.
3257 (define_split
3258 [(set (match_operand:DF 0 "push_operand")
3259 (match_operand:DF 1 "any_fp_register_operand"))]
3260 "reload_completed"
3261 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3262 (set (match_dup 0) (match_dup 1))]
3263 {
3264 /* Preserve memory attributes. */
3265 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3266 })
3267
3268 (define_insn "*pushsf_rex64"
3269 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3270 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3271 "TARGET_64BIT"
3272 {
3273 /* Anything else should be already split before reg-stack. */
3274 gcc_assert (which_alternative == 1);
3275 return "push{q}\t%q1";
3276 }
3277 [(set_attr "type" "multi,push,multi")
3278 (set_attr "unit" "i387,*,*")
3279 (set_attr "mode" "SF,DI,SF")])
3280
3281 (define_insn "*pushsf"
3282 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3283 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3284 "!TARGET_64BIT"
3285 {
3286 /* Anything else should be already split before reg-stack. */
3287 gcc_assert (which_alternative == 1);
3288 return "push{l}\t%1";
3289 }
3290 [(set_attr "type" "multi,push,multi")
3291 (set_attr "unit" "i387,*,*")
3292 (set_attr "mode" "SF,SI,SF")])
3293
3294 ;; %%% Kill this when call knows how to work this out.
3295 (define_split
3296 [(set (match_operand:SF 0 "push_operand")
3297 (match_operand:SF 1 "any_fp_register_operand"))]
3298 "reload_completed"
3299 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3300 (set (match_dup 0) (match_dup 1))]
3301 {
3302 rtx op = XEXP (operands[0], 0);
3303 if (GET_CODE (op) == PRE_DEC)
3304 {
3305 gcc_assert (!TARGET_64BIT);
3306 op = GEN_INT (-4);
3307 }
3308 else
3309 {
3310 op = XEXP (XEXP (op, 1), 1);
3311 gcc_assert (CONST_INT_P (op));
3312 }
3313 operands[2] = op;
3314 /* Preserve memory attributes. */
3315 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3316 })
3317
3318 (define_split
3319 [(set (match_operand:SF 0 "push_operand")
3320 (match_operand:SF 1 "memory_operand"))]
3321 "reload_completed
3322 && find_constant_src (insn)"
3323 [(set (match_dup 0) (match_dup 2))]
3324 "operands[2] = find_constant_src (curr_insn);")
3325
3326 (define_split
3327 [(set (match_operand 0 "push_operand")
3328 (match_operand 1 "general_gr_operand"))]
3329 "reload_completed
3330 && (GET_MODE (operands[0]) == TFmode
3331 || GET_MODE (operands[0]) == XFmode
3332 || GET_MODE (operands[0]) == DFmode)"
3333 [(const_int 0)]
3334 "ix86_split_long_move (operands); DONE;")
3335 \f
3336 ;; Floating point move instructions.
3337
3338 (define_expand "movtf"
3339 [(set (match_operand:TF 0 "nonimmediate_operand")
3340 (match_operand:TF 1 "nonimmediate_operand"))]
3341 "TARGET_64BIT || TARGET_SSE"
3342 "ix86_expand_move (TFmode, operands); DONE;")
3343
3344 (define_expand "mov<mode>"
3345 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3346 (match_operand:X87MODEF 1 "general_operand"))]
3347 ""
3348 "ix86_expand_move (<MODE>mode, operands); DONE;")
3349
3350 (define_insn "*movtf_internal"
3351 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3352 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3353 "(TARGET_64BIT || TARGET_SSE)
3354 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3355 && (lra_in_progress || reload_completed
3356 || !CONST_DOUBLE_P (operands[1])
3357 || ((optimize_function_for_size_p (cfun)
3358 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3359 && standard_sse_constant_p (operands[1], TFmode) == 1
3360 && !memory_operand (operands[0], TFmode))
3361 || (!TARGET_MEMORY_MISMATCH_STALL
3362 && memory_operand (operands[0], TFmode)))"
3363 {
3364 switch (get_attr_type (insn))
3365 {
3366 case TYPE_SSELOG1:
3367 return standard_sse_constant_opcode (insn, operands);
3368
3369 case TYPE_SSEMOV:
3370 /* Handle misaligned load/store since we
3371 don't have movmisaligntf pattern. */
3372 if (misaligned_operand (operands[0], TFmode)
3373 || misaligned_operand (operands[1], TFmode))
3374 {
3375 if (get_attr_mode (insn) == MODE_V4SF)
3376 return "%vmovups\t{%1, %0|%0, %1}";
3377 else if (TARGET_AVX512VL
3378 && (EXT_REX_SSE_REG_P (operands[0])
3379 || EXT_REX_SSE_REG_P (operands[1])))
3380 return "vmovdqu64\t{%1, %0|%0, %1}";
3381 else
3382 return "%vmovdqu\t{%1, %0|%0, %1}";
3383 }
3384 else
3385 {
3386 if (get_attr_mode (insn) == MODE_V4SF)
3387 return "%vmovaps\t{%1, %0|%0, %1}";
3388 else if (TARGET_AVX512VL
3389 && (EXT_REX_SSE_REG_P (operands[0])
3390 || EXT_REX_SSE_REG_P (operands[1])))
3391 return "vmovdqa64\t{%1, %0|%0, %1}";
3392 else
3393 return "%vmovdqa\t{%1, %0|%0, %1}";
3394 }
3395
3396 case TYPE_MULTI:
3397 return "#";
3398
3399 default:
3400 gcc_unreachable ();
3401 }
3402 }
3403 [(set_attr "isa" "*,*,*,x64,x64")
3404 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3405 (set (attr "prefix")
3406 (if_then_else (eq_attr "type" "sselog1,ssemov")
3407 (const_string "maybe_vex")
3408 (const_string "orig")))
3409 (set (attr "mode")
3410 (cond [(eq_attr "alternative" "3,4")
3411 (const_string "DI")
3412 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3413 (const_string "V4SF")
3414 (and (eq_attr "alternative" "2")
3415 (match_test "TARGET_SSE_TYPELESS_STORES"))
3416 (const_string "V4SF")
3417 (match_test "TARGET_AVX")
3418 (const_string "TI")
3419 (ior (not (match_test "TARGET_SSE2"))
3420 (match_test "optimize_function_for_size_p (cfun)"))
3421 (const_string "V4SF")
3422 ]
3423 (const_string "TI")))])
3424
3425 (define_split
3426 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3427 (match_operand:TF 1 "general_gr_operand"))]
3428 "reload_completed"
3429 [(const_int 0)]
3430 "ix86_split_long_move (operands); DONE;")
3431
3432 ;; Possible store forwarding (partial memory) stall
3433 ;; in alternatives 4, 6, 7 and 8.
3434 (define_insn "*movxf_internal"
3435 [(set (match_operand:XF 0 "nonimmediate_operand"
3436 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3437 (match_operand:XF 1 "general_operand"
3438 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3439 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3440 && (lra_in_progress || reload_completed
3441 || !CONST_DOUBLE_P (operands[1])
3442 || ((optimize_function_for_size_p (cfun)
3443 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3444 && standard_80387_constant_p (operands[1]) > 0
3445 && !memory_operand (operands[0], XFmode))
3446 || (!TARGET_MEMORY_MISMATCH_STALL
3447 && memory_operand (operands[0], XFmode))
3448 || !TARGET_HARD_XF_REGS)"
3449 {
3450 switch (get_attr_type (insn))
3451 {
3452 case TYPE_FMOV:
3453 if (which_alternative == 2)
3454 return standard_80387_constant_opcode (operands[1]);
3455 return output_387_reg_move (insn, operands);
3456
3457 case TYPE_MULTI:
3458 return "#";
3459
3460 default:
3461 gcc_unreachable ();
3462 }
3463 }
3464 [(set (attr "isa")
3465 (cond [(eq_attr "alternative" "7,10")
3466 (const_string "nox64")
3467 (eq_attr "alternative" "8,11")
3468 (const_string "x64")
3469 ]
3470 (const_string "*")))
3471 (set (attr "type")
3472 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3473 (const_string "multi")
3474 ]
3475 (const_string "fmov")))
3476 (set (attr "mode")
3477 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3478 (if_then_else (match_test "TARGET_64BIT")
3479 (const_string "DI")
3480 (const_string "SI"))
3481 ]
3482 (const_string "XF")))
3483 (set (attr "preferred_for_size")
3484 (cond [(eq_attr "alternative" "3,4")
3485 (symbol_ref "false")]
3486 (symbol_ref "true")))
3487 (set (attr "enabled")
3488 (cond [(eq_attr "alternative" "9,10,11")
3489 (if_then_else
3490 (match_test "TARGET_HARD_XF_REGS")
3491 (symbol_ref "false")
3492 (const_string "*"))
3493 (not (match_test "TARGET_HARD_XF_REGS"))
3494 (symbol_ref "false")
3495 ]
3496 (const_string "*")))])
3497
3498 (define_split
3499 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3500 (match_operand:XF 1 "general_gr_operand"))]
3501 "reload_completed"
3502 [(const_int 0)]
3503 "ix86_split_long_move (operands); DONE;")
3504
3505 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3506 (define_insn "*movdf_internal"
3507 [(set (match_operand:DF 0 "nonimmediate_operand"
3508 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r ,o ,r ,m")
3509 (match_operand:DF 1 "general_operand"
3510 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))]
3511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3512 && (lra_in_progress || reload_completed
3513 || !CONST_DOUBLE_P (operands[1])
3514 || ((optimize_function_for_size_p (cfun)
3515 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3516 && ((IS_STACK_MODE (DFmode)
3517 && standard_80387_constant_p (operands[1]) > 0)
3518 || (TARGET_SSE2 && TARGET_SSE_MATH
3519 && standard_sse_constant_p (operands[1], DFmode) == 1))
3520 && !memory_operand (operands[0], DFmode))
3521 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3522 && memory_operand (operands[0], DFmode))
3523 || !TARGET_HARD_DF_REGS)"
3524 {
3525 switch (get_attr_type (insn))
3526 {
3527 case TYPE_FMOV:
3528 if (which_alternative == 2)
3529 return standard_80387_constant_opcode (operands[1]);
3530 return output_387_reg_move (insn, operands);
3531
3532 case TYPE_MULTI:
3533 return "#";
3534
3535 case TYPE_IMOV:
3536 if (get_attr_mode (insn) == MODE_SI)
3537 return "mov{l}\t{%1, %k0|%k0, %1}";
3538 else if (which_alternative == 11)
3539 return "movabs{q}\t{%1, %0|%0, %1}";
3540 else
3541 return "mov{q}\t{%1, %0|%0, %1}";
3542
3543 case TYPE_SSELOG1:
3544 return standard_sse_constant_opcode (insn, operands);
3545
3546 case TYPE_SSEMOV:
3547 switch (get_attr_mode (insn))
3548 {
3549 case MODE_DF:
3550 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3551 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3552 return "%vmovsd\t{%1, %0|%0, %1}";
3553
3554 case MODE_V4SF:
3555 return "%vmovaps\t{%1, %0|%0, %1}";
3556 case MODE_V8DF:
3557 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3558 case MODE_V2DF:
3559 return "%vmovapd\t{%1, %0|%0, %1}";
3560
3561 case MODE_V2SF:
3562 gcc_assert (!TARGET_AVX);
3563 return "movlps\t{%1, %0|%0, %1}";
3564 case MODE_V1DF:
3565 gcc_assert (!TARGET_AVX);
3566 return "movlpd\t{%1, %0|%0, %1}";
3567
3568 case MODE_DI:
3569 /* Handle broken assemblers that require movd instead of movq. */
3570 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3571 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3572 return "%vmovd\t{%1, %0|%0, %1}";
3573 return "%vmovq\t{%1, %0|%0, %1}";
3574
3575 default:
3576 gcc_unreachable ();
3577 }
3578
3579 default:
3580 gcc_unreachable ();
3581 }
3582 }
3583 [(set (attr "isa")
3584 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3585 (const_string "nox64")
3586 (eq_attr "alternative" "8,9,10,11,24,25")
3587 (const_string "x64")
3588 (eq_attr "alternative" "12,13,14,15")
3589 (const_string "sse2")
3590 (eq_attr "alternative" "20,21")
3591 (const_string "x64_sse2")
3592 ]
3593 (const_string "*")))
3594 (set (attr "type")
3595 (cond [(eq_attr "alternative" "0,1,2")
3596 (const_string "fmov")
3597 (eq_attr "alternative" "3,4,5,6,7,22,23")
3598 (const_string "multi")
3599 (eq_attr "alternative" "8,9,10,11,24,25")
3600 (const_string "imov")
3601 (eq_attr "alternative" "12,16")
3602 (const_string "sselog1")
3603 ]
3604 (const_string "ssemov")))
3605 (set (attr "modrm")
3606 (if_then_else (eq_attr "alternative" "11")
3607 (const_string "0")
3608 (const_string "*")))
3609 (set (attr "length_immediate")
3610 (if_then_else (eq_attr "alternative" "11")
3611 (const_string "8")
3612 (const_string "*")))
3613 (set (attr "prefix")
3614 (if_then_else (eq_attr "type" "sselog1,ssemov")
3615 (const_string "maybe_vex")
3616 (const_string "orig")))
3617 (set (attr "prefix_data16")
3618 (if_then_else
3619 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3620 (eq_attr "mode" "V1DF"))
3621 (const_string "1")
3622 (const_string "*")))
3623 (set (attr "mode")
3624 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3625 (const_string "SI")
3626 (eq_attr "alternative" "8,9,11,20,21,24,25")
3627 (const_string "DI")
3628
3629 /* xorps is one byte shorter for non-AVX targets. */
3630 (eq_attr "alternative" "12,16")
3631 (cond [(not (match_test "TARGET_SSE2"))
3632 (const_string "V4SF")
3633 (and (match_test "TARGET_AVX512F")
3634 (not (match_test "TARGET_PREFER_AVX256")))
3635 (const_string "XI")
3636 (match_test "TARGET_AVX")
3637 (const_string "V2DF")
3638 (match_test "optimize_function_for_size_p (cfun)")
3639 (const_string "V4SF")
3640 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3641 (const_string "TI")
3642 ]
3643 (const_string "V2DF"))
3644
3645 /* For architectures resolving dependencies on
3646 whole SSE registers use movapd to break dependency
3647 chains, otherwise use short move to avoid extra work. */
3648
3649 /* movaps is one byte shorter for non-AVX targets. */
3650 (eq_attr "alternative" "13,17")
3651 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3652 (not (match_test "TARGET_AVX512VL")))
3653 (ior (match_operand 0 "ext_sse_reg_operand")
3654 (match_operand 1 "ext_sse_reg_operand")))
3655 (const_string "V8DF")
3656 (ior (not (match_test "TARGET_SSE2"))
3657 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3658 (const_string "V4SF")
3659 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3660 (const_string "V2DF")
3661 (match_test "TARGET_AVX")
3662 (const_string "DF")
3663 (match_test "optimize_function_for_size_p (cfun)")
3664 (const_string "V4SF")
3665 ]
3666 (const_string "DF"))
3667
3668 /* For architectures resolving dependencies on register
3669 parts we may avoid extra work to zero out upper part
3670 of register. */
3671 (eq_attr "alternative" "14,18")
3672 (cond [(not (match_test "TARGET_SSE2"))
3673 (const_string "V2SF")
3674 (match_test "TARGET_AVX")
3675 (const_string "DF")
3676 (match_test "TARGET_SSE_SPLIT_REGS")
3677 (const_string "V1DF")
3678 ]
3679 (const_string "DF"))
3680
3681 (and (eq_attr "alternative" "15,19")
3682 (not (match_test "TARGET_SSE2")))
3683 (const_string "V2SF")
3684 ]
3685 (const_string "DF")))
3686 (set (attr "preferred_for_size")
3687 (cond [(eq_attr "alternative" "3,4")
3688 (symbol_ref "false")]
3689 (symbol_ref "true")))
3690 (set (attr "preferred_for_speed")
3691 (cond [(eq_attr "alternative" "3,4")
3692 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3693 (eq_attr "alternative" "20")
3694 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3695 (eq_attr "alternative" "21")
3696 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3697 ]
3698 (symbol_ref "true")))
3699 (set (attr "enabled")
3700 (cond [(eq_attr "alternative" "22,23,24,25")
3701 (if_then_else
3702 (match_test "TARGET_HARD_DF_REGS")
3703 (symbol_ref "false")
3704 (const_string "*"))
3705 (not (match_test "TARGET_HARD_DF_REGS"))
3706 (symbol_ref "false")
3707 ]
3708 (const_string "*")))])
3709
3710 (define_split
3711 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3712 (match_operand:DF 1 "general_gr_operand"))]
3713 "!TARGET_64BIT && reload_completed"
3714 [(const_int 0)]
3715 "ix86_split_long_move (operands); DONE;")
3716
3717 (define_insn "*movsf_internal"
3718 [(set (match_operand:SF 0 "nonimmediate_operand"
3719 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3720 (match_operand:SF 1 "general_operand"
3721 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3722 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3723 && (lra_in_progress || reload_completed
3724 || !CONST_DOUBLE_P (operands[1])
3725 || ((optimize_function_for_size_p (cfun)
3726 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3727 && ((IS_STACK_MODE (SFmode)
3728 && standard_80387_constant_p (operands[1]) > 0)
3729 || (TARGET_SSE && TARGET_SSE_MATH
3730 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3731 || memory_operand (operands[0], SFmode)
3732 || !TARGET_HARD_SF_REGS)"
3733 {
3734 switch (get_attr_type (insn))
3735 {
3736 case TYPE_FMOV:
3737 if (which_alternative == 2)
3738 return standard_80387_constant_opcode (operands[1]);
3739 return output_387_reg_move (insn, operands);
3740
3741 case TYPE_IMOV:
3742 return "mov{l}\t{%1, %0|%0, %1}";
3743
3744 case TYPE_SSELOG1:
3745 return standard_sse_constant_opcode (insn, operands);
3746
3747 case TYPE_SSEMOV:
3748 switch (get_attr_mode (insn))
3749 {
3750 case MODE_SF:
3751 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3752 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3753 return "%vmovss\t{%1, %0|%0, %1}";
3754
3755 case MODE_V16SF:
3756 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3757 case MODE_V4SF:
3758 return "%vmovaps\t{%1, %0|%0, %1}";
3759
3760 case MODE_SI:
3761 return "%vmovd\t{%1, %0|%0, %1}";
3762
3763 default:
3764 gcc_unreachable ();
3765 }
3766
3767 case TYPE_MMXMOV:
3768 switch (get_attr_mode (insn))
3769 {
3770 case MODE_DI:
3771 return "movq\t{%1, %0|%0, %1}";
3772 case MODE_SI:
3773 return "movd\t{%1, %0|%0, %1}";
3774
3775 default:
3776 gcc_unreachable ();
3777 }
3778
3779 default:
3780 gcc_unreachable ();
3781 }
3782 }
3783 [(set (attr "isa")
3784 (cond [(eq_attr "alternative" "14,15")
3785 (const_string "sse2")
3786 ]
3787 (const_string "*")))
3788 (set (attr "type")
3789 (cond [(eq_attr "alternative" "0,1,2")
3790 (const_string "fmov")
3791 (eq_attr "alternative" "3,4,16,17")
3792 (const_string "imov")
3793 (eq_attr "alternative" "5")
3794 (const_string "sselog1")
3795 (eq_attr "alternative" "11,12,13,14,15")
3796 (const_string "mmxmov")
3797 ]
3798 (const_string "ssemov")))
3799 (set (attr "prefix")
3800 (if_then_else (eq_attr "type" "sselog1,ssemov")
3801 (const_string "maybe_vex")
3802 (const_string "orig")))
3803 (set (attr "prefix_data16")
3804 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3805 (const_string "1")
3806 (const_string "*")))
3807 (set (attr "mode")
3808 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3809 (const_string "SI")
3810 (eq_attr "alternative" "11")
3811 (const_string "DI")
3812 (eq_attr "alternative" "5")
3813 (cond [(not (match_test "TARGET_SSE2"))
3814 (const_string "V4SF")
3815 (and (match_test "TARGET_AVX512F")
3816 (not (match_test "TARGET_PREFER_AVX256")))
3817 (const_string "V16SF")
3818 (match_test "TARGET_AVX")
3819 (const_string "V4SF")
3820 (match_test "optimize_function_for_size_p (cfun)")
3821 (const_string "V4SF")
3822 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3823 (const_string "TI")
3824 ]
3825 (const_string "V4SF"))
3826
3827 /* For architectures resolving dependencies on
3828 whole SSE registers use APS move to break dependency
3829 chains, otherwise use short move to avoid extra work.
3830
3831 Do the same for architectures resolving dependencies on
3832 the parts. While in DF mode it is better to always handle
3833 just register parts, the SF mode is different due to lack
3834 of instructions to load just part of the register. It is
3835 better to maintain the whole registers in single format
3836 to avoid problems on using packed logical operations. */
3837 (eq_attr "alternative" "6")
3838 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3839 (not (match_test "TARGET_AVX512VL")))
3840 (ior (match_operand 0 "ext_sse_reg_operand")
3841 (match_operand 1 "ext_sse_reg_operand")))
3842 (const_string "V16SF")
3843 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3844 (match_test "TARGET_SSE_SPLIT_REGS"))
3845 (const_string "V4SF")
3846 ]
3847 (const_string "SF"))
3848 ]
3849 (const_string "SF")))
3850 (set (attr "preferred_for_speed")
3851 (cond [(eq_attr "alternative" "9,14")
3852 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3853 (eq_attr "alternative" "10,15")
3854 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3855 ]
3856 (symbol_ref "true")))
3857 (set (attr "enabled")
3858 (cond [(eq_attr "alternative" "16,17")
3859 (if_then_else
3860 (match_test "TARGET_HARD_SF_REGS")
3861 (symbol_ref "false")
3862 (const_string "*"))
3863 (not (match_test "TARGET_HARD_SF_REGS"))
3864 (symbol_ref "false")
3865 ]
3866 (const_string "*")))])
3867
3868 (define_split
3869 [(set (match_operand 0 "any_fp_register_operand")
3870 (match_operand 1 "nonimmediate_operand"))]
3871 "reload_completed
3872 && (GET_MODE (operands[0]) == TFmode
3873 || GET_MODE (operands[0]) == XFmode
3874 || GET_MODE (operands[0]) == DFmode
3875 || GET_MODE (operands[0]) == SFmode)
3876 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3877 [(set (match_dup 0) (match_dup 2))]
3878 "operands[2] = find_constant_src (curr_insn);")
3879
3880 (define_split
3881 [(set (match_operand 0 "any_fp_register_operand")
3882 (float_extend (match_operand 1 "nonimmediate_operand")))]
3883 "reload_completed
3884 && (GET_MODE (operands[0]) == TFmode
3885 || GET_MODE (operands[0]) == XFmode
3886 || GET_MODE (operands[0]) == DFmode)
3887 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3888 [(set (match_dup 0) (match_dup 2))]
3889 "operands[2] = find_constant_src (curr_insn);")
3890
3891 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3892 (define_split
3893 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3894 (match_operand:X87MODEF 1 "immediate_operand"))]
3895 "reload_completed
3896 && (standard_80387_constant_p (operands[1]) == 8
3897 || standard_80387_constant_p (operands[1]) == 9)"
3898 [(set (match_dup 0)(match_dup 1))
3899 (set (match_dup 0)
3900 (neg:X87MODEF (match_dup 0)))]
3901 {
3902 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3903 operands[1] = CONST0_RTX (<MODE>mode);
3904 else
3905 operands[1] = CONST1_RTX (<MODE>mode);
3906 })
3907
3908 (define_insn "swapxf"
3909 [(set (match_operand:XF 0 "register_operand" "+f")
3910 (match_operand:XF 1 "register_operand" "+f"))
3911 (set (match_dup 1)
3912 (match_dup 0))]
3913 "TARGET_80387"
3914 {
3915 if (STACK_TOP_P (operands[0]))
3916 return "fxch\t%1";
3917 else
3918 return "fxch\t%0";
3919 }
3920 [(set_attr "type" "fxch")
3921 (set_attr "mode" "XF")])
3922
3923 (define_insn "*swap<mode>"
3924 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3925 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3926 (set (match_dup 1)
3927 (match_dup 0))]
3928 "TARGET_80387 || reload_completed"
3929 {
3930 if (STACK_TOP_P (operands[0]))
3931 return "fxch\t%1";
3932 else
3933 return "fxch\t%0";
3934 }
3935 [(set_attr "type" "fxch")
3936 (set_attr "mode" "<MODE>")])
3937 \f
3938 ;; Zero extension instructions
3939
3940 (define_expand "zero_extendsidi2"
3941 [(set (match_operand:DI 0 "nonimmediate_operand")
3942 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3943
3944 (define_insn "*zero_extendsidi2"
3945 [(set (match_operand:DI 0 "nonimmediate_operand"
3946 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r")
3947 (zero_extend:DI
3948 (match_operand:SI 1 "x86_64_zext_operand"
3949 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k")))]
3950 ""
3951 {
3952 switch (get_attr_type (insn))
3953 {
3954 case TYPE_IMOVX:
3955 if (ix86_use_lea_for_mov (insn, operands))
3956 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3957 else
3958 return "mov{l}\t{%1, %k0|%k0, %1}";
3959
3960 case TYPE_MULTI:
3961 return "#";
3962
3963 case TYPE_MMXMOV:
3964 return "movd\t{%1, %0|%0, %1}";
3965
3966 case TYPE_SSEMOV:
3967 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3968 {
3969 if (EXT_REX_SSE_REG_P (operands[0])
3970 || EXT_REX_SSE_REG_P (operands[1]))
3971 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3972 else
3973 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3974 }
3975
3976 if (GENERAL_REG_P (operands[0]))
3977 return "%vmovd\t{%1, %k0|%k0, %1}";
3978
3979 return "%vmovd\t{%1, %0|%0, %1}";
3980
3981 case TYPE_MSKMOV:
3982 return "kmovd\t{%1, %k0|%k0, %1}";
3983
3984 default:
3985 gcc_unreachable ();
3986 }
3987 }
3988 [(set (attr "isa")
3989 (cond [(eq_attr "alternative" "0,1,2")
3990 (const_string "nox64")
3991 (eq_attr "alternative" "3")
3992 (const_string "x64")
3993 (eq_attr "alternative" "7,8,9")
3994 (const_string "sse2")
3995 (eq_attr "alternative" "10")
3996 (const_string "sse4")
3997 (eq_attr "alternative" "11")
3998 (const_string "avx512f")
3999 (eq_attr "alternative" "12")
4000 (const_string "x64_avx512bw")
4001 ]
4002 (const_string "*")))
4003 (set (attr "type")
4004 (cond [(eq_attr "alternative" "0,1,2,4")
4005 (const_string "multi")
4006 (eq_attr "alternative" "5,6")
4007 (const_string "mmxmov")
4008 (eq_attr "alternative" "7")
4009 (if_then_else (match_test "TARGET_64BIT")
4010 (const_string "ssemov")
4011 (const_string "multi"))
4012 (eq_attr "alternative" "8,9,10,11")
4013 (const_string "ssemov")
4014 (eq_attr "alternative" "12")
4015 (const_string "mskmov")
4016 ]
4017 (const_string "imovx")))
4018 (set (attr "prefix_extra")
4019 (if_then_else (eq_attr "alternative" "10,11")
4020 (const_string "1")
4021 (const_string "*")))
4022 (set (attr "prefix")
4023 (if_then_else (eq_attr "type" "ssemov")
4024 (const_string "maybe_vex")
4025 (const_string "orig")))
4026 (set (attr "prefix_0f")
4027 (if_then_else (eq_attr "type" "imovx")
4028 (const_string "0")
4029 (const_string "*")))
4030 (set (attr "mode")
4031 (cond [(eq_attr "alternative" "5,6")
4032 (const_string "DI")
4033 (and (eq_attr "alternative" "7")
4034 (match_test "TARGET_64BIT"))
4035 (const_string "TI")
4036 (eq_attr "alternative" "8,10,11")
4037 (const_string "TI")
4038 ]
4039 (const_string "SI")))
4040 (set (attr "preferred_for_speed")
4041 (cond [(eq_attr "alternative" "7")
4042 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4043 (eq_attr "alternative" "5,8")
4044 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4045 ]
4046 (symbol_ref "true")))])
4047
4048 (define_split
4049 [(set (match_operand:DI 0 "memory_operand")
4050 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4051 "reload_completed"
4052 [(set (match_dup 4) (const_int 0))]
4053 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4054
4055 (define_split
4056 [(set (match_operand:DI 0 "general_reg_operand")
4057 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4058 "!TARGET_64BIT && reload_completed
4059 && REGNO (operands[0]) == REGNO (operands[1])"
4060 [(set (match_dup 4) (const_int 0))]
4061 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4062
4063 (define_split
4064 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4065 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4066 "!TARGET_64BIT && reload_completed
4067 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4068 [(set (match_dup 3) (match_dup 1))
4069 (set (match_dup 4) (const_int 0))]
4070 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4071
4072 (define_mode_attr kmov_isa
4073 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4074
4075 (define_insn "zero_extend<mode>di2"
4076 [(set (match_operand:DI 0 "register_operand" "=r,*r")
4077 (zero_extend:DI
4078 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4079 "TARGET_64BIT"
4080 "@
4081 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4082 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4083 [(set_attr "isa" "*,<kmov_isa>")
4084 (set_attr "type" "imovx,mskmov")
4085 (set_attr "mode" "SI,<MODE>")])
4086
4087 (define_expand "zero_extend<mode>si2"
4088 [(set (match_operand:SI 0 "register_operand")
4089 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4090 ""
4091 {
4092 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4093 {
4094 operands[1] = force_reg (<MODE>mode, operands[1]);
4095 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4096 DONE;
4097 }
4098 })
4099
4100 (define_insn_and_split "zero_extend<mode>si2_and"
4101 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4102 (zero_extend:SI
4103 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4104 (clobber (reg:CC FLAGS_REG))]
4105 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4106 "#"
4107 "&& reload_completed"
4108 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4109 (clobber (reg:CC FLAGS_REG))])]
4110 {
4111 if (!REG_P (operands[1])
4112 || REGNO (operands[0]) != REGNO (operands[1]))
4113 {
4114 ix86_expand_clear (operands[0]);
4115
4116 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4117 emit_insn (gen_movstrict<mode>
4118 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4119 DONE;
4120 }
4121
4122 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4123 }
4124 [(set_attr "type" "alu1")
4125 (set_attr "mode" "SI")])
4126
4127 (define_insn "*zero_extend<mode>si2"
4128 [(set (match_operand:SI 0 "register_operand" "=r,*r")
4129 (zero_extend:SI
4130 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4131 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4132 "@
4133 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4134 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4135 [(set_attr "isa" "*,<kmov_isa>")
4136 (set_attr "type" "imovx,mskmov")
4137 (set_attr "mode" "SI,<MODE>")])
4138
4139 (define_expand "zero_extendqihi2"
4140 [(set (match_operand:HI 0 "register_operand")
4141 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4142 ""
4143 {
4144 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4145 {
4146 operands[1] = force_reg (QImode, operands[1]);
4147 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4148 DONE;
4149 }
4150 })
4151
4152 (define_insn_and_split "zero_extendqihi2_and"
4153 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4154 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4155 (clobber (reg:CC FLAGS_REG))]
4156 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4157 "#"
4158 "&& reload_completed"
4159 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4160 (clobber (reg:CC FLAGS_REG))])]
4161 {
4162 if (!REG_P (operands[1])
4163 || REGNO (operands[0]) != REGNO (operands[1]))
4164 {
4165 ix86_expand_clear (operands[0]);
4166
4167 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4168 emit_insn (gen_movstrictqi
4169 (gen_lowpart (QImode, operands[0]), operands[1]));
4170 DONE;
4171 }
4172
4173 operands[0] = gen_lowpart (SImode, operands[0]);
4174 }
4175 [(set_attr "type" "alu1")
4176 (set_attr "mode" "SI")])
4177
4178 ; zero extend to SImode to avoid partial register stalls
4179 (define_insn "*zero_extendqihi2"
4180 [(set (match_operand:HI 0 "register_operand" "=r,*r")
4181 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4182 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4183 "@
4184 movz{bl|x}\t{%1, %k0|%k0, %1}
4185 kmovb\t{%1, %k0|%k0, %1}"
4186 [(set_attr "isa" "*,avx512dq")
4187 (set_attr "type" "imovx,mskmov")
4188 (set_attr "mode" "SI,QI")])
4189
4190 (define_insn_and_split "*zext<mode>_doubleword_and"
4191 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4192 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4193 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4194 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4195 "#"
4196 "&& reload_completed && GENERAL_REG_P (operands[0])"
4197 [(set (match_dup 2) (const_int 0))]
4198 {
4199 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4200
4201 emit_move_insn (operands[0], const0_rtx);
4202
4203 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4204 emit_insn (gen_movstrict<mode>
4205 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4206 })
4207
4208 (define_insn_and_split "*zext<mode>_doubleword"
4209 [(set (match_operand:DI 0 "register_operand" "=r")
4210 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4211 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4212 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4213 "#"
4214 "&& reload_completed && GENERAL_REG_P (operands[0])"
4215 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4216 (set (match_dup 2) (const_int 0))]
4217 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4218
4219 (define_insn_and_split "*zextsi_doubleword"
4220 [(set (match_operand:DI 0 "register_operand" "=r")
4221 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4222 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4223 "#"
4224 "&& reload_completed && GENERAL_REG_P (operands[0])"
4225 [(set (match_dup 0) (match_dup 1))
4226 (set (match_dup 2) (const_int 0))]
4227 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4228 \f
4229 ;; Sign extension instructions
4230
4231 (define_expand "extendsidi2"
4232 [(set (match_operand:DI 0 "register_operand")
4233 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4234 ""
4235 {
4236 if (!TARGET_64BIT)
4237 {
4238 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4239 DONE;
4240 }
4241 })
4242
4243 (define_insn "*extendsidi2_rex64"
4244 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4245 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4246 "TARGET_64BIT"
4247 "@
4248 {cltq|cdqe}
4249 movs{lq|x}\t{%1, %0|%0, %1}"
4250 [(set_attr "type" "imovx")
4251 (set_attr "mode" "DI")
4252 (set_attr "prefix_0f" "0")
4253 (set_attr "modrm" "0,1")])
4254
4255 (define_insn "extendsidi2_1"
4256 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4257 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4258 (clobber (reg:CC FLAGS_REG))
4259 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4260 "!TARGET_64BIT"
4261 "#")
4262
4263 ;; Split the memory case. If the source register doesn't die, it will stay
4264 ;; this way, if it does die, following peephole2s take care of it.
4265 (define_split
4266 [(set (match_operand:DI 0 "memory_operand")
4267 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4268 (clobber (reg:CC FLAGS_REG))
4269 (clobber (match_operand:SI 2 "register_operand"))]
4270 "reload_completed"
4271 [(const_int 0)]
4272 {
4273 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4274
4275 emit_move_insn (operands[3], operands[1]);
4276
4277 /* Generate a cltd if possible and doing so it profitable. */
4278 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4279 && REGNO (operands[1]) == AX_REG
4280 && REGNO (operands[2]) == DX_REG)
4281 {
4282 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4283 }
4284 else
4285 {
4286 emit_move_insn (operands[2], operands[1]);
4287 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4288 }
4289 emit_move_insn (operands[4], operands[2]);
4290 DONE;
4291 })
4292
4293 ;; Peepholes for the case where the source register does die, after
4294 ;; being split with the above splitter.
4295 (define_peephole2
4296 [(set (match_operand:SI 0 "memory_operand")
4297 (match_operand:SI 1 "general_reg_operand"))
4298 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4299 (parallel [(set (match_dup 2)
4300 (ashiftrt:SI (match_dup 2) (const_int 31)))
4301 (clobber (reg:CC FLAGS_REG))])
4302 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4303 "REGNO (operands[1]) != REGNO (operands[2])
4304 && peep2_reg_dead_p (2, operands[1])
4305 && peep2_reg_dead_p (4, operands[2])
4306 && !reg_mentioned_p (operands[2], operands[3])"
4307 [(set (match_dup 0) (match_dup 1))
4308 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4309 (clobber (reg:CC FLAGS_REG))])
4310 (set (match_dup 3) (match_dup 1))])
4311
4312 (define_peephole2
4313 [(set (match_operand:SI 0 "memory_operand")
4314 (match_operand:SI 1 "general_reg_operand"))
4315 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4316 (ashiftrt:SI (match_dup 1) (const_int 31)))
4317 (clobber (reg:CC FLAGS_REG))])
4318 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4319 "/* cltd is shorter than sarl $31, %eax */
4320 !optimize_function_for_size_p (cfun)
4321 && REGNO (operands[1]) == AX_REG
4322 && REGNO (operands[2]) == DX_REG
4323 && peep2_reg_dead_p (2, operands[1])
4324 && peep2_reg_dead_p (3, operands[2])
4325 && !reg_mentioned_p (operands[2], operands[3])"
4326 [(set (match_dup 0) (match_dup 1))
4327 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4328 (clobber (reg:CC FLAGS_REG))])
4329 (set (match_dup 3) (match_dup 1))])
4330
4331 ;; Extend to register case. Optimize case where source and destination
4332 ;; registers match and cases where we can use cltd.
4333 (define_split
4334 [(set (match_operand:DI 0 "register_operand")
4335 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4336 (clobber (reg:CC FLAGS_REG))
4337 (clobber (match_scratch:SI 2))]
4338 "reload_completed"
4339 [(const_int 0)]
4340 {
4341 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4342
4343 if (REGNO (operands[3]) != REGNO (operands[1]))
4344 emit_move_insn (operands[3], operands[1]);
4345
4346 /* Generate a cltd if possible and doing so it profitable. */
4347 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4348 && REGNO (operands[3]) == AX_REG
4349 && REGNO (operands[4]) == DX_REG)
4350 {
4351 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4352 DONE;
4353 }
4354
4355 if (REGNO (operands[4]) != REGNO (operands[1]))
4356 emit_move_insn (operands[4], operands[1]);
4357
4358 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4359 DONE;
4360 })
4361
4362 (define_insn "extend<mode>di2"
4363 [(set (match_operand:DI 0 "register_operand" "=r")
4364 (sign_extend:DI
4365 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4366 "TARGET_64BIT"
4367 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4368 [(set_attr "type" "imovx")
4369 (set_attr "mode" "DI")])
4370
4371 (define_insn "extendhisi2"
4372 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4373 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4374 ""
4375 {
4376 switch (get_attr_prefix_0f (insn))
4377 {
4378 case 0:
4379 return "{cwtl|cwde}";
4380 default:
4381 return "movs{wl|x}\t{%1, %0|%0, %1}";
4382 }
4383 }
4384 [(set_attr "type" "imovx")
4385 (set_attr "mode" "SI")
4386 (set (attr "prefix_0f")
4387 ;; movsx is short decodable while cwtl is vector decoded.
4388 (if_then_else (and (eq_attr "cpu" "!k6")
4389 (eq_attr "alternative" "0"))
4390 (const_string "0")
4391 (const_string "1")))
4392 (set (attr "znver1_decode")
4393 (if_then_else (eq_attr "prefix_0f" "0")
4394 (const_string "double")
4395 (const_string "direct")))
4396 (set (attr "modrm")
4397 (if_then_else (eq_attr "prefix_0f" "0")
4398 (const_string "0")
4399 (const_string "1")))])
4400
4401 (define_insn "*extendhisi2_zext"
4402 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4403 (zero_extend:DI
4404 (sign_extend:SI
4405 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4406 "TARGET_64BIT"
4407 {
4408 switch (get_attr_prefix_0f (insn))
4409 {
4410 case 0:
4411 return "{cwtl|cwde}";
4412 default:
4413 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4414 }
4415 }
4416 [(set_attr "type" "imovx")
4417 (set_attr "mode" "SI")
4418 (set (attr "prefix_0f")
4419 ;; movsx is short decodable while cwtl is vector decoded.
4420 (if_then_else (and (eq_attr "cpu" "!k6")
4421 (eq_attr "alternative" "0"))
4422 (const_string "0")
4423 (const_string "1")))
4424 (set (attr "modrm")
4425 (if_then_else (eq_attr "prefix_0f" "0")
4426 (const_string "0")
4427 (const_string "1")))])
4428
4429 (define_insn "extendqisi2"
4430 [(set (match_operand:SI 0 "register_operand" "=r")
4431 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4432 ""
4433 "movs{bl|x}\t{%1, %0|%0, %1}"
4434 [(set_attr "type" "imovx")
4435 (set_attr "mode" "SI")])
4436
4437 (define_insn "*extendqisi2_zext"
4438 [(set (match_operand:DI 0 "register_operand" "=r")
4439 (zero_extend:DI
4440 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4441 "TARGET_64BIT"
4442 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4443 [(set_attr "type" "imovx")
4444 (set_attr "mode" "SI")])
4445
4446 (define_insn "extendqihi2"
4447 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4448 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4449 ""
4450 {
4451 switch (get_attr_prefix_0f (insn))
4452 {
4453 case 0:
4454 return "{cbtw|cbw}";
4455 default:
4456 return "movs{bw|x}\t{%1, %0|%0, %1}";
4457 }
4458 }
4459 [(set_attr "type" "imovx")
4460 (set_attr "mode" "HI")
4461 (set (attr "prefix_0f")
4462 ;; movsx is short decodable while cwtl is vector decoded.
4463 (if_then_else (and (eq_attr "cpu" "!k6")
4464 (eq_attr "alternative" "0"))
4465 (const_string "0")
4466 (const_string "1")))
4467 (set (attr "modrm")
4468 (if_then_else (eq_attr "prefix_0f" "0")
4469 (const_string "0")
4470 (const_string "1")))])
4471 \f
4472 ;; Conversions between float and double.
4473
4474 ;; These are all no-ops in the model used for the 80387.
4475 ;; So just emit moves.
4476
4477 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4478 (define_split
4479 [(set (match_operand:DF 0 "push_operand")
4480 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4481 "reload_completed"
4482 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4483 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4484
4485 (define_split
4486 [(set (match_operand:XF 0 "push_operand")
4487 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4488 "reload_completed"
4489 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4490 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4491 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4492
4493 (define_expand "extendsfdf2"
4494 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4495 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4496 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4497 {
4498 /* ??? Needed for compress_float_constant since all fp constants
4499 are TARGET_LEGITIMATE_CONSTANT_P. */
4500 if (CONST_DOUBLE_P (operands[1]))
4501 {
4502 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4503 && standard_80387_constant_p (operands[1]) > 0)
4504 {
4505 operands[1] = simplify_const_unary_operation
4506 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4507 emit_move_insn_1 (operands[0], operands[1]);
4508 DONE;
4509 }
4510 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4511 }
4512 })
4513
4514 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4515 cvtss2sd:
4516 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4517 cvtps2pd xmm2,xmm1
4518 We do the conversion post reload to avoid producing of 128bit spills
4519 that might lead to ICE on 32bit target. The sequence unlikely combine
4520 anyway. */
4521 (define_split
4522 [(set (match_operand:DF 0 "sse_reg_operand")
4523 (float_extend:DF
4524 (match_operand:SF 1 "nonimmediate_operand")))]
4525 "TARGET_USE_VECTOR_FP_CONVERTS
4526 && optimize_insn_for_speed_p ()
4527 && reload_completed
4528 && (!EXT_REX_SSE_REG_P (operands[0])
4529 || TARGET_AVX512VL)"
4530 [(set (match_dup 2)
4531 (float_extend:V2DF
4532 (vec_select:V2SF
4533 (match_dup 3)
4534 (parallel [(const_int 0) (const_int 1)]))))]
4535 {
4536 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4537 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4538 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4539 Try to avoid move when unpacking can be done in source. */
4540 if (REG_P (operands[1]))
4541 {
4542 /* If it is unsafe to overwrite upper half of source, we need
4543 to move to destination and unpack there. */
4544 if (REGNO (operands[0]) != REGNO (operands[1])
4545 || (EXT_REX_SSE_REG_P (operands[1])
4546 && !TARGET_AVX512VL))
4547 {
4548 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4549 emit_move_insn (tmp, operands[1]);
4550 }
4551 else
4552 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4553 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4554 =v, v, then vbroadcastss will be only needed for AVX512F without
4555 AVX512VL. */
4556 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4557 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4558 operands[3]));
4559 else
4560 {
4561 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4562 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4563 }
4564 }
4565 else
4566 emit_insn (gen_vec_setv4sf_0 (operands[3],
4567 CONST0_RTX (V4SFmode), operands[1]));
4568 })
4569
4570 ;; It's more profitable to split and then extend in the same register.
4571 (define_peephole2
4572 [(set (match_operand:DF 0 "sse_reg_operand")
4573 (float_extend:DF
4574 (match_operand:SF 1 "memory_operand")))]
4575 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4576 && optimize_insn_for_speed_p ()"
4577 [(set (match_dup 2) (match_dup 1))
4578 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4579 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4580
4581 (define_insn "*extendsfdf2"
4582 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4583 (float_extend:DF
4584 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4585 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4586 {
4587 switch (which_alternative)
4588 {
4589 case 0:
4590 case 1:
4591 return output_387_reg_move (insn, operands);
4592
4593 case 2:
4594 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4595
4596 default:
4597 gcc_unreachable ();
4598 }
4599 }
4600 [(set_attr "type" "fmov,fmov,ssecvt")
4601 (set_attr "prefix" "orig,orig,maybe_vex")
4602 (set_attr "mode" "SF,XF,DF")
4603 (set (attr "enabled")
4604 (if_then_else
4605 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4606 (if_then_else
4607 (eq_attr "alternative" "0,1")
4608 (symbol_ref "TARGET_MIX_SSE_I387")
4609 (symbol_ref "true"))
4610 (if_then_else
4611 (eq_attr "alternative" "0,1")
4612 (symbol_ref "true")
4613 (symbol_ref "false"))))])
4614
4615 (define_expand "extend<mode>xf2"
4616 [(set (match_operand:XF 0 "nonimmediate_operand")
4617 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4618 "TARGET_80387"
4619 {
4620 /* ??? Needed for compress_float_constant since all fp constants
4621 are TARGET_LEGITIMATE_CONSTANT_P. */
4622 if (CONST_DOUBLE_P (operands[1]))
4623 {
4624 if (standard_80387_constant_p (operands[1]) > 0)
4625 {
4626 operands[1] = simplify_const_unary_operation
4627 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4628 emit_move_insn_1 (operands[0], operands[1]);
4629 DONE;
4630 }
4631 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4632 }
4633 })
4634
4635 (define_insn "*extend<mode>xf2_i387"
4636 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4637 (float_extend:XF
4638 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4639 "TARGET_80387"
4640 "* return output_387_reg_move (insn, operands);"
4641 [(set_attr "type" "fmov")
4642 (set_attr "mode" "<MODE>,XF")])
4643
4644 ;; %%% This seems like bad news.
4645 ;; This cannot output into an f-reg because there is no way to be sure
4646 ;; of truncating in that case. Otherwise this is just like a simple move
4647 ;; insn. So we pretend we can output to a reg in order to get better
4648 ;; register preferencing, but we really use a stack slot.
4649
4650 ;; Conversion from DFmode to SFmode.
4651
4652 (define_expand "truncdfsf2"
4653 [(set (match_operand:SF 0 "nonimmediate_operand")
4654 (float_truncate:SF
4655 (match_operand:DF 1 "nonimmediate_operand")))]
4656 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4657 {
4658 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4659 ;
4660 else if (flag_unsafe_math_optimizations)
4661 ;
4662 else
4663 {
4664 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4665 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4666 DONE;
4667 }
4668 })
4669
4670 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4671 cvtsd2ss:
4672 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4673 cvtpd2ps xmm2,xmm1
4674 We do the conversion post reload to avoid producing of 128bit spills
4675 that might lead to ICE on 32bit target. The sequence unlikely combine
4676 anyway. */
4677 (define_split
4678 [(set (match_operand:SF 0 "sse_reg_operand")
4679 (float_truncate:SF
4680 (match_operand:DF 1 "nonimmediate_operand")))]
4681 "TARGET_USE_VECTOR_FP_CONVERTS
4682 && optimize_insn_for_speed_p ()
4683 && reload_completed
4684 && (!EXT_REX_SSE_REG_P (operands[0])
4685 || TARGET_AVX512VL)"
4686 [(set (match_dup 2)
4687 (vec_concat:V4SF
4688 (float_truncate:V2SF
4689 (match_dup 4))
4690 (match_dup 3)))]
4691 {
4692 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4693 operands[3] = CONST0_RTX (V2SFmode);
4694 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4695 /* Use movsd for loading from memory, unpcklpd for registers.
4696 Try to avoid move when unpacking can be done in source, or SSE3
4697 movddup is available. */
4698 if (REG_P (operands[1]))
4699 {
4700 if (!TARGET_SSE3
4701 && REGNO (operands[0]) != REGNO (operands[1]))
4702 {
4703 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4704 emit_move_insn (tmp, operands[1]);
4705 operands[1] = tmp;
4706 }
4707 else if (!TARGET_SSE3)
4708 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4709 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4710 }
4711 else
4712 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4713 CONST0_RTX (DFmode)));
4714 })
4715
4716 ;; It's more profitable to split and then extend in the same register.
4717 (define_peephole2
4718 [(set (match_operand:SF 0 "sse_reg_operand")
4719 (float_truncate:SF
4720 (match_operand:DF 1 "memory_operand")))]
4721 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4722 && optimize_insn_for_speed_p ()"
4723 [(set (match_dup 2) (match_dup 1))
4724 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4725 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4726
4727 (define_expand "truncdfsf2_with_temp"
4728 [(parallel [(set (match_operand:SF 0)
4729 (float_truncate:SF (match_operand:DF 1)))
4730 (clobber (match_operand:SF 2))])])
4731
4732 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4733 ;; because nothing we do there is unsafe.
4734 (define_insn "*truncdfsf_fast_mixed"
4735 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4736 (float_truncate:SF
4737 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4738 "TARGET_SSE2 && TARGET_SSE_MATH"
4739 {
4740 switch (which_alternative)
4741 {
4742 case 0:
4743 return output_387_reg_move (insn, operands);
4744 case 1:
4745 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4746 default:
4747 gcc_unreachable ();
4748 }
4749 }
4750 [(set_attr "type" "fmov,ssecvt")
4751 (set_attr "prefix" "orig,maybe_vex")
4752 (set_attr "mode" "SF")
4753 (set (attr "enabled")
4754 (cond [(eq_attr "alternative" "0")
4755 (symbol_ref "TARGET_MIX_SSE_I387
4756 && flag_unsafe_math_optimizations")
4757 ]
4758 (symbol_ref "true")))])
4759
4760 (define_insn "*truncdfsf_fast_i387"
4761 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4762 (float_truncate:SF
4763 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4764 "TARGET_80387 && flag_unsafe_math_optimizations"
4765 "* return output_387_reg_move (insn, operands);"
4766 [(set_attr "type" "fmov")
4767 (set_attr "mode" "SF")])
4768
4769 (define_insn "*truncdfsf_mixed"
4770 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4771 (float_truncate:SF
4772 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4773 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4774 "TARGET_MIX_SSE_I387"
4775 {
4776 switch (which_alternative)
4777 {
4778 case 0:
4779 return output_387_reg_move (insn, operands);
4780 case 1:
4781 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4782
4783 default:
4784 return "#";
4785 }
4786 }
4787 [(set_attr "isa" "*,sse2,*,*,*")
4788 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4789 (set_attr "unit" "*,*,i387,i387,i387")
4790 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4791 (set_attr "mode" "SF")])
4792
4793 (define_insn "*truncdfsf_i387"
4794 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4795 (float_truncate:SF
4796 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4797 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4798 "TARGET_80387"
4799 {
4800 switch (which_alternative)
4801 {
4802 case 0:
4803 return output_387_reg_move (insn, operands);
4804
4805 default:
4806 return "#";
4807 }
4808 }
4809 [(set_attr "type" "fmov,multi,multi,multi")
4810 (set_attr "unit" "*,i387,i387,i387")
4811 (set_attr "mode" "SF")])
4812
4813 (define_insn "*truncdfsf2_i387_1"
4814 [(set (match_operand:SF 0 "memory_operand" "=m")
4815 (float_truncate:SF
4816 (match_operand:DF 1 "register_operand" "f")))]
4817 "TARGET_80387
4818 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4819 && !TARGET_MIX_SSE_I387"
4820 "* return output_387_reg_move (insn, operands);"
4821 [(set_attr "type" "fmov")
4822 (set_attr "mode" "SF")])
4823
4824 (define_split
4825 [(set (match_operand:SF 0 "register_operand")
4826 (float_truncate:SF
4827 (match_operand:DF 1 "fp_register_operand")))
4828 (clobber (match_operand 2))]
4829 "reload_completed"
4830 [(set (match_dup 2) (match_dup 1))
4831 (set (match_dup 0) (match_dup 2))]
4832 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4833
4834 ;; Conversion from XFmode to {SF,DF}mode
4835
4836 (define_expand "truncxf<mode>2"
4837 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4838 (float_truncate:MODEF
4839 (match_operand:XF 1 "register_operand")))
4840 (clobber (match_dup 2))])]
4841 "TARGET_80387"
4842 {
4843 if (flag_unsafe_math_optimizations)
4844 {
4845 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4846 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4847 if (reg != operands[0])
4848 emit_move_insn (operands[0], reg);
4849 DONE;
4850 }
4851 else
4852 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4853 })
4854
4855 (define_insn "*truncxfsf2_mixed"
4856 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4857 (float_truncate:SF
4858 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4859 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4860 "TARGET_80387"
4861 {
4862 gcc_assert (!which_alternative);
4863 return output_387_reg_move (insn, operands);
4864 }
4865 [(set_attr "type" "fmov,multi,multi,multi")
4866 (set_attr "unit" "*,i387,i387,i387")
4867 (set_attr "mode" "SF")])
4868
4869 (define_insn "*truncxfdf2_mixed"
4870 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4871 (float_truncate:DF
4872 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4873 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4874 "TARGET_80387"
4875 {
4876 gcc_assert (!which_alternative);
4877 return output_387_reg_move (insn, operands);
4878 }
4879 [(set_attr "isa" "*,*,sse2,*")
4880 (set_attr "type" "fmov,multi,multi,multi")
4881 (set_attr "unit" "*,i387,i387,i387")
4882 (set_attr "mode" "DF")])
4883
4884 (define_insn "truncxf<mode>2_i387_noop"
4885 [(set (match_operand:MODEF 0 "register_operand" "=f")
4886 (float_truncate:MODEF
4887 (match_operand:XF 1 "register_operand" "f")))]
4888 "TARGET_80387 && flag_unsafe_math_optimizations"
4889 "* return output_387_reg_move (insn, operands);"
4890 [(set_attr "type" "fmov")
4891 (set_attr "mode" "<MODE>")])
4892
4893 (define_insn "*truncxf<mode>2_i387"
4894 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4895 (float_truncate:MODEF
4896 (match_operand:XF 1 "register_operand" "f")))]
4897 "TARGET_80387"
4898 "* return output_387_reg_move (insn, operands);"
4899 [(set_attr "type" "fmov")
4900 (set_attr "mode" "<MODE>")])
4901
4902 (define_split
4903 [(set (match_operand:MODEF 0 "register_operand")
4904 (float_truncate:MODEF
4905 (match_operand:XF 1 "register_operand")))
4906 (clobber (match_operand:MODEF 2 "memory_operand"))]
4907 "TARGET_80387 && reload_completed"
4908 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4909 (set (match_dup 0) (match_dup 2))])
4910
4911 (define_split
4912 [(set (match_operand:MODEF 0 "memory_operand")
4913 (float_truncate:MODEF
4914 (match_operand:XF 1 "register_operand")))
4915 (clobber (match_operand:MODEF 2 "memory_operand"))]
4916 "TARGET_80387"
4917 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4918 \f
4919 ;; Signed conversion to DImode.
4920
4921 (define_expand "fix_truncxfdi2"
4922 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4923 (fix:DI (match_operand:XF 1 "register_operand")))
4924 (clobber (reg:CC FLAGS_REG))])]
4925 "TARGET_80387"
4926 {
4927 if (TARGET_FISTTP)
4928 {
4929 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4930 DONE;
4931 }
4932 })
4933
4934 (define_expand "fix_trunc<mode>di2"
4935 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4936 (fix:DI (match_operand:MODEF 1 "register_operand")))
4937 (clobber (reg:CC FLAGS_REG))])]
4938 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4939 {
4940 if (TARGET_FISTTP
4941 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4942 {
4943 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4944 DONE;
4945 }
4946 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4947 {
4948 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4949 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4950 if (out != operands[0])
4951 emit_move_insn (operands[0], out);
4952 DONE;
4953 }
4954 })
4955
4956 ;; Signed conversion to SImode.
4957
4958 (define_expand "fix_truncxfsi2"
4959 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4960 (fix:SI (match_operand:XF 1 "register_operand")))
4961 (clobber (reg:CC FLAGS_REG))])]
4962 "TARGET_80387"
4963 {
4964 if (TARGET_FISTTP)
4965 {
4966 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4967 DONE;
4968 }
4969 })
4970
4971 (define_expand "fix_trunc<mode>si2"
4972 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4973 (fix:SI (match_operand:MODEF 1 "register_operand")))
4974 (clobber (reg:CC FLAGS_REG))])]
4975 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4976 {
4977 if (TARGET_FISTTP
4978 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4979 {
4980 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4981 DONE;
4982 }
4983 if (SSE_FLOAT_MODE_P (<MODE>mode))
4984 {
4985 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4986 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4987 if (out != operands[0])
4988 emit_move_insn (operands[0], out);
4989 DONE;
4990 }
4991 })
4992
4993 ;; Signed conversion to HImode.
4994
4995 (define_expand "fix_trunc<mode>hi2"
4996 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4997 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4998 (clobber (reg:CC FLAGS_REG))])]
4999 "TARGET_80387
5000 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5001 {
5002 if (TARGET_FISTTP)
5003 {
5004 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5005 DONE;
5006 }
5007 })
5008
5009 ;; Unsigned conversion to SImode.
5010
5011 (define_expand "fixuns_trunc<mode>si2"
5012 [(parallel
5013 [(set (match_operand:SI 0 "register_operand")
5014 (unsigned_fix:SI
5015 (match_operand:MODEF 1 "nonimmediate_operand")))
5016 (use (match_dup 2))
5017 (clobber (match_scratch:<ssevecmode> 3))
5018 (clobber (match_scratch:<ssevecmode> 4))])]
5019 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5020 {
5021 machine_mode mode = <MODE>mode;
5022 machine_mode vecmode = <ssevecmode>mode;
5023 REAL_VALUE_TYPE TWO31r;
5024 rtx two31;
5025
5026 if (optimize_insn_for_size_p ())
5027 FAIL;
5028
5029 real_ldexp (&TWO31r, &dconst1, 31);
5030 two31 = const_double_from_real_value (TWO31r, mode);
5031 two31 = ix86_build_const_vector (vecmode, true, two31);
5032 operands[2] = force_reg (vecmode, two31);
5033 })
5034
5035 (define_insn_and_split "*fixuns_trunc<mode>_1"
5036 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5037 (unsigned_fix:SI
5038 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5039 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5040 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5041 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5042 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5043 && optimize_function_for_speed_p (cfun)"
5044 "#"
5045 "&& reload_completed"
5046 [(const_int 0)]
5047 {
5048 ix86_split_convert_uns_si_sse (operands);
5049 DONE;
5050 })
5051
5052 ;; Unsigned conversion to HImode.
5053 ;; Without these patterns, we'll try the unsigned SI conversion which
5054 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5055
5056 (define_expand "fixuns_trunc<mode>hi2"
5057 [(set (match_dup 2)
5058 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5059 (set (match_operand:HI 0 "nonimmediate_operand")
5060 (subreg:HI (match_dup 2) 0))]
5061 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5062 "operands[2] = gen_reg_rtx (SImode);")
5063
5064 ;; When SSE is available, it is always faster to use it!
5065 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5066 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5067 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5068 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5069 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5070 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5071 [(set_attr "type" "sseicvt")
5072 (set_attr "prefix" "maybe_vex")
5073 (set (attr "prefix_rex")
5074 (if_then_else
5075 (match_test "<SWI48:MODE>mode == DImode")
5076 (const_string "1")
5077 (const_string "*")))
5078 (set_attr "mode" "<MODEF:MODE>")
5079 (set_attr "athlon_decode" "double,vector")
5080 (set_attr "amdfam10_decode" "double,double")
5081 (set_attr "bdver1_decode" "double,double")])
5082
5083 ;; Avoid vector decoded forms of the instruction.
5084 (define_peephole2
5085 [(match_scratch:MODEF 2 "x")
5086 (set (match_operand:SWI48 0 "register_operand")
5087 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5088 "TARGET_AVOID_VECTOR_DECODE
5089 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5090 && optimize_insn_for_speed_p ()"
5091 [(set (match_dup 2) (match_dup 1))
5092 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5093
5094 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5095 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5096 (fix:SWI248x (match_operand 1 "register_operand")))]
5097 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5098 && TARGET_FISTTP
5099 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5100 && (TARGET_64BIT || <MODE>mode != DImode))
5101 && TARGET_SSE_MATH)
5102 && can_create_pseudo_p ()"
5103 "#"
5104 "&& 1"
5105 [(const_int 0)]
5106 {
5107 if (memory_operand (operands[0], VOIDmode))
5108 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5109 else
5110 {
5111 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5112 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5113 operands[1],
5114 operands[2]));
5115 }
5116 DONE;
5117 }
5118 [(set_attr "type" "fisttp")
5119 (set_attr "mode" "<MODE>")])
5120
5121 (define_insn "fix_trunc<mode>_i387_fisttp"
5122 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5123 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5124 (clobber (match_scratch:XF 2 "=&1f"))]
5125 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5126 && TARGET_FISTTP
5127 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5128 && (TARGET_64BIT || <MODE>mode != DImode))
5129 && TARGET_SSE_MATH)"
5130 "* return output_fix_trunc (insn, operands, true);"
5131 [(set_attr "type" "fisttp")
5132 (set_attr "mode" "<MODE>")])
5133
5134 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5135 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5136 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5137 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5138 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5139 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5140 && TARGET_FISTTP
5141 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5142 && (TARGET_64BIT || <MODE>mode != DImode))
5143 && TARGET_SSE_MATH)"
5144 "#"
5145 [(set_attr "type" "fisttp")
5146 (set_attr "mode" "<MODE>")])
5147
5148 (define_split
5149 [(set (match_operand:SWI248x 0 "register_operand")
5150 (fix:SWI248x (match_operand 1 "register_operand")))
5151 (clobber (match_operand:SWI248x 2 "memory_operand"))
5152 (clobber (match_scratch 3))]
5153 "reload_completed"
5154 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5155 (clobber (match_dup 3))])
5156 (set (match_dup 0) (match_dup 2))])
5157
5158 (define_split
5159 [(set (match_operand:SWI248x 0 "memory_operand")
5160 (fix:SWI248x (match_operand 1 "register_operand")))
5161 (clobber (match_operand:SWI248x 2 "memory_operand"))
5162 (clobber (match_scratch 3))]
5163 "reload_completed"
5164 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5165 (clobber (match_dup 3))])])
5166
5167 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5168 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5169 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5170 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5171 ;; function in i386.c.
5172 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5173 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5174 (fix:SWI248x (match_operand 1 "register_operand")))
5175 (clobber (reg:CC FLAGS_REG))]
5176 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5177 && !TARGET_FISTTP
5178 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5179 && (TARGET_64BIT || <MODE>mode != DImode))
5180 && can_create_pseudo_p ()"
5181 "#"
5182 "&& 1"
5183 [(const_int 0)]
5184 {
5185 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5186
5187 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5188 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5189 if (memory_operand (operands[0], VOIDmode))
5190 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5191 operands[2], operands[3]));
5192 else
5193 {
5194 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5195 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5196 operands[2], operands[3],
5197 operands[4]));
5198 }
5199 DONE;
5200 }
5201 [(set_attr "type" "fistp")
5202 (set_attr "i387_cw" "trunc")
5203 (set_attr "mode" "<MODE>")])
5204
5205 (define_insn "fix_truncdi_i387"
5206 [(set (match_operand:DI 0 "memory_operand" "=m")
5207 (fix:DI (match_operand 1 "register_operand" "f")))
5208 (use (match_operand:HI 2 "memory_operand" "m"))
5209 (use (match_operand:HI 3 "memory_operand" "m"))
5210 (clobber (match_scratch:XF 4 "=&1f"))]
5211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5212 && !TARGET_FISTTP
5213 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5214 "* return output_fix_trunc (insn, operands, false);"
5215 [(set_attr "type" "fistp")
5216 (set_attr "i387_cw" "trunc")
5217 (set_attr "mode" "DI")])
5218
5219 (define_insn "fix_truncdi_i387_with_temp"
5220 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5221 (fix:DI (match_operand 1 "register_operand" "f,f")))
5222 (use (match_operand:HI 2 "memory_operand" "m,m"))
5223 (use (match_operand:HI 3 "memory_operand" "m,m"))
5224 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5225 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5226 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5227 && !TARGET_FISTTP
5228 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5229 "#"
5230 [(set_attr "type" "fistp")
5231 (set_attr "i387_cw" "trunc")
5232 (set_attr "mode" "DI")])
5233
5234 (define_split
5235 [(set (match_operand:DI 0 "register_operand")
5236 (fix:DI (match_operand 1 "register_operand")))
5237 (use (match_operand:HI 2 "memory_operand"))
5238 (use (match_operand:HI 3 "memory_operand"))
5239 (clobber (match_operand:DI 4 "memory_operand"))
5240 (clobber (match_scratch 5))]
5241 "reload_completed"
5242 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5243 (use (match_dup 2))
5244 (use (match_dup 3))
5245 (clobber (match_dup 5))])
5246 (set (match_dup 0) (match_dup 4))])
5247
5248 (define_split
5249 [(set (match_operand:DI 0 "memory_operand")
5250 (fix:DI (match_operand 1 "register_operand")))
5251 (use (match_operand:HI 2 "memory_operand"))
5252 (use (match_operand:HI 3 "memory_operand"))
5253 (clobber (match_operand:DI 4 "memory_operand"))
5254 (clobber (match_scratch 5))]
5255 "reload_completed"
5256 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5257 (use (match_dup 2))
5258 (use (match_dup 3))
5259 (clobber (match_dup 5))])])
5260
5261 (define_insn "fix_trunc<mode>_i387"
5262 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5263 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5264 (use (match_operand:HI 2 "memory_operand" "m"))
5265 (use (match_operand:HI 3 "memory_operand" "m"))]
5266 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5267 && !TARGET_FISTTP
5268 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5269 "* return output_fix_trunc (insn, operands, false);"
5270 [(set_attr "type" "fistp")
5271 (set_attr "i387_cw" "trunc")
5272 (set_attr "mode" "<MODE>")])
5273
5274 (define_insn "fix_trunc<mode>_i387_with_temp"
5275 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5276 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5277 (use (match_operand:HI 2 "memory_operand" "m,m"))
5278 (use (match_operand:HI 3 "memory_operand" "m,m"))
5279 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5280 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5281 && !TARGET_FISTTP
5282 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5283 "#"
5284 [(set_attr "type" "fistp")
5285 (set_attr "i387_cw" "trunc")
5286 (set_attr "mode" "<MODE>")])
5287
5288 (define_split
5289 [(set (match_operand:SWI24 0 "register_operand")
5290 (fix:SWI24 (match_operand 1 "register_operand")))
5291 (use (match_operand:HI 2 "memory_operand"))
5292 (use (match_operand:HI 3 "memory_operand"))
5293 (clobber (match_operand:SWI24 4 "memory_operand"))]
5294 "reload_completed"
5295 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5296 (use (match_dup 2))
5297 (use (match_dup 3))])
5298 (set (match_dup 0) (match_dup 4))])
5299
5300 (define_split
5301 [(set (match_operand:SWI24 0 "memory_operand")
5302 (fix:SWI24 (match_operand 1 "register_operand")))
5303 (use (match_operand:HI 2 "memory_operand"))
5304 (use (match_operand:HI 3 "memory_operand"))
5305 (clobber (match_operand:SWI24 4 "memory_operand"))]
5306 "reload_completed"
5307 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5308 (use (match_dup 2))
5309 (use (match_dup 3))])])
5310
5311 (define_insn "x86_fnstcw_1"
5312 [(set (match_operand:HI 0 "memory_operand" "=m")
5313 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5314 "TARGET_80387"
5315 "fnstcw\t%0"
5316 [(set (attr "length")
5317 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5318 (set_attr "mode" "HI")
5319 (set_attr "unit" "i387")
5320 (set_attr "bdver1_decode" "vector")])
5321
5322 (define_insn "x86_fldcw_1"
5323 [(set (reg:HI FPCR_REG)
5324 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5325 "TARGET_80387"
5326 "fldcw\t%0"
5327 [(set (attr "length")
5328 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5329 (set_attr "mode" "HI")
5330 (set_attr "unit" "i387")
5331 (set_attr "athlon_decode" "vector")
5332 (set_attr "amdfam10_decode" "vector")
5333 (set_attr "bdver1_decode" "vector")])
5334 \f
5335 ;; Conversion between fixed point and floating point.
5336
5337 ;; Even though we only accept memory inputs, the backend _really_
5338 ;; wants to be able to do this between registers. Thankfully, LRA
5339 ;; will fix this up for us during register allocation.
5340
5341 (define_insn "floathi<mode>2"
5342 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5343 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5344 "TARGET_80387
5345 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5346 || TARGET_MIX_SSE_I387)"
5347 "fild%Z1\t%1"
5348 [(set_attr "type" "fmov")
5349 (set_attr "mode" "<MODE>")
5350 (set_attr "znver1_decode" "double")
5351 (set_attr "fp_int_src" "true")])
5352
5353 (define_insn "float<SWI48x:mode>xf2"
5354 [(set (match_operand:XF 0 "register_operand" "=f")
5355 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5356 "TARGET_80387"
5357 "fild%Z1\t%1"
5358 [(set_attr "type" "fmov")
5359 (set_attr "mode" "XF")
5360 (set_attr "znver1_decode" "double")
5361 (set_attr "fp_int_src" "true")])
5362
5363 (define_expand "float<SWI48:mode><MODEF:mode>2"
5364 [(set (match_operand:MODEF 0 "register_operand")
5365 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5366 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5367 {
5368 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5369 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5370 {
5371 rtx reg = gen_reg_rtx (XFmode);
5372 rtx (*insn)(rtx, rtx);
5373
5374 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5375
5376 if (<MODEF:MODE>mode == SFmode)
5377 insn = gen_truncxfsf2;
5378 else if (<MODEF:MODE>mode == DFmode)
5379 insn = gen_truncxfdf2;
5380 else
5381 gcc_unreachable ();
5382
5383 emit_insn (insn (operands[0], reg));
5384 DONE;
5385 }
5386 })
5387
5388 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5389 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5390 (float:MODEF
5391 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5392 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5393 "@
5394 fild%Z1\t%1
5395 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5396 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5397 [(set_attr "type" "fmov,sseicvt,sseicvt")
5398 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5399 (set_attr "mode" "<MODEF:MODE>")
5400 (set (attr "prefix_rex")
5401 (if_then_else
5402 (and (eq_attr "prefix" "maybe_vex")
5403 (match_test "<SWI48:MODE>mode == DImode"))
5404 (const_string "1")
5405 (const_string "*")))
5406 (set_attr "unit" "i387,*,*")
5407 (set_attr "athlon_decode" "*,double,direct")
5408 (set_attr "amdfam10_decode" "*,vector,double")
5409 (set_attr "bdver1_decode" "*,double,direct")
5410 (set_attr "znver1_decode" "double,*,*")
5411 (set_attr "fp_int_src" "true")
5412 (set (attr "enabled")
5413 (cond [(eq_attr "alternative" "0")
5414 (symbol_ref "TARGET_MIX_SSE_I387
5415 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5416 <SWI48:MODE>mode)")
5417 ]
5418 (symbol_ref "true")))
5419 (set (attr "preferred_for_speed")
5420 (cond [(eq_attr "alternative" "1")
5421 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5422 (symbol_ref "true")))])
5423
5424 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5425 [(set (match_operand:MODEF 0 "register_operand" "=f")
5426 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5427 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5428 "fild%Z1\t%1"
5429 [(set_attr "type" "fmov")
5430 (set_attr "mode" "<MODEF:MODE>")
5431 (set_attr "znver1_decode" "double")
5432 (set_attr "fp_int_src" "true")])
5433
5434 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5435 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5436 ;; alternative in sse2_loadld.
5437 (define_split
5438 [(set (match_operand:MODEF 0 "sse_reg_operand")
5439 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5440 "TARGET_SSE2
5441 && TARGET_USE_VECTOR_CONVERTS
5442 && optimize_function_for_speed_p (cfun)
5443 && reload_completed
5444 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5445 && (!EXT_REX_SSE_REG_P (operands[0])
5446 || TARGET_AVX512VL)"
5447 [(const_int 0)]
5448 {
5449 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5450 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5451
5452 emit_insn (gen_sse2_loadld (operands[4],
5453 CONST0_RTX (V4SImode), operands[1]));
5454
5455 if (<ssevecmode>mode == V4SFmode)
5456 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5457 else
5458 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5459 DONE;
5460 })
5461
5462 ;; Avoid partial SSE register dependency stalls. This splitter should split
5463 ;; late in the pass sequence (after register rename pass), so allocated
5464 ;; registers won't change anymore
5465
5466 (define_split
5467 [(set (match_operand:MODEF 0 "sse_reg_operand")
5468 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5469 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5470 && optimize_function_for_speed_p (cfun)
5471 && (!EXT_REX_SSE_REG_P (operands[0])
5472 || TARGET_AVX512VL)"
5473 [(set (match_dup 0)
5474 (vec_merge:<MODEF:ssevecmode>
5475 (vec_duplicate:<MODEF:ssevecmode>
5476 (float:MODEF
5477 (match_dup 1)))
5478 (match_dup 0)
5479 (const_int 1)))]
5480 {
5481 const machine_mode vmode = <MODEF:ssevecmode>mode;
5482
5483 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5484 emit_move_insn (operands[0], CONST0_RTX (vmode));
5485 })
5486
5487 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5488 ;; late in the pass sequence (after register rename pass),
5489 ;; so allocated registers won't change anymore.
5490
5491 (define_split
5492 [(set (match_operand:SF 0 "sse_reg_operand")
5493 (float_truncate:SF
5494 (match_operand:DF 1 "nonimmediate_operand")))]
5495 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5496 && optimize_function_for_speed_p (cfun)
5497 && (!REG_P (operands[1])
5498 || REGNO (operands[0]) != REGNO (operands[1]))
5499 && (!EXT_REX_SSE_REG_P (operands[0])
5500 || TARGET_AVX512VL)"
5501 [(set (match_dup 0)
5502 (vec_merge:V4SF
5503 (vec_duplicate:V4SF
5504 (float_truncate:SF
5505 (match_dup 1)))
5506 (match_dup 0)
5507 (const_int 1)))]
5508 {
5509 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5510 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5511 })
5512
5513 ;; Break partial reg stall for cvtss2sd. This splitter should split
5514 ;; late in the pass sequence (after register rename pass),
5515 ;; so allocated registers won't change anymore.
5516
5517 (define_split
5518 [(set (match_operand:DF 0 "sse_reg_operand")
5519 (float_extend:DF
5520 (match_operand:SF 1 "nonimmediate_operand")))]
5521 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5522 && optimize_function_for_speed_p (cfun)
5523 && (!REG_P (operands[1])
5524 || REGNO (operands[0]) != REGNO (operands[1]))
5525 && (!EXT_REX_SSE_REG_P (operands[0])
5526 || TARGET_AVX512VL)"
5527 [(set (match_dup 0)
5528 (vec_merge:V2DF
5529 (vec_duplicate:V2DF
5530 (float_extend:DF
5531 (match_dup 1)))
5532 (match_dup 0)
5533 (const_int 1)))]
5534 {
5535 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5536 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5537 })
5538
5539 ;; Avoid store forwarding (partial memory) stall penalty
5540 ;; by passing DImode value through XMM registers. */
5541
5542 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5543 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5544 (float:X87MODEF
5545 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5546 (clobber (match_scratch:V4SI 3 "=X,x"))
5547 (clobber (match_scratch:V4SI 4 "=X,x"))
5548 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5549 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5550 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5551 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5552 "#"
5553 [(set_attr "type" "multi")
5554 (set_attr "mode" "<X87MODEF:MODE>")
5555 (set_attr "unit" "i387")
5556 (set_attr "fp_int_src" "true")])
5557
5558 (define_split
5559 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5560 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5561 (clobber (match_scratch:V4SI 3))
5562 (clobber (match_scratch:V4SI 4))
5563 (clobber (match_operand:DI 2 "memory_operand"))]
5564 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5565 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5566 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5567 && reload_completed"
5568 [(set (match_dup 2) (match_dup 3))
5569 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5570 {
5571 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5572 Assemble the 64-bit DImode value in an xmm register. */
5573 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5574 gen_lowpart (SImode, operands[1])));
5575 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5576 gen_highpart (SImode, operands[1])));
5577 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5578 operands[4]));
5579
5580 operands[3] = gen_lowpart (DImode, operands[3]);
5581 })
5582
5583 (define_split
5584 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5585 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5586 (clobber (match_scratch:V4SI 3))
5587 (clobber (match_scratch:V4SI 4))
5588 (clobber (match_operand:DI 2 "memory_operand"))]
5589 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5590 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5591 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5592 && reload_completed"
5593 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5594
5595 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5596 [(set (match_operand:MODEF 0 "register_operand")
5597 (unsigned_float:MODEF
5598 (match_operand:SWI12 1 "nonimmediate_operand")))]
5599 "!TARGET_64BIT
5600 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5601 {
5602 operands[1] = convert_to_mode (SImode, operands[1], 1);
5603 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5604 DONE;
5605 })
5606
5607 ;; Avoid store forwarding (partial memory) stall penalty by extending
5608 ;; SImode value to DImode through XMM register instead of pushing two
5609 ;; SImode values to stack. Also note that fild loads from memory only.
5610
5611 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5612 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5613 (unsigned_float:X87MODEF
5614 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5615 (clobber (match_scratch:DI 3 "=x"))
5616 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5617 "!TARGET_64BIT
5618 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5619 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5620 "#"
5621 "&& reload_completed"
5622 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5623 (set (match_dup 2) (match_dup 3))
5624 (set (match_dup 0)
5625 (float:X87MODEF (match_dup 2)))]
5626 ""
5627 [(set_attr "type" "multi")
5628 (set_attr "mode" "<MODE>")])
5629
5630 (define_expand "floatunssi<mode>2"
5631 [(parallel
5632 [(set (match_operand:X87MODEF 0 "register_operand")
5633 (unsigned_float:X87MODEF
5634 (match_operand:SI 1 "nonimmediate_operand")))
5635 (clobber (match_scratch:DI 3))
5636 (clobber (match_dup 2))])]
5637 "!TARGET_64BIT
5638 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5639 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5640 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5641 {
5642 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5643 {
5644 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5645 DONE;
5646 }
5647 else
5648 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5649 })
5650
5651 (define_expand "floatunsdisf2"
5652 [(use (match_operand:SF 0 "register_operand"))
5653 (use (match_operand:DI 1 "nonimmediate_operand"))]
5654 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5655 "x86_emit_floatuns (operands); DONE;")
5656
5657 (define_expand "floatunsdidf2"
5658 [(use (match_operand:DF 0 "register_operand"))
5659 (use (match_operand:DI 1 "nonimmediate_operand"))]
5660 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5661 && TARGET_SSE2 && TARGET_SSE_MATH"
5662 {
5663 if (TARGET_64BIT)
5664 x86_emit_floatuns (operands);
5665 else
5666 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5667 DONE;
5668 })
5669 \f
5670 ;; Load effective address instructions
5671
5672 (define_insn_and_split "*lea<mode>"
5673 [(set (match_operand:SWI48 0 "register_operand" "=r")
5674 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5675 ""
5676 {
5677 if (SImode_address_operand (operands[1], VOIDmode))
5678 {
5679 gcc_assert (TARGET_64BIT);
5680 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5681 }
5682 else
5683 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5684 }
5685 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5686 [(const_int 0)]
5687 {
5688 machine_mode mode = <MODE>mode;
5689 rtx pat;
5690
5691 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5692 change operands[] array behind our back. */
5693 pat = PATTERN (curr_insn);
5694
5695 operands[0] = SET_DEST (pat);
5696 operands[1] = SET_SRC (pat);
5697
5698 /* Emit all operations in SImode for zero-extended addresses. */
5699 if (SImode_address_operand (operands[1], VOIDmode))
5700 mode = SImode;
5701
5702 ix86_split_lea_for_addr (curr_insn, operands, mode);
5703
5704 /* Zero-extend return register to DImode for zero-extended addresses. */
5705 if (mode != <MODE>mode)
5706 emit_insn (gen_zero_extendsidi2
5707 (operands[0], gen_lowpart (mode, operands[0])));
5708
5709 DONE;
5710 }
5711 [(set_attr "type" "lea")
5712 (set (attr "mode")
5713 (if_then_else
5714 (match_operand 1 "SImode_address_operand")
5715 (const_string "SI")
5716 (const_string "<MODE>")))])
5717 \f
5718 ;; Add instructions
5719
5720 (define_expand "add<mode>3"
5721 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5722 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5723 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5724 ""
5725 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5726
5727 (define_insn_and_split "*add<dwi>3_doubleword"
5728 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5729 (plus:<DWI>
5730 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5731 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5732 "ro<di>,r<di>")))
5733 (clobber (reg:CC FLAGS_REG))]
5734 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5735 "#"
5736 "reload_completed"
5737 [(parallel [(set (reg:CCC FLAGS_REG)
5738 (compare:CCC
5739 (plus:DWIH (match_dup 1) (match_dup 2))
5740 (match_dup 1)))
5741 (set (match_dup 0)
5742 (plus:DWIH (match_dup 1) (match_dup 2)))])
5743 (parallel [(set (match_dup 3)
5744 (plus:DWIH
5745 (plus:DWIH
5746 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5747 (match_dup 4))
5748 (match_dup 5)))
5749 (clobber (reg:CC FLAGS_REG))])]
5750 {
5751 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5752 if (operands[2] == const0_rtx)
5753 {
5754 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5755 DONE;
5756 }
5757 })
5758
5759 (define_insn "*add<mode>_1"
5760 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5761 (plus:SWI48
5762 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5763 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5766 {
5767 switch (get_attr_type (insn))
5768 {
5769 case TYPE_LEA:
5770 return "#";
5771
5772 case TYPE_INCDEC:
5773 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5774 if (operands[2] == const1_rtx)
5775 return "inc{<imodesuffix>}\t%0";
5776 else
5777 {
5778 gcc_assert (operands[2] == constm1_rtx);
5779 return "dec{<imodesuffix>}\t%0";
5780 }
5781
5782 default:
5783 /* For most processors, ADD is faster than LEA. This alternative
5784 was added to use ADD as much as possible. */
5785 if (which_alternative == 2)
5786 std::swap (operands[1], operands[2]);
5787
5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5790 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5791
5792 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5793 }
5794 }
5795 [(set (attr "type")
5796 (cond [(eq_attr "alternative" "3")
5797 (const_string "lea")
5798 (match_operand:SWI48 2 "incdec_operand")
5799 (const_string "incdec")
5800 ]
5801 (const_string "alu")))
5802 (set (attr "length_immediate")
5803 (if_then_else
5804 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5805 (const_string "1")
5806 (const_string "*")))
5807 (set_attr "mode" "<MODE>")])
5808
5809 ;; It may seem that nonimmediate operand is proper one for operand 1.
5810 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5811 ;; we take care in ix86_binary_operator_ok to not allow two memory
5812 ;; operands so proper swapping will be done in reload. This allow
5813 ;; patterns constructed from addsi_1 to match.
5814
5815 (define_insn "addsi_1_zext"
5816 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5817 (zero_extend:DI
5818 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5819 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5820 (clobber (reg:CC FLAGS_REG))]
5821 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5822 {
5823 switch (get_attr_type (insn))
5824 {
5825 case TYPE_LEA:
5826 return "#";
5827
5828 case TYPE_INCDEC:
5829 if (operands[2] == const1_rtx)
5830 return "inc{l}\t%k0";
5831 else
5832 {
5833 gcc_assert (operands[2] == constm1_rtx);
5834 return "dec{l}\t%k0";
5835 }
5836
5837 default:
5838 /* For most processors, ADD is faster than LEA. This alternative
5839 was added to use ADD as much as possible. */
5840 if (which_alternative == 1)
5841 std::swap (operands[1], operands[2]);
5842
5843 if (x86_maybe_negate_const_int (&operands[2], SImode))
5844 return "sub{l}\t{%2, %k0|%k0, %2}";
5845
5846 return "add{l}\t{%2, %k0|%k0, %2}";
5847 }
5848 }
5849 [(set (attr "type")
5850 (cond [(eq_attr "alternative" "2")
5851 (const_string "lea")
5852 (match_operand:SI 2 "incdec_operand")
5853 (const_string "incdec")
5854 ]
5855 (const_string "alu")))
5856 (set (attr "length_immediate")
5857 (if_then_else
5858 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5859 (const_string "1")
5860 (const_string "*")))
5861 (set_attr "mode" "SI")])
5862
5863 (define_insn "*addhi_1"
5864 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5865 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5866 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5867 (clobber (reg:CC FLAGS_REG))]
5868 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5869 {
5870 switch (get_attr_type (insn))
5871 {
5872 case TYPE_LEA:
5873 return "#";
5874
5875 case TYPE_INCDEC:
5876 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5877 if (operands[2] == const1_rtx)
5878 return "inc{w}\t%0";
5879 else
5880 {
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{w}\t%0";
5883 }
5884
5885 default:
5886 /* For most processors, ADD is faster than LEA. This alternative
5887 was added to use ADD as much as possible. */
5888 if (which_alternative == 2)
5889 std::swap (operands[1], operands[2]);
5890
5891 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5892 if (x86_maybe_negate_const_int (&operands[2], HImode))
5893 return "sub{w}\t{%2, %0|%0, %2}";
5894
5895 return "add{w}\t{%2, %0|%0, %2}";
5896 }
5897 }
5898 [(set (attr "type")
5899 (cond [(eq_attr "alternative" "3")
5900 (const_string "lea")
5901 (match_operand:HI 2 "incdec_operand")
5902 (const_string "incdec")
5903 ]
5904 (const_string "alu")))
5905 (set (attr "length_immediate")
5906 (if_then_else
5907 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5908 (const_string "1")
5909 (const_string "*")))
5910 (set_attr "mode" "HI,HI,HI,SI")])
5911
5912 (define_insn "*addqi_1"
5913 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5914 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5915 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5916 (clobber (reg:CC FLAGS_REG))]
5917 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5918 {
5919 bool widen = (get_attr_mode (insn) != MODE_QI);
5920
5921 switch (get_attr_type (insn))
5922 {
5923 case TYPE_LEA:
5924 return "#";
5925
5926 case TYPE_INCDEC:
5927 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5928 if (operands[2] == const1_rtx)
5929 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5930 else
5931 {
5932 gcc_assert (operands[2] == constm1_rtx);
5933 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5934 }
5935
5936 default:
5937 /* For most processors, ADD is faster than LEA. These alternatives
5938 were added to use ADD as much as possible. */
5939 if (which_alternative == 2 || which_alternative == 4)
5940 std::swap (operands[1], operands[2]);
5941
5942 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5943 if (x86_maybe_negate_const_int (&operands[2], QImode))
5944 {
5945 if (widen)
5946 return "sub{l}\t{%2, %k0|%k0, %2}";
5947 else
5948 return "sub{b}\t{%2, %0|%0, %2}";
5949 }
5950 if (widen)
5951 return "add{l}\t{%k2, %k0|%k0, %k2}";
5952 else
5953 return "add{b}\t{%2, %0|%0, %2}";
5954 }
5955 }
5956 [(set (attr "type")
5957 (cond [(eq_attr "alternative" "5")
5958 (const_string "lea")
5959 (match_operand:QI 2 "incdec_operand")
5960 (const_string "incdec")
5961 ]
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5964 (if_then_else
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5966 (const_string "1")
5967 (const_string "*")))
5968 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5969 ;; Potential partial reg stall on alternatives 3 and 4.
5970 (set (attr "preferred_for_speed")
5971 (cond [(eq_attr "alternative" "3,4")
5972 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5973 (symbol_ref "true")))])
5974
5975 (define_insn "*addqi_1_slp"
5976 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5977 (plus:QI (match_dup 0)
5978 (match_operand:QI 1 "general_operand" "qn,qm")))
5979 (clobber (reg:CC FLAGS_REG))]
5980 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5981 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5982 {
5983 switch (get_attr_type (insn))
5984 {
5985 case TYPE_INCDEC:
5986 if (operands[1] == const1_rtx)
5987 return "inc{b}\t%0";
5988 else
5989 {
5990 gcc_assert (operands[1] == constm1_rtx);
5991 return "dec{b}\t%0";
5992 }
5993
5994 default:
5995 if (x86_maybe_negate_const_int (&operands[1], QImode))
5996 return "sub{b}\t{%1, %0|%0, %1}";
5997
5998 return "add{b}\t{%1, %0|%0, %1}";
5999 }
6000 }
6001 [(set (attr "type")
6002 (if_then_else (match_operand:QI 1 "incdec_operand")
6003 (const_string "incdec")
6004 (const_string "alu1")))
6005 (set (attr "memory")
6006 (if_then_else (match_operand 1 "memory_operand")
6007 (const_string "load")
6008 (const_string "none")))
6009 (set_attr "mode" "QI")])
6010
6011 ;; Split non destructive adds if we cannot use lea.
6012 (define_split
6013 [(set (match_operand:SWI48 0 "register_operand")
6014 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6015 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6016 (clobber (reg:CC FLAGS_REG))]
6017 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6018 [(set (match_dup 0) (match_dup 1))
6019 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6020 (clobber (reg:CC FLAGS_REG))])])
6021
6022 ;; Split non destructive adds if we cannot use lea.
6023 (define_split
6024 [(set (match_operand:DI 0 "register_operand")
6025 (zero_extend:DI
6026 (plus:SI (match_operand:SI 1 "register_operand")
6027 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6028 (clobber (reg:CC FLAGS_REG))]
6029 "TARGET_64BIT
6030 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6031 [(set (match_dup 3) (match_dup 1))
6032 (parallel [(set (match_dup 0)
6033 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6034 (clobber (reg:CC FLAGS_REG))])]
6035 "operands[3] = gen_lowpart (SImode, operands[0]);")
6036
6037 ;; Convert add to the lea pattern to avoid flags dependency.
6038 (define_split
6039 [(set (match_operand:SWI 0 "register_operand")
6040 (plus:SWI (match_operand:SWI 1 "register_operand")
6041 (match_operand:SWI 2 "<nonmemory_operand>")))
6042 (clobber (reg:CC FLAGS_REG))]
6043 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6044 [(set (match_dup 0)
6045 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6046 {
6047 if (<MODE>mode != <LEAMODE>mode)
6048 {
6049 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6050 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6051 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6052 }
6053 })
6054
6055 ;; Convert add to the lea pattern to avoid flags dependency.
6056 (define_split
6057 [(set (match_operand:DI 0 "register_operand")
6058 (zero_extend:DI
6059 (plus:SI (match_operand:SI 1 "register_operand")
6060 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6061 (clobber (reg:CC FLAGS_REG))]
6062 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6063 [(set (match_dup 0)
6064 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6065
6066 (define_insn "*add<mode>_2"
6067 [(set (reg FLAGS_REG)
6068 (compare
6069 (plus:SWI
6070 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6071 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6072 (const_int 0)))
6073 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6074 (plus:SWI (match_dup 1) (match_dup 2)))]
6075 "ix86_match_ccmode (insn, CCGOCmode)
6076 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6077 {
6078 switch (get_attr_type (insn))
6079 {
6080 case TYPE_INCDEC:
6081 if (operands[2] == const1_rtx)
6082 return "inc{<imodesuffix>}\t%0";
6083 else
6084 {
6085 gcc_assert (operands[2] == constm1_rtx);
6086 return "dec{<imodesuffix>}\t%0";
6087 }
6088
6089 default:
6090 if (which_alternative == 2)
6091 std::swap (operands[1], operands[2]);
6092
6093 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6094 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6095 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6096
6097 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6098 }
6099 }
6100 [(set (attr "type")
6101 (if_then_else (match_operand:SWI 2 "incdec_operand")
6102 (const_string "incdec")
6103 (const_string "alu")))
6104 (set (attr "length_immediate")
6105 (if_then_else
6106 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6107 (const_string "1")
6108 (const_string "*")))
6109 (set_attr "mode" "<MODE>")])
6110
6111 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6112 (define_insn "*addsi_2_zext"
6113 [(set (reg FLAGS_REG)
6114 (compare
6115 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6116 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6117 (const_int 0)))
6118 (set (match_operand:DI 0 "register_operand" "=r,r")
6119 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6120 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6121 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6122 {
6123 switch (get_attr_type (insn))
6124 {
6125 case TYPE_INCDEC:
6126 if (operands[2] == const1_rtx)
6127 return "inc{l}\t%k0";
6128 else
6129 {
6130 gcc_assert (operands[2] == constm1_rtx);
6131 return "dec{l}\t%k0";
6132 }
6133
6134 default:
6135 if (which_alternative == 1)
6136 std::swap (operands[1], operands[2]);
6137
6138 if (x86_maybe_negate_const_int (&operands[2], SImode))
6139 return "sub{l}\t{%2, %k0|%k0, %2}";
6140
6141 return "add{l}\t{%2, %k0|%k0, %2}";
6142 }
6143 }
6144 [(set (attr "type")
6145 (if_then_else (match_operand:SI 2 "incdec_operand")
6146 (const_string "incdec")
6147 (const_string "alu")))
6148 (set (attr "length_immediate")
6149 (if_then_else
6150 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6151 (const_string "1")
6152 (const_string "*")))
6153 (set_attr "mode" "SI")])
6154
6155 (define_insn "*add<mode>_3"
6156 [(set (reg FLAGS_REG)
6157 (compare
6158 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6159 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6160 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6161 "ix86_match_ccmode (insn, CCZmode)
6162 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6163 {
6164 switch (get_attr_type (insn))
6165 {
6166 case TYPE_INCDEC:
6167 if (operands[2] == const1_rtx)
6168 return "inc{<imodesuffix>}\t%0";
6169 else
6170 {
6171 gcc_assert (operands[2] == constm1_rtx);
6172 return "dec{<imodesuffix>}\t%0";
6173 }
6174
6175 default:
6176 if (which_alternative == 1)
6177 std::swap (operands[1], operands[2]);
6178
6179 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6180 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6181 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6182
6183 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6184 }
6185 }
6186 [(set (attr "type")
6187 (if_then_else (match_operand:SWI 2 "incdec_operand")
6188 (const_string "incdec")
6189 (const_string "alu")))
6190 (set (attr "length_immediate")
6191 (if_then_else
6192 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6193 (const_string "1")
6194 (const_string "*")))
6195 (set_attr "mode" "<MODE>")])
6196
6197 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6198 (define_insn "*addsi_3_zext"
6199 [(set (reg FLAGS_REG)
6200 (compare
6201 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6202 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6203 (set (match_operand:DI 0 "register_operand" "=r,r")
6204 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6205 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6206 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6207 {
6208 switch (get_attr_type (insn))
6209 {
6210 case TYPE_INCDEC:
6211 if (operands[2] == const1_rtx)
6212 return "inc{l}\t%k0";
6213 else
6214 {
6215 gcc_assert (operands[2] == constm1_rtx);
6216 return "dec{l}\t%k0";
6217 }
6218
6219 default:
6220 if (which_alternative == 1)
6221 std::swap (operands[1], operands[2]);
6222
6223 if (x86_maybe_negate_const_int (&operands[2], SImode))
6224 return "sub{l}\t{%2, %k0|%k0, %2}";
6225
6226 return "add{l}\t{%2, %k0|%k0, %2}";
6227 }
6228 }
6229 [(set (attr "type")
6230 (if_then_else (match_operand:SI 2 "incdec_operand")
6231 (const_string "incdec")
6232 (const_string "alu")))
6233 (set (attr "length_immediate")
6234 (if_then_else
6235 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6236 (const_string "1")
6237 (const_string "*")))
6238 (set_attr "mode" "SI")])
6239
6240 ; For comparisons against 1, -1 and 128, we may generate better code
6241 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6242 ; is matched then. We can't accept general immediate, because for
6243 ; case of overflows, the result is messed up.
6244 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6245 ; only for comparisons not depending on it.
6246
6247 (define_insn "*adddi_4"
6248 [(set (reg FLAGS_REG)
6249 (compare
6250 (match_operand:DI 1 "nonimmediate_operand" "0")
6251 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6252 (clobber (match_scratch:DI 0 "=rm"))]
6253 "TARGET_64BIT
6254 && ix86_match_ccmode (insn, CCGCmode)"
6255 {
6256 switch (get_attr_type (insn))
6257 {
6258 case TYPE_INCDEC:
6259 if (operands[2] == constm1_rtx)
6260 return "inc{q}\t%0";
6261 else
6262 {
6263 gcc_assert (operands[2] == const1_rtx);
6264 return "dec{q}\t%0";
6265 }
6266
6267 default:
6268 if (x86_maybe_negate_const_int (&operands[2], DImode))
6269 return "add{q}\t{%2, %0|%0, %2}";
6270
6271 return "sub{q}\t{%2, %0|%0, %2}";
6272 }
6273 }
6274 [(set (attr "type")
6275 (if_then_else (match_operand:DI 2 "incdec_operand")
6276 (const_string "incdec")
6277 (const_string "alu")))
6278 (set (attr "length_immediate")
6279 (if_then_else
6280 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6281 (const_string "1")
6282 (const_string "*")))
6283 (set_attr "mode" "DI")])
6284
6285 ; For comparisons against 1, -1 and 128, we may generate better code
6286 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6287 ; is matched then. We can't accept general immediate, because for
6288 ; case of overflows, the result is messed up.
6289 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6290 ; only for comparisons not depending on it.
6291
6292 (define_insn "*add<mode>_4"
6293 [(set (reg FLAGS_REG)
6294 (compare
6295 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6296 (match_operand:SWI124 2 "const_int_operand" "n")))
6297 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6298 "ix86_match_ccmode (insn, CCGCmode)"
6299 {
6300 switch (get_attr_type (insn))
6301 {
6302 case TYPE_INCDEC:
6303 if (operands[2] == constm1_rtx)
6304 return "inc{<imodesuffix>}\t%0";
6305 else
6306 {
6307 gcc_assert (operands[2] == const1_rtx);
6308 return "dec{<imodesuffix>}\t%0";
6309 }
6310
6311 default:
6312 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6313 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6314
6315 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6316 }
6317 }
6318 [(set (attr "type")
6319 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6320 (const_string "incdec")
6321 (const_string "alu")))
6322 (set (attr "length_immediate")
6323 (if_then_else
6324 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6325 (const_string "1")
6326 (const_string "*")))
6327 (set_attr "mode" "<MODE>")])
6328
6329 (define_insn "*add<mode>_5"
6330 [(set (reg FLAGS_REG)
6331 (compare
6332 (plus:SWI
6333 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6334 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6335 (const_int 0)))
6336 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6337 "ix86_match_ccmode (insn, CCGOCmode)
6338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6339 {
6340 switch (get_attr_type (insn))
6341 {
6342 case TYPE_INCDEC:
6343 if (operands[2] == const1_rtx)
6344 return "inc{<imodesuffix>}\t%0";
6345 else
6346 {
6347 gcc_assert (operands[2] == constm1_rtx);
6348 return "dec{<imodesuffix>}\t%0";
6349 }
6350
6351 default:
6352 if (which_alternative == 1)
6353 std::swap (operands[1], operands[2]);
6354
6355 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6357 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6358
6359 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6360 }
6361 }
6362 [(set (attr "type")
6363 (if_then_else (match_operand:SWI 2 "incdec_operand")
6364 (const_string "incdec")
6365 (const_string "alu")))
6366 (set (attr "length_immediate")
6367 (if_then_else
6368 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6369 (const_string "1")
6370 (const_string "*")))
6371 (set_attr "mode" "<MODE>")])
6372
6373 (define_insn "addqi_ext_1"
6374 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6375 (const_int 8)
6376 (const_int 8))
6377 (subreg:SI
6378 (plus:QI
6379 (subreg:QI
6380 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6381 (const_int 8)
6382 (const_int 8)) 0)
6383 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6384 (clobber (reg:CC FLAGS_REG))]
6385 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6386 rtx_equal_p (operands[0], operands[1])"
6387 {
6388 switch (get_attr_type (insn))
6389 {
6390 case TYPE_INCDEC:
6391 if (operands[2] == const1_rtx)
6392 return "inc{b}\t%h0";
6393 else
6394 {
6395 gcc_assert (operands[2] == constm1_rtx);
6396 return "dec{b}\t%h0";
6397 }
6398
6399 default:
6400 return "add{b}\t{%2, %h0|%h0, %2}";
6401 }
6402 }
6403 [(set_attr "isa" "*,nox64")
6404 (set (attr "type")
6405 (if_then_else (match_operand:QI 2 "incdec_operand")
6406 (const_string "incdec")
6407 (const_string "alu")))
6408 (set_attr "mode" "QI")])
6409
6410 (define_insn "*addqi_ext_2"
6411 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6412 (const_int 8)
6413 (const_int 8))
6414 (subreg:SI
6415 (plus:QI
6416 (subreg:QI
6417 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6418 (const_int 8)
6419 (const_int 8)) 0)
6420 (subreg:QI
6421 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6422 (const_int 8)
6423 (const_int 8)) 0)) 0))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6426 rtx_equal_p (operands[0], operands[1])
6427 || rtx_equal_p (operands[0], operands[2])"
6428 "add{b}\t{%h2, %h0|%h0, %h2}"
6429 [(set_attr "type" "alu")
6430 (set_attr "mode" "QI")])
6431
6432 ;; Add with jump on overflow.
6433 (define_expand "addv<mode>4"
6434 [(parallel [(set (reg:CCO FLAGS_REG)
6435 (eq:CCO (plus:<DWI>
6436 (sign_extend:<DWI>
6437 (match_operand:SWI 1 "nonimmediate_operand"))
6438 (match_dup 4))
6439 (sign_extend:<DWI>
6440 (plus:SWI (match_dup 1)
6441 (match_operand:SWI 2
6442 "<general_operand>")))))
6443 (set (match_operand:SWI 0 "register_operand")
6444 (plus:SWI (match_dup 1) (match_dup 2)))])
6445 (set (pc) (if_then_else
6446 (eq (reg:CCO FLAGS_REG) (const_int 0))
6447 (label_ref (match_operand 3))
6448 (pc)))]
6449 ""
6450 {
6451 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6452 if (CONST_INT_P (operands[2]))
6453 operands[4] = operands[2];
6454 else
6455 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6456 })
6457
6458 (define_insn "*addv<mode>4"
6459 [(set (reg:CCO FLAGS_REG)
6460 (eq:CCO (plus:<DWI>
6461 (sign_extend:<DWI>
6462 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6463 (sign_extend:<DWI>
6464 (match_operand:SWI 2 "<general_sext_operand>"
6465 "<r>mWe,<r>We")))
6466 (sign_extend:<DWI>
6467 (plus:SWI (match_dup 1) (match_dup 2)))))
6468 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6469 (plus:SWI (match_dup 1) (match_dup 2)))]
6470 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6471 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6472 [(set_attr "type" "alu")
6473 (set_attr "mode" "<MODE>")])
6474
6475 (define_insn "*addv<mode>4_1"
6476 [(set (reg:CCO FLAGS_REG)
6477 (eq:CCO (plus:<DWI>
6478 (sign_extend:<DWI>
6479 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6480 (match_operand:<DWI> 3 "const_int_operand" "i"))
6481 (sign_extend:<DWI>
6482 (plus:SWI (match_dup 1)
6483 (match_operand:SWI 2 "x86_64_immediate_operand"
6484 "<i>")))))
6485 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6486 (plus:SWI (match_dup 1) (match_dup 2)))]
6487 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6488 && CONST_INT_P (operands[2])
6489 && INTVAL (operands[2]) == INTVAL (operands[3])"
6490 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6491 [(set_attr "type" "alu")
6492 (set_attr "mode" "<MODE>")
6493 (set (attr "length_immediate")
6494 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6495 (const_string "1")
6496 (match_test "<MODE_SIZE> == 8")
6497 (const_string "4")]
6498 (const_string "<MODE_SIZE>")))])
6499
6500 (define_expand "uaddv<mode>4"
6501 [(parallel [(set (reg:CCC FLAGS_REG)
6502 (compare:CCC
6503 (plus:SWI
6504 (match_operand:SWI 1 "nonimmediate_operand")
6505 (match_operand:SWI 2 "<general_operand>"))
6506 (match_dup 1)))
6507 (set (match_operand:SWI 0 "register_operand")
6508 (plus:SWI (match_dup 1) (match_dup 2)))])
6509 (set (pc) (if_then_else
6510 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6511 (label_ref (match_operand 3))
6512 (pc)))]
6513 ""
6514 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6515
6516 ;; The lea patterns for modes less than 32 bits need to be matched by
6517 ;; several insns converted to real lea by splitters.
6518
6519 (define_insn_and_split "*lea<mode>_general_1"
6520 [(set (match_operand:SWI12 0 "register_operand" "=r")
6521 (plus:SWI12
6522 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6523 (match_operand:SWI12 2 "register_operand" "r"))
6524 (match_operand:SWI12 3 "immediate_operand" "i")))]
6525 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6526 "#"
6527 "&& reload_completed"
6528 [(set (match_dup 0)
6529 (plus:SI
6530 (plus:SI (match_dup 1) (match_dup 2))
6531 (match_dup 3)))]
6532 {
6533 operands[0] = gen_lowpart (SImode, operands[0]);
6534 operands[1] = gen_lowpart (SImode, operands[1]);
6535 operands[2] = gen_lowpart (SImode, operands[2]);
6536 operands[3] = gen_lowpart (SImode, operands[3]);
6537 }
6538 [(set_attr "type" "lea")
6539 (set_attr "mode" "SI")])
6540
6541 (define_insn_and_split "*lea<mode>_general_2"
6542 [(set (match_operand:SWI12 0 "register_operand" "=r")
6543 (plus:SWI12
6544 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6545 (match_operand 2 "const248_operand" "n"))
6546 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6547 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6548 "#"
6549 "&& reload_completed"
6550 [(set (match_dup 0)
6551 (plus:SI
6552 (mult:SI (match_dup 1) (match_dup 2))
6553 (match_dup 3)))]
6554 {
6555 operands[0] = gen_lowpart (SImode, operands[0]);
6556 operands[1] = gen_lowpart (SImode, operands[1]);
6557 operands[3] = gen_lowpart (SImode, operands[3]);
6558 }
6559 [(set_attr "type" "lea")
6560 (set_attr "mode" "SI")])
6561
6562 (define_insn_and_split "*lea<mode>_general_2b"
6563 [(set (match_operand:SWI12 0 "register_operand" "=r")
6564 (plus:SWI12
6565 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6566 (match_operand 2 "const123_operand" "n"))
6567 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6568 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6569 "#"
6570 "&& reload_completed"
6571 [(set (match_dup 0)
6572 (plus:SI
6573 (ashift:SI (match_dup 1) (match_dup 2))
6574 (match_dup 3)))]
6575 {
6576 operands[0] = gen_lowpart (SImode, operands[0]);
6577 operands[1] = gen_lowpart (SImode, operands[1]);
6578 operands[3] = gen_lowpart (SImode, operands[3]);
6579 }
6580 [(set_attr "type" "lea")
6581 (set_attr "mode" "SI")])
6582
6583 (define_insn_and_split "*lea<mode>_general_3"
6584 [(set (match_operand:SWI12 0 "register_operand" "=r")
6585 (plus:SWI12
6586 (plus:SWI12
6587 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6588 (match_operand 2 "const248_operand" "n"))
6589 (match_operand:SWI12 3 "register_operand" "r"))
6590 (match_operand:SWI12 4 "immediate_operand" "i")))]
6591 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6592 "#"
6593 "&& reload_completed"
6594 [(set (match_dup 0)
6595 (plus:SI
6596 (plus:SI
6597 (mult:SI (match_dup 1) (match_dup 2))
6598 (match_dup 3))
6599 (match_dup 4)))]
6600 {
6601 operands[0] = gen_lowpart (SImode, operands[0]);
6602 operands[1] = gen_lowpart (SImode, operands[1]);
6603 operands[3] = gen_lowpart (SImode, operands[3]);
6604 operands[4] = gen_lowpart (SImode, operands[4]);
6605 }
6606 [(set_attr "type" "lea")
6607 (set_attr "mode" "SI")])
6608
6609 (define_insn_and_split "*lea<mode>_general_3b"
6610 [(set (match_operand:SWI12 0 "register_operand" "=r")
6611 (plus:SWI12
6612 (plus:SWI12
6613 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6614 (match_operand 2 "const123_operand" "n"))
6615 (match_operand:SWI12 3 "register_operand" "r"))
6616 (match_operand:SWI12 4 "immediate_operand" "i")))]
6617 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6618 "#"
6619 "&& reload_completed"
6620 [(set (match_dup 0)
6621 (plus:SI
6622 (plus:SI
6623 (ashift:SI (match_dup 1) (match_dup 2))
6624 (match_dup 3))
6625 (match_dup 4)))]
6626 {
6627 operands[0] = gen_lowpart (SImode, operands[0]);
6628 operands[1] = gen_lowpart (SImode, operands[1]);
6629 operands[3] = gen_lowpart (SImode, operands[3]);
6630 operands[4] = gen_lowpart (SImode, operands[4]);
6631 }
6632 [(set_attr "type" "lea")
6633 (set_attr "mode" "SI")])
6634
6635 (define_insn_and_split "*lea<mode>_general_4"
6636 [(set (match_operand:SWI12 0 "register_operand" "=r")
6637 (any_or:SWI12
6638 (ashift:SWI12
6639 (match_operand:SWI12 1 "index_register_operand" "l")
6640 (match_operand 2 "const_0_to_3_operand" "n"))
6641 (match_operand 3 "const_int_operand" "n")))]
6642 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6643 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6644 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6645 "#"
6646 "&& reload_completed"
6647 [(set (match_dup 0)
6648 (plus:SI
6649 (mult:SI (match_dup 1) (match_dup 2))
6650 (match_dup 3)))]
6651 {
6652 operands[0] = gen_lowpart (SImode, operands[0]);
6653 operands[1] = gen_lowpart (SImode, operands[1]);
6654 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6655 }
6656 [(set_attr "type" "lea")
6657 (set_attr "mode" "SI")])
6658
6659 (define_insn_and_split "*lea<mode>_general_4"
6660 [(set (match_operand:SWI48 0 "register_operand" "=r")
6661 (any_or:SWI48
6662 (ashift:SWI48
6663 (match_operand:SWI48 1 "index_register_operand" "l")
6664 (match_operand 2 "const_0_to_3_operand" "n"))
6665 (match_operand 3 "const_int_operand" "n")))]
6666 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6667 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6668 "#"
6669 "&& reload_completed"
6670 [(set (match_dup 0)
6671 (plus:SWI48
6672 (mult:SWI48 (match_dup 1) (match_dup 2))
6673 (match_dup 3)))]
6674 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6675 [(set_attr "type" "lea")
6676 (set_attr "mode" "<MODE>")])
6677 \f
6678 ;; Subtract instructions
6679
6680 (define_expand "sub<mode>3"
6681 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6682 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6683 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6684 ""
6685 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6686
6687 (define_insn_and_split "*sub<dwi>3_doubleword"
6688 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6689 (minus:<DWI>
6690 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6691 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6692 "ro<di>,r<di>")))
6693 (clobber (reg:CC FLAGS_REG))]
6694 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6695 "#"
6696 "reload_completed"
6697 [(parallel [(set (reg:CC FLAGS_REG)
6698 (compare:CC (match_dup 1) (match_dup 2)))
6699 (set (match_dup 0)
6700 (minus:DWIH (match_dup 1) (match_dup 2)))])
6701 (parallel [(set (match_dup 3)
6702 (minus:DWIH
6703 (minus:DWIH
6704 (match_dup 4)
6705 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6706 (match_dup 5)))
6707 (clobber (reg:CC FLAGS_REG))])]
6708 {
6709 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6710 if (operands[2] == const0_rtx)
6711 {
6712 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6713 DONE;
6714 }
6715 })
6716
6717 (define_insn "*sub<mode>_1"
6718 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6719 (minus:SWI
6720 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6721 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6724 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "<MODE>")])
6727
6728 (define_insn "*subsi_1_zext"
6729 [(set (match_operand:DI 0 "register_operand" "=r")
6730 (zero_extend:DI
6731 (minus:SI (match_operand:SI 1 "register_operand" "0")
6732 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6733 (clobber (reg:CC FLAGS_REG))]
6734 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6738
6739 (define_insn "*subqi_1_slp"
6740 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6741 (minus:QI (match_dup 0)
6742 (match_operand:QI 1 "general_operand" "qn,qm")))
6743 (clobber (reg:CC FLAGS_REG))]
6744 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6745 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6746 "sub{b}\t{%1, %0|%0, %1}"
6747 [(set_attr "type" "alu1")
6748 (set_attr "mode" "QI")])
6749
6750 (define_insn "*sub<mode>_2"
6751 [(set (reg FLAGS_REG)
6752 (compare
6753 (minus:SWI
6754 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6755 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6756 (const_int 0)))
6757 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6758 (minus:SWI (match_dup 1) (match_dup 2)))]
6759 "ix86_match_ccmode (insn, CCGOCmode)
6760 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6761 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "mode" "<MODE>")])
6764
6765 (define_insn "*subsi_2_zext"
6766 [(set (reg FLAGS_REG)
6767 (compare
6768 (minus:SI (match_operand:SI 1 "register_operand" "0")
6769 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6770 (const_int 0)))
6771 (set (match_operand:DI 0 "register_operand" "=r")
6772 (zero_extend:DI
6773 (minus:SI (match_dup 1)
6774 (match_dup 2))))]
6775 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6776 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777 "sub{l}\t{%2, %k0|%k0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "mode" "SI")])
6780
6781 ;; Subtract with jump on overflow.
6782 (define_expand "subv<mode>4"
6783 [(parallel [(set (reg:CCO FLAGS_REG)
6784 (eq:CCO (minus:<DWI>
6785 (sign_extend:<DWI>
6786 (match_operand:SWI 1 "nonimmediate_operand"))
6787 (match_dup 4))
6788 (sign_extend:<DWI>
6789 (minus:SWI (match_dup 1)
6790 (match_operand:SWI 2
6791 "<general_operand>")))))
6792 (set (match_operand:SWI 0 "register_operand")
6793 (minus:SWI (match_dup 1) (match_dup 2)))])
6794 (set (pc) (if_then_else
6795 (eq (reg:CCO FLAGS_REG) (const_int 0))
6796 (label_ref (match_operand 3))
6797 (pc)))]
6798 ""
6799 {
6800 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6801 if (CONST_INT_P (operands[2]))
6802 operands[4] = operands[2];
6803 else
6804 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6805 })
6806
6807 (define_insn "*subv<mode>4"
6808 [(set (reg:CCO FLAGS_REG)
6809 (eq:CCO (minus:<DWI>
6810 (sign_extend:<DWI>
6811 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6812 (sign_extend:<DWI>
6813 (match_operand:SWI 2 "<general_sext_operand>"
6814 "<r>We,<r>m")))
6815 (sign_extend:<DWI>
6816 (minus:SWI (match_dup 1) (match_dup 2)))))
6817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6818 (minus:SWI (match_dup 1) (match_dup 2)))]
6819 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6820 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "<MODE>")])
6823
6824 (define_insn "*subv<mode>4_1"
6825 [(set (reg:CCO FLAGS_REG)
6826 (eq:CCO (minus:<DWI>
6827 (sign_extend:<DWI>
6828 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6829 (match_operand:<DWI> 3 "const_int_operand" "i"))
6830 (sign_extend:<DWI>
6831 (minus:SWI (match_dup 1)
6832 (match_operand:SWI 2 "x86_64_immediate_operand"
6833 "<i>")))))
6834 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6835 (minus:SWI (match_dup 1) (match_dup 2)))]
6836 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6837 && CONST_INT_P (operands[2])
6838 && INTVAL (operands[2]) == INTVAL (operands[3])"
6839 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "<MODE>")
6842 (set (attr "length_immediate")
6843 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6844 (const_string "1")
6845 (match_test "<MODE_SIZE> == 8")
6846 (const_string "4")]
6847 (const_string "<MODE_SIZE>")))])
6848
6849 (define_expand "usubv<mode>4"
6850 [(parallel [(set (reg:CC FLAGS_REG)
6851 (compare:CC
6852 (match_operand:SWI 1 "nonimmediate_operand")
6853 (match_operand:SWI 2 "<general_operand>")))
6854 (set (match_operand:SWI 0 "register_operand")
6855 (minus:SWI (match_dup 1) (match_dup 2)))])
6856 (set (pc) (if_then_else
6857 (ltu (reg:CC FLAGS_REG) (const_int 0))
6858 (label_ref (match_operand 3))
6859 (pc)))]
6860 ""
6861 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6862
6863 (define_insn "*sub<mode>_3"
6864 [(set (reg FLAGS_REG)
6865 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6866 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6867 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6868 (minus:SWI (match_dup 1) (match_dup 2)))]
6869 "ix86_match_ccmode (insn, CCmode)
6870 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6871 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6872 [(set_attr "type" "alu")
6873 (set_attr "mode" "<MODE>")])
6874
6875 (define_peephole2
6876 [(parallel
6877 [(set (reg:CC FLAGS_REG)
6878 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6879 (match_operand:SWI 1 "general_gr_operand")))
6880 (set (match_dup 0)
6881 (minus:SWI (match_dup 0) (match_dup 1)))])]
6882 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6883 [(set (reg:CC FLAGS_REG)
6884 (compare:CC (match_dup 0) (match_dup 1)))])
6885
6886 (define_insn "*subsi_3_zext"
6887 [(set (reg FLAGS_REG)
6888 (compare (match_operand:SI 1 "register_operand" "0")
6889 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6890 (set (match_operand:DI 0 "register_operand" "=r")
6891 (zero_extend:DI
6892 (minus:SI (match_dup 1)
6893 (match_dup 2))))]
6894 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6895 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6896 "sub{l}\t{%2, %1|%1, %2}"
6897 [(set_attr "type" "alu")
6898 (set_attr "mode" "SI")])
6899 \f
6900 ;; Add with carry and subtract with borrow
6901
6902 (define_insn "add<mode>3_carry"
6903 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6904 (plus:SWI
6905 (plus:SWI
6906 (match_operator:SWI 4 "ix86_carry_flag_operator"
6907 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6908 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6909 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6910 (clobber (reg:CC FLAGS_REG))]
6911 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6912 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6913 [(set_attr "type" "alu")
6914 (set_attr "use_carry" "1")
6915 (set_attr "pent_pair" "pu")
6916 (set_attr "mode" "<MODE>")])
6917
6918 (define_insn "*add<mode>3_carry_0"
6919 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6920 (plus:SWI
6921 (match_operator:SWI 3 "ix86_carry_flag_operator"
6922 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6923 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6926 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6927 [(set_attr "type" "alu")
6928 (set_attr "use_carry" "1")
6929 (set_attr "pent_pair" "pu")
6930 (set_attr "mode" "<MODE>")])
6931
6932 (define_insn "*addsi3_carry_zext"
6933 [(set (match_operand:DI 0 "register_operand" "=r")
6934 (zero_extend:DI
6935 (plus:SI
6936 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6937 [(reg FLAGS_REG) (const_int 0)])
6938 (match_operand:SI 1 "register_operand" "%0"))
6939 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6940 (clobber (reg:CC FLAGS_REG))]
6941 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6942 "adc{l}\t{%2, %k0|%k0, %2}"
6943 [(set_attr "type" "alu")
6944 (set_attr "use_carry" "1")
6945 (set_attr "pent_pair" "pu")
6946 (set_attr "mode" "SI")])
6947
6948 (define_insn "*addsi3_carry_zext_0"
6949 [(set (match_operand:DI 0 "register_operand" "=r")
6950 (zero_extend:DI
6951 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6952 [(reg FLAGS_REG) (const_int 0)])
6953 (match_operand:SI 1 "register_operand" "0"))))
6954 (clobber (reg:CC FLAGS_REG))]
6955 "TARGET_64BIT"
6956 "adc{l}\t{$0, %k0|%k0, 0}"
6957 [(set_attr "type" "alu")
6958 (set_attr "use_carry" "1")
6959 (set_attr "pent_pair" "pu")
6960 (set_attr "mode" "SI")])
6961
6962 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6963
6964 (define_insn "addcarry<mode>"
6965 [(set (reg:CCC FLAGS_REG)
6966 (compare:CCC
6967 (zero_extend:<DWI>
6968 (plus:SWI48
6969 (plus:SWI48
6970 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6971 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6972 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6973 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6974 (plus:<DWI>
6975 (zero_extend:<DWI> (match_dup 2))
6976 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6977 [(match_dup 3) (const_int 0)]))))
6978 (set (match_operand:SWI48 0 "register_operand" "=r")
6979 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6980 [(match_dup 3) (const_int 0)])
6981 (match_dup 1))
6982 (match_dup 2)))]
6983 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6984 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6985 [(set_attr "type" "alu")
6986 (set_attr "use_carry" "1")
6987 (set_attr "pent_pair" "pu")
6988 (set_attr "mode" "<MODE>")])
6989
6990 (define_expand "addcarry<mode>_0"
6991 [(parallel
6992 [(set (reg:CCC FLAGS_REG)
6993 (compare:CCC
6994 (plus:SWI48
6995 (match_operand:SWI48 1 "nonimmediate_operand")
6996 (match_operand:SWI48 2 "x86_64_general_operand"))
6997 (match_dup 1)))
6998 (set (match_operand:SWI48 0 "register_operand")
6999 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
7000 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
7001
7002 (define_insn "sub<mode>3_carry"
7003 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7004 (minus:SWI
7005 (minus:SWI
7006 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7007 (match_operator:SWI 4 "ix86_carry_flag_operator"
7008 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7009 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7010 (clobber (reg:CC FLAGS_REG))]
7011 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7012 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7013 [(set_attr "type" "alu")
7014 (set_attr "use_carry" "1")
7015 (set_attr "pent_pair" "pu")
7016 (set_attr "mode" "<MODE>")])
7017
7018 (define_insn "*sub<mode>3_carry_0"
7019 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7020 (minus:SWI
7021 (match_operand:SWI 1 "nonimmediate_operand" "0")
7022 (match_operator:SWI 3 "ix86_carry_flag_operator"
7023 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
7024 (clobber (reg:CC FLAGS_REG))]
7025 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
7026 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
7027 [(set_attr "type" "alu")
7028 (set_attr "use_carry" "1")
7029 (set_attr "pent_pair" "pu")
7030 (set_attr "mode" "<MODE>")])
7031
7032 (define_insn "*subsi3_carry_zext"
7033 [(set (match_operand:DI 0 "register_operand" "=r")
7034 (zero_extend:DI
7035 (minus:SI
7036 (minus:SI
7037 (match_operand:SI 1 "register_operand" "0")
7038 (match_operator:SI 3 "ix86_carry_flag_operator"
7039 [(reg FLAGS_REG) (const_int 0)]))
7040 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7041 (clobber (reg:CC FLAGS_REG))]
7042 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7043 "sbb{l}\t{%2, %k0|%k0, %2}"
7044 [(set_attr "type" "alu")
7045 (set_attr "use_carry" "1")
7046 (set_attr "pent_pair" "pu")
7047 (set_attr "mode" "SI")])
7048
7049 (define_insn "*subsi3_carry_zext_0"
7050 [(set (match_operand:DI 0 "register_operand" "=r")
7051 (zero_extend:DI
7052 (minus:SI
7053 (match_operand:SI 1 "register_operand" "0")
7054 (match_operator:SI 2 "ix86_carry_flag_operator"
7055 [(reg FLAGS_REG) (const_int 0)]))))
7056 (clobber (reg:CC FLAGS_REG))]
7057 "TARGET_64BIT"
7058 "sbb{l}\t{$0, %k0|%k0, 0}"
7059 [(set_attr "type" "alu")
7060 (set_attr "use_carry" "1")
7061 (set_attr "pent_pair" "pu")
7062 (set_attr "mode" "SI")])
7063
7064 (define_insn "sub<mode>3_carry_ccc"
7065 [(set (reg:CCC FLAGS_REG)
7066 (compare:CCC
7067 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7068 (plus:<DWI>
7069 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7070 (zero_extend:<DWI>
7071 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7072 (clobber (match_scratch:DWIH 0 "=r"))]
7073 ""
7074 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7075 [(set_attr "type" "alu")
7076 (set_attr "mode" "<MODE>")])
7077
7078 (define_insn "*sub<mode>3_carry_ccc_1"
7079 [(set (reg:CCC FLAGS_REG)
7080 (compare:CCC
7081 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7082 (plus:<DWI>
7083 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7084 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7085 (clobber (match_scratch:DWIH 0 "=r"))]
7086 ""
7087 {
7088 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7089 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7090 }
7091 [(set_attr "type" "alu")
7092 (set_attr "mode" "<MODE>")])
7093
7094 ;; The sign flag is set from the
7095 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7096 ;; result, the overflow flag likewise, but the overflow flag is also
7097 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7098 (define_insn "sub<mode>3_carry_ccgz"
7099 [(set (reg:CCGZ FLAGS_REG)
7100 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7101 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7102 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7103 UNSPEC_SBB))
7104 (clobber (match_scratch:DWIH 0 "=r"))]
7105 ""
7106 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "mode" "<MODE>")])
7109
7110 (define_insn "subborrow<mode>"
7111 [(set (reg:CCC FLAGS_REG)
7112 (compare:CCC
7113 (zero_extend:<DWI>
7114 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7115 (plus:<DWI>
7116 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7117 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7118 (zero_extend:<DWI>
7119 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7120 (set (match_operand:SWI48 0 "register_operand" "=r")
7121 (minus:SWI48 (minus:SWI48
7122 (match_dup 1)
7123 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7124 [(match_dup 3) (const_int 0)]))
7125 (match_dup 2)))]
7126 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7127 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7128 [(set_attr "type" "alu")
7129 (set_attr "use_carry" "1")
7130 (set_attr "pent_pair" "pu")
7131 (set_attr "mode" "<MODE>")])
7132
7133 (define_expand "subborrow<mode>_0"
7134 [(parallel
7135 [(set (reg:CC FLAGS_REG)
7136 (compare:CC
7137 (match_operand:SWI48 1 "nonimmediate_operand")
7138 (match_operand:SWI48 2 "<general_operand>")))
7139 (set (match_operand:SWI48 0 "register_operand")
7140 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7141 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7142 \f
7143 ;; Overflow setting add instructions
7144
7145 (define_expand "addqi3_cconly_overflow"
7146 [(parallel
7147 [(set (reg:CCC FLAGS_REG)
7148 (compare:CCC
7149 (plus:QI
7150 (match_operand:QI 0 "nonimmediate_operand")
7151 (match_operand:QI 1 "general_operand"))
7152 (match_dup 0)))
7153 (clobber (match_scratch:QI 2))])]
7154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7155
7156 (define_insn "*add<mode>3_cconly_overflow_1"
7157 [(set (reg:CCC FLAGS_REG)
7158 (compare:CCC
7159 (plus:SWI
7160 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7161 (match_operand:SWI 2 "<general_operand>" "<g>"))
7162 (match_dup 1)))
7163 (clobber (match_scratch:SWI 0 "=<r>"))]
7164 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7165 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7166 [(set_attr "type" "alu")
7167 (set_attr "mode" "<MODE>")])
7168
7169 (define_insn "*add<mode>3_cc_overflow_1"
7170 [(set (reg:CCC FLAGS_REG)
7171 (compare:CCC
7172 (plus:SWI
7173 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7174 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7175 (match_dup 1)))
7176 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7177 (plus:SWI (match_dup 1) (match_dup 2)))]
7178 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7179 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7180 [(set_attr "type" "alu")
7181 (set_attr "mode" "<MODE>")])
7182
7183 (define_insn "*addsi3_zext_cc_overflow_1"
7184 [(set (reg:CCC FLAGS_REG)
7185 (compare:CCC
7186 (plus:SI
7187 (match_operand:SI 1 "nonimmediate_operand" "%0")
7188 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7189 (match_dup 1)))
7190 (set (match_operand:DI 0 "register_operand" "=r")
7191 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7192 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7193 "add{l}\t{%2, %k0|%k0, %2}"
7194 [(set_attr "type" "alu")
7195 (set_attr "mode" "SI")])
7196
7197 (define_insn "*add<mode>3_cconly_overflow_2"
7198 [(set (reg:CCC FLAGS_REG)
7199 (compare:CCC
7200 (plus:SWI
7201 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7202 (match_operand:SWI 2 "<general_operand>" "<g>"))
7203 (match_dup 2)))
7204 (clobber (match_scratch:SWI 0 "=<r>"))]
7205 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7206 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7207 [(set_attr "type" "alu")
7208 (set_attr "mode" "<MODE>")])
7209
7210 (define_insn "*add<mode>3_cc_overflow_2"
7211 [(set (reg:CCC FLAGS_REG)
7212 (compare:CCC
7213 (plus:SWI
7214 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7215 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7216 (match_dup 2)))
7217 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7218 (plus:SWI (match_dup 1) (match_dup 2)))]
7219 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7220 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7221 [(set_attr "type" "alu")
7222 (set_attr "mode" "<MODE>")])
7223
7224 (define_insn "*addsi3_zext_cc_overflow_2"
7225 [(set (reg:CCC FLAGS_REG)
7226 (compare:CCC
7227 (plus:SI
7228 (match_operand:SI 1 "nonimmediate_operand" "%0")
7229 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7230 (match_dup 2)))
7231 (set (match_operand:DI 0 "register_operand" "=r")
7232 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7233 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7234 "add{l}\t{%2, %k0|%k0, %2}"
7235 [(set_attr "type" "alu")
7236 (set_attr "mode" "SI")])
7237
7238 ;; The patterns that match these are at the end of this file.
7239
7240 (define_expand "<plusminus_insn>xf3"
7241 [(set (match_operand:XF 0 "register_operand")
7242 (plusminus:XF
7243 (match_operand:XF 1 "register_operand")
7244 (match_operand:XF 2 "register_operand")))]
7245 "TARGET_80387")
7246
7247 (define_expand "<plusminus_insn><mode>3"
7248 [(set (match_operand:MODEF 0 "register_operand")
7249 (plusminus:MODEF
7250 (match_operand:MODEF 1 "register_operand")
7251 (match_operand:MODEF 2 "nonimmediate_operand")))]
7252 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7253 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7254 \f
7255 ;; Multiply instructions
7256
7257 (define_expand "mul<mode>3"
7258 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7259 (mult:SWIM248
7260 (match_operand:SWIM248 1 "register_operand")
7261 (match_operand:SWIM248 2 "<general_operand>")))
7262 (clobber (reg:CC FLAGS_REG))])])
7263
7264 (define_expand "mulqi3"
7265 [(parallel [(set (match_operand:QI 0 "register_operand")
7266 (mult:QI
7267 (match_operand:QI 1 "register_operand")
7268 (match_operand:QI 2 "nonimmediate_operand")))
7269 (clobber (reg:CC FLAGS_REG))])]
7270 "TARGET_QIMODE_MATH")
7271
7272 ;; On AMDFAM10
7273 ;; IMUL reg32/64, reg32/64, imm8 Direct
7274 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7275 ;; IMUL reg32/64, reg32/64, imm32 Direct
7276 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7277 ;; IMUL reg32/64, reg32/64 Direct
7278 ;; IMUL reg32/64, mem32/64 Direct
7279 ;;
7280 ;; On BDVER1, all above IMULs use DirectPath
7281 ;;
7282 ;; On AMDFAM10
7283 ;; IMUL reg16, reg16, imm8 VectorPath
7284 ;; IMUL reg16, mem16, imm8 VectorPath
7285 ;; IMUL reg16, reg16, imm16 VectorPath
7286 ;; IMUL reg16, mem16, imm16 VectorPath
7287 ;; IMUL reg16, reg16 Direct
7288 ;; IMUL reg16, mem16 Direct
7289 ;;
7290 ;; On BDVER1, all HI MULs use DoublePath
7291
7292 (define_insn "*mul<mode>3_1"
7293 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7294 (mult:SWIM248
7295 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7296 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7297 (clobber (reg:CC FLAGS_REG))]
7298 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7299 "@
7300 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7301 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7302 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7303 [(set_attr "type" "imul")
7304 (set_attr "prefix_0f" "0,0,1")
7305 (set (attr "athlon_decode")
7306 (cond [(eq_attr "cpu" "athlon")
7307 (const_string "vector")
7308 (eq_attr "alternative" "1")
7309 (const_string "vector")
7310 (and (eq_attr "alternative" "2")
7311 (ior (match_test "<MODE>mode == HImode")
7312 (match_operand 1 "memory_operand")))
7313 (const_string "vector")]
7314 (const_string "direct")))
7315 (set (attr "amdfam10_decode")
7316 (cond [(and (eq_attr "alternative" "0,1")
7317 (ior (match_test "<MODE>mode == HImode")
7318 (match_operand 1 "memory_operand")))
7319 (const_string "vector")]
7320 (const_string "direct")))
7321 (set (attr "bdver1_decode")
7322 (if_then_else
7323 (match_test "<MODE>mode == HImode")
7324 (const_string "double")
7325 (const_string "direct")))
7326 (set_attr "mode" "<MODE>")])
7327
7328 (define_insn "*mulsi3_1_zext"
7329 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7330 (zero_extend:DI
7331 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7332 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7333 (clobber (reg:CC FLAGS_REG))]
7334 "TARGET_64BIT
7335 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7336 "@
7337 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7338 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7339 imul{l}\t{%2, %k0|%k0, %2}"
7340 [(set_attr "type" "imul")
7341 (set_attr "prefix_0f" "0,0,1")
7342 (set (attr "athlon_decode")
7343 (cond [(eq_attr "cpu" "athlon")
7344 (const_string "vector")
7345 (eq_attr "alternative" "1")
7346 (const_string "vector")
7347 (and (eq_attr "alternative" "2")
7348 (match_operand 1 "memory_operand"))
7349 (const_string "vector")]
7350 (const_string "direct")))
7351 (set (attr "amdfam10_decode")
7352 (cond [(and (eq_attr "alternative" "0,1")
7353 (match_operand 1 "memory_operand"))
7354 (const_string "vector")]
7355 (const_string "direct")))
7356 (set_attr "bdver1_decode" "direct")
7357 (set_attr "mode" "SI")])
7358
7359 ;;On AMDFAM10 and BDVER1
7360 ;; MUL reg8 Direct
7361 ;; MUL mem8 Direct
7362
7363 (define_insn "*mulqi3_1"
7364 [(set (match_operand:QI 0 "register_operand" "=a")
7365 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7366 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7367 (clobber (reg:CC FLAGS_REG))]
7368 "TARGET_QIMODE_MATH
7369 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7370 "mul{b}\t%2"
7371 [(set_attr "type" "imul")
7372 (set_attr "length_immediate" "0")
7373 (set (attr "athlon_decode")
7374 (if_then_else (eq_attr "cpu" "athlon")
7375 (const_string "vector")
7376 (const_string "direct")))
7377 (set_attr "amdfam10_decode" "direct")
7378 (set_attr "bdver1_decode" "direct")
7379 (set_attr "mode" "QI")])
7380
7381 ;; Multiply with jump on overflow.
7382 (define_expand "mulv<mode>4"
7383 [(parallel [(set (reg:CCO FLAGS_REG)
7384 (eq:CCO (mult:<DWI>
7385 (sign_extend:<DWI>
7386 (match_operand:SWI248 1 "register_operand"))
7387 (match_dup 4))
7388 (sign_extend:<DWI>
7389 (mult:SWI248 (match_dup 1)
7390 (match_operand:SWI248 2
7391 "<general_operand>")))))
7392 (set (match_operand:SWI248 0 "register_operand")
7393 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7394 (set (pc) (if_then_else
7395 (eq (reg:CCO FLAGS_REG) (const_int 0))
7396 (label_ref (match_operand 3))
7397 (pc)))]
7398 ""
7399 {
7400 if (CONST_INT_P (operands[2]))
7401 operands[4] = operands[2];
7402 else
7403 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7404 })
7405
7406 (define_insn "*mulv<mode>4"
7407 [(set (reg:CCO FLAGS_REG)
7408 (eq:CCO (mult:<DWI>
7409 (sign_extend:<DWI>
7410 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7411 (sign_extend:<DWI>
7412 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7413 (sign_extend:<DWI>
7414 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7415 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7416 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7417 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7418 "@
7419 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7420 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7421 [(set_attr "type" "imul")
7422 (set_attr "prefix_0f" "0,1")
7423 (set (attr "athlon_decode")
7424 (cond [(eq_attr "cpu" "athlon")
7425 (const_string "vector")
7426 (eq_attr "alternative" "0")
7427 (const_string "vector")
7428 (and (eq_attr "alternative" "1")
7429 (match_operand 1 "memory_operand"))
7430 (const_string "vector")]
7431 (const_string "direct")))
7432 (set (attr "amdfam10_decode")
7433 (cond [(and (eq_attr "alternative" "1")
7434 (match_operand 1 "memory_operand"))
7435 (const_string "vector")]
7436 (const_string "direct")))
7437 (set_attr "bdver1_decode" "direct")
7438 (set_attr "mode" "<MODE>")])
7439
7440 (define_insn "*mulvhi4"
7441 [(set (reg:CCO FLAGS_REG)
7442 (eq:CCO (mult:SI
7443 (sign_extend:SI
7444 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7445 (sign_extend:SI
7446 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7447 (sign_extend:SI
7448 (mult:HI (match_dup 1) (match_dup 2)))))
7449 (set (match_operand:HI 0 "register_operand" "=r")
7450 (mult:HI (match_dup 1) (match_dup 2)))]
7451 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7452 "imul{w}\t{%2, %0|%0, %2}"
7453 [(set_attr "type" "imul")
7454 (set_attr "prefix_0f" "1")
7455 (set_attr "athlon_decode" "vector")
7456 (set_attr "amdfam10_decode" "direct")
7457 (set_attr "bdver1_decode" "double")
7458 (set_attr "mode" "HI")])
7459
7460 (define_insn "*mulv<mode>4_1"
7461 [(set (reg:CCO FLAGS_REG)
7462 (eq:CCO (mult:<DWI>
7463 (sign_extend:<DWI>
7464 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7465 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7466 (sign_extend:<DWI>
7467 (mult:SWI248 (match_dup 1)
7468 (match_operand:SWI248 2
7469 "<immediate_operand>" "K,<i>")))))
7470 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7471 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7472 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7473 && CONST_INT_P (operands[2])
7474 && INTVAL (operands[2]) == INTVAL (operands[3])"
7475 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7476 [(set_attr "type" "imul")
7477 (set (attr "prefix_0f")
7478 (if_then_else
7479 (match_test "<MODE>mode == HImode")
7480 (const_string "0")
7481 (const_string "*")))
7482 (set (attr "athlon_decode")
7483 (cond [(eq_attr "cpu" "athlon")
7484 (const_string "vector")
7485 (eq_attr "alternative" "1")
7486 (const_string "vector")]
7487 (const_string "direct")))
7488 (set (attr "amdfam10_decode")
7489 (cond [(ior (match_test "<MODE>mode == HImode")
7490 (match_operand 1 "memory_operand"))
7491 (const_string "vector")]
7492 (const_string "direct")))
7493 (set (attr "bdver1_decode")
7494 (if_then_else
7495 (match_test "<MODE>mode == HImode")
7496 (const_string "double")
7497 (const_string "direct")))
7498 (set_attr "mode" "<MODE>")
7499 (set (attr "length_immediate")
7500 (cond [(eq_attr "alternative" "0")
7501 (const_string "1")
7502 (match_test "<MODE_SIZE> == 8")
7503 (const_string "4")]
7504 (const_string "<MODE_SIZE>")))])
7505
7506 (define_expand "umulv<mode>4"
7507 [(parallel [(set (reg:CCO FLAGS_REG)
7508 (eq:CCO (mult:<DWI>
7509 (zero_extend:<DWI>
7510 (match_operand:SWI248 1
7511 "nonimmediate_operand"))
7512 (zero_extend:<DWI>
7513 (match_operand:SWI248 2
7514 "nonimmediate_operand")))
7515 (zero_extend:<DWI>
7516 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7517 (set (match_operand:SWI248 0 "register_operand")
7518 (mult:SWI248 (match_dup 1) (match_dup 2)))
7519 (clobber (match_scratch:SWI248 4))])
7520 (set (pc) (if_then_else
7521 (eq (reg:CCO FLAGS_REG) (const_int 0))
7522 (label_ref (match_operand 3))
7523 (pc)))]
7524 ""
7525 {
7526 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7527 operands[1] = force_reg (<MODE>mode, operands[1]);
7528 })
7529
7530 (define_insn "*umulv<mode>4"
7531 [(set (reg:CCO FLAGS_REG)
7532 (eq:CCO (mult:<DWI>
7533 (zero_extend:<DWI>
7534 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7535 (zero_extend:<DWI>
7536 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7537 (zero_extend:<DWI>
7538 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7539 (set (match_operand:SWI248 0 "register_operand" "=a")
7540 (mult:SWI248 (match_dup 1) (match_dup 2)))
7541 (clobber (match_scratch:SWI248 3 "=d"))]
7542 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7543 "mul{<imodesuffix>}\t%2"
7544 [(set_attr "type" "imul")
7545 (set_attr "length_immediate" "0")
7546 (set (attr "athlon_decode")
7547 (if_then_else (eq_attr "cpu" "athlon")
7548 (const_string "vector")
7549 (const_string "double")))
7550 (set_attr "amdfam10_decode" "double")
7551 (set_attr "bdver1_decode" "direct")
7552 (set_attr "mode" "<MODE>")])
7553
7554 (define_expand "<u>mulvqi4"
7555 [(parallel [(set (reg:CCO FLAGS_REG)
7556 (eq:CCO (mult:HI
7557 (any_extend:HI
7558 (match_operand:QI 1 "nonimmediate_operand"))
7559 (any_extend:HI
7560 (match_operand:QI 2 "nonimmediate_operand")))
7561 (any_extend:HI
7562 (mult:QI (match_dup 1) (match_dup 2)))))
7563 (set (match_operand:QI 0 "register_operand")
7564 (mult:QI (match_dup 1) (match_dup 2)))])
7565 (set (pc) (if_then_else
7566 (eq (reg:CCO FLAGS_REG) (const_int 0))
7567 (label_ref (match_operand 3))
7568 (pc)))]
7569 "TARGET_QIMODE_MATH"
7570 {
7571 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7572 operands[1] = force_reg (QImode, operands[1]);
7573 })
7574
7575 (define_insn "*<u>mulvqi4"
7576 [(set (reg:CCO FLAGS_REG)
7577 (eq:CCO (mult:HI
7578 (any_extend:HI
7579 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7580 (any_extend:HI
7581 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7582 (any_extend:HI
7583 (mult:QI (match_dup 1) (match_dup 2)))))
7584 (set (match_operand:QI 0 "register_operand" "=a")
7585 (mult:QI (match_dup 1) (match_dup 2)))]
7586 "TARGET_QIMODE_MATH
7587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7588 "<sgnprefix>mul{b}\t%2"
7589 [(set_attr "type" "imul")
7590 (set_attr "length_immediate" "0")
7591 (set (attr "athlon_decode")
7592 (if_then_else (eq_attr "cpu" "athlon")
7593 (const_string "vector")
7594 (const_string "direct")))
7595 (set_attr "amdfam10_decode" "direct")
7596 (set_attr "bdver1_decode" "direct")
7597 (set_attr "mode" "QI")])
7598
7599 (define_expand "<u>mul<mode><dwi>3"
7600 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7601 (mult:<DWI>
7602 (any_extend:<DWI>
7603 (match_operand:DWIH 1 "nonimmediate_operand"))
7604 (any_extend:<DWI>
7605 (match_operand:DWIH 2 "register_operand"))))
7606 (clobber (reg:CC FLAGS_REG))])])
7607
7608 (define_expand "<u>mulqihi3"
7609 [(parallel [(set (match_operand:HI 0 "register_operand")
7610 (mult:HI
7611 (any_extend:HI
7612 (match_operand:QI 1 "nonimmediate_operand"))
7613 (any_extend:HI
7614 (match_operand:QI 2 "register_operand"))))
7615 (clobber (reg:CC FLAGS_REG))])]
7616 "TARGET_QIMODE_MATH")
7617
7618 (define_insn "*bmi2_umul<mode><dwi>3_1"
7619 [(set (match_operand:DWIH 0 "register_operand" "=r")
7620 (mult:DWIH
7621 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7622 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7623 (set (match_operand:DWIH 1 "register_operand" "=r")
7624 (truncate:DWIH
7625 (lshiftrt:<DWI>
7626 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7627 (zero_extend:<DWI> (match_dup 3)))
7628 (match_operand:QI 4 "const_int_operand" "n"))))]
7629 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7631 "mulx\t{%3, %0, %1|%1, %0, %3}"
7632 [(set_attr "type" "imulx")
7633 (set_attr "prefix" "vex")
7634 (set_attr "mode" "<MODE>")])
7635
7636 (define_insn "*umul<mode><dwi>3_1"
7637 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7638 (mult:<DWI>
7639 (zero_extend:<DWI>
7640 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7641 (zero_extend:<DWI>
7642 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7643 (clobber (reg:CC FLAGS_REG))]
7644 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7645 "@
7646 #
7647 mul{<imodesuffix>}\t%2"
7648 [(set_attr "isa" "bmi2,*")
7649 (set_attr "type" "imulx,imul")
7650 (set_attr "length_immediate" "*,0")
7651 (set (attr "athlon_decode")
7652 (cond [(eq_attr "alternative" "1")
7653 (if_then_else (eq_attr "cpu" "athlon")
7654 (const_string "vector")
7655 (const_string "double"))]
7656 (const_string "*")))
7657 (set_attr "amdfam10_decode" "*,double")
7658 (set_attr "bdver1_decode" "*,direct")
7659 (set_attr "prefix" "vex,orig")
7660 (set_attr "mode" "<MODE>")])
7661
7662 ;; Convert mul to the mulx pattern to avoid flags dependency.
7663 (define_split
7664 [(set (match_operand:<DWI> 0 "register_operand")
7665 (mult:<DWI>
7666 (zero_extend:<DWI>
7667 (match_operand:DWIH 1 "register_operand"))
7668 (zero_extend:<DWI>
7669 (match_operand:DWIH 2 "nonimmediate_operand"))))
7670 (clobber (reg:CC FLAGS_REG))]
7671 "TARGET_BMI2 && reload_completed
7672 && REGNO (operands[1]) == DX_REG"
7673 [(parallel [(set (match_dup 3)
7674 (mult:DWIH (match_dup 1) (match_dup 2)))
7675 (set (match_dup 4)
7676 (truncate:DWIH
7677 (lshiftrt:<DWI>
7678 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7679 (zero_extend:<DWI> (match_dup 2)))
7680 (match_dup 5))))])]
7681 {
7682 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7683
7684 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7685 })
7686
7687 (define_insn "*mul<mode><dwi>3_1"
7688 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7689 (mult:<DWI>
7690 (sign_extend:<DWI>
7691 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7692 (sign_extend:<DWI>
7693 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7694 (clobber (reg:CC FLAGS_REG))]
7695 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7696 "imul{<imodesuffix>}\t%2"
7697 [(set_attr "type" "imul")
7698 (set_attr "length_immediate" "0")
7699 (set (attr "athlon_decode")
7700 (if_then_else (eq_attr "cpu" "athlon")
7701 (const_string "vector")
7702 (const_string "double")))
7703 (set_attr "amdfam10_decode" "double")
7704 (set_attr "bdver1_decode" "direct")
7705 (set_attr "mode" "<MODE>")])
7706
7707 (define_insn "*<u>mulqihi3_1"
7708 [(set (match_operand:HI 0 "register_operand" "=a")
7709 (mult:HI
7710 (any_extend:HI
7711 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7712 (any_extend:HI
7713 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7714 (clobber (reg:CC FLAGS_REG))]
7715 "TARGET_QIMODE_MATH
7716 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7717 "<sgnprefix>mul{b}\t%2"
7718 [(set_attr "type" "imul")
7719 (set_attr "length_immediate" "0")
7720 (set (attr "athlon_decode")
7721 (if_then_else (eq_attr "cpu" "athlon")
7722 (const_string "vector")
7723 (const_string "direct")))
7724 (set_attr "amdfam10_decode" "direct")
7725 (set_attr "bdver1_decode" "direct")
7726 (set_attr "mode" "QI")])
7727
7728 (define_expand "<s>mul<mode>3_highpart"
7729 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7730 (truncate:SWI48
7731 (lshiftrt:<DWI>
7732 (mult:<DWI>
7733 (any_extend:<DWI>
7734 (match_operand:SWI48 1 "nonimmediate_operand"))
7735 (any_extend:<DWI>
7736 (match_operand:SWI48 2 "register_operand")))
7737 (match_dup 3))))
7738 (clobber (match_scratch:SWI48 4))
7739 (clobber (reg:CC FLAGS_REG))])]
7740 ""
7741 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7742
7743 (define_insn "*<s>muldi3_highpart_1"
7744 [(set (match_operand:DI 0 "register_operand" "=d")
7745 (truncate:DI
7746 (lshiftrt:TI
7747 (mult:TI
7748 (any_extend:TI
7749 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7750 (any_extend:TI
7751 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7752 (const_int 64))))
7753 (clobber (match_scratch:DI 3 "=1"))
7754 (clobber (reg:CC FLAGS_REG))]
7755 "TARGET_64BIT
7756 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7757 "<sgnprefix>mul{q}\t%2"
7758 [(set_attr "type" "imul")
7759 (set_attr "length_immediate" "0")
7760 (set (attr "athlon_decode")
7761 (if_then_else (eq_attr "cpu" "athlon")
7762 (const_string "vector")
7763 (const_string "double")))
7764 (set_attr "amdfam10_decode" "double")
7765 (set_attr "bdver1_decode" "direct")
7766 (set_attr "mode" "DI")])
7767
7768 (define_insn "*<s>mulsi3_highpart_zext"
7769 [(set (match_operand:DI 0 "register_operand" "=d")
7770 (zero_extend:DI (truncate:SI
7771 (lshiftrt:DI
7772 (mult:DI (any_extend:DI
7773 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7774 (any_extend:DI
7775 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7776 (const_int 32)))))
7777 (clobber (match_scratch:SI 3 "=1"))
7778 (clobber (reg:CC FLAGS_REG))]
7779 "TARGET_64BIT
7780 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7781 "<sgnprefix>mul{l}\t%2"
7782 [(set_attr "type" "imul")
7783 (set_attr "length_immediate" "0")
7784 (set (attr "athlon_decode")
7785 (if_then_else (eq_attr "cpu" "athlon")
7786 (const_string "vector")
7787 (const_string "double")))
7788 (set_attr "amdfam10_decode" "double")
7789 (set_attr "bdver1_decode" "direct")
7790 (set_attr "mode" "SI")])
7791
7792 (define_insn "*<s>mulsi3_highpart_1"
7793 [(set (match_operand:SI 0 "register_operand" "=d")
7794 (truncate:SI
7795 (lshiftrt:DI
7796 (mult:DI
7797 (any_extend:DI
7798 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7799 (any_extend:DI
7800 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7801 (const_int 32))))
7802 (clobber (match_scratch:SI 3 "=1"))
7803 (clobber (reg:CC FLAGS_REG))]
7804 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7805 "<sgnprefix>mul{l}\t%2"
7806 [(set_attr "type" "imul")
7807 (set_attr "length_immediate" "0")
7808 (set (attr "athlon_decode")
7809 (if_then_else (eq_attr "cpu" "athlon")
7810 (const_string "vector")
7811 (const_string "double")))
7812 (set_attr "amdfam10_decode" "double")
7813 (set_attr "bdver1_decode" "direct")
7814 (set_attr "mode" "SI")])
7815
7816 ;; The patterns that match these are at the end of this file.
7817
7818 (define_expand "mulxf3"
7819 [(set (match_operand:XF 0 "register_operand")
7820 (mult:XF (match_operand:XF 1 "register_operand")
7821 (match_operand:XF 2 "register_operand")))]
7822 "TARGET_80387")
7823
7824 (define_expand "mul<mode>3"
7825 [(set (match_operand:MODEF 0 "register_operand")
7826 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7827 (match_operand:MODEF 2 "nonimmediate_operand")))]
7828 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7829 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7830 \f
7831 ;; Divide instructions
7832
7833 ;; The patterns that match these are at the end of this file.
7834
7835 (define_expand "divxf3"
7836 [(set (match_operand:XF 0 "register_operand")
7837 (div:XF (match_operand:XF 1 "register_operand")
7838 (match_operand:XF 2 "register_operand")))]
7839 "TARGET_80387")
7840
7841 (define_expand "div<mode>3"
7842 [(set (match_operand:MODEF 0 "register_operand")
7843 (div:MODEF (match_operand:MODEF 1 "register_operand")
7844 (match_operand:MODEF 2 "nonimmediate_operand")))]
7845 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7846 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7847 {
7848 if (<MODE>mode == SFmode
7849 && TARGET_SSE && TARGET_SSE_MATH
7850 && TARGET_RECIP_DIV
7851 && optimize_insn_for_speed_p ()
7852 && flag_finite_math_only && !flag_trapping_math
7853 && flag_unsafe_math_optimizations)
7854 {
7855 ix86_emit_swdivsf (operands[0], operands[1],
7856 operands[2], SFmode);
7857 DONE;
7858 }
7859 })
7860 \f
7861 ;; Divmod instructions.
7862
7863 (define_expand "divmod<mode>4"
7864 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7865 (div:SWIM248
7866 (match_operand:SWIM248 1 "register_operand")
7867 (match_operand:SWIM248 2 "nonimmediate_operand")))
7868 (set (match_operand:SWIM248 3 "register_operand")
7869 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7870 (clobber (reg:CC FLAGS_REG))])])
7871
7872 ;; Split with 8bit unsigned divide:
7873 ;; if (dividend an divisor are in [0-255])
7874 ;; use 8bit unsigned integer divide
7875 ;; else
7876 ;; use original integer divide
7877 (define_split
7878 [(set (match_operand:SWI48 0 "register_operand")
7879 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7880 (match_operand:SWI48 3 "nonimmediate_operand")))
7881 (set (match_operand:SWI48 1 "register_operand")
7882 (mod:SWI48 (match_dup 2) (match_dup 3)))
7883 (clobber (reg:CC FLAGS_REG))]
7884 "TARGET_USE_8BIT_IDIV
7885 && TARGET_QIMODE_MATH
7886 && can_create_pseudo_p ()
7887 && !optimize_insn_for_size_p ()"
7888 [(const_int 0)]
7889 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7890
7891 (define_split
7892 [(set (match_operand:DI 0 "register_operand")
7893 (zero_extend:DI
7894 (div:SI (match_operand:SI 2 "register_operand")
7895 (match_operand:SI 3 "nonimmediate_operand"))))
7896 (set (match_operand:SI 1 "register_operand")
7897 (mod:SI (match_dup 2) (match_dup 3)))
7898 (clobber (reg:CC FLAGS_REG))]
7899 "TARGET_USE_8BIT_IDIV
7900 && TARGET_QIMODE_MATH
7901 && can_create_pseudo_p ()
7902 && !optimize_insn_for_size_p ()"
7903 [(const_int 0)]
7904 "ix86_split_idivmod (SImode, operands, true); DONE;")
7905
7906 (define_split
7907 [(set (match_operand:DI 1 "register_operand")
7908 (zero_extend:DI
7909 (mod:SI (match_operand:SI 2 "register_operand")
7910 (match_operand:SI 3 "nonimmediate_operand"))))
7911 (set (match_operand:SI 0 "register_operand")
7912 (div:SI (match_dup 2) (match_dup 3)))
7913 (clobber (reg:CC FLAGS_REG))]
7914 "TARGET_USE_8BIT_IDIV
7915 && TARGET_QIMODE_MATH
7916 && can_create_pseudo_p ()
7917 && !optimize_insn_for_size_p ()"
7918 [(const_int 0)]
7919 "ix86_split_idivmod (SImode, operands, true); DONE;")
7920
7921 (define_insn_and_split "divmod<mode>4_1"
7922 [(set (match_operand:SWI48 0 "register_operand" "=a")
7923 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7924 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7925 (set (match_operand:SWI48 1 "register_operand" "=&d")
7926 (mod:SWI48 (match_dup 2) (match_dup 3)))
7927 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7928 (clobber (reg:CC FLAGS_REG))]
7929 ""
7930 "#"
7931 "reload_completed"
7932 [(parallel [(set (match_dup 1)
7933 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7934 (clobber (reg:CC FLAGS_REG))])
7935 (parallel [(set (match_dup 0)
7936 (div:SWI48 (match_dup 2) (match_dup 3)))
7937 (set (match_dup 1)
7938 (mod:SWI48 (match_dup 2) (match_dup 3)))
7939 (use (match_dup 1))
7940 (clobber (reg:CC FLAGS_REG))])]
7941 {
7942 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7943
7944 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7945 operands[4] = operands[2];
7946 else
7947 {
7948 /* Avoid use of cltd in favor of a mov+shift. */
7949 emit_move_insn (operands[1], operands[2]);
7950 operands[4] = operands[1];
7951 }
7952 }
7953 [(set_attr "type" "multi")
7954 (set_attr "mode" "<MODE>")])
7955
7956 (define_insn_and_split "divmodsi4_zext_1"
7957 [(set (match_operand:DI 0 "register_operand" "=a")
7958 (zero_extend:DI
7959 (div:SI (match_operand:SI 2 "register_operand" "0")
7960 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7961 (set (match_operand:SI 1 "register_operand" "=&d")
7962 (mod:SI (match_dup 2) (match_dup 3)))
7963 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7964 (clobber (reg:CC FLAGS_REG))]
7965 "TARGET_64BIT"
7966 "#"
7967 "reload_completed"
7968 [(parallel [(set (match_dup 1)
7969 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7970 (clobber (reg:CC FLAGS_REG))])
7971 (parallel [(set (match_dup 0)
7972 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7973 (set (match_dup 1)
7974 (mod:SI (match_dup 2) (match_dup 3)))
7975 (use (match_dup 1))
7976 (clobber (reg:CC FLAGS_REG))])]
7977 {
7978 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7979
7980 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7981 operands[4] = operands[2];
7982 else
7983 {
7984 /* Avoid use of cltd in favor of a mov+shift. */
7985 emit_move_insn (operands[1], operands[2]);
7986 operands[4] = operands[1];
7987 }
7988 }
7989 [(set_attr "type" "multi")
7990 (set_attr "mode" "SI")])
7991
7992 (define_insn_and_split "divmodsi4_zext_2"
7993 [(set (match_operand:DI 1 "register_operand" "=&d")
7994 (zero_extend:DI
7995 (mod:SI (match_operand:SI 2 "register_operand" "0")
7996 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7997 (set (match_operand:SI 0 "register_operand" "=a")
7998 (div:SI (match_dup 2) (match_dup 3)))
7999 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8000 (clobber (reg:CC FLAGS_REG))]
8001 "TARGET_64BIT"
8002 "#"
8003 "reload_completed"
8004 [(parallel [(set (match_dup 6)
8005 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8006 (clobber (reg:CC FLAGS_REG))])
8007 (parallel [(set (match_dup 1)
8008 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8009 (set (match_dup 0)
8010 (div:SI (match_dup 2) (match_dup 3)))
8011 (use (match_dup 6))
8012 (clobber (reg:CC FLAGS_REG))])]
8013 {
8014 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8015 operands[6] = gen_lowpart (SImode, operands[1]);
8016
8017 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8018 operands[4] = operands[2];
8019 else
8020 {
8021 /* Avoid use of cltd in favor of a mov+shift. */
8022 emit_move_insn (operands[6], operands[2]);
8023 operands[4] = operands[6];
8024 }
8025 }
8026 [(set_attr "type" "multi")
8027 (set_attr "mode" "SI")])
8028
8029 (define_insn_and_split "*divmod<mode>4"
8030 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8031 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8032 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8033 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8034 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8035 (clobber (reg:CC FLAGS_REG))]
8036 ""
8037 "#"
8038 "reload_completed"
8039 [(parallel [(set (match_dup 1)
8040 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8041 (clobber (reg:CC FLAGS_REG))])
8042 (parallel [(set (match_dup 0)
8043 (div:SWIM248 (match_dup 2) (match_dup 3)))
8044 (set (match_dup 1)
8045 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8046 (use (match_dup 1))
8047 (clobber (reg:CC FLAGS_REG))])]
8048 {
8049 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8050
8051 if (<MODE>mode != HImode
8052 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8053 operands[4] = operands[2];
8054 else
8055 {
8056 /* Avoid use of cltd in favor of a mov+shift. */
8057 emit_move_insn (operands[1], operands[2]);
8058 operands[4] = operands[1];
8059 }
8060 }
8061 [(set_attr "type" "multi")
8062 (set_attr "mode" "<MODE>")])
8063
8064 (define_insn_and_split "*divmodsi4_zext_1"
8065 [(set (match_operand:DI 0 "register_operand" "=a")
8066 (zero_extend:DI
8067 (div:SI (match_operand:SI 2 "register_operand" "0")
8068 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8069 (set (match_operand:SI 1 "register_operand" "=&d")
8070 (mod:SI (match_dup 2) (match_dup 3)))
8071 (clobber (reg:CC FLAGS_REG))]
8072 "TARGET_64BIT"
8073 "#"
8074 "reload_completed"
8075 [(parallel [(set (match_dup 1)
8076 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8077 (clobber (reg:CC FLAGS_REG))])
8078 (parallel [(set (match_dup 0)
8079 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8080 (set (match_dup 1)
8081 (mod:SI (match_dup 2) (match_dup 3)))
8082 (use (match_dup 1))
8083 (clobber (reg:CC FLAGS_REG))])]
8084 {
8085 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8086
8087 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8088 operands[4] = operands[2];
8089 else
8090 {
8091 /* Avoid use of cltd in favor of a mov+shift. */
8092 emit_move_insn (operands[1], operands[2]);
8093 operands[4] = operands[1];
8094 }
8095 }
8096 [(set_attr "type" "multi")
8097 (set_attr "mode" "SI")])
8098
8099 (define_insn_and_split "*divmodsi4_zext_2"
8100 [(set (match_operand:DI 1 "register_operand" "=&d")
8101 (zero_extend:DI
8102 (mod:SI (match_operand:SI 2 "register_operand" "0")
8103 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8104 (set (match_operand:SI 0 "register_operand" "=a")
8105 (div:SI (match_dup 2) (match_dup 3)))
8106 (clobber (reg:CC FLAGS_REG))]
8107 "TARGET_64BIT"
8108 "#"
8109 "reload_completed"
8110 [(parallel [(set (match_dup 6)
8111 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8112 (clobber (reg:CC FLAGS_REG))])
8113 (parallel [(set (match_dup 1)
8114 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8115 (set (match_dup 0)
8116 (div:SI (match_dup 2) (match_dup 3)))
8117 (use (match_dup 6))
8118 (clobber (reg:CC FLAGS_REG))])]
8119 {
8120 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8121 operands[6] = gen_lowpart (SImode, operands[1]);
8122
8123 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8124 operands[4] = operands[2];
8125 else
8126 {
8127 /* Avoid use of cltd in favor of a mov+shift. */
8128 emit_move_insn (operands[6], operands[2]);
8129 operands[4] = operands[6];
8130 }
8131 }
8132 [(set_attr "type" "multi")
8133 (set_attr "mode" "SI")])
8134
8135 (define_insn "*divmod<mode>4_noext"
8136 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8137 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8138 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8139 (set (match_operand:SWIM248 1 "register_operand" "=d")
8140 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8141 (use (match_operand:SWIM248 4 "register_operand" "1"))
8142 (clobber (reg:CC FLAGS_REG))]
8143 ""
8144 "idiv{<imodesuffix>}\t%3"
8145 [(set_attr "type" "idiv")
8146 (set_attr "mode" "<MODE>")])
8147
8148 (define_insn "*divmodsi4_noext_zext_1"
8149 [(set (match_operand:DI 0 "register_operand" "=a")
8150 (zero_extend:DI
8151 (div:SI (match_operand:SI 2 "register_operand" "0")
8152 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8153 (set (match_operand:SI 1 "register_operand" "=d")
8154 (mod:SI (match_dup 2) (match_dup 3)))
8155 (use (match_operand:SI 4 "register_operand" "1"))
8156 (clobber (reg:CC FLAGS_REG))]
8157 "TARGET_64BIT"
8158 "idiv{l}\t%3"
8159 [(set_attr "type" "idiv")
8160 (set_attr "mode" "SI")])
8161
8162 (define_insn "*divmodsi4_noext_zext_2"
8163 [(set (match_operand:DI 1 "register_operand" "=d")
8164 (zero_extend:DI
8165 (mod:SI (match_operand:SI 2 "register_operand" "0")
8166 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8167 (set (match_operand:SI 0 "register_operand" "=a")
8168 (div:SI (match_dup 2) (match_dup 3)))
8169 (use (match_operand:SI 4 "register_operand" "1"))
8170 (clobber (reg:CC FLAGS_REG))]
8171 "TARGET_64BIT"
8172 "idiv{l}\t%3"
8173 [(set_attr "type" "idiv")
8174 (set_attr "mode" "SI")])
8175
8176 (define_expand "divmodqi4"
8177 [(parallel [(set (match_operand:QI 0 "register_operand")
8178 (div:QI
8179 (match_operand:QI 1 "register_operand")
8180 (match_operand:QI 2 "nonimmediate_operand")))
8181 (set (match_operand:QI 3 "register_operand")
8182 (mod:QI (match_dup 1) (match_dup 2)))
8183 (clobber (reg:CC FLAGS_REG))])]
8184 "TARGET_QIMODE_MATH"
8185 {
8186 rtx div, mod;
8187 rtx tmp0, tmp1;
8188
8189 tmp0 = gen_reg_rtx (HImode);
8190 tmp1 = gen_reg_rtx (HImode);
8191
8192 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8193 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8194 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8195
8196 /* Extract remainder from AH. */
8197 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8198 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8199 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8200
8201 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8202 set_unique_reg_note (insn, REG_EQUAL, mod);
8203
8204 /* Extract quotient from AL. */
8205 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8206
8207 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8208 set_unique_reg_note (insn, REG_EQUAL, div);
8209
8210 DONE;
8211 })
8212
8213 ;; Divide AX by r/m8, with result stored in
8214 ;; AL <- Quotient
8215 ;; AH <- Remainder
8216 ;; Change div/mod to HImode and extend the second argument to HImode
8217 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8218 ;; combine may fail.
8219 (define_insn "divmodhiqi3"
8220 [(set (match_operand:HI 0 "register_operand" "=a")
8221 (ior:HI
8222 (ashift:HI
8223 (zero_extend:HI
8224 (truncate:QI
8225 (mod:HI (match_operand:HI 1 "register_operand" "0")
8226 (sign_extend:HI
8227 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8228 (const_int 8))
8229 (zero_extend:HI
8230 (truncate:QI
8231 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8232 (clobber (reg:CC FLAGS_REG))]
8233 "TARGET_QIMODE_MATH"
8234 "idiv{b}\t%2"
8235 [(set_attr "type" "idiv")
8236 (set_attr "mode" "QI")])
8237
8238 (define_expand "udivmod<mode>4"
8239 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8240 (udiv:SWIM248
8241 (match_operand:SWIM248 1 "register_operand")
8242 (match_operand:SWIM248 2 "nonimmediate_operand")))
8243 (set (match_operand:SWIM248 3 "register_operand")
8244 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8245 (clobber (reg:CC FLAGS_REG))])])
8246
8247 ;; Split with 8bit unsigned divide:
8248 ;; if (dividend an divisor are in [0-255])
8249 ;; use 8bit unsigned integer divide
8250 ;; else
8251 ;; use original integer divide
8252 (define_split
8253 [(set (match_operand:SWI48 0 "register_operand")
8254 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8255 (match_operand:SWI48 3 "nonimmediate_operand")))
8256 (set (match_operand:SWI48 1 "register_operand")
8257 (umod:SWI48 (match_dup 2) (match_dup 3)))
8258 (clobber (reg:CC FLAGS_REG))]
8259 "TARGET_USE_8BIT_IDIV
8260 && TARGET_QIMODE_MATH
8261 && can_create_pseudo_p ()
8262 && !optimize_insn_for_size_p ()"
8263 [(const_int 0)]
8264 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8265
8266 (define_split
8267 [(set (match_operand:DI 0 "register_operand")
8268 (zero_extend:DI
8269 (udiv:SI (match_operand:SI 2 "register_operand")
8270 (match_operand:SI 3 "nonimmediate_operand"))))
8271 (set (match_operand:SI 1 "register_operand")
8272 (umod:SI (match_dup 2) (match_dup 3)))
8273 (clobber (reg:CC FLAGS_REG))]
8274 "TARGET_64BIT
8275 && TARGET_USE_8BIT_IDIV
8276 && TARGET_QIMODE_MATH
8277 && can_create_pseudo_p ()
8278 && !optimize_insn_for_size_p ()"
8279 [(const_int 0)]
8280 "ix86_split_idivmod (SImode, operands, false); DONE;")
8281
8282 (define_split
8283 [(set (match_operand:DI 1 "register_operand")
8284 (zero_extend:DI
8285 (umod:SI (match_operand:SI 2 "register_operand")
8286 (match_operand:SI 3 "nonimmediate_operand"))))
8287 (set (match_operand:SI 0 "register_operand")
8288 (udiv:SI (match_dup 2) (match_dup 3)))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "TARGET_64BIT
8291 && TARGET_USE_8BIT_IDIV
8292 && TARGET_QIMODE_MATH
8293 && can_create_pseudo_p ()
8294 && !optimize_insn_for_size_p ()"
8295 [(const_int 0)]
8296 "ix86_split_idivmod (SImode, operands, false); DONE;")
8297
8298 (define_insn_and_split "udivmod<mode>4_1"
8299 [(set (match_operand:SWI48 0 "register_operand" "=a")
8300 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8301 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8302 (set (match_operand:SWI48 1 "register_operand" "=&d")
8303 (umod:SWI48 (match_dup 2) (match_dup 3)))
8304 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8305 (clobber (reg:CC FLAGS_REG))]
8306 ""
8307 "#"
8308 "reload_completed"
8309 [(set (match_dup 1) (const_int 0))
8310 (parallel [(set (match_dup 0)
8311 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8312 (set (match_dup 1)
8313 (umod:SWI48 (match_dup 2) (match_dup 3)))
8314 (use (match_dup 1))
8315 (clobber (reg:CC FLAGS_REG))])]
8316 ""
8317 [(set_attr "type" "multi")
8318 (set_attr "mode" "<MODE>")])
8319
8320 (define_insn_and_split "udivmodsi4_zext_1"
8321 [(set (match_operand:DI 0 "register_operand" "=a")
8322 (zero_extend:DI
8323 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8324 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8325 (set (match_operand:SI 1 "register_operand" "=&d")
8326 (umod:SI (match_dup 2) (match_dup 3)))
8327 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8328 (clobber (reg:CC FLAGS_REG))]
8329 "TARGET_64BIT"
8330 "#"
8331 "reload_completed"
8332 [(set (match_dup 1) (const_int 0))
8333 (parallel [(set (match_dup 0)
8334 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8335 (set (match_dup 1)
8336 (umod:SI (match_dup 2) (match_dup 3)))
8337 (use (match_dup 1))
8338 (clobber (reg:CC FLAGS_REG))])]
8339 ""
8340 [(set_attr "type" "multi")
8341 (set_attr "mode" "SI")])
8342
8343 (define_insn_and_split "udivmodsi4_zext_2"
8344 [(set (match_operand:DI 1 "register_operand" "=&d")
8345 (zero_extend:DI
8346 (umod:SI (match_operand:SI 2 "register_operand" "0")
8347 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8348 (set (match_operand:SI 0 "register_operand" "=a")
8349 (udiv:SI (match_dup 2) (match_dup 3)))
8350 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8351 (clobber (reg:CC FLAGS_REG))]
8352 "TARGET_64BIT"
8353 "#"
8354 "reload_completed"
8355 [(set (match_dup 4) (const_int 0))
8356 (parallel [(set (match_dup 1)
8357 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8358 (set (match_dup 0)
8359 (udiv:SI (match_dup 2) (match_dup 3)))
8360 (use (match_dup 4))
8361 (clobber (reg:CC FLAGS_REG))])]
8362 "operands[4] = gen_lowpart (SImode, operands[1]);"
8363 [(set_attr "type" "multi")
8364 (set_attr "mode" "SI")])
8365
8366 (define_insn_and_split "*udivmod<mode>4"
8367 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8368 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8369 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8370 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8371 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8372 (clobber (reg:CC FLAGS_REG))]
8373 ""
8374 "#"
8375 "reload_completed"
8376 [(set (match_dup 1) (const_int 0))
8377 (parallel [(set (match_dup 0)
8378 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8379 (set (match_dup 1)
8380 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8381 (use (match_dup 1))
8382 (clobber (reg:CC FLAGS_REG))])]
8383 ""
8384 [(set_attr "type" "multi")
8385 (set_attr "mode" "<MODE>")])
8386
8387 (define_insn_and_split "*udivmodsi4_zext_1"
8388 [(set (match_operand:DI 0 "register_operand" "=a")
8389 (zero_extend:DI
8390 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8391 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8392 (set (match_operand:SI 1 "register_operand" "=&d")
8393 (umod:SI (match_dup 2) (match_dup 3)))
8394 (clobber (reg:CC FLAGS_REG))]
8395 "TARGET_64BIT"
8396 "#"
8397 "reload_completed"
8398 [(set (match_dup 1) (const_int 0))
8399 (parallel [(set (match_dup 0)
8400 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8401 (set (match_dup 1)
8402 (umod:SI (match_dup 2) (match_dup 3)))
8403 (use (match_dup 1))
8404 (clobber (reg:CC FLAGS_REG))])]
8405 ""
8406 [(set_attr "type" "multi")
8407 (set_attr "mode" "SI")])
8408
8409 (define_insn_and_split "*udivmodsi4_zext_2"
8410 [(set (match_operand:DI 1 "register_operand" "=&d")
8411 (zero_extend:DI
8412 (umod:SI (match_operand:SI 2 "register_operand" "0")
8413 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8414 (set (match_operand:SI 0 "register_operand" "=a")
8415 (udiv:SI (match_dup 2) (match_dup 3)))
8416 (clobber (reg:CC FLAGS_REG))]
8417 "TARGET_64BIT"
8418 "#"
8419 "reload_completed"
8420 [(set (match_dup 4) (const_int 0))
8421 (parallel [(set (match_dup 1)
8422 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8423 (set (match_dup 0)
8424 (udiv:SI (match_dup 2) (match_dup 3)))
8425 (use (match_dup 4))
8426 (clobber (reg:CC FLAGS_REG))])]
8427 "operands[4] = gen_lowpart (SImode, operands[1]);"
8428 [(set_attr "type" "multi")
8429 (set_attr "mode" "SI")])
8430
8431 ;; Optimize division or modulo by constant power of 2, if the constant
8432 ;; materializes only after expansion.
8433 (define_insn_and_split "*udivmod<mode>4_pow2"
8434 [(set (match_operand:SWI48 0 "register_operand" "=r")
8435 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8436 (match_operand:SWI48 3 "const_int_operand" "n")))
8437 (set (match_operand:SWI48 1 "register_operand" "=r")
8438 (umod:SWI48 (match_dup 2) (match_dup 3)))
8439 (clobber (reg:CC FLAGS_REG))]
8440 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8441 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8442 "#"
8443 "&& 1"
8444 [(set (match_dup 1) (match_dup 2))
8445 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8446 (clobber (reg:CC FLAGS_REG))])
8447 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8448 (clobber (reg:CC FLAGS_REG))])]
8449 {
8450 int v = exact_log2 (UINTVAL (operands[3]));
8451 operands[4] = GEN_INT (v);
8452 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8453 }
8454 [(set_attr "type" "multi")
8455 (set_attr "mode" "<MODE>")])
8456
8457 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8458 [(set (match_operand:DI 0 "register_operand" "=r")
8459 (zero_extend:DI
8460 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8461 (match_operand:SI 3 "const_int_operand" "n"))))
8462 (set (match_operand:SI 1 "register_operand" "=r")
8463 (umod:SI (match_dup 2) (match_dup 3)))
8464 (clobber (reg:CC FLAGS_REG))]
8465 "TARGET_64BIT
8466 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8467 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8468 "#"
8469 "&& 1"
8470 [(set (match_dup 1) (match_dup 2))
8471 (parallel [(set (match_dup 0)
8472 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8473 (clobber (reg:CC FLAGS_REG))])
8474 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8475 (clobber (reg:CC FLAGS_REG))])]
8476 {
8477 int v = exact_log2 (UINTVAL (operands[3]));
8478 operands[4] = GEN_INT (v);
8479 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8480 }
8481 [(set_attr "type" "multi")
8482 (set_attr "mode" "SI")])
8483
8484 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8485 [(set (match_operand:DI 1 "register_operand" "=r")
8486 (zero_extend:DI
8487 (umod:SI (match_operand:SI 2 "register_operand" "0")
8488 (match_operand:SI 3 "const_int_operand" "n"))))
8489 (set (match_operand:SI 0 "register_operand" "=r")
8490 (umod:SI (match_dup 2) (match_dup 3)))
8491 (clobber (reg:CC FLAGS_REG))]
8492 "TARGET_64BIT
8493 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8494 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8495 "#"
8496 "&& 1"
8497 [(set (match_dup 1) (match_dup 2))
8498 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8499 (clobber (reg:CC FLAGS_REG))])
8500 (parallel [(set (match_dup 1)
8501 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8502 (clobber (reg:CC FLAGS_REG))])]
8503 {
8504 int v = exact_log2 (UINTVAL (operands[3]));
8505 operands[4] = GEN_INT (v);
8506 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8507 }
8508 [(set_attr "type" "multi")
8509 (set_attr "mode" "SI")])
8510
8511 (define_insn "*udivmod<mode>4_noext"
8512 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8513 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8514 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8515 (set (match_operand:SWIM248 1 "register_operand" "=d")
8516 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8517 (use (match_operand:SWIM248 4 "register_operand" "1"))
8518 (clobber (reg:CC FLAGS_REG))]
8519 ""
8520 "div{<imodesuffix>}\t%3"
8521 [(set_attr "type" "idiv")
8522 (set_attr "mode" "<MODE>")])
8523
8524 (define_insn "*udivmodsi4_noext_zext_1"
8525 [(set (match_operand:DI 0 "register_operand" "=a")
8526 (zero_extend:DI
8527 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8528 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8529 (set (match_operand:SI 1 "register_operand" "=d")
8530 (umod:SI (match_dup 2) (match_dup 3)))
8531 (use (match_operand:SI 4 "register_operand" "1"))
8532 (clobber (reg:CC FLAGS_REG))]
8533 "TARGET_64BIT"
8534 "div{l}\t%3"
8535 [(set_attr "type" "idiv")
8536 (set_attr "mode" "SI")])
8537
8538 (define_insn "*udivmodsi4_noext_zext_2"
8539 [(set (match_operand:DI 1 "register_operand" "=d")
8540 (zero_extend:DI
8541 (umod:SI (match_operand:SI 2 "register_operand" "0")
8542 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8543 (set (match_operand:SI 0 "register_operand" "=a")
8544 (udiv:SI (match_dup 2) (match_dup 3)))
8545 (use (match_operand:SI 4 "register_operand" "1"))
8546 (clobber (reg:CC FLAGS_REG))]
8547 "TARGET_64BIT"
8548 "div{l}\t%3"
8549 [(set_attr "type" "idiv")
8550 (set_attr "mode" "SI")])
8551
8552 (define_expand "udivmodqi4"
8553 [(parallel [(set (match_operand:QI 0 "register_operand")
8554 (udiv:QI
8555 (match_operand:QI 1 "register_operand")
8556 (match_operand:QI 2 "nonimmediate_operand")))
8557 (set (match_operand:QI 3 "register_operand")
8558 (umod:QI (match_dup 1) (match_dup 2)))
8559 (clobber (reg:CC FLAGS_REG))])]
8560 "TARGET_QIMODE_MATH"
8561 {
8562 rtx div, mod;
8563 rtx tmp0, tmp1;
8564
8565 tmp0 = gen_reg_rtx (HImode);
8566 tmp1 = gen_reg_rtx (HImode);
8567
8568 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8569 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8570 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8571
8572 /* Extract remainder from AH. */
8573 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8574 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8575 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8576
8577 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8578 set_unique_reg_note (insn, REG_EQUAL, mod);
8579
8580 /* Extract quotient from AL. */
8581 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8582
8583 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8584 set_unique_reg_note (insn, REG_EQUAL, div);
8585
8586 DONE;
8587 })
8588
8589 (define_insn "udivmodhiqi3"
8590 [(set (match_operand:HI 0 "register_operand" "=a")
8591 (ior:HI
8592 (ashift:HI
8593 (zero_extend:HI
8594 (truncate:QI
8595 (mod:HI (match_operand:HI 1 "register_operand" "0")
8596 (zero_extend:HI
8597 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8598 (const_int 8))
8599 (zero_extend:HI
8600 (truncate:QI
8601 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_QIMODE_MATH"
8604 "div{b}\t%2"
8605 [(set_attr "type" "idiv")
8606 (set_attr "mode" "QI")])
8607
8608 ;; We cannot use div/idiv for double division, because it causes
8609 ;; "division by zero" on the overflow and that's not what we expect
8610 ;; from truncate. Because true (non truncating) double division is
8611 ;; never generated, we can't create this insn anyway.
8612 ;
8613 ;(define_insn ""
8614 ; [(set (match_operand:SI 0 "register_operand" "=a")
8615 ; (truncate:SI
8616 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8617 ; (zero_extend:DI
8618 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8619 ; (set (match_operand:SI 3 "register_operand" "=d")
8620 ; (truncate:SI
8621 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8622 ; (clobber (reg:CC FLAGS_REG))]
8623 ; ""
8624 ; "div{l}\t{%2, %0|%0, %2}"
8625 ; [(set_attr "type" "idiv")])
8626 \f
8627 ;;- Logical AND instructions
8628
8629 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8630 ;; Note that this excludes ah.
8631
8632 (define_expand "testsi_ccno_1"
8633 [(set (reg:CCNO FLAGS_REG)
8634 (compare:CCNO
8635 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8636 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8637 (const_int 0)))])
8638
8639 (define_expand "testqi_ccz_1"
8640 [(set (reg:CCZ FLAGS_REG)
8641 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8642 (match_operand:QI 1 "nonmemory_operand"))
8643 (const_int 0)))])
8644
8645 (define_expand "testdi_ccno_1"
8646 [(set (reg:CCNO FLAGS_REG)
8647 (compare:CCNO
8648 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8649 (match_operand:DI 1 "x86_64_szext_general_operand"))
8650 (const_int 0)))]
8651 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8652
8653 (define_insn "*testdi_1"
8654 [(set (reg FLAGS_REG)
8655 (compare
8656 (and:DI
8657 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8658 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8659 (const_int 0)))]
8660 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8661 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8662 "@
8663 test{l}\t{%k1, %k0|%k0, %k1}
8664 test{l}\t{%k1, %k0|%k0, %k1}
8665 test{q}\t{%1, %0|%0, %1}
8666 test{q}\t{%1, %0|%0, %1}
8667 test{q}\t{%1, %0|%0, %1}"
8668 [(set_attr "type" "test")
8669 (set_attr "modrm" "0,1,0,1,1")
8670 (set_attr "mode" "SI,SI,DI,DI,DI")])
8671
8672 (define_insn "*testqi_1_maybe_si"
8673 [(set (reg FLAGS_REG)
8674 (compare
8675 (and:QI
8676 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8677 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8678 (const_int 0)))]
8679 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8680 && ix86_match_ccmode (insn,
8681 CONST_INT_P (operands[1])
8682 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8683 {
8684 if (which_alternative == 3)
8685 {
8686 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8687 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8688 return "test{l}\t{%1, %k0|%k0, %1}";
8689 }
8690 return "test{b}\t{%1, %0|%0, %1}";
8691 }
8692 [(set_attr "type" "test")
8693 (set_attr "modrm" "0,1,1,1")
8694 (set_attr "mode" "QI,QI,QI,SI")
8695 (set_attr "pent_pair" "uv,np,uv,np")])
8696
8697 (define_insn "*test<mode>_1"
8698 [(set (reg FLAGS_REG)
8699 (compare
8700 (and:SWI124
8701 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8702 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8703 (const_int 0)))]
8704 "ix86_match_ccmode (insn, CCNOmode)
8705 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8706 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8707 [(set_attr "type" "test")
8708 (set_attr "modrm" "0,1,1")
8709 (set_attr "mode" "<MODE>")
8710 (set_attr "pent_pair" "uv,np,uv")])
8711
8712 (define_expand "testqi_ext_1_ccno"
8713 [(set (reg:CCNO FLAGS_REG)
8714 (compare:CCNO
8715 (and:QI
8716 (subreg:QI
8717 (zero_extract:SI (match_operand 0 "ext_register_operand")
8718 (const_int 8)
8719 (const_int 8)) 0)
8720 (match_operand 1 "const_int_operand"))
8721 (const_int 0)))])
8722
8723 (define_insn "*testqi_ext_1"
8724 [(set (reg FLAGS_REG)
8725 (compare
8726 (and:QI
8727 (subreg:QI
8728 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8729 (const_int 8)
8730 (const_int 8)) 0)
8731 (match_operand:QI 1 "general_operand" "QnBc,m"))
8732 (const_int 0)))]
8733 "ix86_match_ccmode (insn, CCNOmode)"
8734 "test{b}\t{%1, %h0|%h0, %1}"
8735 [(set_attr "isa" "*,nox64")
8736 (set_attr "type" "test")
8737 (set_attr "mode" "QI")])
8738
8739 (define_insn "*testqi_ext_2"
8740 [(set (reg FLAGS_REG)
8741 (compare
8742 (and:QI
8743 (subreg:QI
8744 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8745 (const_int 8)
8746 (const_int 8)) 0)
8747 (subreg:QI
8748 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8749 (const_int 8)
8750 (const_int 8)) 0))
8751 (const_int 0)))]
8752 "ix86_match_ccmode (insn, CCNOmode)"
8753 "test{b}\t{%h1, %h0|%h0, %h1}"
8754 [(set_attr "type" "test")
8755 (set_attr "mode" "QI")])
8756
8757 ;; Combine likes to form bit extractions for some tests. Humor it.
8758 (define_insn_and_split "*testqi_ext_3"
8759 [(set (match_operand 0 "flags_reg_operand")
8760 (match_operator 1 "compare_operator"
8761 [(zero_extract:SWI248
8762 (match_operand 2 "nonimmediate_operand" "rm")
8763 (match_operand 3 "const_int_operand" "n")
8764 (match_operand 4 "const_int_operand" "n"))
8765 (const_int 0)]))]
8766 "ix86_match_ccmode (insn, CCNOmode)
8767 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8768 || GET_MODE (operands[2]) == SImode
8769 || GET_MODE (operands[2]) == HImode
8770 || GET_MODE (operands[2]) == QImode)
8771 /* Ensure that resulting mask is zero or sign extended operand. */
8772 && INTVAL (operands[4]) >= 0
8773 && ((INTVAL (operands[3]) > 0
8774 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8775 || (<MODE>mode == DImode
8776 && INTVAL (operands[3]) > 32
8777 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8778 "#"
8779 "&& 1"
8780 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8781 {
8782 rtx val = operands[2];
8783 HOST_WIDE_INT len = INTVAL (operands[3]);
8784 HOST_WIDE_INT pos = INTVAL (operands[4]);
8785 machine_mode mode = GET_MODE (val);
8786
8787 if (SUBREG_P (val))
8788 {
8789 machine_mode submode = GET_MODE (SUBREG_REG (val));
8790
8791 /* Narrow paradoxical subregs to prevent partial register stalls. */
8792 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8793 && GET_MODE_CLASS (submode) == MODE_INT)
8794 {
8795 val = SUBREG_REG (val);
8796 mode = submode;
8797 }
8798 }
8799
8800 /* Small HImode tests can be converted to QImode. */
8801 if (register_operand (val, HImode) && pos + len <= 8)
8802 {
8803 val = gen_lowpart (QImode, val);
8804 mode = QImode;
8805 }
8806
8807 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8808
8809 wide_int mask
8810 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8811
8812 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8813 })
8814
8815 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8816 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8817 ;; this is relatively important trick.
8818 ;; Do the conversion only post-reload to avoid limiting of the register class
8819 ;; to QI regs.
8820 (define_split
8821 [(set (match_operand 0 "flags_reg_operand")
8822 (match_operator 1 "compare_operator"
8823 [(and (match_operand 2 "QIreg_operand")
8824 (match_operand 3 "const_int_operand"))
8825 (const_int 0)]))]
8826 "reload_completed
8827 && GET_MODE (operands[2]) != QImode
8828 && ((ix86_match_ccmode (insn, CCZmode)
8829 && !(INTVAL (operands[3]) & ~(255 << 8)))
8830 || (ix86_match_ccmode (insn, CCNOmode)
8831 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8832 [(set (match_dup 0)
8833 (match_op_dup 1
8834 [(and:QI
8835 (subreg:QI
8836 (zero_extract:SI (match_dup 2)
8837 (const_int 8)
8838 (const_int 8)) 0)
8839 (match_dup 3))
8840 (const_int 0)]))]
8841 {
8842 operands[2] = gen_lowpart (SImode, operands[2]);
8843 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8844 })
8845
8846 (define_split
8847 [(set (match_operand 0 "flags_reg_operand")
8848 (match_operator 1 "compare_operator"
8849 [(and (match_operand 2 "nonimmediate_operand")
8850 (match_operand 3 "const_int_operand"))
8851 (const_int 0)]))]
8852 "reload_completed
8853 && GET_MODE (operands[2]) != QImode
8854 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8855 && ((ix86_match_ccmode (insn, CCZmode)
8856 && !(INTVAL (operands[3]) & ~255))
8857 || (ix86_match_ccmode (insn, CCNOmode)
8858 && !(INTVAL (operands[3]) & ~127)))"
8859 [(set (match_dup 0)
8860 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8861 (const_int 0)]))]
8862 {
8863 operands[2] = gen_lowpart (QImode, operands[2]);
8864 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8865 })
8866
8867 ;; %%% This used to optimize known byte-wide and operations to memory,
8868 ;; and sometimes to QImode registers. If this is considered useful,
8869 ;; it should be done with splitters.
8870
8871 (define_expand "and<mode>3"
8872 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8873 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8874 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8875 ""
8876 {
8877 machine_mode mode = <MODE>mode;
8878 rtx (*insn) (rtx, rtx);
8879
8880 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8881 {
8882 HOST_WIDE_INT ival = INTVAL (operands[2]);
8883
8884 if (ival == (HOST_WIDE_INT) 0xffffffff)
8885 mode = SImode;
8886 else if (ival == 0xffff)
8887 mode = HImode;
8888 else if (ival == 0xff)
8889 mode = QImode;
8890 }
8891
8892 if (mode == <MODE>mode)
8893 {
8894 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8895 DONE;
8896 }
8897
8898 if (<MODE>mode == DImode)
8899 insn = (mode == SImode)
8900 ? gen_zero_extendsidi2
8901 : (mode == HImode)
8902 ? gen_zero_extendhidi2
8903 : gen_zero_extendqidi2;
8904 else if (<MODE>mode == SImode)
8905 insn = (mode == HImode)
8906 ? gen_zero_extendhisi2
8907 : gen_zero_extendqisi2;
8908 else if (<MODE>mode == HImode)
8909 insn = gen_zero_extendqihi2;
8910 else
8911 gcc_unreachable ();
8912
8913 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8914 DONE;
8915 })
8916
8917 (define_insn_and_split "*anddi3_doubleword"
8918 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8919 (and:DI
8920 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8921 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8922 (clobber (reg:CC FLAGS_REG))]
8923 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8924 && ix86_binary_operator_ok (AND, DImode, operands)"
8925 "#"
8926 "&& reload_completed"
8927 [(const_int 0)]
8928 {
8929 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8930 if (operands[2] == const0_rtx)
8931 {
8932 operands[1] = const0_rtx;
8933 ix86_expand_move (SImode, &operands[0]);
8934 }
8935 else if (operands[2] != constm1_rtx)
8936 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8937 else if (operands[5] == constm1_rtx)
8938 emit_note (NOTE_INSN_DELETED);
8939 if (operands[5] == const0_rtx)
8940 {
8941 operands[4] = const0_rtx;
8942 ix86_expand_move (SImode, &operands[3]);
8943 }
8944 else if (operands[5] != constm1_rtx)
8945 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8946 DONE;
8947 })
8948
8949 (define_insn "*anddi_1"
8950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8951 (and:DI
8952 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8953 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8954 (clobber (reg:CC FLAGS_REG))]
8955 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8956 "@
8957 and{l}\t{%k2, %k0|%k0, %k2}
8958 and{q}\t{%2, %0|%0, %2}
8959 and{q}\t{%2, %0|%0, %2}
8960 #"
8961 [(set_attr "type" "alu,alu,alu,imovx")
8962 (set_attr "length_immediate" "*,*,*,0")
8963 (set (attr "prefix_rex")
8964 (if_then_else
8965 (and (eq_attr "type" "imovx")
8966 (and (match_test "INTVAL (operands[2]) == 0xff")
8967 (match_operand 1 "ext_QIreg_operand")))
8968 (const_string "1")
8969 (const_string "*")))
8970 (set_attr "mode" "SI,DI,DI,SI")])
8971
8972 (define_insn_and_split "*anddi_1_btr"
8973 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8974 (and:DI
8975 (match_operand:DI 1 "nonimmediate_operand" "%0")
8976 (match_operand:DI 2 "const_int_operand" "n")))
8977 (clobber (reg:CC FLAGS_REG))]
8978 "TARGET_64BIT && TARGET_USE_BT
8979 && ix86_binary_operator_ok (AND, DImode, operands)
8980 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8981 "#"
8982 "&& reload_completed"
8983 [(parallel [(set (zero_extract:DI (match_dup 0)
8984 (const_int 1)
8985 (match_dup 3))
8986 (const_int 0))
8987 (clobber (reg:CC FLAGS_REG))])]
8988 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8989 [(set_attr "type" "alu1")
8990 (set_attr "prefix_0f" "1")
8991 (set_attr "znver1_decode" "double")
8992 (set_attr "mode" "DI")])
8993
8994 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8995 (define_split
8996 [(set (match_operand:DI 0 "register_operand")
8997 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8998 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8999 (clobber (reg:CC FLAGS_REG))]
9000 "TARGET_64BIT"
9001 [(parallel [(set (match_dup 0)
9002 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9003 (clobber (reg:CC FLAGS_REG))])]
9004 "operands[2] = gen_lowpart (SImode, operands[2]);")
9005
9006 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9007 (define_insn "*andsi_1_zext"
9008 [(set (match_operand:DI 0 "register_operand" "=r")
9009 (zero_extend:DI
9010 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9012 (clobber (reg:CC FLAGS_REG))]
9013 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9014 "and{l}\t{%2, %k0|%k0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "SI")])
9017
9018 (define_insn "*and<mode>_1"
9019 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
9020 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
9021 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9024 "@
9025 and{<imodesuffix>}\t{%2, %0|%0, %2}
9026 and{<imodesuffix>}\t{%2, %0|%0, %2}
9027 #"
9028 [(set_attr "type" "alu,alu,imovx")
9029 (set_attr "length_immediate" "*,*,0")
9030 (set (attr "prefix_rex")
9031 (if_then_else
9032 (and (eq_attr "type" "imovx")
9033 (and (match_test "INTVAL (operands[2]) == 0xff")
9034 (match_operand 1 "ext_QIreg_operand")))
9035 (const_string "1")
9036 (const_string "*")))
9037 (set_attr "mode" "<MODE>,<MODE>,SI")])
9038
9039 (define_insn "*andqi_1"
9040 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9041 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9042 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9043 (clobber (reg:CC FLAGS_REG))]
9044 "ix86_binary_operator_ok (AND, QImode, operands)"
9045 "@
9046 and{b}\t{%2, %0|%0, %2}
9047 and{b}\t{%2, %0|%0, %2}
9048 and{l}\t{%k2, %k0|%k0, %k2}"
9049 [(set_attr "type" "alu")
9050 (set_attr "mode" "QI,QI,SI")
9051 ;; Potential partial reg stall on alternative 2.
9052 (set (attr "preferred_for_speed")
9053 (cond [(eq_attr "alternative" "2")
9054 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9055 (symbol_ref "true")))])
9056
9057 (define_insn "*andqi_1_slp"
9058 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9059 (and:QI (match_dup 0)
9060 (match_operand:QI 1 "general_operand" "qn,qmn")))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9063 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9064 "and{b}\t{%1, %0|%0, %1}"
9065 [(set_attr "type" "alu1")
9066 (set_attr "mode" "QI")])
9067
9068 (define_split
9069 [(set (match_operand:SWI248 0 "register_operand")
9070 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9071 (match_operand:SWI248 2 "const_int_operand")))
9072 (clobber (reg:CC FLAGS_REG))]
9073 "reload_completed
9074 && (!REG_P (operands[1])
9075 || REGNO (operands[0]) != REGNO (operands[1]))"
9076 [(const_int 0)]
9077 {
9078 HOST_WIDE_INT ival = INTVAL (operands[2]);
9079 machine_mode mode;
9080 rtx (*insn) (rtx, rtx);
9081
9082 if (ival == (HOST_WIDE_INT) 0xffffffff)
9083 mode = SImode;
9084 else if (ival == 0xffff)
9085 mode = HImode;
9086 else
9087 {
9088 gcc_assert (ival == 0xff);
9089 mode = QImode;
9090 }
9091
9092 if (<MODE>mode == DImode)
9093 insn = (mode == SImode)
9094 ? gen_zero_extendsidi2
9095 : (mode == HImode)
9096 ? gen_zero_extendhidi2
9097 : gen_zero_extendqidi2;
9098 else
9099 {
9100 if (<MODE>mode != SImode)
9101 /* Zero extend to SImode to avoid partial register stalls. */
9102 operands[0] = gen_lowpart (SImode, operands[0]);
9103
9104 insn = (mode == HImode)
9105 ? gen_zero_extendhisi2
9106 : gen_zero_extendqisi2;
9107 }
9108 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9109 DONE;
9110 })
9111
9112 (define_split
9113 [(set (match_operand:SWI48 0 "register_operand")
9114 (and:SWI48 (match_dup 0)
9115 (const_int -65536)))
9116 (clobber (reg:CC FLAGS_REG))]
9117 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9118 || optimize_function_for_size_p (cfun)"
9119 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9120 "operands[1] = gen_lowpart (HImode, operands[0]);")
9121
9122 (define_split
9123 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9124 (and:SWI248 (match_dup 0)
9125 (const_int -256)))
9126 (clobber (reg:CC FLAGS_REG))]
9127 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9128 && reload_completed"
9129 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9130 "operands[1] = gen_lowpart (QImode, operands[0]);")
9131
9132 (define_split
9133 [(set (match_operand:SWI248 0 "QIreg_operand")
9134 (and:SWI248 (match_dup 0)
9135 (const_int -65281)))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9138 && reload_completed"
9139 [(parallel
9140 [(set (zero_extract:SI (match_dup 0)
9141 (const_int 8)
9142 (const_int 8))
9143 (subreg:SI
9144 (xor:QI
9145 (subreg:QI
9146 (zero_extract:SI (match_dup 0)
9147 (const_int 8)
9148 (const_int 8)) 0)
9149 (subreg:QI
9150 (zero_extract:SI (match_dup 0)
9151 (const_int 8)
9152 (const_int 8)) 0)) 0))
9153 (clobber (reg:CC FLAGS_REG))])]
9154 "operands[0] = gen_lowpart (SImode, operands[0]);")
9155
9156 (define_insn "*anddi_2"
9157 [(set (reg FLAGS_REG)
9158 (compare
9159 (and:DI
9160 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9161 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9162 (const_int 0)))
9163 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9164 (and:DI (match_dup 1) (match_dup 2)))]
9165 "TARGET_64BIT
9166 && ix86_match_ccmode
9167 (insn,
9168 /* If we are going to emit andl instead of andq, and the operands[2]
9169 constant might have the SImode sign bit set, make sure the sign
9170 flag isn't tested, because the instruction will set the sign flag
9171 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9172 conservatively assume it might have bit 31 set. */
9173 (satisfies_constraint_Z (operands[2])
9174 && (!CONST_INT_P (operands[2])
9175 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9176 ? CCZmode : CCNOmode)
9177 && ix86_binary_operator_ok (AND, DImode, operands)"
9178 "@
9179 and{l}\t{%k2, %k0|%k0, %k2}
9180 and{q}\t{%2, %0|%0, %2}
9181 and{q}\t{%2, %0|%0, %2}"
9182 [(set_attr "type" "alu")
9183 (set_attr "mode" "SI,DI,DI")])
9184
9185 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9186 (define_insn "*andsi_2_zext"
9187 [(set (reg FLAGS_REG)
9188 (compare (and:SI
9189 (match_operand:SI 1 "nonimmediate_operand" "%0")
9190 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9191 (const_int 0)))
9192 (set (match_operand:DI 0 "register_operand" "=r")
9193 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9194 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9195 && ix86_binary_operator_ok (AND, SImode, operands)"
9196 "and{l}\t{%2, %k0|%k0, %2}"
9197 [(set_attr "type" "alu")
9198 (set_attr "mode" "SI")])
9199
9200 (define_insn "*andqi_2_maybe_si"
9201 [(set (reg FLAGS_REG)
9202 (compare (and:QI
9203 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9204 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9205 (const_int 0)))
9206 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9207 (and:QI (match_dup 1) (match_dup 2)))]
9208 "ix86_binary_operator_ok (AND, QImode, operands)
9209 && ix86_match_ccmode (insn,
9210 CONST_INT_P (operands[2])
9211 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9212 {
9213 if (which_alternative == 2)
9214 {
9215 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9216 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9217 return "and{l}\t{%2, %k0|%k0, %2}";
9218 }
9219 return "and{b}\t{%2, %0|%0, %2}";
9220 }
9221 [(set_attr "type" "alu")
9222 (set_attr "mode" "QI,QI,SI")])
9223
9224 (define_insn "*and<mode>_2"
9225 [(set (reg FLAGS_REG)
9226 (compare (and:SWI124
9227 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9228 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9229 (const_int 0)))
9230 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9231 (and:SWI124 (match_dup 1) (match_dup 2)))]
9232 "ix86_match_ccmode (insn, CCNOmode)
9233 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9234 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9235 [(set_attr "type" "alu")
9236 (set_attr "mode" "<MODE>")])
9237
9238 (define_insn "*andqi_2_slp"
9239 [(set (reg FLAGS_REG)
9240 (compare (and:QI
9241 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9242 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9243 (const_int 0)))
9244 (set (strict_low_part (match_dup 0))
9245 (and:QI (match_dup 0) (match_dup 1)))]
9246 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9247 && ix86_match_ccmode (insn, CCNOmode)
9248 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9249 "and{b}\t{%1, %0|%0, %1}"
9250 [(set_attr "type" "alu1")
9251 (set_attr "mode" "QI")])
9252
9253 (define_insn "andqi_ext_1"
9254 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9255 (const_int 8)
9256 (const_int 8))
9257 (subreg:SI
9258 (and:QI
9259 (subreg:QI
9260 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9261 (const_int 8)
9262 (const_int 8)) 0)
9263 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9264 (clobber (reg:CC FLAGS_REG))]
9265 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9266 rtx_equal_p (operands[0], operands[1])"
9267 "and{b}\t{%2, %h0|%h0, %2}"
9268 [(set_attr "isa" "*,nox64")
9269 (set_attr "type" "alu")
9270 (set_attr "mode" "QI")])
9271
9272 ;; Generated by peephole translating test to and. This shows up
9273 ;; often in fp comparisons.
9274 (define_insn "*andqi_ext_1_cc"
9275 [(set (reg FLAGS_REG)
9276 (compare
9277 (and:QI
9278 (subreg:QI
9279 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9280 (const_int 8)
9281 (const_int 8)) 0)
9282 (match_operand:QI 2 "general_operand" "QnBc,m"))
9283 (const_int 0)))
9284 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9285 (const_int 8)
9286 (const_int 8))
9287 (subreg:SI
9288 (and:QI
9289 (subreg:QI
9290 (zero_extract:SI (match_dup 1)
9291 (const_int 8)
9292 (const_int 8)) 0)
9293 (match_dup 2)) 0))]
9294 "ix86_match_ccmode (insn, CCNOmode)
9295 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9296 && rtx_equal_p (operands[0], operands[1])"
9297 "and{b}\t{%2, %h0|%h0, %2}"
9298 [(set_attr "isa" "*,nox64")
9299 (set_attr "type" "alu")
9300 (set_attr "mode" "QI")])
9301
9302 (define_insn "*andqi_ext_2"
9303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9304 (const_int 8)
9305 (const_int 8))
9306 (subreg:SI
9307 (and:QI
9308 (subreg:QI
9309 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9310 (const_int 8)
9311 (const_int 8)) 0)
9312 (subreg:QI
9313 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9314 (const_int 8)
9315 (const_int 8)) 0)) 0))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9318 rtx_equal_p (operands[0], operands[1])
9319 || rtx_equal_p (operands[0], operands[2])"
9320 "and{b}\t{%h2, %h0|%h0, %h2}"
9321 [(set_attr "type" "alu")
9322 (set_attr "mode" "QI")])
9323
9324 ;; Convert wide AND instructions with immediate operand to shorter QImode
9325 ;; equivalents when possible.
9326 ;; Don't do the splitting with memory operands, since it introduces risk
9327 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9328 ;; for size, but that can (should?) be handled by generic code instead.
9329 (define_split
9330 [(set (match_operand:SWI248 0 "QIreg_operand")
9331 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9332 (match_operand:SWI248 2 "const_int_operand")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "reload_completed
9335 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9336 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9337 [(parallel
9338 [(set (zero_extract:SI (match_dup 0)
9339 (const_int 8)
9340 (const_int 8))
9341 (subreg:SI
9342 (and:QI
9343 (subreg:QI
9344 (zero_extract:SI (match_dup 1)
9345 (const_int 8)
9346 (const_int 8)) 0)
9347 (match_dup 2)) 0))
9348 (clobber (reg:CC FLAGS_REG))])]
9349 {
9350 operands[0] = gen_lowpart (SImode, operands[0]);
9351 operands[1] = gen_lowpart (SImode, operands[1]);
9352 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9353 })
9354
9355 ;; Since AND can be encoded with sign extended immediate, this is only
9356 ;; profitable when 7th bit is not set.
9357 (define_split
9358 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9359 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9360 (match_operand:SWI248 2 "const_int_operand")))
9361 (clobber (reg:CC FLAGS_REG))]
9362 "reload_completed
9363 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9364 && !(~INTVAL (operands[2]) & ~255)
9365 && !(INTVAL (operands[2]) & 128)"
9366 [(parallel [(set (strict_low_part (match_dup 0))
9367 (and:QI (match_dup 1)
9368 (match_dup 2)))
9369 (clobber (reg:CC FLAGS_REG))])]
9370 {
9371 operands[0] = gen_lowpart (QImode, operands[0]);
9372 operands[1] = gen_lowpart (QImode, operands[1]);
9373 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9374 })
9375
9376 (define_insn "*andndi3_doubleword"
9377 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9378 (and:DI
9379 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9380 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9383 "#"
9384 [(set_attr "isa" "bmi,bmi,bmi,*")])
9385
9386 (define_split
9387 [(set (match_operand:DI 0 "register_operand")
9388 (and:DI
9389 (not:DI (match_operand:DI 1 "register_operand"))
9390 (match_operand:DI 2 "nonimmediate_operand")))
9391 (clobber (reg:CC FLAGS_REG))]
9392 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9393 && reload_completed"
9394 [(parallel [(set (match_dup 0)
9395 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9396 (clobber (reg:CC FLAGS_REG))])
9397 (parallel [(set (match_dup 3)
9398 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9399 (clobber (reg:CC FLAGS_REG))])]
9400 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9401
9402 (define_split
9403 [(set (match_operand:DI 0 "register_operand")
9404 (and:DI
9405 (not:DI (match_dup 0))
9406 (match_operand:DI 1 "nonimmediate_operand")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9409 && reload_completed"
9410 [(set (match_dup 0) (not:SI (match_dup 0)))
9411 (parallel [(set (match_dup 0)
9412 (and:SI (match_dup 0) (match_dup 1)))
9413 (clobber (reg:CC FLAGS_REG))])
9414 (set (match_dup 2) (not:SI (match_dup 2)))
9415 (parallel [(set (match_dup 2)
9416 (and:SI (match_dup 2) (match_dup 3)))
9417 (clobber (reg:CC FLAGS_REG))])]
9418 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9419
9420 (define_insn "*andn<mode>_1"
9421 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9422 (and:SWI48
9423 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9424 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "TARGET_BMI"
9427 "andn\t{%2, %1, %0|%0, %1, %2}"
9428 [(set_attr "type" "bitmanip")
9429 (set_attr "btver2_decode" "direct, double")
9430 (set_attr "mode" "<MODE>")])
9431
9432 (define_insn "*andn<mode>_1"
9433 [(set (match_operand:SWI12 0 "register_operand" "=r")
9434 (and:SWI12
9435 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9436 (match_operand:SWI12 2 "register_operand" "r")))
9437 (clobber (reg:CC FLAGS_REG))]
9438 "TARGET_BMI"
9439 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9440 [(set_attr "type" "bitmanip")
9441 (set_attr "btver2_decode" "direct")
9442 (set_attr "mode" "SI")])
9443
9444 (define_insn "*andn_<mode>_ccno"
9445 [(set (reg FLAGS_REG)
9446 (compare
9447 (and:SWI48
9448 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9449 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9450 (const_int 0)))
9451 (clobber (match_scratch:SWI48 0 "=r,r"))]
9452 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9453 "andn\t{%2, %1, %0|%0, %1, %2}"
9454 [(set_attr "type" "bitmanip")
9455 (set_attr "btver2_decode" "direct, double")
9456 (set_attr "mode" "<MODE>")])
9457 \f
9458 ;; Logical inclusive and exclusive OR instructions
9459
9460 ;; %%% This used to optimize known byte-wide and operations to memory.
9461 ;; If this is considered useful, it should be done with splitters.
9462
9463 (define_expand "<code><mode>3"
9464 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9465 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9466 (match_operand:SWIM1248x 2 "<general_operand>")))]
9467 ""
9468 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9469
9470 (define_insn_and_split "*<code>di3_doubleword"
9471 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9472 (any_or:DI
9473 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9474 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9477 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9478 "#"
9479 "&& reload_completed"
9480 [(const_int 0)]
9481 {
9482 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9483 if (operands[2] == constm1_rtx)
9484 {
9485 if (<CODE> == IOR)
9486 {
9487 operands[1] = constm1_rtx;
9488 ix86_expand_move (SImode, &operands[0]);
9489 }
9490 else
9491 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9492 }
9493 else if (operands[2] != const0_rtx)
9494 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9495 else if (operands[5] == const0_rtx)
9496 emit_note (NOTE_INSN_DELETED);
9497 if (operands[5] == constm1_rtx)
9498 {
9499 if (<CODE> == IOR)
9500 {
9501 operands[4] = constm1_rtx;
9502 ix86_expand_move (SImode, &operands[3]);
9503 }
9504 else
9505 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9506 }
9507 else if (operands[5] != const0_rtx)
9508 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9509 DONE;
9510 })
9511
9512 (define_insn "*<code><mode>_1"
9513 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9514 (any_or:SWI248
9515 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9516 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9517 (clobber (reg:CC FLAGS_REG))]
9518 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9519 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9520 [(set_attr "type" "alu")
9521 (set_attr "mode" "<MODE>")])
9522
9523 (define_insn_and_split "*iordi_1_bts"
9524 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9525 (ior:DI
9526 (match_operand:DI 1 "nonimmediate_operand" "%0")
9527 (match_operand:DI 2 "const_int_operand" "n")))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "TARGET_64BIT && TARGET_USE_BT
9530 && ix86_binary_operator_ok (IOR, DImode, operands)
9531 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9532 "#"
9533 "&& reload_completed"
9534 [(parallel [(set (zero_extract:DI (match_dup 0)
9535 (const_int 1)
9536 (match_dup 3))
9537 (const_int 1))
9538 (clobber (reg:CC FLAGS_REG))])]
9539 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9540 [(set_attr "type" "alu1")
9541 (set_attr "prefix_0f" "1")
9542 (set_attr "znver1_decode" "double")
9543 (set_attr "mode" "DI")])
9544
9545 (define_insn_and_split "*xordi_1_btc"
9546 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9547 (xor:DI
9548 (match_operand:DI 1 "nonimmediate_operand" "%0")
9549 (match_operand:DI 2 "const_int_operand" "n")))
9550 (clobber (reg:CC FLAGS_REG))]
9551 "TARGET_64BIT && TARGET_USE_BT
9552 && ix86_binary_operator_ok (XOR, DImode, operands)
9553 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9554 "#"
9555 "&& reload_completed"
9556 [(parallel [(set (zero_extract:DI (match_dup 0)
9557 (const_int 1)
9558 (match_dup 3))
9559 (not:DI (zero_extract:DI (match_dup 0)
9560 (const_int 1)
9561 (match_dup 3))))
9562 (clobber (reg:CC FLAGS_REG))])]
9563 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9564 [(set_attr "type" "alu1")
9565 (set_attr "prefix_0f" "1")
9566 (set_attr "znver1_decode" "double")
9567 (set_attr "mode" "DI")])
9568
9569 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9570 (define_insn "*<code>si_1_zext"
9571 [(set (match_operand:DI 0 "register_operand" "=r")
9572 (zero_extend:DI
9573 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9574 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9575 (clobber (reg:CC FLAGS_REG))]
9576 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9577 "<logic>{l}\t{%2, %k0|%k0, %2}"
9578 [(set_attr "type" "alu")
9579 (set_attr "mode" "SI")])
9580
9581 (define_insn "*<code>si_1_zext_imm"
9582 [(set (match_operand:DI 0 "register_operand" "=r")
9583 (any_or:DI
9584 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9585 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9586 (clobber (reg:CC FLAGS_REG))]
9587 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9588 "<logic>{l}\t{%2, %k0|%k0, %2}"
9589 [(set_attr "type" "alu")
9590 (set_attr "mode" "SI")])
9591
9592 (define_insn "*<code>qi_1"
9593 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9594 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9595 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9596 (clobber (reg:CC FLAGS_REG))]
9597 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9598 "@
9599 <logic>{b}\t{%2, %0|%0, %2}
9600 <logic>{b}\t{%2, %0|%0, %2}
9601 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9602 [(set_attr "type" "alu")
9603 (set_attr "mode" "QI,QI,SI")
9604 ;; Potential partial reg stall on alternative 2.
9605 (set (attr "preferred_for_speed")
9606 (cond [(eq_attr "alternative" "2")
9607 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9608 (symbol_ref "true")))])
9609
9610 (define_insn "*<code>qi_1_slp"
9611 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9612 (any_or:QI (match_dup 0)
9613 (match_operand:QI 1 "general_operand" "qmn,qn")))
9614 (clobber (reg:CC FLAGS_REG))]
9615 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9616 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9617 "<logic>{b}\t{%1, %0|%0, %1}"
9618 [(set_attr "type" "alu1")
9619 (set_attr "mode" "QI")])
9620
9621 (define_insn "*<code><mode>_2"
9622 [(set (reg FLAGS_REG)
9623 (compare (any_or:SWI
9624 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9625 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9626 (const_int 0)))
9627 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9628 (any_or:SWI (match_dup 1) (match_dup 2)))]
9629 "ix86_match_ccmode (insn, CCNOmode)
9630 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9631 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9632 [(set_attr "type" "alu")
9633 (set_attr "mode" "<MODE>")])
9634
9635 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9636 ;; ??? Special case for immediate operand is missing - it is tricky.
9637 (define_insn "*<code>si_2_zext"
9638 [(set (reg FLAGS_REG)
9639 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9640 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9641 (const_int 0)))
9642 (set (match_operand:DI 0 "register_operand" "=r")
9643 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9644 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9645 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9646 "<logic>{l}\t{%2, %k0|%k0, %2}"
9647 [(set_attr "type" "alu")
9648 (set_attr "mode" "SI")])
9649
9650 (define_insn "*<code>si_2_zext_imm"
9651 [(set (reg FLAGS_REG)
9652 (compare (any_or:SI
9653 (match_operand:SI 1 "nonimmediate_operand" "%0")
9654 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9655 (const_int 0)))
9656 (set (match_operand:DI 0 "register_operand" "=r")
9657 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9659 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9660 "<logic>{l}\t{%2, %k0|%k0, %2}"
9661 [(set_attr "type" "alu")
9662 (set_attr "mode" "SI")])
9663
9664 (define_insn "*<code>qi_2_slp"
9665 [(set (reg FLAGS_REG)
9666 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9667 (match_operand:QI 1 "general_operand" "qmn,qn"))
9668 (const_int 0)))
9669 (set (strict_low_part (match_dup 0))
9670 (any_or:QI (match_dup 0) (match_dup 1)))]
9671 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9672 && ix86_match_ccmode (insn, CCNOmode)
9673 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9674 "<logic>{b}\t{%1, %0|%0, %1}"
9675 [(set_attr "type" "alu1")
9676 (set_attr "mode" "QI")])
9677
9678 (define_insn "*<code><mode>_3"
9679 [(set (reg FLAGS_REG)
9680 (compare (any_or:SWI
9681 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9682 (match_operand:SWI 2 "<general_operand>" "<g>"))
9683 (const_int 0)))
9684 (clobber (match_scratch:SWI 0 "=<r>"))]
9685 "ix86_match_ccmode (insn, CCNOmode)
9686 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9687 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9688 [(set_attr "type" "alu")
9689 (set_attr "mode" "<MODE>")])
9690
9691 (define_insn "*<code>qi_ext_1"
9692 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9693 (const_int 8)
9694 (const_int 8))
9695 (subreg:SI
9696 (any_or:QI
9697 (subreg:QI
9698 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9699 (const_int 8)
9700 (const_int 8)) 0)
9701 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9702 (clobber (reg:CC FLAGS_REG))]
9703 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9704 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9705 && rtx_equal_p (operands[0], operands[1])"
9706 "<logic>{b}\t{%2, %h0|%h0, %2}"
9707 [(set_attr "isa" "*,nox64")
9708 (set_attr "type" "alu")
9709 (set_attr "mode" "QI")])
9710
9711 (define_insn "*<code>qi_ext_2"
9712 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9713 (const_int 8)
9714 (const_int 8))
9715 (subreg:SI
9716 (any_or:QI
9717 (subreg:QI
9718 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9719 (const_int 8)
9720 (const_int 8)) 0)
9721 (subreg:QI
9722 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9723 (const_int 8)
9724 (const_int 8)) 0)) 0))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9727 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9728 && (rtx_equal_p (operands[0], operands[1])
9729 || rtx_equal_p (operands[0], operands[2]))"
9730 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9731 [(set_attr "type" "alu")
9732 (set_attr "mode" "QI")])
9733
9734 ;; Convert wide OR instructions with immediate operand to shorter QImode
9735 ;; equivalents when possible.
9736 ;; Don't do the splitting with memory operands, since it introduces risk
9737 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9738 ;; for size, but that can (should?) be handled by generic code instead.
9739 (define_split
9740 [(set (match_operand:SWI248 0 "QIreg_operand")
9741 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9742 (match_operand:SWI248 2 "const_int_operand")))
9743 (clobber (reg:CC FLAGS_REG))]
9744 "reload_completed
9745 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9746 && !(INTVAL (operands[2]) & ~(255 << 8))"
9747 [(parallel
9748 [(set (zero_extract:SI (match_dup 0)
9749 (const_int 8)
9750 (const_int 8))
9751 (subreg:SI
9752 (any_or:QI
9753 (subreg:QI
9754 (zero_extract:SI (match_dup 1)
9755 (const_int 8)
9756 (const_int 8)) 0)
9757 (match_dup 2)) 0))
9758 (clobber (reg:CC FLAGS_REG))])]
9759 {
9760 operands[0] = gen_lowpart (SImode, operands[0]);
9761 operands[1] = gen_lowpart (SImode, operands[1]);
9762 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9763 })
9764
9765 ;; Since OR can be encoded with sign extended immediate, this is only
9766 ;; profitable when 7th bit is set.
9767 (define_split
9768 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9769 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9770 (match_operand:SWI248 2 "const_int_operand")))
9771 (clobber (reg:CC FLAGS_REG))]
9772 "reload_completed
9773 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9774 && !(INTVAL (operands[2]) & ~255)
9775 && (INTVAL (operands[2]) & 128)"
9776 [(parallel [(set (strict_low_part (match_dup 0))
9777 (any_or:QI (match_dup 1)
9778 (match_dup 2)))
9779 (clobber (reg:CC FLAGS_REG))])]
9780 {
9781 operands[0] = gen_lowpart (QImode, operands[0]);
9782 operands[1] = gen_lowpart (QImode, operands[1]);
9783 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9784 })
9785
9786 (define_expand "xorqi_ext_1_cc"
9787 [(parallel [
9788 (set (reg:CCNO FLAGS_REG)
9789 (compare:CCNO
9790 (xor:QI
9791 (subreg:QI
9792 (zero_extract:SI (match_operand 1 "ext_register_operand")
9793 (const_int 8)
9794 (const_int 8)) 0)
9795 (match_operand 2 "const_int_operand"))
9796 (const_int 0)))
9797 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9798 (const_int 8)
9799 (const_int 8))
9800 (subreg:SI
9801 (xor:QI
9802 (subreg:QI
9803 (zero_extract:SI (match_dup 1)
9804 (const_int 8)
9805 (const_int 8)) 0)
9806 (match_dup 2)) 0))])])
9807
9808 (define_insn "*xorqi_ext_1_cc"
9809 [(set (reg FLAGS_REG)
9810 (compare
9811 (xor:QI
9812 (subreg:QI
9813 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9814 (const_int 8)
9815 (const_int 8)) 0)
9816 (match_operand:QI 2 "general_operand" "QnBc,m"))
9817 (const_int 0)))
9818 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9819 (const_int 8)
9820 (const_int 8))
9821 (subreg:SI
9822 (xor:QI
9823 (subreg:QI
9824 (zero_extract:SI (match_dup 1)
9825 (const_int 8)
9826 (const_int 8)) 0)
9827 (match_dup 2)) 0))]
9828 "ix86_match_ccmode (insn, CCNOmode)
9829 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9830 && rtx_equal_p (operands[0], operands[1])"
9831 "xor{b}\t{%2, %h0|%h0, %2}"
9832 [(set_attr "isa" "*,nox64")
9833 (set_attr "type" "alu")
9834 (set_attr "mode" "QI")])
9835 \f
9836 ;; Negation instructions
9837
9838 (define_expand "neg<mode>2"
9839 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9840 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9841 ""
9842 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9843
9844 (define_insn_and_split "*neg<dwi>2_doubleword"
9845 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9846 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9847 (clobber (reg:CC FLAGS_REG))]
9848 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9849 "#"
9850 "reload_completed"
9851 [(parallel
9852 [(set (reg:CCZ FLAGS_REG)
9853 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9854 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9855 (parallel
9856 [(set (match_dup 2)
9857 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9858 (match_dup 3))
9859 (const_int 0)))
9860 (clobber (reg:CC FLAGS_REG))])
9861 (parallel
9862 [(set (match_dup 2)
9863 (neg:DWIH (match_dup 2)))
9864 (clobber (reg:CC FLAGS_REG))])]
9865 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9866
9867 (define_insn "*neg<mode>2_1"
9868 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9869 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9870 (clobber (reg:CC FLAGS_REG))]
9871 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9872 "neg{<imodesuffix>}\t%0"
9873 [(set_attr "type" "negnot")
9874 (set_attr "mode" "<MODE>")])
9875
9876 ;; Combine is quite creative about this pattern.
9877 (define_insn "*negsi2_1_zext"
9878 [(set (match_operand:DI 0 "register_operand" "=r")
9879 (lshiftrt:DI
9880 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9881 (const_int 32)))
9882 (const_int 32)))
9883 (clobber (reg:CC FLAGS_REG))]
9884 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9885 "neg{l}\t%k0"
9886 [(set_attr "type" "negnot")
9887 (set_attr "mode" "SI")])
9888
9889 ;; The problem with neg is that it does not perform (compare x 0),
9890 ;; it really performs (compare 0 x), which leaves us with the zero
9891 ;; flag being the only useful item.
9892
9893 (define_insn "*neg<mode>2_cmpz"
9894 [(set (reg:CCZ FLAGS_REG)
9895 (compare:CCZ
9896 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9897 (const_int 0)))
9898 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9899 (neg:SWI (match_dup 1)))]
9900 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9901 "neg{<imodesuffix>}\t%0"
9902 [(set_attr "type" "negnot")
9903 (set_attr "mode" "<MODE>")])
9904
9905 (define_insn "*negsi2_cmpz_zext"
9906 [(set (reg:CCZ FLAGS_REG)
9907 (compare:CCZ
9908 (lshiftrt:DI
9909 (neg:DI (ashift:DI
9910 (match_operand:DI 1 "register_operand" "0")
9911 (const_int 32)))
9912 (const_int 32))
9913 (const_int 0)))
9914 (set (match_operand:DI 0 "register_operand" "=r")
9915 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9916 (const_int 32)))
9917 (const_int 32)))]
9918 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9919 "neg{l}\t%k0"
9920 [(set_attr "type" "negnot")
9921 (set_attr "mode" "SI")])
9922
9923 ;; Negate with jump on overflow.
9924 (define_expand "negv<mode>3"
9925 [(parallel [(set (reg:CCO FLAGS_REG)
9926 (ne:CCO (match_operand:SWI 1 "register_operand")
9927 (match_dup 3)))
9928 (set (match_operand:SWI 0 "register_operand")
9929 (neg:SWI (match_dup 1)))])
9930 (set (pc) (if_then_else
9931 (eq (reg:CCO FLAGS_REG) (const_int 0))
9932 (label_ref (match_operand 2))
9933 (pc)))]
9934 ""
9935 {
9936 operands[3]
9937 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9938 <MODE>mode);
9939 })
9940
9941 (define_insn "*negv<mode>3"
9942 [(set (reg:CCO FLAGS_REG)
9943 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9944 (match_operand:SWI 2 "const_int_operand")))
9945 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9946 (neg:SWI (match_dup 1)))]
9947 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9948 && mode_signbit_p (<MODE>mode, operands[2])"
9949 "neg{<imodesuffix>}\t%0"
9950 [(set_attr "type" "negnot")
9951 (set_attr "mode" "<MODE>")])
9952
9953 ;; Changing of sign for FP values is doable using integer unit too.
9954
9955 (define_expand "<code><mode>2"
9956 [(set (match_operand:X87MODEF 0 "register_operand")
9957 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9958 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9959 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9960
9961 (define_insn "*absneg<mode>2"
9962 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9963 (match_operator:MODEF 3 "absneg_operator"
9964 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9965 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9968 "#"
9969 [(set (attr "enabled")
9970 (if_then_else
9971 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9972 (if_then_else
9973 (eq_attr "alternative" "2")
9974 (symbol_ref "TARGET_MIX_SSE_I387")
9975 (symbol_ref "true"))
9976 (if_then_else
9977 (eq_attr "alternative" "2,3")
9978 (symbol_ref "true")
9979 (symbol_ref "false"))))])
9980
9981 (define_insn "*absnegxf2_i387"
9982 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9983 (match_operator:XF 3 "absneg_operator"
9984 [(match_operand:XF 1 "register_operand" "0,0")]))
9985 (use (match_operand 2))
9986 (clobber (reg:CC FLAGS_REG))]
9987 "TARGET_80387"
9988 "#")
9989
9990 (define_expand "<code>tf2"
9991 [(set (match_operand:TF 0 "register_operand")
9992 (absneg:TF (match_operand:TF 1 "register_operand")))]
9993 "TARGET_SSE"
9994 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9995
9996 (define_insn "*absnegtf2_sse"
9997 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9998 (match_operator:TF 3 "absneg_operator"
9999 [(match_operand:TF 1 "register_operand" "0,Yv")]))
10000 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
10001 (clobber (reg:CC FLAGS_REG))]
10002 "TARGET_SSE"
10003 "#")
10004
10005 ;; Splitters for fp abs and neg.
10006
10007 (define_split
10008 [(set (match_operand 0 "fp_register_operand")
10009 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10010 (use (match_operand 2))
10011 (clobber (reg:CC FLAGS_REG))]
10012 "reload_completed"
10013 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10014
10015 (define_split
10016 [(set (match_operand 0 "sse_reg_operand")
10017 (match_operator 3 "absneg_operator"
10018 [(match_operand 1 "register_operand")]))
10019 (use (match_operand 2 "nonimmediate_operand"))
10020 (clobber (reg:CC FLAGS_REG))]
10021 "reload_completed"
10022 [(set (match_dup 0) (match_dup 3))]
10023 {
10024 machine_mode mode = GET_MODE (operands[0]);
10025 machine_mode vmode = GET_MODE (operands[2]);
10026 rtx tmp;
10027
10028 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10029 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10030 if (operands_match_p (operands[0], operands[2]))
10031 std::swap (operands[1], operands[2]);
10032 if (GET_CODE (operands[3]) == ABS)
10033 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10034 else
10035 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10036 operands[3] = tmp;
10037 })
10038
10039 (define_split
10040 [(set (match_operand:SF 0 "general_reg_operand")
10041 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10042 (use (match_operand:V4SF 2))
10043 (clobber (reg:CC FLAGS_REG))]
10044 "reload_completed"
10045 [(parallel [(set (match_dup 0) (match_dup 1))
10046 (clobber (reg:CC FLAGS_REG))])]
10047 {
10048 rtx tmp;
10049 operands[0] = gen_lowpart (SImode, operands[0]);
10050 if (GET_CODE (operands[1]) == ABS)
10051 {
10052 tmp = gen_int_mode (0x7fffffff, SImode);
10053 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10054 }
10055 else
10056 {
10057 tmp = gen_int_mode (0x80000000, SImode);
10058 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10059 }
10060 operands[1] = tmp;
10061 })
10062
10063 (define_split
10064 [(set (match_operand:DF 0 "general_reg_operand")
10065 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10066 (use (match_operand 2))
10067 (clobber (reg:CC FLAGS_REG))]
10068 "reload_completed"
10069 [(parallel [(set (match_dup 0) (match_dup 1))
10070 (clobber (reg:CC FLAGS_REG))])]
10071 {
10072 rtx tmp;
10073 if (TARGET_64BIT)
10074 {
10075 tmp = gen_lowpart (DImode, operands[0]);
10076 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10077 operands[0] = tmp;
10078
10079 if (GET_CODE (operands[1]) == ABS)
10080 tmp = const0_rtx;
10081 else
10082 tmp = gen_rtx_NOT (DImode, tmp);
10083 }
10084 else
10085 {
10086 operands[0] = gen_highpart (SImode, operands[0]);
10087 if (GET_CODE (operands[1]) == ABS)
10088 {
10089 tmp = gen_int_mode (0x7fffffff, SImode);
10090 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10091 }
10092 else
10093 {
10094 tmp = gen_int_mode (0x80000000, SImode);
10095 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10096 }
10097 }
10098 operands[1] = tmp;
10099 })
10100
10101 (define_split
10102 [(set (match_operand:XF 0 "general_reg_operand")
10103 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10104 (use (match_operand 2))
10105 (clobber (reg:CC FLAGS_REG))]
10106 "reload_completed"
10107 [(parallel [(set (match_dup 0) (match_dup 1))
10108 (clobber (reg:CC FLAGS_REG))])]
10109 {
10110 rtx tmp;
10111 operands[0] = gen_rtx_REG (SImode,
10112 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10113 if (GET_CODE (operands[1]) == ABS)
10114 {
10115 tmp = GEN_INT (0x7fff);
10116 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10117 }
10118 else
10119 {
10120 tmp = GEN_INT (0x8000);
10121 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10122 }
10123 operands[1] = tmp;
10124 })
10125
10126 ;; Conditionalize these after reload. If they match before reload, we
10127 ;; lose the clobber and ability to use integer instructions.
10128
10129 (define_insn "*<code><mode>2_1"
10130 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10131 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10132 "TARGET_80387
10133 && (reload_completed
10134 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10135 "f<absneg_mnemonic>"
10136 [(set_attr "type" "fsgn")
10137 (set_attr "mode" "<MODE>")])
10138
10139 (define_insn "*<code>extendsfdf2"
10140 [(set (match_operand:DF 0 "register_operand" "=f")
10141 (absneg:DF (float_extend:DF
10142 (match_operand:SF 1 "register_operand" "0"))))]
10143 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10144 "f<absneg_mnemonic>"
10145 [(set_attr "type" "fsgn")
10146 (set_attr "mode" "DF")])
10147
10148 (define_insn "*<code>extendsfxf2"
10149 [(set (match_operand:XF 0 "register_operand" "=f")
10150 (absneg:XF (float_extend:XF
10151 (match_operand:SF 1 "register_operand" "0"))))]
10152 "TARGET_80387"
10153 "f<absneg_mnemonic>"
10154 [(set_attr "type" "fsgn")
10155 (set_attr "mode" "XF")])
10156
10157 (define_insn "*<code>extenddfxf2"
10158 [(set (match_operand:XF 0 "register_operand" "=f")
10159 (absneg:XF (float_extend:XF
10160 (match_operand:DF 1 "register_operand" "0"))))]
10161 "TARGET_80387"
10162 "f<absneg_mnemonic>"
10163 [(set_attr "type" "fsgn")
10164 (set_attr "mode" "XF")])
10165
10166 ;; Copysign instructions
10167
10168 (define_mode_iterator CSGNMODE [SF DF TF])
10169 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10170
10171 (define_expand "copysign<mode>3"
10172 [(match_operand:CSGNMODE 0 "register_operand")
10173 (match_operand:CSGNMODE 1 "nonmemory_operand")
10174 (match_operand:CSGNMODE 2 "register_operand")]
10175 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10176 || (TARGET_SSE && (<MODE>mode == TFmode))"
10177 "ix86_expand_copysign (operands); DONE;")
10178
10179 (define_insn_and_split "copysign<mode>3_const"
10180 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10181 (unspec:CSGNMODE
10182 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10183 (match_operand:CSGNMODE 2 "register_operand" "0")
10184 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10185 UNSPEC_COPYSIGN))]
10186 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10187 || (TARGET_SSE && (<MODE>mode == TFmode))"
10188 "#"
10189 "&& reload_completed"
10190 [(const_int 0)]
10191 "ix86_split_copysign_const (operands); DONE;")
10192
10193 (define_insn "copysign<mode>3_var"
10194 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10195 (unspec:CSGNMODE
10196 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10197 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10198 (match_operand:<CSGNVMODE> 4
10199 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10200 (match_operand:<CSGNVMODE> 5
10201 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10202 UNSPEC_COPYSIGN))
10203 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10204 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10205 || (TARGET_SSE && (<MODE>mode == TFmode))"
10206 "#")
10207
10208 (define_split
10209 [(set (match_operand:CSGNMODE 0 "register_operand")
10210 (unspec:CSGNMODE
10211 [(match_operand:CSGNMODE 2 "register_operand")
10212 (match_operand:CSGNMODE 3 "register_operand")
10213 (match_operand:<CSGNVMODE> 4)
10214 (match_operand:<CSGNVMODE> 5)]
10215 UNSPEC_COPYSIGN))
10216 (clobber (match_scratch:<CSGNVMODE> 1))]
10217 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10218 || (TARGET_SSE && (<MODE>mode == TFmode)))
10219 && reload_completed"
10220 [(const_int 0)]
10221 "ix86_split_copysign_var (operands); DONE;")
10222 \f
10223 ;; One complement instructions
10224
10225 (define_expand "one_cmpl<mode>2"
10226 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10227 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10228 ""
10229 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10230
10231 (define_insn_and_split "*one_cmpldi2_doubleword"
10232 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10233 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10234 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10235 && ix86_unary_operator_ok (NOT, DImode, operands)"
10236 "#"
10237 "&& reload_completed"
10238 [(set (match_dup 0)
10239 (not:SI (match_dup 1)))
10240 (set (match_dup 2)
10241 (not:SI (match_dup 3)))]
10242 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10243
10244 (define_insn "*one_cmpl<mode>2_1"
10245 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10246 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10247 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10248 "not{<imodesuffix>}\t%0"
10249 [(set_attr "type" "negnot")
10250 (set_attr "mode" "<MODE>")])
10251
10252 ;; ??? Currently never generated - xor is used instead.
10253 (define_insn "*one_cmplsi2_1_zext"
10254 [(set (match_operand:DI 0 "register_operand" "=r")
10255 (zero_extend:DI
10256 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10257 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10258 "not{l}\t%k0"
10259 [(set_attr "type" "negnot")
10260 (set_attr "mode" "SI")])
10261
10262 (define_insn "*one_cmplqi2_1"
10263 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10264 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10265 "ix86_unary_operator_ok (NOT, QImode, operands)"
10266 "@
10267 not{b}\t%0
10268 not{l}\t%k0"
10269 [(set_attr "type" "negnot")
10270 (set_attr "mode" "QI,SI")
10271 ;; Potential partial reg stall on alternative 1.
10272 (set (attr "preferred_for_speed")
10273 (cond [(eq_attr "alternative" "1")
10274 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10275 (symbol_ref "true")))])
10276
10277 (define_insn "*one_cmpl<mode>2_2"
10278 [(set (reg FLAGS_REG)
10279 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10280 (const_int 0)))
10281 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10282 (not:SWI (match_dup 1)))]
10283 "ix86_match_ccmode (insn, CCNOmode)
10284 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10285 "#"
10286 [(set_attr "type" "alu1")
10287 (set_attr "mode" "<MODE>")])
10288
10289 (define_split
10290 [(set (match_operand 0 "flags_reg_operand")
10291 (match_operator 2 "compare_operator"
10292 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10293 (const_int 0)]))
10294 (set (match_operand:SWI 1 "nonimmediate_operand")
10295 (not:SWI (match_dup 3)))]
10296 "ix86_match_ccmode (insn, CCNOmode)"
10297 [(parallel [(set (match_dup 0)
10298 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10299 (const_int 0)]))
10300 (set (match_dup 1)
10301 (xor:SWI (match_dup 3) (const_int -1)))])])
10302
10303 ;; ??? Currently never generated - xor is used instead.
10304 (define_insn "*one_cmplsi2_2_zext"
10305 [(set (reg FLAGS_REG)
10306 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10307 (const_int 0)))
10308 (set (match_operand:DI 0 "register_operand" "=r")
10309 (zero_extend:DI (not:SI (match_dup 1))))]
10310 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10311 && ix86_unary_operator_ok (NOT, SImode, operands)"
10312 "#"
10313 [(set_attr "type" "alu1")
10314 (set_attr "mode" "SI")])
10315
10316 (define_split
10317 [(set (match_operand 0 "flags_reg_operand")
10318 (match_operator 2 "compare_operator"
10319 [(not:SI (match_operand:SI 3 "register_operand"))
10320 (const_int 0)]))
10321 (set (match_operand:DI 1 "register_operand")
10322 (zero_extend:DI (not:SI (match_dup 3))))]
10323 "ix86_match_ccmode (insn, CCNOmode)"
10324 [(parallel [(set (match_dup 0)
10325 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10326 (const_int 0)]))
10327 (set (match_dup 1)
10328 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10329 \f
10330 ;; Shift instructions
10331
10332 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10333 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10334 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10335 ;; from the assembler input.
10336 ;;
10337 ;; This instruction shifts the target reg/mem as usual, but instead of
10338 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10339 ;; is a left shift double, bits are taken from the high order bits of
10340 ;; reg, else if the insn is a shift right double, bits are taken from the
10341 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10342 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10343 ;;
10344 ;; Since sh[lr]d does not change the `reg' operand, that is done
10345 ;; separately, making all shifts emit pairs of shift double and normal
10346 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10347 ;; support a 63 bit shift, each shift where the count is in a reg expands
10348 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10349 ;;
10350 ;; If the shift count is a constant, we need never emit more than one
10351 ;; shift pair, instead using moves and sign extension for counts greater
10352 ;; than 31.
10353
10354 (define_expand "ashl<mode>3"
10355 [(set (match_operand:SDWIM 0 "<shift_operand>")
10356 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10357 (match_operand:QI 2 "nonmemory_operand")))]
10358 ""
10359 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10360
10361 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10362 [(set (match_operand:<DWI> 0 "register_operand")
10363 (ashift:<DWI>
10364 (match_operand:<DWI> 1 "register_operand")
10365 (subreg:QI
10366 (and:SI
10367 (match_operand:SI 2 "register_operand" "c")
10368 (match_operand:SI 3 "const_int_operand")) 0)))
10369 (clobber (reg:CC FLAGS_REG))]
10370 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10371 && can_create_pseudo_p ()"
10372 "#"
10373 "&& 1"
10374 [(parallel
10375 [(set (match_dup 6)
10376 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10377 (lshiftrt:DWIH (match_dup 5)
10378 (minus:QI (match_dup 8) (match_dup 2)))))
10379 (clobber (reg:CC FLAGS_REG))])
10380 (parallel
10381 [(set (match_dup 4)
10382 (ashift:DWIH (match_dup 5) (match_dup 2)))
10383 (clobber (reg:CC FLAGS_REG))])]
10384 {
10385 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10386
10387 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10388
10389 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10390 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10391 {
10392 rtx tem = gen_reg_rtx (SImode);
10393 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10394 operands[2] = tem;
10395 }
10396
10397 operands[2] = gen_lowpart (QImode, operands[2]);
10398
10399 if (!rtx_equal_p (operands[6], operands[7]))
10400 emit_move_insn (operands[6], operands[7]);
10401 })
10402
10403 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10404 [(set (match_operand:<DWI> 0 "register_operand")
10405 (ashift:<DWI>
10406 (match_operand:<DWI> 1 "register_operand")
10407 (and:QI
10408 (match_operand:QI 2 "register_operand" "c")
10409 (match_operand:QI 3 "const_int_operand"))))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10412 && can_create_pseudo_p ()"
10413 "#"
10414 "&& 1"
10415 [(parallel
10416 [(set (match_dup 6)
10417 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10418 (lshiftrt:DWIH (match_dup 5)
10419 (minus:QI (match_dup 8) (match_dup 2)))))
10420 (clobber (reg:CC FLAGS_REG))])
10421 (parallel
10422 [(set (match_dup 4)
10423 (ashift:DWIH (match_dup 5) (match_dup 2)))
10424 (clobber (reg:CC FLAGS_REG))])]
10425 {
10426 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10427
10428 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10429
10430 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10431 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10432 {
10433 rtx tem = gen_reg_rtx (QImode);
10434 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10435 operands[2] = tem;
10436 }
10437
10438 if (!rtx_equal_p (operands[6], operands[7]))
10439 emit_move_insn (operands[6], operands[7]);
10440 })
10441
10442 (define_insn "*ashl<mode>3_doubleword"
10443 [(set (match_operand:DWI 0 "register_operand" "=&r")
10444 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10445 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10446 (clobber (reg:CC FLAGS_REG))]
10447 ""
10448 "#"
10449 [(set_attr "type" "multi")])
10450
10451 (define_split
10452 [(set (match_operand:DWI 0 "register_operand")
10453 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10454 (match_operand:QI 2 "nonmemory_operand")))
10455 (clobber (reg:CC FLAGS_REG))]
10456 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10457 [(const_int 0)]
10458 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10459
10460 ;; By default we don't ask for a scratch register, because when DWImode
10461 ;; values are manipulated, registers are already at a premium. But if
10462 ;; we have one handy, we won't turn it away.
10463
10464 (define_peephole2
10465 [(match_scratch:DWIH 3 "r")
10466 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10467 (ashift:<DWI>
10468 (match_operand:<DWI> 1 "nonmemory_operand")
10469 (match_operand:QI 2 "nonmemory_operand")))
10470 (clobber (reg:CC FLAGS_REG))])
10471 (match_dup 3)]
10472 "TARGET_CMOVE"
10473 [(const_int 0)]
10474 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10475
10476 (define_insn "x86_64_shld"
10477 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10478 (ior:DI (ashift:DI (match_dup 0)
10479 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10480 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10481 (minus:QI (const_int 64) (match_dup 2)))))
10482 (clobber (reg:CC FLAGS_REG))]
10483 "TARGET_64BIT"
10484 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10485 [(set_attr "type" "ishift")
10486 (set_attr "prefix_0f" "1")
10487 (set_attr "mode" "DI")
10488 (set_attr "athlon_decode" "vector")
10489 (set_attr "amdfam10_decode" "vector")
10490 (set_attr "bdver1_decode" "vector")])
10491
10492 (define_insn "x86_shld"
10493 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10494 (ior:SI (ashift:SI (match_dup 0)
10495 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10496 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10497 (minus:QI (const_int 32) (match_dup 2)))))
10498 (clobber (reg:CC FLAGS_REG))]
10499 ""
10500 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10501 [(set_attr "type" "ishift")
10502 (set_attr "prefix_0f" "1")
10503 (set_attr "mode" "SI")
10504 (set_attr "pent_pair" "np")
10505 (set_attr "athlon_decode" "vector")
10506 (set_attr "amdfam10_decode" "vector")
10507 (set_attr "bdver1_decode" "vector")])
10508
10509 (define_expand "x86_shift<mode>_adj_1"
10510 [(set (reg:CCZ FLAGS_REG)
10511 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10512 (match_dup 4))
10513 (const_int 0)))
10514 (set (match_operand:SWI48 0 "register_operand")
10515 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10516 (match_operand:SWI48 1 "register_operand")
10517 (match_dup 0)))
10518 (set (match_dup 1)
10519 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10520 (match_operand:SWI48 3 "register_operand")
10521 (match_dup 1)))]
10522 "TARGET_CMOVE"
10523 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10524
10525 (define_expand "x86_shift<mode>_adj_2"
10526 [(use (match_operand:SWI48 0 "register_operand"))
10527 (use (match_operand:SWI48 1 "register_operand"))
10528 (use (match_operand:QI 2 "register_operand"))]
10529 ""
10530 {
10531 rtx_code_label *label = gen_label_rtx ();
10532 rtx tmp;
10533
10534 emit_insn (gen_testqi_ccz_1 (operands[2],
10535 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10536
10537 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10538 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10539 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10540 gen_rtx_LABEL_REF (VOIDmode, label),
10541 pc_rtx);
10542 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10543 JUMP_LABEL (tmp) = label;
10544
10545 emit_move_insn (operands[0], operands[1]);
10546 ix86_expand_clear (operands[1]);
10547
10548 emit_label (label);
10549 LABEL_NUSES (label) = 1;
10550
10551 DONE;
10552 })
10553
10554 ;; Avoid useless masking of count operand.
10555 (define_insn_and_split "*ashl<mode>3_mask"
10556 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10557 (ashift:SWI48
10558 (match_operand:SWI48 1 "nonimmediate_operand")
10559 (subreg:QI
10560 (and:SI
10561 (match_operand:SI 2 "register_operand" "c,r")
10562 (match_operand:SI 3 "const_int_operand")) 0)))
10563 (clobber (reg:CC FLAGS_REG))]
10564 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10565 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10566 == GET_MODE_BITSIZE (<MODE>mode)-1
10567 && can_create_pseudo_p ()"
10568 "#"
10569 "&& 1"
10570 [(parallel
10571 [(set (match_dup 0)
10572 (ashift:SWI48 (match_dup 1)
10573 (match_dup 2)))
10574 (clobber (reg:CC FLAGS_REG))])]
10575 "operands[2] = gen_lowpart (QImode, operands[2]);"
10576 [(set_attr "isa" "*,bmi2")])
10577
10578 (define_insn_and_split "*ashl<mode>3_mask_1"
10579 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10580 (ashift:SWI48
10581 (match_operand:SWI48 1 "nonimmediate_operand")
10582 (and:QI
10583 (match_operand:QI 2 "register_operand" "c,r")
10584 (match_operand:QI 3 "const_int_operand"))))
10585 (clobber (reg:CC FLAGS_REG))]
10586 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10587 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10588 == GET_MODE_BITSIZE (<MODE>mode)-1
10589 && can_create_pseudo_p ()"
10590 "#"
10591 "&& 1"
10592 [(parallel
10593 [(set (match_dup 0)
10594 (ashift:SWI48 (match_dup 1)
10595 (match_dup 2)))
10596 (clobber (reg:CC FLAGS_REG))])]
10597 ""
10598 [(set_attr "isa" "*,bmi2")])
10599
10600 (define_insn "*bmi2_ashl<mode>3_1"
10601 [(set (match_operand:SWI48 0 "register_operand" "=r")
10602 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10603 (match_operand:SWI48 2 "register_operand" "r")))]
10604 "TARGET_BMI2"
10605 "shlx\t{%2, %1, %0|%0, %1, %2}"
10606 [(set_attr "type" "ishiftx")
10607 (set_attr "mode" "<MODE>")])
10608
10609 (define_insn "*ashl<mode>3_1"
10610 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10611 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10612 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10613 (clobber (reg:CC FLAGS_REG))]
10614 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10615 {
10616 switch (get_attr_type (insn))
10617 {
10618 case TYPE_LEA:
10619 case TYPE_ISHIFTX:
10620 return "#";
10621
10622 case TYPE_ALU:
10623 gcc_assert (operands[2] == const1_rtx);
10624 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10625 return "add{<imodesuffix>}\t%0, %0";
10626
10627 default:
10628 if (operands[2] == const1_rtx
10629 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10630 return "sal{<imodesuffix>}\t%0";
10631 else
10632 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10633 }
10634 }
10635 [(set_attr "isa" "*,*,bmi2")
10636 (set (attr "type")
10637 (cond [(eq_attr "alternative" "1")
10638 (const_string "lea")
10639 (eq_attr "alternative" "2")
10640 (const_string "ishiftx")
10641 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10642 (match_operand 0 "register_operand"))
10643 (match_operand 2 "const1_operand"))
10644 (const_string "alu")
10645 ]
10646 (const_string "ishift")))
10647 (set (attr "length_immediate")
10648 (if_then_else
10649 (ior (eq_attr "type" "alu")
10650 (and (eq_attr "type" "ishift")
10651 (and (match_operand 2 "const1_operand")
10652 (ior (match_test "TARGET_SHIFT1")
10653 (match_test "optimize_function_for_size_p (cfun)")))))
10654 (const_string "0")
10655 (const_string "*")))
10656 (set_attr "mode" "<MODE>")])
10657
10658 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10659 (define_split
10660 [(set (match_operand:SWI48 0 "register_operand")
10661 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10662 (match_operand:QI 2 "register_operand")))
10663 (clobber (reg:CC FLAGS_REG))]
10664 "TARGET_BMI2 && reload_completed"
10665 [(set (match_dup 0)
10666 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10667 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10668
10669 (define_insn "*bmi2_ashlsi3_1_zext"
10670 [(set (match_operand:DI 0 "register_operand" "=r")
10671 (zero_extend:DI
10672 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10673 (match_operand:SI 2 "register_operand" "r"))))]
10674 "TARGET_64BIT && TARGET_BMI2"
10675 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10676 [(set_attr "type" "ishiftx")
10677 (set_attr "mode" "SI")])
10678
10679 (define_insn "*ashlsi3_1_zext"
10680 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10681 (zero_extend:DI
10682 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10683 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10684 (clobber (reg:CC FLAGS_REG))]
10685 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10686 {
10687 switch (get_attr_type (insn))
10688 {
10689 case TYPE_LEA:
10690 case TYPE_ISHIFTX:
10691 return "#";
10692
10693 case TYPE_ALU:
10694 gcc_assert (operands[2] == const1_rtx);
10695 return "add{l}\t%k0, %k0";
10696
10697 default:
10698 if (operands[2] == const1_rtx
10699 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10700 return "sal{l}\t%k0";
10701 else
10702 return "sal{l}\t{%2, %k0|%k0, %2}";
10703 }
10704 }
10705 [(set_attr "isa" "*,*,bmi2")
10706 (set (attr "type")
10707 (cond [(eq_attr "alternative" "1")
10708 (const_string "lea")
10709 (eq_attr "alternative" "2")
10710 (const_string "ishiftx")
10711 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10712 (match_operand 2 "const1_operand"))
10713 (const_string "alu")
10714 ]
10715 (const_string "ishift")))
10716 (set (attr "length_immediate")
10717 (if_then_else
10718 (ior (eq_attr "type" "alu")
10719 (and (eq_attr "type" "ishift")
10720 (and (match_operand 2 "const1_operand")
10721 (ior (match_test "TARGET_SHIFT1")
10722 (match_test "optimize_function_for_size_p (cfun)")))))
10723 (const_string "0")
10724 (const_string "*")))
10725 (set_attr "mode" "SI")])
10726
10727 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10728 (define_split
10729 [(set (match_operand:DI 0 "register_operand")
10730 (zero_extend:DI
10731 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10732 (match_operand:QI 2 "register_operand"))))
10733 (clobber (reg:CC FLAGS_REG))]
10734 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10735 [(set (match_dup 0)
10736 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10737 "operands[2] = gen_lowpart (SImode, operands[2]);")
10738
10739 (define_insn "*ashlhi3_1"
10740 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10741 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10742 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10743 (clobber (reg:CC FLAGS_REG))]
10744 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10745 {
10746 switch (get_attr_type (insn))
10747 {
10748 case TYPE_LEA:
10749 return "#";
10750
10751 case TYPE_ALU:
10752 gcc_assert (operands[2] == const1_rtx);
10753 return "add{w}\t%0, %0";
10754
10755 default:
10756 if (operands[2] == const1_rtx
10757 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10758 return "sal{w}\t%0";
10759 else
10760 return "sal{w}\t{%2, %0|%0, %2}";
10761 }
10762 }
10763 [(set (attr "type")
10764 (cond [(eq_attr "alternative" "1")
10765 (const_string "lea")
10766 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10767 (match_operand 0 "register_operand"))
10768 (match_operand 2 "const1_operand"))
10769 (const_string "alu")
10770 ]
10771 (const_string "ishift")))
10772 (set (attr "length_immediate")
10773 (if_then_else
10774 (ior (eq_attr "type" "alu")
10775 (and (eq_attr "type" "ishift")
10776 (and (match_operand 2 "const1_operand")
10777 (ior (match_test "TARGET_SHIFT1")
10778 (match_test "optimize_function_for_size_p (cfun)")))))
10779 (const_string "0")
10780 (const_string "*")))
10781 (set_attr "mode" "HI,SI")])
10782
10783 (define_insn "*ashlqi3_1"
10784 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10785 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10786 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10787 (clobber (reg:CC FLAGS_REG))]
10788 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10789 {
10790 switch (get_attr_type (insn))
10791 {
10792 case TYPE_LEA:
10793 return "#";
10794
10795 case TYPE_ALU:
10796 gcc_assert (operands[2] == const1_rtx);
10797 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10798 return "add{l}\t%k0, %k0";
10799 else
10800 return "add{b}\t%0, %0";
10801
10802 default:
10803 if (operands[2] == const1_rtx
10804 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10805 {
10806 if (get_attr_mode (insn) == MODE_SI)
10807 return "sal{l}\t%k0";
10808 else
10809 return "sal{b}\t%0";
10810 }
10811 else
10812 {
10813 if (get_attr_mode (insn) == MODE_SI)
10814 return "sal{l}\t{%2, %k0|%k0, %2}";
10815 else
10816 return "sal{b}\t{%2, %0|%0, %2}";
10817 }
10818 }
10819 }
10820 [(set (attr "type")
10821 (cond [(eq_attr "alternative" "2")
10822 (const_string "lea")
10823 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10824 (match_operand 0 "register_operand"))
10825 (match_operand 2 "const1_operand"))
10826 (const_string "alu")
10827 ]
10828 (const_string "ishift")))
10829 (set (attr "length_immediate")
10830 (if_then_else
10831 (ior (eq_attr "type" "alu")
10832 (and (eq_attr "type" "ishift")
10833 (and (match_operand 2 "const1_operand")
10834 (ior (match_test "TARGET_SHIFT1")
10835 (match_test "optimize_function_for_size_p (cfun)")))))
10836 (const_string "0")
10837 (const_string "*")))
10838 (set_attr "mode" "QI,SI,SI")
10839 ;; Potential partial reg stall on alternative 1.
10840 (set (attr "preferred_for_speed")
10841 (cond [(eq_attr "alternative" "1")
10842 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10843 (symbol_ref "true")))])
10844
10845 (define_insn "*ashlqi3_1_slp"
10846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10847 (ashift:QI (match_dup 0)
10848 (match_operand:QI 1 "nonmemory_operand" "cI")))
10849 (clobber (reg:CC FLAGS_REG))]
10850 "(optimize_function_for_size_p (cfun)
10851 || !TARGET_PARTIAL_FLAG_REG_STALL
10852 || (operands[1] == const1_rtx
10853 && (TARGET_SHIFT1
10854 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10855 {
10856 switch (get_attr_type (insn))
10857 {
10858 case TYPE_ALU1:
10859 gcc_assert (operands[1] == const1_rtx);
10860 return "add{b}\t%0, %0";
10861
10862 default:
10863 if (operands[1] == const1_rtx
10864 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10865 return "sal{b}\t%0";
10866 else
10867 return "sal{b}\t{%1, %0|%0, %1}";
10868 }
10869 }
10870 [(set (attr "type")
10871 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10872 (match_operand 0 "register_operand"))
10873 (match_operand 1 "const1_operand"))
10874 (const_string "alu1")
10875 ]
10876 (const_string "ishift1")))
10877 (set (attr "length_immediate")
10878 (if_then_else
10879 (ior (eq_attr "type" "alu1")
10880 (and (eq_attr "type" "ishift1")
10881 (and (match_operand 1 "const1_operand")
10882 (ior (match_test "TARGET_SHIFT1")
10883 (match_test "optimize_function_for_size_p (cfun)")))))
10884 (const_string "0")
10885 (const_string "*")))
10886 (set_attr "mode" "QI")])
10887
10888 ;; Convert ashift to the lea pattern to avoid flags dependency.
10889 (define_split
10890 [(set (match_operand:SWI 0 "register_operand")
10891 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10892 (match_operand 2 "const_0_to_3_operand")))
10893 (clobber (reg:CC FLAGS_REG))]
10894 "reload_completed
10895 && REGNO (operands[0]) != REGNO (operands[1])"
10896 [(set (match_dup 0)
10897 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10898 {
10899 if (<MODE>mode != <LEAMODE>mode)
10900 {
10901 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10902 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10903 }
10904 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10905 })
10906
10907 ;; Convert ashift to the lea pattern to avoid flags dependency.
10908 (define_split
10909 [(set (match_operand:DI 0 "register_operand")
10910 (zero_extend:DI
10911 (ashift:SI (match_operand:SI 1 "index_register_operand")
10912 (match_operand 2 "const_0_to_3_operand"))))
10913 (clobber (reg:CC FLAGS_REG))]
10914 "TARGET_64BIT && reload_completed
10915 && REGNO (operands[0]) != REGNO (operands[1])"
10916 [(set (match_dup 0)
10917 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10918 {
10919 operands[1] = gen_lowpart (SImode, operands[1]);
10920 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10921 })
10922
10923 ;; This pattern can't accept a variable shift count, since shifts by
10924 ;; zero don't affect the flags. We assume that shifts by constant
10925 ;; zero are optimized away.
10926 (define_insn "*ashl<mode>3_cmp"
10927 [(set (reg FLAGS_REG)
10928 (compare
10929 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10930 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10931 (const_int 0)))
10932 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10933 (ashift:SWI (match_dup 1) (match_dup 2)))]
10934 "(optimize_function_for_size_p (cfun)
10935 || !TARGET_PARTIAL_FLAG_REG_STALL
10936 || (operands[2] == const1_rtx
10937 && (TARGET_SHIFT1
10938 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10939 && ix86_match_ccmode (insn, CCGOCmode)
10940 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10941 {
10942 switch (get_attr_type (insn))
10943 {
10944 case TYPE_ALU:
10945 gcc_assert (operands[2] == const1_rtx);
10946 return "add{<imodesuffix>}\t%0, %0";
10947
10948 default:
10949 if (operands[2] == const1_rtx
10950 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10951 return "sal{<imodesuffix>}\t%0";
10952 else
10953 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10954 }
10955 }
10956 [(set (attr "type")
10957 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10958 (match_operand 0 "register_operand"))
10959 (match_operand 2 "const1_operand"))
10960 (const_string "alu")
10961 ]
10962 (const_string "ishift")))
10963 (set (attr "length_immediate")
10964 (if_then_else
10965 (ior (eq_attr "type" "alu")
10966 (and (eq_attr "type" "ishift")
10967 (and (match_operand 2 "const1_operand")
10968 (ior (match_test "TARGET_SHIFT1")
10969 (match_test "optimize_function_for_size_p (cfun)")))))
10970 (const_string "0")
10971 (const_string "*")))
10972 (set_attr "mode" "<MODE>")])
10973
10974 (define_insn "*ashlsi3_cmp_zext"
10975 [(set (reg FLAGS_REG)
10976 (compare
10977 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10978 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10979 (const_int 0)))
10980 (set (match_operand:DI 0 "register_operand" "=r")
10981 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10982 "TARGET_64BIT
10983 && (optimize_function_for_size_p (cfun)
10984 || !TARGET_PARTIAL_FLAG_REG_STALL
10985 || (operands[2] == const1_rtx
10986 && (TARGET_SHIFT1
10987 || TARGET_DOUBLE_WITH_ADD)))
10988 && ix86_match_ccmode (insn, CCGOCmode)
10989 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10990 {
10991 switch (get_attr_type (insn))
10992 {
10993 case TYPE_ALU:
10994 gcc_assert (operands[2] == const1_rtx);
10995 return "add{l}\t%k0, %k0";
10996
10997 default:
10998 if (operands[2] == const1_rtx
10999 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11000 return "sal{l}\t%k0";
11001 else
11002 return "sal{l}\t{%2, %k0|%k0, %2}";
11003 }
11004 }
11005 [(set (attr "type")
11006 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11007 (match_operand 2 "const1_operand"))
11008 (const_string "alu")
11009 ]
11010 (const_string "ishift")))
11011 (set (attr "length_immediate")
11012 (if_then_else
11013 (ior (eq_attr "type" "alu")
11014 (and (eq_attr "type" "ishift")
11015 (and (match_operand 2 "const1_operand")
11016 (ior (match_test "TARGET_SHIFT1")
11017 (match_test "optimize_function_for_size_p (cfun)")))))
11018 (const_string "0")
11019 (const_string "*")))
11020 (set_attr "mode" "SI")])
11021
11022 (define_insn "*ashl<mode>3_cconly"
11023 [(set (reg FLAGS_REG)
11024 (compare
11025 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11026 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11027 (const_int 0)))
11028 (clobber (match_scratch:SWI 0 "=<r>"))]
11029 "(optimize_function_for_size_p (cfun)
11030 || !TARGET_PARTIAL_FLAG_REG_STALL
11031 || (operands[2] == const1_rtx
11032 && (TARGET_SHIFT1
11033 || TARGET_DOUBLE_WITH_ADD)))
11034 && ix86_match_ccmode (insn, CCGOCmode)"
11035 {
11036 switch (get_attr_type (insn))
11037 {
11038 case TYPE_ALU:
11039 gcc_assert (operands[2] == const1_rtx);
11040 return "add{<imodesuffix>}\t%0, %0";
11041
11042 default:
11043 if (operands[2] == const1_rtx
11044 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11045 return "sal{<imodesuffix>}\t%0";
11046 else
11047 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11048 }
11049 }
11050 [(set (attr "type")
11051 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11052 (match_operand 0 "register_operand"))
11053 (match_operand 2 "const1_operand"))
11054 (const_string "alu")
11055 ]
11056 (const_string "ishift")))
11057 (set (attr "length_immediate")
11058 (if_then_else
11059 (ior (eq_attr "type" "alu")
11060 (and (eq_attr "type" "ishift")
11061 (and (match_operand 2 "const1_operand")
11062 (ior (match_test "TARGET_SHIFT1")
11063 (match_test "optimize_function_for_size_p (cfun)")))))
11064 (const_string "0")
11065 (const_string "*")))
11066 (set_attr "mode" "<MODE>")])
11067
11068 ;; See comment above `ashl<mode>3' about how this works.
11069
11070 (define_expand "<shift_insn><mode>3"
11071 [(set (match_operand:SDWIM 0 "<shift_operand>")
11072 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11073 (match_operand:QI 2 "nonmemory_operand")))]
11074 ""
11075 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11076
11077 ;; Avoid useless masking of count operand.
11078 (define_insn_and_split "*<shift_insn><mode>3_mask"
11079 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11080 (any_shiftrt:SWI48
11081 (match_operand:SWI48 1 "nonimmediate_operand")
11082 (subreg:QI
11083 (and:SI
11084 (match_operand:SI 2 "register_operand" "c,r")
11085 (match_operand:SI 3 "const_int_operand")) 0)))
11086 (clobber (reg:CC FLAGS_REG))]
11087 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11088 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11089 == GET_MODE_BITSIZE (<MODE>mode)-1
11090 && can_create_pseudo_p ()"
11091 "#"
11092 "&& 1"
11093 [(parallel
11094 [(set (match_dup 0)
11095 (any_shiftrt:SWI48 (match_dup 1)
11096 (match_dup 2)))
11097 (clobber (reg:CC FLAGS_REG))])]
11098 "operands[2] = gen_lowpart (QImode, operands[2]);"
11099 [(set_attr "isa" "*,bmi2")])
11100
11101 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
11102 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11103 (any_shiftrt:SWI48
11104 (match_operand:SWI48 1 "nonimmediate_operand")
11105 (and:QI
11106 (match_operand:QI 2 "register_operand" "c,r")
11107 (match_operand:QI 3 "const_int_operand"))))
11108 (clobber (reg:CC FLAGS_REG))]
11109 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11110 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11111 == GET_MODE_BITSIZE (<MODE>mode)-1
11112 && can_create_pseudo_p ()"
11113 "#"
11114 "&& 1"
11115 [(parallel
11116 [(set (match_dup 0)
11117 (any_shiftrt:SWI48 (match_dup 1)
11118 (match_dup 2)))
11119 (clobber (reg:CC FLAGS_REG))])]
11120 ""
11121 [(set_attr "isa" "*,bmi2")])
11122
11123 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
11124 [(set (match_operand:<DWI> 0 "register_operand")
11125 (any_shiftrt:<DWI>
11126 (match_operand:<DWI> 1 "register_operand")
11127 (subreg:QI
11128 (and:SI
11129 (match_operand:SI 2 "register_operand" "c")
11130 (match_operand:SI 3 "const_int_operand")) 0)))
11131 (clobber (reg:CC FLAGS_REG))]
11132 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11133 && can_create_pseudo_p ()"
11134 "#"
11135 "&& 1"
11136 [(parallel
11137 [(set (match_dup 4)
11138 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11139 (ashift:DWIH (match_dup 7)
11140 (minus:QI (match_dup 8) (match_dup 2)))))
11141 (clobber (reg:CC FLAGS_REG))])
11142 (parallel
11143 [(set (match_dup 6)
11144 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11145 (clobber (reg:CC FLAGS_REG))])]
11146 {
11147 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11148
11149 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11150
11151 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11152 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11153 {
11154 rtx tem = gen_reg_rtx (SImode);
11155 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11156 operands[2] = tem;
11157 }
11158
11159 operands[2] = gen_lowpart (QImode, operands[2]);
11160
11161 if (!rtx_equal_p (operands[4], operands[5]))
11162 emit_move_insn (operands[4], operands[5]);
11163 })
11164
11165 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
11166 [(set (match_operand:<DWI> 0 "register_operand")
11167 (any_shiftrt:<DWI>
11168 (match_operand:<DWI> 1 "register_operand")
11169 (and:QI
11170 (match_operand:QI 2 "register_operand" "c")
11171 (match_operand:QI 3 "const_int_operand"))))
11172 (clobber (reg:CC FLAGS_REG))]
11173 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11174 && can_create_pseudo_p ()"
11175 "#"
11176 "&& 1"
11177 [(parallel
11178 [(set (match_dup 4)
11179 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11180 (ashift:DWIH (match_dup 7)
11181 (minus:QI (match_dup 8) (match_dup 2)))))
11182 (clobber (reg:CC FLAGS_REG))])
11183 (parallel
11184 [(set (match_dup 6)
11185 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11186 (clobber (reg:CC FLAGS_REG))])]
11187 {
11188 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11189
11190 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11191
11192 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11193 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11194 {
11195 rtx tem = gen_reg_rtx (QImode);
11196 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11197 operands[2] = tem;
11198 }
11199
11200 if (!rtx_equal_p (operands[4], operands[5]))
11201 emit_move_insn (operands[4], operands[5]);
11202 })
11203
11204 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
11205 [(set (match_operand:DWI 0 "register_operand" "=&r")
11206 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11207 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11208 (clobber (reg:CC FLAGS_REG))]
11209 ""
11210 "#"
11211 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
11212 [(const_int 0)]
11213 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11214 [(set_attr "type" "multi")])
11215
11216 ;; By default we don't ask for a scratch register, because when DWImode
11217 ;; values are manipulated, registers are already at a premium. But if
11218 ;; we have one handy, we won't turn it away.
11219
11220 (define_peephole2
11221 [(match_scratch:DWIH 3 "r")
11222 (parallel [(set (match_operand:<DWI> 0 "register_operand")
11223 (any_shiftrt:<DWI>
11224 (match_operand:<DWI> 1 "register_operand")
11225 (match_operand:QI 2 "nonmemory_operand")))
11226 (clobber (reg:CC FLAGS_REG))])
11227 (match_dup 3)]
11228 "TARGET_CMOVE"
11229 [(const_int 0)]
11230 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11231
11232 (define_insn "x86_64_shrd"
11233 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11234 (ior:DI (lshiftrt:DI (match_dup 0)
11235 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11236 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11237 (minus:QI (const_int 64) (match_dup 2)))))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "TARGET_64BIT"
11240 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11241 [(set_attr "type" "ishift")
11242 (set_attr "prefix_0f" "1")
11243 (set_attr "mode" "DI")
11244 (set_attr "athlon_decode" "vector")
11245 (set_attr "amdfam10_decode" "vector")
11246 (set_attr "bdver1_decode" "vector")])
11247
11248 (define_insn "x86_shrd"
11249 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11250 (ior:SI (lshiftrt:SI (match_dup 0)
11251 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11252 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11253 (minus:QI (const_int 32) (match_dup 2)))))
11254 (clobber (reg:CC FLAGS_REG))]
11255 ""
11256 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11257 [(set_attr "type" "ishift")
11258 (set_attr "prefix_0f" "1")
11259 (set_attr "mode" "SI")
11260 (set_attr "pent_pair" "np")
11261 (set_attr "athlon_decode" "vector")
11262 (set_attr "amdfam10_decode" "vector")
11263 (set_attr "bdver1_decode" "vector")])
11264
11265 (define_insn "ashrdi3_cvt"
11266 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11267 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11268 (match_operand:QI 2 "const_int_operand")))
11269 (clobber (reg:CC FLAGS_REG))]
11270 "TARGET_64BIT && INTVAL (operands[2]) == 63
11271 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11272 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11273 "@
11274 {cqto|cqo}
11275 sar{q}\t{%2, %0|%0, %2}"
11276 [(set_attr "type" "imovx,ishift")
11277 (set_attr "prefix_0f" "0,*")
11278 (set_attr "length_immediate" "0,*")
11279 (set_attr "modrm" "0,1")
11280 (set_attr "mode" "DI")])
11281
11282 (define_insn "*ashrsi3_cvt_zext"
11283 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11284 (zero_extend:DI
11285 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11286 (match_operand:QI 2 "const_int_operand"))))
11287 (clobber (reg:CC FLAGS_REG))]
11288 "TARGET_64BIT && INTVAL (operands[2]) == 31
11289 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11290 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11291 "@
11292 {cltd|cdq}
11293 sar{l}\t{%2, %k0|%k0, %2}"
11294 [(set_attr "type" "imovx,ishift")
11295 (set_attr "prefix_0f" "0,*")
11296 (set_attr "length_immediate" "0,*")
11297 (set_attr "modrm" "0,1")
11298 (set_attr "mode" "SI")])
11299
11300 (define_insn "ashrsi3_cvt"
11301 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11302 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11303 (match_operand:QI 2 "const_int_operand")))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "INTVAL (operands[2]) == 31
11306 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11307 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11308 "@
11309 {cltd|cdq}
11310 sar{l}\t{%2, %0|%0, %2}"
11311 [(set_attr "type" "imovx,ishift")
11312 (set_attr "prefix_0f" "0,*")
11313 (set_attr "length_immediate" "0,*")
11314 (set_attr "modrm" "0,1")
11315 (set_attr "mode" "SI")])
11316
11317 (define_expand "x86_shift<mode>_adj_3"
11318 [(use (match_operand:SWI48 0 "register_operand"))
11319 (use (match_operand:SWI48 1 "register_operand"))
11320 (use (match_operand:QI 2 "register_operand"))]
11321 ""
11322 {
11323 rtx_code_label *label = gen_label_rtx ();
11324 rtx tmp;
11325
11326 emit_insn (gen_testqi_ccz_1 (operands[2],
11327 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11328
11329 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11330 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11331 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11332 gen_rtx_LABEL_REF (VOIDmode, label),
11333 pc_rtx);
11334 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11335 JUMP_LABEL (tmp) = label;
11336
11337 emit_move_insn (operands[0], operands[1]);
11338 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11339 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11340 emit_label (label);
11341 LABEL_NUSES (label) = 1;
11342
11343 DONE;
11344 })
11345
11346 (define_insn "*bmi2_<shift_insn><mode>3_1"
11347 [(set (match_operand:SWI48 0 "register_operand" "=r")
11348 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11349 (match_operand:SWI48 2 "register_operand" "r")))]
11350 "TARGET_BMI2"
11351 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11352 [(set_attr "type" "ishiftx")
11353 (set_attr "mode" "<MODE>")])
11354
11355 (define_insn "*<shift_insn><mode>3_1"
11356 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11357 (any_shiftrt:SWI48
11358 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11359 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11360 (clobber (reg:CC FLAGS_REG))]
11361 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11362 {
11363 switch (get_attr_type (insn))
11364 {
11365 case TYPE_ISHIFTX:
11366 return "#";
11367
11368 default:
11369 if (operands[2] == const1_rtx
11370 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11371 return "<shift>{<imodesuffix>}\t%0";
11372 else
11373 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11374 }
11375 }
11376 [(set_attr "isa" "*,bmi2")
11377 (set_attr "type" "ishift,ishiftx")
11378 (set (attr "length_immediate")
11379 (if_then_else
11380 (and (match_operand 2 "const1_operand")
11381 (ior (match_test "TARGET_SHIFT1")
11382 (match_test "optimize_function_for_size_p (cfun)")))
11383 (const_string "0")
11384 (const_string "*")))
11385 (set_attr "mode" "<MODE>")])
11386
11387 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11388 (define_split
11389 [(set (match_operand:SWI48 0 "register_operand")
11390 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11391 (match_operand:QI 2 "register_operand")))
11392 (clobber (reg:CC FLAGS_REG))]
11393 "TARGET_BMI2 && reload_completed"
11394 [(set (match_dup 0)
11395 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11396 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11397
11398 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11399 [(set (match_operand:DI 0 "register_operand" "=r")
11400 (zero_extend:DI
11401 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11402 (match_operand:SI 2 "register_operand" "r"))))]
11403 "TARGET_64BIT && TARGET_BMI2"
11404 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11405 [(set_attr "type" "ishiftx")
11406 (set_attr "mode" "SI")])
11407
11408 (define_insn "*<shift_insn>si3_1_zext"
11409 [(set (match_operand:DI 0 "register_operand" "=r,r")
11410 (zero_extend:DI
11411 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11412 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11415 {
11416 switch (get_attr_type (insn))
11417 {
11418 case TYPE_ISHIFTX:
11419 return "#";
11420
11421 default:
11422 if (operands[2] == const1_rtx
11423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11424 return "<shift>{l}\t%k0";
11425 else
11426 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11427 }
11428 }
11429 [(set_attr "isa" "*,bmi2")
11430 (set_attr "type" "ishift,ishiftx")
11431 (set (attr "length_immediate")
11432 (if_then_else
11433 (and (match_operand 2 "const1_operand")
11434 (ior (match_test "TARGET_SHIFT1")
11435 (match_test "optimize_function_for_size_p (cfun)")))
11436 (const_string "0")
11437 (const_string "*")))
11438 (set_attr "mode" "SI")])
11439
11440 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11441 (define_split
11442 [(set (match_operand:DI 0 "register_operand")
11443 (zero_extend:DI
11444 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11445 (match_operand:QI 2 "register_operand"))))
11446 (clobber (reg:CC FLAGS_REG))]
11447 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11448 [(set (match_dup 0)
11449 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11450 "operands[2] = gen_lowpart (SImode, operands[2]);")
11451
11452 (define_insn "*<shift_insn><mode>3_1"
11453 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11454 (any_shiftrt:SWI12
11455 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11456 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11457 (clobber (reg:CC FLAGS_REG))]
11458 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11459 {
11460 if (operands[2] == const1_rtx
11461 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11462 return "<shift>{<imodesuffix>}\t%0";
11463 else
11464 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11465 }
11466 [(set_attr "type" "ishift")
11467 (set (attr "length_immediate")
11468 (if_then_else
11469 (and (match_operand 2 "const1_operand")
11470 (ior (match_test "TARGET_SHIFT1")
11471 (match_test "optimize_function_for_size_p (cfun)")))
11472 (const_string "0")
11473 (const_string "*")))
11474 (set_attr "mode" "<MODE>")])
11475
11476 (define_insn "*<shift_insn>qi3_1_slp"
11477 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11478 (any_shiftrt:QI (match_dup 0)
11479 (match_operand:QI 1 "nonmemory_operand" "cI")))
11480 (clobber (reg:CC FLAGS_REG))]
11481 "(optimize_function_for_size_p (cfun)
11482 || !TARGET_PARTIAL_REG_STALL
11483 || (operands[1] == const1_rtx
11484 && TARGET_SHIFT1))"
11485 {
11486 if (operands[1] == const1_rtx
11487 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11488 return "<shift>{b}\t%0";
11489 else
11490 return "<shift>{b}\t{%1, %0|%0, %1}";
11491 }
11492 [(set_attr "type" "ishift1")
11493 (set (attr "length_immediate")
11494 (if_then_else
11495 (and (match_operand 1 "const1_operand")
11496 (ior (match_test "TARGET_SHIFT1")
11497 (match_test "optimize_function_for_size_p (cfun)")))
11498 (const_string "0")
11499 (const_string "*")))
11500 (set_attr "mode" "QI")])
11501
11502 ;; This pattern can't accept a variable shift count, since shifts by
11503 ;; zero don't affect the flags. We assume that shifts by constant
11504 ;; zero are optimized away.
11505 (define_insn "*<shift_insn><mode>3_cmp"
11506 [(set (reg FLAGS_REG)
11507 (compare
11508 (any_shiftrt:SWI
11509 (match_operand:SWI 1 "nonimmediate_operand" "0")
11510 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11511 (const_int 0)))
11512 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11513 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11514 "(optimize_function_for_size_p (cfun)
11515 || !TARGET_PARTIAL_FLAG_REG_STALL
11516 || (operands[2] == const1_rtx
11517 && TARGET_SHIFT1))
11518 && ix86_match_ccmode (insn, CCGOCmode)
11519 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11520 {
11521 if (operands[2] == const1_rtx
11522 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11523 return "<shift>{<imodesuffix>}\t%0";
11524 else
11525 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11526 }
11527 [(set_attr "type" "ishift")
11528 (set (attr "length_immediate")
11529 (if_then_else
11530 (and (match_operand 2 "const1_operand")
11531 (ior (match_test "TARGET_SHIFT1")
11532 (match_test "optimize_function_for_size_p (cfun)")))
11533 (const_string "0")
11534 (const_string "*")))
11535 (set_attr "mode" "<MODE>")])
11536
11537 (define_insn "*<shift_insn>si3_cmp_zext"
11538 [(set (reg FLAGS_REG)
11539 (compare
11540 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11541 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11542 (const_int 0)))
11543 (set (match_operand:DI 0 "register_operand" "=r")
11544 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11545 "TARGET_64BIT
11546 && (optimize_function_for_size_p (cfun)
11547 || !TARGET_PARTIAL_FLAG_REG_STALL
11548 || (operands[2] == const1_rtx
11549 && TARGET_SHIFT1))
11550 && ix86_match_ccmode (insn, CCGOCmode)
11551 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11552 {
11553 if (operands[2] == const1_rtx
11554 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11555 return "<shift>{l}\t%k0";
11556 else
11557 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11558 }
11559 [(set_attr "type" "ishift")
11560 (set (attr "length_immediate")
11561 (if_then_else
11562 (and (match_operand 2 "const1_operand")
11563 (ior (match_test "TARGET_SHIFT1")
11564 (match_test "optimize_function_for_size_p (cfun)")))
11565 (const_string "0")
11566 (const_string "*")))
11567 (set_attr "mode" "SI")])
11568
11569 (define_insn "*<shift_insn><mode>3_cconly"
11570 [(set (reg FLAGS_REG)
11571 (compare
11572 (any_shiftrt:SWI
11573 (match_operand:SWI 1 "register_operand" "0")
11574 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11575 (const_int 0)))
11576 (clobber (match_scratch:SWI 0 "=<r>"))]
11577 "(optimize_function_for_size_p (cfun)
11578 || !TARGET_PARTIAL_FLAG_REG_STALL
11579 || (operands[2] == const1_rtx
11580 && TARGET_SHIFT1))
11581 && ix86_match_ccmode (insn, CCGOCmode)"
11582 {
11583 if (operands[2] == const1_rtx
11584 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11585 return "<shift>{<imodesuffix>}\t%0";
11586 else
11587 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11588 }
11589 [(set_attr "type" "ishift")
11590 (set (attr "length_immediate")
11591 (if_then_else
11592 (and (match_operand 2 "const1_operand")
11593 (ior (match_test "TARGET_SHIFT1")
11594 (match_test "optimize_function_for_size_p (cfun)")))
11595 (const_string "0")
11596 (const_string "*")))
11597 (set_attr "mode" "<MODE>")])
11598 \f
11599 ;; Rotate instructions
11600
11601 (define_expand "<rotate_insn>ti3"
11602 [(set (match_operand:TI 0 "register_operand")
11603 (any_rotate:TI (match_operand:TI 1 "register_operand")
11604 (match_operand:QI 2 "nonmemory_operand")))]
11605 "TARGET_64BIT"
11606 {
11607 if (const_1_to_63_operand (operands[2], VOIDmode))
11608 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11609 (operands[0], operands[1], operands[2]));
11610 else
11611 FAIL;
11612
11613 DONE;
11614 })
11615
11616 (define_expand "<rotate_insn>di3"
11617 [(set (match_operand:DI 0 "shiftdi_operand")
11618 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11619 (match_operand:QI 2 "nonmemory_operand")))]
11620 ""
11621 {
11622 if (TARGET_64BIT)
11623 ix86_expand_binary_operator (<CODE>, DImode, operands);
11624 else if (const_1_to_31_operand (operands[2], VOIDmode))
11625 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11626 (operands[0], operands[1], operands[2]));
11627 else
11628 FAIL;
11629
11630 DONE;
11631 })
11632
11633 (define_expand "<rotate_insn><mode>3"
11634 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11635 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11636 (match_operand:QI 2 "nonmemory_operand")))]
11637 ""
11638 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11639
11640 ;; Avoid useless masking of count operand.
11641 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11642 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11643 (any_rotate:SWI48
11644 (match_operand:SWI48 1 "nonimmediate_operand")
11645 (subreg:QI
11646 (and:SI
11647 (match_operand:SI 2 "register_operand" "c")
11648 (match_operand:SI 3 "const_int_operand")) 0)))
11649 (clobber (reg:CC FLAGS_REG))]
11650 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11651 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11652 == GET_MODE_BITSIZE (<MODE>mode)-1
11653 && can_create_pseudo_p ()"
11654 "#"
11655 "&& 1"
11656 [(parallel
11657 [(set (match_dup 0)
11658 (any_rotate:SWI48 (match_dup 1)
11659 (match_dup 2)))
11660 (clobber (reg:CC FLAGS_REG))])]
11661 "operands[2] = gen_lowpart (QImode, operands[2]);")
11662
11663 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11664 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11665 (any_rotate:SWI48
11666 (match_operand:SWI48 1 "nonimmediate_operand")
11667 (and:QI
11668 (match_operand:QI 2 "register_operand" "c")
11669 (match_operand:QI 3 "const_int_operand"))))
11670 (clobber (reg:CC FLAGS_REG))]
11671 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11672 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11673 == GET_MODE_BITSIZE (<MODE>mode)-1
11674 && can_create_pseudo_p ()"
11675 "#"
11676 "&& 1"
11677 [(parallel
11678 [(set (match_dup 0)
11679 (any_rotate:SWI48 (match_dup 1)
11680 (match_dup 2)))
11681 (clobber (reg:CC FLAGS_REG))])])
11682
11683 ;; Implement rotation using two double-precision
11684 ;; shift instructions and a scratch register.
11685
11686 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11687 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11688 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11689 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11690 (clobber (reg:CC FLAGS_REG))
11691 (clobber (match_scratch:DWIH 3 "=&r"))]
11692 ""
11693 "#"
11694 "reload_completed"
11695 [(set (match_dup 3) (match_dup 4))
11696 (parallel
11697 [(set (match_dup 4)
11698 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11699 (lshiftrt:DWIH (match_dup 5)
11700 (minus:QI (match_dup 6) (match_dup 2)))))
11701 (clobber (reg:CC FLAGS_REG))])
11702 (parallel
11703 [(set (match_dup 5)
11704 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11705 (lshiftrt:DWIH (match_dup 3)
11706 (minus:QI (match_dup 6) (match_dup 2)))))
11707 (clobber (reg:CC FLAGS_REG))])]
11708 {
11709 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11710
11711 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11712 })
11713
11714 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11715 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11716 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11717 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11718 (clobber (reg:CC FLAGS_REG))
11719 (clobber (match_scratch:DWIH 3 "=&r"))]
11720 ""
11721 "#"
11722 "reload_completed"
11723 [(set (match_dup 3) (match_dup 4))
11724 (parallel
11725 [(set (match_dup 4)
11726 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11727 (ashift:DWIH (match_dup 5)
11728 (minus:QI (match_dup 6) (match_dup 2)))))
11729 (clobber (reg:CC FLAGS_REG))])
11730 (parallel
11731 [(set (match_dup 5)
11732 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11733 (ashift:DWIH (match_dup 3)
11734 (minus:QI (match_dup 6) (match_dup 2)))))
11735 (clobber (reg:CC FLAGS_REG))])]
11736 {
11737 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11738
11739 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11740 })
11741
11742 (define_mode_attr rorx_immediate_operand
11743 [(SI "const_0_to_31_operand")
11744 (DI "const_0_to_63_operand")])
11745
11746 (define_insn "*bmi2_rorx<mode>3_1"
11747 [(set (match_operand:SWI48 0 "register_operand" "=r")
11748 (rotatert:SWI48
11749 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11750 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11751 "TARGET_BMI2"
11752 "rorx\t{%2, %1, %0|%0, %1, %2}"
11753 [(set_attr "type" "rotatex")
11754 (set_attr "mode" "<MODE>")])
11755
11756 (define_insn "*<rotate_insn><mode>3_1"
11757 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11758 (any_rotate:SWI48
11759 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11760 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11761 (clobber (reg:CC FLAGS_REG))]
11762 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11763 {
11764 switch (get_attr_type (insn))
11765 {
11766 case TYPE_ROTATEX:
11767 return "#";
11768
11769 default:
11770 if (operands[2] == const1_rtx
11771 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11772 return "<rotate>{<imodesuffix>}\t%0";
11773 else
11774 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11775 }
11776 }
11777 [(set_attr "isa" "*,bmi2")
11778 (set_attr "type" "rotate,rotatex")
11779 (set (attr "length_immediate")
11780 (if_then_else
11781 (and (eq_attr "type" "rotate")
11782 (and (match_operand 2 "const1_operand")
11783 (ior (match_test "TARGET_SHIFT1")
11784 (match_test "optimize_function_for_size_p (cfun)"))))
11785 (const_string "0")
11786 (const_string "*")))
11787 (set_attr "mode" "<MODE>")])
11788
11789 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11790 (define_split
11791 [(set (match_operand:SWI48 0 "register_operand")
11792 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11793 (match_operand:QI 2 "const_int_operand")))
11794 (clobber (reg:CC FLAGS_REG))]
11795 "TARGET_BMI2 && reload_completed"
11796 [(set (match_dup 0)
11797 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11798 {
11799 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11800
11801 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11802 })
11803
11804 (define_split
11805 [(set (match_operand:SWI48 0 "register_operand")
11806 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11807 (match_operand:QI 2 "const_int_operand")))
11808 (clobber (reg:CC FLAGS_REG))]
11809 "TARGET_BMI2 && reload_completed"
11810 [(set (match_dup 0)
11811 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11812
11813 (define_insn "*bmi2_rorxsi3_1_zext"
11814 [(set (match_operand:DI 0 "register_operand" "=r")
11815 (zero_extend:DI
11816 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11817 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11818 "TARGET_64BIT && TARGET_BMI2"
11819 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11820 [(set_attr "type" "rotatex")
11821 (set_attr "mode" "SI")])
11822
11823 (define_insn "*<rotate_insn>si3_1_zext"
11824 [(set (match_operand:DI 0 "register_operand" "=r,r")
11825 (zero_extend:DI
11826 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11827 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11828 (clobber (reg:CC FLAGS_REG))]
11829 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11830 {
11831 switch (get_attr_type (insn))
11832 {
11833 case TYPE_ROTATEX:
11834 return "#";
11835
11836 default:
11837 if (operands[2] == const1_rtx
11838 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11839 return "<rotate>{l}\t%k0";
11840 else
11841 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11842 }
11843 }
11844 [(set_attr "isa" "*,bmi2")
11845 (set_attr "type" "rotate,rotatex")
11846 (set (attr "length_immediate")
11847 (if_then_else
11848 (and (eq_attr "type" "rotate")
11849 (and (match_operand 2 "const1_operand")
11850 (ior (match_test "TARGET_SHIFT1")
11851 (match_test "optimize_function_for_size_p (cfun)"))))
11852 (const_string "0")
11853 (const_string "*")))
11854 (set_attr "mode" "SI")])
11855
11856 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11857 (define_split
11858 [(set (match_operand:DI 0 "register_operand")
11859 (zero_extend:DI
11860 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11861 (match_operand:QI 2 "const_int_operand"))))
11862 (clobber (reg:CC FLAGS_REG))]
11863 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11864 [(set (match_dup 0)
11865 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11866 {
11867 int bitsize = GET_MODE_BITSIZE (SImode);
11868
11869 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11870 })
11871
11872 (define_split
11873 [(set (match_operand:DI 0 "register_operand")
11874 (zero_extend:DI
11875 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11876 (match_operand:QI 2 "const_int_operand"))))
11877 (clobber (reg:CC FLAGS_REG))]
11878 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11879 [(set (match_dup 0)
11880 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11881
11882 (define_insn "*<rotate_insn><mode>3_1"
11883 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11884 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11888 {
11889 if (operands[2] == const1_rtx
11890 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11891 return "<rotate>{<imodesuffix>}\t%0";
11892 else
11893 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11894 }
11895 [(set_attr "type" "rotate")
11896 (set (attr "length_immediate")
11897 (if_then_else
11898 (and (match_operand 2 "const1_operand")
11899 (ior (match_test "TARGET_SHIFT1")
11900 (match_test "optimize_function_for_size_p (cfun)")))
11901 (const_string "0")
11902 (const_string "*")))
11903 (set_attr "mode" "<MODE>")])
11904
11905 (define_insn "*<rotate_insn>qi3_1_slp"
11906 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11907 (any_rotate:QI (match_dup 0)
11908 (match_operand:QI 1 "nonmemory_operand" "cI")))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "(optimize_function_for_size_p (cfun)
11911 || !TARGET_PARTIAL_REG_STALL
11912 || (operands[1] == const1_rtx
11913 && TARGET_SHIFT1))"
11914 {
11915 if (operands[1] == const1_rtx
11916 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11917 return "<rotate>{b}\t%0";
11918 else
11919 return "<rotate>{b}\t{%1, %0|%0, %1}";
11920 }
11921 [(set_attr "type" "rotate1")
11922 (set (attr "length_immediate")
11923 (if_then_else
11924 (and (match_operand 1 "const1_operand")
11925 (ior (match_test "TARGET_SHIFT1")
11926 (match_test "optimize_function_for_size_p (cfun)")))
11927 (const_string "0")
11928 (const_string "*")))
11929 (set_attr "mode" "QI")])
11930
11931 (define_split
11932 [(set (match_operand:HI 0 "QIreg_operand")
11933 (any_rotate:HI (match_dup 0) (const_int 8)))
11934 (clobber (reg:CC FLAGS_REG))]
11935 "reload_completed
11936 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11937 [(parallel [(set (strict_low_part (match_dup 0))
11938 (bswap:HI (match_dup 0)))
11939 (clobber (reg:CC FLAGS_REG))])])
11940 \f
11941 ;; Bit set / bit test instructions
11942
11943 ;; %%% bts, btr, btc
11944
11945 ;; These instructions are *slow* when applied to memory.
11946
11947 (define_code_attr btsc [(ior "bts") (xor "btc")])
11948
11949 (define_insn "*<btsc><mode>"
11950 [(set (match_operand:SWI48 0 "register_operand" "=r")
11951 (any_or:SWI48
11952 (ashift:SWI48 (const_int 1)
11953 (match_operand:QI 2 "register_operand" "r"))
11954 (match_operand:SWI48 1 "register_operand" "0")))
11955 (clobber (reg:CC FLAGS_REG))]
11956 "TARGET_USE_BT"
11957 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11958 [(set_attr "type" "alu1")
11959 (set_attr "prefix_0f" "1")
11960 (set_attr "znver1_decode" "double")
11961 (set_attr "mode" "<MODE>")])
11962
11963 ;; Avoid useless masking of count operand.
11964 (define_insn_and_split "*<btsc><mode>_mask"
11965 [(set (match_operand:SWI48 0 "register_operand")
11966 (any_or:SWI48
11967 (ashift:SWI48
11968 (const_int 1)
11969 (subreg:QI
11970 (and:SI
11971 (match_operand:SI 1 "register_operand")
11972 (match_operand:SI 2 "const_int_operand")) 0))
11973 (match_operand:SWI48 3 "register_operand")))
11974 (clobber (reg:CC FLAGS_REG))]
11975 "TARGET_USE_BT
11976 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11977 == GET_MODE_BITSIZE (<MODE>mode)-1
11978 && can_create_pseudo_p ()"
11979 "#"
11980 "&& 1"
11981 [(parallel
11982 [(set (match_dup 0)
11983 (any_or:SWI48
11984 (ashift:SWI48 (const_int 1)
11985 (match_dup 1))
11986 (match_dup 3)))
11987 (clobber (reg:CC FLAGS_REG))])]
11988 "operands[1] = gen_lowpart (QImode, operands[1]);")
11989
11990 (define_insn_and_split "*<btsc><mode>_mask_1"
11991 [(set (match_operand:SWI48 0 "register_operand")
11992 (any_or:SWI48
11993 (ashift:SWI48
11994 (const_int 1)
11995 (and:QI
11996 (match_operand:QI 1 "register_operand")
11997 (match_operand:QI 2 "const_int_operand")))
11998 (match_operand:SWI48 3 "register_operand")))
11999 (clobber (reg:CC FLAGS_REG))]
12000 "TARGET_USE_BT
12001 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12002 == GET_MODE_BITSIZE (<MODE>mode)-1
12003 && can_create_pseudo_p ()"
12004 "#"
12005 "&& 1"
12006 [(parallel
12007 [(set (match_dup 0)
12008 (any_or:SWI48
12009 (ashift:SWI48 (const_int 1)
12010 (match_dup 1))
12011 (match_dup 3)))
12012 (clobber (reg:CC FLAGS_REG))])])
12013
12014 (define_insn "*btr<mode>"
12015 [(set (match_operand:SWI48 0 "register_operand" "=r")
12016 (and:SWI48
12017 (rotate:SWI48 (const_int -2)
12018 (match_operand:QI 2 "register_operand" "r"))
12019 (match_operand:SWI48 1 "register_operand" "0")))
12020 (clobber (reg:CC FLAGS_REG))]
12021 "TARGET_USE_BT"
12022 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12023 [(set_attr "type" "alu1")
12024 (set_attr "prefix_0f" "1")
12025 (set_attr "znver1_decode" "double")
12026 (set_attr "mode" "<MODE>")])
12027
12028 ;; Avoid useless masking of count operand.
12029 (define_insn_and_split "*btr<mode>_mask"
12030 [(set (match_operand:SWI48 0 "register_operand")
12031 (and:SWI48
12032 (rotate:SWI48
12033 (const_int -2)
12034 (subreg:QI
12035 (and:SI
12036 (match_operand:SI 1 "register_operand")
12037 (match_operand:SI 2 "const_int_operand")) 0))
12038 (match_operand:SWI48 3 "register_operand")))
12039 (clobber (reg:CC FLAGS_REG))]
12040 "TARGET_USE_BT
12041 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12042 == GET_MODE_BITSIZE (<MODE>mode)-1
12043 && can_create_pseudo_p ()"
12044 "#"
12045 "&& 1"
12046 [(parallel
12047 [(set (match_dup 0)
12048 (and:SWI48
12049 (rotate:SWI48 (const_int -2)
12050 (match_dup 1))
12051 (match_dup 3)))
12052 (clobber (reg:CC FLAGS_REG))])]
12053 "operands[1] = gen_lowpart (QImode, operands[1]);")
12054
12055 (define_insn_and_split "*btr<mode>_mask_1"
12056 [(set (match_operand:SWI48 0 "register_operand")
12057 (and:SWI48
12058 (rotate:SWI48
12059 (const_int -2)
12060 (and:QI
12061 (match_operand:QI 1 "register_operand")
12062 (match_operand:QI 2 "const_int_operand")))
12063 (match_operand:SWI48 3 "register_operand")))
12064 (clobber (reg:CC FLAGS_REG))]
12065 "TARGET_USE_BT
12066 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12067 == GET_MODE_BITSIZE (<MODE>mode)-1
12068 && can_create_pseudo_p ()"
12069 "#"
12070 "&& 1"
12071 [(parallel
12072 [(set (match_dup 0)
12073 (and:SWI48
12074 (rotate:SWI48 (const_int -2)
12075 (match_dup 1))
12076 (match_dup 3)))
12077 (clobber (reg:CC FLAGS_REG))])])
12078
12079 ;; These instructions are never faster than the corresponding
12080 ;; and/ior/xor operations when using immediate operand, so with
12081 ;; 32-bit there's no point. But in 64-bit, we can't hold the
12082 ;; relevant immediates within the instruction itself, so operating
12083 ;; on bits in the high 32-bits of a register becomes easier.
12084 ;;
12085 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12086 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12087 ;; negdf respectively, so they can never be disabled entirely.
12088
12089 (define_insn "*btsq_imm"
12090 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12091 (const_int 1)
12092 (match_operand 1 "const_0_to_63_operand" "J"))
12093 (const_int 1))
12094 (clobber (reg:CC FLAGS_REG))]
12095 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12096 "bts{q}\t{%1, %0|%0, %1}"
12097 [(set_attr "type" "alu1")
12098 (set_attr "prefix_0f" "1")
12099 (set_attr "znver1_decode" "double")
12100 (set_attr "mode" "DI")])
12101
12102 (define_insn "*btrq_imm"
12103 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12104 (const_int 1)
12105 (match_operand 1 "const_0_to_63_operand" "J"))
12106 (const_int 0))
12107 (clobber (reg:CC FLAGS_REG))]
12108 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12109 "btr{q}\t{%1, %0|%0, %1}"
12110 [(set_attr "type" "alu1")
12111 (set_attr "prefix_0f" "1")
12112 (set_attr "znver1_decode" "double")
12113 (set_attr "mode" "DI")])
12114
12115 (define_insn "*btcq_imm"
12116 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12117 (const_int 1)
12118 (match_operand 1 "const_0_to_63_operand" "J"))
12119 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12120 (clobber (reg:CC FLAGS_REG))]
12121 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12122 "btc{q}\t{%1, %0|%0, %1}"
12123 [(set_attr "type" "alu1")
12124 (set_attr "prefix_0f" "1")
12125 (set_attr "znver1_decode" "double")
12126 (set_attr "mode" "DI")])
12127
12128 ;; Allow Nocona to avoid these instructions if a register is available.
12129
12130 (define_peephole2
12131 [(match_scratch:DI 2 "r")
12132 (parallel [(set (zero_extract:DI
12133 (match_operand:DI 0 "nonimmediate_operand")
12134 (const_int 1)
12135 (match_operand 1 "const_0_to_63_operand"))
12136 (const_int 1))
12137 (clobber (reg:CC FLAGS_REG))])]
12138 "TARGET_64BIT && !TARGET_USE_BT"
12139 [(parallel [(set (match_dup 0)
12140 (ior:DI (match_dup 0) (match_dup 3)))
12141 (clobber (reg:CC FLAGS_REG))])]
12142 {
12143 int i = INTVAL (operands[1]);
12144
12145 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12146
12147 if (!x86_64_immediate_operand (operands[3], DImode))
12148 {
12149 emit_move_insn (operands[2], operands[3]);
12150 operands[3] = operands[2];
12151 }
12152 })
12153
12154 (define_peephole2
12155 [(match_scratch:DI 2 "r")
12156 (parallel [(set (zero_extract:DI
12157 (match_operand:DI 0 "nonimmediate_operand")
12158 (const_int 1)
12159 (match_operand 1 "const_0_to_63_operand"))
12160 (const_int 0))
12161 (clobber (reg:CC FLAGS_REG))])]
12162 "TARGET_64BIT && !TARGET_USE_BT"
12163 [(parallel [(set (match_dup 0)
12164 (and:DI (match_dup 0) (match_dup 3)))
12165 (clobber (reg:CC FLAGS_REG))])]
12166 {
12167 int i = INTVAL (operands[1]);
12168
12169 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12170
12171 if (!x86_64_immediate_operand (operands[3], DImode))
12172 {
12173 emit_move_insn (operands[2], operands[3]);
12174 operands[3] = operands[2];
12175 }
12176 })
12177
12178 (define_peephole2
12179 [(match_scratch:DI 2 "r")
12180 (parallel [(set (zero_extract:DI
12181 (match_operand:DI 0 "nonimmediate_operand")
12182 (const_int 1)
12183 (match_operand 1 "const_0_to_63_operand"))
12184 (not:DI (zero_extract:DI
12185 (match_dup 0) (const_int 1) (match_dup 1))))
12186 (clobber (reg:CC FLAGS_REG))])]
12187 "TARGET_64BIT && !TARGET_USE_BT"
12188 [(parallel [(set (match_dup 0)
12189 (xor:DI (match_dup 0) (match_dup 3)))
12190 (clobber (reg:CC FLAGS_REG))])]
12191 {
12192 int i = INTVAL (operands[1]);
12193
12194 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12195
12196 if (!x86_64_immediate_operand (operands[3], DImode))
12197 {
12198 emit_move_insn (operands[2], operands[3]);
12199 operands[3] = operands[2];
12200 }
12201 })
12202
12203 ;; %%% bt
12204
12205 (define_insn "*bt<mode>"
12206 [(set (reg:CCC FLAGS_REG)
12207 (compare:CCC
12208 (zero_extract:SWI48
12209 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12210 (const_int 1)
12211 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12212 (const_int 0)))]
12213 ""
12214 {
12215 switch (get_attr_mode (insn))
12216 {
12217 case MODE_SI:
12218 return "bt{l}\t{%1, %k0|%k0, %1}";
12219
12220 case MODE_DI:
12221 return "bt{q}\t{%q1, %0|%0, %q1}";
12222
12223 default:
12224 gcc_unreachable ();
12225 }
12226 }
12227 [(set_attr "type" "alu1")
12228 (set_attr "prefix_0f" "1")
12229 (set (attr "mode")
12230 (if_then_else
12231 (and (match_test "CONST_INT_P (operands[1])")
12232 (match_test "INTVAL (operands[1]) < 32"))
12233 (const_string "SI")
12234 (const_string "<MODE>")))])
12235
12236 (define_insn_and_split "*jcc_bt<mode>"
12237 [(set (pc)
12238 (if_then_else (match_operator 0 "bt_comparison_operator"
12239 [(zero_extract:SWI48
12240 (match_operand:SWI48 1 "nonimmediate_operand")
12241 (const_int 1)
12242 (match_operand:SI 2 "nonmemory_operand"))
12243 (const_int 0)])
12244 (label_ref (match_operand 3))
12245 (pc)))
12246 (clobber (reg:CC FLAGS_REG))]
12247 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12248 && (CONST_INT_P (operands[2])
12249 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12250 && INTVAL (operands[2])
12251 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12252 : !memory_operand (operands[1], <MODE>mode))
12253 && can_create_pseudo_p ()"
12254 "#"
12255 "&& 1"
12256 [(set (reg:CCC FLAGS_REG)
12257 (compare:CCC
12258 (zero_extract:SWI48
12259 (match_dup 1)
12260 (const_int 1)
12261 (match_dup 2))
12262 (const_int 0)))
12263 (set (pc)
12264 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12265 (label_ref (match_dup 3))
12266 (pc)))]
12267 {
12268 operands[0] = shallow_copy_rtx (operands[0]);
12269 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12270 })
12271
12272 (define_insn_and_split "*jcc_bt<mode>_1"
12273 [(set (pc)
12274 (if_then_else (match_operator 0 "bt_comparison_operator"
12275 [(zero_extract:SWI48
12276 (match_operand:SWI48 1 "register_operand")
12277 (const_int 1)
12278 (zero_extend:SI
12279 (match_operand:QI 2 "register_operand")))
12280 (const_int 0)])
12281 (label_ref (match_operand 3))
12282 (pc)))
12283 (clobber (reg:CC FLAGS_REG))]
12284 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12285 && can_create_pseudo_p ()"
12286 "#"
12287 "&& 1"
12288 [(set (reg:CCC FLAGS_REG)
12289 (compare:CCC
12290 (zero_extract:SWI48
12291 (match_dup 1)
12292 (const_int 1)
12293 (match_dup 2))
12294 (const_int 0)))
12295 (set (pc)
12296 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12297 (label_ref (match_dup 3))
12298 (pc)))]
12299 {
12300 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12301 operands[0] = shallow_copy_rtx (operands[0]);
12302 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12303 })
12304
12305 ;; Avoid useless masking of bit offset operand.
12306 (define_insn_and_split "*jcc_bt<mode>_mask"
12307 [(set (pc)
12308 (if_then_else (match_operator 0 "bt_comparison_operator"
12309 [(zero_extract:SWI48
12310 (match_operand:SWI48 1 "register_operand")
12311 (const_int 1)
12312 (and:SI
12313 (match_operand:SI 2 "register_operand")
12314 (match_operand 3 "const_int_operand")))])
12315 (label_ref (match_operand 4))
12316 (pc)))
12317 (clobber (reg:CC FLAGS_REG))]
12318 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12319 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12320 == GET_MODE_BITSIZE (<MODE>mode)-1
12321 && can_create_pseudo_p ()"
12322 "#"
12323 "&& 1"
12324 [(set (reg:CCC FLAGS_REG)
12325 (compare:CCC
12326 (zero_extract:SWI48
12327 (match_dup 1)
12328 (const_int 1)
12329 (match_dup 2))
12330 (const_int 0)))
12331 (set (pc)
12332 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12333 (label_ref (match_dup 4))
12334 (pc)))]
12335 {
12336 operands[0] = shallow_copy_rtx (operands[0]);
12337 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12338 })
12339 \f
12340 ;; Store-flag instructions.
12341
12342 ;; For all sCOND expanders, also expand the compare or test insn that
12343 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12344
12345 (define_insn_and_split "*setcc_di_1"
12346 [(set (match_operand:DI 0 "register_operand" "=q")
12347 (match_operator:DI 1 "ix86_comparison_operator"
12348 [(reg FLAGS_REG) (const_int 0)]))]
12349 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12350 "#"
12351 "&& reload_completed"
12352 [(set (match_dup 2) (match_dup 1))
12353 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12354 {
12355 operands[1] = shallow_copy_rtx (operands[1]);
12356 PUT_MODE (operands[1], QImode);
12357 operands[2] = gen_lowpart (QImode, operands[0]);
12358 })
12359
12360 (define_insn_and_split "*setcc_si_1_and"
12361 [(set (match_operand:SI 0 "register_operand" "=q")
12362 (match_operator:SI 1 "ix86_comparison_operator"
12363 [(reg FLAGS_REG) (const_int 0)]))
12364 (clobber (reg:CC FLAGS_REG))]
12365 "!TARGET_PARTIAL_REG_STALL
12366 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12367 "#"
12368 "&& reload_completed"
12369 [(set (match_dup 2) (match_dup 1))
12370 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12371 (clobber (reg:CC FLAGS_REG))])]
12372 {
12373 operands[1] = shallow_copy_rtx (operands[1]);
12374 PUT_MODE (operands[1], QImode);
12375 operands[2] = gen_lowpart (QImode, operands[0]);
12376 })
12377
12378 (define_insn_and_split "*setcc_si_1_movzbl"
12379 [(set (match_operand:SI 0 "register_operand" "=q")
12380 (match_operator:SI 1 "ix86_comparison_operator"
12381 [(reg FLAGS_REG) (const_int 0)]))]
12382 "!TARGET_PARTIAL_REG_STALL
12383 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12384 "#"
12385 "&& reload_completed"
12386 [(set (match_dup 2) (match_dup 1))
12387 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12388 {
12389 operands[1] = shallow_copy_rtx (operands[1]);
12390 PUT_MODE (operands[1], QImode);
12391 operands[2] = gen_lowpart (QImode, operands[0]);
12392 })
12393
12394 (define_insn "*setcc_qi"
12395 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12396 (match_operator:QI 1 "ix86_comparison_operator"
12397 [(reg FLAGS_REG) (const_int 0)]))]
12398 ""
12399 "set%C1\t%0"
12400 [(set_attr "type" "setcc")
12401 (set_attr "mode" "QI")])
12402
12403 (define_insn "*setcc_qi_slp"
12404 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12405 (match_operator:QI 1 "ix86_comparison_operator"
12406 [(reg FLAGS_REG) (const_int 0)]))]
12407 ""
12408 "set%C1\t%0"
12409 [(set_attr "type" "setcc")
12410 (set_attr "mode" "QI")])
12411
12412 ;; In general it is not safe to assume too much about CCmode registers,
12413 ;; so simplify-rtx stops when it sees a second one. Under certain
12414 ;; conditions this is safe on x86, so help combine not create
12415 ;;
12416 ;; seta %al
12417 ;; testb %al, %al
12418 ;; sete %al
12419
12420 (define_split
12421 [(set (match_operand:QI 0 "nonimmediate_operand")
12422 (ne:QI (match_operator 1 "ix86_comparison_operator"
12423 [(reg FLAGS_REG) (const_int 0)])
12424 (const_int 0)))]
12425 ""
12426 [(set (match_dup 0) (match_dup 1))]
12427 {
12428 operands[1] = shallow_copy_rtx (operands[1]);
12429 PUT_MODE (operands[1], QImode);
12430 })
12431
12432 (define_split
12433 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12434 (ne:QI (match_operator 1 "ix86_comparison_operator"
12435 [(reg FLAGS_REG) (const_int 0)])
12436 (const_int 0)))]
12437 ""
12438 [(set (match_dup 0) (match_dup 1))]
12439 {
12440 operands[1] = shallow_copy_rtx (operands[1]);
12441 PUT_MODE (operands[1], QImode);
12442 })
12443
12444 (define_split
12445 [(set (match_operand:QI 0 "nonimmediate_operand")
12446 (eq:QI (match_operator 1 "ix86_comparison_operator"
12447 [(reg FLAGS_REG) (const_int 0)])
12448 (const_int 0)))]
12449 ""
12450 [(set (match_dup 0) (match_dup 1))]
12451 {
12452 operands[1] = shallow_copy_rtx (operands[1]);
12453 PUT_MODE (operands[1], QImode);
12454 PUT_CODE (operands[1],
12455 ix86_reverse_condition (GET_CODE (operands[1]),
12456 GET_MODE (XEXP (operands[1], 0))));
12457
12458 /* Make sure that (a) the CCmode we have for the flags is strong
12459 enough for the reversed compare or (b) we have a valid FP compare. */
12460 if (! ix86_comparison_operator (operands[1], VOIDmode))
12461 FAIL;
12462 })
12463
12464 (define_split
12465 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12466 (eq:QI (match_operator 1 "ix86_comparison_operator"
12467 [(reg FLAGS_REG) (const_int 0)])
12468 (const_int 0)))]
12469 ""
12470 [(set (match_dup 0) (match_dup 1))]
12471 {
12472 operands[1] = shallow_copy_rtx (operands[1]);
12473 PUT_MODE (operands[1], QImode);
12474 PUT_CODE (operands[1],
12475 ix86_reverse_condition (GET_CODE (operands[1]),
12476 GET_MODE (XEXP (operands[1], 0))));
12477
12478 /* Make sure that (a) the CCmode we have for the flags is strong
12479 enough for the reversed compare or (b) we have a valid FP compare. */
12480 if (! ix86_comparison_operator (operands[1], VOIDmode))
12481 FAIL;
12482 })
12483
12484 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12485 ;; subsequent logical operations are used to imitate conditional moves.
12486 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12487 ;; it directly.
12488
12489 (define_insn "setcc_<mode>_sse"
12490 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12491 (match_operator:MODEF 3 "sse_comparison_operator"
12492 [(match_operand:MODEF 1 "register_operand" "0,x")
12493 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12494 "SSE_FLOAT_MODE_P (<MODE>mode)"
12495 "@
12496 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12497 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12498 [(set_attr "isa" "noavx,avx")
12499 (set_attr "type" "ssecmp")
12500 (set_attr "length_immediate" "1")
12501 (set_attr "prefix" "orig,vex")
12502 (set_attr "mode" "<MODE>")])
12503 \f
12504 ;; Basic conditional jump instructions.
12505 ;; We ignore the overflow flag for signed branch instructions.
12506
12507 (define_insn "*jcc"
12508 [(set (pc)
12509 (if_then_else (match_operator 1 "ix86_comparison_operator"
12510 [(reg FLAGS_REG) (const_int 0)])
12511 (label_ref (match_operand 0))
12512 (pc)))]
12513 ""
12514 "%!%+j%C1\t%l0"
12515 [(set_attr "type" "ibr")
12516 (set_attr "modrm" "0")
12517 (set (attr "length")
12518 (if_then_else
12519 (and (ge (minus (match_dup 0) (pc))
12520 (const_int -126))
12521 (lt (minus (match_dup 0) (pc))
12522 (const_int 128)))
12523 (const_int 2)
12524 (const_int 6)))
12525 (set_attr "maybe_prefix_bnd" "1")])
12526
12527 ;; In general it is not safe to assume too much about CCmode registers,
12528 ;; so simplify-rtx stops when it sees a second one. Under certain
12529 ;; conditions this is safe on x86, so help combine not create
12530 ;;
12531 ;; seta %al
12532 ;; testb %al, %al
12533 ;; je Lfoo
12534
12535 (define_split
12536 [(set (pc)
12537 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12538 [(reg FLAGS_REG) (const_int 0)])
12539 (const_int 0))
12540 (label_ref (match_operand 1))
12541 (pc)))]
12542 ""
12543 [(set (pc)
12544 (if_then_else (match_dup 0)
12545 (label_ref (match_dup 1))
12546 (pc)))]
12547 {
12548 operands[0] = shallow_copy_rtx (operands[0]);
12549 PUT_MODE (operands[0], VOIDmode);
12550 })
12551
12552 (define_split
12553 [(set (pc)
12554 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12555 [(reg FLAGS_REG) (const_int 0)])
12556 (const_int 0))
12557 (label_ref (match_operand 1))
12558 (pc)))]
12559 ""
12560 [(set (pc)
12561 (if_then_else (match_dup 0)
12562 (label_ref (match_dup 1))
12563 (pc)))]
12564 {
12565 operands[0] = shallow_copy_rtx (operands[0]);
12566 PUT_MODE (operands[0], VOIDmode);
12567 PUT_CODE (operands[0],
12568 ix86_reverse_condition (GET_CODE (operands[0]),
12569 GET_MODE (XEXP (operands[0], 0))));
12570
12571 /* Make sure that (a) the CCmode we have for the flags is strong
12572 enough for the reversed compare or (b) we have a valid FP compare. */
12573 if (! ix86_comparison_operator (operands[0], VOIDmode))
12574 FAIL;
12575 })
12576 \f
12577 ;; Unconditional and other jump instructions
12578
12579 (define_insn "jump"
12580 [(set (pc)
12581 (label_ref (match_operand 0)))]
12582 ""
12583 "%!jmp\t%l0"
12584 [(set_attr "type" "ibr")
12585 (set_attr "modrm" "0")
12586 (set (attr "length")
12587 (if_then_else
12588 (and (ge (minus (match_dup 0) (pc))
12589 (const_int -126))
12590 (lt (minus (match_dup 0) (pc))
12591 (const_int 128)))
12592 (const_int 2)
12593 (const_int 5)))
12594 (set_attr "maybe_prefix_bnd" "1")])
12595
12596 (define_expand "indirect_jump"
12597 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12598 ""
12599 {
12600 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12601 operands[0] = convert_memory_address (word_mode, operands[0]);
12602 cfun->machine->has_local_indirect_jump = true;
12603 })
12604
12605 (define_insn "*indirect_jump"
12606 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12607 ""
12608 "* return ix86_output_indirect_jmp (operands[0]);"
12609 [(set (attr "type")
12610 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12611 != indirect_branch_keep)")
12612 (const_string "multi")
12613 (const_string "ibr")))
12614 (set_attr "length_immediate" "0")
12615 (set_attr "maybe_prefix_bnd" "1")])
12616
12617 (define_expand "tablejump"
12618 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12619 (use (label_ref (match_operand 1)))])]
12620 ""
12621 {
12622 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12623 relative. Convert the relative address to an absolute address. */
12624 if (flag_pic)
12625 {
12626 rtx op0, op1;
12627 enum rtx_code code;
12628
12629 /* We can't use @GOTOFF for text labels on VxWorks;
12630 see gotoff_operand. */
12631 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12632 {
12633 code = PLUS;
12634 op0 = operands[0];
12635 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12636 }
12637 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12638 {
12639 code = PLUS;
12640 op0 = operands[0];
12641 op1 = pic_offset_table_rtx;
12642 }
12643 else
12644 {
12645 code = MINUS;
12646 op0 = pic_offset_table_rtx;
12647 op1 = operands[0];
12648 }
12649
12650 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12651 OPTAB_DIRECT);
12652 }
12653
12654 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12655 operands[0] = convert_memory_address (word_mode, operands[0]);
12656 cfun->machine->has_local_indirect_jump = true;
12657 })
12658
12659 (define_insn "*tablejump_1"
12660 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12661 (use (label_ref (match_operand 1)))]
12662 ""
12663 "* return ix86_output_indirect_jmp (operands[0]);"
12664 [(set (attr "type")
12665 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12666 != indirect_branch_keep)")
12667 (const_string "multi")
12668 (const_string "ibr")))
12669 (set_attr "length_immediate" "0")
12670 (set_attr "maybe_prefix_bnd" "1")])
12671 \f
12672 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12673
12674 (define_peephole2
12675 [(set (reg FLAGS_REG) (match_operand 0))
12676 (set (match_operand:QI 1 "register_operand")
12677 (match_operator:QI 2 "ix86_comparison_operator"
12678 [(reg FLAGS_REG) (const_int 0)]))
12679 (set (match_operand 3 "any_QIreg_operand")
12680 (zero_extend (match_dup 1)))]
12681 "(peep2_reg_dead_p (3, operands[1])
12682 || operands_match_p (operands[1], operands[3]))
12683 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12684 && peep2_regno_dead_p (0, FLAGS_REG)"
12685 [(set (match_dup 4) (match_dup 0))
12686 (set (strict_low_part (match_dup 5))
12687 (match_dup 2))]
12688 {
12689 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12690 operands[5] = gen_lowpart (QImode, operands[3]);
12691 ix86_expand_clear (operands[3]);
12692 })
12693
12694 (define_peephole2
12695 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12696 (match_operand 4)])
12697 (set (match_operand:QI 1 "register_operand")
12698 (match_operator:QI 2 "ix86_comparison_operator"
12699 [(reg FLAGS_REG) (const_int 0)]))
12700 (set (match_operand 3 "any_QIreg_operand")
12701 (zero_extend (match_dup 1)))]
12702 "(peep2_reg_dead_p (3, operands[1])
12703 || operands_match_p (operands[1], operands[3]))
12704 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12705 && ! reg_set_p (operands[3], operands[4])
12706 && peep2_regno_dead_p (0, FLAGS_REG)"
12707 [(parallel [(set (match_dup 5) (match_dup 0))
12708 (match_dup 4)])
12709 (set (strict_low_part (match_dup 6))
12710 (match_dup 2))]
12711 {
12712 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12713 operands[6] = gen_lowpart (QImode, operands[3]);
12714 ix86_expand_clear (operands[3]);
12715 })
12716
12717 (define_peephole2
12718 [(set (reg FLAGS_REG) (match_operand 0))
12719 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12720 (match_operand 5)])
12721 (set (match_operand:QI 2 "register_operand")
12722 (match_operator:QI 3 "ix86_comparison_operator"
12723 [(reg FLAGS_REG) (const_int 0)]))
12724 (set (match_operand 4 "any_QIreg_operand")
12725 (zero_extend (match_dup 2)))]
12726 "(peep2_reg_dead_p (4, operands[2])
12727 || operands_match_p (operands[2], operands[4]))
12728 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12729 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12730 && ! reg_set_p (operands[4], operands[5])
12731 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12732 && peep2_regno_dead_p (0, FLAGS_REG)"
12733 [(set (match_dup 6) (match_dup 0))
12734 (parallel [(set (match_dup 7) (match_dup 1))
12735 (match_dup 5)])
12736 (set (strict_low_part (match_dup 8))
12737 (match_dup 3))]
12738 {
12739 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12740 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12741 operands[8] = gen_lowpart (QImode, operands[4]);
12742 ix86_expand_clear (operands[4]);
12743 })
12744
12745 ;; Similar, but match zero extend with andsi3.
12746
12747 (define_peephole2
12748 [(set (reg FLAGS_REG) (match_operand 0))
12749 (set (match_operand:QI 1 "register_operand")
12750 (match_operator:QI 2 "ix86_comparison_operator"
12751 [(reg FLAGS_REG) (const_int 0)]))
12752 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12753 (and:SI (match_dup 3) (const_int 255)))
12754 (clobber (reg:CC FLAGS_REG))])]
12755 "REGNO (operands[1]) == REGNO (operands[3])
12756 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12757 && peep2_regno_dead_p (0, FLAGS_REG)"
12758 [(set (match_dup 4) (match_dup 0))
12759 (set (strict_low_part (match_dup 5))
12760 (match_dup 2))]
12761 {
12762 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12763 operands[5] = gen_lowpart (QImode, operands[3]);
12764 ix86_expand_clear (operands[3]);
12765 })
12766
12767 (define_peephole2
12768 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12769 (match_operand 4)])
12770 (set (match_operand:QI 1 "register_operand")
12771 (match_operator:QI 2 "ix86_comparison_operator"
12772 [(reg FLAGS_REG) (const_int 0)]))
12773 (parallel [(set (match_operand 3 "any_QIreg_operand")
12774 (zero_extend (match_dup 1)))
12775 (clobber (reg:CC FLAGS_REG))])]
12776 "(peep2_reg_dead_p (3, operands[1])
12777 || operands_match_p (operands[1], operands[3]))
12778 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12779 && ! reg_set_p (operands[3], operands[4])
12780 && peep2_regno_dead_p (0, FLAGS_REG)"
12781 [(parallel [(set (match_dup 5) (match_dup 0))
12782 (match_dup 4)])
12783 (set (strict_low_part (match_dup 6))
12784 (match_dup 2))]
12785 {
12786 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12787 operands[6] = gen_lowpart (QImode, operands[3]);
12788 ix86_expand_clear (operands[3]);
12789 })
12790
12791 (define_peephole2
12792 [(set (reg FLAGS_REG) (match_operand 0))
12793 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12794 (match_operand 5)])
12795 (set (match_operand:QI 2 "register_operand")
12796 (match_operator:QI 3 "ix86_comparison_operator"
12797 [(reg FLAGS_REG) (const_int 0)]))
12798 (parallel [(set (match_operand 4 "any_QIreg_operand")
12799 (zero_extend (match_dup 2)))
12800 (clobber (reg:CC FLAGS_REG))])]
12801 "(peep2_reg_dead_p (4, operands[2])
12802 || operands_match_p (operands[2], operands[4]))
12803 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12804 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12805 && ! reg_set_p (operands[4], operands[5])
12806 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12807 && peep2_regno_dead_p (0, FLAGS_REG)"
12808 [(set (match_dup 6) (match_dup 0))
12809 (parallel [(set (match_dup 7) (match_dup 1))
12810 (match_dup 5)])
12811 (set (strict_low_part (match_dup 8))
12812 (match_dup 3))]
12813 {
12814 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12815 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12816 operands[8] = gen_lowpart (QImode, operands[4]);
12817 ix86_expand_clear (operands[4]);
12818 })
12819 \f
12820 ;; Call instructions.
12821
12822 ;; The predicates normally associated with named expanders are not properly
12823 ;; checked for calls. This is a bug in the generic code, but it isn't that
12824 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12825
12826 ;; P6 processors will jump to the address after the decrement when %esp
12827 ;; is used as a call operand, so they will execute return address as a code.
12828 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12829
12830 ;; Register constraint for call instruction.
12831 (define_mode_attr c [(SI "l") (DI "r")])
12832
12833 ;; Call subroutine returning no value.
12834
12835 (define_expand "call"
12836 [(call (match_operand:QI 0)
12837 (match_operand 1))
12838 (use (match_operand 2))]
12839 ""
12840 {
12841 ix86_expand_call (NULL, operands[0], operands[1],
12842 operands[2], NULL, false);
12843 DONE;
12844 })
12845
12846 (define_expand "sibcall"
12847 [(call (match_operand:QI 0)
12848 (match_operand 1))
12849 (use (match_operand 2))]
12850 ""
12851 {
12852 ix86_expand_call (NULL, operands[0], operands[1],
12853 operands[2], NULL, true);
12854 DONE;
12855 })
12856
12857 (define_insn "*call"
12858 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12859 (match_operand 1))]
12860 "!SIBLING_CALL_P (insn)"
12861 "* return ix86_output_call_insn (insn, operands[0]);"
12862 [(set_attr "type" "call")])
12863
12864 ;; This covers both call and sibcall since only GOT slot is allowed.
12865 (define_insn "*call_got_x32"
12866 [(call (mem:QI (zero_extend:DI
12867 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12868 (match_operand 1))]
12869 "TARGET_X32"
12870 {
12871 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12872 return ix86_output_call_insn (insn, fnaddr);
12873 }
12874 [(set_attr "type" "call")])
12875
12876 ;; Since sibcall never returns, we can only use call-clobbered register
12877 ;; as GOT base.
12878 (define_insn "*sibcall_GOT_32"
12879 [(call (mem:QI
12880 (mem:SI (plus:SI
12881 (match_operand:SI 0 "register_no_elim_operand" "U")
12882 (match_operand:SI 1 "GOT32_symbol_operand"))))
12883 (match_operand 2))]
12884 "!TARGET_MACHO
12885 && !TARGET_64BIT
12886 && !TARGET_INDIRECT_BRANCH_REGISTER
12887 && SIBLING_CALL_P (insn)"
12888 {
12889 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12890 fnaddr = gen_const_mem (SImode, fnaddr);
12891 return ix86_output_call_insn (insn, fnaddr);
12892 }
12893 [(set_attr "type" "call")])
12894
12895 (define_insn "*sibcall"
12896 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12897 (match_operand 1))]
12898 "SIBLING_CALL_P (insn)"
12899 "* return ix86_output_call_insn (insn, operands[0]);"
12900 [(set_attr "type" "call")])
12901
12902 (define_insn "*sibcall_memory"
12903 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12904 (match_operand 1))
12905 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12906 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12907 "* return ix86_output_call_insn (insn, operands[0]);"
12908 [(set_attr "type" "call")])
12909
12910 (define_peephole2
12911 [(set (match_operand:W 0 "register_operand")
12912 (match_operand:W 1 "memory_operand"))
12913 (call (mem:QI (match_dup 0))
12914 (match_operand 3))]
12915 "!TARGET_X32
12916 && !TARGET_INDIRECT_BRANCH_REGISTER
12917 && SIBLING_CALL_P (peep2_next_insn (1))
12918 && !reg_mentioned_p (operands[0],
12919 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12920 [(parallel [(call (mem:QI (match_dup 1))
12921 (match_dup 3))
12922 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12923
12924 (define_peephole2
12925 [(set (match_operand:W 0 "register_operand")
12926 (match_operand:W 1 "memory_operand"))
12927 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12928 (call (mem:QI (match_dup 0))
12929 (match_operand 3))]
12930 "!TARGET_X32
12931 && !TARGET_INDIRECT_BRANCH_REGISTER
12932 && SIBLING_CALL_P (peep2_next_insn (2))
12933 && !reg_mentioned_p (operands[0],
12934 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12935 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12936 (parallel [(call (mem:QI (match_dup 1))
12937 (match_dup 3))
12938 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12939
12940 (define_expand "call_pop"
12941 [(parallel [(call (match_operand:QI 0)
12942 (match_operand:SI 1))
12943 (set (reg:SI SP_REG)
12944 (plus:SI (reg:SI SP_REG)
12945 (match_operand:SI 3)))])]
12946 "!TARGET_64BIT"
12947 {
12948 ix86_expand_call (NULL, operands[0], operands[1],
12949 operands[2], operands[3], false);
12950 DONE;
12951 })
12952
12953 (define_insn "*call_pop"
12954 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12955 (match_operand 1))
12956 (set (reg:SI SP_REG)
12957 (plus:SI (reg:SI SP_REG)
12958 (match_operand:SI 2 "immediate_operand" "i")))]
12959 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12960 "* return ix86_output_call_insn (insn, operands[0]);"
12961 [(set_attr "type" "call")])
12962
12963 (define_insn "*sibcall_pop"
12964 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12965 (match_operand 1))
12966 (set (reg:SI SP_REG)
12967 (plus:SI (reg:SI SP_REG)
12968 (match_operand:SI 2 "immediate_operand" "i")))]
12969 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12970 "* return ix86_output_call_insn (insn, operands[0]);"
12971 [(set_attr "type" "call")])
12972
12973 (define_insn "*sibcall_pop_memory"
12974 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12975 (match_operand 1))
12976 (set (reg:SI SP_REG)
12977 (plus:SI (reg:SI SP_REG)
12978 (match_operand:SI 2 "immediate_operand" "i")))
12979 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12980 "!TARGET_64BIT"
12981 "* return ix86_output_call_insn (insn, operands[0]);"
12982 [(set_attr "type" "call")])
12983
12984 (define_peephole2
12985 [(set (match_operand:SI 0 "register_operand")
12986 (match_operand:SI 1 "memory_operand"))
12987 (parallel [(call (mem:QI (match_dup 0))
12988 (match_operand 3))
12989 (set (reg:SI SP_REG)
12990 (plus:SI (reg:SI SP_REG)
12991 (match_operand:SI 4 "immediate_operand")))])]
12992 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12993 && !reg_mentioned_p (operands[0],
12994 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12995 [(parallel [(call (mem:QI (match_dup 1))
12996 (match_dup 3))
12997 (set (reg:SI SP_REG)
12998 (plus:SI (reg:SI SP_REG)
12999 (match_dup 4)))
13000 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13001
13002 (define_peephole2
13003 [(set (match_operand:SI 0 "register_operand")
13004 (match_operand:SI 1 "memory_operand"))
13005 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13006 (parallel [(call (mem:QI (match_dup 0))
13007 (match_operand 3))
13008 (set (reg:SI SP_REG)
13009 (plus:SI (reg:SI SP_REG)
13010 (match_operand:SI 4 "immediate_operand")))])]
13011 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13012 && !reg_mentioned_p (operands[0],
13013 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13014 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13015 (parallel [(call (mem:QI (match_dup 1))
13016 (match_dup 3))
13017 (set (reg:SI SP_REG)
13018 (plus:SI (reg:SI SP_REG)
13019 (match_dup 4)))
13020 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13021
13022 ;; Combining simple memory jump instruction
13023
13024 (define_peephole2
13025 [(set (match_operand:W 0 "register_operand")
13026 (match_operand:W 1 "memory_operand"))
13027 (set (pc) (match_dup 0))]
13028 "!TARGET_X32
13029 && !TARGET_INDIRECT_BRANCH_REGISTER
13030 && peep2_reg_dead_p (2, operands[0])"
13031 [(set (pc) (match_dup 1))])
13032
13033 ;; Call subroutine, returning value in operand 0
13034
13035 (define_expand "call_value"
13036 [(set (match_operand 0)
13037 (call (match_operand:QI 1)
13038 (match_operand 2)))
13039 (use (match_operand 3))]
13040 ""
13041 {
13042 ix86_expand_call (operands[0], operands[1], operands[2],
13043 operands[3], NULL, false);
13044 DONE;
13045 })
13046
13047 (define_expand "sibcall_value"
13048 [(set (match_operand 0)
13049 (call (match_operand:QI 1)
13050 (match_operand 2)))
13051 (use (match_operand 3))]
13052 ""
13053 {
13054 ix86_expand_call (operands[0], operands[1], operands[2],
13055 operands[3], NULL, true);
13056 DONE;
13057 })
13058
13059 (define_insn "*call_value"
13060 [(set (match_operand 0)
13061 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13062 (match_operand 2)))]
13063 "!SIBLING_CALL_P (insn)"
13064 "* return ix86_output_call_insn (insn, operands[1]);"
13065 [(set_attr "type" "callv")])
13066
13067 ;; This covers both call and sibcall since only GOT slot is allowed.
13068 (define_insn "*call_value_got_x32"
13069 [(set (match_operand 0)
13070 (call (mem:QI
13071 (zero_extend:DI
13072 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13073 (match_operand 2)))]
13074 "TARGET_X32"
13075 {
13076 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13077 return ix86_output_call_insn (insn, fnaddr);
13078 }
13079 [(set_attr "type" "callv")])
13080
13081 ;; Since sibcall never returns, we can only use call-clobbered register
13082 ;; as GOT base.
13083 (define_insn "*sibcall_value_GOT_32"
13084 [(set (match_operand 0)
13085 (call (mem:QI
13086 (mem:SI (plus:SI
13087 (match_operand:SI 1 "register_no_elim_operand" "U")
13088 (match_operand:SI 2 "GOT32_symbol_operand"))))
13089 (match_operand 3)))]
13090 "!TARGET_MACHO
13091 && !TARGET_64BIT
13092 && !TARGET_INDIRECT_BRANCH_REGISTER
13093 && SIBLING_CALL_P (insn)"
13094 {
13095 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13096 fnaddr = gen_const_mem (SImode, fnaddr);
13097 return ix86_output_call_insn (insn, fnaddr);
13098 }
13099 [(set_attr "type" "callv")])
13100
13101 (define_insn "*sibcall_value"
13102 [(set (match_operand 0)
13103 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13104 (match_operand 2)))]
13105 "SIBLING_CALL_P (insn)"
13106 "* return ix86_output_call_insn (insn, operands[1]);"
13107 [(set_attr "type" "callv")])
13108
13109 (define_insn "*sibcall_value_memory"
13110 [(set (match_operand 0)
13111 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13112 (match_operand 2)))
13113 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13114 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13115 "* return ix86_output_call_insn (insn, operands[1]);"
13116 [(set_attr "type" "callv")])
13117
13118 (define_peephole2
13119 [(set (match_operand:W 0 "register_operand")
13120 (match_operand:W 1 "memory_operand"))
13121 (set (match_operand 2)
13122 (call (mem:QI (match_dup 0))
13123 (match_operand 3)))]
13124 "!TARGET_X32
13125 && !TARGET_INDIRECT_BRANCH_REGISTER
13126 && SIBLING_CALL_P (peep2_next_insn (1))
13127 && !reg_mentioned_p (operands[0],
13128 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13129 [(parallel [(set (match_dup 2)
13130 (call (mem:QI (match_dup 1))
13131 (match_dup 3)))
13132 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13133
13134 (define_peephole2
13135 [(set (match_operand:W 0 "register_operand")
13136 (match_operand:W 1 "memory_operand"))
13137 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13138 (set (match_operand 2)
13139 (call (mem:QI (match_dup 0))
13140 (match_operand 3)))]
13141 "!TARGET_X32
13142 && !TARGET_INDIRECT_BRANCH_REGISTER
13143 && SIBLING_CALL_P (peep2_next_insn (2))
13144 && !reg_mentioned_p (operands[0],
13145 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13146 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13147 (parallel [(set (match_dup 2)
13148 (call (mem:QI (match_dup 1))
13149 (match_dup 3)))
13150 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13151
13152 (define_expand "call_value_pop"
13153 [(parallel [(set (match_operand 0)
13154 (call (match_operand:QI 1)
13155 (match_operand:SI 2)))
13156 (set (reg:SI SP_REG)
13157 (plus:SI (reg:SI SP_REG)
13158 (match_operand:SI 4)))])]
13159 "!TARGET_64BIT"
13160 {
13161 ix86_expand_call (operands[0], operands[1], operands[2],
13162 operands[3], operands[4], false);
13163 DONE;
13164 })
13165
13166 (define_insn "*call_value_pop"
13167 [(set (match_operand 0)
13168 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13169 (match_operand 2)))
13170 (set (reg:SI SP_REG)
13171 (plus:SI (reg:SI SP_REG)
13172 (match_operand:SI 3 "immediate_operand" "i")))]
13173 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13174 "* return ix86_output_call_insn (insn, operands[1]);"
13175 [(set_attr "type" "callv")])
13176
13177 (define_insn "*sibcall_value_pop"
13178 [(set (match_operand 0)
13179 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13180 (match_operand 2)))
13181 (set (reg:SI SP_REG)
13182 (plus:SI (reg:SI SP_REG)
13183 (match_operand:SI 3 "immediate_operand" "i")))]
13184 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13185 "* return ix86_output_call_insn (insn, operands[1]);"
13186 [(set_attr "type" "callv")])
13187
13188 (define_insn "*sibcall_value_pop_memory"
13189 [(set (match_operand 0)
13190 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13191 (match_operand 2)))
13192 (set (reg:SI SP_REG)
13193 (plus:SI (reg:SI SP_REG)
13194 (match_operand:SI 3 "immediate_operand" "i")))
13195 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13196 "!TARGET_64BIT"
13197 "* return ix86_output_call_insn (insn, operands[1]);"
13198 [(set_attr "type" "callv")])
13199
13200 (define_peephole2
13201 [(set (match_operand:SI 0 "register_operand")
13202 (match_operand:SI 1 "memory_operand"))
13203 (parallel [(set (match_operand 2)
13204 (call (mem:QI (match_dup 0))
13205 (match_operand 3)))
13206 (set (reg:SI SP_REG)
13207 (plus:SI (reg:SI SP_REG)
13208 (match_operand:SI 4 "immediate_operand")))])]
13209 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13210 && !reg_mentioned_p (operands[0],
13211 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13212 [(parallel [(set (match_dup 2)
13213 (call (mem:QI (match_dup 1))
13214 (match_dup 3)))
13215 (set (reg:SI SP_REG)
13216 (plus:SI (reg:SI SP_REG)
13217 (match_dup 4)))
13218 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13219
13220 (define_peephole2
13221 [(set (match_operand:SI 0 "register_operand")
13222 (match_operand:SI 1 "memory_operand"))
13223 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13224 (parallel [(set (match_operand 2)
13225 (call (mem:QI (match_dup 0))
13226 (match_operand 3)))
13227 (set (reg:SI SP_REG)
13228 (plus:SI (reg:SI SP_REG)
13229 (match_operand:SI 4 "immediate_operand")))])]
13230 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13231 && !reg_mentioned_p (operands[0],
13232 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13233 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13234 (parallel [(set (match_dup 2)
13235 (call (mem:QI (match_dup 1))
13236 (match_dup 3)))
13237 (set (reg:SI SP_REG)
13238 (plus:SI (reg:SI SP_REG)
13239 (match_dup 4)))
13240 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13241
13242 ;; Call subroutine returning any type.
13243
13244 (define_expand "untyped_call"
13245 [(parallel [(call (match_operand 0)
13246 (const_int 0))
13247 (match_operand 1)
13248 (match_operand 2)])]
13249 ""
13250 {
13251 int i;
13252
13253 /* In order to give reg-stack an easier job in validating two
13254 coprocessor registers as containing a possible return value,
13255 simply pretend the untyped call returns a complex long double
13256 value.
13257
13258 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13259 and should have the default ABI. */
13260
13261 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13262 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13263 operands[0], const0_rtx,
13264 GEN_INT ((TARGET_64BIT
13265 ? (ix86_abi == SYSV_ABI
13266 ? X86_64_SSE_REGPARM_MAX
13267 : X86_64_MS_SSE_REGPARM_MAX)
13268 : X86_32_SSE_REGPARM_MAX)
13269 - 1),
13270 NULL, false);
13271
13272 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13273 {
13274 rtx set = XVECEXP (operands[2], 0, i);
13275 emit_move_insn (SET_DEST (set), SET_SRC (set));
13276 }
13277
13278 /* The optimizer does not know that the call sets the function value
13279 registers we stored in the result block. We avoid problems by
13280 claiming that all hard registers are used and clobbered at this
13281 point. */
13282 emit_insn (gen_blockage ());
13283
13284 DONE;
13285 })
13286 \f
13287 ;; Prologue and epilogue instructions
13288
13289 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13290 ;; all of memory. This blocks insns from being moved across this point.
13291
13292 (define_insn "blockage"
13293 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13294 ""
13295 ""
13296 [(set_attr "length" "0")])
13297
13298 ;; Do not schedule instructions accessing memory across this point.
13299
13300 (define_expand "memory_blockage"
13301 [(set (match_dup 0)
13302 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13303 ""
13304 {
13305 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13306 MEM_VOLATILE_P (operands[0]) = 1;
13307 })
13308
13309 (define_insn "*memory_blockage"
13310 [(set (match_operand:BLK 0)
13311 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13312 ""
13313 ""
13314 [(set_attr "length" "0")])
13315
13316 ;; As USE insns aren't meaningful after reload, this is used instead
13317 ;; to prevent deleting instructions setting registers for PIC code
13318 (define_insn "prologue_use"
13319 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13320 ""
13321 ""
13322 [(set_attr "length" "0")])
13323
13324 ;; Insn emitted into the body of a function to return from a function.
13325 ;; This is only done if the function's epilogue is known to be simple.
13326 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13327
13328 (define_expand "return"
13329 [(simple_return)]
13330 "ix86_can_use_return_insn_p ()"
13331 {
13332 if (crtl->args.pops_args)
13333 {
13334 rtx popc = GEN_INT (crtl->args.pops_args);
13335 emit_jump_insn (gen_simple_return_pop_internal (popc));
13336 DONE;
13337 }
13338 })
13339
13340 ;; We need to disable this for TARGET_SEH, as otherwise
13341 ;; shrink-wrapped prologue gets enabled too. This might exceed
13342 ;; the maximum size of prologue in unwind information.
13343 ;; Also disallow shrink-wrapping if using stack slot to pass the
13344 ;; static chain pointer - the first instruction has to be pushl %esi
13345 ;; and it can't be moved around, as we use alternate entry points
13346 ;; in that case.
13347
13348 (define_expand "simple_return"
13349 [(simple_return)]
13350 "!TARGET_SEH && !ix86_static_chain_on_stack"
13351 {
13352 if (crtl->args.pops_args)
13353 {
13354 rtx popc = GEN_INT (crtl->args.pops_args);
13355 emit_jump_insn (gen_simple_return_pop_internal (popc));
13356 DONE;
13357 }
13358 })
13359
13360 (define_insn "simple_return_internal"
13361 [(simple_return)]
13362 "reload_completed"
13363 "* return ix86_output_function_return (false);"
13364 [(set_attr "length" "1")
13365 (set_attr "atom_unit" "jeu")
13366 (set_attr "length_immediate" "0")
13367 (set_attr "modrm" "0")
13368 (set_attr "maybe_prefix_bnd" "1")])
13369
13370 (define_insn "interrupt_return"
13371 [(simple_return)
13372 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13373 "reload_completed"
13374 {
13375 return TARGET_64BIT ? "iretq" : "iret";
13376 })
13377
13378 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13379 ;; instruction Athlon and K8 have.
13380
13381 (define_insn "simple_return_internal_long"
13382 [(simple_return)
13383 (unspec [(const_int 0)] UNSPEC_REP)]
13384 "reload_completed"
13385 "* return ix86_output_function_return (true);"
13386 [(set_attr "length" "2")
13387 (set_attr "atom_unit" "jeu")
13388 (set_attr "length_immediate" "0")
13389 (set_attr "prefix_rep" "1")
13390 (set_attr "modrm" "0")])
13391
13392 (define_insn_and_split "simple_return_pop_internal"
13393 [(simple_return)
13394 (use (match_operand:SI 0 "const_int_operand"))]
13395 "reload_completed"
13396 "%!ret\t%0"
13397 "&& cfun->machine->function_return_type != indirect_branch_keep"
13398 [(const_int 0)]
13399 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13400 [(set_attr "length" "3")
13401 (set_attr "atom_unit" "jeu")
13402 (set_attr "length_immediate" "2")
13403 (set_attr "modrm" "0")
13404 (set_attr "maybe_prefix_bnd" "1")])
13405
13406 (define_insn "simple_return_indirect_internal"
13407 [(simple_return)
13408 (use (match_operand 0 "register_operand" "r"))]
13409 "reload_completed"
13410 "* return ix86_output_indirect_function_return (operands[0]);"
13411 [(set (attr "type")
13412 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13413 != indirect_branch_keep)")
13414 (const_string "multi")
13415 (const_string "ibr")))
13416 (set_attr "length_immediate" "0")
13417 (set_attr "maybe_prefix_bnd" "1")])
13418
13419 (define_insn "nop"
13420 [(const_int 0)]
13421 ""
13422 "nop"
13423 [(set_attr "length" "1")
13424 (set_attr "length_immediate" "0")
13425 (set_attr "modrm" "0")])
13426
13427 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13428 (define_insn "nops"
13429 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13430 UNSPECV_NOPS)]
13431 "reload_completed"
13432 {
13433 int num = INTVAL (operands[0]);
13434
13435 gcc_assert (IN_RANGE (num, 1, 8));
13436
13437 while (num--)
13438 fputs ("\tnop\n", asm_out_file);
13439
13440 return "";
13441 }
13442 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13443 (set_attr "length_immediate" "0")
13444 (set_attr "modrm" "0")])
13445
13446 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13447 ;; branch prediction penalty for the third jump in a 16-byte
13448 ;; block on K8.
13449
13450 (define_insn "pad"
13451 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13452 ""
13453 {
13454 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13455 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13456 #else
13457 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13458 The align insn is used to avoid 3 jump instructions in the row to improve
13459 branch prediction and the benefits hardly outweigh the cost of extra 8
13460 nops on the average inserted by full alignment pseudo operation. */
13461 #endif
13462 return "";
13463 }
13464 [(set_attr "length" "16")])
13465
13466 (define_expand "prologue"
13467 [(const_int 0)]
13468 ""
13469 "ix86_expand_prologue (); DONE;")
13470
13471 (define_expand "set_got"
13472 [(parallel
13473 [(set (match_operand:SI 0 "register_operand")
13474 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13475 (clobber (reg:CC FLAGS_REG))])]
13476 "!TARGET_64BIT"
13477 {
13478 if (flag_pic && !TARGET_VXWORKS_RTP)
13479 ix86_pc_thunk_call_expanded = true;
13480 })
13481
13482 (define_insn "*set_got"
13483 [(set (match_operand:SI 0 "register_operand" "=r")
13484 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13485 (clobber (reg:CC FLAGS_REG))]
13486 "!TARGET_64BIT"
13487 "* return output_set_got (operands[0], NULL_RTX);"
13488 [(set_attr "type" "multi")
13489 (set_attr "length" "12")])
13490
13491 (define_expand "set_got_labelled"
13492 [(parallel
13493 [(set (match_operand:SI 0 "register_operand")
13494 (unspec:SI [(label_ref (match_operand 1))]
13495 UNSPEC_SET_GOT))
13496 (clobber (reg:CC FLAGS_REG))])]
13497 "!TARGET_64BIT"
13498 {
13499 if (flag_pic && !TARGET_VXWORKS_RTP)
13500 ix86_pc_thunk_call_expanded = true;
13501 })
13502
13503 (define_insn "*set_got_labelled"
13504 [(set (match_operand:SI 0 "register_operand" "=r")
13505 (unspec:SI [(label_ref (match_operand 1))]
13506 UNSPEC_SET_GOT))
13507 (clobber (reg:CC FLAGS_REG))]
13508 "!TARGET_64BIT"
13509 "* return output_set_got (operands[0], operands[1]);"
13510 [(set_attr "type" "multi")
13511 (set_attr "length" "12")])
13512
13513 (define_insn "set_got_rex64"
13514 [(set (match_operand:DI 0 "register_operand" "=r")
13515 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13516 "TARGET_64BIT"
13517 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13518 [(set_attr "type" "lea")
13519 (set_attr "length_address" "4")
13520 (set_attr "modrm_class" "unknown")
13521 (set_attr "mode" "DI")])
13522
13523 (define_insn "set_rip_rex64"
13524 [(set (match_operand:DI 0 "register_operand" "=r")
13525 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13526 "TARGET_64BIT"
13527 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13528 [(set_attr "type" "lea")
13529 (set_attr "length_address" "4")
13530 (set_attr "mode" "DI")])
13531
13532 (define_insn "set_got_offset_rex64"
13533 [(set (match_operand:DI 0 "register_operand" "=r")
13534 (unspec:DI
13535 [(label_ref (match_operand 1))]
13536 UNSPEC_SET_GOT_OFFSET))]
13537 "TARGET_LP64"
13538 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13539 [(set_attr "type" "imov")
13540 (set_attr "length_immediate" "0")
13541 (set_attr "length_address" "8")
13542 (set_attr "mode" "DI")])
13543
13544 (define_expand "epilogue"
13545 [(const_int 0)]
13546 ""
13547 "ix86_expand_epilogue (1); DONE;")
13548
13549 (define_expand "sibcall_epilogue"
13550 [(const_int 0)]
13551 ""
13552 "ix86_expand_epilogue (0); DONE;")
13553
13554 (define_expand "eh_return"
13555 [(use (match_operand 0 "register_operand"))]
13556 ""
13557 {
13558 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13559
13560 /* Tricky bit: we write the address of the handler to which we will
13561 be returning into someone else's stack frame, one word below the
13562 stack address we wish to restore. */
13563 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13564 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13565 tmp = gen_rtx_MEM (Pmode, tmp);
13566 emit_move_insn (tmp, ra);
13567
13568 emit_jump_insn (gen_eh_return_internal ());
13569 emit_barrier ();
13570 DONE;
13571 })
13572
13573 (define_insn_and_split "eh_return_internal"
13574 [(eh_return)]
13575 ""
13576 "#"
13577 "epilogue_completed"
13578 [(const_int 0)]
13579 "ix86_expand_epilogue (2); DONE;")
13580
13581 (define_insn "leave"
13582 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13583 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13584 (clobber (mem:BLK (scratch)))]
13585 "!TARGET_64BIT"
13586 "leave"
13587 [(set_attr "type" "leave")])
13588
13589 (define_insn "leave_rex64"
13590 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13591 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13592 (clobber (mem:BLK (scratch)))]
13593 "TARGET_64BIT"
13594 "leave"
13595 [(set_attr "type" "leave")])
13596 \f
13597 ;; Handle -fsplit-stack.
13598
13599 (define_expand "split_stack_prologue"
13600 [(const_int 0)]
13601 ""
13602 {
13603 ix86_expand_split_stack_prologue ();
13604 DONE;
13605 })
13606
13607 ;; In order to support the call/return predictor, we use a return
13608 ;; instruction which the middle-end doesn't see.
13609 (define_insn "split_stack_return"
13610 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13611 UNSPECV_SPLIT_STACK_RETURN)]
13612 ""
13613 {
13614 if (operands[0] == const0_rtx)
13615 return "ret";
13616 else
13617 return "ret\t%0";
13618 }
13619 [(set_attr "atom_unit" "jeu")
13620 (set_attr "modrm" "0")
13621 (set (attr "length")
13622 (if_then_else (match_operand:SI 0 "const0_operand")
13623 (const_int 1)
13624 (const_int 3)))
13625 (set (attr "length_immediate")
13626 (if_then_else (match_operand:SI 0 "const0_operand")
13627 (const_int 0)
13628 (const_int 2)))])
13629
13630 ;; If there are operand 0 bytes available on the stack, jump to
13631 ;; operand 1.
13632
13633 (define_expand "split_stack_space_check"
13634 [(set (pc) (if_then_else
13635 (ltu (minus (reg SP_REG)
13636 (match_operand 0 "register_operand"))
13637 (match_dup 2))
13638 (label_ref (match_operand 1))
13639 (pc)))]
13640 ""
13641 {
13642 rtx reg = gen_reg_rtx (Pmode);
13643
13644 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13645
13646 operands[2] = ix86_split_stack_guard ();
13647 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13648
13649 DONE;
13650 })
13651 \f
13652 ;; Bit manipulation instructions.
13653
13654 (define_expand "ffs<mode>2"
13655 [(set (match_dup 2) (const_int -1))
13656 (parallel [(set (match_dup 3) (match_dup 4))
13657 (set (match_operand:SWI48 0 "register_operand")
13658 (ctz:SWI48
13659 (match_operand:SWI48 1 "nonimmediate_operand")))])
13660 (set (match_dup 0) (if_then_else:SWI48
13661 (eq (match_dup 3) (const_int 0))
13662 (match_dup 2)
13663 (match_dup 0)))
13664 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13665 (clobber (reg:CC FLAGS_REG))])]
13666 ""
13667 {
13668 machine_mode flags_mode;
13669
13670 if (<MODE>mode == SImode && !TARGET_CMOVE)
13671 {
13672 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13673 DONE;
13674 }
13675
13676 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13677
13678 operands[2] = gen_reg_rtx (<MODE>mode);
13679 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13680 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13681 })
13682
13683 (define_insn_and_split "ffssi2_no_cmove"
13684 [(set (match_operand:SI 0 "register_operand" "=r")
13685 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13686 (clobber (match_scratch:SI 2 "=&q"))
13687 (clobber (reg:CC FLAGS_REG))]
13688 "!TARGET_CMOVE"
13689 "#"
13690 "&& reload_completed"
13691 [(parallel [(set (match_dup 4) (match_dup 5))
13692 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13693 (set (strict_low_part (match_dup 3))
13694 (eq:QI (match_dup 4) (const_int 0)))
13695 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13696 (clobber (reg:CC FLAGS_REG))])
13697 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13698 (clobber (reg:CC FLAGS_REG))])
13699 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13700 (clobber (reg:CC FLAGS_REG))])]
13701 {
13702 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13703
13704 operands[3] = gen_lowpart (QImode, operands[2]);
13705 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13706 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13707
13708 ix86_expand_clear (operands[2]);
13709 })
13710
13711 (define_insn_and_split "*tzcnt<mode>_1"
13712 [(set (reg:CCC FLAGS_REG)
13713 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13714 (const_int 0)))
13715 (set (match_operand:SWI48 0 "register_operand" "=r")
13716 (ctz:SWI48 (match_dup 1)))]
13717 "TARGET_BMI"
13718 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13719 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13720 && optimize_function_for_speed_p (cfun)
13721 && !reg_mentioned_p (operands[0], operands[1])"
13722 [(parallel
13723 [(set (reg:CCC FLAGS_REG)
13724 (compare:CCC (match_dup 1) (const_int 0)))
13725 (set (match_dup 0)
13726 (ctz:SWI48 (match_dup 1)))
13727 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13728 "ix86_expand_clear (operands[0]);"
13729 [(set_attr "type" "alu1")
13730 (set_attr "prefix_0f" "1")
13731 (set_attr "prefix_rep" "1")
13732 (set_attr "btver2_decode" "double")
13733 (set_attr "mode" "<MODE>")])
13734
13735 ; False dependency happens when destination is only updated by tzcnt,
13736 ; lzcnt or popcnt. There is no false dependency when destination is
13737 ; also used in source.
13738 (define_insn "*tzcnt<mode>_1_falsedep"
13739 [(set (reg:CCC FLAGS_REG)
13740 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13741 (const_int 0)))
13742 (set (match_operand:SWI48 0 "register_operand" "=r")
13743 (ctz:SWI48 (match_dup 1)))
13744 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13745 UNSPEC_INSN_FALSE_DEP)]
13746 "TARGET_BMI"
13747 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13748 [(set_attr "type" "alu1")
13749 (set_attr "prefix_0f" "1")
13750 (set_attr "prefix_rep" "1")
13751 (set_attr "btver2_decode" "double")
13752 (set_attr "mode" "<MODE>")])
13753
13754 (define_insn "*bsf<mode>_1"
13755 [(set (reg:CCZ FLAGS_REG)
13756 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13757 (const_int 0)))
13758 (set (match_operand:SWI48 0 "register_operand" "=r")
13759 (ctz:SWI48 (match_dup 1)))]
13760 ""
13761 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13762 [(set_attr "type" "alu1")
13763 (set_attr "prefix_0f" "1")
13764 (set_attr "btver2_decode" "double")
13765 (set_attr "znver1_decode" "vector")
13766 (set_attr "mode" "<MODE>")])
13767
13768 (define_insn_and_split "ctz<mode>2"
13769 [(set (match_operand:SWI48 0 "register_operand" "=r")
13770 (ctz:SWI48
13771 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13772 (clobber (reg:CC FLAGS_REG))]
13773 ""
13774 {
13775 if (TARGET_BMI)
13776 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13777 else if (optimize_function_for_size_p (cfun))
13778 ;
13779 else if (TARGET_GENERIC)
13780 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13781 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13782
13783 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13784 }
13785 "(TARGET_BMI || TARGET_GENERIC)
13786 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13787 && optimize_function_for_speed_p (cfun)
13788 && !reg_mentioned_p (operands[0], operands[1])"
13789 [(parallel
13790 [(set (match_dup 0)
13791 (ctz:SWI48 (match_dup 1)))
13792 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13793 (clobber (reg:CC FLAGS_REG))])]
13794 "ix86_expand_clear (operands[0]);"
13795 [(set_attr "type" "alu1")
13796 (set_attr "prefix_0f" "1")
13797 (set (attr "prefix_rep")
13798 (if_then_else
13799 (ior (match_test "TARGET_BMI")
13800 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13801 (match_test "TARGET_GENERIC")))
13802 (const_string "1")
13803 (const_string "0")))
13804 (set_attr "mode" "<MODE>")])
13805
13806 ; False dependency happens when destination is only updated by tzcnt,
13807 ; lzcnt or popcnt. There is no false dependency when destination is
13808 ; also used in source.
13809 (define_insn "*ctz<mode>2_falsedep"
13810 [(set (match_operand:SWI48 0 "register_operand" "=r")
13811 (ctz:SWI48
13812 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13813 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13814 UNSPEC_INSN_FALSE_DEP)
13815 (clobber (reg:CC FLAGS_REG))]
13816 ""
13817 {
13818 if (TARGET_BMI)
13819 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13820 else if (TARGET_GENERIC)
13821 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13822 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13823 else
13824 gcc_unreachable ();
13825 }
13826 [(set_attr "type" "alu1")
13827 (set_attr "prefix_0f" "1")
13828 (set_attr "prefix_rep" "1")
13829 (set_attr "mode" "<MODE>")])
13830
13831 (define_insn "bsr_rex64"
13832 [(set (match_operand:DI 0 "register_operand" "=r")
13833 (minus:DI (const_int 63)
13834 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13835 (clobber (reg:CC FLAGS_REG))]
13836 "TARGET_64BIT"
13837 "bsr{q}\t{%1, %0|%0, %1}"
13838 [(set_attr "type" "alu1")
13839 (set_attr "prefix_0f" "1")
13840 (set_attr "znver1_decode" "vector")
13841 (set_attr "mode" "DI")])
13842
13843 (define_insn "bsr"
13844 [(set (match_operand:SI 0 "register_operand" "=r")
13845 (minus:SI (const_int 31)
13846 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13847 (clobber (reg:CC FLAGS_REG))]
13848 ""
13849 "bsr{l}\t{%1, %0|%0, %1}"
13850 [(set_attr "type" "alu1")
13851 (set_attr "prefix_0f" "1")
13852 (set_attr "znver1_decode" "vector")
13853 (set_attr "mode" "SI")])
13854
13855 (define_insn "*bsrhi"
13856 [(set (match_operand:HI 0 "register_operand" "=r")
13857 (minus:HI (const_int 15)
13858 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13859 (clobber (reg:CC FLAGS_REG))]
13860 ""
13861 "bsr{w}\t{%1, %0|%0, %1}"
13862 [(set_attr "type" "alu1")
13863 (set_attr "prefix_0f" "1")
13864 (set_attr "znver1_decode" "vector")
13865 (set_attr "mode" "HI")])
13866
13867 (define_expand "clz<mode>2"
13868 [(parallel
13869 [(set (match_operand:SWI48 0 "register_operand")
13870 (minus:SWI48
13871 (match_dup 2)
13872 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13873 (clobber (reg:CC FLAGS_REG))])
13874 (parallel
13875 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13876 (clobber (reg:CC FLAGS_REG))])]
13877 ""
13878 {
13879 if (TARGET_LZCNT)
13880 {
13881 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13882 DONE;
13883 }
13884 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13885 })
13886
13887 (define_insn_and_split "clz<mode>2_lzcnt"
13888 [(set (match_operand:SWI48 0 "register_operand" "=r")
13889 (clz:SWI48
13890 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13891 (clobber (reg:CC FLAGS_REG))]
13892 "TARGET_LZCNT"
13893 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13894 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13895 && optimize_function_for_speed_p (cfun)
13896 && !reg_mentioned_p (operands[0], operands[1])"
13897 [(parallel
13898 [(set (match_dup 0)
13899 (clz:SWI48 (match_dup 1)))
13900 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13901 (clobber (reg:CC FLAGS_REG))])]
13902 "ix86_expand_clear (operands[0]);"
13903 [(set_attr "prefix_rep" "1")
13904 (set_attr "type" "bitmanip")
13905 (set_attr "mode" "<MODE>")])
13906
13907 ; False dependency happens when destination is only updated by tzcnt,
13908 ; lzcnt or popcnt. There is no false dependency when destination is
13909 ; also used in source.
13910 (define_insn "*clz<mode>2_lzcnt_falsedep"
13911 [(set (match_operand:SWI48 0 "register_operand" "=r")
13912 (clz:SWI48
13913 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13914 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13915 UNSPEC_INSN_FALSE_DEP)
13916 (clobber (reg:CC FLAGS_REG))]
13917 "TARGET_LZCNT"
13918 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13919 [(set_attr "prefix_rep" "1")
13920 (set_attr "type" "bitmanip")
13921 (set_attr "mode" "<MODE>")])
13922
13923 (define_int_iterator LT_ZCNT
13924 [(UNSPEC_TZCNT "TARGET_BMI")
13925 (UNSPEC_LZCNT "TARGET_LZCNT")])
13926
13927 (define_int_attr lt_zcnt
13928 [(UNSPEC_TZCNT "tzcnt")
13929 (UNSPEC_LZCNT "lzcnt")])
13930
13931 (define_int_attr lt_zcnt_type
13932 [(UNSPEC_TZCNT "alu1")
13933 (UNSPEC_LZCNT "bitmanip")])
13934
13935 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13936 ;; provides operand size as output when source operand is zero.
13937
13938 (define_insn_and_split "<lt_zcnt>_<mode>"
13939 [(set (match_operand:SWI48 0 "register_operand" "=r")
13940 (unspec:SWI48
13941 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13942 (clobber (reg:CC FLAGS_REG))]
13943 ""
13944 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13945 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13946 && optimize_function_for_speed_p (cfun)
13947 && !reg_mentioned_p (operands[0], operands[1])"
13948 [(parallel
13949 [(set (match_dup 0)
13950 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13951 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13952 (clobber (reg:CC FLAGS_REG))])]
13953 "ix86_expand_clear (operands[0]);"
13954 [(set_attr "type" "<lt_zcnt_type>")
13955 (set_attr "prefix_0f" "1")
13956 (set_attr "prefix_rep" "1")
13957 (set_attr "mode" "<MODE>")])
13958
13959 ; False dependency happens when destination is only updated by tzcnt,
13960 ; lzcnt or popcnt. There is no false dependency when destination is
13961 ; also used in source.
13962 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13963 [(set (match_operand:SWI48 0 "register_operand" "=r")
13964 (unspec:SWI48
13965 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13966 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13967 UNSPEC_INSN_FALSE_DEP)
13968 (clobber (reg:CC FLAGS_REG))]
13969 ""
13970 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13971 [(set_attr "type" "<lt_zcnt_type>")
13972 (set_attr "prefix_0f" "1")
13973 (set_attr "prefix_rep" "1")
13974 (set_attr "mode" "<MODE>")])
13975
13976 (define_insn "<lt_zcnt>_hi"
13977 [(set (match_operand:HI 0 "register_operand" "=r")
13978 (unspec:HI
13979 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13980 (clobber (reg:CC FLAGS_REG))]
13981 ""
13982 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13983 [(set_attr "type" "<lt_zcnt_type>")
13984 (set_attr "prefix_0f" "1")
13985 (set_attr "prefix_rep" "1")
13986 (set_attr "mode" "HI")])
13987
13988 ;; BMI instructions.
13989
13990 (define_insn "bmi_bextr_<mode>"
13991 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13992 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13993 (match_operand:SWI48 2 "register_operand" "r,r")]
13994 UNSPEC_BEXTR))
13995 (clobber (reg:CC FLAGS_REG))]
13996 "TARGET_BMI"
13997 "bextr\t{%2, %1, %0|%0, %1, %2}"
13998 [(set_attr "type" "bitmanip")
13999 (set_attr "btver2_decode" "direct, double")
14000 (set_attr "mode" "<MODE>")])
14001
14002 (define_insn "*bmi_bextr_<mode>_ccz"
14003 [(set (reg:CCZ FLAGS_REG)
14004 (compare:CCZ
14005 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14006 (match_operand:SWI48 2 "register_operand" "r,r")]
14007 UNSPEC_BEXTR)
14008 (const_int 0)))
14009 (clobber (match_scratch:SWI48 0 "=r,r"))]
14010 "TARGET_BMI"
14011 "bextr\t{%2, %1, %0|%0, %1, %2}"
14012 [(set_attr "type" "bitmanip")
14013 (set_attr "btver2_decode" "direct, double")
14014 (set_attr "mode" "<MODE>")])
14015
14016 (define_insn "*bmi_blsi_<mode>"
14017 [(set (match_operand:SWI48 0 "register_operand" "=r")
14018 (and:SWI48
14019 (neg:SWI48
14020 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14021 (match_dup 1)))
14022 (clobber (reg:CC FLAGS_REG))]
14023 "TARGET_BMI"
14024 "blsi\t{%1, %0|%0, %1}"
14025 [(set_attr "type" "bitmanip")
14026 (set_attr "btver2_decode" "double")
14027 (set_attr "mode" "<MODE>")])
14028
14029 (define_insn "*bmi_blsmsk_<mode>"
14030 [(set (match_operand:SWI48 0 "register_operand" "=r")
14031 (xor:SWI48
14032 (plus:SWI48
14033 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14034 (const_int -1))
14035 (match_dup 1)))
14036 (clobber (reg:CC FLAGS_REG))]
14037 "TARGET_BMI"
14038 "blsmsk\t{%1, %0|%0, %1}"
14039 [(set_attr "type" "bitmanip")
14040 (set_attr "btver2_decode" "double")
14041 (set_attr "mode" "<MODE>")])
14042
14043 (define_insn "*bmi_blsr_<mode>"
14044 [(set (match_operand:SWI48 0 "register_operand" "=r")
14045 (and:SWI48
14046 (plus:SWI48
14047 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14048 (const_int -1))
14049 (match_dup 1)))
14050 (clobber (reg:CC FLAGS_REG))]
14051 "TARGET_BMI"
14052 "blsr\t{%1, %0|%0, %1}"
14053 [(set_attr "type" "bitmanip")
14054 (set_attr "btver2_decode" "double")
14055 (set_attr "mode" "<MODE>")])
14056
14057 (define_insn "*bmi_blsr_<mode>_cmp"
14058 [(set (reg:CCZ FLAGS_REG)
14059 (compare:CCZ
14060 (and:SWI48
14061 (plus:SWI48
14062 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14063 (const_int -1))
14064 (match_dup 1))
14065 (const_int 0)))
14066 (set (match_operand:SWI48 0 "register_operand" "=r")
14067 (and:SWI48
14068 (plus:SWI48
14069 (match_dup 1)
14070 (const_int -1))
14071 (match_dup 1)))]
14072 "TARGET_BMI"
14073 "blsr\t{%1, %0|%0, %1}"
14074 [(set_attr "type" "bitmanip")
14075 (set_attr "btver2_decode" "double")
14076 (set_attr "mode" "<MODE>")])
14077
14078 (define_insn "*bmi_blsr_<mode>_ccz"
14079 [(set (reg:CCZ FLAGS_REG)
14080 (compare:CCZ
14081 (and:SWI48
14082 (plus:SWI48
14083 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14084 (const_int -1))
14085 (match_dup 1))
14086 (const_int 0)))
14087 (clobber (match_scratch:SWI48 0 "=r"))]
14088 "TARGET_BMI"
14089 "blsr\t{%1, %0|%0, %1}"
14090 [(set_attr "type" "bitmanip")
14091 (set_attr "btver2_decode" "double")
14092 (set_attr "mode" "<MODE>")])
14093
14094 ;; BMI2 instructions.
14095 (define_expand "bmi2_bzhi_<mode>3"
14096 [(parallel
14097 [(set (match_operand:SWI48 0 "register_operand")
14098 (zero_extract:SWI48
14099 (match_operand:SWI48 1 "nonimmediate_operand")
14100 (umin:SWI48
14101 (and:SWI48 (match_operand:SWI48 2 "register_operand")
14102 (const_int 255))
14103 (match_dup 3))
14104 (const_int 0)))
14105 (clobber (reg:CC FLAGS_REG))])]
14106 "TARGET_BMI2"
14107 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14108
14109 (define_insn "*bmi2_bzhi_<mode>3"
14110 [(set (match_operand:SWI48 0 "register_operand" "=r")
14111 (zero_extract:SWI48
14112 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14113 (umin:SWI48
14114 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14115 (const_int 255))
14116 (match_operand:SWI48 3 "const_int_operand" "n"))
14117 (const_int 0)))
14118 (clobber (reg:CC FLAGS_REG))]
14119 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14120 "bzhi\t{%2, %1, %0|%0, %1, %2}"
14121 [(set_attr "type" "bitmanip")
14122 (set_attr "prefix" "vex")
14123 (set_attr "mode" "<MODE>")])
14124
14125 (define_insn "*bmi2_bzhi_<mode>3_1"
14126 [(set (match_operand:SWI48 0 "register_operand" "=r")
14127 (zero_extract:SWI48
14128 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14129 (umin:SWI48
14130 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14131 (match_operand:SWI48 3 "const_int_operand" "n"))
14132 (const_int 0)))
14133 (clobber (reg:CC FLAGS_REG))]
14134 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14135 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14136 [(set_attr "type" "bitmanip")
14137 (set_attr "prefix" "vex")
14138 (set_attr "mode" "<MODE>")])
14139
14140 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14141 [(set (reg:CCZ FLAGS_REG)
14142 (compare:CCZ
14143 (zero_extract:SWI48
14144 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14145 (umin:SWI48
14146 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14147 (match_operand:SWI48 3 "const_int_operand" "n"))
14148 (const_int 0))
14149 (const_int 0)))
14150 (clobber (match_scratch:SWI48 0 "=r"))]
14151 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14152 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14153 [(set_attr "type" "bitmanip")
14154 (set_attr "prefix" "vex")
14155 (set_attr "mode" "<MODE>")])
14156
14157 (define_insn "bmi2_pdep_<mode>3"
14158 [(set (match_operand:SWI48 0 "register_operand" "=r")
14159 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14160 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14161 UNSPEC_PDEP))]
14162 "TARGET_BMI2"
14163 "pdep\t{%2, %1, %0|%0, %1, %2}"
14164 [(set_attr "type" "bitmanip")
14165 (set_attr "prefix" "vex")
14166 (set_attr "mode" "<MODE>")])
14167
14168 (define_insn "bmi2_pext_<mode>3"
14169 [(set (match_operand:SWI48 0 "register_operand" "=r")
14170 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14171 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14172 UNSPEC_PEXT))]
14173 "TARGET_BMI2"
14174 "pext\t{%2, %1, %0|%0, %1, %2}"
14175 [(set_attr "type" "bitmanip")
14176 (set_attr "prefix" "vex")
14177 (set_attr "mode" "<MODE>")])
14178
14179 ;; TBM instructions.
14180 (define_insn "tbm_bextri_<mode>"
14181 [(set (match_operand:SWI48 0 "register_operand" "=r")
14182 (zero_extract:SWI48
14183 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14184 (match_operand 2 "const_0_to_255_operand" "N")
14185 (match_operand 3 "const_0_to_255_operand" "N")))
14186 (clobber (reg:CC FLAGS_REG))]
14187 "TARGET_TBM"
14188 {
14189 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14190 return "bextr\t{%2, %1, %0|%0, %1, %2}";
14191 }
14192 [(set_attr "type" "bitmanip")
14193 (set_attr "mode" "<MODE>")])
14194
14195 (define_insn "*tbm_blcfill_<mode>"
14196 [(set (match_operand:SWI48 0 "register_operand" "=r")
14197 (and:SWI48
14198 (plus:SWI48
14199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14200 (const_int 1))
14201 (match_dup 1)))
14202 (clobber (reg:CC FLAGS_REG))]
14203 "TARGET_TBM"
14204 "blcfill\t{%1, %0|%0, %1}"
14205 [(set_attr "type" "bitmanip")
14206 (set_attr "mode" "<MODE>")])
14207
14208 (define_insn "*tbm_blci_<mode>"
14209 [(set (match_operand:SWI48 0 "register_operand" "=r")
14210 (ior:SWI48
14211 (not:SWI48
14212 (plus:SWI48
14213 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14214 (const_int 1)))
14215 (match_dup 1)))
14216 (clobber (reg:CC FLAGS_REG))]
14217 "TARGET_TBM"
14218 "blci\t{%1, %0|%0, %1}"
14219 [(set_attr "type" "bitmanip")
14220 (set_attr "mode" "<MODE>")])
14221
14222 (define_insn "*tbm_blcic_<mode>"
14223 [(set (match_operand:SWI48 0 "register_operand" "=r")
14224 (and:SWI48
14225 (plus:SWI48
14226 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14227 (const_int 1))
14228 (not:SWI48
14229 (match_dup 1))))
14230 (clobber (reg:CC FLAGS_REG))]
14231 "TARGET_TBM"
14232 "blcic\t{%1, %0|%0, %1}"
14233 [(set_attr "type" "bitmanip")
14234 (set_attr "mode" "<MODE>")])
14235
14236 (define_insn "*tbm_blcmsk_<mode>"
14237 [(set (match_operand:SWI48 0 "register_operand" "=r")
14238 (xor:SWI48
14239 (plus:SWI48
14240 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14241 (const_int 1))
14242 (match_dup 1)))
14243 (clobber (reg:CC FLAGS_REG))]
14244 "TARGET_TBM"
14245 "blcmsk\t{%1, %0|%0, %1}"
14246 [(set_attr "type" "bitmanip")
14247 (set_attr "mode" "<MODE>")])
14248
14249 (define_insn "*tbm_blcs_<mode>"
14250 [(set (match_operand:SWI48 0 "register_operand" "=r")
14251 (ior:SWI48
14252 (plus:SWI48
14253 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14254 (const_int 1))
14255 (match_dup 1)))
14256 (clobber (reg:CC FLAGS_REG))]
14257 "TARGET_TBM"
14258 "blcs\t{%1, %0|%0, %1}"
14259 [(set_attr "type" "bitmanip")
14260 (set_attr "mode" "<MODE>")])
14261
14262 (define_insn "*tbm_blsfill_<mode>"
14263 [(set (match_operand:SWI48 0 "register_operand" "=r")
14264 (ior:SWI48
14265 (plus:SWI48
14266 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14267 (const_int -1))
14268 (match_dup 1)))
14269 (clobber (reg:CC FLAGS_REG))]
14270 "TARGET_TBM"
14271 "blsfill\t{%1, %0|%0, %1}"
14272 [(set_attr "type" "bitmanip")
14273 (set_attr "mode" "<MODE>")])
14274
14275 (define_insn "*tbm_blsic_<mode>"
14276 [(set (match_operand:SWI48 0 "register_operand" "=r")
14277 (ior:SWI48
14278 (plus:SWI48
14279 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14280 (const_int -1))
14281 (not:SWI48
14282 (match_dup 1))))
14283 (clobber (reg:CC FLAGS_REG))]
14284 "TARGET_TBM"
14285 "blsic\t{%1, %0|%0, %1}"
14286 [(set_attr "type" "bitmanip")
14287 (set_attr "mode" "<MODE>")])
14288
14289 (define_insn "*tbm_t1mskc_<mode>"
14290 [(set (match_operand:SWI48 0 "register_operand" "=r")
14291 (ior:SWI48
14292 (plus:SWI48
14293 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14294 (const_int 1))
14295 (not:SWI48
14296 (match_dup 1))))
14297 (clobber (reg:CC FLAGS_REG))]
14298 "TARGET_TBM"
14299 "t1mskc\t{%1, %0|%0, %1}"
14300 [(set_attr "type" "bitmanip")
14301 (set_attr "mode" "<MODE>")])
14302
14303 (define_insn "*tbm_tzmsk_<mode>"
14304 [(set (match_operand:SWI48 0 "register_operand" "=r")
14305 (and:SWI48
14306 (plus:SWI48
14307 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14308 (const_int -1))
14309 (not:SWI48
14310 (match_dup 1))))
14311 (clobber (reg:CC FLAGS_REG))]
14312 "TARGET_TBM"
14313 "tzmsk\t{%1, %0|%0, %1}"
14314 [(set_attr "type" "bitmanip")
14315 (set_attr "mode" "<MODE>")])
14316
14317 (define_insn_and_split "popcount<mode>2"
14318 [(set (match_operand:SWI48 0 "register_operand" "=r")
14319 (popcount:SWI48
14320 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14321 (clobber (reg:CC FLAGS_REG))]
14322 "TARGET_POPCNT"
14323 {
14324 #if TARGET_MACHO
14325 return "popcnt\t{%1, %0|%0, %1}";
14326 #else
14327 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14328 #endif
14329 }
14330 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14331 && optimize_function_for_speed_p (cfun)
14332 && !reg_mentioned_p (operands[0], operands[1])"
14333 [(parallel
14334 [(set (match_dup 0)
14335 (popcount:SWI48 (match_dup 1)))
14336 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14337 (clobber (reg:CC FLAGS_REG))])]
14338 "ix86_expand_clear (operands[0]);"
14339 [(set_attr "prefix_rep" "1")
14340 (set_attr "type" "bitmanip")
14341 (set_attr "mode" "<MODE>")])
14342
14343 ; False dependency happens when destination is only updated by tzcnt,
14344 ; lzcnt or popcnt. There is no false dependency when destination is
14345 ; also used in source.
14346 (define_insn "*popcount<mode>2_falsedep"
14347 [(set (match_operand:SWI48 0 "register_operand" "=r")
14348 (popcount:SWI48
14349 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14350 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14351 UNSPEC_INSN_FALSE_DEP)
14352 (clobber (reg:CC FLAGS_REG))]
14353 "TARGET_POPCNT"
14354 {
14355 #if TARGET_MACHO
14356 return "popcnt\t{%1, %0|%0, %1}";
14357 #else
14358 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14359 #endif
14360 }
14361 [(set_attr "prefix_rep" "1")
14362 (set_attr "type" "bitmanip")
14363 (set_attr "mode" "<MODE>")])
14364
14365 (define_insn_and_split "*popcounthi2_1"
14366 [(set (match_operand:SI 0 "register_operand")
14367 (popcount:SI
14368 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14369 (clobber (reg:CC FLAGS_REG))]
14370 "TARGET_POPCNT
14371 && can_create_pseudo_p ()"
14372 "#"
14373 "&& 1"
14374 [(const_int 0)]
14375 {
14376 rtx tmp = gen_reg_rtx (HImode);
14377
14378 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14379 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14380 DONE;
14381 })
14382
14383 (define_insn "popcounthi2"
14384 [(set (match_operand:HI 0 "register_operand" "=r")
14385 (popcount:HI
14386 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14387 (clobber (reg:CC FLAGS_REG))]
14388 "TARGET_POPCNT"
14389 {
14390 #if TARGET_MACHO
14391 return "popcnt\t{%1, %0|%0, %1}";
14392 #else
14393 return "popcnt{w}\t{%1, %0|%0, %1}";
14394 #endif
14395 }
14396 [(set_attr "prefix_rep" "1")
14397 (set_attr "type" "bitmanip")
14398 (set_attr "mode" "HI")])
14399
14400 (define_expand "bswapdi2"
14401 [(set (match_operand:DI 0 "register_operand")
14402 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14403 "TARGET_64BIT"
14404 {
14405 if (!TARGET_MOVBE)
14406 operands[1] = force_reg (DImode, operands[1]);
14407 })
14408
14409 (define_expand "bswapsi2"
14410 [(set (match_operand:SI 0 "register_operand")
14411 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14412 ""
14413 {
14414 if (TARGET_MOVBE)
14415 ;
14416 else if (TARGET_BSWAP)
14417 operands[1] = force_reg (SImode, operands[1]);
14418 else
14419 {
14420 rtx x = operands[0];
14421
14422 emit_move_insn (x, operands[1]);
14423 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14424 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14425 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14426 DONE;
14427 }
14428 })
14429
14430 (define_insn "*bswap<mode>2_movbe"
14431 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14432 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14433 "TARGET_MOVBE
14434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14435 "@
14436 bswap\t%0
14437 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14438 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14439 [(set_attr "type" "bitmanip,imov,imov")
14440 (set_attr "modrm" "0,1,1")
14441 (set_attr "prefix_0f" "*,1,1")
14442 (set_attr "prefix_extra" "*,1,1")
14443 (set_attr "mode" "<MODE>")])
14444
14445 (define_insn "*bswap<mode>2"
14446 [(set (match_operand:SWI48 0 "register_operand" "=r")
14447 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14448 "TARGET_BSWAP"
14449 "bswap\t%0"
14450 [(set_attr "type" "bitmanip")
14451 (set_attr "modrm" "0")
14452 (set_attr "mode" "<MODE>")])
14453
14454 (define_expand "bswaphi2"
14455 [(set (match_operand:HI 0 "register_operand")
14456 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14457 "TARGET_MOVBE")
14458
14459 (define_insn "*bswaphi2_movbe"
14460 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14461 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14462 "TARGET_MOVBE
14463 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14464 "@
14465 xchg{b}\t{%h0, %b0|%b0, %h0}
14466 movbe{w}\t{%1, %0|%0, %1}
14467 movbe{w}\t{%1, %0|%0, %1}"
14468 [(set_attr "type" "imov")
14469 (set_attr "modrm" "*,1,1")
14470 (set_attr "prefix_0f" "*,1,1")
14471 (set_attr "prefix_extra" "*,1,1")
14472 (set_attr "pent_pair" "np,*,*")
14473 (set_attr "athlon_decode" "vector,*,*")
14474 (set_attr "amdfam10_decode" "double,*,*")
14475 (set_attr "bdver1_decode" "double,*,*")
14476 (set_attr "mode" "QI,HI,HI")])
14477
14478 (define_peephole2
14479 [(set (match_operand:HI 0 "general_reg_operand")
14480 (bswap:HI (match_dup 0)))]
14481 "TARGET_MOVBE
14482 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14483 && peep2_regno_dead_p (0, FLAGS_REG)"
14484 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14485 (clobber (reg:CC FLAGS_REG))])])
14486
14487 (define_insn "bswaphi_lowpart"
14488 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14489 (bswap:HI (match_dup 0)))
14490 (clobber (reg:CC FLAGS_REG))]
14491 ""
14492 "@
14493 xchg{b}\t{%h0, %b0|%b0, %h0}
14494 rol{w}\t{$8, %0|%0, 8}"
14495 [(set (attr "preferred_for_size")
14496 (cond [(eq_attr "alternative" "0")
14497 (symbol_ref "true")]
14498 (symbol_ref "false")))
14499 (set (attr "preferred_for_speed")
14500 (cond [(eq_attr "alternative" "0")
14501 (symbol_ref "TARGET_USE_XCHGB")]
14502 (symbol_ref "!TARGET_USE_XCHGB")))
14503 (set_attr "length" "2,4")
14504 (set_attr "mode" "QI,HI")])
14505
14506 (define_expand "paritydi2"
14507 [(set (match_operand:DI 0 "register_operand")
14508 (parity:DI (match_operand:DI 1 "register_operand")))]
14509 "! TARGET_POPCNT"
14510 {
14511 rtx scratch = gen_reg_rtx (QImode);
14512
14513 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14514 NULL_RTX, operands[1]));
14515
14516 ix86_expand_setcc (scratch, ORDERED,
14517 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14518
14519 if (TARGET_64BIT)
14520 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14521 else
14522 {
14523 rtx tmp = gen_reg_rtx (SImode);
14524
14525 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14526 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14527 }
14528 DONE;
14529 })
14530
14531 (define_expand "paritysi2"
14532 [(set (match_operand:SI 0 "register_operand")
14533 (parity:SI (match_operand:SI 1 "register_operand")))]
14534 "! TARGET_POPCNT"
14535 {
14536 rtx scratch = gen_reg_rtx (QImode);
14537
14538 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14539
14540 ix86_expand_setcc (scratch, ORDERED,
14541 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14542
14543 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14544 DONE;
14545 })
14546
14547 (define_insn_and_split "paritydi2_cmp"
14548 [(set (reg:CC FLAGS_REG)
14549 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14550 UNSPEC_PARITY))
14551 (clobber (match_scratch:DI 0 "=r"))
14552 (clobber (match_scratch:SI 1 "=&r"))
14553 (clobber (match_scratch:HI 2 "=Q"))]
14554 "! TARGET_POPCNT"
14555 "#"
14556 "&& reload_completed"
14557 [(parallel
14558 [(set (match_dup 1)
14559 (xor:SI (match_dup 1) (match_dup 4)))
14560 (clobber (reg:CC FLAGS_REG))])
14561 (parallel
14562 [(set (reg:CC FLAGS_REG)
14563 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14564 (clobber (match_dup 1))
14565 (clobber (match_dup 2))])]
14566 {
14567 operands[4] = gen_lowpart (SImode, operands[3]);
14568
14569 if (TARGET_64BIT)
14570 {
14571 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14572 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14573 }
14574 else
14575 operands[1] = gen_highpart (SImode, operands[3]);
14576 })
14577
14578 (define_insn_and_split "paritysi2_cmp"
14579 [(set (reg:CC FLAGS_REG)
14580 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14581 UNSPEC_PARITY))
14582 (clobber (match_scratch:SI 0 "=r"))
14583 (clobber (match_scratch:HI 1 "=&Q"))]
14584 "! TARGET_POPCNT"
14585 "#"
14586 "&& reload_completed"
14587 [(parallel
14588 [(set (match_dup 1)
14589 (xor:HI (match_dup 1) (match_dup 3)))
14590 (clobber (reg:CC FLAGS_REG))])
14591 (parallel
14592 [(set (reg:CC FLAGS_REG)
14593 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14594 (clobber (match_dup 1))])]
14595 {
14596 operands[3] = gen_lowpart (HImode, operands[2]);
14597
14598 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14599 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14600 })
14601
14602 (define_insn "*parityhi2_cmp"
14603 [(set (reg:CC FLAGS_REG)
14604 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14605 UNSPEC_PARITY))
14606 (clobber (match_scratch:HI 0 "=Q"))]
14607 "! TARGET_POPCNT"
14608 "xor{b}\t{%h0, %b0|%b0, %h0}"
14609 [(set_attr "length" "2")
14610 (set_attr "mode" "HI")])
14611
14612 \f
14613 ;; Thread-local storage patterns for ELF.
14614 ;;
14615 ;; Note that these code sequences must appear exactly as shown
14616 ;; in order to allow linker relaxation.
14617
14618 (define_insn "*tls_global_dynamic_32_gnu"
14619 [(set (match_operand:SI 0 "register_operand" "=a")
14620 (unspec:SI
14621 [(match_operand:SI 1 "register_operand" "Yb")
14622 (match_operand 2 "tls_symbolic_operand")
14623 (match_operand 3 "constant_call_address_operand" "Bz")
14624 (reg:SI SP_REG)]
14625 UNSPEC_TLS_GD))
14626 (clobber (match_scratch:SI 4 "=d"))
14627 (clobber (match_scratch:SI 5 "=c"))
14628 (clobber (reg:CC FLAGS_REG))]
14629 "!TARGET_64BIT && TARGET_GNU_TLS"
14630 {
14631 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14632 output_asm_insn
14633 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14634 else
14635 output_asm_insn
14636 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14637 if (TARGET_SUN_TLS)
14638 #ifdef HAVE_AS_IX86_TLSGDPLT
14639 return "call\t%a2@tlsgdplt";
14640 #else
14641 return "call\t%p3@plt";
14642 #endif
14643 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14644 return "call\t%P3";
14645 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14646 }
14647 [(set_attr "type" "multi")
14648 (set_attr "length" "12")])
14649
14650 (define_expand "tls_global_dynamic_32"
14651 [(parallel
14652 [(set (match_operand:SI 0 "register_operand")
14653 (unspec:SI [(match_operand:SI 2 "register_operand")
14654 (match_operand 1 "tls_symbolic_operand")
14655 (match_operand 3 "constant_call_address_operand")
14656 (reg:SI SP_REG)]
14657 UNSPEC_TLS_GD))
14658 (clobber (match_scratch:SI 4))
14659 (clobber (match_scratch:SI 5))
14660 (clobber (reg:CC FLAGS_REG))])]
14661 ""
14662 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14663
14664 (define_insn "*tls_global_dynamic_64_<mode>"
14665 [(set (match_operand:P 0 "register_operand" "=a")
14666 (call:P
14667 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14668 (match_operand 3)))
14669 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14670 (reg:P SP_REG)]
14671 UNSPEC_TLS_GD)]
14672 "TARGET_64BIT"
14673 {
14674 if (!TARGET_X32)
14675 fputs (ASM_BYTE "0x66\n", asm_out_file);
14676 output_asm_insn
14677 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14678 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14679 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14680 else
14681 fputs (ASM_BYTE "0x66\n", asm_out_file);
14682 fputs ("\trex64\n", asm_out_file);
14683 if (TARGET_SUN_TLS)
14684 return "call\t%p2@plt";
14685 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14686 return "call\t%P2";
14687 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14688 }
14689 [(set_attr "type" "multi")
14690 (set (attr "length")
14691 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14692
14693 (define_insn "*tls_global_dynamic_64_largepic"
14694 [(set (match_operand:DI 0 "register_operand" "=a")
14695 (call:DI
14696 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14697 (match_operand:DI 3 "immediate_operand" "i")))
14698 (match_operand 4)))
14699 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14700 (reg:DI SP_REG)]
14701 UNSPEC_TLS_GD)]
14702 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14703 && GET_CODE (operands[3]) == CONST
14704 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14705 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14706 {
14707 output_asm_insn
14708 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14709 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14710 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14711 return "call\t{*%%rax|rax}";
14712 }
14713 [(set_attr "type" "multi")
14714 (set_attr "length" "22")])
14715
14716 (define_expand "tls_global_dynamic_64_<mode>"
14717 [(parallel
14718 [(set (match_operand:P 0 "register_operand")
14719 (call:P
14720 (mem:QI (match_operand 2))
14721 (const_int 0)))
14722 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14723 (reg:P SP_REG)]
14724 UNSPEC_TLS_GD)])]
14725 "TARGET_64BIT"
14726 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14727
14728 (define_insn "*tls_local_dynamic_base_32_gnu"
14729 [(set (match_operand:SI 0 "register_operand" "=a")
14730 (unspec:SI
14731 [(match_operand:SI 1 "register_operand" "Yb")
14732 (match_operand 2 "constant_call_address_operand" "Bz")
14733 (reg:SI SP_REG)]
14734 UNSPEC_TLS_LD_BASE))
14735 (clobber (match_scratch:SI 3 "=d"))
14736 (clobber (match_scratch:SI 4 "=c"))
14737 (clobber (reg:CC FLAGS_REG))]
14738 "!TARGET_64BIT && TARGET_GNU_TLS"
14739 {
14740 output_asm_insn
14741 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14742 if (TARGET_SUN_TLS)
14743 {
14744 if (HAVE_AS_IX86_TLSLDMPLT)
14745 return "call\t%&@tlsldmplt";
14746 else
14747 return "call\t%p2@plt";
14748 }
14749 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14750 return "call\t%P2";
14751 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14752 }
14753 [(set_attr "type" "multi")
14754 (set_attr "length" "11")])
14755
14756 (define_expand "tls_local_dynamic_base_32"
14757 [(parallel
14758 [(set (match_operand:SI 0 "register_operand")
14759 (unspec:SI
14760 [(match_operand:SI 1 "register_operand")
14761 (match_operand 2 "constant_call_address_operand")
14762 (reg:SI SP_REG)]
14763 UNSPEC_TLS_LD_BASE))
14764 (clobber (match_scratch:SI 3))
14765 (clobber (match_scratch:SI 4))
14766 (clobber (reg:CC FLAGS_REG))])]
14767 ""
14768 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14769
14770 (define_insn "*tls_local_dynamic_base_64_<mode>"
14771 [(set (match_operand:P 0 "register_operand" "=a")
14772 (call:P
14773 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14774 (match_operand 2)))
14775 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14776 "TARGET_64BIT"
14777 {
14778 output_asm_insn
14779 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14780 if (TARGET_SUN_TLS)
14781 return "call\t%p1@plt";
14782 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14783 return "call\t%P1";
14784 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14785 }
14786 [(set_attr "type" "multi")
14787 (set_attr "length" "12")])
14788
14789 (define_insn "*tls_local_dynamic_base_64_largepic"
14790 [(set (match_operand:DI 0 "register_operand" "=a")
14791 (call:DI
14792 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14793 (match_operand:DI 2 "immediate_operand" "i")))
14794 (match_operand 3)))
14795 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14796 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14797 && GET_CODE (operands[2]) == CONST
14798 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14799 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14800 {
14801 output_asm_insn
14802 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14803 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14804 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14805 return "call\t{*%%rax|rax}";
14806 }
14807 [(set_attr "type" "multi")
14808 (set_attr "length" "22")])
14809
14810 (define_expand "tls_local_dynamic_base_64_<mode>"
14811 [(parallel
14812 [(set (match_operand:P 0 "register_operand")
14813 (call:P
14814 (mem:QI (match_operand 1))
14815 (const_int 0)))
14816 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14817 "TARGET_64BIT"
14818 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14819
14820 ;; Local dynamic of a single variable is a lose. Show combine how
14821 ;; to convert that back to global dynamic.
14822
14823 (define_insn_and_split "*tls_local_dynamic_32_once"
14824 [(set (match_operand:SI 0 "register_operand" "=a")
14825 (plus:SI
14826 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14827 (match_operand 2 "constant_call_address_operand" "Bz")
14828 (reg:SI SP_REG)]
14829 UNSPEC_TLS_LD_BASE)
14830 (const:SI (unspec:SI
14831 [(match_operand 3 "tls_symbolic_operand")]
14832 UNSPEC_DTPOFF))))
14833 (clobber (match_scratch:SI 4 "=d"))
14834 (clobber (match_scratch:SI 5 "=c"))
14835 (clobber (reg:CC FLAGS_REG))]
14836 ""
14837 "#"
14838 ""
14839 [(parallel
14840 [(set (match_dup 0)
14841 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14842 (reg:SI SP_REG)]
14843 UNSPEC_TLS_GD))
14844 (clobber (match_dup 4))
14845 (clobber (match_dup 5))
14846 (clobber (reg:CC FLAGS_REG))])])
14847
14848 ;; Load and add the thread base pointer from %<tp_seg>:0.
14849 (define_insn_and_split "*load_tp_<mode>"
14850 [(set (match_operand:PTR 0 "register_operand" "=r")
14851 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14852 ""
14853 "#"
14854 ""
14855 [(set (match_dup 0)
14856 (match_dup 1))]
14857 {
14858 addr_space_t as = DEFAULT_TLS_SEG_REG;
14859
14860 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14861 set_mem_addr_space (operands[1], as);
14862 })
14863
14864 (define_insn_and_split "*load_tp_x32_zext"
14865 [(set (match_operand:DI 0 "register_operand" "=r")
14866 (zero_extend:DI
14867 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14868 "TARGET_X32"
14869 "#"
14870 ""
14871 [(set (match_dup 0)
14872 (zero_extend:DI (match_dup 1)))]
14873 {
14874 addr_space_t as = DEFAULT_TLS_SEG_REG;
14875
14876 operands[1] = gen_const_mem (SImode, const0_rtx);
14877 set_mem_addr_space (operands[1], as);
14878 })
14879
14880 (define_insn_and_split "*add_tp_<mode>"
14881 [(set (match_operand:PTR 0 "register_operand" "=r")
14882 (plus:PTR
14883 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14884 (match_operand:PTR 1 "register_operand" "0")))
14885 (clobber (reg:CC FLAGS_REG))]
14886 ""
14887 "#"
14888 ""
14889 [(parallel
14890 [(set (match_dup 0)
14891 (plus:PTR (match_dup 1) (match_dup 2)))
14892 (clobber (reg:CC FLAGS_REG))])]
14893 {
14894 addr_space_t as = DEFAULT_TLS_SEG_REG;
14895
14896 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14897 set_mem_addr_space (operands[2], as);
14898 })
14899
14900 (define_insn_and_split "*add_tp_x32_zext"
14901 [(set (match_operand:DI 0 "register_operand" "=r")
14902 (zero_extend:DI
14903 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14904 (match_operand:SI 1 "register_operand" "0"))))
14905 (clobber (reg:CC FLAGS_REG))]
14906 "TARGET_X32"
14907 "#"
14908 ""
14909 [(parallel
14910 [(set (match_dup 0)
14911 (zero_extend:DI
14912 (plus:SI (match_dup 1) (match_dup 2))))
14913 (clobber (reg:CC FLAGS_REG))])]
14914 {
14915 addr_space_t as = DEFAULT_TLS_SEG_REG;
14916
14917 operands[2] = gen_const_mem (SImode, const0_rtx);
14918 set_mem_addr_space (operands[2], as);
14919 })
14920
14921 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14922 ;; %rax as destination of the initial executable code sequence.
14923 (define_insn "tls_initial_exec_64_sun"
14924 [(set (match_operand:DI 0 "register_operand" "=a")
14925 (unspec:DI
14926 [(match_operand 1 "tls_symbolic_operand")]
14927 UNSPEC_TLS_IE_SUN))
14928 (clobber (reg:CC FLAGS_REG))]
14929 "TARGET_64BIT && TARGET_SUN_TLS"
14930 {
14931 output_asm_insn
14932 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14933 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14934 }
14935 [(set_attr "type" "multi")])
14936
14937 ;; GNU2 TLS patterns can be split.
14938
14939 (define_expand "tls_dynamic_gnu2_32"
14940 [(set (match_dup 3)
14941 (plus:SI (match_operand:SI 2 "register_operand")
14942 (const:SI
14943 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14944 UNSPEC_TLSDESC))))
14945 (parallel
14946 [(set (match_operand:SI 0 "register_operand")
14947 (unspec:SI [(match_dup 1) (match_dup 3)
14948 (match_dup 2) (reg:SI SP_REG)]
14949 UNSPEC_TLSDESC))
14950 (clobber (reg:CC FLAGS_REG))])]
14951 "!TARGET_64BIT && TARGET_GNU2_TLS"
14952 {
14953 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14954 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14955 })
14956
14957 (define_insn "*tls_dynamic_gnu2_lea_32"
14958 [(set (match_operand:SI 0 "register_operand" "=r")
14959 (plus:SI (match_operand:SI 1 "register_operand" "b")
14960 (const:SI
14961 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14962 UNSPEC_TLSDESC))))]
14963 "!TARGET_64BIT && TARGET_GNU2_TLS"
14964 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14965 [(set_attr "type" "lea")
14966 (set_attr "mode" "SI")
14967 (set_attr "length" "6")
14968 (set_attr "length_address" "4")])
14969
14970 (define_insn "*tls_dynamic_gnu2_call_32"
14971 [(set (match_operand:SI 0 "register_operand" "=a")
14972 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14973 (match_operand:SI 2 "register_operand" "0")
14974 ;; we have to make sure %ebx still points to the GOT
14975 (match_operand:SI 3 "register_operand" "b")
14976 (reg:SI SP_REG)]
14977 UNSPEC_TLSDESC))
14978 (clobber (reg:CC FLAGS_REG))]
14979 "!TARGET_64BIT && TARGET_GNU2_TLS"
14980 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14981 [(set_attr "type" "call")
14982 (set_attr "length" "2")
14983 (set_attr "length_address" "0")])
14984
14985 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14986 [(set (match_operand:SI 0 "register_operand" "=&a")
14987 (plus:SI
14988 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14989 (match_operand:SI 4)
14990 (match_operand:SI 2 "register_operand" "b")
14991 (reg:SI SP_REG)]
14992 UNSPEC_TLSDESC)
14993 (const:SI (unspec:SI
14994 [(match_operand 1 "tls_symbolic_operand")]
14995 UNSPEC_DTPOFF))))
14996 (clobber (reg:CC FLAGS_REG))]
14997 "!TARGET_64BIT && TARGET_GNU2_TLS"
14998 "#"
14999 ""
15000 [(set (match_dup 0) (match_dup 5))]
15001 {
15002 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15003 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15004 })
15005
15006 (define_expand "tls_dynamic_gnu2_64"
15007 [(set (match_dup 2)
15008 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15009 UNSPEC_TLSDESC))
15010 (parallel
15011 [(set (match_operand:DI 0 "register_operand")
15012 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15013 UNSPEC_TLSDESC))
15014 (clobber (reg:CC FLAGS_REG))])]
15015 "TARGET_64BIT && TARGET_GNU2_TLS"
15016 {
15017 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15018 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15019 })
15020
15021 (define_insn "*tls_dynamic_gnu2_lea_64"
15022 [(set (match_operand:DI 0 "register_operand" "=r")
15023 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15024 UNSPEC_TLSDESC))]
15025 "TARGET_64BIT && TARGET_GNU2_TLS"
15026 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15027 [(set_attr "type" "lea")
15028 (set_attr "mode" "DI")
15029 (set_attr "length" "7")
15030 (set_attr "length_address" "4")])
15031
15032 (define_insn "*tls_dynamic_gnu2_call_64"
15033 [(set (match_operand:DI 0 "register_operand" "=a")
15034 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15035 (match_operand:DI 2 "register_operand" "0")
15036 (reg:DI SP_REG)]
15037 UNSPEC_TLSDESC))
15038 (clobber (reg:CC FLAGS_REG))]
15039 "TARGET_64BIT && TARGET_GNU2_TLS"
15040 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15041 [(set_attr "type" "call")
15042 (set_attr "length" "2")
15043 (set_attr "length_address" "0")])
15044
15045 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15046 [(set (match_operand:DI 0 "register_operand" "=&a")
15047 (plus:DI
15048 (unspec:DI [(match_operand 2 "tls_modbase_operand")
15049 (match_operand:DI 3)
15050 (reg:DI SP_REG)]
15051 UNSPEC_TLSDESC)
15052 (const:DI (unspec:DI
15053 [(match_operand 1 "tls_symbolic_operand")]
15054 UNSPEC_DTPOFF))))
15055 (clobber (reg:CC FLAGS_REG))]
15056 "TARGET_64BIT && TARGET_GNU2_TLS"
15057 "#"
15058 ""
15059 [(set (match_dup 0) (match_dup 4))]
15060 {
15061 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15062 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15063 })
15064
15065 (define_split
15066 [(match_operand 0 "tls_address_pattern")]
15067 "TARGET_TLS_DIRECT_SEG_REFS"
15068 [(match_dup 0)]
15069 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15070
15071 \f
15072 ;; These patterns match the binary 387 instructions for addM3, subM3,
15073 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15074 ;; SFmode. The first is the normal insn, the second the same insn but
15075 ;; with one operand a conversion, and the third the same insn but with
15076 ;; the other operand a conversion. The conversion may be SFmode or
15077 ;; SImode if the target mode DFmode, but only SImode if the target mode
15078 ;; is SFmode.
15079
15080 ;; Gcc is slightly more smart about handling normal two address instructions
15081 ;; so use special patterns for add and mull.
15082
15083 (define_insn "*fop_<mode>_comm"
15084 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15085 (match_operator:MODEF 3 "binary_fp_operator"
15086 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15087 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15088 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15089 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15090 && COMMUTATIVE_ARITH_P (operands[3])
15091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15092 "* return output_387_binary_op (insn, operands);"
15093 [(set (attr "type")
15094 (if_then_else (eq_attr "alternative" "1,2")
15095 (if_then_else (match_operand:MODEF 3 "mult_operator")
15096 (const_string "ssemul")
15097 (const_string "sseadd"))
15098 (if_then_else (match_operand:MODEF 3 "mult_operator")
15099 (const_string "fmul")
15100 (const_string "fop"))))
15101 (set_attr "isa" "*,noavx,avx")
15102 (set_attr "prefix" "orig,orig,vex")
15103 (set_attr "mode" "<MODE>")
15104 (set (attr "enabled")
15105 (if_then_else
15106 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15107 (if_then_else
15108 (eq_attr "alternative" "0")
15109 (symbol_ref "TARGET_MIX_SSE_I387
15110 && X87_ENABLE_ARITH (<MODE>mode)")
15111 (const_string "*"))
15112 (if_then_else
15113 (eq_attr "alternative" "0")
15114 (symbol_ref "true")
15115 (symbol_ref "false"))))])
15116
15117 (define_insn "*rcpsf2_sse"
15118 [(set (match_operand:SF 0 "register_operand" "=x")
15119 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15120 UNSPEC_RCP))]
15121 "TARGET_SSE && TARGET_SSE_MATH"
15122 "%vrcpss\t{%1, %d0|%d0, %1}"
15123 [(set_attr "type" "sse")
15124 (set_attr "atom_sse_attr" "rcp")
15125 (set_attr "btver2_sse_attr" "rcp")
15126 (set_attr "prefix" "maybe_vex")
15127 (set_attr "mode" "SF")])
15128
15129 (define_insn "*fop_<mode>_1"
15130 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
15131 (match_operator:MODEF 3 "binary_fp_operator"
15132 [(match_operand:MODEF 1
15133 "x87nonimm_ssenomem_operand" "0,fm,0,v")
15134 (match_operand:MODEF 2
15135 "nonimmediate_operand" "fm,0,xm,vm")]))]
15136 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15137 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15138 && !COMMUTATIVE_ARITH_P (operands[3])
15139 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15140 "* return output_387_binary_op (insn, operands);"
15141 [(set (attr "type")
15142 (if_then_else (eq_attr "alternative" "2,3")
15143 (if_then_else (match_operand:MODEF 3 "div_operator")
15144 (const_string "ssediv")
15145 (const_string "sseadd"))
15146 (if_then_else (match_operand:MODEF 3 "div_operator")
15147 (const_string "fdiv")
15148 (const_string "fop"))))
15149 (set_attr "isa" "*,*,noavx,avx")
15150 (set_attr "prefix" "orig,orig,orig,vex")
15151 (set_attr "mode" "<MODE>")
15152 (set (attr "enabled")
15153 (if_then_else
15154 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15155 (if_then_else
15156 (eq_attr "alternative" "0,1")
15157 (symbol_ref "TARGET_MIX_SSE_I387
15158 && X87_ENABLE_ARITH (<MODE>mode)")
15159 (const_string "*"))
15160 (if_then_else
15161 (eq_attr "alternative" "0,1")
15162 (symbol_ref "true")
15163 (symbol_ref "false"))))])
15164
15165 ;; ??? Add SSE splitters for these!
15166 (define_insn "*fop_<MODEF:mode>_2_i387"
15167 [(set (match_operand:MODEF 0 "register_operand" "=f")
15168 (match_operator:MODEF 3 "binary_fp_operator"
15169 [(float:MODEF
15170 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15171 (match_operand:MODEF 2 "register_operand" "0")]))]
15172 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15173 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15174 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15175 || optimize_function_for_size_p (cfun))"
15176 "* return output_387_binary_op (insn, operands);"
15177 [(set (attr "type")
15178 (cond [(match_operand:MODEF 3 "mult_operator")
15179 (const_string "fmul")
15180 (match_operand:MODEF 3 "div_operator")
15181 (const_string "fdiv")
15182 ]
15183 (const_string "fop")))
15184 (set_attr "fp_int_src" "true")
15185 (set_attr "mode" "<SWI24:MODE>")])
15186
15187 (define_insn "*fop_<MODEF:mode>_3_i387"
15188 [(set (match_operand:MODEF 0 "register_operand" "=f")
15189 (match_operator:MODEF 3 "binary_fp_operator"
15190 [(match_operand:MODEF 1 "register_operand" "0")
15191 (float:MODEF
15192 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15193 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15194 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15195 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15196 || optimize_function_for_size_p (cfun))"
15197 "* return output_387_binary_op (insn, operands);"
15198 [(set (attr "type")
15199 (cond [(match_operand:MODEF 3 "mult_operator")
15200 (const_string "fmul")
15201 (match_operand:MODEF 3 "div_operator")
15202 (const_string "fdiv")
15203 ]
15204 (const_string "fop")))
15205 (set_attr "fp_int_src" "true")
15206 (set_attr "mode" "<MODE>")])
15207
15208 (define_insn "*fop_df_4_i387"
15209 [(set (match_operand:DF 0 "register_operand" "=f,f")
15210 (match_operator:DF 3 "binary_fp_operator"
15211 [(float_extend:DF
15212 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15213 (match_operand:DF 2 "register_operand" "0,f")]))]
15214 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15215 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15216 "* return output_387_binary_op (insn, operands);"
15217 [(set (attr "type")
15218 (cond [(match_operand:DF 3 "mult_operator")
15219 (const_string "fmul")
15220 (match_operand:DF 3 "div_operator")
15221 (const_string "fdiv")
15222 ]
15223 (const_string "fop")))
15224 (set_attr "mode" "SF")])
15225
15226 (define_insn "*fop_df_5_i387"
15227 [(set (match_operand:DF 0 "register_operand" "=f,f")
15228 (match_operator:DF 3 "binary_fp_operator"
15229 [(match_operand:DF 1 "register_operand" "0,f")
15230 (float_extend:DF
15231 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15232 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15233 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15234 "* return output_387_binary_op (insn, operands);"
15235 [(set (attr "type")
15236 (cond [(match_operand:DF 3 "mult_operator")
15237 (const_string "fmul")
15238 (match_operand:DF 3 "div_operator")
15239 (const_string "fdiv")
15240 ]
15241 (const_string "fop")))
15242 (set_attr "mode" "SF")])
15243
15244 (define_insn "*fop_df_6_i387"
15245 [(set (match_operand:DF 0 "register_operand" "=f,f")
15246 (match_operator:DF 3 "binary_fp_operator"
15247 [(float_extend:DF
15248 (match_operand:SF 1 "register_operand" "0,f"))
15249 (float_extend:DF
15250 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15251 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15252 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15253 "* return output_387_binary_op (insn, operands);"
15254 [(set (attr "type")
15255 (cond [(match_operand:DF 3 "mult_operator")
15256 (const_string "fmul")
15257 (match_operand:DF 3 "div_operator")
15258 (const_string "fdiv")
15259 ]
15260 (const_string "fop")))
15261 (set_attr "mode" "SF")])
15262
15263 (define_insn "*fop_xf_comm_i387"
15264 [(set (match_operand:XF 0 "register_operand" "=f")
15265 (match_operator:XF 3 "binary_fp_operator"
15266 [(match_operand:XF 1 "register_operand" "%0")
15267 (match_operand:XF 2 "register_operand" "f")]))]
15268 "TARGET_80387
15269 && COMMUTATIVE_ARITH_P (operands[3])"
15270 "* return output_387_binary_op (insn, operands);"
15271 [(set (attr "type")
15272 (if_then_else (match_operand:XF 3 "mult_operator")
15273 (const_string "fmul")
15274 (const_string "fop")))
15275 (set_attr "mode" "XF")])
15276
15277 (define_insn "*fop_xf_1_i387"
15278 [(set (match_operand:XF 0 "register_operand" "=f,f")
15279 (match_operator:XF 3 "binary_fp_operator"
15280 [(match_operand:XF 1 "register_operand" "0,f")
15281 (match_operand:XF 2 "register_operand" "f,0")]))]
15282 "TARGET_80387
15283 && !COMMUTATIVE_ARITH_P (operands[3])"
15284 "* return output_387_binary_op (insn, operands);"
15285 [(set (attr "type")
15286 (if_then_else (match_operand:XF 3 "div_operator")
15287 (const_string "fdiv")
15288 (const_string "fop")))
15289 (set_attr "mode" "XF")])
15290
15291 (define_insn "*fop_xf_2_i387"
15292 [(set (match_operand:XF 0 "register_operand" "=f")
15293 (match_operator:XF 3 "binary_fp_operator"
15294 [(float:XF
15295 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15296 (match_operand:XF 2 "register_operand" "0")]))]
15297 "TARGET_80387
15298 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15299 "* return output_387_binary_op (insn, operands);"
15300 [(set (attr "type")
15301 (cond [(match_operand:XF 3 "mult_operator")
15302 (const_string "fmul")
15303 (match_operand:XF 3 "div_operator")
15304 (const_string "fdiv")
15305 ]
15306 (const_string "fop")))
15307 (set_attr "fp_int_src" "true")
15308 (set_attr "mode" "<MODE>")])
15309
15310 (define_insn "*fop_xf_3_i387"
15311 [(set (match_operand:XF 0 "register_operand" "=f")
15312 (match_operator:XF 3 "binary_fp_operator"
15313 [(match_operand:XF 1 "register_operand" "0")
15314 (float:XF
15315 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15316 "TARGET_80387
15317 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15318 "* return output_387_binary_op (insn, operands);"
15319 [(set (attr "type")
15320 (cond [(match_operand:XF 3 "mult_operator")
15321 (const_string "fmul")
15322 (match_operand:XF 3 "div_operator")
15323 (const_string "fdiv")
15324 ]
15325 (const_string "fop")))
15326 (set_attr "fp_int_src" "true")
15327 (set_attr "mode" "<MODE>")])
15328
15329 (define_insn "*fop_xf_4_i387"
15330 [(set (match_operand:XF 0 "register_operand" "=f,f")
15331 (match_operator:XF 3 "binary_fp_operator"
15332 [(float_extend:XF
15333 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15334 (match_operand:XF 2 "register_operand" "0,f")]))]
15335 "TARGET_80387"
15336 "* return output_387_binary_op (insn, operands);"
15337 [(set (attr "type")
15338 (cond [(match_operand:XF 3 "mult_operator")
15339 (const_string "fmul")
15340 (match_operand:XF 3 "div_operator")
15341 (const_string "fdiv")
15342 ]
15343 (const_string "fop")))
15344 (set_attr "mode" "<MODE>")])
15345
15346 (define_insn "*fop_xf_5_i387"
15347 [(set (match_operand:XF 0 "register_operand" "=f,f")
15348 (match_operator:XF 3 "binary_fp_operator"
15349 [(match_operand:XF 1 "register_operand" "0,f")
15350 (float_extend:XF
15351 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15352 "TARGET_80387"
15353 "* return output_387_binary_op (insn, operands);"
15354 [(set (attr "type")
15355 (cond [(match_operand:XF 3 "mult_operator")
15356 (const_string "fmul")
15357 (match_operand:XF 3 "div_operator")
15358 (const_string "fdiv")
15359 ]
15360 (const_string "fop")))
15361 (set_attr "mode" "<MODE>")])
15362
15363 (define_insn "*fop_xf_6_i387"
15364 [(set (match_operand:XF 0 "register_operand" "=f,f")
15365 (match_operator:XF 3 "binary_fp_operator"
15366 [(float_extend:XF
15367 (match_operand:MODEF 1 "register_operand" "0,f"))
15368 (float_extend:XF
15369 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15370 "TARGET_80387"
15371 "* return output_387_binary_op (insn, operands);"
15372 [(set (attr "type")
15373 (cond [(match_operand:XF 3 "mult_operator")
15374 (const_string "fmul")
15375 (match_operand:XF 3 "div_operator")
15376 (const_string "fdiv")
15377 ]
15378 (const_string "fop")))
15379 (set_attr "mode" "<MODE>")])
15380 \f
15381 ;; FPU special functions.
15382
15383 ;; This pattern implements a no-op XFmode truncation for
15384 ;; all fancy i386 XFmode math functions.
15385
15386 (define_insn "truncxf<mode>2_i387_noop_unspec"
15387 [(set (match_operand:MODEF 0 "register_operand" "=f")
15388 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15389 UNSPEC_TRUNC_NOOP))]
15390 "TARGET_USE_FANCY_MATH_387"
15391 "* return output_387_reg_move (insn, operands);"
15392 [(set_attr "type" "fmov")
15393 (set_attr "mode" "<MODE>")])
15394
15395 (define_insn "sqrtxf2"
15396 [(set (match_operand:XF 0 "register_operand" "=f")
15397 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15398 "TARGET_USE_FANCY_MATH_387"
15399 "fsqrt"
15400 [(set_attr "type" "fpspc")
15401 (set_attr "mode" "XF")
15402 (set_attr "athlon_decode" "direct")
15403 (set_attr "amdfam10_decode" "direct")
15404 (set_attr "bdver1_decode" "direct")])
15405
15406 (define_insn "sqrt_extend<mode>xf2_i387"
15407 [(set (match_operand:XF 0 "register_operand" "=f")
15408 (sqrt:XF
15409 (float_extend:XF
15410 (match_operand:MODEF 1 "register_operand" "0"))))]
15411 "TARGET_USE_FANCY_MATH_387"
15412 "fsqrt"
15413 [(set_attr "type" "fpspc")
15414 (set_attr "mode" "XF")
15415 (set_attr "athlon_decode" "direct")
15416 (set_attr "amdfam10_decode" "direct")
15417 (set_attr "bdver1_decode" "direct")])
15418
15419 (define_insn "*rsqrtsf2_sse"
15420 [(set (match_operand:SF 0 "register_operand" "=x")
15421 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15422 UNSPEC_RSQRT))]
15423 "TARGET_SSE && TARGET_SSE_MATH"
15424 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15425 [(set_attr "type" "sse")
15426 (set_attr "atom_sse_attr" "rcp")
15427 (set_attr "btver2_sse_attr" "rcp")
15428 (set_attr "prefix" "maybe_vex")
15429 (set_attr "mode" "SF")])
15430
15431 (define_expand "rsqrtsf2"
15432 [(set (match_operand:SF 0 "register_operand")
15433 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15434 UNSPEC_RSQRT))]
15435 "TARGET_SSE && TARGET_SSE_MATH"
15436 {
15437 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15438 DONE;
15439 })
15440
15441 (define_insn "*sqrt<mode>2_sse"
15442 [(set (match_operand:MODEF 0 "register_operand" "=v")
15443 (sqrt:MODEF
15444 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15445 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15446 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15447 [(set_attr "type" "sse")
15448 (set_attr "atom_sse_attr" "sqrt")
15449 (set_attr "btver2_sse_attr" "sqrt")
15450 (set_attr "prefix" "maybe_vex")
15451 (set_attr "mode" "<MODE>")
15452 (set_attr "athlon_decode" "*")
15453 (set_attr "amdfam10_decode" "*")
15454 (set_attr "bdver1_decode" "*")])
15455
15456 (define_expand "sqrt<mode>2"
15457 [(set (match_operand:MODEF 0 "register_operand")
15458 (sqrt:MODEF
15459 (match_operand:MODEF 1 "nonimmediate_operand")))]
15460 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15461 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15462 {
15463 if (<MODE>mode == SFmode
15464 && TARGET_SSE && TARGET_SSE_MATH
15465 && TARGET_RECIP_SQRT
15466 && !optimize_function_for_size_p (cfun)
15467 && flag_finite_math_only && !flag_trapping_math
15468 && flag_unsafe_math_optimizations)
15469 {
15470 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15471 DONE;
15472 }
15473
15474 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15475 {
15476 rtx op0 = gen_reg_rtx (XFmode);
15477 rtx op1 = force_reg (<MODE>mode, operands[1]);
15478
15479 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15480 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15481 DONE;
15482 }
15483 })
15484
15485 (define_insn "fpremxf4_i387"
15486 [(set (match_operand:XF 0 "register_operand" "=f")
15487 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15488 (match_operand:XF 3 "register_operand" "1")]
15489 UNSPEC_FPREM_F))
15490 (set (match_operand:XF 1 "register_operand" "=u")
15491 (unspec:XF [(match_dup 2) (match_dup 3)]
15492 UNSPEC_FPREM_U))
15493 (set (reg:CCFP FPSR_REG)
15494 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15495 UNSPEC_C2_FLAG))]
15496 "TARGET_USE_FANCY_MATH_387
15497 && flag_finite_math_only"
15498 "fprem"
15499 [(set_attr "type" "fpspc")
15500 (set_attr "znver1_decode" "vector")
15501 (set_attr "mode" "XF")])
15502
15503 (define_expand "fmodxf3"
15504 [(use (match_operand:XF 0 "register_operand"))
15505 (use (match_operand:XF 1 "general_operand"))
15506 (use (match_operand:XF 2 "general_operand"))]
15507 "TARGET_USE_FANCY_MATH_387
15508 && flag_finite_math_only"
15509 {
15510 rtx_code_label *label = gen_label_rtx ();
15511
15512 rtx op1 = gen_reg_rtx (XFmode);
15513 rtx op2 = gen_reg_rtx (XFmode);
15514
15515 emit_move_insn (op2, operands[2]);
15516 emit_move_insn (op1, operands[1]);
15517
15518 emit_label (label);
15519 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15520 ix86_emit_fp_unordered_jump (label);
15521 LABEL_NUSES (label) = 1;
15522
15523 emit_move_insn (operands[0], op1);
15524 DONE;
15525 })
15526
15527 (define_expand "fmod<mode>3"
15528 [(use (match_operand:MODEF 0 "register_operand"))
15529 (use (match_operand:MODEF 1 "general_operand"))
15530 (use (match_operand:MODEF 2 "general_operand"))]
15531 "TARGET_USE_FANCY_MATH_387
15532 && flag_finite_math_only"
15533 {
15534 rtx (*gen_truncxf) (rtx, rtx);
15535
15536 rtx_code_label *label = gen_label_rtx ();
15537
15538 rtx op1 = gen_reg_rtx (XFmode);
15539 rtx op2 = gen_reg_rtx (XFmode);
15540
15541 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15542 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15543
15544 emit_label (label);
15545 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15546 ix86_emit_fp_unordered_jump (label);
15547 LABEL_NUSES (label) = 1;
15548
15549 /* Truncate the result properly for strict SSE math. */
15550 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15551 && !TARGET_MIX_SSE_I387)
15552 gen_truncxf = gen_truncxf<mode>2;
15553 else
15554 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15555
15556 emit_insn (gen_truncxf (operands[0], op1));
15557 DONE;
15558 })
15559
15560 (define_insn "fprem1xf4_i387"
15561 [(set (match_operand:XF 0 "register_operand" "=f")
15562 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15563 (match_operand:XF 3 "register_operand" "1")]
15564 UNSPEC_FPREM1_F))
15565 (set (match_operand:XF 1 "register_operand" "=u")
15566 (unspec:XF [(match_dup 2) (match_dup 3)]
15567 UNSPEC_FPREM1_U))
15568 (set (reg:CCFP FPSR_REG)
15569 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15570 UNSPEC_C2_FLAG))]
15571 "TARGET_USE_FANCY_MATH_387
15572 && flag_finite_math_only"
15573 "fprem1"
15574 [(set_attr "type" "fpspc")
15575 (set_attr "znver1_decode" "vector")
15576 (set_attr "mode" "XF")])
15577
15578 (define_expand "remainderxf3"
15579 [(use (match_operand:XF 0 "register_operand"))
15580 (use (match_operand:XF 1 "general_operand"))
15581 (use (match_operand:XF 2 "general_operand"))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && flag_finite_math_only"
15584 {
15585 rtx_code_label *label = gen_label_rtx ();
15586
15587 rtx op1 = gen_reg_rtx (XFmode);
15588 rtx op2 = gen_reg_rtx (XFmode);
15589
15590 emit_move_insn (op2, operands[2]);
15591 emit_move_insn (op1, operands[1]);
15592
15593 emit_label (label);
15594 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15595 ix86_emit_fp_unordered_jump (label);
15596 LABEL_NUSES (label) = 1;
15597
15598 emit_move_insn (operands[0], op1);
15599 DONE;
15600 })
15601
15602 (define_expand "remainder<mode>3"
15603 [(use (match_operand:MODEF 0 "register_operand"))
15604 (use (match_operand:MODEF 1 "general_operand"))
15605 (use (match_operand:MODEF 2 "general_operand"))]
15606 "TARGET_USE_FANCY_MATH_387
15607 && flag_finite_math_only"
15608 {
15609 rtx (*gen_truncxf) (rtx, rtx);
15610
15611 rtx_code_label *label = gen_label_rtx ();
15612
15613 rtx op1 = gen_reg_rtx (XFmode);
15614 rtx op2 = gen_reg_rtx (XFmode);
15615
15616 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15617 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15618
15619 emit_label (label);
15620
15621 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15622 ix86_emit_fp_unordered_jump (label);
15623 LABEL_NUSES (label) = 1;
15624
15625 /* Truncate the result properly for strict SSE math. */
15626 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15627 && !TARGET_MIX_SSE_I387)
15628 gen_truncxf = gen_truncxf<mode>2;
15629 else
15630 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15631
15632 emit_insn (gen_truncxf (operands[0], op1));
15633 DONE;
15634 })
15635
15636 (define_int_iterator SINCOS
15637 [UNSPEC_SIN
15638 UNSPEC_COS])
15639
15640 (define_int_attr sincos
15641 [(UNSPEC_SIN "sin")
15642 (UNSPEC_COS "cos")])
15643
15644 (define_insn "*<sincos>xf2_i387"
15645 [(set (match_operand:XF 0 "register_operand" "=f")
15646 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15647 SINCOS))]
15648 "TARGET_USE_FANCY_MATH_387
15649 && flag_unsafe_math_optimizations"
15650 "f<sincos>"
15651 [(set_attr "type" "fpspc")
15652 (set_attr "znver1_decode" "vector")
15653 (set_attr "mode" "XF")])
15654
15655 (define_insn "*<sincos>_extend<mode>xf2_i387"
15656 [(set (match_operand:XF 0 "register_operand" "=f")
15657 (unspec:XF [(float_extend:XF
15658 (match_operand:MODEF 1 "register_operand" "0"))]
15659 SINCOS))]
15660 "TARGET_USE_FANCY_MATH_387
15661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15662 || TARGET_MIX_SSE_I387)
15663 && flag_unsafe_math_optimizations"
15664 "f<sincos>"
15665 [(set_attr "type" "fpspc")
15666 (set_attr "znver1_decode" "vector")
15667 (set_attr "mode" "XF")])
15668
15669 ;; When sincos pattern is defined, sin and cos builtin functions will be
15670 ;; expanded to sincos pattern with one of its outputs left unused.
15671 ;; CSE pass will figure out if two sincos patterns can be combined,
15672 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15673 ;; depending on the unused output.
15674
15675 (define_insn "sincosxf3"
15676 [(set (match_operand:XF 0 "register_operand" "=f")
15677 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15678 UNSPEC_SINCOS_COS))
15679 (set (match_operand:XF 1 "register_operand" "=u")
15680 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15681 "TARGET_USE_FANCY_MATH_387
15682 && flag_unsafe_math_optimizations"
15683 "fsincos"
15684 [(set_attr "type" "fpspc")
15685 (set_attr "znver1_decode" "vector")
15686 (set_attr "mode" "XF")])
15687
15688 (define_split
15689 [(set (match_operand:XF 0 "register_operand")
15690 (unspec:XF [(match_operand:XF 2 "register_operand")]
15691 UNSPEC_SINCOS_COS))
15692 (set (match_operand:XF 1 "register_operand")
15693 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15694 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15695 && can_create_pseudo_p ()"
15696 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15697
15698 (define_split
15699 [(set (match_operand:XF 0 "register_operand")
15700 (unspec:XF [(match_operand:XF 2 "register_operand")]
15701 UNSPEC_SINCOS_COS))
15702 (set (match_operand:XF 1 "register_operand")
15703 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15704 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15705 && can_create_pseudo_p ()"
15706 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15707
15708 (define_insn "sincos_extend<mode>xf3_i387"
15709 [(set (match_operand:XF 0 "register_operand" "=f")
15710 (unspec:XF [(float_extend:XF
15711 (match_operand:MODEF 2 "register_operand" "0"))]
15712 UNSPEC_SINCOS_COS))
15713 (set (match_operand:XF 1 "register_operand" "=u")
15714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15715 "TARGET_USE_FANCY_MATH_387
15716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15717 || TARGET_MIX_SSE_I387)
15718 && flag_unsafe_math_optimizations"
15719 "fsincos"
15720 [(set_attr "type" "fpspc")
15721 (set_attr "znver1_decode" "vector")
15722 (set_attr "mode" "XF")])
15723
15724 (define_split
15725 [(set (match_operand:XF 0 "register_operand")
15726 (unspec:XF [(float_extend:XF
15727 (match_operand:MODEF 2 "register_operand"))]
15728 UNSPEC_SINCOS_COS))
15729 (set (match_operand:XF 1 "register_operand")
15730 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15731 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15732 && can_create_pseudo_p ()"
15733 [(set (match_dup 1)
15734 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15735
15736 (define_split
15737 [(set (match_operand:XF 0 "register_operand")
15738 (unspec:XF [(float_extend:XF
15739 (match_operand:MODEF 2 "register_operand"))]
15740 UNSPEC_SINCOS_COS))
15741 (set (match_operand:XF 1 "register_operand")
15742 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15743 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15744 && can_create_pseudo_p ()"
15745 [(set (match_dup 0)
15746 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15747
15748 (define_expand "sincos<mode>3"
15749 [(use (match_operand:MODEF 0 "register_operand"))
15750 (use (match_operand:MODEF 1 "register_operand"))
15751 (use (match_operand:MODEF 2 "register_operand"))]
15752 "TARGET_USE_FANCY_MATH_387
15753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15754 || TARGET_MIX_SSE_I387)
15755 && flag_unsafe_math_optimizations"
15756 {
15757 rtx op0 = gen_reg_rtx (XFmode);
15758 rtx op1 = gen_reg_rtx (XFmode);
15759
15760 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15761 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15762 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15763 DONE;
15764 })
15765
15766 (define_insn "fptanxf4_i387"
15767 [(set (match_operand:XF 0 "register_operand" "=f")
15768 (match_operand:XF 3 "const_double_operand" "F"))
15769 (set (match_operand:XF 1 "register_operand" "=u")
15770 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15771 UNSPEC_TAN))]
15772 "TARGET_USE_FANCY_MATH_387
15773 && flag_unsafe_math_optimizations
15774 && standard_80387_constant_p (operands[3]) == 2"
15775 "fptan"
15776 [(set_attr "type" "fpspc")
15777 (set_attr "znver1_decode" "vector")
15778 (set_attr "mode" "XF")])
15779
15780 (define_insn "fptan_extend<mode>xf4_i387"
15781 [(set (match_operand:MODEF 0 "register_operand" "=f")
15782 (match_operand:MODEF 3 "const_double_operand" "F"))
15783 (set (match_operand:XF 1 "register_operand" "=u")
15784 (unspec:XF [(float_extend:XF
15785 (match_operand:MODEF 2 "register_operand" "0"))]
15786 UNSPEC_TAN))]
15787 "TARGET_USE_FANCY_MATH_387
15788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15789 || TARGET_MIX_SSE_I387)
15790 && flag_unsafe_math_optimizations
15791 && standard_80387_constant_p (operands[3]) == 2"
15792 "fptan"
15793 [(set_attr "type" "fpspc")
15794 (set_attr "znver1_decode" "vector")
15795 (set_attr "mode" "XF")])
15796
15797 (define_expand "tanxf2"
15798 [(use (match_operand:XF 0 "register_operand"))
15799 (use (match_operand:XF 1 "register_operand"))]
15800 "TARGET_USE_FANCY_MATH_387
15801 && flag_unsafe_math_optimizations"
15802 {
15803 rtx one = gen_reg_rtx (XFmode);
15804 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15805
15806 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15807 DONE;
15808 })
15809
15810 (define_expand "tan<mode>2"
15811 [(use (match_operand:MODEF 0 "register_operand"))
15812 (use (match_operand:MODEF 1 "register_operand"))]
15813 "TARGET_USE_FANCY_MATH_387
15814 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15815 || TARGET_MIX_SSE_I387)
15816 && flag_unsafe_math_optimizations"
15817 {
15818 rtx op0 = gen_reg_rtx (XFmode);
15819
15820 rtx one = gen_reg_rtx (<MODE>mode);
15821 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15822
15823 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15824 operands[1], op2));
15825 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15826 DONE;
15827 })
15828
15829 (define_insn "*fpatanxf3_i387"
15830 [(set (match_operand:XF 0 "register_operand" "=f")
15831 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15832 (match_operand:XF 2 "register_operand" "u")]
15833 UNSPEC_FPATAN))
15834 (clobber (match_scratch:XF 3 "=2"))]
15835 "TARGET_USE_FANCY_MATH_387
15836 && flag_unsafe_math_optimizations"
15837 "fpatan"
15838 [(set_attr "type" "fpspc")
15839 (set_attr "znver1_decode" "vector")
15840 (set_attr "mode" "XF")])
15841
15842 (define_insn "fpatan_extend<mode>xf3_i387"
15843 [(set (match_operand:XF 0 "register_operand" "=f")
15844 (unspec:XF [(float_extend:XF
15845 (match_operand:MODEF 1 "register_operand" "0"))
15846 (float_extend:XF
15847 (match_operand:MODEF 2 "register_operand" "u"))]
15848 UNSPEC_FPATAN))
15849 (clobber (match_scratch:XF 3 "=2"))]
15850 "TARGET_USE_FANCY_MATH_387
15851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15852 || TARGET_MIX_SSE_I387)
15853 && flag_unsafe_math_optimizations"
15854 "fpatan"
15855 [(set_attr "type" "fpspc")
15856 (set_attr "znver1_decode" "vector")
15857 (set_attr "mode" "XF")])
15858
15859 (define_expand "atan2xf3"
15860 [(parallel [(set (match_operand:XF 0 "register_operand")
15861 (unspec:XF [(match_operand:XF 2 "register_operand")
15862 (match_operand:XF 1 "register_operand")]
15863 UNSPEC_FPATAN))
15864 (clobber (match_scratch:XF 3))])]
15865 "TARGET_USE_FANCY_MATH_387
15866 && flag_unsafe_math_optimizations")
15867
15868 (define_expand "atan2<mode>3"
15869 [(use (match_operand:MODEF 0 "register_operand"))
15870 (use (match_operand:MODEF 1 "register_operand"))
15871 (use (match_operand:MODEF 2 "register_operand"))]
15872 "TARGET_USE_FANCY_MATH_387
15873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15874 || TARGET_MIX_SSE_I387)
15875 && flag_unsafe_math_optimizations"
15876 {
15877 rtx op0 = gen_reg_rtx (XFmode);
15878
15879 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15880 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15881 DONE;
15882 })
15883
15884 (define_expand "atanxf2"
15885 [(parallel [(set (match_operand:XF 0 "register_operand")
15886 (unspec:XF [(match_dup 2)
15887 (match_operand:XF 1 "register_operand")]
15888 UNSPEC_FPATAN))
15889 (clobber (match_scratch:XF 3))])]
15890 "TARGET_USE_FANCY_MATH_387
15891 && flag_unsafe_math_optimizations"
15892 {
15893 operands[2] = gen_reg_rtx (XFmode);
15894 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15895 })
15896
15897 (define_expand "atan<mode>2"
15898 [(use (match_operand:MODEF 0 "register_operand"))
15899 (use (match_operand:MODEF 1 "register_operand"))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15902 || TARGET_MIX_SSE_I387)
15903 && flag_unsafe_math_optimizations"
15904 {
15905 rtx op0 = gen_reg_rtx (XFmode);
15906
15907 rtx op2 = gen_reg_rtx (<MODE>mode);
15908 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15909
15910 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15911 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15912 DONE;
15913 })
15914
15915 (define_expand "asinxf2"
15916 [(set (match_dup 2)
15917 (mult:XF (match_operand:XF 1 "register_operand")
15918 (match_dup 1)))
15919 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15920 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15921 (parallel [(set (match_operand:XF 0 "register_operand")
15922 (unspec:XF [(match_dup 5) (match_dup 1)]
15923 UNSPEC_FPATAN))
15924 (clobber (match_scratch:XF 6))])]
15925 "TARGET_USE_FANCY_MATH_387
15926 && flag_unsafe_math_optimizations"
15927 {
15928 int i;
15929
15930 for (i = 2; i < 6; i++)
15931 operands[i] = gen_reg_rtx (XFmode);
15932
15933 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15934 })
15935
15936 (define_expand "asin<mode>2"
15937 [(use (match_operand:MODEF 0 "register_operand"))
15938 (use (match_operand:MODEF 1 "general_operand"))]
15939 "TARGET_USE_FANCY_MATH_387
15940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15941 || TARGET_MIX_SSE_I387)
15942 && flag_unsafe_math_optimizations"
15943 {
15944 rtx op0 = gen_reg_rtx (XFmode);
15945 rtx op1 = gen_reg_rtx (XFmode);
15946
15947 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15948 emit_insn (gen_asinxf2 (op0, op1));
15949 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15950 DONE;
15951 })
15952
15953 (define_expand "acosxf2"
15954 [(set (match_dup 2)
15955 (mult:XF (match_operand:XF 1 "register_operand")
15956 (match_dup 1)))
15957 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15958 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15959 (parallel [(set (match_operand:XF 0 "register_operand")
15960 (unspec:XF [(match_dup 1) (match_dup 5)]
15961 UNSPEC_FPATAN))
15962 (clobber (match_scratch:XF 6))])]
15963 "TARGET_USE_FANCY_MATH_387
15964 && flag_unsafe_math_optimizations"
15965 {
15966 int i;
15967
15968 for (i = 2; i < 6; i++)
15969 operands[i] = gen_reg_rtx (XFmode);
15970
15971 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15972 })
15973
15974 (define_expand "acos<mode>2"
15975 [(use (match_operand:MODEF 0 "register_operand"))
15976 (use (match_operand:MODEF 1 "general_operand"))]
15977 "TARGET_USE_FANCY_MATH_387
15978 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15979 || TARGET_MIX_SSE_I387)
15980 && flag_unsafe_math_optimizations"
15981 {
15982 rtx op0 = gen_reg_rtx (XFmode);
15983 rtx op1 = gen_reg_rtx (XFmode);
15984
15985 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15986 emit_insn (gen_acosxf2 (op0, op1));
15987 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15988 DONE;
15989 })
15990
15991 (define_insn "fyl2xxf3_i387"
15992 [(set (match_operand:XF 0 "register_operand" "=f")
15993 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15994 (match_operand:XF 2 "register_operand" "u")]
15995 UNSPEC_FYL2X))
15996 (clobber (match_scratch:XF 3 "=2"))]
15997 "TARGET_USE_FANCY_MATH_387
15998 && flag_unsafe_math_optimizations"
15999 "fyl2x"
16000 [(set_attr "type" "fpspc")
16001 (set_attr "znver1_decode" "vector")
16002 (set_attr "mode" "XF")])
16003
16004 (define_insn "fyl2x_extend<mode>xf3_i387"
16005 [(set (match_operand:XF 0 "register_operand" "=f")
16006 (unspec:XF [(float_extend:XF
16007 (match_operand:MODEF 1 "register_operand" "0"))
16008 (match_operand:XF 2 "register_operand" "u")]
16009 UNSPEC_FYL2X))
16010 (clobber (match_scratch:XF 3 "=2"))]
16011 "TARGET_USE_FANCY_MATH_387
16012 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16013 || TARGET_MIX_SSE_I387)
16014 && flag_unsafe_math_optimizations"
16015 "fyl2x"
16016 [(set_attr "type" "fpspc")
16017 (set_attr "znver1_decode" "vector")
16018 (set_attr "mode" "XF")])
16019
16020 (define_expand "logxf2"
16021 [(parallel [(set (match_operand:XF 0 "register_operand")
16022 (unspec:XF [(match_operand:XF 1 "register_operand")
16023 (match_dup 2)] UNSPEC_FYL2X))
16024 (clobber (match_scratch:XF 3))])]
16025 "TARGET_USE_FANCY_MATH_387
16026 && flag_unsafe_math_optimizations"
16027 {
16028 operands[2] = gen_reg_rtx (XFmode);
16029 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16030 })
16031
16032 (define_expand "log<mode>2"
16033 [(use (match_operand:MODEF 0 "register_operand"))
16034 (use (match_operand:MODEF 1 "register_operand"))]
16035 "TARGET_USE_FANCY_MATH_387
16036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16037 || TARGET_MIX_SSE_I387)
16038 && flag_unsafe_math_optimizations"
16039 {
16040 rtx op0 = gen_reg_rtx (XFmode);
16041
16042 rtx op2 = gen_reg_rtx (XFmode);
16043 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16044
16045 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16047 DONE;
16048 })
16049
16050 (define_expand "log10xf2"
16051 [(parallel [(set (match_operand:XF 0 "register_operand")
16052 (unspec:XF [(match_operand:XF 1 "register_operand")
16053 (match_dup 2)] UNSPEC_FYL2X))
16054 (clobber (match_scratch:XF 3))])]
16055 "TARGET_USE_FANCY_MATH_387
16056 && flag_unsafe_math_optimizations"
16057 {
16058 operands[2] = gen_reg_rtx (XFmode);
16059 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16060 })
16061
16062 (define_expand "log10<mode>2"
16063 [(use (match_operand:MODEF 0 "register_operand"))
16064 (use (match_operand:MODEF 1 "register_operand"))]
16065 "TARGET_USE_FANCY_MATH_387
16066 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16067 || TARGET_MIX_SSE_I387)
16068 && flag_unsafe_math_optimizations"
16069 {
16070 rtx op0 = gen_reg_rtx (XFmode);
16071
16072 rtx op2 = gen_reg_rtx (XFmode);
16073 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16074
16075 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16077 DONE;
16078 })
16079
16080 (define_expand "log2xf2"
16081 [(parallel [(set (match_operand:XF 0 "register_operand")
16082 (unspec:XF [(match_operand:XF 1 "register_operand")
16083 (match_dup 2)] UNSPEC_FYL2X))
16084 (clobber (match_scratch:XF 3))])]
16085 "TARGET_USE_FANCY_MATH_387
16086 && flag_unsafe_math_optimizations"
16087 {
16088 operands[2] = gen_reg_rtx (XFmode);
16089 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16090 })
16091
16092 (define_expand "log2<mode>2"
16093 [(use (match_operand:MODEF 0 "register_operand"))
16094 (use (match_operand:MODEF 1 "register_operand"))]
16095 "TARGET_USE_FANCY_MATH_387
16096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16097 || TARGET_MIX_SSE_I387)
16098 && flag_unsafe_math_optimizations"
16099 {
16100 rtx op0 = gen_reg_rtx (XFmode);
16101
16102 rtx op2 = gen_reg_rtx (XFmode);
16103 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16104
16105 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16106 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16107 DONE;
16108 })
16109
16110 (define_insn "fyl2xp1xf3_i387"
16111 [(set (match_operand:XF 0 "register_operand" "=f")
16112 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16113 (match_operand:XF 2 "register_operand" "u")]
16114 UNSPEC_FYL2XP1))
16115 (clobber (match_scratch:XF 3 "=2"))]
16116 "TARGET_USE_FANCY_MATH_387
16117 && flag_unsafe_math_optimizations"
16118 "fyl2xp1"
16119 [(set_attr "type" "fpspc")
16120 (set_attr "znver1_decode" "vector")
16121 (set_attr "mode" "XF")])
16122
16123 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16124 [(set (match_operand:XF 0 "register_operand" "=f")
16125 (unspec:XF [(float_extend:XF
16126 (match_operand:MODEF 1 "register_operand" "0"))
16127 (match_operand:XF 2 "register_operand" "u")]
16128 UNSPEC_FYL2XP1))
16129 (clobber (match_scratch:XF 3 "=2"))]
16130 "TARGET_USE_FANCY_MATH_387
16131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16132 || TARGET_MIX_SSE_I387)
16133 && flag_unsafe_math_optimizations"
16134 "fyl2xp1"
16135 [(set_attr "type" "fpspc")
16136 (set_attr "znver1_decode" "vector")
16137 (set_attr "mode" "XF")])
16138
16139 (define_expand "log1pxf2"
16140 [(use (match_operand:XF 0 "register_operand"))
16141 (use (match_operand:XF 1 "register_operand"))]
16142 "TARGET_USE_FANCY_MATH_387
16143 && flag_unsafe_math_optimizations"
16144 {
16145 ix86_emit_i387_log1p (operands[0], operands[1]);
16146 DONE;
16147 })
16148
16149 (define_expand "log1p<mode>2"
16150 [(use (match_operand:MODEF 0 "register_operand"))
16151 (use (match_operand:MODEF 1 "register_operand"))]
16152 "TARGET_USE_FANCY_MATH_387
16153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16154 || TARGET_MIX_SSE_I387)
16155 && flag_unsafe_math_optimizations"
16156 {
16157 rtx op0;
16158
16159 op0 = gen_reg_rtx (XFmode);
16160
16161 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16162
16163 ix86_emit_i387_log1p (op0, operands[1]);
16164 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16165 DONE;
16166 })
16167
16168 (define_insn "fxtractxf3_i387"
16169 [(set (match_operand:XF 0 "register_operand" "=f")
16170 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16171 UNSPEC_XTRACT_FRACT))
16172 (set (match_operand:XF 1 "register_operand" "=u")
16173 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16174 "TARGET_USE_FANCY_MATH_387
16175 && flag_unsafe_math_optimizations"
16176 "fxtract"
16177 [(set_attr "type" "fpspc")
16178 (set_attr "znver1_decode" "vector")
16179 (set_attr "mode" "XF")])
16180
16181 (define_insn "fxtract_extend<mode>xf3_i387"
16182 [(set (match_operand:XF 0 "register_operand" "=f")
16183 (unspec:XF [(float_extend:XF
16184 (match_operand:MODEF 2 "register_operand" "0"))]
16185 UNSPEC_XTRACT_FRACT))
16186 (set (match_operand:XF 1 "register_operand" "=u")
16187 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16188 "TARGET_USE_FANCY_MATH_387
16189 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16190 || TARGET_MIX_SSE_I387)
16191 && flag_unsafe_math_optimizations"
16192 "fxtract"
16193 [(set_attr "type" "fpspc")
16194 (set_attr "znver1_decode" "vector")
16195 (set_attr "mode" "XF")])
16196
16197 (define_expand "logbxf2"
16198 [(parallel [(set (match_dup 2)
16199 (unspec:XF [(match_operand:XF 1 "register_operand")]
16200 UNSPEC_XTRACT_FRACT))
16201 (set (match_operand:XF 0 "register_operand")
16202 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16203 "TARGET_USE_FANCY_MATH_387
16204 && flag_unsafe_math_optimizations"
16205 "operands[2] = gen_reg_rtx (XFmode);")
16206
16207 (define_expand "logb<mode>2"
16208 [(use (match_operand:MODEF 0 "register_operand"))
16209 (use (match_operand:MODEF 1 "register_operand"))]
16210 "TARGET_USE_FANCY_MATH_387
16211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16212 || TARGET_MIX_SSE_I387)
16213 && flag_unsafe_math_optimizations"
16214 {
16215 rtx op0 = gen_reg_rtx (XFmode);
16216 rtx op1 = gen_reg_rtx (XFmode);
16217
16218 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16219 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16220 DONE;
16221 })
16222
16223 (define_expand "ilogbxf2"
16224 [(use (match_operand:SI 0 "register_operand"))
16225 (use (match_operand:XF 1 "register_operand"))]
16226 "TARGET_USE_FANCY_MATH_387
16227 && flag_unsafe_math_optimizations"
16228 {
16229 rtx op0, op1;
16230
16231 if (optimize_insn_for_size_p ())
16232 FAIL;
16233
16234 op0 = gen_reg_rtx (XFmode);
16235 op1 = gen_reg_rtx (XFmode);
16236
16237 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16238 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16239 DONE;
16240 })
16241
16242 (define_expand "ilogb<mode>2"
16243 [(use (match_operand:SI 0 "register_operand"))
16244 (use (match_operand:MODEF 1 "register_operand"))]
16245 "TARGET_USE_FANCY_MATH_387
16246 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16247 || TARGET_MIX_SSE_I387)
16248 && flag_unsafe_math_optimizations"
16249 {
16250 rtx op0, op1;
16251
16252 if (optimize_insn_for_size_p ())
16253 FAIL;
16254
16255 op0 = gen_reg_rtx (XFmode);
16256 op1 = gen_reg_rtx (XFmode);
16257
16258 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16259 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16260 DONE;
16261 })
16262
16263 (define_insn "*f2xm1xf2_i387"
16264 [(set (match_operand:XF 0 "register_operand" "=f")
16265 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16266 UNSPEC_F2XM1))]
16267 "TARGET_USE_FANCY_MATH_387
16268 && flag_unsafe_math_optimizations"
16269 "f2xm1"
16270 [(set_attr "type" "fpspc")
16271 (set_attr "znver1_decode" "vector")
16272 (set_attr "mode" "XF")])
16273
16274 (define_insn "fscalexf4_i387"
16275 [(set (match_operand:XF 0 "register_operand" "=f")
16276 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16277 (match_operand:XF 3 "register_operand" "1")]
16278 UNSPEC_FSCALE_FRACT))
16279 (set (match_operand:XF 1 "register_operand" "=u")
16280 (unspec:XF [(match_dup 2) (match_dup 3)]
16281 UNSPEC_FSCALE_EXP))]
16282 "TARGET_USE_FANCY_MATH_387
16283 && flag_unsafe_math_optimizations"
16284 "fscale"
16285 [(set_attr "type" "fpspc")
16286 (set_attr "znver1_decode" "vector")
16287 (set_attr "mode" "XF")])
16288
16289 (define_expand "expNcorexf3"
16290 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16291 (match_operand:XF 2 "register_operand")))
16292 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16293 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16294 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16295 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16296 (parallel [(set (match_operand:XF 0 "register_operand")
16297 (unspec:XF [(match_dup 8) (match_dup 4)]
16298 UNSPEC_FSCALE_FRACT))
16299 (set (match_dup 9)
16300 (unspec:XF [(match_dup 8) (match_dup 4)]
16301 UNSPEC_FSCALE_EXP))])]
16302 "TARGET_USE_FANCY_MATH_387
16303 && flag_unsafe_math_optimizations"
16304 {
16305 int i;
16306
16307 for (i = 3; i < 10; i++)
16308 operands[i] = gen_reg_rtx (XFmode);
16309
16310 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16311 })
16312
16313 (define_expand "expxf2"
16314 [(use (match_operand:XF 0 "register_operand"))
16315 (use (match_operand:XF 1 "register_operand"))]
16316 "TARGET_USE_FANCY_MATH_387
16317 && flag_unsafe_math_optimizations"
16318 {
16319 rtx op2;
16320
16321 op2 = gen_reg_rtx (XFmode);
16322 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16323
16324 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16325 DONE;
16326 })
16327
16328 (define_expand "exp<mode>2"
16329 [(use (match_operand:MODEF 0 "register_operand"))
16330 (use (match_operand:MODEF 1 "general_operand"))]
16331 "TARGET_USE_FANCY_MATH_387
16332 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16333 || TARGET_MIX_SSE_I387)
16334 && flag_unsafe_math_optimizations"
16335 {
16336 rtx op0, op1;
16337
16338 op0 = gen_reg_rtx (XFmode);
16339 op1 = gen_reg_rtx (XFmode);
16340
16341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16342 emit_insn (gen_expxf2 (op0, op1));
16343 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16344 DONE;
16345 })
16346
16347 (define_expand "exp10xf2"
16348 [(use (match_operand:XF 0 "register_operand"))
16349 (use (match_operand:XF 1 "register_operand"))]
16350 "TARGET_USE_FANCY_MATH_387
16351 && flag_unsafe_math_optimizations"
16352 {
16353 rtx op2;
16354
16355 op2 = gen_reg_rtx (XFmode);
16356 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16357
16358 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16359 DONE;
16360 })
16361
16362 (define_expand "exp10<mode>2"
16363 [(use (match_operand:MODEF 0 "register_operand"))
16364 (use (match_operand:MODEF 1 "general_operand"))]
16365 "TARGET_USE_FANCY_MATH_387
16366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16367 || TARGET_MIX_SSE_I387)
16368 && flag_unsafe_math_optimizations"
16369 {
16370 rtx op0, op1;
16371
16372 op0 = gen_reg_rtx (XFmode);
16373 op1 = gen_reg_rtx (XFmode);
16374
16375 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16376 emit_insn (gen_exp10xf2 (op0, op1));
16377 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16378 DONE;
16379 })
16380
16381 (define_expand "exp2xf2"
16382 [(use (match_operand:XF 0 "register_operand"))
16383 (use (match_operand:XF 1 "register_operand"))]
16384 "TARGET_USE_FANCY_MATH_387
16385 && flag_unsafe_math_optimizations"
16386 {
16387 rtx op2;
16388
16389 op2 = gen_reg_rtx (XFmode);
16390 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16391
16392 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16393 DONE;
16394 })
16395
16396 (define_expand "exp2<mode>2"
16397 [(use (match_operand:MODEF 0 "register_operand"))
16398 (use (match_operand:MODEF 1 "general_operand"))]
16399 "TARGET_USE_FANCY_MATH_387
16400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16401 || TARGET_MIX_SSE_I387)
16402 && flag_unsafe_math_optimizations"
16403 {
16404 rtx op0, op1;
16405
16406 op0 = gen_reg_rtx (XFmode);
16407 op1 = gen_reg_rtx (XFmode);
16408
16409 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16410 emit_insn (gen_exp2xf2 (op0, op1));
16411 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16412 DONE;
16413 })
16414
16415 (define_expand "expm1xf2"
16416 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16417 (match_dup 2)))
16418 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16419 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16420 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16421 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16422 (parallel [(set (match_dup 7)
16423 (unspec:XF [(match_dup 6) (match_dup 4)]
16424 UNSPEC_FSCALE_FRACT))
16425 (set (match_dup 8)
16426 (unspec:XF [(match_dup 6) (match_dup 4)]
16427 UNSPEC_FSCALE_EXP))])
16428 (parallel [(set (match_dup 10)
16429 (unspec:XF [(match_dup 9) (match_dup 8)]
16430 UNSPEC_FSCALE_FRACT))
16431 (set (match_dup 11)
16432 (unspec:XF [(match_dup 9) (match_dup 8)]
16433 UNSPEC_FSCALE_EXP))])
16434 (set (match_dup 12) (minus:XF (match_dup 10)
16435 (float_extend:XF (match_dup 13))))
16436 (set (match_operand:XF 0 "register_operand")
16437 (plus:XF (match_dup 12) (match_dup 7)))]
16438 "TARGET_USE_FANCY_MATH_387
16439 && flag_unsafe_math_optimizations"
16440 {
16441 int i;
16442
16443 for (i = 2; i < 13; i++)
16444 operands[i] = gen_reg_rtx (XFmode);
16445
16446 operands[13]
16447 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16448
16449 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16450 })
16451
16452 (define_expand "expm1<mode>2"
16453 [(use (match_operand:MODEF 0 "register_operand"))
16454 (use (match_operand:MODEF 1 "general_operand"))]
16455 "TARGET_USE_FANCY_MATH_387
16456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16457 || TARGET_MIX_SSE_I387)
16458 && flag_unsafe_math_optimizations"
16459 {
16460 rtx op0, op1;
16461
16462 op0 = gen_reg_rtx (XFmode);
16463 op1 = gen_reg_rtx (XFmode);
16464
16465 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16466 emit_insn (gen_expm1xf2 (op0, op1));
16467 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16468 DONE;
16469 })
16470
16471 (define_expand "ldexpxf3"
16472 [(match_operand:XF 0 "register_operand")
16473 (match_operand:XF 1 "register_operand")
16474 (match_operand:SI 2 "register_operand")]
16475 "TARGET_USE_FANCY_MATH_387
16476 && flag_unsafe_math_optimizations"
16477 {
16478 rtx tmp1, tmp2;
16479
16480 tmp1 = gen_reg_rtx (XFmode);
16481 tmp2 = gen_reg_rtx (XFmode);
16482
16483 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16484 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16485 operands[1], tmp1));
16486 DONE;
16487 })
16488
16489 (define_expand "ldexp<mode>3"
16490 [(use (match_operand:MODEF 0 "register_operand"))
16491 (use (match_operand:MODEF 1 "general_operand"))
16492 (use (match_operand:SI 2 "register_operand"))]
16493 "TARGET_USE_FANCY_MATH_387
16494 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16495 || TARGET_MIX_SSE_I387)
16496 && flag_unsafe_math_optimizations"
16497 {
16498 rtx op0, op1;
16499
16500 op0 = gen_reg_rtx (XFmode);
16501 op1 = gen_reg_rtx (XFmode);
16502
16503 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16504 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16505 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16506 DONE;
16507 })
16508
16509 (define_expand "scalbxf3"
16510 [(parallel [(set (match_operand:XF 0 " register_operand")
16511 (unspec:XF [(match_operand:XF 1 "register_operand")
16512 (match_operand:XF 2 "register_operand")]
16513 UNSPEC_FSCALE_FRACT))
16514 (set (match_dup 3)
16515 (unspec:XF [(match_dup 1) (match_dup 2)]
16516 UNSPEC_FSCALE_EXP))])]
16517 "TARGET_USE_FANCY_MATH_387
16518 && flag_unsafe_math_optimizations"
16519 {
16520 operands[3] = gen_reg_rtx (XFmode);
16521 })
16522
16523 (define_expand "scalb<mode>3"
16524 [(use (match_operand:MODEF 0 "register_operand"))
16525 (use (match_operand:MODEF 1 "general_operand"))
16526 (use (match_operand:MODEF 2 "general_operand"))]
16527 "TARGET_USE_FANCY_MATH_387
16528 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16529 || TARGET_MIX_SSE_I387)
16530 && flag_unsafe_math_optimizations"
16531 {
16532 rtx op0, op1, op2;
16533
16534 op0 = gen_reg_rtx (XFmode);
16535 op1 = gen_reg_rtx (XFmode);
16536 op2 = gen_reg_rtx (XFmode);
16537
16538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16539 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16540 emit_insn (gen_scalbxf3 (op0, op1, op2));
16541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16542 DONE;
16543 })
16544
16545 (define_expand "significandxf2"
16546 [(parallel [(set (match_operand:XF 0 "register_operand")
16547 (unspec:XF [(match_operand:XF 1 "register_operand")]
16548 UNSPEC_XTRACT_FRACT))
16549 (set (match_dup 2)
16550 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16551 "TARGET_USE_FANCY_MATH_387
16552 && flag_unsafe_math_optimizations"
16553 "operands[2] = gen_reg_rtx (XFmode);")
16554
16555 (define_expand "significand<mode>2"
16556 [(use (match_operand:MODEF 0 "register_operand"))
16557 (use (match_operand:MODEF 1 "register_operand"))]
16558 "TARGET_USE_FANCY_MATH_387
16559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16560 || TARGET_MIX_SSE_I387)
16561 && flag_unsafe_math_optimizations"
16562 {
16563 rtx op0 = gen_reg_rtx (XFmode);
16564 rtx op1 = gen_reg_rtx (XFmode);
16565
16566 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16568 DONE;
16569 })
16570 \f
16571
16572 (define_insn "sse4_1_round<mode>2"
16573 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16574 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
16575 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16576 UNSPEC_ROUND))]
16577 "TARGET_SSE4_1"
16578 "@
16579 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16580 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16581 [(set_attr "type" "ssecvt")
16582 (set_attr "prefix_extra" "1,*")
16583 (set_attr "length_immediate" "*,1")
16584 (set_attr "prefix" "maybe_vex,evex")
16585 (set_attr "isa" "noavx512f,avx512f")
16586 (set_attr "mode" "<MODE>")])
16587
16588 (define_insn "rintxf2"
16589 [(set (match_operand:XF 0 "register_operand" "=f")
16590 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16591 UNSPEC_FRNDINT))]
16592 "TARGET_USE_FANCY_MATH_387"
16593 "frndint"
16594 [(set_attr "type" "fpspc")
16595 (set_attr "znver1_decode" "vector")
16596 (set_attr "mode" "XF")])
16597
16598 (define_insn "rint<mode>2_frndint"
16599 [(set (match_operand:MODEF 0 "register_operand" "=f")
16600 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16601 UNSPEC_FRNDINT))]
16602 "TARGET_USE_FANCY_MATH_387"
16603 "frndint"
16604 [(set_attr "type" "fpspc")
16605 (set_attr "znver1_decode" "vector")
16606 (set_attr "mode" "<MODE>")])
16607
16608 (define_expand "rint<mode>2"
16609 [(use (match_operand:MODEF 0 "register_operand"))
16610 (use (match_operand:MODEF 1 "register_operand"))]
16611 "(TARGET_USE_FANCY_MATH_387
16612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16613 || TARGET_MIX_SSE_I387))
16614 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16615 {
16616 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16617 {
16618 if (TARGET_SSE4_1)
16619 emit_insn (gen_sse4_1_round<mode>2
16620 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16621 else
16622 ix86_expand_rint (operands[0], operands[1]);
16623 }
16624 else
16625 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16626 DONE;
16627 })
16628
16629 (define_expand "round<mode>2"
16630 [(match_operand:X87MODEF 0 "register_operand")
16631 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16632 "(TARGET_USE_FANCY_MATH_387
16633 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16634 || TARGET_MIX_SSE_I387)
16635 && flag_unsafe_math_optimizations
16636 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16637 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16638 && !flag_trapping_math && !flag_rounding_math)"
16639 {
16640 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16641 && !flag_trapping_math && !flag_rounding_math)
16642 {
16643 if (TARGET_SSE4_1)
16644 {
16645 operands[1] = force_reg (<MODE>mode, operands[1]);
16646 ix86_expand_round_sse4 (operands[0], operands[1]);
16647 }
16648 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16649 ix86_expand_round (operands[0], operands[1]);
16650 else
16651 ix86_expand_rounddf_32 (operands[0], operands[1]);
16652 }
16653 else
16654 {
16655 operands[1] = force_reg (<MODE>mode, operands[1]);
16656 ix86_emit_i387_round (operands[0], operands[1]);
16657 }
16658 DONE;
16659 })
16660
16661 (define_insn_and_split "*fistdi2_1"
16662 [(set (match_operand:DI 0 "nonimmediate_operand")
16663 (unspec:DI [(match_operand:XF 1 "register_operand")]
16664 UNSPEC_FIST))]
16665 "TARGET_USE_FANCY_MATH_387
16666 && can_create_pseudo_p ()"
16667 "#"
16668 "&& 1"
16669 [(const_int 0)]
16670 {
16671 if (memory_operand (operands[0], VOIDmode))
16672 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16673 else
16674 {
16675 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16676 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16677 operands[2]));
16678 }
16679 DONE;
16680 }
16681 [(set_attr "type" "fpspc")
16682 (set_attr "mode" "DI")])
16683
16684 (define_insn "fistdi2"
16685 [(set (match_operand:DI 0 "memory_operand" "=m")
16686 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16687 UNSPEC_FIST))
16688 (clobber (match_scratch:XF 2 "=&1f"))]
16689 "TARGET_USE_FANCY_MATH_387"
16690 "* return output_fix_trunc (insn, operands, false);"
16691 [(set_attr "type" "fpspc")
16692 (set_attr "mode" "DI")])
16693
16694 (define_insn "fistdi2_with_temp"
16695 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16696 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16697 UNSPEC_FIST))
16698 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16699 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16700 "TARGET_USE_FANCY_MATH_387"
16701 "#"
16702 [(set_attr "type" "fpspc")
16703 (set_attr "mode" "DI")])
16704
16705 (define_split
16706 [(set (match_operand:DI 0 "register_operand")
16707 (unspec:DI [(match_operand:XF 1 "register_operand")]
16708 UNSPEC_FIST))
16709 (clobber (match_operand:DI 2 "memory_operand"))
16710 (clobber (match_scratch 3))]
16711 "reload_completed"
16712 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16713 (clobber (match_dup 3))])
16714 (set (match_dup 0) (match_dup 2))])
16715
16716 (define_split
16717 [(set (match_operand:DI 0 "memory_operand")
16718 (unspec:DI [(match_operand:XF 1 "register_operand")]
16719 UNSPEC_FIST))
16720 (clobber (match_operand:DI 2 "memory_operand"))
16721 (clobber (match_scratch 3))]
16722 "reload_completed"
16723 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16724 (clobber (match_dup 3))])])
16725
16726 (define_insn_and_split "*fist<mode>2_1"
16727 [(set (match_operand:SWI24 0 "register_operand")
16728 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16729 UNSPEC_FIST))]
16730 "TARGET_USE_FANCY_MATH_387
16731 && can_create_pseudo_p ()"
16732 "#"
16733 "&& 1"
16734 [(const_int 0)]
16735 {
16736 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16737 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16738 operands[2]));
16739 DONE;
16740 }
16741 [(set_attr "type" "fpspc")
16742 (set_attr "mode" "<MODE>")])
16743
16744 (define_insn "fist<mode>2"
16745 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16746 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16747 UNSPEC_FIST))]
16748 "TARGET_USE_FANCY_MATH_387"
16749 "* return output_fix_trunc (insn, operands, false);"
16750 [(set_attr "type" "fpspc")
16751 (set_attr "mode" "<MODE>")])
16752
16753 (define_insn "fist<mode>2_with_temp"
16754 [(set (match_operand:SWI24 0 "register_operand" "=r")
16755 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16756 UNSPEC_FIST))
16757 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16758 "TARGET_USE_FANCY_MATH_387"
16759 "#"
16760 [(set_attr "type" "fpspc")
16761 (set_attr "mode" "<MODE>")])
16762
16763 (define_split
16764 [(set (match_operand:SWI24 0 "register_operand")
16765 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16766 UNSPEC_FIST))
16767 (clobber (match_operand:SWI24 2 "memory_operand"))]
16768 "reload_completed"
16769 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16770 (set (match_dup 0) (match_dup 2))])
16771
16772 (define_split
16773 [(set (match_operand:SWI24 0 "memory_operand")
16774 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16775 UNSPEC_FIST))
16776 (clobber (match_operand:SWI24 2 "memory_operand"))]
16777 "reload_completed"
16778 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16779
16780 (define_expand "lrintxf<mode>2"
16781 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16782 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16783 UNSPEC_FIST))]
16784 "TARGET_USE_FANCY_MATH_387")
16785
16786 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16787 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16788 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16789 UNSPEC_FIX_NOTRUNC))]
16790 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16791
16792 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16793 [(match_operand:SWI248x 0 "nonimmediate_operand")
16794 (match_operand:X87MODEF 1 "register_operand")]
16795 "(TARGET_USE_FANCY_MATH_387
16796 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16797 || TARGET_MIX_SSE_I387)
16798 && flag_unsafe_math_optimizations)
16799 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16800 && <SWI248x:MODE>mode != HImode
16801 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16802 && !flag_trapping_math && !flag_rounding_math)"
16803 {
16804 if (optimize_insn_for_size_p ())
16805 FAIL;
16806
16807 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16808 && <SWI248x:MODE>mode != HImode
16809 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16810 && !flag_trapping_math && !flag_rounding_math)
16811 ix86_expand_lround (operands[0], operands[1]);
16812 else
16813 ix86_emit_i387_round (operands[0], operands[1]);
16814 DONE;
16815 })
16816
16817 (define_int_iterator FRNDINT_ROUNDING
16818 [UNSPEC_FRNDINT_FLOOR
16819 UNSPEC_FRNDINT_CEIL
16820 UNSPEC_FRNDINT_TRUNC])
16821
16822 (define_int_iterator FIST_ROUNDING
16823 [UNSPEC_FIST_FLOOR
16824 UNSPEC_FIST_CEIL])
16825
16826 ;; Base name for define_insn
16827 (define_int_attr rounding_insn
16828 [(UNSPEC_FRNDINT_FLOOR "floor")
16829 (UNSPEC_FRNDINT_CEIL "ceil")
16830 (UNSPEC_FRNDINT_TRUNC "btrunc")
16831 (UNSPEC_FIST_FLOOR "floor")
16832 (UNSPEC_FIST_CEIL "ceil")])
16833
16834 (define_int_attr rounding
16835 [(UNSPEC_FRNDINT_FLOOR "floor")
16836 (UNSPEC_FRNDINT_CEIL "ceil")
16837 (UNSPEC_FRNDINT_TRUNC "trunc")
16838 (UNSPEC_FIST_FLOOR "floor")
16839 (UNSPEC_FIST_CEIL "ceil")])
16840
16841 (define_int_attr ROUNDING
16842 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16843 (UNSPEC_FRNDINT_CEIL "CEIL")
16844 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16845 (UNSPEC_FIST_FLOOR "FLOOR")
16846 (UNSPEC_FIST_CEIL "CEIL")])
16847
16848 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16849 (define_insn_and_split "frndint<mode>2_<rounding>"
16850 [(set (match_operand:X87MODEF 0 "register_operand")
16851 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16852 FRNDINT_ROUNDING))
16853 (clobber (reg:CC FLAGS_REG))]
16854 "TARGET_USE_FANCY_MATH_387
16855 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16856 && can_create_pseudo_p ()"
16857 "#"
16858 "&& 1"
16859 [(const_int 0)]
16860 {
16861 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16862
16863 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16864 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16865
16866 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16867 operands[2], operands[3]));
16868 DONE;
16869 }
16870 [(set_attr "type" "frndint")
16871 (set_attr "i387_cw" "<rounding>")
16872 (set_attr "mode" "<MODE>")])
16873
16874 (define_insn "frndint<mode>2_<rounding>_i387"
16875 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16876 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16877 FRNDINT_ROUNDING))
16878 (use (match_operand:HI 2 "memory_operand" "m"))
16879 (use (match_operand:HI 3 "memory_operand" "m"))]
16880 "TARGET_USE_FANCY_MATH_387
16881 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16882 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16883 [(set_attr "type" "frndint")
16884 (set_attr "i387_cw" "<rounding>")
16885 (set_attr "mode" "<MODE>")])
16886
16887 (define_expand "<rounding_insn>xf2"
16888 [(parallel [(set (match_operand:XF 0 "register_operand")
16889 (unspec:XF [(match_operand:XF 1 "register_operand")]
16890 FRNDINT_ROUNDING))
16891 (clobber (reg:CC FLAGS_REG))])]
16892 "TARGET_USE_FANCY_MATH_387
16893 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16894
16895 (define_expand "<rounding_insn><mode>2"
16896 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16897 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16898 FRNDINT_ROUNDING))
16899 (clobber (reg:CC FLAGS_REG))])]
16900 "(TARGET_USE_FANCY_MATH_387
16901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16902 || TARGET_MIX_SSE_I387)
16903 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16904 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16905 && (TARGET_SSE4_1 || !flag_trapping_math
16906 || flag_fp_int_builtin_inexact))"
16907 {
16908 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16909 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16910 {
16911 if (TARGET_SSE4_1)
16912 emit_insn (gen_sse4_1_round<mode>2
16913 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16914 | ROUND_NO_EXC)));
16915 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16916 {
16917 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16918 ix86_expand_floorceil (operands[0], operands[1], true);
16919 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16920 ix86_expand_floorceil (operands[0], operands[1], false);
16921 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16922 ix86_expand_trunc (operands[0], operands[1]);
16923 else
16924 gcc_unreachable ();
16925 }
16926 else
16927 {
16928 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16929 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16930 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16931 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16932 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16933 ix86_expand_truncdf_32 (operands[0], operands[1]);
16934 else
16935 gcc_unreachable ();
16936 }
16937 }
16938 else
16939 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16940 DONE;
16941 })
16942
16943 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16944 (define_insn_and_split "frndintxf2_mask_pm"
16945 [(set (match_operand:XF 0 "register_operand")
16946 (unspec:XF [(match_operand:XF 1 "register_operand")]
16947 UNSPEC_FRNDINT_MASK_PM))
16948 (clobber (reg:CC FLAGS_REG))]
16949 "TARGET_USE_FANCY_MATH_387
16950 && flag_unsafe_math_optimizations
16951 && can_create_pseudo_p ()"
16952 "#"
16953 "&& 1"
16954 [(const_int 0)]
16955 {
16956 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16957
16958 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16959 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16960
16961 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16962 operands[2], operands[3]));
16963 DONE;
16964 }
16965 [(set_attr "type" "frndint")
16966 (set_attr "i387_cw" "mask_pm")
16967 (set_attr "mode" "XF")])
16968
16969 (define_insn "frndintxf2_mask_pm_i387"
16970 [(set (match_operand:XF 0 "register_operand" "=f")
16971 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16972 UNSPEC_FRNDINT_MASK_PM))
16973 (use (match_operand:HI 2 "memory_operand" "m"))
16974 (use (match_operand:HI 3 "memory_operand" "m"))]
16975 "TARGET_USE_FANCY_MATH_387
16976 && flag_unsafe_math_optimizations"
16977 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16978 [(set_attr "type" "frndint")
16979 (set_attr "i387_cw" "mask_pm")
16980 (set_attr "mode" "XF")])
16981
16982 (define_expand "nearbyintxf2"
16983 [(parallel [(set (match_operand:XF 0 "register_operand")
16984 (unspec:XF [(match_operand:XF 1 "register_operand")]
16985 UNSPEC_FRNDINT_MASK_PM))
16986 (clobber (reg:CC FLAGS_REG))])]
16987 "TARGET_USE_FANCY_MATH_387
16988 && flag_unsafe_math_optimizations")
16989
16990 (define_expand "nearbyint<mode>2"
16991 [(use (match_operand:MODEF 0 "register_operand"))
16992 (use (match_operand:MODEF 1 "register_operand"))]
16993 "TARGET_USE_FANCY_MATH_387
16994 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16995 || TARGET_MIX_SSE_I387)
16996 && flag_unsafe_math_optimizations"
16997 {
16998 rtx op0 = gen_reg_rtx (XFmode);
16999 rtx op1 = gen_reg_rtx (XFmode);
17000
17001 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17002 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17003
17004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17005 DONE;
17006 })
17007
17008 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17009 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17010 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17011 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17012 FIST_ROUNDING))
17013 (clobber (reg:CC FLAGS_REG))]
17014 "TARGET_USE_FANCY_MATH_387
17015 && flag_unsafe_math_optimizations
17016 && can_create_pseudo_p ()"
17017 "#"
17018 "&& 1"
17019 [(const_int 0)]
17020 {
17021 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17022
17023 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17024 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17025 if (memory_operand (operands[0], VOIDmode))
17026 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17027 operands[2], operands[3]));
17028 else
17029 {
17030 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17031 emit_insn (gen_fist<mode>2_<rounding>_with_temp
17032 (operands[0], operands[1], operands[2],
17033 operands[3], operands[4]));
17034 }
17035 DONE;
17036 }
17037 [(set_attr "type" "fistp")
17038 (set_attr "i387_cw" "<rounding>")
17039 (set_attr "mode" "<MODE>")])
17040
17041 (define_insn "fistdi2_<rounding>"
17042 [(set (match_operand:DI 0 "memory_operand" "=m")
17043 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17044 FIST_ROUNDING))
17045 (use (match_operand:HI 2 "memory_operand" "m"))
17046 (use (match_operand:HI 3 "memory_operand" "m"))
17047 (clobber (match_scratch:XF 4 "=&1f"))]
17048 "TARGET_USE_FANCY_MATH_387
17049 && flag_unsafe_math_optimizations"
17050 "* return output_fix_trunc (insn, operands, false);"
17051 [(set_attr "type" "fistp")
17052 (set_attr "i387_cw" "<rounding>")
17053 (set_attr "mode" "DI")])
17054
17055 (define_insn "fistdi2_<rounding>_with_temp"
17056 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17057 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17058 FIST_ROUNDING))
17059 (use (match_operand:HI 2 "memory_operand" "m,m"))
17060 (use (match_operand:HI 3 "memory_operand" "m,m"))
17061 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17062 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17063 "TARGET_USE_FANCY_MATH_387
17064 && flag_unsafe_math_optimizations"
17065 "#"
17066 [(set_attr "type" "fistp")
17067 (set_attr "i387_cw" "<rounding>")
17068 (set_attr "mode" "DI")])
17069
17070 (define_split
17071 [(set (match_operand:DI 0 "register_operand")
17072 (unspec:DI [(match_operand:XF 1 "register_operand")]
17073 FIST_ROUNDING))
17074 (use (match_operand:HI 2 "memory_operand"))
17075 (use (match_operand:HI 3 "memory_operand"))
17076 (clobber (match_operand:DI 4 "memory_operand"))
17077 (clobber (match_scratch 5))]
17078 "reload_completed"
17079 [(parallel [(set (match_dup 4)
17080 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17081 (use (match_dup 2))
17082 (use (match_dup 3))
17083 (clobber (match_dup 5))])
17084 (set (match_dup 0) (match_dup 4))])
17085
17086 (define_split
17087 [(set (match_operand:DI 0 "memory_operand")
17088 (unspec:DI [(match_operand:XF 1 "register_operand")]
17089 FIST_ROUNDING))
17090 (use (match_operand:HI 2 "memory_operand"))
17091 (use (match_operand:HI 3 "memory_operand"))
17092 (clobber (match_operand:DI 4 "memory_operand"))
17093 (clobber (match_scratch 5))]
17094 "reload_completed"
17095 [(parallel [(set (match_dup 0)
17096 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17097 (use (match_dup 2))
17098 (use (match_dup 3))
17099 (clobber (match_dup 5))])])
17100
17101 (define_insn "fist<mode>2_<rounding>"
17102 [(set (match_operand:SWI24 0 "memory_operand" "=m")
17103 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17104 FIST_ROUNDING))
17105 (use (match_operand:HI 2 "memory_operand" "m"))
17106 (use (match_operand:HI 3 "memory_operand" "m"))]
17107 "TARGET_USE_FANCY_MATH_387
17108 && flag_unsafe_math_optimizations"
17109 "* return output_fix_trunc (insn, operands, false);"
17110 [(set_attr "type" "fistp")
17111 (set_attr "i387_cw" "<rounding>")
17112 (set_attr "mode" "<MODE>")])
17113
17114 (define_insn "fist<mode>2_<rounding>_with_temp"
17115 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
17116 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
17117 FIST_ROUNDING))
17118 (use (match_operand:HI 2 "memory_operand" "m,m"))
17119 (use (match_operand:HI 3 "memory_operand" "m,m"))
17120 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
17121 "TARGET_USE_FANCY_MATH_387
17122 && flag_unsafe_math_optimizations"
17123 "#"
17124 [(set_attr "type" "fistp")
17125 (set_attr "i387_cw" "<rounding>")
17126 (set_attr "mode" "<MODE>")])
17127
17128 (define_split
17129 [(set (match_operand:SWI24 0 "register_operand")
17130 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17131 FIST_ROUNDING))
17132 (use (match_operand:HI 2 "memory_operand"))
17133 (use (match_operand:HI 3 "memory_operand"))
17134 (clobber (match_operand:SWI24 4 "memory_operand"))]
17135 "reload_completed"
17136 [(parallel [(set (match_dup 4)
17137 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17138 (use (match_dup 2))
17139 (use (match_dup 3))])
17140 (set (match_dup 0) (match_dup 4))])
17141
17142 (define_split
17143 [(set (match_operand:SWI24 0 "memory_operand")
17144 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17145 FIST_ROUNDING))
17146 (use (match_operand:HI 2 "memory_operand"))
17147 (use (match_operand:HI 3 "memory_operand"))
17148 (clobber (match_operand:SWI24 4 "memory_operand"))]
17149 "reload_completed"
17150 [(parallel [(set (match_dup 0)
17151 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17152 (use (match_dup 2))
17153 (use (match_dup 3))])])
17154
17155 (define_expand "l<rounding_insn>xf<mode>2"
17156 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17157 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17158 FIST_ROUNDING))
17159 (clobber (reg:CC FLAGS_REG))])]
17160 "TARGET_USE_FANCY_MATH_387
17161 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17162 && flag_unsafe_math_optimizations")
17163
17164 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17165 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17166 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17167 FIST_ROUNDING))
17168 (clobber (reg:CC FLAGS_REG))])]
17169 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17170 && !flag_trapping_math"
17171 {
17172 if (TARGET_64BIT && optimize_insn_for_size_p ())
17173 FAIL;
17174
17175 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17176 ix86_expand_lfloorceil (operands[0], operands[1], true);
17177 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17178 ix86_expand_lfloorceil (operands[0], operands[1], false);
17179 else
17180 gcc_unreachable ();
17181
17182 DONE;
17183 })
17184
17185 (define_insn "fxam<mode>2_i387"
17186 [(set (match_operand:HI 0 "register_operand" "=a")
17187 (unspec:HI
17188 [(match_operand:X87MODEF 1 "register_operand" "f")]
17189 UNSPEC_FXAM))]
17190 "TARGET_USE_FANCY_MATH_387"
17191 "fxam\n\tfnstsw\t%0"
17192 [(set_attr "type" "multi")
17193 (set_attr "length" "4")
17194 (set_attr "unit" "i387")
17195 (set_attr "mode" "<MODE>")])
17196
17197 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17198 [(set (match_operand:HI 0 "register_operand")
17199 (unspec:HI
17200 [(match_operand:MODEF 1 "memory_operand")]
17201 UNSPEC_FXAM_MEM))]
17202 "TARGET_USE_FANCY_MATH_387
17203 && can_create_pseudo_p ()"
17204 "#"
17205 "&& 1"
17206 [(set (match_dup 2)(match_dup 1))
17207 (set (match_dup 0)
17208 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17209 {
17210 operands[2] = gen_reg_rtx (<MODE>mode);
17211
17212 MEM_VOLATILE_P (operands[1]) = 1;
17213 }
17214 [(set_attr "type" "multi")
17215 (set_attr "unit" "i387")
17216 (set_attr "mode" "<MODE>")])
17217
17218 (define_expand "isinfxf2"
17219 [(use (match_operand:SI 0 "register_operand"))
17220 (use (match_operand:XF 1 "register_operand"))]
17221 "TARGET_USE_FANCY_MATH_387
17222 && ix86_libc_has_function (function_c99_misc)"
17223 {
17224 rtx mask = GEN_INT (0x45);
17225 rtx val = GEN_INT (0x05);
17226
17227 rtx scratch = gen_reg_rtx (HImode);
17228 rtx res = gen_reg_rtx (QImode);
17229
17230 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17231
17232 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17233 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17234 ix86_expand_setcc (res, EQ,
17235 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17236 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17237 DONE;
17238 })
17239
17240 (define_expand "isinf<mode>2"
17241 [(use (match_operand:SI 0 "register_operand"))
17242 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17243 "TARGET_USE_FANCY_MATH_387
17244 && ix86_libc_has_function (function_c99_misc)
17245 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17246 {
17247 rtx mask = GEN_INT (0x45);
17248 rtx val = GEN_INT (0x05);
17249
17250 rtx scratch = gen_reg_rtx (HImode);
17251 rtx res = gen_reg_rtx (QImode);
17252
17253 /* Remove excess precision by forcing value through memory. */
17254 if (memory_operand (operands[1], VOIDmode))
17255 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17256 else
17257 {
17258 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17259
17260 emit_move_insn (temp, operands[1]);
17261 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17262 }
17263
17264 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17265 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17266 ix86_expand_setcc (res, EQ,
17267 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17268 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17269 DONE;
17270 })
17271
17272 (define_expand "signbittf2"
17273 [(use (match_operand:SI 0 "register_operand"))
17274 (use (match_operand:TF 1 "register_operand"))]
17275 "TARGET_SSE"
17276 {
17277 if (TARGET_SSE4_1)
17278 {
17279 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17280 rtx scratch = gen_reg_rtx (QImode);
17281
17282 emit_insn (gen_ptesttf2 (operands[1], mask));
17283 ix86_expand_setcc (scratch, NE,
17284 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17285
17286 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17287 }
17288 else
17289 {
17290 emit_insn (gen_sse_movmskps (operands[0],
17291 gen_lowpart (V4SFmode, operands[1])));
17292 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17293 }
17294 DONE;
17295 })
17296
17297 (define_expand "signbitxf2"
17298 [(use (match_operand:SI 0 "register_operand"))
17299 (use (match_operand:XF 1 "register_operand"))]
17300 "TARGET_USE_FANCY_MATH_387"
17301 {
17302 rtx scratch = gen_reg_rtx (HImode);
17303
17304 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17305 emit_insn (gen_andsi3 (operands[0],
17306 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17307 DONE;
17308 })
17309
17310 (define_insn "movmsk_df"
17311 [(set (match_operand:SI 0 "register_operand" "=r")
17312 (unspec:SI
17313 [(match_operand:DF 1 "register_operand" "x")]
17314 UNSPEC_MOVMSK))]
17315 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17316 "%vmovmskpd\t{%1, %0|%0, %1}"
17317 [(set_attr "type" "ssemov")
17318 (set_attr "prefix" "maybe_vex")
17319 (set_attr "mode" "DF")])
17320
17321 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17322 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17323 (define_expand "signbitdf2"
17324 [(use (match_operand:SI 0 "register_operand"))
17325 (use (match_operand:DF 1 "register_operand"))]
17326 "TARGET_USE_FANCY_MATH_387
17327 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17328 {
17329 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17330 {
17331 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17332 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17333 }
17334 else
17335 {
17336 rtx scratch = gen_reg_rtx (HImode);
17337
17338 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17339 emit_insn (gen_andsi3 (operands[0],
17340 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17341 }
17342 DONE;
17343 })
17344
17345 (define_expand "signbitsf2"
17346 [(use (match_operand:SI 0 "register_operand"))
17347 (use (match_operand:SF 1 "register_operand"))]
17348 "TARGET_USE_FANCY_MATH_387
17349 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17350 {
17351 rtx scratch = gen_reg_rtx (HImode);
17352
17353 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17354 emit_insn (gen_andsi3 (operands[0],
17355 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17356 DONE;
17357 })
17358 \f
17359 ;; Block operation instructions
17360
17361 (define_insn "cld"
17362 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17363 ""
17364 "cld"
17365 [(set_attr "length" "1")
17366 (set_attr "length_immediate" "0")
17367 (set_attr "modrm" "0")])
17368
17369 (define_expand "movmem<mode>"
17370 [(use (match_operand:BLK 0 "memory_operand"))
17371 (use (match_operand:BLK 1 "memory_operand"))
17372 (use (match_operand:SWI48 2 "nonmemory_operand"))
17373 (use (match_operand:SWI48 3 "const_int_operand"))
17374 (use (match_operand:SI 4 "const_int_operand"))
17375 (use (match_operand:SI 5 "const_int_operand"))
17376 (use (match_operand:SI 6 ""))
17377 (use (match_operand:SI 7 ""))
17378 (use (match_operand:SI 8 ""))]
17379 ""
17380 {
17381 if (ix86_expand_set_or_movmem (operands[0], operands[1],
17382 operands[2], NULL, operands[3],
17383 operands[4], operands[5],
17384 operands[6], operands[7],
17385 operands[8], false))
17386 DONE;
17387 else
17388 FAIL;
17389 })
17390
17391 ;; Most CPUs don't like single string operations
17392 ;; Handle this case here to simplify previous expander.
17393
17394 (define_expand "strmov"
17395 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17396 (set (match_operand 1 "memory_operand") (match_dup 4))
17397 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17398 (clobber (reg:CC FLAGS_REG))])
17399 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17400 (clobber (reg:CC FLAGS_REG))])]
17401 ""
17402 {
17403 /* Can't use this for non-default address spaces. */
17404 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17405 FAIL;
17406
17407 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17408
17409 /* If .md ever supports :P for Pmode, these can be directly
17410 in the pattern above. */
17411 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17412 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17413
17414 /* Can't use this if the user has appropriated esi or edi. */
17415 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17416 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17417 {
17418 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17419 operands[2], operands[3],
17420 operands[5], operands[6]));
17421 DONE;
17422 }
17423
17424 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17425 })
17426
17427 (define_expand "strmov_singleop"
17428 [(parallel [(set (match_operand 1 "memory_operand")
17429 (match_operand 3 "memory_operand"))
17430 (set (match_operand 0 "register_operand")
17431 (match_operand 4))
17432 (set (match_operand 2 "register_operand")
17433 (match_operand 5))])]
17434 ""
17435 {
17436 if (TARGET_CLD)
17437 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17438 })
17439
17440 (define_insn "*strmovdi_rex_1"
17441 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17442 (mem:DI (match_operand:P 3 "register_operand" "1")))
17443 (set (match_operand:P 0 "register_operand" "=D")
17444 (plus:P (match_dup 2)
17445 (const_int 8)))
17446 (set (match_operand:P 1 "register_operand" "=S")
17447 (plus:P (match_dup 3)
17448 (const_int 8)))]
17449 "TARGET_64BIT
17450 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17451 && ix86_check_no_addr_space (insn)"
17452 "%^movsq"
17453 [(set_attr "type" "str")
17454 (set_attr "memory" "both")
17455 (set_attr "mode" "DI")])
17456
17457 (define_insn "*strmovsi_1"
17458 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17459 (mem:SI (match_operand:P 3 "register_operand" "1")))
17460 (set (match_operand:P 0 "register_operand" "=D")
17461 (plus:P (match_dup 2)
17462 (const_int 4)))
17463 (set (match_operand:P 1 "register_operand" "=S")
17464 (plus:P (match_dup 3)
17465 (const_int 4)))]
17466 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17467 && ix86_check_no_addr_space (insn)"
17468 "%^movs{l|d}"
17469 [(set_attr "type" "str")
17470 (set_attr "memory" "both")
17471 (set_attr "mode" "SI")])
17472
17473 (define_insn "*strmovhi_1"
17474 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17475 (mem:HI (match_operand:P 3 "register_operand" "1")))
17476 (set (match_operand:P 0 "register_operand" "=D")
17477 (plus:P (match_dup 2)
17478 (const_int 2)))
17479 (set (match_operand:P 1 "register_operand" "=S")
17480 (plus:P (match_dup 3)
17481 (const_int 2)))]
17482 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17483 && ix86_check_no_addr_space (insn)"
17484 "%^movsw"
17485 [(set_attr "type" "str")
17486 (set_attr "memory" "both")
17487 (set_attr "mode" "HI")])
17488
17489 (define_insn "*strmovqi_1"
17490 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17491 (mem:QI (match_operand:P 3 "register_operand" "1")))
17492 (set (match_operand:P 0 "register_operand" "=D")
17493 (plus:P (match_dup 2)
17494 (const_int 1)))
17495 (set (match_operand:P 1 "register_operand" "=S")
17496 (plus:P (match_dup 3)
17497 (const_int 1)))]
17498 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17499 && ix86_check_no_addr_space (insn)"
17500 "%^movsb"
17501 [(set_attr "type" "str")
17502 (set_attr "memory" "both")
17503 (set (attr "prefix_rex")
17504 (if_then_else
17505 (match_test "<P:MODE>mode == DImode")
17506 (const_string "0")
17507 (const_string "*")))
17508 (set_attr "mode" "QI")])
17509
17510 (define_expand "rep_mov"
17511 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17512 (set (match_operand 0 "register_operand")
17513 (match_operand 5))
17514 (set (match_operand 2 "register_operand")
17515 (match_operand 6))
17516 (set (match_operand 1 "memory_operand")
17517 (match_operand 3 "memory_operand"))
17518 (use (match_dup 4))])]
17519 ""
17520 {
17521 if (TARGET_CLD)
17522 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17523 })
17524
17525 (define_insn "*rep_movdi_rex64"
17526 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17527 (set (match_operand:P 0 "register_operand" "=D")
17528 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17529 (const_int 3))
17530 (match_operand:P 3 "register_operand" "0")))
17531 (set (match_operand:P 1 "register_operand" "=S")
17532 (plus:P (ashift:P (match_dup 5) (const_int 3))
17533 (match_operand:P 4 "register_operand" "1")))
17534 (set (mem:BLK (match_dup 3))
17535 (mem:BLK (match_dup 4)))
17536 (use (match_dup 5))]
17537 "TARGET_64BIT
17538 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17539 && ix86_check_no_addr_space (insn)"
17540 "%^rep{%;} movsq"
17541 [(set_attr "type" "str")
17542 (set_attr "prefix_rep" "1")
17543 (set_attr "memory" "both")
17544 (set_attr "mode" "DI")])
17545
17546 (define_insn "*rep_movsi"
17547 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17548 (set (match_operand:P 0 "register_operand" "=D")
17549 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17550 (const_int 2))
17551 (match_operand:P 3 "register_operand" "0")))
17552 (set (match_operand:P 1 "register_operand" "=S")
17553 (plus:P (ashift:P (match_dup 5) (const_int 2))
17554 (match_operand:P 4 "register_operand" "1")))
17555 (set (mem:BLK (match_dup 3))
17556 (mem:BLK (match_dup 4)))
17557 (use (match_dup 5))]
17558 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17559 && ix86_check_no_addr_space (insn)"
17560 "%^rep{%;} movs{l|d}"
17561 [(set_attr "type" "str")
17562 (set_attr "prefix_rep" "1")
17563 (set_attr "memory" "both")
17564 (set_attr "mode" "SI")])
17565
17566 (define_insn "*rep_movqi"
17567 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17568 (set (match_operand:P 0 "register_operand" "=D")
17569 (plus:P (match_operand:P 3 "register_operand" "0")
17570 (match_operand:P 5 "register_operand" "2")))
17571 (set (match_operand:P 1 "register_operand" "=S")
17572 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17573 (set (mem:BLK (match_dup 3))
17574 (mem:BLK (match_dup 4)))
17575 (use (match_dup 5))]
17576 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17577 && ix86_check_no_addr_space (insn)"
17578 "%^rep{%;} movsb"
17579 [(set_attr "type" "str")
17580 (set_attr "prefix_rep" "1")
17581 (set_attr "memory" "both")
17582 (set_attr "mode" "QI")])
17583
17584 (define_expand "setmem<mode>"
17585 [(use (match_operand:BLK 0 "memory_operand"))
17586 (use (match_operand:SWI48 1 "nonmemory_operand"))
17587 (use (match_operand:QI 2 "nonmemory_operand"))
17588 (use (match_operand 3 "const_int_operand"))
17589 (use (match_operand:SI 4 "const_int_operand"))
17590 (use (match_operand:SI 5 "const_int_operand"))
17591 (use (match_operand:SI 6 ""))
17592 (use (match_operand:SI 7 ""))
17593 (use (match_operand:SI 8 ""))]
17594 ""
17595 {
17596 if (ix86_expand_set_or_movmem (operands[0], NULL,
17597 operands[1], operands[2],
17598 operands[3], operands[4],
17599 operands[5], operands[6],
17600 operands[7], operands[8], true))
17601 DONE;
17602 else
17603 FAIL;
17604 })
17605
17606 ;; Most CPUs don't like single string operations
17607 ;; Handle this case here to simplify previous expander.
17608
17609 (define_expand "strset"
17610 [(set (match_operand 1 "memory_operand")
17611 (match_operand 2 "register_operand"))
17612 (parallel [(set (match_operand 0 "register_operand")
17613 (match_dup 3))
17614 (clobber (reg:CC FLAGS_REG))])]
17615 ""
17616 {
17617 /* Can't use this for non-default address spaces. */
17618 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17619 FAIL;
17620
17621 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17622 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17623
17624 /* If .md ever supports :P for Pmode, this can be directly
17625 in the pattern above. */
17626 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17627 GEN_INT (GET_MODE_SIZE (GET_MODE
17628 (operands[2]))));
17629 /* Can't use this if the user has appropriated eax or edi. */
17630 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17631 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17632 {
17633 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17634 operands[3]));
17635 DONE;
17636 }
17637 })
17638
17639 (define_expand "strset_singleop"
17640 [(parallel [(set (match_operand 1 "memory_operand")
17641 (match_operand 2 "register_operand"))
17642 (set (match_operand 0 "register_operand")
17643 (match_operand 3))
17644 (unspec [(const_int 0)] UNSPEC_STOS)])]
17645 ""
17646 {
17647 if (TARGET_CLD)
17648 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17649 })
17650
17651 (define_insn "*strsetdi_rex_1"
17652 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17653 (match_operand:DI 2 "register_operand" "a"))
17654 (set (match_operand:P 0 "register_operand" "=D")
17655 (plus:P (match_dup 1)
17656 (const_int 8)))
17657 (unspec [(const_int 0)] UNSPEC_STOS)]
17658 "TARGET_64BIT
17659 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17660 && ix86_check_no_addr_space (insn)"
17661 "%^stosq"
17662 [(set_attr "type" "str")
17663 (set_attr "memory" "store")
17664 (set_attr "mode" "DI")])
17665
17666 (define_insn "*strsetsi_1"
17667 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17668 (match_operand:SI 2 "register_operand" "a"))
17669 (set (match_operand:P 0 "register_operand" "=D")
17670 (plus:P (match_dup 1)
17671 (const_int 4)))
17672 (unspec [(const_int 0)] UNSPEC_STOS)]
17673 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17674 && ix86_check_no_addr_space (insn)"
17675 "%^stos{l|d}"
17676 [(set_attr "type" "str")
17677 (set_attr "memory" "store")
17678 (set_attr "mode" "SI")])
17679
17680 (define_insn "*strsethi_1"
17681 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17682 (match_operand:HI 2 "register_operand" "a"))
17683 (set (match_operand:P 0 "register_operand" "=D")
17684 (plus:P (match_dup 1)
17685 (const_int 2)))
17686 (unspec [(const_int 0)] UNSPEC_STOS)]
17687 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17688 && ix86_check_no_addr_space (insn)"
17689 "%^stosw"
17690 [(set_attr "type" "str")
17691 (set_attr "memory" "store")
17692 (set_attr "mode" "HI")])
17693
17694 (define_insn "*strsetqi_1"
17695 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17696 (match_operand:QI 2 "register_operand" "a"))
17697 (set (match_operand:P 0 "register_operand" "=D")
17698 (plus:P (match_dup 1)
17699 (const_int 1)))
17700 (unspec [(const_int 0)] UNSPEC_STOS)]
17701 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17702 && ix86_check_no_addr_space (insn)"
17703 "%^stosb"
17704 [(set_attr "type" "str")
17705 (set_attr "memory" "store")
17706 (set (attr "prefix_rex")
17707 (if_then_else
17708 (match_test "<P:MODE>mode == DImode")
17709 (const_string "0")
17710 (const_string "*")))
17711 (set_attr "mode" "QI")])
17712
17713 (define_expand "rep_stos"
17714 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17715 (set (match_operand 0 "register_operand")
17716 (match_operand 4))
17717 (set (match_operand 2 "memory_operand") (const_int 0))
17718 (use (match_operand 3 "register_operand"))
17719 (use (match_dup 1))])]
17720 ""
17721 {
17722 if (TARGET_CLD)
17723 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17724 })
17725
17726 (define_insn "*rep_stosdi_rex64"
17727 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17728 (set (match_operand:P 0 "register_operand" "=D")
17729 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17730 (const_int 3))
17731 (match_operand:P 3 "register_operand" "0")))
17732 (set (mem:BLK (match_dup 3))
17733 (const_int 0))
17734 (use (match_operand:DI 2 "register_operand" "a"))
17735 (use (match_dup 4))]
17736 "TARGET_64BIT
17737 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17738 && ix86_check_no_addr_space (insn)"
17739 "%^rep{%;} stosq"
17740 [(set_attr "type" "str")
17741 (set_attr "prefix_rep" "1")
17742 (set_attr "memory" "store")
17743 (set_attr "mode" "DI")])
17744
17745 (define_insn "*rep_stossi"
17746 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17747 (set (match_operand:P 0 "register_operand" "=D")
17748 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17749 (const_int 2))
17750 (match_operand:P 3 "register_operand" "0")))
17751 (set (mem:BLK (match_dup 3))
17752 (const_int 0))
17753 (use (match_operand:SI 2 "register_operand" "a"))
17754 (use (match_dup 4))]
17755 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17756 && ix86_check_no_addr_space (insn)"
17757 "%^rep{%;} stos{l|d}"
17758 [(set_attr "type" "str")
17759 (set_attr "prefix_rep" "1")
17760 (set_attr "memory" "store")
17761 (set_attr "mode" "SI")])
17762
17763 (define_insn "*rep_stosqi"
17764 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17765 (set (match_operand:P 0 "register_operand" "=D")
17766 (plus:P (match_operand:P 3 "register_operand" "0")
17767 (match_operand:P 4 "register_operand" "1")))
17768 (set (mem:BLK (match_dup 3))
17769 (const_int 0))
17770 (use (match_operand:QI 2 "register_operand" "a"))
17771 (use (match_dup 4))]
17772 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17773 && ix86_check_no_addr_space (insn)"
17774 "%^rep{%;} stosb"
17775 [(set_attr "type" "str")
17776 (set_attr "prefix_rep" "1")
17777 (set_attr "memory" "store")
17778 (set (attr "prefix_rex")
17779 (if_then_else
17780 (match_test "<P:MODE>mode == DImode")
17781 (const_string "0")
17782 (const_string "*")))
17783 (set_attr "mode" "QI")])
17784
17785 (define_expand "cmpstrnsi"
17786 [(set (match_operand:SI 0 "register_operand")
17787 (compare:SI (match_operand:BLK 1 "general_operand")
17788 (match_operand:BLK 2 "general_operand")))
17789 (use (match_operand 3 "general_operand"))
17790 (use (match_operand 4 "immediate_operand"))]
17791 ""
17792 {
17793 rtx addr1, addr2, out, outlow, count, countreg, align;
17794
17795 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17796 FAIL;
17797
17798 /* Can't use this if the user has appropriated ecx, esi or edi. */
17799 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17800 FAIL;
17801
17802 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17803 will have rewritten the length arg to be the minimum of the const string
17804 length and the actual length arg. If both strings are the same and
17805 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17806 will incorrectly base the results on chars past the 0 byte. */
17807 tree t1 = MEM_EXPR (operands[1]);
17808 tree t2 = MEM_EXPR (operands[2]);
17809 if (!((t1 && TREE_CODE (t1) == MEM_REF
17810 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17811 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17812 || (t2 && TREE_CODE (t2) == MEM_REF
17813 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17814 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17815 FAIL;
17816
17817 out = operands[0];
17818 if (!REG_P (out))
17819 out = gen_reg_rtx (SImode);
17820
17821 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17822 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17823 if (addr1 != XEXP (operands[1], 0))
17824 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17825 if (addr2 != XEXP (operands[2], 0))
17826 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17827
17828 count = operands[3];
17829 countreg = ix86_zero_extend_to_Pmode (count);
17830
17831 /* %%% Iff we are testing strict equality, we can use known alignment
17832 to good advantage. This may be possible with combine, particularly
17833 once cc0 is dead. */
17834 align = operands[4];
17835
17836 if (CONST_INT_P (count))
17837 {
17838 if (INTVAL (count) == 0)
17839 {
17840 emit_move_insn (operands[0], const0_rtx);
17841 DONE;
17842 }
17843 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17844 operands[1], operands[2]));
17845 }
17846 else
17847 {
17848 rtx (*gen_cmp) (rtx, rtx);
17849
17850 gen_cmp = (TARGET_64BIT
17851 ? gen_cmpdi_1 : gen_cmpsi_1);
17852
17853 emit_insn (gen_cmp (countreg, countreg));
17854 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17855 operands[1], operands[2]));
17856 }
17857
17858 outlow = gen_lowpart (QImode, out);
17859 emit_insn (gen_cmpintqi (outlow));
17860 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17861
17862 if (operands[0] != out)
17863 emit_move_insn (operands[0], out);
17864
17865 DONE;
17866 })
17867
17868 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17869
17870 (define_expand "cmpintqi"
17871 [(set (match_dup 1)
17872 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17873 (set (match_dup 2)
17874 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17875 (parallel [(set (match_operand:QI 0 "register_operand")
17876 (minus:QI (match_dup 1)
17877 (match_dup 2)))
17878 (clobber (reg:CC FLAGS_REG))])]
17879 ""
17880 {
17881 operands[1] = gen_reg_rtx (QImode);
17882 operands[2] = gen_reg_rtx (QImode);
17883 })
17884
17885 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17886 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17887
17888 (define_expand "cmpstrnqi_nz_1"
17889 [(parallel [(set (reg:CC FLAGS_REG)
17890 (compare:CC (match_operand 4 "memory_operand")
17891 (match_operand 5 "memory_operand")))
17892 (use (match_operand 2 "register_operand"))
17893 (use (match_operand:SI 3 "immediate_operand"))
17894 (clobber (match_operand 0 "register_operand"))
17895 (clobber (match_operand 1 "register_operand"))
17896 (clobber (match_dup 2))])]
17897 ""
17898 {
17899 if (TARGET_CLD)
17900 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17901 })
17902
17903 (define_insn "*cmpstrnqi_nz_1"
17904 [(set (reg:CC FLAGS_REG)
17905 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17906 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17907 (use (match_operand:P 6 "register_operand" "2"))
17908 (use (match_operand:SI 3 "immediate_operand" "i"))
17909 (clobber (match_operand:P 0 "register_operand" "=S"))
17910 (clobber (match_operand:P 1 "register_operand" "=D"))
17911 (clobber (match_operand:P 2 "register_operand" "=c"))]
17912 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17913 && ix86_check_no_addr_space (insn)"
17914 "%^repz{%;} cmpsb"
17915 [(set_attr "type" "str")
17916 (set_attr "mode" "QI")
17917 (set (attr "prefix_rex")
17918 (if_then_else
17919 (match_test "<P:MODE>mode == DImode")
17920 (const_string "0")
17921 (const_string "*")))
17922 (set_attr "prefix_rep" "1")])
17923
17924 ;; The same, but the count is not known to not be zero.
17925
17926 (define_expand "cmpstrnqi_1"
17927 [(parallel [(set (reg:CC FLAGS_REG)
17928 (if_then_else:CC (ne (match_operand 2 "register_operand")
17929 (const_int 0))
17930 (compare:CC (match_operand 4 "memory_operand")
17931 (match_operand 5 "memory_operand"))
17932 (const_int 0)))
17933 (use (match_operand:SI 3 "immediate_operand"))
17934 (use (reg:CC FLAGS_REG))
17935 (clobber (match_operand 0 "register_operand"))
17936 (clobber (match_operand 1 "register_operand"))
17937 (clobber (match_dup 2))])]
17938 ""
17939 {
17940 if (TARGET_CLD)
17941 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17942 })
17943
17944 (define_insn "*cmpstrnqi_1"
17945 [(set (reg:CC FLAGS_REG)
17946 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17947 (const_int 0))
17948 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17949 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17950 (const_int 0)))
17951 (use (match_operand:SI 3 "immediate_operand" "i"))
17952 (use (reg:CC FLAGS_REG))
17953 (clobber (match_operand:P 0 "register_operand" "=S"))
17954 (clobber (match_operand:P 1 "register_operand" "=D"))
17955 (clobber (match_operand:P 2 "register_operand" "=c"))]
17956 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17957 && ix86_check_no_addr_space (insn)"
17958 "%^repz{%;} cmpsb"
17959 [(set_attr "type" "str")
17960 (set_attr "mode" "QI")
17961 (set (attr "prefix_rex")
17962 (if_then_else
17963 (match_test "<P:MODE>mode == DImode")
17964 (const_string "0")
17965 (const_string "*")))
17966 (set_attr "prefix_rep" "1")])
17967
17968 (define_expand "strlen<mode>"
17969 [(set (match_operand:P 0 "register_operand")
17970 (unspec:P [(match_operand:BLK 1 "general_operand")
17971 (match_operand:QI 2 "immediate_operand")
17972 (match_operand 3 "immediate_operand")]
17973 UNSPEC_SCAS))]
17974 ""
17975 {
17976 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17977 DONE;
17978 else
17979 FAIL;
17980 })
17981
17982 (define_expand "strlenqi_1"
17983 [(parallel [(set (match_operand 0 "register_operand")
17984 (match_operand 2))
17985 (clobber (match_operand 1 "register_operand"))
17986 (clobber (reg:CC FLAGS_REG))])]
17987 ""
17988 {
17989 if (TARGET_CLD)
17990 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17991 })
17992
17993 (define_insn "*strlenqi_1"
17994 [(set (match_operand:P 0 "register_operand" "=&c")
17995 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17996 (match_operand:QI 2 "register_operand" "a")
17997 (match_operand:P 3 "immediate_operand" "i")
17998 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17999 (clobber (match_operand:P 1 "register_operand" "=D"))
18000 (clobber (reg:CC FLAGS_REG))]
18001 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18002 && ix86_check_no_addr_space (insn)"
18003 "%^repnz{%;} scasb"
18004 [(set_attr "type" "str")
18005 (set_attr "mode" "QI")
18006 (set (attr "prefix_rex")
18007 (if_then_else
18008 (match_test "<P:MODE>mode == DImode")
18009 (const_string "0")
18010 (const_string "*")))
18011 (set_attr "prefix_rep" "1")])
18012
18013 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18014 ;; handled in combine, but it is not currently up to the task.
18015 ;; When used for their truth value, the cmpstrn* expanders generate
18016 ;; code like this:
18017 ;;
18018 ;; repz cmpsb
18019 ;; seta %al
18020 ;; setb %dl
18021 ;; cmpb %al, %dl
18022 ;; jcc label
18023 ;;
18024 ;; The intermediate three instructions are unnecessary.
18025
18026 ;; This one handles cmpstrn*_nz_1...
18027 (define_peephole2
18028 [(parallel[
18029 (set (reg:CC FLAGS_REG)
18030 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18031 (mem:BLK (match_operand 5 "register_operand"))))
18032 (use (match_operand 6 "register_operand"))
18033 (use (match_operand:SI 3 "immediate_operand"))
18034 (clobber (match_operand 0 "register_operand"))
18035 (clobber (match_operand 1 "register_operand"))
18036 (clobber (match_operand 2 "register_operand"))])
18037 (set (match_operand:QI 7 "register_operand")
18038 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18039 (set (match_operand:QI 8 "register_operand")
18040 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18041 (set (reg FLAGS_REG)
18042 (compare (match_dup 7) (match_dup 8)))
18043 ]
18044 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18045 [(parallel[
18046 (set (reg:CC FLAGS_REG)
18047 (compare:CC (mem:BLK (match_dup 4))
18048 (mem:BLK (match_dup 5))))
18049 (use (match_dup 6))
18050 (use (match_dup 3))
18051 (clobber (match_dup 0))
18052 (clobber (match_dup 1))
18053 (clobber (match_dup 2))])])
18054
18055 ;; ...and this one handles cmpstrn*_1.
18056 (define_peephole2
18057 [(parallel[
18058 (set (reg:CC FLAGS_REG)
18059 (if_then_else:CC (ne (match_operand 6 "register_operand")
18060 (const_int 0))
18061 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18062 (mem:BLK (match_operand 5 "register_operand")))
18063 (const_int 0)))
18064 (use (match_operand:SI 3 "immediate_operand"))
18065 (use (reg:CC FLAGS_REG))
18066 (clobber (match_operand 0 "register_operand"))
18067 (clobber (match_operand 1 "register_operand"))
18068 (clobber (match_operand 2 "register_operand"))])
18069 (set (match_operand:QI 7 "register_operand")
18070 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18071 (set (match_operand:QI 8 "register_operand")
18072 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18073 (set (reg FLAGS_REG)
18074 (compare (match_dup 7) (match_dup 8)))
18075 ]
18076 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18077 [(parallel[
18078 (set (reg:CC FLAGS_REG)
18079 (if_then_else:CC (ne (match_dup 6)
18080 (const_int 0))
18081 (compare:CC (mem:BLK (match_dup 4))
18082 (mem:BLK (match_dup 5)))
18083 (const_int 0)))
18084 (use (match_dup 3))
18085 (use (reg:CC FLAGS_REG))
18086 (clobber (match_dup 0))
18087 (clobber (match_dup 1))
18088 (clobber (match_dup 2))])])
18089 \f
18090 ;; Conditional move instructions.
18091
18092 (define_expand "mov<mode>cc"
18093 [(set (match_operand:SWIM 0 "register_operand")
18094 (if_then_else:SWIM (match_operand 1 "comparison_operator")
18095 (match_operand:SWIM 2 "<general_operand>")
18096 (match_operand:SWIM 3 "<general_operand>")))]
18097 ""
18098 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18099
18100 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18101 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18102 ;; So just document what we're doing explicitly.
18103
18104 (define_expand "x86_mov<mode>cc_0_m1"
18105 [(parallel
18106 [(set (match_operand:SWI48 0 "register_operand")
18107 (if_then_else:SWI48
18108 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18109 [(match_operand 1 "flags_reg_operand")
18110 (const_int 0)])
18111 (const_int -1)
18112 (const_int 0)))
18113 (clobber (reg:CC FLAGS_REG))])])
18114
18115 (define_insn "*x86_mov<mode>cc_0_m1"
18116 [(set (match_operand:SWI48 0 "register_operand" "=r")
18117 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18118 [(reg FLAGS_REG) (const_int 0)])
18119 (const_int -1)
18120 (const_int 0)))
18121 (clobber (reg:CC FLAGS_REG))]
18122 ""
18123 "sbb{<imodesuffix>}\t%0, %0"
18124 [(set_attr "type" "alu1")
18125 (set_attr "modrm_class" "op0")
18126 (set_attr "use_carry" "1")
18127 (set_attr "pent_pair" "pu")
18128 (set_attr "mode" "<MODE>")
18129 (set_attr "length_immediate" "0")])
18130
18131 (define_insn "*x86_mov<mode>cc_0_m1_se"
18132 [(set (match_operand:SWI48 0 "register_operand" "=r")
18133 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18134 [(reg FLAGS_REG) (const_int 0)])
18135 (const_int 1)
18136 (const_int 0)))
18137 (clobber (reg:CC FLAGS_REG))]
18138 ""
18139 "sbb{<imodesuffix>}\t%0, %0"
18140 [(set_attr "type" "alu1")
18141 (set_attr "modrm_class" "op0")
18142 (set_attr "use_carry" "1")
18143 (set_attr "pent_pair" "pu")
18144 (set_attr "mode" "<MODE>")
18145 (set_attr "length_immediate" "0")])
18146
18147 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18148 [(set (match_operand:SWI48 0 "register_operand" "=r")
18149 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18150 [(reg FLAGS_REG) (const_int 0)])))
18151 (clobber (reg:CC FLAGS_REG))]
18152 ""
18153 "sbb{<imodesuffix>}\t%0, %0"
18154 [(set_attr "type" "alu1")
18155 (set_attr "modrm_class" "op0")
18156 (set_attr "use_carry" "1")
18157 (set_attr "pent_pair" "pu")
18158 (set_attr "mode" "<MODE>")
18159 (set_attr "length_immediate" "0")])
18160
18161 (define_insn "*mov<mode>cc_noc"
18162 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18163 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18164 [(reg FLAGS_REG) (const_int 0)])
18165 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18166 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18167 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18168 "@
18169 cmov%O2%C1\t{%2, %0|%0, %2}
18170 cmov%O2%c1\t{%3, %0|%0, %3}"
18171 [(set_attr "type" "icmov")
18172 (set_attr "mode" "<MODE>")])
18173
18174 (define_insn "*movsicc_noc_zext"
18175 [(set (match_operand:DI 0 "register_operand" "=r,r")
18176 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18177 [(reg FLAGS_REG) (const_int 0)])
18178 (zero_extend:DI
18179 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18180 (zero_extend:DI
18181 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18182 "TARGET_64BIT
18183 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18184 "@
18185 cmov%O2%C1\t{%2, %k0|%k0, %2}
18186 cmov%O2%c1\t{%3, %k0|%k0, %3}"
18187 [(set_attr "type" "icmov")
18188 (set_attr "mode" "SI")])
18189
18190 ;; Don't do conditional moves with memory inputs. This splitter helps
18191 ;; register starved x86_32 by forcing inputs into registers before reload.
18192 (define_split
18193 [(set (match_operand:SWI248 0 "register_operand")
18194 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18195 [(reg FLAGS_REG) (const_int 0)])
18196 (match_operand:SWI248 2 "nonimmediate_operand")
18197 (match_operand:SWI248 3 "nonimmediate_operand")))]
18198 "!TARGET_64BIT && TARGET_CMOVE
18199 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18200 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18201 && can_create_pseudo_p ()
18202 && optimize_insn_for_speed_p ()"
18203 [(set (match_dup 0)
18204 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18205 {
18206 if (MEM_P (operands[2]))
18207 operands[2] = force_reg (<MODE>mode, operands[2]);
18208 if (MEM_P (operands[3]))
18209 operands[3] = force_reg (<MODE>mode, operands[3]);
18210 })
18211
18212 (define_insn "*movqicc_noc"
18213 [(set (match_operand:QI 0 "register_operand" "=r,r")
18214 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18215 [(reg FLAGS_REG) (const_int 0)])
18216 (match_operand:QI 2 "register_operand" "r,0")
18217 (match_operand:QI 3 "register_operand" "0,r")))]
18218 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18219 "#"
18220 [(set_attr "type" "icmov")
18221 (set_attr "mode" "QI")])
18222
18223 (define_split
18224 [(set (match_operand:SWI12 0 "register_operand")
18225 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18226 [(reg FLAGS_REG) (const_int 0)])
18227 (match_operand:SWI12 2 "register_operand")
18228 (match_operand:SWI12 3 "register_operand")))]
18229 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18230 && reload_completed"
18231 [(set (match_dup 0)
18232 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18233 {
18234 operands[0] = gen_lowpart (SImode, operands[0]);
18235 operands[2] = gen_lowpart (SImode, operands[2]);
18236 operands[3] = gen_lowpart (SImode, operands[3]);
18237 })
18238
18239 ;; Don't do conditional moves with memory inputs
18240 (define_peephole2
18241 [(match_scratch:SWI248 4 "r")
18242 (set (match_operand:SWI248 0 "register_operand")
18243 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18244 [(reg FLAGS_REG) (const_int 0)])
18245 (match_operand:SWI248 2 "nonimmediate_operand")
18246 (match_operand:SWI248 3 "nonimmediate_operand")))]
18247 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18248 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18249 && optimize_insn_for_speed_p ()"
18250 [(set (match_dup 4) (match_dup 5))
18251 (set (match_dup 0)
18252 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18253 {
18254 if (MEM_P (operands[2]))
18255 {
18256 operands[5] = operands[2];
18257 operands[2] = operands[4];
18258 }
18259 else if (MEM_P (operands[3]))
18260 {
18261 operands[5] = operands[3];
18262 operands[3] = operands[4];
18263 }
18264 else
18265 gcc_unreachable ();
18266 })
18267
18268 (define_peephole2
18269 [(match_scratch:SI 4 "r")
18270 (set (match_operand:DI 0 "register_operand")
18271 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18272 [(reg FLAGS_REG) (const_int 0)])
18273 (zero_extend:DI
18274 (match_operand:SI 2 "nonimmediate_operand"))
18275 (zero_extend:DI
18276 (match_operand:SI 3 "nonimmediate_operand"))))]
18277 "TARGET_64BIT
18278 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18279 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18280 && optimize_insn_for_speed_p ()"
18281 [(set (match_dup 4) (match_dup 5))
18282 (set (match_dup 0)
18283 (if_then_else:DI (match_dup 1)
18284 (zero_extend:DI (match_dup 2))
18285 (zero_extend:DI (match_dup 3))))]
18286 {
18287 if (MEM_P (operands[2]))
18288 {
18289 operands[5] = operands[2];
18290 operands[2] = operands[4];
18291 }
18292 else if (MEM_P (operands[3]))
18293 {
18294 operands[5] = operands[3];
18295 operands[3] = operands[4];
18296 }
18297 else
18298 gcc_unreachable ();
18299 })
18300
18301 (define_expand "mov<mode>cc"
18302 [(set (match_operand:X87MODEF 0 "register_operand")
18303 (if_then_else:X87MODEF
18304 (match_operand 1 "comparison_operator")
18305 (match_operand:X87MODEF 2 "register_operand")
18306 (match_operand:X87MODEF 3 "register_operand")))]
18307 "(TARGET_80387 && TARGET_CMOVE)
18308 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18309 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18310
18311 (define_insn "*movxfcc_1"
18312 [(set (match_operand:XF 0 "register_operand" "=f,f")
18313 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18314 [(reg FLAGS_REG) (const_int 0)])
18315 (match_operand:XF 2 "register_operand" "f,0")
18316 (match_operand:XF 3 "register_operand" "0,f")))]
18317 "TARGET_80387 && TARGET_CMOVE"
18318 "@
18319 fcmov%F1\t{%2, %0|%0, %2}
18320 fcmov%f1\t{%3, %0|%0, %3}"
18321 [(set_attr "type" "fcmov")
18322 (set_attr "mode" "XF")])
18323
18324 (define_insn "*movdfcc_1"
18325 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18326 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18327 [(reg FLAGS_REG) (const_int 0)])
18328 (match_operand:DF 2 "nonimmediate_operand"
18329 "f ,0,rm,0 ,rm,0")
18330 (match_operand:DF 3 "nonimmediate_operand"
18331 "0 ,f,0 ,rm,0, rm")))]
18332 "TARGET_80387 && TARGET_CMOVE
18333 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18334 "@
18335 fcmov%F1\t{%2, %0|%0, %2}
18336 fcmov%f1\t{%3, %0|%0, %3}
18337 #
18338 #
18339 cmov%O2%C1\t{%2, %0|%0, %2}
18340 cmov%O2%c1\t{%3, %0|%0, %3}"
18341 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18342 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18343 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18344
18345 (define_split
18346 [(set (match_operand:DF 0 "general_reg_operand")
18347 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18348 [(reg FLAGS_REG) (const_int 0)])
18349 (match_operand:DF 2 "nonimmediate_operand")
18350 (match_operand:DF 3 "nonimmediate_operand")))]
18351 "!TARGET_64BIT && reload_completed"
18352 [(set (match_dup 2)
18353 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18354 (set (match_dup 3)
18355 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18356 {
18357 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18358 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18359 })
18360
18361 (define_insn "*movsfcc_1_387"
18362 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18363 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18364 [(reg FLAGS_REG) (const_int 0)])
18365 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18366 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18367 "TARGET_80387 && TARGET_CMOVE
18368 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18369 "@
18370 fcmov%F1\t{%2, %0|%0, %2}
18371 fcmov%f1\t{%3, %0|%0, %3}
18372 cmov%O2%C1\t{%2, %0|%0, %2}
18373 cmov%O2%c1\t{%3, %0|%0, %3}"
18374 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18375 (set_attr "mode" "SF,SF,SI,SI")])
18376
18377 ;; Don't do conditional moves with memory inputs. This splitter helps
18378 ;; register starved x86_32 by forcing inputs into registers before reload.
18379 (define_split
18380 [(set (match_operand:MODEF 0 "register_operand")
18381 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18382 [(reg FLAGS_REG) (const_int 0)])
18383 (match_operand:MODEF 2 "nonimmediate_operand")
18384 (match_operand:MODEF 3 "nonimmediate_operand")))]
18385 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18386 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18387 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18388 && can_create_pseudo_p ()
18389 && optimize_insn_for_speed_p ()"
18390 [(set (match_dup 0)
18391 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18392 {
18393 if (MEM_P (operands[2]))
18394 operands[2] = force_reg (<MODE>mode, operands[2]);
18395 if (MEM_P (operands[3]))
18396 operands[3] = force_reg (<MODE>mode, operands[3]);
18397 })
18398
18399 ;; Don't do conditional moves with memory inputs
18400 (define_peephole2
18401 [(match_scratch:MODEF 4 "r")
18402 (set (match_operand:MODEF 0 "general_reg_operand")
18403 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18404 [(reg FLAGS_REG) (const_int 0)])
18405 (match_operand:MODEF 2 "nonimmediate_operand")
18406 (match_operand:MODEF 3 "nonimmediate_operand")))]
18407 "(<MODE>mode != DFmode || TARGET_64BIT)
18408 && TARGET_80387 && TARGET_CMOVE
18409 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18410 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18411 && optimize_insn_for_speed_p ()"
18412 [(set (match_dup 4) (match_dup 5))
18413 (set (match_dup 0)
18414 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18415 {
18416 if (MEM_P (operands[2]))
18417 {
18418 operands[5] = operands[2];
18419 operands[2] = operands[4];
18420 }
18421 else if (MEM_P (operands[3]))
18422 {
18423 operands[5] = operands[3];
18424 operands[3] = operands[4];
18425 }
18426 else
18427 gcc_unreachable ();
18428 })
18429
18430 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18431 ;; the scalar versions to have only XMM registers as operands.
18432
18433 ;; XOP conditional move
18434 (define_insn "*xop_pcmov_<mode>"
18435 [(set (match_operand:MODEF 0 "register_operand" "=x")
18436 (if_then_else:MODEF
18437 (match_operand:MODEF 1 "register_operand" "x")
18438 (match_operand:MODEF 2 "register_operand" "x")
18439 (match_operand:MODEF 3 "register_operand" "x")))]
18440 "TARGET_XOP"
18441 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18442 [(set_attr "type" "sse4arg")])
18443
18444 ;; These versions of the min/max patterns are intentionally ignorant of
18445 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18446 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18447 ;; are undefined in this condition, we're certain this is correct.
18448
18449 (define_insn "<code><mode>3"
18450 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18451 (smaxmin:MODEF
18452 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18453 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18454 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18455 "@
18456 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18457 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18458 [(set_attr "isa" "noavx,avx")
18459 (set_attr "prefix" "orig,vex")
18460 (set_attr "type" "sseadd")
18461 (set_attr "mode" "<MODE>")])
18462
18463 ;; These versions of the min/max patterns implement exactly the operations
18464 ;; min = (op1 < op2 ? op1 : op2)
18465 ;; max = (!(op1 < op2) ? op1 : op2)
18466 ;; Their operands are not commutative, and thus they may be used in the
18467 ;; presence of -0.0 and NaN.
18468
18469 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18470 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18471 (unspec:MODEF
18472 [(match_operand:MODEF 1 "register_operand" "0,v")
18473 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18474 IEEE_MAXMIN))]
18475 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18476 "@
18477 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18478 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18479 [(set_attr "isa" "noavx,avx")
18480 (set_attr "prefix" "orig,maybe_evex")
18481 (set_attr "type" "sseadd")
18482 (set_attr "mode" "<MODE>")])
18483
18484 ;; Make two stack loads independent:
18485 ;; fld aa fld aa
18486 ;; fld %st(0) -> fld bb
18487 ;; fmul bb fmul %st(1), %st
18488 ;;
18489 ;; Actually we only match the last two instructions for simplicity.
18490
18491 (define_peephole2
18492 [(set (match_operand 0 "fp_register_operand")
18493 (match_operand 1 "fp_register_operand"))
18494 (set (match_dup 0)
18495 (match_operator 2 "binary_fp_operator"
18496 [(match_dup 0)
18497 (match_operand 3 "memory_operand")]))]
18498 "REGNO (operands[0]) != REGNO (operands[1])"
18499 [(set (match_dup 0) (match_dup 3))
18500 (set (match_dup 0)
18501 (match_op_dup 2
18502 [(match_dup 5) (match_dup 4)]))]
18503 {
18504 operands[4] = operands[0];
18505 operands[5] = operands[1];
18506
18507 /* The % modifier is not operational anymore in peephole2's, so we have to
18508 swap the operands manually in the case of addition and multiplication. */
18509 if (COMMUTATIVE_ARITH_P (operands[2]))
18510 std::swap (operands[4], operands[5]);
18511 })
18512
18513 (define_peephole2
18514 [(set (match_operand 0 "fp_register_operand")
18515 (match_operand 1 "fp_register_operand"))
18516 (set (match_dup 0)
18517 (match_operator 2 "binary_fp_operator"
18518 [(match_operand 3 "memory_operand")
18519 (match_dup 0)]))]
18520 "REGNO (operands[0]) != REGNO (operands[1])"
18521 [(set (match_dup 0) (match_dup 3))
18522 (set (match_dup 0)
18523 (match_op_dup 2
18524 [(match_dup 4) (match_dup 5)]))]
18525 {
18526 operands[4] = operands[0];
18527 operands[5] = operands[1];
18528
18529 /* The % modifier is not operational anymore in peephole2's, so we have to
18530 swap the operands manually in the case of addition and multiplication. */
18531 if (COMMUTATIVE_ARITH_P (operands[2]))
18532 std::swap (operands[4], operands[5]);
18533 })
18534
18535 ;; Conditional addition patterns
18536 (define_expand "add<mode>cc"
18537 [(match_operand:SWI 0 "register_operand")
18538 (match_operand 1 "ordered_comparison_operator")
18539 (match_operand:SWI 2 "register_operand")
18540 (match_operand:SWI 3 "const_int_operand")]
18541 ""
18542 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18543 \f
18544 ;; Misc patterns (?)
18545
18546 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18547 ;; Otherwise there will be nothing to keep
18548 ;;
18549 ;; [(set (reg ebp) (reg esp))]
18550 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18551 ;; (clobber (eflags)]
18552 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18553 ;;
18554 ;; in proper program order.
18555
18556 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18557 [(set (match_operand:P 0 "register_operand" "=r,r")
18558 (plus:P (match_operand:P 1 "register_operand" "0,r")
18559 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18560 (clobber (reg:CC FLAGS_REG))
18561 (clobber (mem:BLK (scratch)))]
18562 ""
18563 {
18564 switch (get_attr_type (insn))
18565 {
18566 case TYPE_IMOV:
18567 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18568
18569 case TYPE_ALU:
18570 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18571 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18572 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18573
18574 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18575
18576 default:
18577 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18578 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18579 }
18580 }
18581 [(set (attr "type")
18582 (cond [(and (eq_attr "alternative" "0")
18583 (not (match_test "TARGET_OPT_AGU")))
18584 (const_string "alu")
18585 (match_operand:<MODE> 2 "const0_operand")
18586 (const_string "imov")
18587 ]
18588 (const_string "lea")))
18589 (set (attr "length_immediate")
18590 (cond [(eq_attr "type" "imov")
18591 (const_string "0")
18592 (and (eq_attr "type" "alu")
18593 (match_operand 2 "const128_operand"))
18594 (const_string "1")
18595 ]
18596 (const_string "*")))
18597 (set_attr "mode" "<MODE>")])
18598
18599 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18600 [(set (match_operand:P 0 "register_operand" "=r")
18601 (minus:P (match_operand:P 1 "register_operand" "0")
18602 (match_operand:P 2 "register_operand" "r")))
18603 (clobber (reg:CC FLAGS_REG))
18604 (clobber (mem:BLK (scratch)))]
18605 ""
18606 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18607 [(set_attr "type" "alu")
18608 (set_attr "mode" "<MODE>")])
18609
18610 (define_insn "allocate_stack_worker_probe_<mode>"
18611 [(set (match_operand:P 0 "register_operand" "=a")
18612 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18613 UNSPECV_STACK_PROBE))
18614 (clobber (reg:CC FLAGS_REG))]
18615 "ix86_target_stack_probe ()"
18616 "call\t___chkstk_ms"
18617 [(set_attr "type" "multi")
18618 (set_attr "length" "5")])
18619
18620 (define_expand "allocate_stack"
18621 [(match_operand 0 "register_operand")
18622 (match_operand 1 "general_operand")]
18623 "ix86_target_stack_probe ()"
18624 {
18625 rtx x;
18626
18627 #ifndef CHECK_STACK_LIMIT
18628 #define CHECK_STACK_LIMIT 0
18629 #endif
18630
18631 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18632 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18633 x = operands[1];
18634 else
18635 {
18636 rtx (*insn) (rtx, rtx);
18637
18638 x = copy_to_mode_reg (Pmode, operands[1]);
18639
18640 insn = (TARGET_64BIT
18641 ? gen_allocate_stack_worker_probe_di
18642 : gen_allocate_stack_worker_probe_si);
18643
18644 emit_insn (insn (x, x));
18645 }
18646
18647 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18648 stack_pointer_rtx, 0, OPTAB_DIRECT);
18649
18650 if (x != stack_pointer_rtx)
18651 emit_move_insn (stack_pointer_rtx, x);
18652
18653 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18654 DONE;
18655 })
18656
18657 (define_expand "probe_stack"
18658 [(match_operand 0 "memory_operand")]
18659 ""
18660 {
18661 rtx (*insn) (rtx, rtx)
18662 = (GET_MODE (operands[0]) == DImode
18663 ? gen_probe_stack_di : gen_probe_stack_si);
18664
18665 emit_insn (insn (operands[0], const0_rtx));
18666 DONE;
18667 })
18668
18669 ;; Use OR for stack probes, this is shorter.
18670 (define_insn "probe_stack_<mode>"
18671 [(set (match_operand:W 0 "memory_operand" "=m")
18672 (unspec:W [(match_operand:W 1 "const0_operand")]
18673 UNSPEC_PROBE_STACK))
18674 (clobber (reg:CC FLAGS_REG))]
18675 ""
18676 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18677 [(set_attr "type" "alu1")
18678 (set_attr "mode" "<MODE>")
18679 (set_attr "length_immediate" "1")])
18680
18681 (define_insn "adjust_stack_and_probe<mode>"
18682 [(set (match_operand:P 0 "register_operand" "=r")
18683 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18684 UNSPECV_PROBE_STACK_RANGE))
18685 (set (reg:P SP_REG)
18686 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18687 (clobber (reg:CC FLAGS_REG))
18688 (clobber (mem:BLK (scratch)))]
18689 ""
18690 "* return output_adjust_stack_and_probe (operands[0]);"
18691 [(set_attr "type" "multi")])
18692
18693 (define_insn "probe_stack_range<mode>"
18694 [(set (match_operand:P 0 "register_operand" "=r")
18695 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18696 (match_operand:P 2 "const_int_operand" "n")]
18697 UNSPECV_PROBE_STACK_RANGE))
18698 (clobber (reg:CC FLAGS_REG))]
18699 ""
18700 "* return output_probe_stack_range (operands[0], operands[2]);"
18701 [(set_attr "type" "multi")])
18702
18703 (define_expand "builtin_setjmp_receiver"
18704 [(label_ref (match_operand 0))]
18705 "!TARGET_64BIT && flag_pic"
18706 {
18707 #if TARGET_MACHO
18708 if (TARGET_MACHO)
18709 {
18710 rtx xops[3];
18711 rtx_code_label *label_rtx = gen_label_rtx ();
18712 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18713 xops[0] = xops[1] = pic_offset_table_rtx;
18714 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18715 ix86_expand_binary_operator (MINUS, SImode, xops);
18716 }
18717 else
18718 #endif
18719 emit_insn (gen_set_got (pic_offset_table_rtx));
18720 DONE;
18721 })
18722
18723 (define_expand "save_stack_nonlocal"
18724 [(set (match_operand 0 "memory_operand")
18725 (match_operand 1 "register_operand"))]
18726 ""
18727 {
18728 rtx stack_slot;
18729 if ((flag_cf_protection & CF_RETURN))
18730 {
18731 /* Copy shadow stack pointer to the first slot and stack ppointer
18732 to the second slot. */
18733 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18734 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18735 rtx ssp = gen_reg_rtx (word_mode);
18736 emit_insn ((word_mode == SImode)
18737 ? gen_rdsspsi (ssp)
18738 : gen_rdsspdi (ssp));
18739 emit_move_insn (ssp_slot, ssp);
18740 }
18741 else
18742 stack_slot = adjust_address (operands[0], Pmode, 0);
18743 emit_move_insn (stack_slot, operands[1]);
18744 DONE;
18745 })
18746
18747 (define_expand "restore_stack_nonlocal"
18748 [(set (match_operand 0 "register_operand" "")
18749 (match_operand 1 "memory_operand" ""))]
18750 ""
18751 {
18752 rtx stack_slot;
18753 if ((flag_cf_protection & CF_RETURN))
18754 {
18755 /* Restore shadow stack pointer from the first slot and stack
18756 pointer from the second slot. */
18757 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18758 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18759
18760 rtx flags, jump, noadj_label, inc_label, loop_label;
18761 rtx reg_adj, reg_ssp, tmp, clob;
18762
18763 /* Get the current shadow stack pointer. The code below will check if
18764 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18765 is a NOP. */
18766 reg_ssp = gen_reg_rtx (word_mode);
18767 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18768 emit_insn ((word_mode == SImode)
18769 ? gen_rdsspsi (reg_ssp)
18770 : gen_rdsspdi (reg_ssp));
18771
18772 /* Compare through substraction the saved and the current ssp to decide
18773 if ssp has to be adjusted. */
18774 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18775 ssp_slot));
18776 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18777 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18778 emit_insn (tmp);
18779
18780 /* Compare and jump over adjustment code. */
18781 noadj_label = gen_label_rtx ();
18782 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18783 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18784 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18785 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18786 pc_rtx);
18787 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18788 JUMP_LABEL (jump) = noadj_label;
18789
18790 /* Compute the numebr of frames to adjust. */
18791 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18792 tmp = gen_rtx_SET (reg_adj,
18793 gen_rtx_LSHIFTRT (ptr_mode,
18794 negate_rtx (ptr_mode, reg_adj),
18795 GEN_INT ((word_mode == SImode)
18796 ? 2
18797 : 3)));
18798 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18799 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18800 emit_insn (tmp);
18801
18802 /* Check if number of frames <= 255 so no loop is needed. */
18803 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18804 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18805 emit_insn (gen_rtx_SET (flags, tmp));
18806
18807 inc_label = gen_label_rtx ();
18808 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18809 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18810 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18811 pc_rtx);
18812 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18813 JUMP_LABEL (jump) = inc_label;
18814
18815 rtx reg_255 = gen_reg_rtx (word_mode);
18816 emit_move_insn (reg_255, GEN_INT (255));
18817
18818 /* Adjust the ssp in a loop. */
18819 loop_label = gen_label_rtx ();
18820 emit_label (loop_label);
18821 LABEL_NUSES (loop_label) = 1;
18822
18823 emit_insn ((word_mode == SImode)
18824 ? gen_incsspsi (reg_255)
18825 : gen_incsspdi (reg_255));
18826 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18827 reg_adj,
18828 GEN_INT (255)));
18829 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18830 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18831 emit_insn (tmp);
18832
18833 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18834 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18835 emit_insn (gen_rtx_SET (flags, tmp));
18836
18837 /* Jump to the loop label. */
18838 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18839 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18840 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18841 pc_rtx);
18842 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18843 JUMP_LABEL (jump) = loop_label;
18844
18845 emit_label (inc_label);
18846 LABEL_NUSES (inc_label) = 1;
18847 emit_insn ((word_mode == SImode)
18848 ? gen_incsspsi (reg_ssp)
18849 : gen_incsspdi (reg_ssp));
18850
18851 emit_label (noadj_label);
18852 LABEL_NUSES (noadj_label) = 1;
18853 }
18854 else
18855 stack_slot = adjust_address (operands[1], Pmode, 0);
18856 emit_move_insn (operands[0], stack_slot);
18857 DONE;
18858 })
18859
18860
18861 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18862 ;; Do not split instructions with mask registers.
18863 (define_split
18864 [(set (match_operand 0 "general_reg_operand")
18865 (match_operator 3 "promotable_binary_operator"
18866 [(match_operand 1 "general_reg_operand")
18867 (match_operand 2 "aligned_operand")]))
18868 (clobber (reg:CC FLAGS_REG))]
18869 "! TARGET_PARTIAL_REG_STALL && reload_completed
18870 && ((GET_MODE (operands[0]) == HImode
18871 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18872 /* ??? next two lines just !satisfies_constraint_K (...) */
18873 || !CONST_INT_P (operands[2])
18874 || satisfies_constraint_K (operands[2])))
18875 || (GET_MODE (operands[0]) == QImode
18876 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18877 [(parallel [(set (match_dup 0)
18878 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18879 (clobber (reg:CC FLAGS_REG))])]
18880 {
18881 operands[0] = gen_lowpart (SImode, operands[0]);
18882 operands[1] = gen_lowpart (SImode, operands[1]);
18883 if (GET_CODE (operands[3]) != ASHIFT)
18884 operands[2] = gen_lowpart (SImode, operands[2]);
18885 operands[3] = shallow_copy_rtx (operands[3]);
18886 PUT_MODE (operands[3], SImode);
18887 })
18888
18889 ; Promote the QImode tests, as i386 has encoding of the AND
18890 ; instruction with 32-bit sign-extended immediate and thus the
18891 ; instruction size is unchanged, except in the %eax case for
18892 ; which it is increased by one byte, hence the ! optimize_size.
18893 (define_split
18894 [(set (match_operand 0 "flags_reg_operand")
18895 (match_operator 2 "compare_operator"
18896 [(and (match_operand 3 "aligned_operand")
18897 (match_operand 4 "const_int_operand"))
18898 (const_int 0)]))
18899 (set (match_operand 1 "register_operand")
18900 (and (match_dup 3) (match_dup 4)))]
18901 "! TARGET_PARTIAL_REG_STALL && reload_completed
18902 && optimize_insn_for_speed_p ()
18903 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18904 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18905 /* Ensure that the operand will remain sign-extended immediate. */
18906 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18907 [(parallel [(set (match_dup 0)
18908 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18909 (const_int 0)]))
18910 (set (match_dup 1)
18911 (and:SI (match_dup 3) (match_dup 4)))])]
18912 {
18913 operands[4]
18914 = gen_int_mode (INTVAL (operands[4])
18915 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18916 operands[1] = gen_lowpart (SImode, operands[1]);
18917 operands[3] = gen_lowpart (SImode, operands[3]);
18918 })
18919
18920 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18921 ; the TEST instruction with 32-bit sign-extended immediate and thus
18922 ; the instruction size would at least double, which is not what we
18923 ; want even with ! optimize_size.
18924 (define_split
18925 [(set (match_operand 0 "flags_reg_operand")
18926 (match_operator 1 "compare_operator"
18927 [(and (match_operand:HI 2 "aligned_operand")
18928 (match_operand:HI 3 "const_int_operand"))
18929 (const_int 0)]))]
18930 "! TARGET_PARTIAL_REG_STALL && reload_completed
18931 && ! TARGET_FAST_PREFIX
18932 && optimize_insn_for_speed_p ()
18933 /* Ensure that the operand will remain sign-extended immediate. */
18934 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18935 [(set (match_dup 0)
18936 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18937 (const_int 0)]))]
18938 {
18939 operands[3]
18940 = gen_int_mode (INTVAL (operands[3])
18941 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18942 operands[2] = gen_lowpart (SImode, operands[2]);
18943 })
18944
18945 (define_split
18946 [(set (match_operand 0 "register_operand")
18947 (neg (match_operand 1 "register_operand")))
18948 (clobber (reg:CC FLAGS_REG))]
18949 "! TARGET_PARTIAL_REG_STALL && reload_completed
18950 && (GET_MODE (operands[0]) == HImode
18951 || (GET_MODE (operands[0]) == QImode
18952 && (TARGET_PROMOTE_QImode
18953 || optimize_insn_for_size_p ())))"
18954 [(parallel [(set (match_dup 0)
18955 (neg:SI (match_dup 1)))
18956 (clobber (reg:CC FLAGS_REG))])]
18957 {
18958 operands[0] = gen_lowpart (SImode, operands[0]);
18959 operands[1] = gen_lowpart (SImode, operands[1]);
18960 })
18961
18962 ;; Do not split instructions with mask regs.
18963 (define_split
18964 [(set (match_operand 0 "general_reg_operand")
18965 (not (match_operand 1 "general_reg_operand")))]
18966 "! TARGET_PARTIAL_REG_STALL && reload_completed
18967 && (GET_MODE (operands[0]) == HImode
18968 || (GET_MODE (operands[0]) == QImode
18969 && (TARGET_PROMOTE_QImode
18970 || optimize_insn_for_size_p ())))"
18971 [(set (match_dup 0)
18972 (not:SI (match_dup 1)))]
18973 {
18974 operands[0] = gen_lowpart (SImode, operands[0]);
18975 operands[1] = gen_lowpart (SImode, operands[1]);
18976 })
18977 \f
18978 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18979 ;; transform a complex memory operation into two memory to register operations.
18980
18981 ;; Don't push memory operands
18982 (define_peephole2
18983 [(set (match_operand:SWI 0 "push_operand")
18984 (match_operand:SWI 1 "memory_operand"))
18985 (match_scratch:SWI 2 "<r>")]
18986 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18987 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18988 [(set (match_dup 2) (match_dup 1))
18989 (set (match_dup 0) (match_dup 2))])
18990
18991 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18992 ;; SImode pushes.
18993 (define_peephole2
18994 [(set (match_operand:SF 0 "push_operand")
18995 (match_operand:SF 1 "memory_operand"))
18996 (match_scratch:SF 2 "r")]
18997 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18998 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18999 [(set (match_dup 2) (match_dup 1))
19000 (set (match_dup 0) (match_dup 2))])
19001
19002 ;; Don't move an immediate directly to memory when the instruction
19003 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19004 (define_peephole2
19005 [(match_scratch:SWI124 1 "<r>")
19006 (set (match_operand:SWI124 0 "memory_operand")
19007 (const_int 0))]
19008 "optimize_insn_for_speed_p ()
19009 && ((<MODE>mode == HImode
19010 && TARGET_LCP_STALL)
19011 || (!TARGET_USE_MOV0
19012 && TARGET_SPLIT_LONG_MOVES
19013 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19014 && peep2_regno_dead_p (0, FLAGS_REG)"
19015 [(parallel [(set (match_dup 2) (const_int 0))
19016 (clobber (reg:CC FLAGS_REG))])
19017 (set (match_dup 0) (match_dup 1))]
19018 "operands[2] = gen_lowpart (SImode, operands[1]);")
19019
19020 (define_peephole2
19021 [(match_scratch:SWI124 2 "<r>")
19022 (set (match_operand:SWI124 0 "memory_operand")
19023 (match_operand:SWI124 1 "immediate_operand"))]
19024 "optimize_insn_for_speed_p ()
19025 && ((<MODE>mode == HImode
19026 && TARGET_LCP_STALL)
19027 || (TARGET_SPLIT_LONG_MOVES
19028 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19029 [(set (match_dup 2) (match_dup 1))
19030 (set (match_dup 0) (match_dup 2))])
19031
19032 ;; Don't compare memory with zero, load and use a test instead.
19033 (define_peephole2
19034 [(set (match_operand 0 "flags_reg_operand")
19035 (match_operator 1 "compare_operator"
19036 [(match_operand:SI 2 "memory_operand")
19037 (const_int 0)]))
19038 (match_scratch:SI 3 "r")]
19039 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19040 [(set (match_dup 3) (match_dup 2))
19041 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19042
19043 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19044 ;; Don't split NOTs with a displacement operand, because resulting XOR
19045 ;; will not be pairable anyway.
19046 ;;
19047 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19048 ;; represented using a modRM byte. The XOR replacement is long decoded,
19049 ;; so this split helps here as well.
19050 ;;
19051 ;; Note: Can't do this as a regular split because we can't get proper
19052 ;; lifetime information then.
19053
19054 (define_peephole2
19055 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19056 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19057 "optimize_insn_for_speed_p ()
19058 && ((TARGET_NOT_UNPAIRABLE
19059 && (!MEM_P (operands[0])
19060 || !memory_displacement_operand (operands[0], <MODE>mode)))
19061 || (TARGET_NOT_VECTORMODE
19062 && long_memory_operand (operands[0], <MODE>mode)))
19063 && peep2_regno_dead_p (0, FLAGS_REG)"
19064 [(parallel [(set (match_dup 0)
19065 (xor:SWI124 (match_dup 1) (const_int -1)))
19066 (clobber (reg:CC FLAGS_REG))])])
19067
19068 ;; Non pairable "test imm, reg" instructions can be translated to
19069 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19070 ;; byte opcode instead of two, have a short form for byte operands),
19071 ;; so do it for other CPUs as well. Given that the value was dead,
19072 ;; this should not create any new dependencies. Pass on the sub-word
19073 ;; versions if we're concerned about partial register stalls.
19074
19075 (define_peephole2
19076 [(set (match_operand 0 "flags_reg_operand")
19077 (match_operator 1 "compare_operator"
19078 [(and:SI (match_operand:SI 2 "register_operand")
19079 (match_operand:SI 3 "immediate_operand"))
19080 (const_int 0)]))]
19081 "ix86_match_ccmode (insn, CCNOmode)
19082 && (REGNO (operands[2]) != AX_REG
19083 || satisfies_constraint_K (operands[3]))
19084 && peep2_reg_dead_p (1, operands[2])"
19085 [(parallel
19086 [(set (match_dup 0)
19087 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19088 (const_int 0)]))
19089 (set (match_dup 2)
19090 (and:SI (match_dup 2) (match_dup 3)))])])
19091
19092 ;; We don't need to handle HImode case, because it will be promoted to SImode
19093 ;; on ! TARGET_PARTIAL_REG_STALL
19094
19095 (define_peephole2
19096 [(set (match_operand 0 "flags_reg_operand")
19097 (match_operator 1 "compare_operator"
19098 [(and:QI (match_operand:QI 2 "register_operand")
19099 (match_operand:QI 3 "immediate_operand"))
19100 (const_int 0)]))]
19101 "! TARGET_PARTIAL_REG_STALL
19102 && ix86_match_ccmode (insn, CCNOmode)
19103 && REGNO (operands[2]) != AX_REG
19104 && peep2_reg_dead_p (1, operands[2])"
19105 [(parallel
19106 [(set (match_dup 0)
19107 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19108 (const_int 0)]))
19109 (set (match_dup 2)
19110 (and:QI (match_dup 2) (match_dup 3)))])])
19111
19112 (define_peephole2
19113 [(set (match_operand 0 "flags_reg_operand")
19114 (match_operator 1 "compare_operator"
19115 [(and:QI
19116 (subreg:QI
19117 (zero_extract:SI (match_operand 2 "QIreg_operand")
19118 (const_int 8)
19119 (const_int 8)) 0)
19120 (match_operand 3 "const_int_operand"))
19121 (const_int 0)]))]
19122 "! TARGET_PARTIAL_REG_STALL
19123 && ix86_match_ccmode (insn, CCNOmode)
19124 && REGNO (operands[2]) != AX_REG
19125 && peep2_reg_dead_p (1, operands[2])"
19126 [(parallel
19127 [(set (match_dup 0)
19128 (match_op_dup 1
19129 [(and:QI
19130 (subreg:QI
19131 (zero_extract:SI (match_dup 2)
19132 (const_int 8)
19133 (const_int 8)) 0)
19134 (match_dup 3))
19135 (const_int 0)]))
19136 (set (zero_extract:SI (match_dup 2)
19137 (const_int 8)
19138 (const_int 8))
19139 (subreg:SI
19140 (and:QI
19141 (subreg:QI
19142 (zero_extract:SI (match_dup 2)
19143 (const_int 8)
19144 (const_int 8)) 0)
19145 (match_dup 3)) 0))])])
19146
19147 ;; Don't do logical operations with memory inputs.
19148 (define_peephole2
19149 [(match_scratch:SWI 2 "<r>")
19150 (parallel [(set (match_operand:SWI 0 "register_operand")
19151 (match_operator:SWI 3 "arith_or_logical_operator"
19152 [(match_dup 0)
19153 (match_operand:SWI 1 "memory_operand")]))
19154 (clobber (reg:CC FLAGS_REG))])]
19155 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19156 [(set (match_dup 2) (match_dup 1))
19157 (parallel [(set (match_dup 0)
19158 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19159 (clobber (reg:CC FLAGS_REG))])])
19160
19161 (define_peephole2
19162 [(match_scratch:SWI 2 "<r>")
19163 (parallel [(set (match_operand:SWI 0 "register_operand")
19164 (match_operator:SWI 3 "arith_or_logical_operator"
19165 [(match_operand:SWI 1 "memory_operand")
19166 (match_dup 0)]))
19167 (clobber (reg:CC FLAGS_REG))])]
19168 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19169 [(set (match_dup 2) (match_dup 1))
19170 (parallel [(set (match_dup 0)
19171 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19172 (clobber (reg:CC FLAGS_REG))])])
19173
19174 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
19175 ;; the memory address refers to the destination of the load!
19176
19177 (define_peephole2
19178 [(set (match_operand:SWI 0 "general_reg_operand")
19179 (match_operand:SWI 1 "general_reg_operand"))
19180 (parallel [(set (match_dup 0)
19181 (match_operator:SWI 3 "commutative_operator"
19182 [(match_dup 0)
19183 (match_operand:SWI 2 "memory_operand")]))
19184 (clobber (reg:CC FLAGS_REG))])]
19185 "REGNO (operands[0]) != REGNO (operands[1])
19186 && (<MODE>mode != QImode
19187 || any_QIreg_operand (operands[1], QImode))"
19188 [(set (match_dup 0) (match_dup 4))
19189 (parallel [(set (match_dup 0)
19190 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19191 (clobber (reg:CC FLAGS_REG))])]
19192 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19193
19194 (define_peephole2
19195 [(set (match_operand 0 "mmx_reg_operand")
19196 (match_operand 1 "mmx_reg_operand"))
19197 (set (match_dup 0)
19198 (match_operator 3 "commutative_operator"
19199 [(match_dup 0)
19200 (match_operand 2 "memory_operand")]))]
19201 "REGNO (operands[0]) != REGNO (operands[1])"
19202 [(set (match_dup 0) (match_dup 2))
19203 (set (match_dup 0)
19204 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19205
19206 (define_peephole2
19207 [(set (match_operand 0 "sse_reg_operand")
19208 (match_operand 1 "sse_reg_operand"))
19209 (set (match_dup 0)
19210 (match_operator 3 "commutative_operator"
19211 [(match_dup 0)
19212 (match_operand 2 "memory_operand")]))]
19213 "REGNO (operands[0]) != REGNO (operands[1])"
19214 [(set (match_dup 0) (match_dup 2))
19215 (set (match_dup 0)
19216 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19217
19218 ; Don't do logical operations with memory outputs
19219 ;
19220 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19221 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19222 ; the same decoder scheduling characteristics as the original.
19223
19224 (define_peephole2
19225 [(match_scratch:SWI 2 "<r>")
19226 (parallel [(set (match_operand:SWI 0 "memory_operand")
19227 (match_operator:SWI 3 "arith_or_logical_operator"
19228 [(match_dup 0)
19229 (match_operand:SWI 1 "<nonmemory_operand>")]))
19230 (clobber (reg:CC FLAGS_REG))])]
19231 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19232 [(set (match_dup 2) (match_dup 0))
19233 (parallel [(set (match_dup 2)
19234 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19235 (clobber (reg:CC FLAGS_REG))])
19236 (set (match_dup 0) (match_dup 2))])
19237
19238 (define_peephole2
19239 [(match_scratch:SWI 2 "<r>")
19240 (parallel [(set (match_operand:SWI 0 "memory_operand")
19241 (match_operator:SWI 3 "arith_or_logical_operator"
19242 [(match_operand:SWI 1 "<nonmemory_operand>")
19243 (match_dup 0)]))
19244 (clobber (reg:CC FLAGS_REG))])]
19245 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19246 [(set (match_dup 2) (match_dup 0))
19247 (parallel [(set (match_dup 2)
19248 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19249 (clobber (reg:CC FLAGS_REG))])
19250 (set (match_dup 0) (match_dup 2))])
19251
19252 ;; Attempt to use arith or logical operations with memory outputs with
19253 ;; setting of flags.
19254 (define_peephole2
19255 [(set (match_operand:SWI 0 "register_operand")
19256 (match_operand:SWI 1 "memory_operand"))
19257 (parallel [(set (match_dup 0)
19258 (match_operator:SWI 3 "plusminuslogic_operator"
19259 [(match_dup 0)
19260 (match_operand:SWI 2 "<nonmemory_operand>")]))
19261 (clobber (reg:CC FLAGS_REG))])
19262 (set (match_dup 1) (match_dup 0))
19263 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19264 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19265 && peep2_reg_dead_p (4, operands[0])
19266 && !reg_overlap_mentioned_p (operands[0], operands[1])
19267 && !reg_overlap_mentioned_p (operands[0], operands[2])
19268 && (<MODE>mode != QImode
19269 || immediate_operand (operands[2], QImode)
19270 || any_QIreg_operand (operands[2], QImode))
19271 && ix86_match_ccmode (peep2_next_insn (3),
19272 (GET_CODE (operands[3]) == PLUS
19273 || GET_CODE (operands[3]) == MINUS)
19274 ? CCGOCmode : CCNOmode)"
19275 [(parallel [(set (match_dup 4) (match_dup 6))
19276 (set (match_dup 1) (match_dup 5))])]
19277 {
19278 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19279 operands[5]
19280 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19281 copy_rtx (operands[1]),
19282 operands[2]);
19283 operands[6]
19284 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19285 copy_rtx (operands[5]),
19286 const0_rtx);
19287 })
19288
19289 ;; Likewise for cmpelim optimized pattern.
19290 (define_peephole2
19291 [(set (match_operand:SWI 0 "register_operand")
19292 (match_operand:SWI 1 "memory_operand"))
19293 (parallel [(set (reg FLAGS_REG)
19294 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19295 [(match_dup 0)
19296 (match_operand:SWI 2 "<nonmemory_operand>")])
19297 (const_int 0)))
19298 (set (match_dup 0) (match_dup 3))])
19299 (set (match_dup 1) (match_dup 0))]
19300 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19301 && peep2_reg_dead_p (3, operands[0])
19302 && !reg_overlap_mentioned_p (operands[0], operands[1])
19303 && !reg_overlap_mentioned_p (operands[0], operands[2])
19304 && ix86_match_ccmode (peep2_next_insn (1),
19305 (GET_CODE (operands[3]) == PLUS
19306 || GET_CODE (operands[3]) == MINUS)
19307 ? CCGOCmode : CCNOmode)"
19308 [(parallel [(set (match_dup 4) (match_dup 6))
19309 (set (match_dup 1) (match_dup 5))])]
19310 {
19311 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19312 operands[5]
19313 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19314 copy_rtx (operands[1]), operands[2]);
19315 operands[6]
19316 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19317 const0_rtx);
19318 })
19319
19320 ;; Likewise for instances where we have a lea pattern.
19321 (define_peephole2
19322 [(set (match_operand:SWI 0 "register_operand")
19323 (match_operand:SWI 1 "memory_operand"))
19324 (set (match_operand:SWI 3 "register_operand")
19325 (plus:SWI (match_dup 0)
19326 (match_operand:SWI 2 "<nonmemory_operand>")))
19327 (set (match_dup 1) (match_dup 3))
19328 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19329 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19330 && peep2_reg_dead_p (4, operands[3])
19331 && (rtx_equal_p (operands[0], operands[3])
19332 || peep2_reg_dead_p (2, operands[0]))
19333 && !reg_overlap_mentioned_p (operands[0], operands[1])
19334 && !reg_overlap_mentioned_p (operands[3], operands[1])
19335 && !reg_overlap_mentioned_p (operands[0], operands[2])
19336 && (<MODE>mode != QImode
19337 || immediate_operand (operands[2], QImode)
19338 || any_QIreg_operand (operands[2], QImode))
19339 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19340 [(parallel [(set (match_dup 4) (match_dup 6))
19341 (set (match_dup 1) (match_dup 5))])]
19342 {
19343 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19344 operands[5]
19345 = gen_rtx_PLUS (<MODE>mode,
19346 copy_rtx (operands[1]),
19347 operands[2]);
19348 operands[6]
19349 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19350 copy_rtx (operands[5]),
19351 const0_rtx);
19352 })
19353
19354 (define_peephole2
19355 [(parallel [(set (match_operand:SWI 0 "register_operand")
19356 (match_operator:SWI 2 "plusminuslogic_operator"
19357 [(match_dup 0)
19358 (match_operand:SWI 1 "memory_operand")]))
19359 (clobber (reg:CC FLAGS_REG))])
19360 (set (match_dup 1) (match_dup 0))
19361 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19362 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19363 && GET_CODE (operands[2]) != MINUS
19364 && peep2_reg_dead_p (3, operands[0])
19365 && !reg_overlap_mentioned_p (operands[0], operands[1])
19366 && ix86_match_ccmode (peep2_next_insn (2),
19367 GET_CODE (operands[2]) == PLUS
19368 ? CCGOCmode : CCNOmode)"
19369 [(parallel [(set (match_dup 3) (match_dup 5))
19370 (set (match_dup 1) (match_dup 4))])]
19371 {
19372 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19373 operands[4]
19374 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19375 copy_rtx (operands[1]),
19376 operands[0]);
19377 operands[5]
19378 = gen_rtx_COMPARE (GET_MODE (operands[3]),
19379 copy_rtx (operands[4]),
19380 const0_rtx);
19381 })
19382
19383 ;; Likewise for cmpelim optimized pattern.
19384 (define_peephole2
19385 [(parallel [(set (reg FLAGS_REG)
19386 (compare (match_operator:SWI 2 "plusminuslogic_operator"
19387 [(match_operand:SWI 0 "register_operand")
19388 (match_operand:SWI 1 "memory_operand")])
19389 (const_int 0)))
19390 (set (match_dup 0) (match_dup 2))])
19391 (set (match_dup 1) (match_dup 0))]
19392 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19393 && peep2_reg_dead_p (2, operands[0])
19394 && !reg_overlap_mentioned_p (operands[0], operands[1])
19395 && ix86_match_ccmode (peep2_next_insn (0),
19396 (GET_CODE (operands[2]) == PLUS
19397 || GET_CODE (operands[2]) == MINUS)
19398 ? CCGOCmode : CCNOmode)"
19399 [(parallel [(set (match_dup 3) (match_dup 5))
19400 (set (match_dup 1) (match_dup 4))])]
19401 {
19402 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19403 operands[4]
19404 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19405 copy_rtx (operands[1]), operands[0]);
19406 operands[5]
19407 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19408 const0_rtx);
19409 })
19410
19411 (define_peephole2
19412 [(set (match_operand:SWI12 0 "register_operand")
19413 (match_operand:SWI12 1 "memory_operand"))
19414 (parallel [(set (match_operand:SI 4 "register_operand")
19415 (match_operator:SI 3 "plusminuslogic_operator"
19416 [(match_dup 4)
19417 (match_operand:SI 2 "nonmemory_operand")]))
19418 (clobber (reg:CC FLAGS_REG))])
19419 (set (match_dup 1) (match_dup 0))
19420 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19421 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19422 && REGNO (operands[0]) == REGNO (operands[4])
19423 && peep2_reg_dead_p (4, operands[0])
19424 && (<MODE>mode != QImode
19425 || immediate_operand (operands[2], SImode)
19426 || any_QIreg_operand (operands[2], SImode))
19427 && !reg_overlap_mentioned_p (operands[0], operands[1])
19428 && !reg_overlap_mentioned_p (operands[0], operands[2])
19429 && ix86_match_ccmode (peep2_next_insn (3),
19430 (GET_CODE (operands[3]) == PLUS
19431 || GET_CODE (operands[3]) == MINUS)
19432 ? CCGOCmode : CCNOmode)"
19433 [(parallel [(set (match_dup 4) (match_dup 6))
19434 (set (match_dup 1) (match_dup 5))])]
19435 {
19436 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19437 operands[5]
19438 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19439 copy_rtx (operands[1]),
19440 gen_lowpart (<MODE>mode, operands[2]));
19441 operands[6]
19442 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19443 copy_rtx (operands[5]),
19444 const0_rtx);
19445 })
19446
19447 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19448 (define_peephole2
19449 [(set (match_operand 0 "general_reg_operand")
19450 (match_operand 1 "const0_operand"))]
19451 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19452 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19453 && peep2_regno_dead_p (0, FLAGS_REG)"
19454 [(parallel [(set (match_dup 0) (const_int 0))
19455 (clobber (reg:CC FLAGS_REG))])]
19456 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19457
19458 (define_peephole2
19459 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19460 (const_int 0))]
19461 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19462 && peep2_regno_dead_p (0, FLAGS_REG)"
19463 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19464 (clobber (reg:CC FLAGS_REG))])])
19465
19466 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19467 (define_peephole2
19468 [(set (match_operand:SWI248 0 "general_reg_operand")
19469 (const_int -1))]
19470 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19471 && peep2_regno_dead_p (0, FLAGS_REG)"
19472 [(parallel [(set (match_dup 0) (const_int -1))
19473 (clobber (reg:CC FLAGS_REG))])]
19474 {
19475 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19476 operands[0] = gen_lowpart (SImode, operands[0]);
19477 })
19478
19479 ;; Attempt to convert simple lea to add/shift.
19480 ;; These can be created by move expanders.
19481 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19482 ;; relevant lea instructions were already split.
19483
19484 (define_peephole2
19485 [(set (match_operand:SWI48 0 "register_operand")
19486 (plus:SWI48 (match_dup 0)
19487 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19488 "!TARGET_OPT_AGU
19489 && peep2_regno_dead_p (0, FLAGS_REG)"
19490 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19491 (clobber (reg:CC FLAGS_REG))])])
19492
19493 (define_peephole2
19494 [(set (match_operand:SWI48 0 "register_operand")
19495 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19496 (match_dup 0)))]
19497 "!TARGET_OPT_AGU
19498 && peep2_regno_dead_p (0, FLAGS_REG)"
19499 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19500 (clobber (reg:CC FLAGS_REG))])])
19501
19502 (define_peephole2
19503 [(set (match_operand:DI 0 "register_operand")
19504 (zero_extend:DI
19505 (plus:SI (match_operand:SI 1 "register_operand")
19506 (match_operand:SI 2 "nonmemory_operand"))))]
19507 "TARGET_64BIT && !TARGET_OPT_AGU
19508 && REGNO (operands[0]) == REGNO (operands[1])
19509 && peep2_regno_dead_p (0, FLAGS_REG)"
19510 [(parallel [(set (match_dup 0)
19511 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19512 (clobber (reg:CC FLAGS_REG))])])
19513
19514 (define_peephole2
19515 [(set (match_operand:DI 0 "register_operand")
19516 (zero_extend:DI
19517 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19518 (match_operand:SI 2 "register_operand"))))]
19519 "TARGET_64BIT && !TARGET_OPT_AGU
19520 && REGNO (operands[0]) == REGNO (operands[2])
19521 && peep2_regno_dead_p (0, FLAGS_REG)"
19522 [(parallel [(set (match_dup 0)
19523 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19524 (clobber (reg:CC FLAGS_REG))])])
19525
19526 (define_peephole2
19527 [(set (match_operand:SWI48 0 "register_operand")
19528 (mult:SWI48 (match_dup 0)
19529 (match_operand:SWI48 1 "const_int_operand")))]
19530 "pow2p_hwi (INTVAL (operands[1]))
19531 && peep2_regno_dead_p (0, FLAGS_REG)"
19532 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19533 (clobber (reg:CC FLAGS_REG))])]
19534 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19535
19536 (define_peephole2
19537 [(set (match_operand:DI 0 "register_operand")
19538 (zero_extend:DI
19539 (mult:SI (match_operand:SI 1 "register_operand")
19540 (match_operand:SI 2 "const_int_operand"))))]
19541 "TARGET_64BIT
19542 && pow2p_hwi (INTVAL (operands[2]))
19543 && REGNO (operands[0]) == REGNO (operands[1])
19544 && peep2_regno_dead_p (0, FLAGS_REG)"
19545 [(parallel [(set (match_dup 0)
19546 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19547 (clobber (reg:CC FLAGS_REG))])]
19548 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19549
19550 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19551 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19552 ;; On many CPUs it is also faster, since special hardware to avoid esp
19553 ;; dependencies is present.
19554
19555 ;; While some of these conversions may be done using splitters, we use
19556 ;; peepholes in order to allow combine_stack_adjustments pass to see
19557 ;; nonobfuscated RTL.
19558
19559 ;; Convert prologue esp subtractions to push.
19560 ;; We need register to push. In order to keep verify_flow_info happy we have
19561 ;; two choices
19562 ;; - use scratch and clobber it in order to avoid dependencies
19563 ;; - use already live register
19564 ;; We can't use the second way right now, since there is no reliable way how to
19565 ;; verify that given register is live. First choice will also most likely in
19566 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19567 ;; call clobbered registers are dead. We may want to use base pointer as an
19568 ;; alternative when no register is available later.
19569
19570 (define_peephole2
19571 [(match_scratch:W 1 "r")
19572 (parallel [(set (reg:P SP_REG)
19573 (plus:P (reg:P SP_REG)
19574 (match_operand:P 0 "const_int_operand")))
19575 (clobber (reg:CC FLAGS_REG))
19576 (clobber (mem:BLK (scratch)))])]
19577 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19578 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19579 && ix86_red_zone_size == 0"
19580 [(clobber (match_dup 1))
19581 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19582 (clobber (mem:BLK (scratch)))])])
19583
19584 (define_peephole2
19585 [(match_scratch:W 1 "r")
19586 (parallel [(set (reg:P SP_REG)
19587 (plus:P (reg:P SP_REG)
19588 (match_operand:P 0 "const_int_operand")))
19589 (clobber (reg:CC FLAGS_REG))
19590 (clobber (mem:BLK (scratch)))])]
19591 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19592 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19593 && ix86_red_zone_size == 0"
19594 [(clobber (match_dup 1))
19595 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19596 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19597 (clobber (mem:BLK (scratch)))])])
19598
19599 ;; Convert esp subtractions to push.
19600 (define_peephole2
19601 [(match_scratch:W 1 "r")
19602 (parallel [(set (reg:P SP_REG)
19603 (plus:P (reg:P SP_REG)
19604 (match_operand:P 0 "const_int_operand")))
19605 (clobber (reg:CC FLAGS_REG))])]
19606 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19607 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19608 && ix86_red_zone_size == 0"
19609 [(clobber (match_dup 1))
19610 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19611
19612 (define_peephole2
19613 [(match_scratch:W 1 "r")
19614 (parallel [(set (reg:P SP_REG)
19615 (plus:P (reg:P SP_REG)
19616 (match_operand:P 0 "const_int_operand")))
19617 (clobber (reg:CC FLAGS_REG))])]
19618 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19619 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19620 && ix86_red_zone_size == 0"
19621 [(clobber (match_dup 1))
19622 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19623 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19624
19625 ;; Convert epilogue deallocator to pop.
19626 (define_peephole2
19627 [(match_scratch:W 1 "r")
19628 (parallel [(set (reg:P SP_REG)
19629 (plus:P (reg:P SP_REG)
19630 (match_operand:P 0 "const_int_operand")))
19631 (clobber (reg:CC FLAGS_REG))
19632 (clobber (mem:BLK (scratch)))])]
19633 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19634 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19635 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19636 (clobber (mem:BLK (scratch)))])])
19637
19638 ;; Two pops case is tricky, since pop causes dependency
19639 ;; on destination register. We use two registers if available.
19640 (define_peephole2
19641 [(match_scratch:W 1 "r")
19642 (match_scratch:W 2 "r")
19643 (parallel [(set (reg:P SP_REG)
19644 (plus:P (reg:P SP_REG)
19645 (match_operand:P 0 "const_int_operand")))
19646 (clobber (reg:CC FLAGS_REG))
19647 (clobber (mem:BLK (scratch)))])]
19648 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19649 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19650 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19651 (clobber (mem:BLK (scratch)))])
19652 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19653
19654 (define_peephole2
19655 [(match_scratch:W 1 "r")
19656 (parallel [(set (reg:P SP_REG)
19657 (plus:P (reg:P SP_REG)
19658 (match_operand:P 0 "const_int_operand")))
19659 (clobber (reg:CC FLAGS_REG))
19660 (clobber (mem:BLK (scratch)))])]
19661 "optimize_insn_for_size_p ()
19662 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19663 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19664 (clobber (mem:BLK (scratch)))])
19665 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19666
19667 ;; Convert esp additions to pop.
19668 (define_peephole2
19669 [(match_scratch:W 1 "r")
19670 (parallel [(set (reg:P SP_REG)
19671 (plus:P (reg:P SP_REG)
19672 (match_operand:P 0 "const_int_operand")))
19673 (clobber (reg:CC FLAGS_REG))])]
19674 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19675 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19676
19677 ;; Two pops case is tricky, since pop causes dependency
19678 ;; on destination register. We use two registers if available.
19679 (define_peephole2
19680 [(match_scratch:W 1 "r")
19681 (match_scratch:W 2 "r")
19682 (parallel [(set (reg:P SP_REG)
19683 (plus:P (reg:P SP_REG)
19684 (match_operand:P 0 "const_int_operand")))
19685 (clobber (reg:CC FLAGS_REG))])]
19686 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19687 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19688 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19689
19690 (define_peephole2
19691 [(match_scratch:W 1 "r")
19692 (parallel [(set (reg:P SP_REG)
19693 (plus:P (reg:P SP_REG)
19694 (match_operand:P 0 "const_int_operand")))
19695 (clobber (reg:CC FLAGS_REG))])]
19696 "optimize_insn_for_size_p ()
19697 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19698 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19699 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19700 \f
19701 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19702 ;; required and register dies. Similarly for 128 to -128.
19703 (define_peephole2
19704 [(set (match_operand 0 "flags_reg_operand")
19705 (match_operator 1 "compare_operator"
19706 [(match_operand 2 "register_operand")
19707 (match_operand 3 "const_int_operand")]))]
19708 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19709 && incdec_operand (operands[3], GET_MODE (operands[3])))
19710 || (!TARGET_FUSE_CMP_AND_BRANCH
19711 && INTVAL (operands[3]) == 128))
19712 && ix86_match_ccmode (insn, CCGCmode)
19713 && peep2_reg_dead_p (1, operands[2])"
19714 [(parallel [(set (match_dup 0)
19715 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19716 (clobber (match_dup 2))])])
19717 \f
19718 ;; Convert imul by three, five and nine into lea
19719 (define_peephole2
19720 [(parallel
19721 [(set (match_operand:SWI48 0 "register_operand")
19722 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19723 (match_operand:SWI48 2 "const359_operand")))
19724 (clobber (reg:CC FLAGS_REG))])]
19725 "!TARGET_PARTIAL_REG_STALL
19726 || <MODE>mode == SImode
19727 || optimize_function_for_size_p (cfun)"
19728 [(set (match_dup 0)
19729 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19730 (match_dup 1)))]
19731 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19732
19733 (define_peephole2
19734 [(parallel
19735 [(set (match_operand:SWI48 0 "register_operand")
19736 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19737 (match_operand:SWI48 2 "const359_operand")))
19738 (clobber (reg:CC FLAGS_REG))])]
19739 "optimize_insn_for_speed_p ()
19740 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19741 [(set (match_dup 0) (match_dup 1))
19742 (set (match_dup 0)
19743 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19744 (match_dup 0)))]
19745 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19746
19747 ;; imul $32bit_imm, mem, reg is vector decoded, while
19748 ;; imul $32bit_imm, reg, reg is direct decoded.
19749 (define_peephole2
19750 [(match_scratch:SWI48 3 "r")
19751 (parallel [(set (match_operand:SWI48 0 "register_operand")
19752 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19753 (match_operand:SWI48 2 "immediate_operand")))
19754 (clobber (reg:CC FLAGS_REG))])]
19755 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19756 && !satisfies_constraint_K (operands[2])"
19757 [(set (match_dup 3) (match_dup 1))
19758 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19759 (clobber (reg:CC FLAGS_REG))])])
19760
19761 (define_peephole2
19762 [(match_scratch:SI 3 "r")
19763 (parallel [(set (match_operand:DI 0 "register_operand")
19764 (zero_extend:DI
19765 (mult:SI (match_operand:SI 1 "memory_operand")
19766 (match_operand:SI 2 "immediate_operand"))))
19767 (clobber (reg:CC FLAGS_REG))])]
19768 "TARGET_64BIT
19769 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19770 && !satisfies_constraint_K (operands[2])"
19771 [(set (match_dup 3) (match_dup 1))
19772 (parallel [(set (match_dup 0)
19773 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19774 (clobber (reg:CC FLAGS_REG))])])
19775
19776 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19777 ;; Convert it into imul reg, reg
19778 ;; It would be better to force assembler to encode instruction using long
19779 ;; immediate, but there is apparently no way to do so.
19780 (define_peephole2
19781 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19782 (mult:SWI248
19783 (match_operand:SWI248 1 "nonimmediate_operand")
19784 (match_operand:SWI248 2 "const_int_operand")))
19785 (clobber (reg:CC FLAGS_REG))])
19786 (match_scratch:SWI248 3 "r")]
19787 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19788 && satisfies_constraint_K (operands[2])"
19789 [(set (match_dup 3) (match_dup 2))
19790 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19791 (clobber (reg:CC FLAGS_REG))])]
19792 {
19793 if (!rtx_equal_p (operands[0], operands[1]))
19794 emit_move_insn (operands[0], operands[1]);
19795 })
19796
19797 ;; After splitting up read-modify operations, array accesses with memory
19798 ;; operands might end up in form:
19799 ;; sall $2, %eax
19800 ;; movl 4(%esp), %edx
19801 ;; addl %edx, %eax
19802 ;; instead of pre-splitting:
19803 ;; sall $2, %eax
19804 ;; addl 4(%esp), %eax
19805 ;; Turn it into:
19806 ;; movl 4(%esp), %edx
19807 ;; leal (%edx,%eax,4), %eax
19808
19809 (define_peephole2
19810 [(match_scratch:W 5 "r")
19811 (parallel [(set (match_operand 0 "register_operand")
19812 (ashift (match_operand 1 "register_operand")
19813 (match_operand 2 "const_int_operand")))
19814 (clobber (reg:CC FLAGS_REG))])
19815 (parallel [(set (match_operand 3 "register_operand")
19816 (plus (match_dup 0)
19817 (match_operand 4 "x86_64_general_operand")))
19818 (clobber (reg:CC FLAGS_REG))])]
19819 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19820 /* Validate MODE for lea. */
19821 && ((!TARGET_PARTIAL_REG_STALL
19822 && (GET_MODE (operands[0]) == QImode
19823 || GET_MODE (operands[0]) == HImode))
19824 || GET_MODE (operands[0]) == SImode
19825 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19826 && (rtx_equal_p (operands[0], operands[3])
19827 || peep2_reg_dead_p (2, operands[0]))
19828 /* We reorder load and the shift. */
19829 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19830 [(set (match_dup 5) (match_dup 4))
19831 (set (match_dup 0) (match_dup 1))]
19832 {
19833 machine_mode op1mode = GET_MODE (operands[1]);
19834 machine_mode mode = op1mode == DImode ? DImode : SImode;
19835 int scale = 1 << INTVAL (operands[2]);
19836 rtx index = gen_lowpart (word_mode, operands[1]);
19837 rtx base = gen_lowpart (word_mode, operands[5]);
19838 rtx dest = gen_lowpart (mode, operands[3]);
19839
19840 operands[1] = gen_rtx_PLUS (word_mode, base,
19841 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19842 if (mode != word_mode)
19843 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19844
19845 operands[5] = base;
19846 if (op1mode != word_mode)
19847 operands[5] = gen_lowpart (op1mode, operands[5]);
19848
19849 operands[0] = dest;
19850 })
19851 \f
19852 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19853 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19854 ;; caught for use by garbage collectors and the like. Using an insn that
19855 ;; maps to SIGILL makes it more likely the program will rightfully die.
19856 ;; Keeping with tradition, "6" is in honor of #UD.
19857 (define_insn "trap"
19858 [(trap_if (const_int 1) (const_int 6))]
19859 ""
19860 {
19861 #ifdef HAVE_AS_IX86_UD2
19862 return "ud2";
19863 #else
19864 return ASM_SHORT "0x0b0f";
19865 #endif
19866 }
19867 [(set_attr "length" "2")])
19868
19869 (define_insn "ud2"
19870 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19871 ""
19872 {
19873 #ifdef HAVE_AS_IX86_UD2
19874 return "ud2";
19875 #else
19876 return ASM_SHORT "0x0b0f";
19877 #endif
19878 }
19879 [(set_attr "length" "2")])
19880
19881 (define_expand "prefetch"
19882 [(prefetch (match_operand 0 "address_operand")
19883 (match_operand:SI 1 "const_int_operand")
19884 (match_operand:SI 2 "const_int_operand"))]
19885 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19886 {
19887 bool write = INTVAL (operands[1]) != 0;
19888 int locality = INTVAL (operands[2]);
19889
19890 gcc_assert (IN_RANGE (locality, 0, 3));
19891
19892 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19893 supported by SSE counterpart (non-SSE2 athlon machines) or the
19894 SSE prefetch is not available (K6 machines). Otherwise use SSE
19895 prefetch as it allows specifying of locality. */
19896
19897 if (write)
19898 {
19899 if (TARGET_PREFETCHWT1)
19900 operands[2] = GEN_INT (MAX (locality, 2));
19901 else if (TARGET_PRFCHW)
19902 operands[2] = GEN_INT (3);
19903 else if (TARGET_3DNOW && !TARGET_SSE2)
19904 operands[2] = GEN_INT (3);
19905 else if (TARGET_PREFETCH_SSE)
19906 operands[1] = const0_rtx;
19907 else
19908 {
19909 gcc_assert (TARGET_3DNOW);
19910 operands[2] = GEN_INT (3);
19911 }
19912 }
19913 else
19914 {
19915 if (TARGET_PREFETCH_SSE)
19916 ;
19917 else
19918 {
19919 gcc_assert (TARGET_3DNOW);
19920 operands[2] = GEN_INT (3);
19921 }
19922 }
19923 })
19924
19925 (define_insn "*prefetch_sse"
19926 [(prefetch (match_operand 0 "address_operand" "p")
19927 (const_int 0)
19928 (match_operand:SI 1 "const_int_operand"))]
19929 "TARGET_PREFETCH_SSE"
19930 {
19931 static const char * const patterns[4] = {
19932 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19933 };
19934
19935 int locality = INTVAL (operands[1]);
19936 gcc_assert (IN_RANGE (locality, 0, 3));
19937
19938 return patterns[locality];
19939 }
19940 [(set_attr "type" "sse")
19941 (set_attr "atom_sse_attr" "prefetch")
19942 (set (attr "length_address")
19943 (symbol_ref "memory_address_length (operands[0], false)"))
19944 (set_attr "memory" "none")])
19945
19946 (define_insn "*prefetch_3dnow"
19947 [(prefetch (match_operand 0 "address_operand" "p")
19948 (match_operand:SI 1 "const_int_operand" "n")
19949 (const_int 3))]
19950 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19951 {
19952 if (INTVAL (operands[1]) == 0)
19953 return "prefetch\t%a0";
19954 else
19955 return "prefetchw\t%a0";
19956 }
19957 [(set_attr "type" "mmx")
19958 (set (attr "length_address")
19959 (symbol_ref "memory_address_length (operands[0], false)"))
19960 (set_attr "memory" "none")])
19961
19962 (define_insn "*prefetch_prefetchwt1"
19963 [(prefetch (match_operand 0 "address_operand" "p")
19964 (const_int 1)
19965 (const_int 2))]
19966 "TARGET_PREFETCHWT1"
19967 "prefetchwt1\t%a0";
19968 [(set_attr "type" "sse")
19969 (set (attr "length_address")
19970 (symbol_ref "memory_address_length (operands[0], false)"))
19971 (set_attr "memory" "none")])
19972
19973 (define_expand "stack_protect_set"
19974 [(match_operand 0 "memory_operand")
19975 (match_operand 1 "memory_operand")]
19976 "TARGET_SSP_TLS_GUARD"
19977 {
19978 rtx (*insn)(rtx, rtx);
19979
19980 insn = (TARGET_LP64
19981 ? gen_stack_protect_set_di
19982 : gen_stack_protect_set_si);
19983
19984 emit_insn (insn (operands[0], operands[1]));
19985 DONE;
19986 })
19987
19988 (define_insn "stack_protect_set_<mode>"
19989 [(set (match_operand:PTR 0 "memory_operand" "=m")
19990 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19991 UNSPEC_SP_SET))
19992 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19993 (clobber (reg:CC FLAGS_REG))]
19994 "TARGET_SSP_TLS_GUARD"
19995 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19996 [(set_attr "type" "multi")])
19997
19998 (define_expand "stack_protect_test"
19999 [(match_operand 0 "memory_operand")
20000 (match_operand 1 "memory_operand")
20001 (match_operand 2)]
20002 "TARGET_SSP_TLS_GUARD"
20003 {
20004 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20005
20006 rtx (*insn)(rtx, rtx, rtx);
20007
20008 insn = (TARGET_LP64
20009 ? gen_stack_protect_test_di
20010 : gen_stack_protect_test_si);
20011
20012 emit_insn (insn (flags, operands[0], operands[1]));
20013
20014 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20015 flags, const0_rtx, operands[2]));
20016 DONE;
20017 })
20018
20019 (define_insn "stack_protect_test_<mode>"
20020 [(set (match_operand:CCZ 0 "flags_reg_operand")
20021 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20022 (match_operand:PTR 2 "memory_operand" "m")]
20023 UNSPEC_SP_TEST))
20024 (clobber (match_scratch:PTR 3 "=&r"))]
20025 "TARGET_SSP_TLS_GUARD"
20026 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
20027 [(set_attr "type" "multi")])
20028
20029 (define_insn "sse4_2_crc32<mode>"
20030 [(set (match_operand:SI 0 "register_operand" "=r")
20031 (unspec:SI
20032 [(match_operand:SI 1 "register_operand" "0")
20033 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20034 UNSPEC_CRC32))]
20035 "TARGET_SSE4_2 || TARGET_CRC32"
20036 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20037 [(set_attr "type" "sselog1")
20038 (set_attr "prefix_rep" "1")
20039 (set_attr "prefix_extra" "1")
20040 (set (attr "prefix_data16")
20041 (if_then_else (match_operand:HI 2)
20042 (const_string "1")
20043 (const_string "*")))
20044 (set (attr "prefix_rex")
20045 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20046 (const_string "1")
20047 (const_string "*")))
20048 (set_attr "mode" "SI")])
20049
20050 (define_insn "sse4_2_crc32di"
20051 [(set (match_operand:DI 0 "register_operand" "=r")
20052 (unspec:DI
20053 [(match_operand:DI 1 "register_operand" "0")
20054 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20055 UNSPEC_CRC32))]
20056 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20057 "crc32{q}\t{%2, %0|%0, %2}"
20058 [(set_attr "type" "sselog1")
20059 (set_attr "prefix_rep" "1")
20060 (set_attr "prefix_extra" "1")
20061 (set_attr "mode" "DI")])
20062
20063 (define_insn "rdpmc"
20064 [(set (match_operand:DI 0 "register_operand" "=A")
20065 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20066 UNSPECV_RDPMC))]
20067 "!TARGET_64BIT"
20068 "rdpmc"
20069 [(set_attr "type" "other")
20070 (set_attr "length" "2")])
20071
20072 (define_insn "rdpmc_rex64"
20073 [(set (match_operand:DI 0 "register_operand" "=a")
20074 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20075 UNSPECV_RDPMC))
20076 (set (match_operand:DI 1 "register_operand" "=d")
20077 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
20078 "TARGET_64BIT"
20079 "rdpmc"
20080 [(set_attr "type" "other")
20081 (set_attr "length" "2")])
20082
20083 (define_insn "rdtsc"
20084 [(set (match_operand:DI 0 "register_operand" "=A")
20085 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20086 "!TARGET_64BIT"
20087 "rdtsc"
20088 [(set_attr "type" "other")
20089 (set_attr "length" "2")])
20090
20091 (define_insn "rdtsc_rex64"
20092 [(set (match_operand:DI 0 "register_operand" "=a")
20093 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20094 (set (match_operand:DI 1 "register_operand" "=d")
20095 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20096 "TARGET_64BIT"
20097 "rdtsc"
20098 [(set_attr "type" "other")
20099 (set_attr "length" "2")])
20100
20101 (define_insn "rdtscp"
20102 [(set (match_operand:DI 0 "register_operand" "=A")
20103 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20104 (set (match_operand:SI 1 "register_operand" "=c")
20105 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20106 "!TARGET_64BIT"
20107 "rdtscp"
20108 [(set_attr "type" "other")
20109 (set_attr "length" "3")])
20110
20111 (define_insn "rdtscp_rex64"
20112 [(set (match_operand:DI 0 "register_operand" "=a")
20113 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20114 (set (match_operand:DI 1 "register_operand" "=d")
20115 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20116 (set (match_operand:SI 2 "register_operand" "=c")
20117 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20118 "TARGET_64BIT"
20119 "rdtscp"
20120 [(set_attr "type" "other")
20121 (set_attr "length" "3")])
20122
20123 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20124 ;;
20125 ;; FXSR, XSAVE and XSAVEOPT instructions
20126 ;;
20127 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20128
20129 (define_insn "fxsave"
20130 [(set (match_operand:BLK 0 "memory_operand" "=m")
20131 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20132 "TARGET_FXSR"
20133 "fxsave\t%0"
20134 [(set_attr "type" "other")
20135 (set_attr "memory" "store")
20136 (set (attr "length")
20137 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20138
20139 (define_insn "fxsave64"
20140 [(set (match_operand:BLK 0 "memory_operand" "=m")
20141 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20142 "TARGET_64BIT && TARGET_FXSR"
20143 "fxsave64\t%0"
20144 [(set_attr "type" "other")
20145 (set_attr "memory" "store")
20146 (set (attr "length")
20147 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20148
20149 (define_insn "fxrstor"
20150 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20151 UNSPECV_FXRSTOR)]
20152 "TARGET_FXSR"
20153 "fxrstor\t%0"
20154 [(set_attr "type" "other")
20155 (set_attr "memory" "load")
20156 (set (attr "length")
20157 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20158
20159 (define_insn "fxrstor64"
20160 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20161 UNSPECV_FXRSTOR64)]
20162 "TARGET_64BIT && TARGET_FXSR"
20163 "fxrstor64\t%0"
20164 [(set_attr "type" "other")
20165 (set_attr "memory" "load")
20166 (set (attr "length")
20167 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20168
20169 (define_int_iterator ANY_XSAVE
20170 [UNSPECV_XSAVE
20171 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20172 (UNSPECV_XSAVEC "TARGET_XSAVEC")
20173 (UNSPECV_XSAVES "TARGET_XSAVES")])
20174
20175 (define_int_iterator ANY_XSAVE64
20176 [UNSPECV_XSAVE64
20177 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20178 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20179 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20180
20181 (define_int_attr xsave
20182 [(UNSPECV_XSAVE "xsave")
20183 (UNSPECV_XSAVE64 "xsave64")
20184 (UNSPECV_XSAVEOPT "xsaveopt")
20185 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20186 (UNSPECV_XSAVEC "xsavec")
20187 (UNSPECV_XSAVEC64 "xsavec64")
20188 (UNSPECV_XSAVES "xsaves")
20189 (UNSPECV_XSAVES64 "xsaves64")])
20190
20191 (define_int_iterator ANY_XRSTOR
20192 [UNSPECV_XRSTOR
20193 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20194
20195 (define_int_iterator ANY_XRSTOR64
20196 [UNSPECV_XRSTOR64
20197 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20198
20199 (define_int_attr xrstor
20200 [(UNSPECV_XRSTOR "xrstor")
20201 (UNSPECV_XRSTOR64 "xrstor")
20202 (UNSPECV_XRSTORS "xrstors")
20203 (UNSPECV_XRSTORS64 "xrstors")])
20204
20205 (define_insn "<xsave>"
20206 [(set (match_operand:BLK 0 "memory_operand" "=m")
20207 (unspec_volatile:BLK
20208 [(match_operand:DI 1 "register_operand" "A")]
20209 ANY_XSAVE))]
20210 "!TARGET_64BIT && TARGET_XSAVE"
20211 "<xsave>\t%0"
20212 [(set_attr "type" "other")
20213 (set_attr "memory" "store")
20214 (set (attr "length")
20215 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20216
20217 (define_insn "<xsave>_rex64"
20218 [(set (match_operand:BLK 0 "memory_operand" "=m")
20219 (unspec_volatile:BLK
20220 [(match_operand:SI 1 "register_operand" "a")
20221 (match_operand:SI 2 "register_operand" "d")]
20222 ANY_XSAVE))]
20223 "TARGET_64BIT && TARGET_XSAVE"
20224 "<xsave>\t%0"
20225 [(set_attr "type" "other")
20226 (set_attr "memory" "store")
20227 (set (attr "length")
20228 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20229
20230 (define_insn "<xsave>"
20231 [(set (match_operand:BLK 0 "memory_operand" "=m")
20232 (unspec_volatile:BLK
20233 [(match_operand:SI 1 "register_operand" "a")
20234 (match_operand:SI 2 "register_operand" "d")]
20235 ANY_XSAVE64))]
20236 "TARGET_64BIT && TARGET_XSAVE"
20237 "<xsave>\t%0"
20238 [(set_attr "type" "other")
20239 (set_attr "memory" "store")
20240 (set (attr "length")
20241 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20242
20243 (define_insn "<xrstor>"
20244 [(unspec_volatile:BLK
20245 [(match_operand:BLK 0 "memory_operand" "m")
20246 (match_operand:DI 1 "register_operand" "A")]
20247 ANY_XRSTOR)]
20248 "!TARGET_64BIT && TARGET_XSAVE"
20249 "<xrstor>\t%0"
20250 [(set_attr "type" "other")
20251 (set_attr "memory" "load")
20252 (set (attr "length")
20253 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20254
20255 (define_insn "<xrstor>_rex64"
20256 [(unspec_volatile:BLK
20257 [(match_operand:BLK 0 "memory_operand" "m")
20258 (match_operand:SI 1 "register_operand" "a")
20259 (match_operand:SI 2 "register_operand" "d")]
20260 ANY_XRSTOR)]
20261 "TARGET_64BIT && TARGET_XSAVE"
20262 "<xrstor>\t%0"
20263 [(set_attr "type" "other")
20264 (set_attr "memory" "load")
20265 (set (attr "length")
20266 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20267
20268 (define_insn "<xrstor>64"
20269 [(unspec_volatile:BLK
20270 [(match_operand:BLK 0 "memory_operand" "m")
20271 (match_operand:SI 1 "register_operand" "a")
20272 (match_operand:SI 2 "register_operand" "d")]
20273 ANY_XRSTOR64)]
20274 "TARGET_64BIT && TARGET_XSAVE"
20275 "<xrstor>64\t%0"
20276 [(set_attr "type" "other")
20277 (set_attr "memory" "load")
20278 (set (attr "length")
20279 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20280
20281 (define_insn "xsetbv"
20282 [(unspec_volatile:SI
20283 [(match_operand:SI 0 "register_operand" "c")
20284 (match_operand:DI 1 "register_operand" "A")]
20285 UNSPECV_XSETBV)]
20286 "!TARGET_64BIT && TARGET_XSAVE"
20287 "xsetbv"
20288 [(set_attr "type" "other")])
20289
20290 (define_insn "xsetbv_rex64"
20291 [(unspec_volatile:SI
20292 [(match_operand:SI 0 "register_operand" "c")
20293 (match_operand:SI 1 "register_operand" "a")
20294 (match_operand:SI 2 "register_operand" "d")]
20295 UNSPECV_XSETBV)]
20296 "TARGET_64BIT && TARGET_XSAVE"
20297 "xsetbv"
20298 [(set_attr "type" "other")])
20299
20300 (define_insn "xgetbv"
20301 [(set (match_operand:DI 0 "register_operand" "=A")
20302 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20303 UNSPECV_XGETBV))]
20304 "!TARGET_64BIT && TARGET_XSAVE"
20305 "xgetbv"
20306 [(set_attr "type" "other")])
20307
20308 (define_insn "xgetbv_rex64"
20309 [(set (match_operand:DI 0 "register_operand" "=a")
20310 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20311 UNSPECV_XGETBV))
20312 (set (match_operand:DI 1 "register_operand" "=d")
20313 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20314 "TARGET_64BIT && TARGET_XSAVE"
20315 "xgetbv"
20316 [(set_attr "type" "other")])
20317
20318 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20319 ;;
20320 ;; Floating-point instructions for atomic compound assignments
20321 ;;
20322 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20323
20324 ; Clobber all floating-point registers on environment save and restore
20325 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20326 (define_insn "fnstenv"
20327 [(set (match_operand:BLK 0 "memory_operand" "=m")
20328 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20329 (clobber (reg:HI FPCR_REG))
20330 (clobber (reg:XF ST0_REG))
20331 (clobber (reg:XF ST1_REG))
20332 (clobber (reg:XF ST2_REG))
20333 (clobber (reg:XF ST3_REG))
20334 (clobber (reg:XF ST4_REG))
20335 (clobber (reg:XF ST5_REG))
20336 (clobber (reg:XF ST6_REG))
20337 (clobber (reg:XF ST7_REG))]
20338 "TARGET_80387"
20339 "fnstenv\t%0"
20340 [(set_attr "type" "other")
20341 (set_attr "memory" "store")
20342 (set (attr "length")
20343 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20344
20345 (define_insn "fldenv"
20346 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20347 UNSPECV_FLDENV)
20348 (clobber (reg:CCFP FPSR_REG))
20349 (clobber (reg:HI FPCR_REG))
20350 (clobber (reg:XF ST0_REG))
20351 (clobber (reg:XF ST1_REG))
20352 (clobber (reg:XF ST2_REG))
20353 (clobber (reg:XF ST3_REG))
20354 (clobber (reg:XF ST4_REG))
20355 (clobber (reg:XF ST5_REG))
20356 (clobber (reg:XF ST6_REG))
20357 (clobber (reg:XF ST7_REG))]
20358 "TARGET_80387"
20359 "fldenv\t%0"
20360 [(set_attr "type" "other")
20361 (set_attr "memory" "load")
20362 (set (attr "length")
20363 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20364
20365 (define_insn "fnstsw"
20366 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20367 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20368 "TARGET_80387"
20369 "fnstsw\t%0"
20370 [(set_attr "type" "other,other")
20371 (set_attr "memory" "none,store")
20372 (set (attr "length")
20373 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20374
20375 (define_insn "fnclex"
20376 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20377 "TARGET_80387"
20378 "fnclex"
20379 [(set_attr "type" "other")
20380 (set_attr "memory" "none")
20381 (set_attr "length" "2")])
20382
20383 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20384 ;;
20385 ;; LWP instructions
20386 ;;
20387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20388
20389 (define_expand "lwp_llwpcb"
20390 [(unspec_volatile [(match_operand 0 "register_operand")]
20391 UNSPECV_LLWP_INTRINSIC)]
20392 "TARGET_LWP")
20393
20394 (define_insn "*lwp_llwpcb<mode>1"
20395 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20396 UNSPECV_LLWP_INTRINSIC)]
20397 "TARGET_LWP"
20398 "llwpcb\t%0"
20399 [(set_attr "type" "lwp")
20400 (set_attr "mode" "<MODE>")
20401 (set_attr "length" "5")])
20402
20403 (define_expand "lwp_slwpcb"
20404 [(set (match_operand 0 "register_operand")
20405 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20406 "TARGET_LWP"
20407 {
20408 rtx (*insn)(rtx);
20409
20410 insn = (Pmode == DImode
20411 ? gen_lwp_slwpcbdi
20412 : gen_lwp_slwpcbsi);
20413
20414 emit_insn (insn (operands[0]));
20415 DONE;
20416 })
20417
20418 (define_insn "lwp_slwpcb<mode>"
20419 [(set (match_operand:P 0 "register_operand" "=r")
20420 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20421 "TARGET_LWP"
20422 "slwpcb\t%0"
20423 [(set_attr "type" "lwp")
20424 (set_attr "mode" "<MODE>")
20425 (set_attr "length" "5")])
20426
20427 (define_expand "lwp_lwpval<mode>3"
20428 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20429 (match_operand:SI 2 "nonimmediate_operand")
20430 (match_operand:SI 3 "const_int_operand")]
20431 UNSPECV_LWPVAL_INTRINSIC)]
20432 "TARGET_LWP"
20433 ;; Avoid unused variable warning.
20434 "(void) operands[0];")
20435
20436 (define_insn "*lwp_lwpval<mode>3_1"
20437 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20438 (match_operand:SI 1 "nonimmediate_operand" "rm")
20439 (match_operand:SI 2 "const_int_operand" "i")]
20440 UNSPECV_LWPVAL_INTRINSIC)]
20441 "TARGET_LWP"
20442 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20443 [(set_attr "type" "lwp")
20444 (set_attr "mode" "<MODE>")
20445 (set (attr "length")
20446 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20447
20448 (define_expand "lwp_lwpins<mode>3"
20449 [(set (reg:CCC FLAGS_REG)
20450 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20451 (match_operand:SI 2 "nonimmediate_operand")
20452 (match_operand:SI 3 "const_int_operand")]
20453 UNSPECV_LWPINS_INTRINSIC))
20454 (set (match_operand:QI 0 "nonimmediate_operand")
20455 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20456 "TARGET_LWP")
20457
20458 (define_insn "*lwp_lwpins<mode>3_1"
20459 [(set (reg:CCC FLAGS_REG)
20460 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20461 (match_operand:SI 1 "nonimmediate_operand" "rm")
20462 (match_operand:SI 2 "const_int_operand" "i")]
20463 UNSPECV_LWPINS_INTRINSIC))]
20464 "TARGET_LWP"
20465 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20466 [(set_attr "type" "lwp")
20467 (set_attr "mode" "<MODE>")
20468 (set (attr "length")
20469 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20470
20471 (define_int_iterator RDFSGSBASE
20472 [UNSPECV_RDFSBASE
20473 UNSPECV_RDGSBASE])
20474
20475 (define_int_iterator WRFSGSBASE
20476 [UNSPECV_WRFSBASE
20477 UNSPECV_WRGSBASE])
20478
20479 (define_int_attr fsgs
20480 [(UNSPECV_RDFSBASE "fs")
20481 (UNSPECV_RDGSBASE "gs")
20482 (UNSPECV_WRFSBASE "fs")
20483 (UNSPECV_WRGSBASE "gs")])
20484
20485 (define_insn "rd<fsgs>base<mode>"
20486 [(set (match_operand:SWI48 0 "register_operand" "=r")
20487 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20488 "TARGET_64BIT && TARGET_FSGSBASE"
20489 "rd<fsgs>base\t%0"
20490 [(set_attr "type" "other")
20491 (set_attr "prefix_extra" "2")])
20492
20493 (define_insn "wr<fsgs>base<mode>"
20494 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20495 WRFSGSBASE)]
20496 "TARGET_64BIT && TARGET_FSGSBASE"
20497 "wr<fsgs>base\t%0"
20498 [(set_attr "type" "other")
20499 (set_attr "prefix_extra" "2")])
20500
20501 (define_insn "rdrand<mode>_1"
20502 [(set (match_operand:SWI248 0 "register_operand" "=r")
20503 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20504 (set (reg:CCC FLAGS_REG)
20505 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20506 "TARGET_RDRND"
20507 "rdrand\t%0"
20508 [(set_attr "type" "other")
20509 (set_attr "prefix_extra" "1")])
20510
20511 (define_insn "rdseed<mode>_1"
20512 [(set (match_operand:SWI248 0 "register_operand" "=r")
20513 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20514 (set (reg:CCC FLAGS_REG)
20515 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20516 "TARGET_RDSEED"
20517 "rdseed\t%0"
20518 [(set_attr "type" "other")
20519 (set_attr "prefix_extra" "1")])
20520
20521 (define_expand "pause"
20522 [(set (match_dup 0)
20523 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20524 ""
20525 {
20526 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20527 MEM_VOLATILE_P (operands[0]) = 1;
20528 })
20529
20530 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20531 ;; They have the same encoding.
20532 (define_insn "*pause"
20533 [(set (match_operand:BLK 0)
20534 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20535 ""
20536 "rep%; nop"
20537 [(set_attr "length" "2")
20538 (set_attr "memory" "unknown")])
20539
20540 ;; CET instructions
20541 (define_insn "rdssp<mode>"
20542 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20543 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20544 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20545 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20546 [(set_attr "length" "6")
20547 (set_attr "type" "other")])
20548
20549 (define_insn "incssp<mode>"
20550 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20551 UNSPECV_INCSSP)]
20552 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20553 "incssp<mskmodesuffix>\t%0"
20554 [(set_attr "length" "4")
20555 (set_attr "type" "other")])
20556
20557 (define_insn "saveprevssp"
20558 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20559 "TARGET_SHSTK"
20560 "saveprevssp"
20561 [(set_attr "length" "5")
20562 (set_attr "type" "other")])
20563
20564 (define_insn "rstorssp"
20565 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20566 UNSPECV_RSTORSSP)]
20567 "TARGET_SHSTK"
20568 "rstorssp\t%0"
20569 [(set_attr "length" "5")
20570 (set_attr "type" "other")])
20571
20572 (define_insn "wrss<mode>"
20573 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20574 (match_operand:SWI48x 1 "memory_operand" "m")]
20575 UNSPECV_WRSS)]
20576 "TARGET_SHSTK"
20577 "wrss<mskmodesuffix>\t%0, %1"
20578 [(set_attr "length" "3")
20579 (set_attr "type" "other")])
20580
20581 (define_insn "wruss<mode>"
20582 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20583 (match_operand:SWI48x 1 "memory_operand" "m")]
20584 UNSPECV_WRUSS)]
20585 "TARGET_SHSTK"
20586 "wruss<mskmodesuffix>\t%0, %1"
20587 [(set_attr "length" "4")
20588 (set_attr "type" "other")])
20589
20590 (define_insn "setssbsy"
20591 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20592 "TARGET_SHSTK"
20593 "setssbsy"
20594 [(set_attr "length" "4")
20595 (set_attr "type" "other")])
20596
20597 (define_insn "clrssbsy"
20598 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20599 UNSPECV_CLRSSBSY)]
20600 "TARGET_SHSTK"
20601 "clrssbsy\t%0"
20602 [(set_attr "length" "4")
20603 (set_attr "type" "other")])
20604
20605 (define_insn "nop_endbr"
20606 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20607 "(flag_cf_protection & CF_BRANCH)"
20608 "*
20609 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20610 [(set_attr "length" "4")
20611 (set_attr "length_immediate" "0")
20612 (set_attr "modrm" "0")])
20613
20614 ;; For RTM support
20615 (define_expand "xbegin"
20616 [(set (match_operand:SI 0 "register_operand")
20617 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20618 "TARGET_RTM"
20619 {
20620 rtx_code_label *label = gen_label_rtx ();
20621
20622 /* xbegin is emitted as jump_insn, so reload won't be able
20623 to reload its operand. Force the value into AX hard register. */
20624 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20625 emit_move_insn (ax_reg, constm1_rtx);
20626
20627 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20628
20629 emit_label (label);
20630 LABEL_NUSES (label) = 1;
20631
20632 emit_move_insn (operands[0], ax_reg);
20633
20634 DONE;
20635 })
20636
20637 (define_insn "xbegin_1"
20638 [(set (pc)
20639 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20640 (const_int 0))
20641 (label_ref (match_operand 1))
20642 (pc)))
20643 (set (match_operand:SI 0 "register_operand" "+a")
20644 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20645 "TARGET_RTM"
20646 "xbegin\t%l1"
20647 [(set_attr "type" "other")
20648 (set_attr "length" "6")])
20649
20650 (define_insn "xend"
20651 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20652 "TARGET_RTM"
20653 "xend"
20654 [(set_attr "type" "other")
20655 (set_attr "length" "3")])
20656
20657 (define_insn "xabort"
20658 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20659 UNSPECV_XABORT)]
20660 "TARGET_RTM"
20661 "xabort\t%0"
20662 [(set_attr "type" "other")
20663 (set_attr "length" "3")])
20664
20665 (define_expand "xtest"
20666 [(set (match_operand:QI 0 "register_operand")
20667 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20668 "TARGET_RTM"
20669 {
20670 emit_insn (gen_xtest_1 ());
20671
20672 ix86_expand_setcc (operands[0], NE,
20673 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20674 DONE;
20675 })
20676
20677 (define_insn "xtest_1"
20678 [(set (reg:CCZ FLAGS_REG)
20679 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20680 "TARGET_RTM"
20681 "xtest"
20682 [(set_attr "type" "other")
20683 (set_attr "length" "3")])
20684
20685 (define_insn "clwb"
20686 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20687 UNSPECV_CLWB)]
20688 "TARGET_CLWB"
20689 "clwb\t%a0"
20690 [(set_attr "type" "sse")
20691 (set_attr "atom_sse_attr" "fence")
20692 (set_attr "memory" "unknown")])
20693
20694 (define_insn "clflushopt"
20695 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20696 UNSPECV_CLFLUSHOPT)]
20697 "TARGET_CLFLUSHOPT"
20698 "clflushopt\t%a0"
20699 [(set_attr "type" "sse")
20700 (set_attr "atom_sse_attr" "fence")
20701 (set_attr "memory" "unknown")])
20702
20703 ;; MONITORX and MWAITX
20704 (define_insn "mwaitx"
20705 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20706 (match_operand:SI 1 "register_operand" "a")
20707 (match_operand:SI 2 "register_operand" "b")]
20708 UNSPECV_MWAITX)]
20709 "TARGET_MWAITX"
20710 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20711 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20712 ;; we only need to set up 32bit registers.
20713 "mwaitx"
20714 [(set_attr "length" "3")])
20715
20716 (define_insn "monitorx_<mode>"
20717 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20718 (match_operand:SI 1 "register_operand" "c")
20719 (match_operand:SI 2 "register_operand" "d")]
20720 UNSPECV_MONITORX)]
20721 "TARGET_MWAITX"
20722 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20723 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20724 ;; zero extended to 64bit, we only need to set up 32bit registers.
20725 "%^monitorx"
20726 [(set (attr "length")
20727 (symbol_ref ("(Pmode != word_mode) + 3")))])
20728
20729 ;; CLZERO
20730 (define_insn "clzero_<mode>"
20731 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20732 UNSPECV_CLZERO)]
20733 "TARGET_CLZERO"
20734 "clzero"
20735 [(set_attr "length" "3")
20736 (set_attr "memory" "unknown")])
20737
20738 ;; MPX instructions
20739
20740 (define_expand "<mode>_mk"
20741 [(set (match_operand:BND 0 "register_operand")
20742 (unspec:BND
20743 [(mem:<bnd_ptr>
20744 (match_par_dup 3
20745 [(match_operand:<bnd_ptr> 1 "register_operand")
20746 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20747 UNSPEC_BNDMK))]
20748 "TARGET_MPX"
20749 {
20750 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20751 operands[2]),
20752 UNSPEC_BNDMK_ADDR);
20753 })
20754
20755 (define_insn "*<mode>_mk"
20756 [(set (match_operand:BND 0 "register_operand" "=w")
20757 (unspec:BND
20758 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20759 [(unspec:<bnd_ptr>
20760 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20761 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20762 UNSPEC_BNDMK_ADDR)])]
20763 UNSPEC_BNDMK))]
20764 "TARGET_MPX"
20765 "bndmk\t{%3, %0|%0, %3}"
20766 [(set_attr "type" "mpxmk")])
20767
20768 (define_expand "mov<mode>"
20769 [(set (match_operand:BND 0 "general_operand")
20770 (match_operand:BND 1 "general_operand"))]
20771 "TARGET_MPX"
20772 "ix86_expand_move (<MODE>mode, operands); DONE;")
20773
20774 (define_insn "*mov<mode>_internal_mpx"
20775 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20776 (match_operand:BND 1 "general_operand" "wm,w"))]
20777 "TARGET_MPX"
20778 "bndmov\t{%1, %0|%0, %1}"
20779 [(set_attr "type" "mpxmov")])
20780
20781 (define_expand "<mode>_<bndcheck>"
20782 [(parallel
20783 [(unspec
20784 [(match_operand:BND 0 "register_operand")
20785 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20786 (set (match_dup 2)
20787 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20788 "TARGET_MPX"
20789 {
20790 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20791 MEM_VOLATILE_P (operands[2]) = 1;
20792 })
20793
20794 (define_insn "*<mode>_<bndcheck>"
20795 [(unspec
20796 [(match_operand:BND 0 "register_operand" "w")
20797 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20798 (set (match_operand:BLK 2 "bnd_mem_operator")
20799 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20800 "TARGET_MPX"
20801 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20802 [(set_attr "type" "mpxchk")])
20803
20804 (define_expand "<mode>_ldx"
20805 [(parallel
20806 [(set (match_operand:BND 0 "register_operand")
20807 (unspec:BND
20808 [(mem:<bnd_ptr>
20809 (match_par_dup 3
20810 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20811 (match_operand:<bnd_ptr> 2 "register_operand")]))]
20812 UNSPEC_BNDLDX))
20813 (use (mem:BLK (match_dup 1)))])]
20814 "TARGET_MPX"
20815 {
20816 /* Avoid registers which cannot be used as index. */
20817 if (!index_register_operand (operands[2], Pmode))
20818 operands[2] = copy_addr_to_reg (operands[2]);
20819
20820 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20821 operands[2]),
20822 UNSPEC_BNDLDX_ADDR);
20823 })
20824
20825 (define_insn "*<mode>_ldx"
20826 [(set (match_operand:BND 0 "register_operand" "=w")
20827 (unspec:BND
20828 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20829 [(unspec:<bnd_ptr>
20830 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20831 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20832 UNSPEC_BNDLDX_ADDR)])]
20833 UNSPEC_BNDLDX))
20834 (use (mem:BLK (match_dup 1)))]
20835 "TARGET_MPX"
20836 "bndldx\t{%3, %0|%0, %3}"
20837 [(set_attr "type" "mpxld")])
20838
20839 (define_expand "<mode>_stx"
20840 [(parallel
20841 [(unspec
20842 [(mem:<bnd_ptr>
20843 (match_par_dup 3
20844 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20845 (match_operand:<bnd_ptr> 1 "register_operand")]))
20846 (match_operand:BND 2 "register_operand")]
20847 UNSPEC_BNDSTX)
20848 (set (match_dup 4)
20849 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20850 "TARGET_MPX"
20851 {
20852 /* Avoid registers which cannot be used as index. */
20853 if (!index_register_operand (operands[1], Pmode))
20854 operands[1] = copy_addr_to_reg (operands[1]);
20855
20856 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20857 operands[1]),
20858 UNSPEC_BNDLDX_ADDR);
20859 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20860 MEM_VOLATILE_P (operands[4]) = 1;
20861 })
20862
20863 (define_insn "*<mode>_stx"
20864 [(unspec
20865 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20866 [(unspec:<bnd_ptr>
20867 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20868 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20869 UNSPEC_BNDLDX_ADDR)])
20870 (match_operand:BND 2 "register_operand" "w")]
20871 UNSPEC_BNDSTX)
20872 (set (match_operand:BLK 4 "bnd_mem_operator")
20873 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20874 "TARGET_MPX"
20875 "bndstx\t{%2, %3|%3, %2}"
20876 [(set_attr "type" "mpxst")])
20877
20878 (define_insn "move_size_reloc_<mode>"
20879 [(set (match_operand:SWI48 0 "register_operand" "=r")
20880 (unspec:SWI48
20881 [(match_operand:SWI48 1 "symbol_operand")]
20882 UNSPEC_SIZEOF))]
20883 "TARGET_MPX"
20884 {
20885 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20886 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20887 else
20888 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20889 }
20890 [(set_attr "type" "imov")
20891 (set_attr "mode" "<MODE>")])
20892
20893 ;; RDPKRU and WRPKRU
20894
20895 (define_expand "rdpkru"
20896 [(parallel
20897 [(set (match_operand:SI 0 "register_operand")
20898 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20899 (set (match_dup 2) (const_int 0))])]
20900 "TARGET_PKU"
20901 {
20902 operands[1] = force_reg (SImode, const0_rtx);
20903 operands[2] = gen_reg_rtx (SImode);
20904 })
20905
20906 (define_insn "*rdpkru"
20907 [(set (match_operand:SI 0 "register_operand" "=a")
20908 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20909 UNSPECV_PKU))
20910 (set (match_operand:SI 1 "register_operand" "=d")
20911 (const_int 0))]
20912 "TARGET_PKU"
20913 "rdpkru"
20914 [(set_attr "type" "other")])
20915
20916 (define_expand "wrpkru"
20917 [(unspec_volatile:SI
20918 [(match_operand:SI 0 "register_operand")
20919 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20920 "TARGET_PKU"
20921 {
20922 operands[1] = force_reg (SImode, const0_rtx);
20923 operands[2] = force_reg (SImode, const0_rtx);
20924 })
20925
20926 (define_insn "*wrpkru"
20927 [(unspec_volatile:SI
20928 [(match_operand:SI 0 "register_operand" "a")
20929 (match_operand:SI 1 "register_operand" "d")
20930 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20931 "TARGET_PKU"
20932 "wrpkru"
20933 [(set_attr "type" "other")])
20934
20935 (define_insn "rdpid"
20936 [(set (match_operand:SI 0 "register_operand" "=r")
20937 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20938 "!TARGET_64BIT && TARGET_RDPID"
20939 "rdpid\t%0"
20940 [(set_attr "type" "other")])
20941
20942 (define_insn "rdpid_rex64"
20943 [(set (match_operand:DI 0 "register_operand" "=r")
20944 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20945 "TARGET_64BIT && TARGET_RDPID"
20946 "rdpid\t%0"
20947 [(set_attr "type" "other")])
20948
20949 ;; Intirinsics for > i486
20950
20951 (define_insn "wbinvd"
20952 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20953 ""
20954 "wbinvd"
20955 [(set_attr "type" "other")])
20956
20957 (define_insn "wbnoinvd"
20958 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20959 "TARGET_WBNOINVD"
20960 "wbnoinvd"
20961 [(set_attr "type" "other")])
20962
20963 (define_insn "movdiri<mode>"
20964 [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m")
20965 (match_operand:SWI48 1 "register_operand" "r")]
20966 UNSPECV_MOVDIRI)]
20967 "TARGET_MOVDIRI"
20968 "movdiri\t{%1, %0|%0, %1}"
20969 [(set_attr "type" "other")])
20970
20971 (define_insn "movdir64b_<mode>"
20972 [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r")
20973 (match_operand:XI 1 "memory_operand")]
20974 UNSPECV_MOVDIR64B)]
20975 "TARGET_MOVDIR64B"
20976 "movdir64b\t{%1, %0|%0, %1}"
20977 [(set_attr "type" "other")])
20978
20979 (include "mmx.md")
20980 (include "sse.md")
20981 (include "sync.md")