]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
Add x86 pcommit instruction.
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
21 ;;
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24 ;;
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;; otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;; delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
67
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
70 UNSPEC_GOT
71 UNSPEC_GOTOFF
72 UNSPEC_GOTPCREL
73 UNSPEC_GOTTPOFF
74 UNSPEC_TPOFF
75 UNSPEC_NTPOFF
76 UNSPEC_DTPOFF
77 UNSPEC_GOTNTPOFF
78 UNSPEC_INDNTPOFF
79 UNSPEC_PLTOFF
80 UNSPEC_MACHOPIC_OFFSET
81 UNSPEC_PCREL
82 UNSPEC_SIZEOF
83
84 ;; Prologue support
85 UNSPEC_STACK_ALLOC
86 UNSPEC_SET_GOT
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_PAUSE
112 UNSPEC_LEA_ADDR
113 UNSPEC_XBEGIN_ABORT
114 UNSPEC_STOS
115 UNSPEC_PEEPSIB
116 UNSPEC_INSN_FALSE_DEP
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 UNSPEC_SP_TLS_SET
170 UNSPEC_SP_TLS_TEST
171
172 ;; For ROUND support
173 UNSPEC_ROUND
174
175 ;; For CRC32 support
176 UNSPEC_CRC32
177
178 ;; For BMI support
179 UNSPEC_BEXTR
180
181 ;; For BMI2 support
182 UNSPEC_PDEP
183 UNSPEC_PEXT
184
185 ;; For AVX512F support
186 UNSPEC_KMOV
187
188 UNSPEC_BNDMK
189 UNSPEC_BNDMK_ADDR
190 UNSPEC_BNDSTX
191 UNSPEC_BNDLDX
192 UNSPEC_BNDLDX_ADDR
193 UNSPEC_BNDCL
194 UNSPEC_BNDCU
195 UNSPEC_BNDCN
196 UNSPEC_MPX_FENCE
197 ])
198
199 (define_c_enum "unspecv" [
200 UNSPECV_BLOCKAGE
201 UNSPECV_STACK_PROBE
202 UNSPECV_PROBE_STACK_RANGE
203 UNSPECV_ALIGN
204 UNSPECV_PROLOGUE_USE
205 UNSPECV_SPLIT_STACK_RETURN
206 UNSPECV_CLD
207 UNSPECV_NOPS
208 UNSPECV_RDTSC
209 UNSPECV_RDTSCP
210 UNSPECV_RDPMC
211 UNSPECV_LLWP_INTRINSIC
212 UNSPECV_SLWP_INTRINSIC
213 UNSPECV_LWPVAL_INTRINSIC
214 UNSPECV_LWPINS_INTRINSIC
215 UNSPECV_RDFSBASE
216 UNSPECV_RDGSBASE
217 UNSPECV_WRFSBASE
218 UNSPECV_WRGSBASE
219 UNSPECV_FXSAVE
220 UNSPECV_FXRSTOR
221 UNSPECV_FXSAVE64
222 UNSPECV_FXRSTOR64
223 UNSPECV_XSAVE
224 UNSPECV_XRSTOR
225 UNSPECV_XSAVE64
226 UNSPECV_XRSTOR64
227 UNSPECV_XSAVEOPT
228 UNSPECV_XSAVEOPT64
229 UNSPECV_XSAVES
230 UNSPECV_XRSTORS
231 UNSPECV_XSAVES64
232 UNSPECV_XRSTORS64
233 UNSPECV_XSAVEC
234 UNSPECV_XSAVEC64
235
236 ;; For atomic compound assignments.
237 UNSPECV_FNSTENV
238 UNSPECV_FLDENV
239 UNSPECV_FNSTSW
240 UNSPECV_FNCLEX
241
242 ;; For RDRAND support
243 UNSPECV_RDRAND
244
245 ;; For RDSEED support
246 UNSPECV_RDSEED
247
248 ;; For RTM support
249 UNSPECV_XBEGIN
250 UNSPECV_XEND
251 UNSPECV_XABORT
252 UNSPECV_XTEST
253
254 UNSPECV_NLGR
255
256 ;; For CLWB support
257 UNSPECV_CLWB
258
259 ;; For PCOMMIT support
260 UNSPECV_PCOMMIT
261
262 ;; For CLFLUSHOPT support
263 UNSPECV_CLFLUSHOPT
264 ])
265
266 ;; Constants to represent rounding modes in the ROUND instruction
267 (define_constants
268 [(ROUND_FLOOR 0x1)
269 (ROUND_CEIL 0x2)
270 (ROUND_TRUNC 0x3)
271 (ROUND_MXCSR 0x4)
272 (ROUND_NO_EXC 0x8)
273 ])
274
275 ;; Constants to represent AVX512F embeded rounding
276 (define_constants
277 [(ROUND_NEAREST_INT 0)
278 (ROUND_NEG_INF 1)
279 (ROUND_POS_INF 2)
280 (ROUND_ZERO 3)
281 (NO_ROUND 4)
282 (ROUND_SAE 8)
283 ])
284
285 ;; Constants to represent pcomtrue/pcomfalse variants
286 (define_constants
287 [(PCOM_FALSE 0)
288 (PCOM_TRUE 1)
289 (COM_FALSE_S 2)
290 (COM_FALSE_P 3)
291 (COM_TRUE_S 4)
292 (COM_TRUE_P 5)
293 ])
294
295 ;; Constants used in the XOP pperm instruction
296 (define_constants
297 [(PPERM_SRC 0x00) /* copy source */
298 (PPERM_INVERT 0x20) /* invert source */
299 (PPERM_REVERSE 0x40) /* bit reverse source */
300 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
301 (PPERM_ZERO 0x80) /* all 0's */
302 (PPERM_ONES 0xa0) /* all 1's */
303 (PPERM_SIGN 0xc0) /* propagate sign bit */
304 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
305 (PPERM_SRC1 0x00) /* use first source byte */
306 (PPERM_SRC2 0x10) /* use second source byte */
307 ])
308
309 ;; Registers by name.
310 (define_constants
311 [(AX_REG 0)
312 (DX_REG 1)
313 (CX_REG 2)
314 (BX_REG 3)
315 (SI_REG 4)
316 (DI_REG 5)
317 (BP_REG 6)
318 (SP_REG 7)
319 (ST0_REG 8)
320 (ST1_REG 9)
321 (ST2_REG 10)
322 (ST3_REG 11)
323 (ST4_REG 12)
324 (ST5_REG 13)
325 (ST6_REG 14)
326 (ST7_REG 15)
327 (FLAGS_REG 17)
328 (FPSR_REG 18)
329 (FPCR_REG 19)
330 (XMM0_REG 21)
331 (XMM1_REG 22)
332 (XMM2_REG 23)
333 (XMM3_REG 24)
334 (XMM4_REG 25)
335 (XMM5_REG 26)
336 (XMM6_REG 27)
337 (XMM7_REG 28)
338 (MM0_REG 29)
339 (MM1_REG 30)
340 (MM2_REG 31)
341 (MM3_REG 32)
342 (MM4_REG 33)
343 (MM5_REG 34)
344 (MM6_REG 35)
345 (MM7_REG 36)
346 (R8_REG 37)
347 (R9_REG 38)
348 (R10_REG 39)
349 (R11_REG 40)
350 (R12_REG 41)
351 (R13_REG 42)
352 (R14_REG 43)
353 (R15_REG 44)
354 (XMM8_REG 45)
355 (XMM9_REG 46)
356 (XMM10_REG 47)
357 (XMM11_REG 48)
358 (XMM12_REG 49)
359 (XMM13_REG 50)
360 (XMM14_REG 51)
361 (XMM15_REG 52)
362 (XMM16_REG 53)
363 (XMM17_REG 54)
364 (XMM18_REG 55)
365 (XMM19_REG 56)
366 (XMM20_REG 57)
367 (XMM21_REG 58)
368 (XMM22_REG 59)
369 (XMM23_REG 60)
370 (XMM24_REG 61)
371 (XMM25_REG 62)
372 (XMM26_REG 63)
373 (XMM27_REG 64)
374 (XMM28_REG 65)
375 (XMM29_REG 66)
376 (XMM30_REG 67)
377 (XMM31_REG 68)
378 (MASK0_REG 69)
379 (MASK1_REG 70)
380 (MASK2_REG 71)
381 (MASK3_REG 72)
382 (MASK4_REG 73)
383 (MASK5_REG 74)
384 (MASK6_REG 75)
385 (MASK7_REG 76)
386 (BND0_REG 77)
387 (BND1_REG 78)
388 ])
389
390 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
391 ;; from i386.c.
392
393 ;; In C guard expressions, put expressions which may be compile-time
394 ;; constants first. This allows for better optimization. For
395 ;; example, write "TARGET_64BIT && reload_completed", not
396 ;; "reload_completed && TARGET_64BIT".
397
398 \f
399 ;; Processor type.
400 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
401 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
402 btver2"
403 (const (symbol_ref "ix86_schedule")))
404
405 ;; A basic instruction type. Refinements due to arguments to be
406 ;; provided in other attributes.
407 (define_attr "type"
408 "other,multi,
409 alu,alu1,negnot,imov,imovx,lea,
410 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
411 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
412 push,pop,call,callv,leave,
413 str,bitmanip,
414 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
415 fxch,fistp,fisttp,frndint,
416 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
417 ssemul,sseimul,ssediv,sselog,sselog1,
418 sseishft,sseishft1,ssecmp,ssecomi,
419 ssecvt,ssecvt1,sseicvt,sseins,
420 sseshuf,sseshuf1,ssemuladd,sse4arg,
421 lwp,mskmov,msklog,
422 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
423 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
424 (const_string "other"))
425
426 ;; Main data type used by the insn
427 (define_attr "mode"
428 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
429 V2DF,V2SF,V1DF,V8DF"
430 (const_string "unknown"))
431
432 ;; The CPU unit operations uses.
433 (define_attr "unit" "integer,i387,sse,mmx,unknown"
434 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
435 fxch,fistp,fisttp,frndint")
436 (const_string "i387")
437 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
438 ssemul,sseimul,ssediv,sselog,sselog1,
439 sseishft,sseishft1,ssecmp,ssecomi,
440 ssecvt,ssecvt1,sseicvt,sseins,
441 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
442 (const_string "sse")
443 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
444 (const_string "mmx")
445 (eq_attr "type" "other")
446 (const_string "unknown")]
447 (const_string "integer")))
448
449 ;; The minimum required alignment of vector mode memory operands of the SSE
450 ;; (non-VEX/EVEX) instruction in bits, if it is different from
451 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
452 ;; multiple alternatives, this should be conservative maximum of those minimum
453 ;; required alignments.
454 (define_attr "ssememalign" "" (const_int 0))
455
456 ;; The (bounding maximum) length of an instruction immediate.
457 (define_attr "length_immediate" ""
458 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
459 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
460 mpxld,mpxst")
461 (const_int 0)
462 (eq_attr "unit" "i387,sse,mmx")
463 (const_int 0)
464 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
465 rotate,rotatex,rotate1,imul,icmp,push,pop")
466 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
467 (eq_attr "type" "imov,test")
468 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
469 (eq_attr "type" "call")
470 (if_then_else (match_operand 0 "constant_call_address_operand")
471 (const_int 4)
472 (const_int 0))
473 (eq_attr "type" "callv")
474 (if_then_else (match_operand 1 "constant_call_address_operand")
475 (const_int 4)
476 (const_int 0))
477 ;; We don't know the size before shorten_branches. Expect
478 ;; the instruction to fit for better scheduling.
479 (eq_attr "type" "ibr")
480 (const_int 1)
481 ]
482 (symbol_ref "/* Update immediate_length and other attributes! */
483 gcc_unreachable (),1")))
484
485 ;; The (bounding maximum) length of an instruction address.
486 (define_attr "length_address" ""
487 (cond [(eq_attr "type" "str,other,multi,fxch")
488 (const_int 0)
489 (and (eq_attr "type" "call")
490 (match_operand 0 "constant_call_address_operand"))
491 (const_int 0)
492 (and (eq_attr "type" "callv")
493 (match_operand 1 "constant_call_address_operand"))
494 (const_int 0)
495 ]
496 (symbol_ref "ix86_attr_length_address_default (insn)")))
497
498 ;; Set when length prefix is used.
499 (define_attr "prefix_data16" ""
500 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
501 (const_int 0)
502 (eq_attr "mode" "HI")
503 (const_int 1)
504 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
505 (const_int 1)
506 ]
507 (const_int 0)))
508
509 ;; Set when string REP prefix is used.
510 (define_attr "prefix_rep" ""
511 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
512 (const_int 0)
513 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
514 (const_int 1)
515 (and (eq_attr "type" "ibr,call,callv")
516 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
517 (const_int 1)
518 ]
519 (const_int 0)))
520
521 ;; Set when 0f opcode prefix is used.
522 (define_attr "prefix_0f" ""
523 (if_then_else
524 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
525 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
526 (eq_attr "unit" "sse,mmx"))
527 (const_int 1)
528 (const_int 0)))
529
530 ;; Set when REX opcode prefix is used.
531 (define_attr "prefix_rex" ""
532 (cond [(not (match_test "TARGET_64BIT"))
533 (const_int 0)
534 (and (eq_attr "mode" "DI")
535 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
536 (eq_attr "unit" "!mmx")))
537 (const_int 1)
538 (and (eq_attr "mode" "QI")
539 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
540 (const_int 1)
541 (match_test "x86_extended_reg_mentioned_p (insn)")
542 (const_int 1)
543 (and (eq_attr "type" "imovx")
544 (match_operand:QI 1 "ext_QIreg_operand"))
545 (const_int 1)
546 ]
547 (const_int 0)))
548
549 ;; There are also additional prefixes in 3DNOW, SSSE3.
550 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
551 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
552 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
553 (define_attr "prefix_extra" ""
554 (cond [(eq_attr "type" "ssemuladd,sse4arg")
555 (const_int 2)
556 (eq_attr "type" "sseiadd1,ssecvt1")
557 (const_int 1)
558 ]
559 (const_int 0)))
560
561 ;; Prefix used: original, VEX or maybe VEX.
562 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
563 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
564 (const_string "vex")
565 (eq_attr "mode" "XI,V16SF,V8DF")
566 (const_string "evex")
567 ]
568 (const_string "orig")))
569
570 ;; VEX W bit is used.
571 (define_attr "prefix_vex_w" "" (const_int 0))
572
573 ;; The length of VEX prefix
574 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
575 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
576 ;; still prefix_0f 1, with prefix_extra 1.
577 (define_attr "length_vex" ""
578 (if_then_else (and (eq_attr "prefix_0f" "1")
579 (eq_attr "prefix_extra" "0"))
580 (if_then_else (eq_attr "prefix_vex_w" "1")
581 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
582 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
583 (if_then_else (eq_attr "prefix_vex_w" "1")
584 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
585 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
586
587 ;; 4-bytes evex prefix and 1 byte opcode.
588 (define_attr "length_evex" "" (const_int 5))
589
590 ;; Set when modrm byte is used.
591 (define_attr "modrm" ""
592 (cond [(eq_attr "type" "str,leave")
593 (const_int 0)
594 (eq_attr "unit" "i387")
595 (const_int 0)
596 (and (eq_attr "type" "incdec")
597 (and (not (match_test "TARGET_64BIT"))
598 (ior (match_operand:SI 1 "register_operand")
599 (match_operand:HI 1 "register_operand"))))
600 (const_int 0)
601 (and (eq_attr "type" "push")
602 (not (match_operand 1 "memory_operand")))
603 (const_int 0)
604 (and (eq_attr "type" "pop")
605 (not (match_operand 0 "memory_operand")))
606 (const_int 0)
607 (and (eq_attr "type" "imov")
608 (and (not (eq_attr "mode" "DI"))
609 (ior (and (match_operand 0 "register_operand")
610 (match_operand 1 "immediate_operand"))
611 (ior (and (match_operand 0 "ax_reg_operand")
612 (match_operand 1 "memory_displacement_only_operand"))
613 (and (match_operand 0 "memory_displacement_only_operand")
614 (match_operand 1 "ax_reg_operand"))))))
615 (const_int 0)
616 (and (eq_attr "type" "call")
617 (match_operand 0 "constant_call_address_operand"))
618 (const_int 0)
619 (and (eq_attr "type" "callv")
620 (match_operand 1 "constant_call_address_operand"))
621 (const_int 0)
622 (and (eq_attr "type" "alu,alu1,icmp,test")
623 (match_operand 0 "ax_reg_operand"))
624 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
625 ]
626 (const_int 1)))
627
628 ;; When this attribute is set, calculate total insn length from
629 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
630 (define_attr "length_nobnd" "" (const_int 0))
631
632 ;; The (bounding maximum) length of an instruction in bytes.
633 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
634 ;; Later we may want to split them and compute proper length as for
635 ;; other insns.
636 (define_attr "length" ""
637 (cond [(eq_attr "length_nobnd" "!0")
638 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
639 (attr "length_nobnd"))
640 (eq_attr "type" "other,multi,fistp,frndint")
641 (const_int 16)
642 (eq_attr "type" "fcmp")
643 (const_int 4)
644 (eq_attr "unit" "i387")
645 (plus (const_int 2)
646 (plus (attr "prefix_data16")
647 (attr "length_address")))
648 (ior (eq_attr "prefix" "evex")
649 (and (ior (eq_attr "prefix" "maybe_evex")
650 (eq_attr "prefix" "maybe_vex"))
651 (match_test "TARGET_AVX512F")))
652 (plus (attr "length_evex")
653 (plus (attr "length_immediate")
654 (plus (attr "modrm")
655 (attr "length_address"))))
656 (ior (eq_attr "prefix" "vex")
657 (and (ior (eq_attr "prefix" "maybe_vex")
658 (eq_attr "prefix" "maybe_evex"))
659 (match_test "TARGET_AVX")))
660 (plus (attr "length_vex")
661 (plus (attr "length_immediate")
662 (plus (attr "modrm")
663 (attr "length_address"))))]
664 (plus (plus (attr "modrm")
665 (plus (attr "prefix_0f")
666 (plus (attr "prefix_rex")
667 (plus (attr "prefix_extra")
668 (const_int 1)))))
669 (plus (attr "prefix_rep")
670 (plus (attr "prefix_data16")
671 (plus (attr "length_immediate")
672 (attr "length_address")))))))
673
674 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
675 ;; `store' if there is a simple memory reference therein, or `unknown'
676 ;; if the instruction is complex.
677
678 (define_attr "memory" "none,load,store,both,unknown"
679 (cond [(eq_attr "type" "other,multi,str,lwp")
680 (const_string "unknown")
681 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
682 (const_string "none")
683 (eq_attr "type" "fistp,leave")
684 (const_string "both")
685 (eq_attr "type" "frndint")
686 (const_string "load")
687 (eq_attr "type" "mpxld")
688 (const_string "load")
689 (eq_attr "type" "mpxst")
690 (const_string "store")
691 (eq_attr "type" "push")
692 (if_then_else (match_operand 1 "memory_operand")
693 (const_string "both")
694 (const_string "store"))
695 (eq_attr "type" "pop")
696 (if_then_else (match_operand 0 "memory_operand")
697 (const_string "both")
698 (const_string "load"))
699 (eq_attr "type" "setcc")
700 (if_then_else (match_operand 0 "memory_operand")
701 (const_string "store")
702 (const_string "none"))
703 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
704 (if_then_else (ior (match_operand 0 "memory_operand")
705 (match_operand 1 "memory_operand"))
706 (const_string "load")
707 (const_string "none"))
708 (eq_attr "type" "ibr")
709 (if_then_else (match_operand 0 "memory_operand")
710 (const_string "load")
711 (const_string "none"))
712 (eq_attr "type" "call")
713 (if_then_else (match_operand 0 "constant_call_address_operand")
714 (const_string "none")
715 (const_string "load"))
716 (eq_attr "type" "callv")
717 (if_then_else (match_operand 1 "constant_call_address_operand")
718 (const_string "none")
719 (const_string "load"))
720 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
721 (match_operand 1 "memory_operand"))
722 (const_string "both")
723 (and (match_operand 0 "memory_operand")
724 (match_operand 1 "memory_operand"))
725 (const_string "both")
726 (match_operand 0 "memory_operand")
727 (const_string "store")
728 (match_operand 1 "memory_operand")
729 (const_string "load")
730 (and (eq_attr "type"
731 "!alu1,negnot,ishift1,
732 imov,imovx,icmp,test,bitmanip,
733 fmov,fcmp,fsgn,
734 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
735 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
736 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
737 (match_operand 2 "memory_operand"))
738 (const_string "load")
739 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
740 (match_operand 3 "memory_operand"))
741 (const_string "load")
742 ]
743 (const_string "none")))
744
745 ;; Indicates if an instruction has both an immediate and a displacement.
746
747 (define_attr "imm_disp" "false,true,unknown"
748 (cond [(eq_attr "type" "other,multi")
749 (const_string "unknown")
750 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
751 (and (match_operand 0 "memory_displacement_operand")
752 (match_operand 1 "immediate_operand")))
753 (const_string "true")
754 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
755 (and (match_operand 0 "memory_displacement_operand")
756 (match_operand 2 "immediate_operand")))
757 (const_string "true")
758 ]
759 (const_string "false")))
760
761 ;; Indicates if an FP operation has an integer source.
762
763 (define_attr "fp_int_src" "false,true"
764 (const_string "false"))
765
766 ;; Defines rounding mode of an FP operation.
767
768 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
769 (const_string "any"))
770
771 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
772 (define_attr "use_carry" "0,1" (const_string "0"))
773
774 ;; Define attribute to indicate unaligned ssemov insns
775 (define_attr "movu" "0,1" (const_string "0"))
776
777 ;; Used to control the "enabled" attribute on a per-instruction basis.
778 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
779 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
780 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
781 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
782 (const_string "base"))
783
784 (define_attr "enabled" ""
785 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
786 (eq_attr "isa" "x64_sse4")
787 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
788 (eq_attr "isa" "x64_sse4_noavx")
789 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
790 (eq_attr "isa" "x64_avx")
791 (symbol_ref "TARGET_64BIT && TARGET_AVX")
792 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
793 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
794 (eq_attr "isa" "sse2_noavx")
795 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
796 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
797 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
798 (eq_attr "isa" "sse4_noavx")
799 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
800 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
801 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
802 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
803 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
804 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
805 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
806 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
807 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
808 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
809 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
810 (eq_attr "isa" "fma_avx512f")
811 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
812 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
813 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
814 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
815 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
816 ]
817 (const_int 1)))
818
819 (define_attr "preferred_for_speed" "" (const_int 1))
820
821 ;; Describe a user's asm statement.
822 (define_asm_attributes
823 [(set_attr "length" "128")
824 (set_attr "type" "multi")])
825
826 (define_code_iterator plusminus [plus minus])
827
828 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
829
830 (define_code_iterator multdiv [mult div])
831
832 ;; Base name for define_insn
833 (define_code_attr plusminus_insn
834 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
835 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
836
837 ;; Base name for insn mnemonic.
838 (define_code_attr plusminus_mnemonic
839 [(plus "add") (ss_plus "adds") (us_plus "addus")
840 (minus "sub") (ss_minus "subs") (us_minus "subus")])
841 (define_code_attr plusminus_carry_mnemonic
842 [(plus "adc") (minus "sbb")])
843 (define_code_attr multdiv_mnemonic
844 [(mult "mul") (div "div")])
845
846 ;; Mark commutative operators as such in constraints.
847 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
848 (minus "") (ss_minus "") (us_minus "")])
849
850 ;; Mapping of max and min
851 (define_code_iterator maxmin [smax smin umax umin])
852
853 ;; Mapping of signed max and min
854 (define_code_iterator smaxmin [smax smin])
855
856 ;; Mapping of unsigned max and min
857 (define_code_iterator umaxmin [umax umin])
858
859 ;; Base name for integer and FP insn mnemonic
860 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
861 (umax "maxu") (umin "minu")])
862 (define_code_attr maxmin_float [(smax "max") (smin "min")])
863
864 ;; Mapping of logic operators
865 (define_code_iterator any_logic [and ior xor])
866 (define_code_iterator any_or [ior xor])
867 (define_code_iterator fpint_logic [and xor])
868
869 ;; Base name for insn mnemonic.
870 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
871
872 ;; Mapping of logic-shift operators
873 (define_code_iterator any_lshift [ashift lshiftrt])
874
875 ;; Mapping of shift-right operators
876 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
877
878 ;; Mapping of all shift operators
879 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
880
881 ;; Base name for define_insn
882 (define_code_attr shift_insn
883 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
884
885 ;; Base name for insn mnemonic.
886 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
887 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
888
889 ;; Mapping of rotate operators
890 (define_code_iterator any_rotate [rotate rotatert])
891
892 ;; Base name for define_insn
893 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
894
895 ;; Base name for insn mnemonic.
896 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
897
898 ;; Mapping of abs neg operators
899 (define_code_iterator absneg [abs neg])
900
901 ;; Base name for x87 insn mnemonic.
902 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
903
904 ;; Used in signed and unsigned widening multiplications.
905 (define_code_iterator any_extend [sign_extend zero_extend])
906
907 ;; Prefix for insn menmonic.
908 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
909
910 ;; Prefix for define_insn
911 (define_code_attr u [(sign_extend "") (zero_extend "u")])
912 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
913 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
914
915 ;; Used in signed and unsigned truncations.
916 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
917 ;; Instruction suffix for truncations.
918 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
919
920 ;; Used in signed and unsigned fix.
921 (define_code_iterator any_fix [fix unsigned_fix])
922 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
923
924 ;; Used in signed and unsigned float.
925 (define_code_iterator any_float [float unsigned_float])
926 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
927
928 ;; All integer modes.
929 (define_mode_iterator SWI1248x [QI HI SI DI])
930
931 ;; All integer modes with AVX512BW.
932 (define_mode_iterator SWI1248_AVX512BW
933 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
934
935 ;; All integer modes without QImode.
936 (define_mode_iterator SWI248x [HI SI DI])
937
938 ;; All integer modes without QImode and HImode.
939 (define_mode_iterator SWI48x [SI DI])
940
941 ;; All integer modes without SImode and DImode.
942 (define_mode_iterator SWI12 [QI HI])
943
944 ;; All integer modes without DImode.
945 (define_mode_iterator SWI124 [QI HI SI])
946
947 ;; All integer modes without QImode and DImode.
948 (define_mode_iterator SWI24 [HI SI])
949
950 ;; Single word integer modes.
951 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
952
953 ;; Single word integer modes without QImode.
954 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
955
956 ;; Single word integer modes without QImode and HImode.
957 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
958
959 ;; All math-dependant single and double word integer modes.
960 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
961 (HI "TARGET_HIMODE_MATH")
962 SI DI (TI "TARGET_64BIT")])
963
964 ;; Math-dependant single word integer modes.
965 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
966 (HI "TARGET_HIMODE_MATH")
967 SI (DI "TARGET_64BIT")])
968
969 ;; Math-dependant integer modes without DImode.
970 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
971 (HI "TARGET_HIMODE_MATH")
972 SI])
973
974 ;; Math-dependant single word integer modes without QImode.
975 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
976 SI (DI "TARGET_64BIT")])
977
978 ;; Double word integer modes.
979 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
980 (TI "TARGET_64BIT")])
981
982 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
983 ;; compile time constant, it is faster to use <MODE_SIZE> than
984 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
985 ;; command line options just use GET_MODE_SIZE macro.
986 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
987 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
988 (V16QI "16") (V32QI "32") (V64QI "64")
989 (V8HI "16") (V16HI "32") (V32HI "64")
990 (V4SI "16") (V8SI "32") (V16SI "64")
991 (V2DI "16") (V4DI "32") (V8DI "64")
992 (V1TI "16") (V2TI "32") (V4TI "64")
993 (V2DF "16") (V4DF "32") (V8DF "64")
994 (V4SF "16") (V8SF "32") (V16SF "64")])
995
996 ;; Double word integer modes as mode attribute.
997 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
998 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
999
1000 ;; Half mode for double word integer modes.
1001 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1002 (DI "TARGET_64BIT")])
1003
1004 ;; Bound modes.
1005 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1006 (BND64 "TARGET_LP64")])
1007
1008 ;; Pointer mode corresponding to bound mode.
1009 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1010
1011 ;; MPX check types
1012 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1013
1014 ;; Check name
1015 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1016 (UNSPEC_BNDCU "cu")
1017 (UNSPEC_BNDCN "cn")])
1018
1019 ;; Instruction suffix for integer modes.
1020 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1021
1022 ;; Instruction suffix for masks.
1023 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1024
1025 ;; Pointer size prefix for integer modes (Intel asm dialect)
1026 (define_mode_attr iptrsize [(QI "BYTE")
1027 (HI "WORD")
1028 (SI "DWORD")
1029 (DI "QWORD")])
1030
1031 ;; Register class for integer modes.
1032 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1033
1034 ;; Immediate operand constraint for integer modes.
1035 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1036
1037 ;; General operand constraint for word modes.
1038 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1039
1040 ;; Immediate operand constraint for double integer modes.
1041 (define_mode_attr di [(SI "nF") (DI "e")])
1042
1043 ;; Immediate operand constraint for shifts.
1044 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1045
1046 ;; General operand predicate for integer modes.
1047 (define_mode_attr general_operand
1048 [(QI "general_operand")
1049 (HI "general_operand")
1050 (SI "x86_64_general_operand")
1051 (DI "x86_64_general_operand")
1052 (TI "x86_64_general_operand")])
1053
1054 ;; General sign extend operand predicate for integer modes,
1055 ;; which disallows VOIDmode operands and thus it is suitable
1056 ;; for use inside sign_extend.
1057 (define_mode_attr general_sext_operand
1058 [(QI "sext_operand")
1059 (HI "sext_operand")
1060 (SI "x86_64_sext_operand")
1061 (DI "x86_64_sext_operand")])
1062
1063 ;; General sign/zero extend operand predicate for integer modes.
1064 (define_mode_attr general_szext_operand
1065 [(QI "general_operand")
1066 (HI "general_operand")
1067 (SI "x86_64_szext_general_operand")
1068 (DI "x86_64_szext_general_operand")])
1069
1070 ;; Immediate operand predicate for integer modes.
1071 (define_mode_attr immediate_operand
1072 [(QI "immediate_operand")
1073 (HI "immediate_operand")
1074 (SI "x86_64_immediate_operand")
1075 (DI "x86_64_immediate_operand")])
1076
1077 ;; Nonmemory operand predicate for integer modes.
1078 (define_mode_attr nonmemory_operand
1079 [(QI "nonmemory_operand")
1080 (HI "nonmemory_operand")
1081 (SI "x86_64_nonmemory_operand")
1082 (DI "x86_64_nonmemory_operand")])
1083
1084 ;; Operand predicate for shifts.
1085 (define_mode_attr shift_operand
1086 [(QI "nonimmediate_operand")
1087 (HI "nonimmediate_operand")
1088 (SI "nonimmediate_operand")
1089 (DI "shiftdi_operand")
1090 (TI "register_operand")])
1091
1092 ;; Operand predicate for shift argument.
1093 (define_mode_attr shift_immediate_operand
1094 [(QI "const_1_to_31_operand")
1095 (HI "const_1_to_31_operand")
1096 (SI "const_1_to_31_operand")
1097 (DI "const_1_to_63_operand")])
1098
1099 ;; Input operand predicate for arithmetic left shifts.
1100 (define_mode_attr ashl_input_operand
1101 [(QI "nonimmediate_operand")
1102 (HI "nonimmediate_operand")
1103 (SI "nonimmediate_operand")
1104 (DI "ashldi_input_operand")
1105 (TI "reg_or_pm1_operand")])
1106
1107 ;; SSE and x87 SFmode and DFmode floating point modes
1108 (define_mode_iterator MODEF [SF DF])
1109
1110 ;; All x87 floating point modes
1111 (define_mode_iterator X87MODEF [SF DF XF])
1112
1113 ;; SSE instruction suffix for various modes
1114 (define_mode_attr ssemodesuffix
1115 [(SF "ss") (DF "sd")
1116 (V16SF "ps") (V8DF "pd")
1117 (V8SF "ps") (V4DF "pd")
1118 (V4SF "ps") (V2DF "pd")
1119 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1120 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1121 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1122
1123 ;; SSE vector suffix for floating point modes
1124 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1125
1126 ;; SSE vector mode corresponding to a scalar mode
1127 (define_mode_attr ssevecmode
1128 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1129 (define_mode_attr ssevecmodelower
1130 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1131
1132 ;; Instruction suffix for REX 64bit operators.
1133 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1134
1135 ;; This mode iterator allows :P to be used for patterns that operate on
1136 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1137 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1138
1139 ;; This mode iterator allows :W to be used for patterns that operate on
1140 ;; word_mode sized quantities.
1141 (define_mode_iterator W
1142 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1143
1144 ;; This mode iterator allows :PTR to be used for patterns that operate on
1145 ;; ptr_mode sized quantities.
1146 (define_mode_iterator PTR
1147 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1148 \f
1149 ;; Scheduling descriptions
1150
1151 (include "pentium.md")
1152 (include "ppro.md")
1153 (include "k6.md")
1154 (include "athlon.md")
1155 (include "bdver1.md")
1156 (include "bdver3.md")
1157 (include "btver2.md")
1158 (include "geode.md")
1159 (include "atom.md")
1160 (include "slm.md")
1161 (include "core2.md")
1162
1163 \f
1164 ;; Operand and operator predicates and constraints
1165
1166 (include "predicates.md")
1167 (include "constraints.md")
1168
1169 \f
1170 ;; Compare and branch/compare and store instructions.
1171
1172 (define_expand "cbranch<mode>4"
1173 [(set (reg:CC FLAGS_REG)
1174 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1175 (match_operand:SDWIM 2 "<general_operand>")))
1176 (set (pc) (if_then_else
1177 (match_operator 0 "ordered_comparison_operator"
1178 [(reg:CC FLAGS_REG) (const_int 0)])
1179 (label_ref (match_operand 3))
1180 (pc)))]
1181 ""
1182 {
1183 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1184 operands[1] = force_reg (<MODE>mode, operands[1]);
1185 ix86_expand_branch (GET_CODE (operands[0]),
1186 operands[1], operands[2], operands[3]);
1187 DONE;
1188 })
1189
1190 (define_expand "cstore<mode>4"
1191 [(set (reg:CC FLAGS_REG)
1192 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1193 (match_operand:SWIM 3 "<general_operand>")))
1194 (set (match_operand:QI 0 "register_operand")
1195 (match_operator 1 "ordered_comparison_operator"
1196 [(reg:CC FLAGS_REG) (const_int 0)]))]
1197 ""
1198 {
1199 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1200 operands[2] = force_reg (<MODE>mode, operands[2]);
1201 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1202 operands[2], operands[3]);
1203 DONE;
1204 })
1205
1206 (define_expand "cmp<mode>_1"
1207 [(set (reg:CC FLAGS_REG)
1208 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1209 (match_operand:SWI48 1 "<general_operand>")))])
1210
1211 (define_insn "*cmp<mode>_ccno_1"
1212 [(set (reg FLAGS_REG)
1213 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1214 (match_operand:SWI 1 "const0_operand")))]
1215 "ix86_match_ccmode (insn, CCNOmode)"
1216 "@
1217 test{<imodesuffix>}\t%0, %0
1218 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1219 [(set_attr "type" "test,icmp")
1220 (set_attr "length_immediate" "0,1")
1221 (set_attr "mode" "<MODE>")])
1222
1223 (define_insn "*cmp<mode>_1"
1224 [(set (reg FLAGS_REG)
1225 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1226 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1227 "ix86_match_ccmode (insn, CCmode)"
1228 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1229 [(set_attr "type" "icmp")
1230 (set_attr "mode" "<MODE>")])
1231
1232 (define_insn "*cmp<mode>_minus_1"
1233 [(set (reg FLAGS_REG)
1234 (compare
1235 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1236 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1237 (const_int 0)))]
1238 "ix86_match_ccmode (insn, CCGOCmode)"
1239 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1240 [(set_attr "type" "icmp")
1241 (set_attr "mode" "<MODE>")])
1242
1243 (define_insn "*cmpqi_ext_1"
1244 [(set (reg FLAGS_REG)
1245 (compare
1246 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1247 (subreg:QI
1248 (zero_extract:SI
1249 (match_operand 1 "ext_register_operand" "Q,Q")
1250 (const_int 8)
1251 (const_int 8)) 0)))]
1252 "ix86_match_ccmode (insn, CCmode)"
1253 "cmp{b}\t{%h1, %0|%0, %h1}"
1254 [(set_attr "isa" "*,nox64")
1255 (set_attr "type" "icmp")
1256 (set_attr "mode" "QI")])
1257
1258 (define_insn "*cmpqi_ext_2"
1259 [(set (reg FLAGS_REG)
1260 (compare
1261 (subreg:QI
1262 (zero_extract:SI
1263 (match_operand 0 "ext_register_operand" "Q")
1264 (const_int 8)
1265 (const_int 8)) 0)
1266 (match_operand:QI 1 "const0_operand")))]
1267 "ix86_match_ccmode (insn, CCNOmode)"
1268 "test{b}\t%h0, %h0"
1269 [(set_attr "type" "test")
1270 (set_attr "length_immediate" "0")
1271 (set_attr "mode" "QI")])
1272
1273 (define_expand "cmpqi_ext_3"
1274 [(set (reg:CC FLAGS_REG)
1275 (compare:CC
1276 (subreg:QI
1277 (zero_extract:SI
1278 (match_operand 0 "ext_register_operand")
1279 (const_int 8)
1280 (const_int 8)) 0)
1281 (match_operand:QI 1 "const_int_operand")))])
1282
1283 (define_insn "*cmpqi_ext_3"
1284 [(set (reg FLAGS_REG)
1285 (compare
1286 (subreg:QI
1287 (zero_extract:SI
1288 (match_operand 0 "ext_register_operand" "Q,Q")
1289 (const_int 8)
1290 (const_int 8)) 0)
1291 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1292 "ix86_match_ccmode (insn, CCmode)"
1293 "cmp{b}\t{%1, %h0|%h0, %1}"
1294 [(set_attr "isa" "*,nox64")
1295 (set_attr "type" "icmp")
1296 (set_attr "modrm" "1")
1297 (set_attr "mode" "QI")])
1298
1299 (define_insn "*cmpqi_ext_4"
1300 [(set (reg FLAGS_REG)
1301 (compare
1302 (subreg:QI
1303 (zero_extract:SI
1304 (match_operand 0 "ext_register_operand" "Q")
1305 (const_int 8)
1306 (const_int 8)) 0)
1307 (subreg:QI
1308 (zero_extract:SI
1309 (match_operand 1 "ext_register_operand" "Q")
1310 (const_int 8)
1311 (const_int 8)) 0)))]
1312 "ix86_match_ccmode (insn, CCmode)"
1313 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1314 [(set_attr "type" "icmp")
1315 (set_attr "mode" "QI")])
1316
1317 ;; These implement float point compares.
1318 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1319 ;; which would allow mix and match FP modes on the compares. Which is what
1320 ;; the old patterns did, but with many more of them.
1321
1322 (define_expand "cbranchxf4"
1323 [(set (reg:CC FLAGS_REG)
1324 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1325 (match_operand:XF 2 "nonmemory_operand")))
1326 (set (pc) (if_then_else
1327 (match_operator 0 "ix86_fp_comparison_operator"
1328 [(reg:CC FLAGS_REG)
1329 (const_int 0)])
1330 (label_ref (match_operand 3))
1331 (pc)))]
1332 "TARGET_80387"
1333 {
1334 ix86_expand_branch (GET_CODE (operands[0]),
1335 operands[1], operands[2], operands[3]);
1336 DONE;
1337 })
1338
1339 (define_expand "cstorexf4"
1340 [(set (reg:CC FLAGS_REG)
1341 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1342 (match_operand:XF 3 "nonmemory_operand")))
1343 (set (match_operand:QI 0 "register_operand")
1344 (match_operator 1 "ix86_fp_comparison_operator"
1345 [(reg:CC FLAGS_REG)
1346 (const_int 0)]))]
1347 "TARGET_80387"
1348 {
1349 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1350 operands[2], operands[3]);
1351 DONE;
1352 })
1353
1354 (define_expand "cbranch<mode>4"
1355 [(set (reg:CC FLAGS_REG)
1356 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1357 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1358 (set (pc) (if_then_else
1359 (match_operator 0 "ix86_fp_comparison_operator"
1360 [(reg:CC FLAGS_REG)
1361 (const_int 0)])
1362 (label_ref (match_operand 3))
1363 (pc)))]
1364 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1365 {
1366 ix86_expand_branch (GET_CODE (operands[0]),
1367 operands[1], operands[2], operands[3]);
1368 DONE;
1369 })
1370
1371 (define_expand "cstore<mode>4"
1372 [(set (reg:CC FLAGS_REG)
1373 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1374 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1375 (set (match_operand:QI 0 "register_operand")
1376 (match_operator 1 "ix86_fp_comparison_operator"
1377 [(reg:CC FLAGS_REG)
1378 (const_int 0)]))]
1379 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1380 {
1381 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1382 operands[2], operands[3]);
1383 DONE;
1384 })
1385
1386 (define_expand "cbranchcc4"
1387 [(set (pc) (if_then_else
1388 (match_operator 0 "comparison_operator"
1389 [(match_operand 1 "flags_reg_operand")
1390 (match_operand 2 "const0_operand")])
1391 (label_ref (match_operand 3))
1392 (pc)))]
1393 ""
1394 {
1395 ix86_expand_branch (GET_CODE (operands[0]),
1396 operands[1], operands[2], operands[3]);
1397 DONE;
1398 })
1399
1400 (define_expand "cstorecc4"
1401 [(set (match_operand:QI 0 "register_operand")
1402 (match_operator 1 "comparison_operator"
1403 [(match_operand 2 "flags_reg_operand")
1404 (match_operand 3 "const0_operand")]))]
1405 ""
1406 {
1407 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1408 operands[2], operands[3]);
1409 DONE;
1410 })
1411
1412
1413 ;; FP compares, step 1:
1414 ;; Set the FP condition codes.
1415 ;;
1416 ;; CCFPmode compare with exceptions
1417 ;; CCFPUmode compare with no exceptions
1418
1419 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1420 ;; used to manage the reg stack popping would not be preserved.
1421
1422 (define_insn "*cmp<mode>_0_i387"
1423 [(set (match_operand:HI 0 "register_operand" "=a")
1424 (unspec:HI
1425 [(compare:CCFP
1426 (match_operand:X87MODEF 1 "register_operand" "f")
1427 (match_operand:X87MODEF 2 "const0_operand"))]
1428 UNSPEC_FNSTSW))]
1429 "TARGET_80387"
1430 "* return output_fp_compare (insn, operands, false, false);"
1431 [(set_attr "type" "multi")
1432 (set_attr "unit" "i387")
1433 (set_attr "mode" "<MODE>")])
1434
1435 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1436 [(set (reg:CCFP FLAGS_REG)
1437 (compare:CCFP
1438 (match_operand:X87MODEF 1 "register_operand" "f")
1439 (match_operand:X87MODEF 2 "const0_operand")))
1440 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1441 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1442 "#"
1443 "&& reload_completed"
1444 [(set (match_dup 0)
1445 (unspec:HI
1446 [(compare:CCFP (match_dup 1)(match_dup 2))]
1447 UNSPEC_FNSTSW))
1448 (set (reg:CC FLAGS_REG)
1449 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1450 ""
1451 [(set_attr "type" "multi")
1452 (set_attr "unit" "i387")
1453 (set_attr "mode" "<MODE>")])
1454
1455 (define_insn "*cmpxf_i387"
1456 [(set (match_operand:HI 0 "register_operand" "=a")
1457 (unspec:HI
1458 [(compare:CCFP
1459 (match_operand:XF 1 "register_operand" "f")
1460 (match_operand:XF 2 "register_operand" "f"))]
1461 UNSPEC_FNSTSW))]
1462 "TARGET_80387"
1463 "* return output_fp_compare (insn, operands, false, false);"
1464 [(set_attr "type" "multi")
1465 (set_attr "unit" "i387")
1466 (set_attr "mode" "XF")])
1467
1468 (define_insn_and_split "*cmpxf_cc_i387"
1469 [(set (reg:CCFP FLAGS_REG)
1470 (compare:CCFP
1471 (match_operand:XF 1 "register_operand" "f")
1472 (match_operand:XF 2 "register_operand" "f")))
1473 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1474 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1475 "#"
1476 "&& reload_completed"
1477 [(set (match_dup 0)
1478 (unspec:HI
1479 [(compare:CCFP (match_dup 1)(match_dup 2))]
1480 UNSPEC_FNSTSW))
1481 (set (reg:CC FLAGS_REG)
1482 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1483 ""
1484 [(set_attr "type" "multi")
1485 (set_attr "unit" "i387")
1486 (set_attr "mode" "XF")])
1487
1488 (define_insn "*cmp<mode>_i387"
1489 [(set (match_operand:HI 0 "register_operand" "=a")
1490 (unspec:HI
1491 [(compare:CCFP
1492 (match_operand:MODEF 1 "register_operand" "f")
1493 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1494 UNSPEC_FNSTSW))]
1495 "TARGET_80387"
1496 "* return output_fp_compare (insn, operands, false, false);"
1497 [(set_attr "type" "multi")
1498 (set_attr "unit" "i387")
1499 (set_attr "mode" "<MODE>")])
1500
1501 (define_insn_and_split "*cmp<mode>_cc_i387"
1502 [(set (reg:CCFP FLAGS_REG)
1503 (compare:CCFP
1504 (match_operand:MODEF 1 "register_operand" "f")
1505 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1506 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1507 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1508 "#"
1509 "&& reload_completed"
1510 [(set (match_dup 0)
1511 (unspec:HI
1512 [(compare:CCFP (match_dup 1)(match_dup 2))]
1513 UNSPEC_FNSTSW))
1514 (set (reg:CC FLAGS_REG)
1515 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1516 ""
1517 [(set_attr "type" "multi")
1518 (set_attr "unit" "i387")
1519 (set_attr "mode" "<MODE>")])
1520
1521 (define_insn "*cmpu<mode>_i387"
1522 [(set (match_operand:HI 0 "register_operand" "=a")
1523 (unspec:HI
1524 [(compare:CCFPU
1525 (match_operand:X87MODEF 1 "register_operand" "f")
1526 (match_operand:X87MODEF 2 "register_operand" "f"))]
1527 UNSPEC_FNSTSW))]
1528 "TARGET_80387"
1529 "* return output_fp_compare (insn, operands, false, true);"
1530 [(set_attr "type" "multi")
1531 (set_attr "unit" "i387")
1532 (set_attr "mode" "<MODE>")])
1533
1534 (define_insn_and_split "*cmpu<mode>_cc_i387"
1535 [(set (reg:CCFPU FLAGS_REG)
1536 (compare:CCFPU
1537 (match_operand:X87MODEF 1 "register_operand" "f")
1538 (match_operand:X87MODEF 2 "register_operand" "f")))
1539 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1540 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1541 "#"
1542 "&& reload_completed"
1543 [(set (match_dup 0)
1544 (unspec:HI
1545 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1546 UNSPEC_FNSTSW))
1547 (set (reg:CC FLAGS_REG)
1548 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1549 ""
1550 [(set_attr "type" "multi")
1551 (set_attr "unit" "i387")
1552 (set_attr "mode" "<MODE>")])
1553
1554 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1555 [(set (match_operand:HI 0 "register_operand" "=a")
1556 (unspec:HI
1557 [(compare:CCFP
1558 (match_operand:X87MODEF 1 "register_operand" "f")
1559 (match_operator:X87MODEF 3 "float_operator"
1560 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1561 UNSPEC_FNSTSW))]
1562 "TARGET_80387
1563 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1564 || optimize_function_for_size_p (cfun))"
1565 "* return output_fp_compare (insn, operands, false, false);"
1566 [(set_attr "type" "multi")
1567 (set_attr "unit" "i387")
1568 (set_attr "fp_int_src" "true")
1569 (set_attr "mode" "<SWI24:MODE>")])
1570
1571 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1572 [(set (reg:CCFP FLAGS_REG)
1573 (compare:CCFP
1574 (match_operand:X87MODEF 1 "register_operand" "f")
1575 (match_operator:X87MODEF 3 "float_operator"
1576 [(match_operand:SWI24 2 "memory_operand" "m")])))
1577 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1578 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1579 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1580 || optimize_function_for_size_p (cfun))"
1581 "#"
1582 "&& reload_completed"
1583 [(set (match_dup 0)
1584 (unspec:HI
1585 [(compare:CCFP
1586 (match_dup 1)
1587 (match_op_dup 3 [(match_dup 2)]))]
1588 UNSPEC_FNSTSW))
1589 (set (reg:CC FLAGS_REG)
1590 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1591 ""
1592 [(set_attr "type" "multi")
1593 (set_attr "unit" "i387")
1594 (set_attr "fp_int_src" "true")
1595 (set_attr "mode" "<SWI24:MODE>")])
1596
1597 ;; FP compares, step 2
1598 ;; Move the fpsw to ax.
1599
1600 (define_insn "x86_fnstsw_1"
1601 [(set (match_operand:HI 0 "register_operand" "=a")
1602 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1603 "TARGET_80387"
1604 "fnstsw\t%0"
1605 [(set_attr "length" "2")
1606 (set_attr "mode" "SI")
1607 (set_attr "unit" "i387")])
1608
1609 ;; FP compares, step 3
1610 ;; Get ax into flags, general case.
1611
1612 (define_insn "x86_sahf_1"
1613 [(set (reg:CC FLAGS_REG)
1614 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1615 UNSPEC_SAHF))]
1616 "TARGET_SAHF"
1617 {
1618 #ifndef HAVE_AS_IX86_SAHF
1619 if (TARGET_64BIT)
1620 return ASM_BYTE "0x9e";
1621 else
1622 #endif
1623 return "sahf";
1624 }
1625 [(set_attr "length" "1")
1626 (set_attr "athlon_decode" "vector")
1627 (set_attr "amdfam10_decode" "direct")
1628 (set_attr "bdver1_decode" "direct")
1629 (set_attr "mode" "SI")])
1630
1631 ;; Pentium Pro can do steps 1 through 3 in one go.
1632 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1633 ;; (these i387 instructions set flags directly)
1634
1635 (define_mode_iterator FPCMP [CCFP CCFPU])
1636 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1637
1638 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1639 [(set (reg:FPCMP FLAGS_REG)
1640 (compare:FPCMP
1641 (match_operand:MODEF 0 "register_operand" "f,x")
1642 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1643 "TARGET_MIX_SSE_I387
1644 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1645 "* return output_fp_compare (insn, operands, true,
1646 <FPCMP:MODE>mode == CCFPUmode);"
1647 [(set_attr "type" "fcmp,ssecomi")
1648 (set_attr "prefix" "orig,maybe_vex")
1649 (set_attr "mode" "<MODEF:MODE>")
1650 (set (attr "prefix_rep")
1651 (if_then_else (eq_attr "type" "ssecomi")
1652 (const_string "0")
1653 (const_string "*")))
1654 (set (attr "prefix_data16")
1655 (cond [(eq_attr "type" "fcmp")
1656 (const_string "*")
1657 (eq_attr "mode" "DF")
1658 (const_string "1")
1659 ]
1660 (const_string "0")))
1661 (set_attr "athlon_decode" "vector")
1662 (set_attr "amdfam10_decode" "direct")
1663 (set_attr "bdver1_decode" "double")])
1664
1665 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1666 [(set (reg:FPCMP FLAGS_REG)
1667 (compare:FPCMP
1668 (match_operand:MODEF 0 "register_operand" "x")
1669 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1670 "TARGET_SSE_MATH
1671 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1672 "* return output_fp_compare (insn, operands, true,
1673 <FPCMP:MODE>mode == CCFPUmode);"
1674 [(set_attr "type" "ssecomi")
1675 (set_attr "prefix" "maybe_vex")
1676 (set_attr "mode" "<MODEF:MODE>")
1677 (set_attr "prefix_rep" "0")
1678 (set (attr "prefix_data16")
1679 (if_then_else (eq_attr "mode" "DF")
1680 (const_string "1")
1681 (const_string "0")))
1682 (set_attr "athlon_decode" "vector")
1683 (set_attr "amdfam10_decode" "direct")
1684 (set_attr "bdver1_decode" "double")])
1685
1686 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1687 [(set (reg:FPCMP FLAGS_REG)
1688 (compare:FPCMP
1689 (match_operand:X87MODEF 0 "register_operand" "f")
1690 (match_operand:X87MODEF 1 "register_operand" "f")))]
1691 "TARGET_80387 && TARGET_CMOVE
1692 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1693 "* return output_fp_compare (insn, operands, true,
1694 <FPCMP:MODE>mode == CCFPUmode);"
1695 [(set_attr "type" "fcmp")
1696 (set_attr "mode" "<X87MODEF:MODE>")
1697 (set_attr "athlon_decode" "vector")
1698 (set_attr "amdfam10_decode" "direct")
1699 (set_attr "bdver1_decode" "double")])
1700 \f
1701 ;; Push/pop instructions.
1702
1703 (define_insn "*push<mode>2"
1704 [(set (match_operand:DWI 0 "push_operand" "=<")
1705 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1706 ""
1707 "#"
1708 [(set_attr "type" "multi")
1709 (set_attr "mode" "<MODE>")])
1710
1711 (define_split
1712 [(set (match_operand:TI 0 "push_operand")
1713 (match_operand:TI 1 "general_operand"))]
1714 "TARGET_64BIT && reload_completed
1715 && !SSE_REG_P (operands[1])"
1716 [(const_int 0)]
1717 "ix86_split_long_move (operands); DONE;")
1718
1719 (define_insn "*pushdi2_rex64"
1720 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1721 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1722 "TARGET_64BIT"
1723 "@
1724 push{q}\t%1
1725 #"
1726 [(set_attr "type" "push,multi")
1727 (set_attr "mode" "DI")])
1728
1729 ;; Convert impossible pushes of immediate to existing instructions.
1730 ;; First try to get scratch register and go through it. In case this
1731 ;; fails, push sign extended lower part first and then overwrite
1732 ;; upper part by 32bit move.
1733 (define_peephole2
1734 [(match_scratch:DI 2 "r")
1735 (set (match_operand:DI 0 "push_operand")
1736 (match_operand:DI 1 "immediate_operand"))]
1737 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1738 && !x86_64_immediate_operand (operands[1], DImode)"
1739 [(set (match_dup 2) (match_dup 1))
1740 (set (match_dup 0) (match_dup 2))])
1741
1742 ;; We need to define this as both peepholer and splitter for case
1743 ;; peephole2 pass is not run.
1744 ;; "&& 1" is needed to keep it from matching the previous pattern.
1745 (define_peephole2
1746 [(set (match_operand:DI 0 "push_operand")
1747 (match_operand:DI 1 "immediate_operand"))]
1748 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1749 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1750 [(set (match_dup 0) (match_dup 1))
1751 (set (match_dup 2) (match_dup 3))]
1752 {
1753 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1754
1755 operands[1] = gen_lowpart (DImode, operands[2]);
1756 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1757 GEN_INT (4)));
1758 })
1759
1760 (define_split
1761 [(set (match_operand:DI 0 "push_operand")
1762 (match_operand:DI 1 "immediate_operand"))]
1763 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1764 ? epilogue_completed : reload_completed)
1765 && !symbolic_operand (operands[1], DImode)
1766 && !x86_64_immediate_operand (operands[1], DImode)"
1767 [(set (match_dup 0) (match_dup 1))
1768 (set (match_dup 2) (match_dup 3))]
1769 {
1770 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1771
1772 operands[1] = gen_lowpart (DImode, operands[2]);
1773 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1774 GEN_INT (4)));
1775 })
1776
1777 (define_split
1778 [(set (match_operand:DI 0 "push_operand")
1779 (match_operand:DI 1 "general_operand"))]
1780 "!TARGET_64BIT && reload_completed
1781 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1782 [(const_int 0)]
1783 "ix86_split_long_move (operands); DONE;")
1784
1785 (define_insn "*pushsi2"
1786 [(set (match_operand:SI 0 "push_operand" "=<")
1787 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1788 "!TARGET_64BIT"
1789 "push{l}\t%1"
1790 [(set_attr "type" "push")
1791 (set_attr "mode" "SI")])
1792
1793 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1794 ;; "push a byte/word". But actually we use pushl, which has the effect
1795 ;; of rounding the amount pushed up to a word.
1796
1797 ;; For TARGET_64BIT we always round up to 8 bytes.
1798 (define_insn "*push<mode>2_rex64"
1799 [(set (match_operand:SWI124 0 "push_operand" "=X")
1800 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1801 "TARGET_64BIT"
1802 "push{q}\t%q1"
1803 [(set_attr "type" "push")
1804 (set_attr "mode" "DI")])
1805
1806 (define_insn "*push<mode>2"
1807 [(set (match_operand:SWI12 0 "push_operand" "=X")
1808 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1809 "!TARGET_64BIT"
1810 "push{l}\t%k1"
1811 [(set_attr "type" "push")
1812 (set_attr "mode" "SI")])
1813
1814 (define_insn "*push<mode>2_prologue"
1815 [(set (match_operand:W 0 "push_operand" "=<")
1816 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1817 (clobber (mem:BLK (scratch)))]
1818 ""
1819 "push{<imodesuffix>}\t%1"
1820 [(set_attr "type" "push")
1821 (set_attr "mode" "<MODE>")])
1822
1823 (define_insn "*pop<mode>1"
1824 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1825 (match_operand:W 1 "pop_operand" ">"))]
1826 ""
1827 "pop{<imodesuffix>}\t%0"
1828 [(set_attr "type" "pop")
1829 (set_attr "mode" "<MODE>")])
1830
1831 (define_insn "*pop<mode>1_epilogue"
1832 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1833 (match_operand:W 1 "pop_operand" ">"))
1834 (clobber (mem:BLK (scratch)))]
1835 ""
1836 "pop{<imodesuffix>}\t%0"
1837 [(set_attr "type" "pop")
1838 (set_attr "mode" "<MODE>")])
1839
1840 (define_insn "*pushfl<mode>2"
1841 [(set (match_operand:W 0 "push_operand" "=<")
1842 (match_operand:W 1 "flags_reg_operand"))]
1843 ""
1844 "pushf{<imodesuffix>}"
1845 [(set_attr "type" "push")
1846 (set_attr "mode" "<MODE>")])
1847
1848 (define_insn "*popfl<mode>1"
1849 [(set (match_operand:W 0 "flags_reg_operand")
1850 (match_operand:W 1 "pop_operand" ">"))]
1851 ""
1852 "popf{<imodesuffix>}"
1853 [(set_attr "type" "pop")
1854 (set_attr "mode" "<MODE>")])
1855
1856 \f
1857 ;; Move instructions.
1858
1859 (define_expand "movxi"
1860 [(set (match_operand:XI 0 "nonimmediate_operand")
1861 (match_operand:XI 1 "general_operand"))]
1862 "TARGET_AVX512F"
1863 "ix86_expand_move (XImode, operands); DONE;")
1864
1865 ;; Reload patterns to support multi-word load/store
1866 ;; with non-offsetable address.
1867 (define_expand "reload_noff_store"
1868 [(parallel [(match_operand 0 "memory_operand" "=m")
1869 (match_operand 1 "register_operand" "r")
1870 (match_operand:DI 2 "register_operand" "=&r")])]
1871 "TARGET_64BIT"
1872 {
1873 rtx mem = operands[0];
1874 rtx addr = XEXP (mem, 0);
1875
1876 emit_move_insn (operands[2], addr);
1877 mem = replace_equiv_address_nv (mem, operands[2]);
1878
1879 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1880 DONE;
1881 })
1882
1883 (define_expand "reload_noff_load"
1884 [(parallel [(match_operand 0 "register_operand" "=r")
1885 (match_operand 1 "memory_operand" "m")
1886 (match_operand:DI 2 "register_operand" "=r")])]
1887 "TARGET_64BIT"
1888 {
1889 rtx mem = operands[1];
1890 rtx addr = XEXP (mem, 0);
1891
1892 emit_move_insn (operands[2], addr);
1893 mem = replace_equiv_address_nv (mem, operands[2]);
1894
1895 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1896 DONE;
1897 })
1898
1899 (define_expand "movoi"
1900 [(set (match_operand:OI 0 "nonimmediate_operand")
1901 (match_operand:OI 1 "general_operand"))]
1902 "TARGET_AVX"
1903 "ix86_expand_move (OImode, operands); DONE;")
1904
1905 (define_expand "movti"
1906 [(set (match_operand:TI 0 "nonimmediate_operand")
1907 (match_operand:TI 1 "nonimmediate_operand"))]
1908 "TARGET_64BIT || TARGET_SSE"
1909 {
1910 if (TARGET_64BIT)
1911 ix86_expand_move (TImode, operands);
1912 else
1913 ix86_expand_vector_move (TImode, operands);
1914 DONE;
1915 })
1916
1917 ;; This expands to what emit_move_complex would generate if we didn't
1918 ;; have a movti pattern. Having this avoids problems with reload on
1919 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1920 ;; to have around all the time.
1921 (define_expand "movcdi"
1922 [(set (match_operand:CDI 0 "nonimmediate_operand")
1923 (match_operand:CDI 1 "general_operand"))]
1924 ""
1925 {
1926 if (push_operand (operands[0], CDImode))
1927 emit_move_complex_push (CDImode, operands[0], operands[1]);
1928 else
1929 emit_move_complex_parts (operands[0], operands[1]);
1930 DONE;
1931 })
1932
1933 (define_expand "mov<mode>"
1934 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1935 (match_operand:SWI1248x 1 "general_operand"))]
1936 ""
1937 "ix86_expand_move (<MODE>mode, operands); DONE;")
1938
1939 (define_insn "*mov<mode>_xor"
1940 [(set (match_operand:SWI48 0 "register_operand" "=r")
1941 (match_operand:SWI48 1 "const0_operand"))
1942 (clobber (reg:CC FLAGS_REG))]
1943 "reload_completed"
1944 "xor{l}\t%k0, %k0"
1945 [(set_attr "type" "alu1")
1946 (set_attr "mode" "SI")
1947 (set_attr "length_immediate" "0")])
1948
1949 (define_insn "*mov<mode>_or"
1950 [(set (match_operand:SWI48 0 "register_operand" "=r")
1951 (match_operand:SWI48 1 "const_int_operand"))
1952 (clobber (reg:CC FLAGS_REG))]
1953 "reload_completed
1954 && operands[1] == constm1_rtx"
1955 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1956 [(set_attr "type" "alu1")
1957 (set_attr "mode" "<MODE>")
1958 (set_attr "length_immediate" "1")])
1959
1960 (define_insn "*movxi_internal_avx512f"
1961 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1962 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1963 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1964 {
1965 switch (which_alternative)
1966 {
1967 case 0:
1968 return standard_sse_constant_opcode (insn, operands[1]);
1969 case 1:
1970 case 2:
1971 if (misaligned_operand (operands[0], XImode)
1972 || misaligned_operand (operands[1], XImode))
1973 return "vmovdqu32\t{%1, %0|%0, %1}";
1974 else
1975 return "vmovdqa32\t{%1, %0|%0, %1}";
1976 default:
1977 gcc_unreachable ();
1978 }
1979 }
1980 [(set_attr "type" "sselog1,ssemov,ssemov")
1981 (set_attr "prefix" "evex")
1982 (set_attr "mode" "XI")])
1983
1984 (define_insn "*movoi_internal_avx"
1985 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1986 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1987 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988 {
1989 switch (get_attr_type (insn))
1990 {
1991 case TYPE_SSELOG1:
1992 return standard_sse_constant_opcode (insn, operands[1]);
1993
1994 case TYPE_SSEMOV:
1995 if (misaligned_operand (operands[0], OImode)
1996 || misaligned_operand (operands[1], OImode))
1997 {
1998 if (get_attr_mode (insn) == MODE_V8SF)
1999 return "vmovups\t{%1, %0|%0, %1}";
2000 else if (get_attr_mode (insn) == MODE_XI)
2001 return "vmovdqu32\t{%1, %0|%0, %1}";
2002 else
2003 return "vmovdqu\t{%1, %0|%0, %1}";
2004 }
2005 else
2006 {
2007 if (get_attr_mode (insn) == MODE_V8SF)
2008 return "vmovaps\t{%1, %0|%0, %1}";
2009 else if (get_attr_mode (insn) == MODE_XI)
2010 return "vmovdqa32\t{%1, %0|%0, %1}";
2011 else
2012 return "vmovdqa\t{%1, %0|%0, %1}";
2013 }
2014
2015 default:
2016 gcc_unreachable ();
2017 }
2018 }
2019 [(set_attr "type" "sselog1,ssemov,ssemov")
2020 (set_attr "prefix" "vex")
2021 (set (attr "mode")
2022 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2023 (match_operand 1 "ext_sse_reg_operand"))
2024 (const_string "XI")
2025 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2026 (const_string "V8SF")
2027 (and (eq_attr "alternative" "2")
2028 (match_test "TARGET_SSE_TYPELESS_STORES"))
2029 (const_string "V8SF")
2030 ]
2031 (const_string "OI")))])
2032
2033 (define_insn "*movti_internal"
2034 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2035 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2036 "(TARGET_64BIT || TARGET_SSE)
2037 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2038 {
2039 switch (get_attr_type (insn))
2040 {
2041 case TYPE_MULTI:
2042 return "#";
2043
2044 case TYPE_SSELOG1:
2045 return standard_sse_constant_opcode (insn, operands[1]);
2046
2047 case TYPE_SSEMOV:
2048 /* TDmode values are passed as TImode on the stack. Moving them
2049 to stack may result in unaligned memory access. */
2050 if (misaligned_operand (operands[0], TImode)
2051 || misaligned_operand (operands[1], TImode))
2052 {
2053 if (get_attr_mode (insn) == MODE_V4SF)
2054 return "%vmovups\t{%1, %0|%0, %1}";
2055 else if (get_attr_mode (insn) == MODE_XI)
2056 return "vmovdqu32\t{%1, %0|%0, %1}";
2057 else
2058 return "%vmovdqu\t{%1, %0|%0, %1}";
2059 }
2060 else
2061 {
2062 if (get_attr_mode (insn) == MODE_V4SF)
2063 return "%vmovaps\t{%1, %0|%0, %1}";
2064 else if (get_attr_mode (insn) == MODE_XI)
2065 return "vmovdqa32\t{%1, %0|%0, %1}";
2066 else
2067 return "%vmovdqa\t{%1, %0|%0, %1}";
2068 }
2069
2070 default:
2071 gcc_unreachable ();
2072 }
2073 }
2074 [(set_attr "isa" "x64,x64,*,*,*")
2075 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2076 (set (attr "prefix")
2077 (if_then_else (eq_attr "type" "sselog1,ssemov")
2078 (const_string "maybe_vex")
2079 (const_string "orig")))
2080 (set (attr "mode")
2081 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2082 (match_operand 1 "ext_sse_reg_operand"))
2083 (const_string "XI")
2084 (eq_attr "alternative" "0,1")
2085 (const_string "DI")
2086 (ior (not (match_test "TARGET_SSE2"))
2087 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2088 (const_string "V4SF")
2089 (and (eq_attr "alternative" "4")
2090 (match_test "TARGET_SSE_TYPELESS_STORES"))
2091 (const_string "V4SF")
2092 (match_test "TARGET_AVX")
2093 (const_string "TI")
2094 (match_test "optimize_function_for_size_p (cfun)")
2095 (const_string "V4SF")
2096 ]
2097 (const_string "TI")))])
2098
2099 (define_split
2100 [(set (match_operand:TI 0 "nonimmediate_operand")
2101 (match_operand:TI 1 "general_operand"))]
2102 "reload_completed
2103 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2104 [(const_int 0)]
2105 "ix86_split_long_move (operands); DONE;")
2106
2107 (define_insn "*movdi_internal"
2108 [(set (match_operand:DI 0 "nonimmediate_operand"
2109 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2110 (match_operand:DI 1 "general_operand"
2111 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2112 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2113 {
2114 switch (get_attr_type (insn))
2115 {
2116 case TYPE_MSKMOV:
2117 return "kmovq\t{%1, %0|%0, %1}";
2118
2119 case TYPE_MULTI:
2120 return "#";
2121
2122 case TYPE_MMX:
2123 return "pxor\t%0, %0";
2124
2125 case TYPE_MMXMOV:
2126 /* Handle broken assemblers that require movd instead of movq. */
2127 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2128 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2129 return "movd\t{%1, %0|%0, %1}";
2130 return "movq\t{%1, %0|%0, %1}";
2131
2132 case TYPE_SSELOG1:
2133 if (GENERAL_REG_P (operands[0]))
2134 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2135
2136 return standard_sse_constant_opcode (insn, operands[1]);
2137
2138 case TYPE_SSEMOV:
2139 switch (get_attr_mode (insn))
2140 {
2141 case MODE_DI:
2142 /* Handle broken assemblers that require movd instead of movq. */
2143 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2144 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2145 return "%vmovd\t{%1, %0|%0, %1}";
2146 return "%vmovq\t{%1, %0|%0, %1}";
2147 case MODE_TI:
2148 return "%vmovdqa\t{%1, %0|%0, %1}";
2149 case MODE_XI:
2150 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2151
2152 case MODE_V2SF:
2153 gcc_assert (!TARGET_AVX);
2154 return "movlps\t{%1, %0|%0, %1}";
2155 case MODE_V4SF:
2156 return "%vmovaps\t{%1, %0|%0, %1}";
2157
2158 default:
2159 gcc_unreachable ();
2160 }
2161
2162 case TYPE_SSECVT:
2163 if (SSE_REG_P (operands[0]))
2164 return "movq2dq\t{%1, %0|%0, %1}";
2165 else
2166 return "movdq2q\t{%1, %0|%0, %1}";
2167
2168 case TYPE_LEA:
2169 return "lea{q}\t{%E1, %0|%0, %E1}";
2170
2171 case TYPE_IMOV:
2172 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2173 if (get_attr_mode (insn) == MODE_SI)
2174 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2175 else if (which_alternative == 4)
2176 return "movabs{q}\t{%1, %0|%0, %1}";
2177 else if (ix86_use_lea_for_mov (insn, operands))
2178 return "lea{q}\t{%E1, %0|%0, %E1}";
2179 else
2180 return "mov{q}\t{%1, %0|%0, %1}";
2181
2182 default:
2183 gcc_unreachable ();
2184 }
2185 }
2186 [(set (attr "isa")
2187 (cond [(eq_attr "alternative" "0,1")
2188 (const_string "nox64")
2189 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2190 (const_string "x64")
2191 (eq_attr "alternative" "17")
2192 (const_string "x64_sse4")
2193 ]
2194 (const_string "*")))
2195 (set (attr "type")
2196 (cond [(eq_attr "alternative" "0,1")
2197 (const_string "multi")
2198 (eq_attr "alternative" "6")
2199 (const_string "mmx")
2200 (eq_attr "alternative" "7,8,9,10,11")
2201 (const_string "mmxmov")
2202 (eq_attr "alternative" "12,17")
2203 (const_string "sselog1")
2204 (eq_attr "alternative" "13,14,15,16,18")
2205 (const_string "ssemov")
2206 (eq_attr "alternative" "19,20")
2207 (const_string "ssecvt")
2208 (eq_attr "alternative" "21,22,23,24")
2209 (const_string "mskmov")
2210 (match_operand 1 "pic_32bit_operand")
2211 (const_string "lea")
2212 ]
2213 (const_string "imov")))
2214 (set (attr "modrm")
2215 (if_then_else
2216 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2217 (const_string "0")
2218 (const_string "*")))
2219 (set (attr "length_immediate")
2220 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2221 (const_string "8")
2222 (eq_attr "alternative" "17")
2223 (const_string "1")
2224 ]
2225 (const_string "*")))
2226 (set (attr "prefix_rex")
2227 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2228 (const_string "1")
2229 (const_string "*")))
2230 (set (attr "prefix_extra")
2231 (if_then_else (eq_attr "alternative" "17")
2232 (const_string "1")
2233 (const_string "*")))
2234 (set (attr "prefix")
2235 (if_then_else (eq_attr "type" "sselog1,ssemov")
2236 (const_string "maybe_vex")
2237 (const_string "orig")))
2238 (set (attr "prefix_data16")
2239 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2240 (const_string "1")
2241 (const_string "*")))
2242 (set (attr "mode")
2243 (cond [(eq_attr "alternative" "2")
2244 (const_string "SI")
2245 (eq_attr "alternative" "12,13")
2246 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2247 (match_operand 1 "ext_sse_reg_operand"))
2248 (const_string "XI")
2249 (ior (not (match_test "TARGET_SSE2"))
2250 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2251 (const_string "V4SF")
2252 (match_test "TARGET_AVX")
2253 (const_string "TI")
2254 (match_test "optimize_function_for_size_p (cfun)")
2255 (const_string "V4SF")
2256 ]
2257 (const_string "TI"))
2258
2259 (and (eq_attr "alternative" "14,15")
2260 (not (match_test "TARGET_SSE2")))
2261 (const_string "V2SF")
2262 (eq_attr "alternative" "17")
2263 (const_string "TI")
2264 ]
2265 (const_string "DI")))])
2266
2267 (define_split
2268 [(set (match_operand:DI 0 "nonimmediate_operand")
2269 (match_operand:DI 1 "general_operand"))]
2270 "!TARGET_64BIT && reload_completed
2271 && !(MMX_REG_P (operands[0])
2272 || SSE_REG_P (operands[0])
2273 || MASK_REG_P (operands[0]))
2274 && !(MMX_REG_P (operands[1])
2275 || SSE_REG_P (operands[1])
2276 || MASK_REG_P (operands[1]))"
2277 [(const_int 0)]
2278 "ix86_split_long_move (operands); DONE;")
2279
2280 (define_insn "*movsi_internal"
2281 [(set (match_operand:SI 0 "nonimmediate_operand"
2282 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2283 (match_operand:SI 1 "general_operand"
2284 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2285 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2286 {
2287 switch (get_attr_type (insn))
2288 {
2289 case TYPE_SSELOG1:
2290 if (GENERAL_REG_P (operands[0]))
2291 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2292
2293 return standard_sse_constant_opcode (insn, operands[1]);
2294
2295 case TYPE_MSKMOV:
2296 return "kmovd\t{%1, %0|%0, %1}";
2297
2298 case TYPE_SSEMOV:
2299 switch (get_attr_mode (insn))
2300 {
2301 case MODE_SI:
2302 return "%vmovd\t{%1, %0|%0, %1}";
2303 case MODE_TI:
2304 return "%vmovdqa\t{%1, %0|%0, %1}";
2305 case MODE_XI:
2306 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2307
2308 case MODE_V4SF:
2309 return "%vmovaps\t{%1, %0|%0, %1}";
2310
2311 case MODE_SF:
2312 gcc_assert (!TARGET_AVX);
2313 return "movss\t{%1, %0|%0, %1}";
2314
2315 default:
2316 gcc_unreachable ();
2317 }
2318
2319 case TYPE_MMX:
2320 return "pxor\t%0, %0";
2321
2322 case TYPE_MMXMOV:
2323 switch (get_attr_mode (insn))
2324 {
2325 case MODE_DI:
2326 return "movq\t{%1, %0|%0, %1}";
2327 case MODE_SI:
2328 return "movd\t{%1, %0|%0, %1}";
2329
2330 default:
2331 gcc_unreachable ();
2332 }
2333
2334 case TYPE_LEA:
2335 return "lea{l}\t{%E1, %0|%0, %E1}";
2336
2337 case TYPE_IMOV:
2338 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2339 if (ix86_use_lea_for_mov (insn, operands))
2340 return "lea{l}\t{%E1, %0|%0, %E1}";
2341 else
2342 return "mov{l}\t{%1, %0|%0, %1}";
2343
2344 default:
2345 gcc_unreachable ();
2346 }
2347 }
2348 [(set (attr "isa")
2349 (if_then_else (eq_attr "alternative" "11")
2350 (const_string "sse4")
2351 (const_string "*")))
2352 (set (attr "type")
2353 (cond [(eq_attr "alternative" "2")
2354 (const_string "mmx")
2355 (eq_attr "alternative" "3,4,5")
2356 (const_string "mmxmov")
2357 (eq_attr "alternative" "6,11")
2358 (const_string "sselog1")
2359 (eq_attr "alternative" "7,8,9,10,12")
2360 (const_string "ssemov")
2361 (eq_attr "alternative" "13,14")
2362 (const_string "mskmov")
2363 (match_operand 1 "pic_32bit_operand")
2364 (const_string "lea")
2365 ]
2366 (const_string "imov")))
2367 (set (attr "length_immediate")
2368 (if_then_else (eq_attr "alternative" "11")
2369 (const_string "1")
2370 (const_string "*")))
2371 (set (attr "prefix_extra")
2372 (if_then_else (eq_attr "alternative" "11")
2373 (const_string "1")
2374 (const_string "*")))
2375 (set (attr "prefix")
2376 (if_then_else (eq_attr "type" "sselog1,ssemov")
2377 (const_string "maybe_vex")
2378 (const_string "orig")))
2379 (set (attr "prefix_data16")
2380 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2381 (const_string "1")
2382 (const_string "*")))
2383 (set (attr "mode")
2384 (cond [(eq_attr "alternative" "2,3")
2385 (const_string "DI")
2386 (eq_attr "alternative" "6,7")
2387 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2388 (match_operand 1 "ext_sse_reg_operand"))
2389 (const_string "XI")
2390 (ior (not (match_test "TARGET_SSE2"))
2391 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2392 (const_string "V4SF")
2393 (match_test "TARGET_AVX")
2394 (const_string "TI")
2395 (match_test "optimize_function_for_size_p (cfun)")
2396 (const_string "V4SF")
2397 ]
2398 (const_string "TI"))
2399
2400 (and (eq_attr "alternative" "8,9")
2401 (not (match_test "TARGET_SSE2")))
2402 (const_string "SF")
2403 (eq_attr "alternative" "11")
2404 (const_string "TI")
2405 ]
2406 (const_string "SI")))])
2407
2408 (define_insn "kmovw"
2409 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2410 (unspec:HI
2411 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2412 UNSPEC_KMOV))]
2413 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2414 "@
2415 kmovw\t{%k1, %0|%0, %k1}
2416 kmovw\t{%1, %0|%0, %1}";
2417 [(set_attr "mode" "HI")
2418 (set_attr "type" "mskmov")
2419 (set_attr "prefix" "vex")])
2420
2421
2422 (define_insn "*movhi_internal"
2423 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2424 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2425 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2426 {
2427 switch (get_attr_type (insn))
2428 {
2429 case TYPE_IMOVX:
2430 /* movzwl is faster than movw on p2 due to partial word stalls,
2431 though not as fast as an aligned movl. */
2432 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2433
2434 case TYPE_MSKMOV:
2435 switch (which_alternative)
2436 {
2437 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2438 case 5: return "kmovw\t{%1, %0|%0, %1}";
2439 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2440 default: gcc_unreachable ();
2441 }
2442
2443 default:
2444 if (get_attr_mode (insn) == MODE_SI)
2445 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2446 else
2447 return "mov{w}\t{%1, %0|%0, %1}";
2448 }
2449 }
2450 [(set (attr "type")
2451 (cond [(eq_attr "alternative" "4,5,6")
2452 (const_string "mskmov")
2453 (match_test "optimize_function_for_size_p (cfun)")
2454 (const_string "imov")
2455 (and (eq_attr "alternative" "0")
2456 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2457 (not (match_test "TARGET_HIMODE_MATH"))))
2458 (const_string "imov")
2459 (and (eq_attr "alternative" "1,2")
2460 (match_operand:HI 1 "aligned_operand"))
2461 (const_string "imov")
2462 (and (match_test "TARGET_MOVX")
2463 (eq_attr "alternative" "0,2"))
2464 (const_string "imovx")
2465 ]
2466 (const_string "imov")))
2467 (set (attr "prefix")
2468 (if_then_else (eq_attr "alternative" "4,5,6")
2469 (const_string "vex")
2470 (const_string "orig")))
2471 (set (attr "mode")
2472 (cond [(eq_attr "type" "imovx")
2473 (const_string "SI")
2474 (and (eq_attr "alternative" "1,2")
2475 (match_operand:HI 1 "aligned_operand"))
2476 (const_string "SI")
2477 (and (eq_attr "alternative" "0")
2478 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2479 (not (match_test "TARGET_HIMODE_MATH"))))
2480 (const_string "SI")
2481 ]
2482 (const_string "HI")))])
2483
2484 ;; Situation is quite tricky about when to choose full sized (SImode) move
2485 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2486 ;; partial register dependency machines (such as AMD Athlon), where QImode
2487 ;; moves issue extra dependency and for partial register stalls machines
2488 ;; that don't use QImode patterns (and QImode move cause stall on the next
2489 ;; instruction).
2490 ;;
2491 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2492 ;; register stall machines with, where we use QImode instructions, since
2493 ;; partial register stall can be caused there. Then we use movzx.
2494
2495 (define_insn "*movqi_internal"
2496 [(set (match_operand:QI 0 "nonimmediate_operand"
2497 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2498 (match_operand:QI 1 "general_operand"
2499 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2500 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2501 {
2502 switch (get_attr_type (insn))
2503 {
2504 case TYPE_IMOVX:
2505 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2506 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2507
2508 case TYPE_MSKMOV:
2509 switch (which_alternative)
2510 {
2511 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2512 : "kmovw\t{%k1, %0|%0, %k1}";
2513 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2514 : "kmovw\t{%1, %0|%0, %1}";
2515 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2516 : "kmovw\t{%1, %k0|%k0, %1}";
2517 case 10:
2518 case 11:
2519 gcc_assert (TARGET_AVX512DQ);
2520 return "kmovb\t{%1, %0|%0, %1}";
2521 default: gcc_unreachable ();
2522 }
2523
2524 default:
2525 if (get_attr_mode (insn) == MODE_SI)
2526 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2527 else
2528 return "mov{b}\t{%1, %0|%0, %1}";
2529 }
2530 }
2531 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2532 (set (attr "type")
2533 (cond [(eq_attr "alternative" "3,5")
2534 (const_string "imovx")
2535 (eq_attr "alternative" "7,8,9,10,11")
2536 (const_string "mskmov")
2537 (and (eq_attr "alternative" "5")
2538 (not (match_operand:QI 1 "aligned_operand")))
2539 (const_string "imovx")
2540 (match_test "optimize_function_for_size_p (cfun)")
2541 (const_string "imov")
2542 (and (eq_attr "alternative" "3")
2543 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2544 (not (match_test "TARGET_QIMODE_MATH"))))
2545 (const_string "imov")
2546 (and (match_test "TARGET_MOVX")
2547 (eq_attr "alternative" "2"))
2548 (const_string "imovx")
2549 ]
2550 (const_string "imov")))
2551 (set (attr "prefix")
2552 (if_then_else (eq_attr "alternative" "7,8,9")
2553 (const_string "vex")
2554 (const_string "orig")))
2555 (set (attr "mode")
2556 (cond [(eq_attr "alternative" "3,4,5")
2557 (const_string "SI")
2558 (eq_attr "alternative" "6")
2559 (const_string "QI")
2560 (eq_attr "type" "imovx")
2561 (const_string "SI")
2562 (and (eq_attr "type" "imov")
2563 (and (eq_attr "alternative" "0,1")
2564 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2565 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2566 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2567 (const_string "SI")
2568 ;; Avoid partial register stalls when not using QImode arithmetic
2569 (and (eq_attr "type" "imov")
2570 (and (eq_attr "alternative" "0,1")
2571 (and (match_test "TARGET_PARTIAL_REG_STALL")
2572 (not (match_test "TARGET_QIMODE_MATH")))))
2573 (const_string "SI")
2574 ]
2575 (const_string "QI")))])
2576
2577 ;; Stores and loads of ax to arbitrary constant address.
2578 ;; We fake an second form of instruction to force reload to load address
2579 ;; into register when rax is not available
2580 (define_insn "*movabs<mode>_1"
2581 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2582 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2583 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2584 "@
2585 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2586 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2587 [(set_attr "type" "imov")
2588 (set_attr "modrm" "0,*")
2589 (set_attr "length_address" "8,0")
2590 (set_attr "length_immediate" "0,*")
2591 (set_attr "memory" "store")
2592 (set_attr "mode" "<MODE>")])
2593
2594 (define_insn "*movabs<mode>_2"
2595 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2596 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2597 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2598 "@
2599 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2600 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2601 [(set_attr "type" "imov")
2602 (set_attr "modrm" "0,*")
2603 (set_attr "length_address" "8,0")
2604 (set_attr "length_immediate" "0")
2605 (set_attr "memory" "load")
2606 (set_attr "mode" "<MODE>")])
2607
2608 (define_insn "*swap<mode>"
2609 [(set (match_operand:SWI48 0 "register_operand" "+r")
2610 (match_operand:SWI48 1 "register_operand" "+r"))
2611 (set (match_dup 1)
2612 (match_dup 0))]
2613 ""
2614 "xchg{<imodesuffix>}\t%1, %0"
2615 [(set_attr "type" "imov")
2616 (set_attr "mode" "<MODE>")
2617 (set_attr "pent_pair" "np")
2618 (set_attr "athlon_decode" "vector")
2619 (set_attr "amdfam10_decode" "double")
2620 (set_attr "bdver1_decode" "double")])
2621
2622 (define_insn "*swap<mode>_1"
2623 [(set (match_operand:SWI12 0 "register_operand" "+r")
2624 (match_operand:SWI12 1 "register_operand" "+r"))
2625 (set (match_dup 1)
2626 (match_dup 0))]
2627 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2628 "xchg{l}\t%k1, %k0"
2629 [(set_attr "type" "imov")
2630 (set_attr "mode" "SI")
2631 (set_attr "pent_pair" "np")
2632 (set_attr "athlon_decode" "vector")
2633 (set_attr "amdfam10_decode" "double")
2634 (set_attr "bdver1_decode" "double")])
2635
2636 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2637 ;; is disabled for AMDFAM10
2638 (define_insn "*swap<mode>_2"
2639 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2640 (match_operand:SWI12 1 "register_operand" "+<r>"))
2641 (set (match_dup 1)
2642 (match_dup 0))]
2643 "TARGET_PARTIAL_REG_STALL"
2644 "xchg{<imodesuffix>}\t%1, %0"
2645 [(set_attr "type" "imov")
2646 (set_attr "mode" "<MODE>")
2647 (set_attr "pent_pair" "np")
2648 (set_attr "athlon_decode" "vector")])
2649
2650 (define_expand "movstrict<mode>"
2651 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2652 (match_operand:SWI12 1 "general_operand"))]
2653 ""
2654 {
2655 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2656 FAIL;
2657 if (GET_CODE (operands[0]) == SUBREG
2658 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2659 FAIL;
2660 /* Don't generate memory->memory moves, go through a register */
2661 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2662 operands[1] = force_reg (<MODE>mode, operands[1]);
2663 })
2664
2665 (define_insn "*movstrict<mode>_1"
2666 [(set (strict_low_part
2667 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2668 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2669 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2670 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2671 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2672 [(set_attr "type" "imov")
2673 (set_attr "mode" "<MODE>")])
2674
2675 (define_insn "*movstrict<mode>_xor"
2676 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2677 (match_operand:SWI12 1 "const0_operand"))
2678 (clobber (reg:CC FLAGS_REG))]
2679 "reload_completed"
2680 "xor{<imodesuffix>}\t%0, %0"
2681 [(set_attr "type" "alu1")
2682 (set_attr "mode" "<MODE>")
2683 (set_attr "length_immediate" "0")])
2684
2685 (define_insn "*mov<mode>_extv_1"
2686 [(set (match_operand:SWI24 0 "register_operand" "=R")
2687 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2688 (const_int 8)
2689 (const_int 8)))]
2690 ""
2691 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2692 [(set_attr "type" "imovx")
2693 (set_attr "mode" "SI")])
2694
2695 (define_insn "*movqi_extv_1"
2696 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2697 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2698 (const_int 8)
2699 (const_int 8)))]
2700 ""
2701 {
2702 switch (get_attr_type (insn))
2703 {
2704 case TYPE_IMOVX:
2705 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2706 default:
2707 return "mov{b}\t{%h1, %0|%0, %h1}";
2708 }
2709 }
2710 [(set_attr "isa" "*,*,nox64")
2711 (set (attr "type")
2712 (if_then_else (and (match_operand:QI 0 "register_operand")
2713 (ior (not (match_operand:QI 0 "QIreg_operand"))
2714 (match_test "TARGET_MOVX")))
2715 (const_string "imovx")
2716 (const_string "imov")))
2717 (set (attr "mode")
2718 (if_then_else (eq_attr "type" "imovx")
2719 (const_string "SI")
2720 (const_string "QI")))])
2721
2722 (define_insn "*mov<mode>_extzv_1"
2723 [(set (match_operand:SWI48 0 "register_operand" "=R")
2724 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2725 (const_int 8)
2726 (const_int 8)))]
2727 ""
2728 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2729 [(set_attr "type" "imovx")
2730 (set_attr "mode" "SI")])
2731
2732 (define_insn "*movqi_extzv_2"
2733 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2734 (subreg:QI
2735 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2736 (const_int 8)
2737 (const_int 8)) 0))]
2738 ""
2739 {
2740 switch (get_attr_type (insn))
2741 {
2742 case TYPE_IMOVX:
2743 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2744 default:
2745 return "mov{b}\t{%h1, %0|%0, %h1}";
2746 }
2747 }
2748 [(set_attr "isa" "*,*,nox64")
2749 (set (attr "type")
2750 (if_then_else (and (match_operand:QI 0 "register_operand")
2751 (ior (not (match_operand:QI 0 "QIreg_operand"))
2752 (match_test "TARGET_MOVX")))
2753 (const_string "imovx")
2754 (const_string "imov")))
2755 (set (attr "mode")
2756 (if_then_else (eq_attr "type" "imovx")
2757 (const_string "SI")
2758 (const_string "QI")))])
2759
2760 (define_insn "mov<mode>_insv_1"
2761 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2762 (const_int 8)
2763 (const_int 8))
2764 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2765 ""
2766 {
2767 if (CONST_INT_P (operands[1]))
2768 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2769 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2770 }
2771 [(set_attr "isa" "*,nox64")
2772 (set_attr "type" "imov")
2773 (set_attr "mode" "QI")])
2774
2775 (define_insn "*movqi_insv_2"
2776 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2777 (const_int 8)
2778 (const_int 8))
2779 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2780 (const_int 8)))]
2781 ""
2782 "mov{b}\t{%h1, %h0|%h0, %h1}"
2783 [(set_attr "type" "imov")
2784 (set_attr "mode" "QI")])
2785 \f
2786 ;; Floating point push instructions.
2787
2788 (define_insn "*pushtf"
2789 [(set (match_operand:TF 0 "push_operand" "=<,<")
2790 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2791 "TARGET_64BIT || TARGET_SSE"
2792 {
2793 /* This insn should be already split before reg-stack. */
2794 gcc_unreachable ();
2795 }
2796 [(set_attr "isa" "*,x64")
2797 (set_attr "type" "multi")
2798 (set_attr "unit" "sse,*")
2799 (set_attr "mode" "TF,DI")])
2800
2801 ;; %%% Kill this when call knows how to work this out.
2802 (define_split
2803 [(set (match_operand:TF 0 "push_operand")
2804 (match_operand:TF 1 "sse_reg_operand"))]
2805 "TARGET_SSE && reload_completed"
2806 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2807 (set (match_dup 0) (match_dup 1))]
2808 {
2809 /* Preserve memory attributes. */
2810 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2811 })
2812
2813 (define_insn "*pushxf"
2814 [(set (match_operand:XF 0 "push_operand" "=<,<")
2815 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2816 ""
2817 {
2818 /* This insn should be already split before reg-stack. */
2819 gcc_unreachable ();
2820 }
2821 [(set_attr "type" "multi")
2822 (set_attr "unit" "i387,*")
2823 (set (attr "mode")
2824 (cond [(eq_attr "alternative" "1")
2825 (if_then_else (match_test "TARGET_64BIT")
2826 (const_string "DI")
2827 (const_string "SI"))
2828 ]
2829 (const_string "XF")))])
2830
2831 ;; %%% Kill this when call knows how to work this out.
2832 (define_split
2833 [(set (match_operand:XF 0 "push_operand")
2834 (match_operand:XF 1 "fp_register_operand"))]
2835 "reload_completed"
2836 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2837 (set (match_dup 0) (match_dup 1))]
2838 {
2839 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2840 /* Preserve memory attributes. */
2841 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2842 })
2843
2844 (define_insn "*pushdf"
2845 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2846 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2847 ""
2848 {
2849 /* This insn should be already split before reg-stack. */
2850 gcc_unreachable ();
2851 }
2852 [(set_attr "isa" "*,nox64,x64,sse2")
2853 (set_attr "type" "multi")
2854 (set_attr "unit" "i387,*,*,sse")
2855 (set_attr "mode" "DF,SI,DI,DF")])
2856
2857 ;; %%% Kill this when call knows how to work this out.
2858 (define_split
2859 [(set (match_operand:DF 0 "push_operand")
2860 (match_operand:DF 1 "any_fp_register_operand"))]
2861 "reload_completed"
2862 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2863 (set (match_dup 0) (match_dup 1))]
2864 {
2865 /* Preserve memory attributes. */
2866 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2867 })
2868
2869 (define_insn "*pushsf_rex64"
2870 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2871 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2872 "TARGET_64BIT"
2873 {
2874 /* Anything else should be already split before reg-stack. */
2875 gcc_assert (which_alternative == 1);
2876 return "push{q}\t%q1";
2877 }
2878 [(set_attr "type" "multi,push,multi")
2879 (set_attr "unit" "i387,*,*")
2880 (set_attr "mode" "SF,DI,SF")])
2881
2882 (define_insn "*pushsf"
2883 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2884 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2885 "!TARGET_64BIT"
2886 {
2887 /* Anything else should be already split before reg-stack. */
2888 gcc_assert (which_alternative == 1);
2889 return "push{l}\t%1";
2890 }
2891 [(set_attr "type" "multi,push,multi")
2892 (set_attr "unit" "i387,*,*")
2893 (set_attr "mode" "SF,SI,SF")])
2894
2895 ;; %%% Kill this when call knows how to work this out.
2896 (define_split
2897 [(set (match_operand:SF 0 "push_operand")
2898 (match_operand:SF 1 "any_fp_register_operand"))]
2899 "reload_completed"
2900 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2901 (set (match_dup 0) (match_dup 1))]
2902 {
2903 rtx op = XEXP (operands[0], 0);
2904 if (GET_CODE (op) == PRE_DEC)
2905 {
2906 gcc_assert (!TARGET_64BIT);
2907 op = GEN_INT (-4);
2908 }
2909 else
2910 {
2911 op = XEXP (XEXP (op, 1), 1);
2912 gcc_assert (CONST_INT_P (op));
2913 }
2914 operands[2] = op;
2915 /* Preserve memory attributes. */
2916 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2917 })
2918
2919 (define_split
2920 [(set (match_operand:SF 0 "push_operand")
2921 (match_operand:SF 1 "memory_operand"))]
2922 "reload_completed
2923 && (operands[2] = find_constant_src (insn))"
2924 [(set (match_dup 0) (match_dup 2))])
2925
2926 (define_split
2927 [(set (match_operand 0 "push_operand")
2928 (match_operand 1 "general_operand"))]
2929 "reload_completed
2930 && (GET_MODE (operands[0]) == TFmode
2931 || GET_MODE (operands[0]) == XFmode
2932 || GET_MODE (operands[0]) == DFmode)
2933 && !ANY_FP_REG_P (operands[1])"
2934 [(const_int 0)]
2935 "ix86_split_long_move (operands); DONE;")
2936 \f
2937 ;; Floating point move instructions.
2938
2939 (define_expand "movtf"
2940 [(set (match_operand:TF 0 "nonimmediate_operand")
2941 (match_operand:TF 1 "nonimmediate_operand"))]
2942 "TARGET_64BIT || TARGET_SSE"
2943 "ix86_expand_move (TFmode, operands); DONE;")
2944
2945 (define_expand "mov<mode>"
2946 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2947 (match_operand:X87MODEF 1 "general_operand"))]
2948 ""
2949 "ix86_expand_move (<MODE>mode, operands); DONE;")
2950
2951 (define_insn "*movtf_internal"
2952 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2953 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2954 "(TARGET_64BIT || TARGET_SSE)
2955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2956 && (!can_create_pseudo_p ()
2957 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2958 || GET_CODE (operands[1]) != CONST_DOUBLE
2959 || (optimize_function_for_size_p (cfun)
2960 && standard_sse_constant_p (operands[1])
2961 && !memory_operand (operands[0], TFmode))
2962 || (!TARGET_MEMORY_MISMATCH_STALL
2963 && memory_operand (operands[0], TFmode)))"
2964 {
2965 switch (get_attr_type (insn))
2966 {
2967 case TYPE_SSELOG1:
2968 return standard_sse_constant_opcode (insn, operands[1]);
2969
2970 case TYPE_SSEMOV:
2971 /* Handle misaligned load/store since we
2972 don't have movmisaligntf pattern. */
2973 if (misaligned_operand (operands[0], TFmode)
2974 || misaligned_operand (operands[1], TFmode))
2975 {
2976 if (get_attr_mode (insn) == MODE_V4SF)
2977 return "%vmovups\t{%1, %0|%0, %1}";
2978 else
2979 return "%vmovdqu\t{%1, %0|%0, %1}";
2980 }
2981 else
2982 {
2983 if (get_attr_mode (insn) == MODE_V4SF)
2984 return "%vmovaps\t{%1, %0|%0, %1}";
2985 else
2986 return "%vmovdqa\t{%1, %0|%0, %1}";
2987 }
2988
2989 case TYPE_MULTI:
2990 return "#";
2991
2992 default:
2993 gcc_unreachable ();
2994 }
2995 }
2996 [(set_attr "isa" "*,*,*,x64,x64")
2997 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2998 (set (attr "prefix")
2999 (if_then_else (eq_attr "type" "sselog1,ssemov")
3000 (const_string "maybe_vex")
3001 (const_string "orig")))
3002 (set (attr "mode")
3003 (cond [(eq_attr "alternative" "3,4")
3004 (const_string "DI")
3005 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3006 (const_string "V4SF")
3007 (and (eq_attr "alternative" "2")
3008 (match_test "TARGET_SSE_TYPELESS_STORES"))
3009 (const_string "V4SF")
3010 (match_test "TARGET_AVX")
3011 (const_string "TI")
3012 (ior (not (match_test "TARGET_SSE2"))
3013 (match_test "optimize_function_for_size_p (cfun)"))
3014 (const_string "V4SF")
3015 ]
3016 (const_string "TI")))])
3017
3018 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
3019 (define_insn "*movxf_internal"
3020 [(set (match_operand:XF 0 "nonimmediate_operand"
3021 "=f,m,f,?Yx*r ,!o ,!o")
3022 (match_operand:XF 1 "general_operand"
3023 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
3024 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3025 && (!can_create_pseudo_p ()
3026 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3027 || GET_CODE (operands[1]) != CONST_DOUBLE
3028 || (optimize_function_for_size_p (cfun)
3029 && standard_80387_constant_p (operands[1]) > 0
3030 && !memory_operand (operands[0], XFmode))
3031 || (!TARGET_MEMORY_MISMATCH_STALL
3032 && memory_operand (operands[0], XFmode)))"
3033 {
3034 switch (get_attr_type (insn))
3035 {
3036 case TYPE_FMOV:
3037 if (which_alternative == 2)
3038 return standard_80387_constant_opcode (operands[1]);
3039 return output_387_reg_move (insn, operands);
3040
3041 case TYPE_MULTI:
3042 return "#";
3043
3044 default:
3045 gcc_unreachable ();
3046 }
3047 }
3048 [(set_attr "isa" "*,*,*,*,nox64,x64")
3049 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
3050 (set (attr "mode")
3051 (cond [(eq_attr "alternative" "3,4,5")
3052 (if_then_else (match_test "TARGET_64BIT")
3053 (const_string "DI")
3054 (const_string "SI"))
3055 ]
3056 (const_string "XF")))])
3057
3058 ;; Possible store forwarding (partial memory) stall in alternative 4.
3059 (define_insn "*movdf_internal"
3060 [(set (match_operand:DF 0 "nonimmediate_operand"
3061 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3062 (match_operand:DF 1 "general_operand"
3063 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3064 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3065 && (!can_create_pseudo_p ()
3066 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3067 || GET_CODE (operands[1]) != CONST_DOUBLE
3068 || (optimize_function_for_size_p (cfun)
3069 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3070 && standard_80387_constant_p (operands[1]) > 0)
3071 || (TARGET_SSE2 && TARGET_SSE_MATH
3072 && standard_sse_constant_p (operands[1])))
3073 && !memory_operand (operands[0], DFmode))
3074 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3075 && memory_operand (operands[0], DFmode)))"
3076 {
3077 switch (get_attr_type (insn))
3078 {
3079 case TYPE_FMOV:
3080 if (which_alternative == 2)
3081 return standard_80387_constant_opcode (operands[1]);
3082 return output_387_reg_move (insn, operands);
3083
3084 case TYPE_MULTI:
3085 return "#";
3086
3087 case TYPE_IMOV:
3088 if (get_attr_mode (insn) == MODE_SI)
3089 return "mov{l}\t{%1, %k0|%k0, %1}";
3090 else if (which_alternative == 8)
3091 return "movabs{q}\t{%1, %0|%0, %1}";
3092 else
3093 return "mov{q}\t{%1, %0|%0, %1}";
3094
3095 case TYPE_SSELOG1:
3096 return standard_sse_constant_opcode (insn, operands[1]);
3097
3098 case TYPE_SSEMOV:
3099 switch (get_attr_mode (insn))
3100 {
3101 case MODE_DF:
3102 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3103 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104 return "%vmovsd\t{%1, %0|%0, %1}";
3105
3106 case MODE_V4SF:
3107 return "%vmovaps\t{%1, %0|%0, %1}";
3108 case MODE_V8DF:
3109 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3110 case MODE_V2DF:
3111 return "%vmovapd\t{%1, %0|%0, %1}";
3112
3113 case MODE_V2SF:
3114 gcc_assert (!TARGET_AVX);
3115 return "movlps\t{%1, %0|%0, %1}";
3116 case MODE_V1DF:
3117 gcc_assert (!TARGET_AVX);
3118 return "movlpd\t{%1, %0|%0, %1}";
3119
3120 case MODE_DI:
3121 /* Handle broken assemblers that require movd instead of movq. */
3122 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3123 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3124 return "%vmovd\t{%1, %0|%0, %1}";
3125 return "%vmovq\t{%1, %0|%0, %1}";
3126
3127 default:
3128 gcc_unreachable ();
3129 }
3130
3131 default:
3132 gcc_unreachable ();
3133 }
3134 }
3135 [(set (attr "isa")
3136 (cond [(eq_attr "alternative" "3,4")
3137 (const_string "nox64")
3138 (eq_attr "alternative" "5,6,7,8,17,18")
3139 (const_string "x64")
3140 (eq_attr "alternative" "9,10,11,12")
3141 (const_string "sse2")
3142 ]
3143 (const_string "*")))
3144 (set (attr "type")
3145 (cond [(eq_attr "alternative" "0,1,2")
3146 (const_string "fmov")
3147 (eq_attr "alternative" "3,4")
3148 (const_string "multi")
3149 (eq_attr "alternative" "5,6,7,8")
3150 (const_string "imov")
3151 (eq_attr "alternative" "9,13")
3152 (const_string "sselog1")
3153 ]
3154 (const_string "ssemov")))
3155 (set (attr "modrm")
3156 (if_then_else (eq_attr "alternative" "8")
3157 (const_string "0")
3158 (const_string "*")))
3159 (set (attr "length_immediate")
3160 (if_then_else (eq_attr "alternative" "8")
3161 (const_string "8")
3162 (const_string "*")))
3163 (set (attr "prefix")
3164 (if_then_else (eq_attr "type" "sselog1,ssemov")
3165 (const_string "maybe_vex")
3166 (const_string "orig")))
3167 (set (attr "prefix_data16")
3168 (if_then_else
3169 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3170 (eq_attr "mode" "V1DF"))
3171 (const_string "1")
3172 (const_string "*")))
3173 (set (attr "mode")
3174 (cond [(eq_attr "alternative" "3,4,7")
3175 (const_string "SI")
3176 (eq_attr "alternative" "5,6,8,17,18")
3177 (const_string "DI")
3178
3179 /* xorps is one byte shorter for non-AVX targets. */
3180 (eq_attr "alternative" "9,13")
3181 (cond [(not (match_test "TARGET_SSE2"))
3182 (const_string "V4SF")
3183 (match_test "TARGET_AVX512F")
3184 (const_string "XI")
3185 (match_test "TARGET_AVX")
3186 (const_string "V2DF")
3187 (match_test "optimize_function_for_size_p (cfun)")
3188 (const_string "V4SF")
3189 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3190 (const_string "TI")
3191 ]
3192 (const_string "V2DF"))
3193
3194 /* For architectures resolving dependencies on
3195 whole SSE registers use movapd to break dependency
3196 chains, otherwise use short move to avoid extra work. */
3197
3198 /* movaps is one byte shorter for non-AVX targets. */
3199 (eq_attr "alternative" "10,14")
3200 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3201 (match_operand 1 "ext_sse_reg_operand"))
3202 (const_string "V8DF")
3203 (ior (not (match_test "TARGET_SSE2"))
3204 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3205 (const_string "V4SF")
3206 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3207 (const_string "V2DF")
3208 (match_test "TARGET_AVX")
3209 (const_string "DF")
3210 (match_test "optimize_function_for_size_p (cfun)")
3211 (const_string "V4SF")
3212 ]
3213 (const_string "DF"))
3214
3215 /* For architectures resolving dependencies on register
3216 parts we may avoid extra work to zero out upper part
3217 of register. */
3218 (eq_attr "alternative" "11,15")
3219 (cond [(not (match_test "TARGET_SSE2"))
3220 (const_string "V2SF")
3221 (match_test "TARGET_AVX")
3222 (const_string "DF")
3223 (match_test "TARGET_SSE_SPLIT_REGS")
3224 (const_string "V1DF")
3225 ]
3226 (const_string "DF"))
3227
3228 (and (eq_attr "alternative" "12,16")
3229 (not (match_test "TARGET_SSE2")))
3230 (const_string "V2SF")
3231 ]
3232 (const_string "DF")))])
3233
3234 (define_insn "*movsf_internal"
3235 [(set (match_operand:SF 0 "nonimmediate_operand"
3236 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3237 (match_operand:SF 1 "general_operand"
3238 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3239 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3240 && (!can_create_pseudo_p ()
3241 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3242 || GET_CODE (operands[1]) != CONST_DOUBLE
3243 || (optimize_function_for_size_p (cfun)
3244 && ((!TARGET_SSE_MATH
3245 && standard_80387_constant_p (operands[1]) > 0)
3246 || (TARGET_SSE_MATH
3247 && standard_sse_constant_p (operands[1]))))
3248 || memory_operand (operands[0], SFmode))"
3249 {
3250 switch (get_attr_type (insn))
3251 {
3252 case TYPE_FMOV:
3253 if (which_alternative == 2)
3254 return standard_80387_constant_opcode (operands[1]);
3255 return output_387_reg_move (insn, operands);
3256
3257 case TYPE_IMOV:
3258 return "mov{l}\t{%1, %0|%0, %1}";
3259
3260 case TYPE_SSELOG1:
3261 return standard_sse_constant_opcode (insn, operands[1]);
3262
3263 case TYPE_SSEMOV:
3264 switch (get_attr_mode (insn))
3265 {
3266 case MODE_SF:
3267 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3268 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3269 return "%vmovss\t{%1, %0|%0, %1}";
3270
3271 case MODE_V16SF:
3272 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3273 case MODE_V4SF:
3274 return "%vmovaps\t{%1, %0|%0, %1}";
3275
3276 case MODE_SI:
3277 return "%vmovd\t{%1, %0|%0, %1}";
3278
3279 default:
3280 gcc_unreachable ();
3281 }
3282
3283 case TYPE_MMXMOV:
3284 switch (get_attr_mode (insn))
3285 {
3286 case MODE_DI:
3287 return "movq\t{%1, %0|%0, %1}";
3288 case MODE_SI:
3289 return "movd\t{%1, %0|%0, %1}";
3290
3291 default:
3292 gcc_unreachable ();
3293 }
3294
3295 default:
3296 gcc_unreachable ();
3297 }
3298 }
3299 [(set (attr "type")
3300 (cond [(eq_attr "alternative" "0,1,2")
3301 (const_string "fmov")
3302 (eq_attr "alternative" "3,4")
3303 (const_string "imov")
3304 (eq_attr "alternative" "5")
3305 (const_string "sselog1")
3306 (eq_attr "alternative" "11,12,13,14,15")
3307 (const_string "mmxmov")
3308 ]
3309 (const_string "ssemov")))
3310 (set (attr "prefix")
3311 (if_then_else (eq_attr "type" "sselog1,ssemov")
3312 (const_string "maybe_vex")
3313 (const_string "orig")))
3314 (set (attr "prefix_data16")
3315 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3316 (const_string "1")
3317 (const_string "*")))
3318 (set (attr "mode")
3319 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3320 (const_string "SI")
3321 (eq_attr "alternative" "11")
3322 (const_string "DI")
3323 (eq_attr "alternative" "5")
3324 (cond [(not (match_test "TARGET_SSE2"))
3325 (const_string "V4SF")
3326 (match_test "TARGET_AVX512F")
3327 (const_string "V16SF")
3328 (match_test "TARGET_AVX")
3329 (const_string "V4SF")
3330 (match_test "optimize_function_for_size_p (cfun)")
3331 (const_string "V4SF")
3332 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3333 (const_string "TI")
3334 ]
3335 (const_string "V4SF"))
3336
3337 /* For architectures resolving dependencies on
3338 whole SSE registers use APS move to break dependency
3339 chains, otherwise use short move to avoid extra work.
3340
3341 Do the same for architectures resolving dependencies on
3342 the parts. While in DF mode it is better to always handle
3343 just register parts, the SF mode is different due to lack
3344 of instructions to load just part of the register. It is
3345 better to maintain the whole registers in single format
3346 to avoid problems on using packed logical operations. */
3347 (eq_attr "alternative" "6")
3348 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3349 (match_operand 1 "ext_sse_reg_operand"))
3350 (const_string "V16SF")
3351 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3352 (match_test "TARGET_SSE_SPLIT_REGS"))
3353 (const_string "V4SF")
3354 ]
3355 (const_string "SF"))
3356 ]
3357 (const_string "SF")))])
3358
3359 (define_split
3360 [(set (match_operand 0 "any_fp_register_operand")
3361 (match_operand 1 "memory_operand"))]
3362 "reload_completed
3363 && (GET_MODE (operands[0]) == TFmode
3364 || GET_MODE (operands[0]) == XFmode
3365 || GET_MODE (operands[0]) == DFmode
3366 || GET_MODE (operands[0]) == SFmode)
3367 && (operands[2] = find_constant_src (insn))"
3368 [(set (match_dup 0) (match_dup 2))]
3369 {
3370 rtx c = operands[2];
3371 int r = REGNO (operands[0]);
3372
3373 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3374 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3375 FAIL;
3376 })
3377
3378 (define_split
3379 [(set (match_operand 0 "any_fp_register_operand")
3380 (float_extend (match_operand 1 "memory_operand")))]
3381 "reload_completed
3382 && (GET_MODE (operands[0]) == TFmode
3383 || GET_MODE (operands[0]) == XFmode
3384 || GET_MODE (operands[0]) == DFmode)
3385 && (operands[2] = find_constant_src (insn))"
3386 [(set (match_dup 0) (match_dup 2))]
3387 {
3388 rtx c = operands[2];
3389 int r = REGNO (operands[0]);
3390
3391 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3392 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3393 FAIL;
3394 })
3395
3396 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3397 (define_split
3398 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3399 (match_operand:X87MODEF 1 "immediate_operand"))]
3400 "reload_completed
3401 && (standard_80387_constant_p (operands[1]) == 8
3402 || standard_80387_constant_p (operands[1]) == 9)"
3403 [(set (match_dup 0)(match_dup 1))
3404 (set (match_dup 0)
3405 (neg:X87MODEF (match_dup 0)))]
3406 {
3407 REAL_VALUE_TYPE r;
3408
3409 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3410 if (real_isnegzero (&r))
3411 operands[1] = CONST0_RTX (<MODE>mode);
3412 else
3413 operands[1] = CONST1_RTX (<MODE>mode);
3414 })
3415
3416 (define_split
3417 [(set (match_operand 0 "nonimmediate_operand")
3418 (match_operand 1 "general_operand"))]
3419 "reload_completed
3420 && (GET_MODE (operands[0]) == TFmode
3421 || GET_MODE (operands[0]) == XFmode
3422 || GET_MODE (operands[0]) == DFmode)
3423 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3424 [(const_int 0)]
3425 "ix86_split_long_move (operands); DONE;")
3426
3427 (define_insn "swapxf"
3428 [(set (match_operand:XF 0 "register_operand" "+f")
3429 (match_operand:XF 1 "register_operand" "+f"))
3430 (set (match_dup 1)
3431 (match_dup 0))]
3432 "TARGET_80387"
3433 {
3434 if (STACK_TOP_P (operands[0]))
3435 return "fxch\t%1";
3436 else
3437 return "fxch\t%0";
3438 }
3439 [(set_attr "type" "fxch")
3440 (set_attr "mode" "XF")])
3441
3442 (define_insn "*swap<mode>"
3443 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3444 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3445 (set (match_dup 1)
3446 (match_dup 0))]
3447 "TARGET_80387 || reload_completed"
3448 {
3449 if (STACK_TOP_P (operands[0]))
3450 return "fxch\t%1";
3451 else
3452 return "fxch\t%0";
3453 }
3454 [(set_attr "type" "fxch")
3455 (set_attr "mode" "<MODE>")])
3456 \f
3457 ;; Zero extension instructions
3458
3459 (define_expand "zero_extendsidi2"
3460 [(set (match_operand:DI 0 "nonimmediate_operand")
3461 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3462
3463 (define_insn "*zero_extendsidi2"
3464 [(set (match_operand:DI 0 "nonimmediate_operand"
3465 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3466 (zero_extend:DI
3467 (match_operand:SI 1 "x86_64_zext_operand"
3468 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3469 ""
3470 {
3471 switch (get_attr_type (insn))
3472 {
3473 case TYPE_IMOVX:
3474 if (ix86_use_lea_for_mov (insn, operands))
3475 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3476 else
3477 return "mov{l}\t{%1, %k0|%k0, %1}";
3478
3479 case TYPE_MULTI:
3480 return "#";
3481
3482 case TYPE_MMXMOV:
3483 return "movd\t{%1, %0|%0, %1}";
3484
3485 case TYPE_SSELOG1:
3486 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3487
3488 case TYPE_SSEMOV:
3489 if (GENERAL_REG_P (operands[0]))
3490 return "%vmovd\t{%1, %k0|%k0, %1}";
3491
3492 return "%vmovd\t{%1, %0|%0, %1}";
3493
3494 default:
3495 gcc_unreachable ();
3496 }
3497 }
3498 [(set (attr "isa")
3499 (cond [(eq_attr "alternative" "0,1,2")
3500 (const_string "nox64")
3501 (eq_attr "alternative" "3,7")
3502 (const_string "x64")
3503 (eq_attr "alternative" "8")
3504 (const_string "x64_sse4")
3505 (eq_attr "alternative" "10")
3506 (const_string "sse2")
3507 ]
3508 (const_string "*")))
3509 (set (attr "type")
3510 (cond [(eq_attr "alternative" "0,1,2,4")
3511 (const_string "multi")
3512 (eq_attr "alternative" "5,6")
3513 (const_string "mmxmov")
3514 (eq_attr "alternative" "7,9,10")
3515 (const_string "ssemov")
3516 (eq_attr "alternative" "8")
3517 (const_string "sselog1")
3518 ]
3519 (const_string "imovx")))
3520 (set (attr "prefix_extra")
3521 (if_then_else (eq_attr "alternative" "8")
3522 (const_string "1")
3523 (const_string "*")))
3524 (set (attr "length_immediate")
3525 (if_then_else (eq_attr "alternative" "8")
3526 (const_string "1")
3527 (const_string "*")))
3528 (set (attr "prefix")
3529 (if_then_else (eq_attr "type" "ssemov,sselog1")
3530 (const_string "maybe_vex")
3531 (const_string "orig")))
3532 (set (attr "prefix_0f")
3533 (if_then_else (eq_attr "type" "imovx")
3534 (const_string "0")
3535 (const_string "*")))
3536 (set (attr "mode")
3537 (cond [(eq_attr "alternative" "5,6")
3538 (const_string "DI")
3539 (eq_attr "alternative" "7,8,9")
3540 (const_string "TI")
3541 ]
3542 (const_string "SI")))])
3543
3544 (define_split
3545 [(set (match_operand:DI 0 "memory_operand")
3546 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3547 "reload_completed"
3548 [(set (match_dup 4) (const_int 0))]
3549 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3550
3551 (define_split
3552 [(set (match_operand:DI 0 "register_operand")
3553 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3554 "!TARGET_64BIT && reload_completed
3555 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3556 && true_regnum (operands[0]) == true_regnum (operands[1])"
3557 [(set (match_dup 4) (const_int 0))]
3558 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3559
3560 (define_split
3561 [(set (match_operand:DI 0 "nonimmediate_operand")
3562 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3563 "!TARGET_64BIT && reload_completed
3564 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3565 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3566 [(set (match_dup 3) (match_dup 1))
3567 (set (match_dup 4) (const_int 0))]
3568 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3569
3570 (define_insn "zero_extend<mode>di2"
3571 [(set (match_operand:DI 0 "register_operand" "=r")
3572 (zero_extend:DI
3573 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3574 "TARGET_64BIT"
3575 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3576 [(set_attr "type" "imovx")
3577 (set_attr "mode" "SI")])
3578
3579 (define_expand "zero_extend<mode>si2"
3580 [(set (match_operand:SI 0 "register_operand")
3581 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3582 ""
3583 {
3584 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3585 {
3586 operands[1] = force_reg (<MODE>mode, operands[1]);
3587 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3588 DONE;
3589 }
3590 })
3591
3592 (define_insn_and_split "zero_extend<mode>si2_and"
3593 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3594 (zero_extend:SI
3595 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3596 (clobber (reg:CC FLAGS_REG))]
3597 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3598 "#"
3599 "&& reload_completed"
3600 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3601 (clobber (reg:CC FLAGS_REG))])]
3602 {
3603 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3604 {
3605 ix86_expand_clear (operands[0]);
3606
3607 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3608 emit_insn (gen_movstrict<mode>
3609 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3610 DONE;
3611 }
3612
3613 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3614 }
3615 [(set_attr "type" "alu1")
3616 (set_attr "mode" "SI")])
3617
3618 (define_insn "*zero_extend<mode>si2"
3619 [(set (match_operand:SI 0 "register_operand" "=r")
3620 (zero_extend:SI
3621 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3622 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3623 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3624 [(set_attr "type" "imovx")
3625 (set_attr "mode" "SI")])
3626
3627 (define_expand "zero_extendqihi2"
3628 [(set (match_operand:HI 0 "register_operand")
3629 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3630 ""
3631 {
3632 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3633 {
3634 operands[1] = force_reg (QImode, operands[1]);
3635 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3636 DONE;
3637 }
3638 })
3639
3640 (define_insn_and_split "zero_extendqihi2_and"
3641 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3642 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3643 (clobber (reg:CC FLAGS_REG))]
3644 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3645 "#"
3646 "&& reload_completed"
3647 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3648 (clobber (reg:CC FLAGS_REG))])]
3649 {
3650 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3651 {
3652 ix86_expand_clear (operands[0]);
3653
3654 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3655 emit_insn (gen_movstrictqi
3656 (gen_lowpart (QImode, operands[0]), operands[1]));
3657 DONE;
3658 }
3659
3660 operands[0] = gen_lowpart (SImode, operands[0]);
3661 }
3662 [(set_attr "type" "alu1")
3663 (set_attr "mode" "SI")])
3664
3665 ; zero extend to SImode to avoid partial register stalls
3666 (define_insn "*zero_extendqihi2"
3667 [(set (match_operand:HI 0 "register_operand" "=r")
3668 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3669 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3670 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3671 [(set_attr "type" "imovx")
3672 (set_attr "mode" "SI")])
3673 \f
3674 ;; Sign extension instructions
3675
3676 (define_expand "extendsidi2"
3677 [(set (match_operand:DI 0 "register_operand")
3678 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3679 ""
3680 {
3681 if (!TARGET_64BIT)
3682 {
3683 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3684 DONE;
3685 }
3686 })
3687
3688 (define_insn "*extendsidi2_rex64"
3689 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3690 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3691 "TARGET_64BIT"
3692 "@
3693 {cltq|cdqe}
3694 movs{lq|x}\t{%1, %0|%0, %1}"
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "DI")
3697 (set_attr "prefix_0f" "0")
3698 (set_attr "modrm" "0,1")])
3699
3700 (define_insn "extendsidi2_1"
3701 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3702 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3703 (clobber (reg:CC FLAGS_REG))
3704 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3705 "!TARGET_64BIT"
3706 "#")
3707
3708 ;; Split the memory case. If the source register doesn't die, it will stay
3709 ;; this way, if it does die, following peephole2s take care of it.
3710 (define_split
3711 [(set (match_operand:DI 0 "memory_operand")
3712 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3713 (clobber (reg:CC FLAGS_REG))
3714 (clobber (match_operand:SI 2 "register_operand"))]
3715 "reload_completed"
3716 [(const_int 0)]
3717 {
3718 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3719
3720 emit_move_insn (operands[3], operands[1]);
3721
3722 /* Generate a cltd if possible and doing so it profitable. */
3723 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3724 && true_regnum (operands[1]) == AX_REG
3725 && true_regnum (operands[2]) == DX_REG)
3726 {
3727 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3728 }
3729 else
3730 {
3731 emit_move_insn (operands[2], operands[1]);
3732 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3733 }
3734 emit_move_insn (operands[4], operands[2]);
3735 DONE;
3736 })
3737
3738 ;; Peepholes for the case where the source register does die, after
3739 ;; being split with the above splitter.
3740 (define_peephole2
3741 [(set (match_operand:SI 0 "memory_operand")
3742 (match_operand:SI 1 "register_operand"))
3743 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3744 (parallel [(set (match_dup 2)
3745 (ashiftrt:SI (match_dup 2) (const_int 31)))
3746 (clobber (reg:CC FLAGS_REG))])
3747 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3748 "REGNO (operands[1]) != REGNO (operands[2])
3749 && peep2_reg_dead_p (2, operands[1])
3750 && peep2_reg_dead_p (4, operands[2])
3751 && !reg_mentioned_p (operands[2], operands[3])"
3752 [(set (match_dup 0) (match_dup 1))
3753 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3754 (clobber (reg:CC FLAGS_REG))])
3755 (set (match_dup 3) (match_dup 1))])
3756
3757 (define_peephole2
3758 [(set (match_operand:SI 0 "memory_operand")
3759 (match_operand:SI 1 "register_operand"))
3760 (parallel [(set (match_operand:SI 2 "register_operand")
3761 (ashiftrt:SI (match_dup 1) (const_int 31)))
3762 (clobber (reg:CC FLAGS_REG))])
3763 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3764 "/* cltd is shorter than sarl $31, %eax */
3765 !optimize_function_for_size_p (cfun)
3766 && true_regnum (operands[1]) == AX_REG
3767 && true_regnum (operands[2]) == DX_REG
3768 && peep2_reg_dead_p (2, operands[1])
3769 && peep2_reg_dead_p (3, operands[2])
3770 && !reg_mentioned_p (operands[2], operands[3])"
3771 [(set (match_dup 0) (match_dup 1))
3772 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3773 (clobber (reg:CC FLAGS_REG))])
3774 (set (match_dup 3) (match_dup 1))])
3775
3776 ;; Extend to register case. Optimize case where source and destination
3777 ;; registers match and cases where we can use cltd.
3778 (define_split
3779 [(set (match_operand:DI 0 "register_operand")
3780 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3781 (clobber (reg:CC FLAGS_REG))
3782 (clobber (match_scratch:SI 2))]
3783 "reload_completed"
3784 [(const_int 0)]
3785 {
3786 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3787
3788 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3789 emit_move_insn (operands[3], operands[1]);
3790
3791 /* Generate a cltd if possible and doing so it profitable. */
3792 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3793 && true_regnum (operands[3]) == AX_REG
3794 && true_regnum (operands[4]) == DX_REG)
3795 {
3796 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3797 DONE;
3798 }
3799
3800 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3801 emit_move_insn (operands[4], operands[1]);
3802
3803 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3804 DONE;
3805 })
3806
3807 (define_insn "extend<mode>di2"
3808 [(set (match_operand:DI 0 "register_operand" "=r")
3809 (sign_extend:DI
3810 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3811 "TARGET_64BIT"
3812 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "imovx")
3814 (set_attr "mode" "DI")])
3815
3816 (define_insn "extendhisi2"
3817 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3818 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3819 ""
3820 {
3821 switch (get_attr_prefix_0f (insn))
3822 {
3823 case 0:
3824 return "{cwtl|cwde}";
3825 default:
3826 return "movs{wl|x}\t{%1, %0|%0, %1}";
3827 }
3828 }
3829 [(set_attr "type" "imovx")
3830 (set_attr "mode" "SI")
3831 (set (attr "prefix_0f")
3832 ;; movsx is short decodable while cwtl is vector decoded.
3833 (if_then_else (and (eq_attr "cpu" "!k6")
3834 (eq_attr "alternative" "0"))
3835 (const_string "0")
3836 (const_string "1")))
3837 (set (attr "modrm")
3838 (if_then_else (eq_attr "prefix_0f" "0")
3839 (const_string "0")
3840 (const_string "1")))])
3841
3842 (define_insn "*extendhisi2_zext"
3843 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3844 (zero_extend:DI
3845 (sign_extend:SI
3846 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3847 "TARGET_64BIT"
3848 {
3849 switch (get_attr_prefix_0f (insn))
3850 {
3851 case 0:
3852 return "{cwtl|cwde}";
3853 default:
3854 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3855 }
3856 }
3857 [(set_attr "type" "imovx")
3858 (set_attr "mode" "SI")
3859 (set (attr "prefix_0f")
3860 ;; movsx is short decodable while cwtl is vector decoded.
3861 (if_then_else (and (eq_attr "cpu" "!k6")
3862 (eq_attr "alternative" "0"))
3863 (const_string "0")
3864 (const_string "1")))
3865 (set (attr "modrm")
3866 (if_then_else (eq_attr "prefix_0f" "0")
3867 (const_string "0")
3868 (const_string "1")))])
3869
3870 (define_insn "extendqisi2"
3871 [(set (match_operand:SI 0 "register_operand" "=r")
3872 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3873 ""
3874 "movs{bl|x}\t{%1, %0|%0, %1}"
3875 [(set_attr "type" "imovx")
3876 (set_attr "mode" "SI")])
3877
3878 (define_insn "*extendqisi2_zext"
3879 [(set (match_operand:DI 0 "register_operand" "=r")
3880 (zero_extend:DI
3881 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3882 "TARGET_64BIT"
3883 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3884 [(set_attr "type" "imovx")
3885 (set_attr "mode" "SI")])
3886
3887 (define_insn "extendqihi2"
3888 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3889 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3890 ""
3891 {
3892 switch (get_attr_prefix_0f (insn))
3893 {
3894 case 0:
3895 return "{cbtw|cbw}";
3896 default:
3897 return "movs{bw|x}\t{%1, %0|%0, %1}";
3898 }
3899 }
3900 [(set_attr "type" "imovx")
3901 (set_attr "mode" "HI")
3902 (set (attr "prefix_0f")
3903 ;; movsx is short decodable while cwtl is vector decoded.
3904 (if_then_else (and (eq_attr "cpu" "!k6")
3905 (eq_attr "alternative" "0"))
3906 (const_string "0")
3907 (const_string "1")))
3908 (set (attr "modrm")
3909 (if_then_else (eq_attr "prefix_0f" "0")
3910 (const_string "0")
3911 (const_string "1")))])
3912 \f
3913 ;; Conversions between float and double.
3914
3915 ;; These are all no-ops in the model used for the 80387.
3916 ;; So just emit moves.
3917
3918 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3919 (define_split
3920 [(set (match_operand:DF 0 "push_operand")
3921 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3922 "reload_completed"
3923 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3924 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3925
3926 (define_split
3927 [(set (match_operand:XF 0 "push_operand")
3928 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3929 "reload_completed"
3930 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3931 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3932 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3933
3934 (define_expand "extendsfdf2"
3935 [(set (match_operand:DF 0 "nonimmediate_operand")
3936 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3937 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3938 {
3939 /* ??? Needed for compress_float_constant since all fp constants
3940 are TARGET_LEGITIMATE_CONSTANT_P. */
3941 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3942 {
3943 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3944 && standard_80387_constant_p (operands[1]) > 0)
3945 {
3946 operands[1] = simplify_const_unary_operation
3947 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3948 emit_move_insn_1 (operands[0], operands[1]);
3949 DONE;
3950 }
3951 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3952 }
3953 })
3954
3955 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3956 cvtss2sd:
3957 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3958 cvtps2pd xmm2,xmm1
3959 We do the conversion post reload to avoid producing of 128bit spills
3960 that might lead to ICE on 32bit target. The sequence unlikely combine
3961 anyway. */
3962 (define_split
3963 [(set (match_operand:DF 0 "register_operand")
3964 (float_extend:DF
3965 (match_operand:SF 1 "nonimmediate_operand")))]
3966 "TARGET_USE_VECTOR_FP_CONVERTS
3967 && optimize_insn_for_speed_p ()
3968 && reload_completed && SSE_REG_P (operands[0])"
3969 [(set (match_dup 2)
3970 (float_extend:V2DF
3971 (vec_select:V2SF
3972 (match_dup 3)
3973 (parallel [(const_int 0) (const_int 1)]))))]
3974 {
3975 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3976 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3977 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3978 Try to avoid move when unpacking can be done in source. */
3979 if (REG_P (operands[1]))
3980 {
3981 /* If it is unsafe to overwrite upper half of source, we need
3982 to move to destination and unpack there. */
3983 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3984 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3985 && true_regnum (operands[0]) != true_regnum (operands[1]))
3986 {
3987 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3988 emit_move_insn (tmp, operands[1]);
3989 }
3990 else
3991 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3992 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3993 operands[3]));
3994 }
3995 else
3996 emit_insn (gen_vec_setv4sf_0 (operands[3],
3997 CONST0_RTX (V4SFmode), operands[1]));
3998 })
3999
4000 ;; It's more profitable to split and then extend in the same register.
4001 (define_peephole2
4002 [(set (match_operand:DF 0 "register_operand")
4003 (float_extend:DF
4004 (match_operand:SF 1 "memory_operand")))]
4005 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4006 && optimize_insn_for_speed_p ()
4007 && SSE_REG_P (operands[0])"
4008 [(set (match_dup 2) (match_dup 1))
4009 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4010 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4011
4012 (define_insn "*extendsfdf2_mixed"
4013 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4014 (float_extend:DF
4015 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4016 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4017 {
4018 switch (which_alternative)
4019 {
4020 case 0:
4021 case 1:
4022 return output_387_reg_move (insn, operands);
4023
4024 case 2:
4025 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4026
4027 default:
4028 gcc_unreachable ();
4029 }
4030 }
4031 [(set_attr "type" "fmov,fmov,ssecvt")
4032 (set_attr "prefix" "orig,orig,maybe_vex")
4033 (set_attr "mode" "SF,XF,DF")])
4034
4035 (define_insn "*extendsfdf2_sse"
4036 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4037 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4038 "TARGET_SSE2 && TARGET_SSE_MATH"
4039 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4040 [(set_attr "type" "ssecvt")
4041 (set_attr "prefix" "maybe_vex")
4042 (set_attr "mode" "DF")])
4043
4044 (define_insn "*extendsfdf2_i387"
4045 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4046 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4047 "TARGET_80387"
4048 "* return output_387_reg_move (insn, operands);"
4049 [(set_attr "type" "fmov")
4050 (set_attr "mode" "SF,XF")])
4051
4052 (define_expand "extend<mode>xf2"
4053 [(set (match_operand:XF 0 "nonimmediate_operand")
4054 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4055 "TARGET_80387"
4056 {
4057 /* ??? Needed for compress_float_constant since all fp constants
4058 are TARGET_LEGITIMATE_CONSTANT_P. */
4059 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4060 {
4061 if (standard_80387_constant_p (operands[1]) > 0)
4062 {
4063 operands[1] = simplify_const_unary_operation
4064 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4065 emit_move_insn_1 (operands[0], operands[1]);
4066 DONE;
4067 }
4068 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4069 }
4070 })
4071
4072 (define_insn "*extend<mode>xf2_i387"
4073 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4074 (float_extend:XF
4075 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4076 "TARGET_80387"
4077 "* return output_387_reg_move (insn, operands);"
4078 [(set_attr "type" "fmov")
4079 (set_attr "mode" "<MODE>,XF")])
4080
4081 ;; %%% This seems bad bad news.
4082 ;; This cannot output into an f-reg because there is no way to be sure
4083 ;; of truncating in that case. Otherwise this is just like a simple move
4084 ;; insn. So we pretend we can output to a reg in order to get better
4085 ;; register preferencing, but we really use a stack slot.
4086
4087 ;; Conversion from DFmode to SFmode.
4088
4089 (define_expand "truncdfsf2"
4090 [(set (match_operand:SF 0 "nonimmediate_operand")
4091 (float_truncate:SF
4092 (match_operand:DF 1 "nonimmediate_operand")))]
4093 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4094 {
4095 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4096 ;
4097 else if (flag_unsafe_math_optimizations)
4098 ;
4099 else
4100 {
4101 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4102 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4103 DONE;
4104 }
4105 })
4106
4107 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4108 cvtsd2ss:
4109 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4110 cvtpd2ps xmm2,xmm1
4111 We do the conversion post reload to avoid producing of 128bit spills
4112 that might lead to ICE on 32bit target. The sequence unlikely combine
4113 anyway. */
4114 (define_split
4115 [(set (match_operand:SF 0 "register_operand")
4116 (float_truncate:SF
4117 (match_operand:DF 1 "nonimmediate_operand")))]
4118 "TARGET_USE_VECTOR_FP_CONVERTS
4119 && optimize_insn_for_speed_p ()
4120 && reload_completed && SSE_REG_P (operands[0])"
4121 [(set (match_dup 2)
4122 (vec_concat:V4SF
4123 (float_truncate:V2SF
4124 (match_dup 4))
4125 (match_dup 3)))]
4126 {
4127 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4128 operands[3] = CONST0_RTX (V2SFmode);
4129 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4130 /* Use movsd for loading from memory, unpcklpd for registers.
4131 Try to avoid move when unpacking can be done in source, or SSE3
4132 movddup is available. */
4133 if (REG_P (operands[1]))
4134 {
4135 if (!TARGET_SSE3
4136 && true_regnum (operands[0]) != true_regnum (operands[1])
4137 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4138 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4139 {
4140 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4141 emit_move_insn (tmp, operands[1]);
4142 operands[1] = tmp;
4143 }
4144 else if (!TARGET_SSE3)
4145 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4146 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4147 }
4148 else
4149 emit_insn (gen_sse2_loadlpd (operands[4],
4150 CONST0_RTX (V2DFmode), operands[1]));
4151 })
4152
4153 ;; It's more profitable to split and then extend in the same register.
4154 (define_peephole2
4155 [(set (match_operand:SF 0 "register_operand")
4156 (float_truncate:SF
4157 (match_operand:DF 1 "memory_operand")))]
4158 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4159 && optimize_insn_for_speed_p ()
4160 && SSE_REG_P (operands[0])"
4161 [(set (match_dup 2) (match_dup 1))
4162 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4163 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4164
4165 (define_expand "truncdfsf2_with_temp"
4166 [(parallel [(set (match_operand:SF 0)
4167 (float_truncate:SF (match_operand:DF 1)))
4168 (clobber (match_operand:SF 2))])])
4169
4170 (define_insn "*truncdfsf_fast_mixed"
4171 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4172 (float_truncate:SF
4173 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4174 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4175 {
4176 switch (which_alternative)
4177 {
4178 case 0:
4179 return output_387_reg_move (insn, operands);
4180 case 1:
4181 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4182 default:
4183 gcc_unreachable ();
4184 }
4185 }
4186 [(set_attr "type" "fmov,ssecvt")
4187 (set_attr "prefix" "orig,maybe_vex")
4188 (set_attr "mode" "SF")])
4189
4190 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4191 ;; because nothing we do here is unsafe.
4192 (define_insn "*truncdfsf_fast_sse"
4193 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4194 (float_truncate:SF
4195 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4196 "TARGET_SSE2 && TARGET_SSE_MATH"
4197 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4198 [(set_attr "type" "ssecvt")
4199 (set_attr "prefix" "maybe_vex")
4200 (set_attr "mode" "SF")])
4201
4202 (define_insn "*truncdfsf_fast_i387"
4203 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4204 (float_truncate:SF
4205 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4206 "TARGET_80387 && flag_unsafe_math_optimizations"
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "SF")])
4210
4211 (define_insn "*truncdfsf_mixed"
4212 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4213 (float_truncate:SF
4214 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4215 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4216 "TARGET_MIX_SSE_I387"
4217 {
4218 switch (which_alternative)
4219 {
4220 case 0:
4221 return output_387_reg_move (insn, operands);
4222 case 1:
4223 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4224
4225 default:
4226 return "#";
4227 }
4228 }
4229 [(set_attr "isa" "*,sse2,*,*,*")
4230 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4231 (set_attr "unit" "*,*,i387,i387,i387")
4232 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4233 (set_attr "mode" "SF")])
4234
4235 (define_insn "*truncdfsf_i387"
4236 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4237 (float_truncate:SF
4238 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4239 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4240 "TARGET_80387"
4241 {
4242 switch (which_alternative)
4243 {
4244 case 0:
4245 return output_387_reg_move (insn, operands);
4246
4247 default:
4248 return "#";
4249 }
4250 }
4251 [(set_attr "type" "fmov,multi,multi,multi")
4252 (set_attr "unit" "*,i387,i387,i387")
4253 (set_attr "mode" "SF")])
4254
4255 (define_insn "*truncdfsf2_i387_1"
4256 [(set (match_operand:SF 0 "memory_operand" "=m")
4257 (float_truncate:SF
4258 (match_operand:DF 1 "register_operand" "f")))]
4259 "TARGET_80387
4260 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4261 && !TARGET_MIX_SSE_I387"
4262 "* return output_387_reg_move (insn, operands);"
4263 [(set_attr "type" "fmov")
4264 (set_attr "mode" "SF")])
4265
4266 (define_split
4267 [(set (match_operand:SF 0 "register_operand")
4268 (float_truncate:SF
4269 (match_operand:DF 1 "fp_register_operand")))
4270 (clobber (match_operand 2))]
4271 "reload_completed"
4272 [(set (match_dup 2) (match_dup 1))
4273 (set (match_dup 0) (match_dup 2))]
4274 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4275
4276 ;; Conversion from XFmode to {SF,DF}mode
4277
4278 (define_expand "truncxf<mode>2"
4279 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4280 (float_truncate:MODEF
4281 (match_operand:XF 1 "register_operand")))
4282 (clobber (match_dup 2))])]
4283 "TARGET_80387"
4284 {
4285 if (flag_unsafe_math_optimizations)
4286 {
4287 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4288 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4289 if (reg != operands[0])
4290 emit_move_insn (operands[0], reg);
4291 DONE;
4292 }
4293 else
4294 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4295 })
4296
4297 (define_insn "*truncxfsf2_mixed"
4298 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4299 (float_truncate:SF
4300 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4301 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4302 "TARGET_80387"
4303 {
4304 gcc_assert (!which_alternative);
4305 return output_387_reg_move (insn, operands);
4306 }
4307 [(set_attr "type" "fmov,multi,multi,multi")
4308 (set_attr "unit" "*,i387,i387,i387")
4309 (set_attr "mode" "SF")])
4310
4311 (define_insn "*truncxfdf2_mixed"
4312 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4313 (float_truncate:DF
4314 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4315 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4316 "TARGET_80387"
4317 {
4318 gcc_assert (!which_alternative);
4319 return output_387_reg_move (insn, operands);
4320 }
4321 [(set_attr "isa" "*,*,sse2,*")
4322 (set_attr "type" "fmov,multi,multi,multi")
4323 (set_attr "unit" "*,i387,i387,i387")
4324 (set_attr "mode" "DF")])
4325
4326 (define_insn "truncxf<mode>2_i387_noop"
4327 [(set (match_operand:MODEF 0 "register_operand" "=f")
4328 (float_truncate:MODEF
4329 (match_operand:XF 1 "register_operand" "f")))]
4330 "TARGET_80387 && flag_unsafe_math_optimizations"
4331 "* return output_387_reg_move (insn, operands);"
4332 [(set_attr "type" "fmov")
4333 (set_attr "mode" "<MODE>")])
4334
4335 (define_insn "*truncxf<mode>2_i387"
4336 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4337 (float_truncate:MODEF
4338 (match_operand:XF 1 "register_operand" "f")))]
4339 "TARGET_80387"
4340 "* return output_387_reg_move (insn, operands);"
4341 [(set_attr "type" "fmov")
4342 (set_attr "mode" "<MODE>")])
4343
4344 (define_split
4345 [(set (match_operand:MODEF 0 "register_operand")
4346 (float_truncate:MODEF
4347 (match_operand:XF 1 "register_operand")))
4348 (clobber (match_operand:MODEF 2 "memory_operand"))]
4349 "TARGET_80387 && reload_completed"
4350 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4351 (set (match_dup 0) (match_dup 2))])
4352
4353 (define_split
4354 [(set (match_operand:MODEF 0 "memory_operand")
4355 (float_truncate:MODEF
4356 (match_operand:XF 1 "register_operand")))
4357 (clobber (match_operand:MODEF 2 "memory_operand"))]
4358 "TARGET_80387"
4359 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4360 \f
4361 ;; Signed conversion to DImode.
4362
4363 (define_expand "fix_truncxfdi2"
4364 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4365 (fix:DI (match_operand:XF 1 "register_operand")))
4366 (clobber (reg:CC FLAGS_REG))])]
4367 "TARGET_80387"
4368 {
4369 if (TARGET_FISTTP)
4370 {
4371 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4372 DONE;
4373 }
4374 })
4375
4376 (define_expand "fix_trunc<mode>di2"
4377 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4378 (fix:DI (match_operand:MODEF 1 "register_operand")))
4379 (clobber (reg:CC FLAGS_REG))])]
4380 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4381 {
4382 if (TARGET_FISTTP
4383 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4384 {
4385 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4386 DONE;
4387 }
4388 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4389 {
4390 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4391 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4392 if (out != operands[0])
4393 emit_move_insn (operands[0], out);
4394 DONE;
4395 }
4396 })
4397
4398 ;; Signed conversion to SImode.
4399
4400 (define_expand "fix_truncxfsi2"
4401 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4402 (fix:SI (match_operand:XF 1 "register_operand")))
4403 (clobber (reg:CC FLAGS_REG))])]
4404 "TARGET_80387"
4405 {
4406 if (TARGET_FISTTP)
4407 {
4408 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4409 DONE;
4410 }
4411 })
4412
4413 (define_expand "fix_trunc<mode>si2"
4414 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4415 (fix:SI (match_operand:MODEF 1 "register_operand")))
4416 (clobber (reg:CC FLAGS_REG))])]
4417 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4418 {
4419 if (TARGET_FISTTP
4420 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4421 {
4422 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4423 DONE;
4424 }
4425 if (SSE_FLOAT_MODE_P (<MODE>mode))
4426 {
4427 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4428 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4429 if (out != operands[0])
4430 emit_move_insn (operands[0], out);
4431 DONE;
4432 }
4433 })
4434
4435 ;; Signed conversion to HImode.
4436
4437 (define_expand "fix_trunc<mode>hi2"
4438 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4439 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4440 (clobber (reg:CC FLAGS_REG))])]
4441 "TARGET_80387
4442 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4443 {
4444 if (TARGET_FISTTP)
4445 {
4446 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4447 DONE;
4448 }
4449 })
4450
4451 ;; Unsigned conversion to SImode.
4452
4453 (define_expand "fixuns_trunc<mode>si2"
4454 [(parallel
4455 [(set (match_operand:SI 0 "register_operand")
4456 (unsigned_fix:SI
4457 (match_operand:MODEF 1 "nonimmediate_operand")))
4458 (use (match_dup 2))
4459 (clobber (match_scratch:<ssevecmode> 3))
4460 (clobber (match_scratch:<ssevecmode> 4))])]
4461 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4462 {
4463 machine_mode mode = <MODE>mode;
4464 machine_mode vecmode = <ssevecmode>mode;
4465 REAL_VALUE_TYPE TWO31r;
4466 rtx two31;
4467
4468 if (optimize_insn_for_size_p ())
4469 FAIL;
4470
4471 real_ldexp (&TWO31r, &dconst1, 31);
4472 two31 = const_double_from_real_value (TWO31r, mode);
4473 two31 = ix86_build_const_vector (vecmode, true, two31);
4474 operands[2] = force_reg (vecmode, two31);
4475 })
4476
4477 (define_insn_and_split "*fixuns_trunc<mode>_1"
4478 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4479 (unsigned_fix:SI
4480 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4481 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4482 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4483 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4484 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4485 && optimize_function_for_speed_p (cfun)"
4486 "#"
4487 "&& reload_completed"
4488 [(const_int 0)]
4489 {
4490 ix86_split_convert_uns_si_sse (operands);
4491 DONE;
4492 })
4493
4494 ;; Unsigned conversion to HImode.
4495 ;; Without these patterns, we'll try the unsigned SI conversion which
4496 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4497
4498 (define_expand "fixuns_trunc<mode>hi2"
4499 [(set (match_dup 2)
4500 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4501 (set (match_operand:HI 0 "nonimmediate_operand")
4502 (subreg:HI (match_dup 2) 0))]
4503 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4504 "operands[2] = gen_reg_rtx (SImode);")
4505
4506 ;; When SSE is available, it is always faster to use it!
4507 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4508 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4509 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4510 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4511 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4512 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4513 [(set_attr "type" "sseicvt")
4514 (set_attr "prefix" "maybe_vex")
4515 (set (attr "prefix_rex")
4516 (if_then_else
4517 (match_test "<SWI48:MODE>mode == DImode")
4518 (const_string "1")
4519 (const_string "*")))
4520 (set_attr "mode" "<MODEF:MODE>")
4521 (set_attr "athlon_decode" "double,vector")
4522 (set_attr "amdfam10_decode" "double,double")
4523 (set_attr "bdver1_decode" "double,double")])
4524
4525 ;; Avoid vector decoded forms of the instruction.
4526 (define_peephole2
4527 [(match_scratch:MODEF 2 "x")
4528 (set (match_operand:SWI48 0 "register_operand")
4529 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4530 "TARGET_AVOID_VECTOR_DECODE
4531 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4532 && optimize_insn_for_speed_p ()"
4533 [(set (match_dup 2) (match_dup 1))
4534 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4535
4536 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4537 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4538 (fix:SWI248x (match_operand 1 "register_operand")))]
4539 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4540 && TARGET_FISTTP
4541 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4542 && (TARGET_64BIT || <MODE>mode != DImode))
4543 && TARGET_SSE_MATH)
4544 && can_create_pseudo_p ()"
4545 "#"
4546 "&& 1"
4547 [(const_int 0)]
4548 {
4549 if (memory_operand (operands[0], VOIDmode))
4550 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4551 else
4552 {
4553 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4554 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4555 operands[1],
4556 operands[2]));
4557 }
4558 DONE;
4559 }
4560 [(set_attr "type" "fisttp")
4561 (set_attr "mode" "<MODE>")])
4562
4563 (define_insn "fix_trunc<mode>_i387_fisttp"
4564 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4565 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4566 (clobber (match_scratch:XF 2 "=&1f"))]
4567 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && TARGET_FISTTP
4569 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && (TARGET_64BIT || <MODE>mode != DImode))
4571 && TARGET_SSE_MATH)"
4572 "* return output_fix_trunc (insn, operands, true);"
4573 [(set_attr "type" "fisttp")
4574 (set_attr "mode" "<MODE>")])
4575
4576 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4577 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4578 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4579 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4580 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4581 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4582 && TARGET_FISTTP
4583 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && (TARGET_64BIT || <MODE>mode != DImode))
4585 && TARGET_SSE_MATH)"
4586 "#"
4587 [(set_attr "type" "fisttp")
4588 (set_attr "mode" "<MODE>")])
4589
4590 (define_split
4591 [(set (match_operand:SWI248x 0 "register_operand")
4592 (fix:SWI248x (match_operand 1 "register_operand")))
4593 (clobber (match_operand:SWI248x 2 "memory_operand"))
4594 (clobber (match_scratch 3))]
4595 "reload_completed"
4596 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4597 (clobber (match_dup 3))])
4598 (set (match_dup 0) (match_dup 2))])
4599
4600 (define_split
4601 [(set (match_operand:SWI248x 0 "memory_operand")
4602 (fix:SWI248x (match_operand 1 "register_operand")))
4603 (clobber (match_operand:SWI248x 2 "memory_operand"))
4604 (clobber (match_scratch 3))]
4605 "reload_completed"
4606 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4607 (clobber (match_dup 3))])])
4608
4609 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4610 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4611 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4612 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4613 ;; function in i386.c.
4614 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4615 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4616 (fix:SWI248x (match_operand 1 "register_operand")))
4617 (clobber (reg:CC FLAGS_REG))]
4618 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4619 && !TARGET_FISTTP
4620 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4621 && (TARGET_64BIT || <MODE>mode != DImode))
4622 && can_create_pseudo_p ()"
4623 "#"
4624 "&& 1"
4625 [(const_int 0)]
4626 {
4627 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4628
4629 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4630 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4631 if (memory_operand (operands[0], VOIDmode))
4632 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4633 operands[2], operands[3]));
4634 else
4635 {
4636 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4637 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4638 operands[2], operands[3],
4639 operands[4]));
4640 }
4641 DONE;
4642 }
4643 [(set_attr "type" "fistp")
4644 (set_attr "i387_cw" "trunc")
4645 (set_attr "mode" "<MODE>")])
4646
4647 (define_insn "fix_truncdi_i387"
4648 [(set (match_operand:DI 0 "memory_operand" "=m")
4649 (fix:DI (match_operand 1 "register_operand" "f")))
4650 (use (match_operand:HI 2 "memory_operand" "m"))
4651 (use (match_operand:HI 3 "memory_operand" "m"))
4652 (clobber (match_scratch:XF 4 "=&1f"))]
4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654 && !TARGET_FISTTP
4655 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4656 "* return output_fix_trunc (insn, operands, false);"
4657 [(set_attr "type" "fistp")
4658 (set_attr "i387_cw" "trunc")
4659 (set_attr "mode" "DI")])
4660
4661 (define_insn "fix_truncdi_i387_with_temp"
4662 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4663 (fix:DI (match_operand 1 "register_operand" "f,f")))
4664 (use (match_operand:HI 2 "memory_operand" "m,m"))
4665 (use (match_operand:HI 3 "memory_operand" "m,m"))
4666 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4667 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4668 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && !TARGET_FISTTP
4670 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4671 "#"
4672 [(set_attr "type" "fistp")
4673 (set_attr "i387_cw" "trunc")
4674 (set_attr "mode" "DI")])
4675
4676 (define_split
4677 [(set (match_operand:DI 0 "register_operand")
4678 (fix:DI (match_operand 1 "register_operand")))
4679 (use (match_operand:HI 2 "memory_operand"))
4680 (use (match_operand:HI 3 "memory_operand"))
4681 (clobber (match_operand:DI 4 "memory_operand"))
4682 (clobber (match_scratch 5))]
4683 "reload_completed"
4684 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4685 (use (match_dup 2))
4686 (use (match_dup 3))
4687 (clobber (match_dup 5))])
4688 (set (match_dup 0) (match_dup 4))])
4689
4690 (define_split
4691 [(set (match_operand:DI 0 "memory_operand")
4692 (fix:DI (match_operand 1 "register_operand")))
4693 (use (match_operand:HI 2 "memory_operand"))
4694 (use (match_operand:HI 3 "memory_operand"))
4695 (clobber (match_operand:DI 4 "memory_operand"))
4696 (clobber (match_scratch 5))]
4697 "reload_completed"
4698 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4699 (use (match_dup 2))
4700 (use (match_dup 3))
4701 (clobber (match_dup 5))])])
4702
4703 (define_insn "fix_trunc<mode>_i387"
4704 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4705 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4706 (use (match_operand:HI 2 "memory_operand" "m"))
4707 (use (match_operand:HI 3 "memory_operand" "m"))]
4708 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4709 && !TARGET_FISTTP
4710 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4711 "* return output_fix_trunc (insn, operands, false);"
4712 [(set_attr "type" "fistp")
4713 (set_attr "i387_cw" "trunc")
4714 (set_attr "mode" "<MODE>")])
4715
4716 (define_insn "fix_trunc<mode>_i387_with_temp"
4717 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4718 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4719 (use (match_operand:HI 2 "memory_operand" "m,m"))
4720 (use (match_operand:HI 3 "memory_operand" "m,m"))
4721 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4722 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4723 && !TARGET_FISTTP
4724 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4725 "#"
4726 [(set_attr "type" "fistp")
4727 (set_attr "i387_cw" "trunc")
4728 (set_attr "mode" "<MODE>")])
4729
4730 (define_split
4731 [(set (match_operand:SWI24 0 "register_operand")
4732 (fix:SWI24 (match_operand 1 "register_operand")))
4733 (use (match_operand:HI 2 "memory_operand"))
4734 (use (match_operand:HI 3 "memory_operand"))
4735 (clobber (match_operand:SWI24 4 "memory_operand"))]
4736 "reload_completed"
4737 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4738 (use (match_dup 2))
4739 (use (match_dup 3))])
4740 (set (match_dup 0) (match_dup 4))])
4741
4742 (define_split
4743 [(set (match_operand:SWI24 0 "memory_operand")
4744 (fix:SWI24 (match_operand 1 "register_operand")))
4745 (use (match_operand:HI 2 "memory_operand"))
4746 (use (match_operand:HI 3 "memory_operand"))
4747 (clobber (match_operand:SWI24 4 "memory_operand"))]
4748 "reload_completed"
4749 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4750 (use (match_dup 2))
4751 (use (match_dup 3))])])
4752
4753 (define_insn "x86_fnstcw_1"
4754 [(set (match_operand:HI 0 "memory_operand" "=m")
4755 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4756 "TARGET_80387"
4757 "fnstcw\t%0"
4758 [(set (attr "length")
4759 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4760 (set_attr "mode" "HI")
4761 (set_attr "unit" "i387")
4762 (set_attr "bdver1_decode" "vector")])
4763
4764 (define_insn "x86_fldcw_1"
4765 [(set (reg:HI FPCR_REG)
4766 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4767 "TARGET_80387"
4768 "fldcw\t%0"
4769 [(set (attr "length")
4770 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4771 (set_attr "mode" "HI")
4772 (set_attr "unit" "i387")
4773 (set_attr "athlon_decode" "vector")
4774 (set_attr "amdfam10_decode" "vector")
4775 (set_attr "bdver1_decode" "vector")])
4776 \f
4777 ;; Conversion between fixed point and floating point.
4778
4779 ;; Even though we only accept memory inputs, the backend _really_
4780 ;; wants to be able to do this between registers. Thankfully, LRA
4781 ;; will fix this up for us during register allocation.
4782
4783 (define_insn "floathi<mode>2"
4784 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4785 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4786 "TARGET_80387
4787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4788 || TARGET_MIX_SSE_I387)"
4789 "fild%Z1\t%1"
4790 [(set_attr "type" "fmov")
4791 (set_attr "mode" "<MODE>")
4792 (set_attr "fp_int_src" "true")])
4793
4794 (define_insn "float<SWI48x:mode>xf2"
4795 [(set (match_operand:XF 0 "register_operand" "=f")
4796 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4797 "TARGET_80387"
4798 "fild%Z1\t%1"
4799 [(set_attr "type" "fmov")
4800 (set_attr "mode" "XF")
4801 (set_attr "fp_int_src" "true")])
4802
4803 (define_expand "float<SWI48:mode><MODEF:mode>2"
4804 [(set (match_operand:MODEF 0 "register_operand")
4805 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4806 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4807 {
4808 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4809 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4810 {
4811 rtx reg = gen_reg_rtx (XFmode);
4812 rtx (*insn)(rtx, rtx);
4813
4814 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4815
4816 if (<MODEF:MODE>mode == SFmode)
4817 insn = gen_truncxfsf2;
4818 else if (<MODEF:MODE>mode == DFmode)
4819 insn = gen_truncxfdf2;
4820 else
4821 gcc_unreachable ();
4822
4823 emit_insn (insn (operands[0], reg));
4824 DONE;
4825 }
4826 })
4827
4828 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4829 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4830 (float:MODEF
4831 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4832 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4833 "@
4834 fild%Z1\t%1
4835 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4836 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4837 [(set_attr "type" "fmov,sseicvt,sseicvt")
4838 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4839 (set_attr "mode" "<MODEF:MODE>")
4840 (set (attr "prefix_rex")
4841 (if_then_else
4842 (and (eq_attr "prefix" "maybe_vex")
4843 (match_test "<SWI48:MODE>mode == DImode"))
4844 (const_string "1")
4845 (const_string "*")))
4846 (set_attr "unit" "i387,*,*")
4847 (set_attr "athlon_decode" "*,double,direct")
4848 (set_attr "amdfam10_decode" "*,vector,double")
4849 (set_attr "bdver1_decode" "*,double,direct")
4850 (set_attr "fp_int_src" "true")
4851 (set (attr "enabled")
4852 (cond [(eq_attr "alternative" "0")
4853 (symbol_ref "TARGET_MIX_SSE_I387
4854 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4855 <SWI48:MODE>mode)")
4856 ]
4857 (symbol_ref "true")))
4858 (set (attr "preferred_for_speed")
4859 (cond [(eq_attr "alternative" "1")
4860 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4861 (symbol_ref "true")))
4862 ])
4863
4864 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4865 [(set (match_operand:MODEF 0 "register_operand" "=f")
4866 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4867 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4868 "fild%Z1\t%1"
4869 [(set_attr "type" "fmov")
4870 (set_attr "mode" "<MODEF:MODE>")
4871 (set_attr "fp_int_src" "true")])
4872
4873 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4874 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4875 ;; alternative in sse2_loadld.
4876 (define_split
4877 [(set (match_operand:MODEF 0 "register_operand")
4878 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4879 "TARGET_SSE2 && TARGET_SSE_MATH
4880 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4881 && reload_completed && SSE_REG_P (operands[0])
4882 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4883 [(const_int 0)]
4884 {
4885 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4886 <MODE>mode, 0);
4887 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4888
4889 emit_insn (gen_sse2_loadld (operands[4],
4890 CONST0_RTX (V4SImode), operands[1]));
4891
4892 if (<ssevecmode>mode == V4SFmode)
4893 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4894 else
4895 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4896 DONE;
4897 })
4898
4899 ;; Avoid partial SSE register dependency stalls
4900 (define_split
4901 [(set (match_operand:MODEF 0 "register_operand")
4902 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4903 "TARGET_SSE2 && TARGET_SSE_MATH
4904 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4905 && optimize_function_for_speed_p (cfun)
4906 && reload_completed && SSE_REG_P (operands[0])"
4907 [(const_int 0)]
4908 {
4909 const machine_mode vmode = <MODEF:ssevecmode>mode;
4910 const machine_mode mode = <MODEF:MODE>mode;
4911 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4912
4913 emit_move_insn (op0, CONST0_RTX (vmode));
4914
4915 t = gen_rtx_FLOAT (mode, operands[1]);
4916 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4917 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4918 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4919 DONE;
4920 })
4921
4922 ;; Break partial reg stall for cvtsd2ss.
4923
4924 (define_peephole2
4925 [(set (match_operand:SF 0 "register_operand")
4926 (float_truncate:SF
4927 (match_operand:DF 1 "nonimmediate_operand")))]
4928 "TARGET_SSE2 && TARGET_SSE_MATH
4929 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4930 && optimize_function_for_speed_p (cfun)
4931 && SSE_REG_P (operands[0])
4932 && (!SSE_REG_P (operands[1])
4933 || REGNO (operands[0]) != REGNO (operands[1]))"
4934 [(set (match_dup 0)
4935 (vec_merge:V4SF
4936 (vec_duplicate:V4SF
4937 (float_truncate:V2SF
4938 (match_dup 1)))
4939 (match_dup 0)
4940 (const_int 1)))]
4941 {
4942 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4943 SFmode, 0);
4944 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4945 DFmode, 0);
4946 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4947 })
4948
4949 ;; Break partial reg stall for cvtss2sd.
4950
4951 (define_peephole2
4952 [(set (match_operand:DF 0 "register_operand")
4953 (float_extend:DF
4954 (match_operand:SF 1 "nonimmediate_operand")))]
4955 "TARGET_SSE2 && TARGET_SSE_MATH
4956 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4957 && optimize_function_for_speed_p (cfun)
4958 && SSE_REG_P (operands[0])
4959 && (!SSE_REG_P (operands[1])
4960 || REGNO (operands[0]) != REGNO (operands[1]))"
4961 [(set (match_dup 0)
4962 (vec_merge:V2DF
4963 (float_extend:V2DF
4964 (vec_select:V2SF
4965 (match_dup 1)
4966 (parallel [(const_int 0) (const_int 1)])))
4967 (match_dup 0)
4968 (const_int 1)))]
4969 {
4970 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4971 DFmode, 0);
4972 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4973 SFmode, 0);
4974 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4975 })
4976
4977 ;; Avoid store forwarding (partial memory) stall penalty
4978 ;; by passing DImode value through XMM registers. */
4979
4980 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4981 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4982 (float:X87MODEF
4983 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4984 (clobber (match_scratch:V4SI 3 "=X,x"))
4985 (clobber (match_scratch:V4SI 4 "=X,x"))
4986 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4987 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4988 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4989 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4990 "#"
4991 [(set_attr "type" "multi")
4992 (set_attr "mode" "<X87MODEF:MODE>")
4993 (set_attr "unit" "i387")
4994 (set_attr "fp_int_src" "true")])
4995
4996 (define_split
4997 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4998 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4999 (clobber (match_scratch:V4SI 3))
5000 (clobber (match_scratch:V4SI 4))
5001 (clobber (match_operand:DI 2 "memory_operand"))]
5002 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5003 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5004 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5005 && reload_completed"
5006 [(set (match_dup 2) (match_dup 3))
5007 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5008 {
5009 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5010 Assemble the 64-bit DImode value in an xmm register. */
5011 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5012 gen_rtx_SUBREG (SImode, operands[1], 0)));
5013 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5014 gen_rtx_SUBREG (SImode, operands[1], 4)));
5015 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5016 operands[4]));
5017
5018 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5019 })
5020
5021 (define_split
5022 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5023 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5024 (clobber (match_scratch:V4SI 3))
5025 (clobber (match_scratch:V4SI 4))
5026 (clobber (match_operand:DI 2 "memory_operand"))]
5027 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5028 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5029 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5030 && reload_completed"
5031 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5032
5033 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5034 [(set (match_operand:MODEF 0 "register_operand")
5035 (unsigned_float:MODEF
5036 (match_operand:SWI12 1 "nonimmediate_operand")))]
5037 "!TARGET_64BIT
5038 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5039 {
5040 operands[1] = convert_to_mode (SImode, operands[1], 1);
5041 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5042 DONE;
5043 })
5044
5045 ;; Avoid store forwarding (partial memory) stall penalty by extending
5046 ;; SImode value to DImode through XMM register instead of pushing two
5047 ;; SImode values to stack. Also note that fild loads from memory only.
5048
5049 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5050 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5051 (unsigned_float:X87MODEF
5052 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5053 (clobber (match_scratch:DI 3 "=x"))
5054 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5055 "!TARGET_64BIT
5056 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5057 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5058 "#"
5059 "&& reload_completed"
5060 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5061 (set (match_dup 2) (match_dup 3))
5062 (set (match_dup 0)
5063 (float:X87MODEF (match_dup 2)))]
5064 ""
5065 [(set_attr "type" "multi")
5066 (set_attr "mode" "<MODE>")])
5067
5068 (define_expand "floatunssi<mode>2"
5069 [(parallel
5070 [(set (match_operand:X87MODEF 0 "register_operand")
5071 (unsigned_float:X87MODEF
5072 (match_operand:SI 1 "nonimmediate_operand")))
5073 (clobber (match_scratch:DI 3))
5074 (clobber (match_dup 2))])]
5075 "!TARGET_64BIT
5076 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5077 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5078 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5079 {
5080 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5081 {
5082 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5083 DONE;
5084 }
5085 else
5086 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5087 })
5088
5089 (define_expand "floatunsdisf2"
5090 [(use (match_operand:SF 0 "register_operand"))
5091 (use (match_operand:DI 1 "nonimmediate_operand"))]
5092 "TARGET_64BIT && TARGET_SSE_MATH"
5093 "x86_emit_floatuns (operands); DONE;")
5094
5095 (define_expand "floatunsdidf2"
5096 [(use (match_operand:DF 0 "register_operand"))
5097 (use (match_operand:DI 1 "nonimmediate_operand"))]
5098 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5099 && TARGET_SSE2 && TARGET_SSE_MATH"
5100 {
5101 if (TARGET_64BIT)
5102 x86_emit_floatuns (operands);
5103 else
5104 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5105 DONE;
5106 })
5107 \f
5108 ;; Load effective address instructions
5109
5110 (define_insn_and_split "*lea<mode>"
5111 [(set (match_operand:SWI48 0 "register_operand" "=r")
5112 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5113 ""
5114 {
5115 if (SImode_address_operand (operands[1], VOIDmode))
5116 {
5117 gcc_assert (TARGET_64BIT);
5118 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5119 }
5120 else
5121 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5122 }
5123 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5124 [(const_int 0)]
5125 {
5126 machine_mode mode = <MODE>mode;
5127 rtx pat;
5128
5129 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5130 change operands[] array behind our back. */
5131 pat = PATTERN (curr_insn);
5132
5133 operands[0] = SET_DEST (pat);
5134 operands[1] = SET_SRC (pat);
5135
5136 /* Emit all operations in SImode for zero-extended addresses. */
5137 if (SImode_address_operand (operands[1], VOIDmode))
5138 mode = SImode;
5139
5140 ix86_split_lea_for_addr (curr_insn, operands, mode);
5141
5142 /* Zero-extend return register to DImode for zero-extended addresses. */
5143 if (mode != <MODE>mode)
5144 emit_insn (gen_zero_extendsidi2
5145 (operands[0], gen_lowpart (mode, operands[0])));
5146
5147 DONE;
5148 }
5149 [(set_attr "type" "lea")
5150 (set (attr "mode")
5151 (if_then_else
5152 (match_operand 1 "SImode_address_operand")
5153 (const_string "SI")
5154 (const_string "<MODE>")))])
5155 \f
5156 ;; Add instructions
5157
5158 (define_expand "add<mode>3"
5159 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5160 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5161 (match_operand:SDWIM 2 "<general_operand>")))]
5162 ""
5163 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5164
5165 (define_insn_and_split "*add<dwi>3_doubleword"
5166 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5167 (plus:<DWI>
5168 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5169 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5170 (clobber (reg:CC FLAGS_REG))]
5171 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5172 "#"
5173 "reload_completed"
5174 [(parallel [(set (reg:CC FLAGS_REG)
5175 (unspec:CC [(match_dup 1) (match_dup 2)]
5176 UNSPEC_ADD_CARRY))
5177 (set (match_dup 0)
5178 (plus:DWIH (match_dup 1) (match_dup 2)))])
5179 (parallel [(set (match_dup 3)
5180 (plus:DWIH
5181 (match_dup 4)
5182 (plus:DWIH
5183 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5184 (match_dup 5))))
5185 (clobber (reg:CC FLAGS_REG))])]
5186 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5187
5188 (define_insn "*add<mode>3_cc"
5189 [(set (reg:CC FLAGS_REG)
5190 (unspec:CC
5191 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5192 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5193 UNSPEC_ADD_CARRY))
5194 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5195 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5196 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5197 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5198 [(set_attr "type" "alu")
5199 (set_attr "mode" "<MODE>")])
5200
5201 (define_insn "addqi3_cc"
5202 [(set (reg:CC FLAGS_REG)
5203 (unspec:CC
5204 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5205 (match_operand:QI 2 "general_operand" "qn,qm")]
5206 UNSPEC_ADD_CARRY))
5207 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5208 (plus:QI (match_dup 1) (match_dup 2)))]
5209 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5210 "add{b}\t{%2, %0|%0, %2}"
5211 [(set_attr "type" "alu")
5212 (set_attr "mode" "QI")])
5213
5214 (define_insn "*add<mode>_1"
5215 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5216 (plus:SWI48
5217 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5218 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5219 (clobber (reg:CC FLAGS_REG))]
5220 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5221 {
5222 switch (get_attr_type (insn))
5223 {
5224 case TYPE_LEA:
5225 return "#";
5226
5227 case TYPE_INCDEC:
5228 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5229 if (operands[2] == const1_rtx)
5230 return "inc{<imodesuffix>}\t%0";
5231 else
5232 {
5233 gcc_assert (operands[2] == constm1_rtx);
5234 return "dec{<imodesuffix>}\t%0";
5235 }
5236
5237 default:
5238 /* For most processors, ADD is faster than LEA. This alternative
5239 was added to use ADD as much as possible. */
5240 if (which_alternative == 2)
5241 std::swap (operands[1], operands[2]);
5242
5243 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5244 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5245 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5246
5247 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5248 }
5249 }
5250 [(set (attr "type")
5251 (cond [(eq_attr "alternative" "3")
5252 (const_string "lea")
5253 (match_operand:SWI48 2 "incdec_operand")
5254 (const_string "incdec")
5255 ]
5256 (const_string "alu")))
5257 (set (attr "length_immediate")
5258 (if_then_else
5259 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5260 (const_string "1")
5261 (const_string "*")))
5262 (set_attr "mode" "<MODE>")])
5263
5264 ;; It may seem that nonimmediate operand is proper one for operand 1.
5265 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5266 ;; we take care in ix86_binary_operator_ok to not allow two memory
5267 ;; operands so proper swapping will be done in reload. This allow
5268 ;; patterns constructed from addsi_1 to match.
5269
5270 (define_insn "addsi_1_zext"
5271 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5272 (zero_extend:DI
5273 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5274 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5275 (clobber (reg:CC FLAGS_REG))]
5276 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5277 {
5278 switch (get_attr_type (insn))
5279 {
5280 case TYPE_LEA:
5281 return "#";
5282
5283 case TYPE_INCDEC:
5284 if (operands[2] == const1_rtx)
5285 return "inc{l}\t%k0";
5286 else
5287 {
5288 gcc_assert (operands[2] == constm1_rtx);
5289 return "dec{l}\t%k0";
5290 }
5291
5292 default:
5293 /* For most processors, ADD is faster than LEA. This alternative
5294 was added to use ADD as much as possible. */
5295 if (which_alternative == 1)
5296 std::swap (operands[1], operands[2]);
5297
5298 if (x86_maybe_negate_const_int (&operands[2], SImode))
5299 return "sub{l}\t{%2, %k0|%k0, %2}";
5300
5301 return "add{l}\t{%2, %k0|%k0, %2}";
5302 }
5303 }
5304 [(set (attr "type")
5305 (cond [(eq_attr "alternative" "2")
5306 (const_string "lea")
5307 (match_operand:SI 2 "incdec_operand")
5308 (const_string "incdec")
5309 ]
5310 (const_string "alu")))
5311 (set (attr "length_immediate")
5312 (if_then_else
5313 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5314 (const_string "1")
5315 (const_string "*")))
5316 (set_attr "mode" "SI")])
5317
5318 (define_insn "*addhi_1"
5319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5320 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5321 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5322 (clobber (reg:CC FLAGS_REG))]
5323 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5324 {
5325 switch (get_attr_type (insn))
5326 {
5327 case TYPE_LEA:
5328 return "#";
5329
5330 case TYPE_INCDEC:
5331 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5332 if (operands[2] == const1_rtx)
5333 return "inc{w}\t%0";
5334 else
5335 {
5336 gcc_assert (operands[2] == constm1_rtx);
5337 return "dec{w}\t%0";
5338 }
5339
5340 default:
5341 /* For most processors, ADD is faster than LEA. This alternative
5342 was added to use ADD as much as possible. */
5343 if (which_alternative == 2)
5344 std::swap (operands[1], operands[2]);
5345
5346 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5347 if (x86_maybe_negate_const_int (&operands[2], HImode))
5348 return "sub{w}\t{%2, %0|%0, %2}";
5349
5350 return "add{w}\t{%2, %0|%0, %2}";
5351 }
5352 }
5353 [(set (attr "type")
5354 (cond [(eq_attr "alternative" "3")
5355 (const_string "lea")
5356 (match_operand:HI 2 "incdec_operand")
5357 (const_string "incdec")
5358 ]
5359 (const_string "alu")))
5360 (set (attr "length_immediate")
5361 (if_then_else
5362 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5363 (const_string "1")
5364 (const_string "*")))
5365 (set_attr "mode" "HI,HI,HI,SI")])
5366
5367 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5368 (define_insn "*addqi_1"
5369 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5370 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5371 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5372 (clobber (reg:CC FLAGS_REG))]
5373 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5374 {
5375 bool widen = (which_alternative == 3 || which_alternative == 4);
5376
5377 switch (get_attr_type (insn))
5378 {
5379 case TYPE_LEA:
5380 return "#";
5381
5382 case TYPE_INCDEC:
5383 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5384 if (operands[2] == const1_rtx)
5385 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5386 else
5387 {
5388 gcc_assert (operands[2] == constm1_rtx);
5389 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5390 }
5391
5392 default:
5393 /* For most processors, ADD is faster than LEA. These alternatives
5394 were added to use ADD as much as possible. */
5395 if (which_alternative == 2 || which_alternative == 4)
5396 std::swap (operands[1], operands[2]);
5397
5398 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5399 if (x86_maybe_negate_const_int (&operands[2], QImode))
5400 {
5401 if (widen)
5402 return "sub{l}\t{%2, %k0|%k0, %2}";
5403 else
5404 return "sub{b}\t{%2, %0|%0, %2}";
5405 }
5406 if (widen)
5407 return "add{l}\t{%k2, %k0|%k0, %k2}";
5408 else
5409 return "add{b}\t{%2, %0|%0, %2}";
5410 }
5411 }
5412 [(set (attr "type")
5413 (cond [(eq_attr "alternative" "5")
5414 (const_string "lea")
5415 (match_operand:QI 2 "incdec_operand")
5416 (const_string "incdec")
5417 ]
5418 (const_string "alu")))
5419 (set (attr "length_immediate")
5420 (if_then_else
5421 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5422 (const_string "1")
5423 (const_string "*")))
5424 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5425
5426 (define_insn "*addqi_1_slp"
5427 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5428 (plus:QI (match_dup 0)
5429 (match_operand:QI 1 "general_operand" "qn,qm")))
5430 (clobber (reg:CC FLAGS_REG))]
5431 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5432 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5433 {
5434 switch (get_attr_type (insn))
5435 {
5436 case TYPE_INCDEC:
5437 if (operands[1] == const1_rtx)
5438 return "inc{b}\t%0";
5439 else
5440 {
5441 gcc_assert (operands[1] == constm1_rtx);
5442 return "dec{b}\t%0";
5443 }
5444
5445 default:
5446 if (x86_maybe_negate_const_int (&operands[1], QImode))
5447 return "sub{b}\t{%1, %0|%0, %1}";
5448
5449 return "add{b}\t{%1, %0|%0, %1}";
5450 }
5451 }
5452 [(set (attr "type")
5453 (if_then_else (match_operand:QI 1 "incdec_operand")
5454 (const_string "incdec")
5455 (const_string "alu1")))
5456 (set (attr "memory")
5457 (if_then_else (match_operand 1 "memory_operand")
5458 (const_string "load")
5459 (const_string "none")))
5460 (set_attr "mode" "QI")])
5461
5462 ;; Split non destructive adds if we cannot use lea.
5463 (define_split
5464 [(set (match_operand:SWI48 0 "register_operand")
5465 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5466 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5467 (clobber (reg:CC FLAGS_REG))]
5468 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5469 [(set (match_dup 0) (match_dup 1))
5470 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5471 (clobber (reg:CC FLAGS_REG))])])
5472
5473 ;; Convert add to the lea pattern to avoid flags dependency.
5474 (define_split
5475 [(set (match_operand:SWI 0 "register_operand")
5476 (plus:SWI (match_operand:SWI 1 "register_operand")
5477 (match_operand:SWI 2 "<nonmemory_operand>")))
5478 (clobber (reg:CC FLAGS_REG))]
5479 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5480 [(const_int 0)]
5481 {
5482 machine_mode mode = <MODE>mode;
5483 rtx pat;
5484
5485 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5486 {
5487 mode = SImode;
5488 operands[0] = gen_lowpart (mode, operands[0]);
5489 operands[1] = gen_lowpart (mode, operands[1]);
5490 operands[2] = gen_lowpart (mode, operands[2]);
5491 }
5492
5493 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5494
5495 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5496 DONE;
5497 })
5498
5499 ;; Split non destructive adds if we cannot use lea.
5500 (define_split
5501 [(set (match_operand:DI 0 "register_operand")
5502 (zero_extend:DI
5503 (plus:SI (match_operand:SI 1 "register_operand")
5504 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "TARGET_64BIT
5507 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5508 [(set (match_dup 3) (match_dup 1))
5509 (parallel [(set (match_dup 0)
5510 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5511 (clobber (reg:CC FLAGS_REG))])]
5512 "operands[3] = gen_lowpart (SImode, operands[0]);")
5513
5514 ;; Convert add to the lea pattern to avoid flags dependency.
5515 (define_split
5516 [(set (match_operand:DI 0 "register_operand")
5517 (zero_extend:DI
5518 (plus:SI (match_operand:SI 1 "register_operand")
5519 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5522 [(set (match_dup 0)
5523 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5524
5525 (define_insn "*add<mode>_2"
5526 [(set (reg FLAGS_REG)
5527 (compare
5528 (plus:SWI
5529 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5530 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5531 (const_int 0)))
5532 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5533 (plus:SWI (match_dup 1) (match_dup 2)))]
5534 "ix86_match_ccmode (insn, CCGOCmode)
5535 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5536 {
5537 switch (get_attr_type (insn))
5538 {
5539 case TYPE_INCDEC:
5540 if (operands[2] == const1_rtx)
5541 return "inc{<imodesuffix>}\t%0";
5542 else
5543 {
5544 gcc_assert (operands[2] == constm1_rtx);
5545 return "dec{<imodesuffix>}\t%0";
5546 }
5547
5548 default:
5549 if (which_alternative == 2)
5550 std::swap (operands[1], operands[2]);
5551
5552 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5553 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5554 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5555
5556 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5557 }
5558 }
5559 [(set (attr "type")
5560 (if_then_else (match_operand:SWI 2 "incdec_operand")
5561 (const_string "incdec")
5562 (const_string "alu")))
5563 (set (attr "length_immediate")
5564 (if_then_else
5565 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5566 (const_string "1")
5567 (const_string "*")))
5568 (set_attr "mode" "<MODE>")])
5569
5570 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5571 (define_insn "*addsi_2_zext"
5572 [(set (reg FLAGS_REG)
5573 (compare
5574 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5575 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5576 (const_int 0)))
5577 (set (match_operand:DI 0 "register_operand" "=r,r")
5578 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5579 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5580 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5581 {
5582 switch (get_attr_type (insn))
5583 {
5584 case TYPE_INCDEC:
5585 if (operands[2] == const1_rtx)
5586 return "inc{l}\t%k0";
5587 else
5588 {
5589 gcc_assert (operands[2] == constm1_rtx);
5590 return "dec{l}\t%k0";
5591 }
5592
5593 default:
5594 if (which_alternative == 1)
5595 std::swap (operands[1], operands[2]);
5596
5597 if (x86_maybe_negate_const_int (&operands[2], SImode))
5598 return "sub{l}\t{%2, %k0|%k0, %2}";
5599
5600 return "add{l}\t{%2, %k0|%k0, %2}";
5601 }
5602 }
5603 [(set (attr "type")
5604 (if_then_else (match_operand:SI 2 "incdec_operand")
5605 (const_string "incdec")
5606 (const_string "alu")))
5607 (set (attr "length_immediate")
5608 (if_then_else
5609 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5610 (const_string "1")
5611 (const_string "*")))
5612 (set_attr "mode" "SI")])
5613
5614 (define_insn "*add<mode>_3"
5615 [(set (reg FLAGS_REG)
5616 (compare
5617 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5618 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5619 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5620 "ix86_match_ccmode (insn, CCZmode)
5621 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5622 {
5623 switch (get_attr_type (insn))
5624 {
5625 case TYPE_INCDEC:
5626 if (operands[2] == const1_rtx)
5627 return "inc{<imodesuffix>}\t%0";
5628 else
5629 {
5630 gcc_assert (operands[2] == constm1_rtx);
5631 return "dec{<imodesuffix>}\t%0";
5632 }
5633
5634 default:
5635 if (which_alternative == 1)
5636 std::swap (operands[1], operands[2]);
5637
5638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5640 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5641
5642 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5643 }
5644 }
5645 [(set (attr "type")
5646 (if_then_else (match_operand:SWI 2 "incdec_operand")
5647 (const_string "incdec")
5648 (const_string "alu")))
5649 (set (attr "length_immediate")
5650 (if_then_else
5651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5652 (const_string "1")
5653 (const_string "*")))
5654 (set_attr "mode" "<MODE>")])
5655
5656 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5657 (define_insn "*addsi_3_zext"
5658 [(set (reg FLAGS_REG)
5659 (compare
5660 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5661 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5662 (set (match_operand:DI 0 "register_operand" "=r,r")
5663 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5664 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5665 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5666 {
5667 switch (get_attr_type (insn))
5668 {
5669 case TYPE_INCDEC:
5670 if (operands[2] == const1_rtx)
5671 return "inc{l}\t%k0";
5672 else
5673 {
5674 gcc_assert (operands[2] == constm1_rtx);
5675 return "dec{l}\t%k0";
5676 }
5677
5678 default:
5679 if (which_alternative == 1)
5680 std::swap (operands[1], operands[2]);
5681
5682 if (x86_maybe_negate_const_int (&operands[2], SImode))
5683 return "sub{l}\t{%2, %k0|%k0, %2}";
5684
5685 return "add{l}\t{%2, %k0|%k0, %2}";
5686 }
5687 }
5688 [(set (attr "type")
5689 (if_then_else (match_operand:SI 2 "incdec_operand")
5690 (const_string "incdec")
5691 (const_string "alu")))
5692 (set (attr "length_immediate")
5693 (if_then_else
5694 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5695 (const_string "1")
5696 (const_string "*")))
5697 (set_attr "mode" "SI")])
5698
5699 ; For comparisons against 1, -1 and 128, we may generate better code
5700 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5701 ; is matched then. We can't accept general immediate, because for
5702 ; case of overflows, the result is messed up.
5703 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5704 ; only for comparisons not depending on it.
5705
5706 (define_insn "*adddi_4"
5707 [(set (reg FLAGS_REG)
5708 (compare
5709 (match_operand:DI 1 "nonimmediate_operand" "0")
5710 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5711 (clobber (match_scratch:DI 0 "=rm"))]
5712 "TARGET_64BIT
5713 && ix86_match_ccmode (insn, CCGCmode)"
5714 {
5715 switch (get_attr_type (insn))
5716 {
5717 case TYPE_INCDEC:
5718 if (operands[2] == constm1_rtx)
5719 return "inc{q}\t%0";
5720 else
5721 {
5722 gcc_assert (operands[2] == const1_rtx);
5723 return "dec{q}\t%0";
5724 }
5725
5726 default:
5727 if (x86_maybe_negate_const_int (&operands[2], DImode))
5728 return "add{q}\t{%2, %0|%0, %2}";
5729
5730 return "sub{q}\t{%2, %0|%0, %2}";
5731 }
5732 }
5733 [(set (attr "type")
5734 (if_then_else (match_operand:DI 2 "incdec_operand")
5735 (const_string "incdec")
5736 (const_string "alu")))
5737 (set (attr "length_immediate")
5738 (if_then_else
5739 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5740 (const_string "1")
5741 (const_string "*")))
5742 (set_attr "mode" "DI")])
5743
5744 ; For comparisons against 1, -1 and 128, we may generate better code
5745 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5746 ; is matched then. We can't accept general immediate, because for
5747 ; case of overflows, the result is messed up.
5748 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5749 ; only for comparisons not depending on it.
5750
5751 (define_insn "*add<mode>_4"
5752 [(set (reg FLAGS_REG)
5753 (compare
5754 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5755 (match_operand:SWI124 2 "const_int_operand" "n")))
5756 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5757 "ix86_match_ccmode (insn, CCGCmode)"
5758 {
5759 switch (get_attr_type (insn))
5760 {
5761 case TYPE_INCDEC:
5762 if (operands[2] == constm1_rtx)
5763 return "inc{<imodesuffix>}\t%0";
5764 else
5765 {
5766 gcc_assert (operands[2] == const1_rtx);
5767 return "dec{<imodesuffix>}\t%0";
5768 }
5769
5770 default:
5771 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5772 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5773
5774 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5775 }
5776 }
5777 [(set (attr "type")
5778 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5779 (const_string "incdec")
5780 (const_string "alu")))
5781 (set (attr "length_immediate")
5782 (if_then_else
5783 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5784 (const_string "1")
5785 (const_string "*")))
5786 (set_attr "mode" "<MODE>")])
5787
5788 (define_insn "*add<mode>_5"
5789 [(set (reg FLAGS_REG)
5790 (compare
5791 (plus:SWI
5792 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5793 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5794 (const_int 0)))
5795 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5796 "ix86_match_ccmode (insn, CCGOCmode)
5797 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5798 {
5799 switch (get_attr_type (insn))
5800 {
5801 case TYPE_INCDEC:
5802 if (operands[2] == const1_rtx)
5803 return "inc{<imodesuffix>}\t%0";
5804 else
5805 {
5806 gcc_assert (operands[2] == constm1_rtx);
5807 return "dec{<imodesuffix>}\t%0";
5808 }
5809
5810 default:
5811 if (which_alternative == 1)
5812 std::swap (operands[1], operands[2]);
5813
5814 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5815 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5816 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5817
5818 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5819 }
5820 }
5821 [(set (attr "type")
5822 (if_then_else (match_operand:SWI 2 "incdec_operand")
5823 (const_string "incdec")
5824 (const_string "alu")))
5825 (set (attr "length_immediate")
5826 (if_then_else
5827 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5828 (const_string "1")
5829 (const_string "*")))
5830 (set_attr "mode" "<MODE>")])
5831
5832 (define_insn "addqi_ext_1"
5833 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5834 (const_int 8)
5835 (const_int 8))
5836 (plus:SI
5837 (zero_extract:SI
5838 (match_operand 1 "ext_register_operand" "0,0")
5839 (const_int 8)
5840 (const_int 8))
5841 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5842 (clobber (reg:CC FLAGS_REG))]
5843 ""
5844 {
5845 switch (get_attr_type (insn))
5846 {
5847 case TYPE_INCDEC:
5848 if (operands[2] == const1_rtx)
5849 return "inc{b}\t%h0";
5850 else
5851 {
5852 gcc_assert (operands[2] == constm1_rtx);
5853 return "dec{b}\t%h0";
5854 }
5855
5856 default:
5857 return "add{b}\t{%2, %h0|%h0, %2}";
5858 }
5859 }
5860 [(set_attr "isa" "*,nox64")
5861 (set (attr "type")
5862 (if_then_else (match_operand:QI 2 "incdec_operand")
5863 (const_string "incdec")
5864 (const_string "alu")))
5865 (set_attr "modrm" "1")
5866 (set_attr "mode" "QI")])
5867
5868 (define_insn "*addqi_ext_2"
5869 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5870 (const_int 8)
5871 (const_int 8))
5872 (plus:SI
5873 (zero_extract:SI
5874 (match_operand 1 "ext_register_operand" "%0")
5875 (const_int 8)
5876 (const_int 8))
5877 (zero_extract:SI
5878 (match_operand 2 "ext_register_operand" "Q")
5879 (const_int 8)
5880 (const_int 8))))
5881 (clobber (reg:CC FLAGS_REG))]
5882 ""
5883 "add{b}\t{%h2, %h0|%h0, %h2}"
5884 [(set_attr "type" "alu")
5885 (set_attr "mode" "QI")])
5886
5887 ;; Add with jump on overflow.
5888 (define_expand "addv<mode>4"
5889 [(parallel [(set (reg:CCO FLAGS_REG)
5890 (eq:CCO (plus:<DWI>
5891 (sign_extend:<DWI>
5892 (match_operand:SWI 1 "nonimmediate_operand"))
5893 (match_dup 4))
5894 (sign_extend:<DWI>
5895 (plus:SWI (match_dup 1)
5896 (match_operand:SWI 2
5897 "<general_operand>")))))
5898 (set (match_operand:SWI 0 "register_operand")
5899 (plus:SWI (match_dup 1) (match_dup 2)))])
5900 (set (pc) (if_then_else
5901 (eq (reg:CCO FLAGS_REG) (const_int 0))
5902 (label_ref (match_operand 3))
5903 (pc)))]
5904 ""
5905 {
5906 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5907 if (CONST_INT_P (operands[2]))
5908 operands[4] = operands[2];
5909 else
5910 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5911 })
5912
5913 (define_insn "*addv<mode>4"
5914 [(set (reg:CCO FLAGS_REG)
5915 (eq:CCO (plus:<DWI>
5916 (sign_extend:<DWI>
5917 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5918 (sign_extend:<DWI>
5919 (match_operand:SWI 2 "<general_sext_operand>"
5920 "<r>mWe,<r>We")))
5921 (sign_extend:<DWI>
5922 (plus:SWI (match_dup 1) (match_dup 2)))))
5923 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5924 (plus:SWI (match_dup 1) (match_dup 2)))]
5925 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5926 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5927 [(set_attr "type" "alu")
5928 (set_attr "mode" "<MODE>")])
5929
5930 (define_insn "*addv<mode>4_1"
5931 [(set (reg:CCO FLAGS_REG)
5932 (eq:CCO (plus:<DWI>
5933 (sign_extend:<DWI>
5934 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5935 (match_operand:<DWI> 3 "const_int_operand" "i"))
5936 (sign_extend:<DWI>
5937 (plus:SWI (match_dup 1)
5938 (match_operand:SWI 2 "x86_64_immediate_operand"
5939 "<i>")))))
5940 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5941 (plus:SWI (match_dup 1) (match_dup 2)))]
5942 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5943 && CONST_INT_P (operands[2])
5944 && INTVAL (operands[2]) == INTVAL (operands[3])"
5945 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5946 [(set_attr "type" "alu")
5947 (set_attr "mode" "<MODE>")
5948 (set (attr "length_immediate")
5949 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5950 (const_string "1")
5951 (match_test "<MODE_SIZE> == 8")
5952 (const_string "4")]
5953 (const_string "<MODE_SIZE>")))])
5954
5955 ;; The lea patterns for modes less than 32 bits need to be matched by
5956 ;; several insns converted to real lea by splitters.
5957
5958 (define_insn_and_split "*lea_general_1"
5959 [(set (match_operand 0 "register_operand" "=r")
5960 (plus (plus (match_operand 1 "index_register_operand" "l")
5961 (match_operand 2 "register_operand" "r"))
5962 (match_operand 3 "immediate_operand" "i")))]
5963 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5964 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5965 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5966 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5967 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5968 || GET_MODE (operands[3]) == VOIDmode)"
5969 "#"
5970 "&& reload_completed"
5971 [(const_int 0)]
5972 {
5973 machine_mode mode = SImode;
5974 rtx pat;
5975
5976 operands[0] = gen_lowpart (mode, operands[0]);
5977 operands[1] = gen_lowpart (mode, operands[1]);
5978 operands[2] = gen_lowpart (mode, operands[2]);
5979 operands[3] = gen_lowpart (mode, operands[3]);
5980
5981 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5982 operands[3]);
5983
5984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5985 DONE;
5986 }
5987 [(set_attr "type" "lea")
5988 (set_attr "mode" "SI")])
5989
5990 (define_insn_and_split "*lea_general_2"
5991 [(set (match_operand 0 "register_operand" "=r")
5992 (plus (mult (match_operand 1 "index_register_operand" "l")
5993 (match_operand 2 "const248_operand" "n"))
5994 (match_operand 3 "nonmemory_operand" "ri")))]
5995 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5996 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5997 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5998 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5999 || GET_MODE (operands[3]) == VOIDmode)"
6000 "#"
6001 "&& reload_completed"
6002 [(const_int 0)]
6003 {
6004 machine_mode mode = SImode;
6005 rtx pat;
6006
6007 operands[0] = gen_lowpart (mode, operands[0]);
6008 operands[1] = gen_lowpart (mode, operands[1]);
6009 operands[3] = gen_lowpart (mode, operands[3]);
6010
6011 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6012 operands[3]);
6013
6014 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6015 DONE;
6016 }
6017 [(set_attr "type" "lea")
6018 (set_attr "mode" "SI")])
6019
6020 (define_insn_and_split "*lea_general_3"
6021 [(set (match_operand 0 "register_operand" "=r")
6022 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6023 (match_operand 2 "const248_operand" "n"))
6024 (match_operand 3 "register_operand" "r"))
6025 (match_operand 4 "immediate_operand" "i")))]
6026 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6027 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6028 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6029 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6030 "#"
6031 "&& reload_completed"
6032 [(const_int 0)]
6033 {
6034 machine_mode mode = SImode;
6035 rtx pat;
6036
6037 operands[0] = gen_lowpart (mode, operands[0]);
6038 operands[1] = gen_lowpart (mode, operands[1]);
6039 operands[3] = gen_lowpart (mode, operands[3]);
6040 operands[4] = gen_lowpart (mode, operands[4]);
6041
6042 pat = gen_rtx_PLUS (mode,
6043 gen_rtx_PLUS (mode,
6044 gen_rtx_MULT (mode, operands[1],
6045 operands[2]),
6046 operands[3]),
6047 operands[4]);
6048
6049 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6050 DONE;
6051 }
6052 [(set_attr "type" "lea")
6053 (set_attr "mode" "SI")])
6054
6055 (define_insn_and_split "*lea_general_4"
6056 [(set (match_operand 0 "register_operand" "=r")
6057 (any_or (ashift
6058 (match_operand 1 "index_register_operand" "l")
6059 (match_operand 2 "const_int_operand" "n"))
6060 (match_operand 3 "const_int_operand" "n")))]
6061 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6062 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6063 || GET_MODE (operands[0]) == SImode
6064 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6065 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6066 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6067 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6068 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6069 "#"
6070 "&& reload_completed"
6071 [(const_int 0)]
6072 {
6073 machine_mode mode = GET_MODE (operands[0]);
6074 rtx pat;
6075
6076 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6077 {
6078 mode = SImode;
6079 operands[0] = gen_lowpart (mode, operands[0]);
6080 operands[1] = gen_lowpart (mode, operands[1]);
6081 }
6082
6083 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6084
6085 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6086 INTVAL (operands[3]));
6087
6088 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6089 DONE;
6090 }
6091 [(set_attr "type" "lea")
6092 (set (attr "mode")
6093 (if_then_else (match_operand:DI 0)
6094 (const_string "DI")
6095 (const_string "SI")))])
6096 \f
6097 ;; Subtract instructions
6098
6099 (define_expand "sub<mode>3"
6100 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6101 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6102 (match_operand:SDWIM 2 "<general_operand>")))]
6103 ""
6104 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6105
6106 (define_insn_and_split "*sub<dwi>3_doubleword"
6107 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6108 (minus:<DWI>
6109 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6110 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6111 (clobber (reg:CC FLAGS_REG))]
6112 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6113 "#"
6114 "reload_completed"
6115 [(parallel [(set (reg:CC FLAGS_REG)
6116 (compare:CC (match_dup 1) (match_dup 2)))
6117 (set (match_dup 0)
6118 (minus:DWIH (match_dup 1) (match_dup 2)))])
6119 (parallel [(set (match_dup 3)
6120 (minus:DWIH
6121 (match_dup 4)
6122 (plus:DWIH
6123 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6124 (match_dup 5))))
6125 (clobber (reg:CC FLAGS_REG))])]
6126 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6127
6128 (define_insn "*sub<mode>_1"
6129 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6130 (minus:SWI
6131 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6132 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6133 (clobber (reg:CC FLAGS_REG))]
6134 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6135 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6136 [(set_attr "type" "alu")
6137 (set_attr "mode" "<MODE>")])
6138
6139 (define_insn "*subsi_1_zext"
6140 [(set (match_operand:DI 0 "register_operand" "=r")
6141 (zero_extend:DI
6142 (minus:SI (match_operand:SI 1 "register_operand" "0")
6143 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6144 (clobber (reg:CC FLAGS_REG))]
6145 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6146 "sub{l}\t{%2, %k0|%k0, %2}"
6147 [(set_attr "type" "alu")
6148 (set_attr "mode" "SI")])
6149
6150 (define_insn "*subqi_1_slp"
6151 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6152 (minus:QI (match_dup 0)
6153 (match_operand:QI 1 "general_operand" "qn,qm")))
6154 (clobber (reg:CC FLAGS_REG))]
6155 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6156 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6157 "sub{b}\t{%1, %0|%0, %1}"
6158 [(set_attr "type" "alu1")
6159 (set_attr "mode" "QI")])
6160
6161 (define_insn "*sub<mode>_2"
6162 [(set (reg FLAGS_REG)
6163 (compare
6164 (minus:SWI
6165 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6166 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6167 (const_int 0)))
6168 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6169 (minus:SWI (match_dup 1) (match_dup 2)))]
6170 "ix86_match_ccmode (insn, CCGOCmode)
6171 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6172 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6173 [(set_attr "type" "alu")
6174 (set_attr "mode" "<MODE>")])
6175
6176 (define_insn "*subsi_2_zext"
6177 [(set (reg FLAGS_REG)
6178 (compare
6179 (minus:SI (match_operand:SI 1 "register_operand" "0")
6180 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6181 (const_int 0)))
6182 (set (match_operand:DI 0 "register_operand" "=r")
6183 (zero_extend:DI
6184 (minus:SI (match_dup 1)
6185 (match_dup 2))))]
6186 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6187 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6188 "sub{l}\t{%2, %k0|%k0, %2}"
6189 [(set_attr "type" "alu")
6190 (set_attr "mode" "SI")])
6191
6192 ;; Subtract with jump on overflow.
6193 (define_expand "subv<mode>4"
6194 [(parallel [(set (reg:CCO FLAGS_REG)
6195 (eq:CCO (minus:<DWI>
6196 (sign_extend:<DWI>
6197 (match_operand:SWI 1 "nonimmediate_operand"))
6198 (match_dup 4))
6199 (sign_extend:<DWI>
6200 (minus:SWI (match_dup 1)
6201 (match_operand:SWI 2
6202 "<general_operand>")))))
6203 (set (match_operand:SWI 0 "register_operand")
6204 (minus:SWI (match_dup 1) (match_dup 2)))])
6205 (set (pc) (if_then_else
6206 (eq (reg:CCO FLAGS_REG) (const_int 0))
6207 (label_ref (match_operand 3))
6208 (pc)))]
6209 ""
6210 {
6211 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6212 if (CONST_INT_P (operands[2]))
6213 operands[4] = operands[2];
6214 else
6215 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6216 })
6217
6218 (define_insn "*subv<mode>4"
6219 [(set (reg:CCO FLAGS_REG)
6220 (eq:CCO (minus:<DWI>
6221 (sign_extend:<DWI>
6222 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6223 (sign_extend:<DWI>
6224 (match_operand:SWI 2 "<general_sext_operand>"
6225 "<r>We,<r>m")))
6226 (sign_extend:<DWI>
6227 (minus:SWI (match_dup 1) (match_dup 2)))))
6228 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6229 (minus:SWI (match_dup 1) (match_dup 2)))]
6230 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6231 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6232 [(set_attr "type" "alu")
6233 (set_attr "mode" "<MODE>")])
6234
6235 (define_insn "*subv<mode>4_1"
6236 [(set (reg:CCO FLAGS_REG)
6237 (eq:CCO (minus:<DWI>
6238 (sign_extend:<DWI>
6239 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6240 (match_operand:<DWI> 3 "const_int_operand" "i"))
6241 (sign_extend:<DWI>
6242 (minus:SWI (match_dup 1)
6243 (match_operand:SWI 2 "x86_64_immediate_operand"
6244 "<i>")))))
6245 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6246 (minus:SWI (match_dup 1) (match_dup 2)))]
6247 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6248 && CONST_INT_P (operands[2])
6249 && INTVAL (operands[2]) == INTVAL (operands[3])"
6250 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6251 [(set_attr "type" "alu")
6252 (set_attr "mode" "<MODE>")
6253 (set (attr "length_immediate")
6254 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6255 (const_string "1")
6256 (match_test "<MODE_SIZE> == 8")
6257 (const_string "4")]
6258 (const_string "<MODE_SIZE>")))])
6259
6260 (define_insn "*sub<mode>_3"
6261 [(set (reg FLAGS_REG)
6262 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6263 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6264 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6265 (minus:SWI (match_dup 1) (match_dup 2)))]
6266 "ix86_match_ccmode (insn, CCmode)
6267 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6268 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6269 [(set_attr "type" "alu")
6270 (set_attr "mode" "<MODE>")])
6271
6272 (define_insn "*subsi_3_zext"
6273 [(set (reg FLAGS_REG)
6274 (compare (match_operand:SI 1 "register_operand" "0")
6275 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6276 (set (match_operand:DI 0 "register_operand" "=r")
6277 (zero_extend:DI
6278 (minus:SI (match_dup 1)
6279 (match_dup 2))))]
6280 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6281 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6282 "sub{l}\t{%2, %1|%1, %2}"
6283 [(set_attr "type" "alu")
6284 (set_attr "mode" "SI")])
6285 \f
6286 ;; Add with carry and subtract with borrow
6287
6288 (define_expand "<plusminus_insn><mode>3_carry"
6289 [(parallel
6290 [(set (match_operand:SWI 0 "nonimmediate_operand")
6291 (plusminus:SWI
6292 (match_operand:SWI 1 "nonimmediate_operand")
6293 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6294 [(match_operand 3 "flags_reg_operand")
6295 (const_int 0)])
6296 (match_operand:SWI 2 "<general_operand>"))))
6297 (clobber (reg:CC FLAGS_REG))])]
6298 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6299
6300 (define_insn "*<plusminus_insn><mode>3_carry"
6301 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6302 (plusminus:SWI
6303 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6304 (plus:SWI
6305 (match_operator 3 "ix86_carry_flag_operator"
6306 [(reg FLAGS_REG) (const_int 0)])
6307 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6308 (clobber (reg:CC FLAGS_REG))]
6309 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6310 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6311 [(set_attr "type" "alu")
6312 (set_attr "use_carry" "1")
6313 (set_attr "pent_pair" "pu")
6314 (set_attr "mode" "<MODE>")])
6315
6316 (define_insn "*addsi3_carry_zext"
6317 [(set (match_operand:DI 0 "register_operand" "=r")
6318 (zero_extend:DI
6319 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6320 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6321 [(reg FLAGS_REG) (const_int 0)])
6322 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6323 (clobber (reg:CC FLAGS_REG))]
6324 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6325 "adc{l}\t{%2, %k0|%k0, %2}"
6326 [(set_attr "type" "alu")
6327 (set_attr "use_carry" "1")
6328 (set_attr "pent_pair" "pu")
6329 (set_attr "mode" "SI")])
6330
6331 (define_insn "*subsi3_carry_zext"
6332 [(set (match_operand:DI 0 "register_operand" "=r")
6333 (zero_extend:DI
6334 (minus:SI (match_operand:SI 1 "register_operand" "0")
6335 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6336 [(reg FLAGS_REG) (const_int 0)])
6337 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6338 (clobber (reg:CC FLAGS_REG))]
6339 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6340 "sbb{l}\t{%2, %k0|%k0, %2}"
6341 [(set_attr "type" "alu")
6342 (set_attr "pent_pair" "pu")
6343 (set_attr "mode" "SI")])
6344 \f
6345 ;; ADCX instruction
6346
6347 (define_insn "adcx<mode>3"
6348 [(set (reg:CCC FLAGS_REG)
6349 (compare:CCC
6350 (plus:SWI48
6351 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6352 (plus:SWI48
6353 (match_operator 4 "ix86_carry_flag_operator"
6354 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6355 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6356 (const_int 0)))
6357 (set (match_operand:SWI48 0 "register_operand" "=r")
6358 (plus:SWI48 (match_dup 1)
6359 (plus:SWI48 (match_op_dup 4
6360 [(match_dup 3) (const_int 0)])
6361 (match_dup 2))))]
6362 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6363 "adcx\t{%2, %0|%0, %2}"
6364 [(set_attr "type" "alu")
6365 (set_attr "use_carry" "1")
6366 (set_attr "mode" "<MODE>")])
6367 \f
6368 ;; Overflow setting add instructions
6369
6370 (define_insn "*add<mode>3_cconly_overflow"
6371 [(set (reg:CCC FLAGS_REG)
6372 (compare:CCC
6373 (plus:SWI
6374 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6375 (match_operand:SWI 2 "<general_operand>" "<g>"))
6376 (match_dup 1)))
6377 (clobber (match_scratch:SWI 0 "=<r>"))]
6378 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6379 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6380 [(set_attr "type" "alu")
6381 (set_attr "mode" "<MODE>")])
6382
6383 (define_insn "*add<mode>3_cc_overflow"
6384 [(set (reg:CCC FLAGS_REG)
6385 (compare:CCC
6386 (plus:SWI
6387 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6388 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6389 (match_dup 1)))
6390 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6391 (plus:SWI (match_dup 1) (match_dup 2)))]
6392 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6393 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6394 [(set_attr "type" "alu")
6395 (set_attr "mode" "<MODE>")])
6396
6397 (define_insn "*addsi3_zext_cc_overflow"
6398 [(set (reg:CCC FLAGS_REG)
6399 (compare:CCC
6400 (plus:SI
6401 (match_operand:SI 1 "nonimmediate_operand" "%0")
6402 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6403 (match_dup 1)))
6404 (set (match_operand:DI 0 "register_operand" "=r")
6405 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6406 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6407 "add{l}\t{%2, %k0|%k0, %2}"
6408 [(set_attr "type" "alu")
6409 (set_attr "mode" "SI")])
6410
6411 ;; The patterns that match these are at the end of this file.
6412
6413 (define_expand "<plusminus_insn>xf3"
6414 [(set (match_operand:XF 0 "register_operand")
6415 (plusminus:XF
6416 (match_operand:XF 1 "register_operand")
6417 (match_operand:XF 2 "register_operand")))]
6418 "TARGET_80387")
6419
6420 (define_expand "<plusminus_insn><mode>3"
6421 [(set (match_operand:MODEF 0 "register_operand")
6422 (plusminus:MODEF
6423 (match_operand:MODEF 1 "register_operand")
6424 (match_operand:MODEF 2 "nonimmediate_operand")))]
6425 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6426 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6427 \f
6428 ;; Multiply instructions
6429
6430 (define_expand "mul<mode>3"
6431 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6432 (mult:SWIM248
6433 (match_operand:SWIM248 1 "register_operand")
6434 (match_operand:SWIM248 2 "<general_operand>")))
6435 (clobber (reg:CC FLAGS_REG))])])
6436
6437 (define_expand "mulqi3"
6438 [(parallel [(set (match_operand:QI 0 "register_operand")
6439 (mult:QI
6440 (match_operand:QI 1 "register_operand")
6441 (match_operand:QI 2 "nonimmediate_operand")))
6442 (clobber (reg:CC FLAGS_REG))])]
6443 "TARGET_QIMODE_MATH")
6444
6445 ;; On AMDFAM10
6446 ;; IMUL reg32/64, reg32/64, imm8 Direct
6447 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6448 ;; IMUL reg32/64, reg32/64, imm32 Direct
6449 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6450 ;; IMUL reg32/64, reg32/64 Direct
6451 ;; IMUL reg32/64, mem32/64 Direct
6452 ;;
6453 ;; On BDVER1, all above IMULs use DirectPath
6454
6455 (define_insn "*mul<mode>3_1"
6456 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6457 (mult:SWI48
6458 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6459 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6460 (clobber (reg:CC FLAGS_REG))]
6461 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6462 "@
6463 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6464 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6465 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6466 [(set_attr "type" "imul")
6467 (set_attr "prefix_0f" "0,0,1")
6468 (set (attr "athlon_decode")
6469 (cond [(eq_attr "cpu" "athlon")
6470 (const_string "vector")
6471 (eq_attr "alternative" "1")
6472 (const_string "vector")
6473 (and (eq_attr "alternative" "2")
6474 (match_operand 1 "memory_operand"))
6475 (const_string "vector")]
6476 (const_string "direct")))
6477 (set (attr "amdfam10_decode")
6478 (cond [(and (eq_attr "alternative" "0,1")
6479 (match_operand 1 "memory_operand"))
6480 (const_string "vector")]
6481 (const_string "direct")))
6482 (set_attr "bdver1_decode" "direct")
6483 (set_attr "mode" "<MODE>")])
6484
6485 (define_insn "*mulsi3_1_zext"
6486 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6487 (zero_extend:DI
6488 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6489 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6490 (clobber (reg:CC FLAGS_REG))]
6491 "TARGET_64BIT
6492 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6493 "@
6494 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6495 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6496 imul{l}\t{%2, %k0|%k0, %2}"
6497 [(set_attr "type" "imul")
6498 (set_attr "prefix_0f" "0,0,1")
6499 (set (attr "athlon_decode")
6500 (cond [(eq_attr "cpu" "athlon")
6501 (const_string "vector")
6502 (eq_attr "alternative" "1")
6503 (const_string "vector")
6504 (and (eq_attr "alternative" "2")
6505 (match_operand 1 "memory_operand"))
6506 (const_string "vector")]
6507 (const_string "direct")))
6508 (set (attr "amdfam10_decode")
6509 (cond [(and (eq_attr "alternative" "0,1")
6510 (match_operand 1 "memory_operand"))
6511 (const_string "vector")]
6512 (const_string "direct")))
6513 (set_attr "bdver1_decode" "direct")
6514 (set_attr "mode" "SI")])
6515
6516 ;; On AMDFAM10
6517 ;; IMUL reg16, reg16, imm8 VectorPath
6518 ;; IMUL reg16, mem16, imm8 VectorPath
6519 ;; IMUL reg16, reg16, imm16 VectorPath
6520 ;; IMUL reg16, mem16, imm16 VectorPath
6521 ;; IMUL reg16, reg16 Direct
6522 ;; IMUL reg16, mem16 Direct
6523 ;;
6524 ;; On BDVER1, all HI MULs use DoublePath
6525
6526 (define_insn "*mulhi3_1"
6527 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6528 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6529 (match_operand:HI 2 "general_operand" "K,n,mr")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "TARGET_HIMODE_MATH
6532 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6533 "@
6534 imul{w}\t{%2, %1, %0|%0, %1, %2}
6535 imul{w}\t{%2, %1, %0|%0, %1, %2}
6536 imul{w}\t{%2, %0|%0, %2}"
6537 [(set_attr "type" "imul")
6538 (set_attr "prefix_0f" "0,0,1")
6539 (set (attr "athlon_decode")
6540 (cond [(eq_attr "cpu" "athlon")
6541 (const_string "vector")
6542 (eq_attr "alternative" "1,2")
6543 (const_string "vector")]
6544 (const_string "direct")))
6545 (set (attr "amdfam10_decode")
6546 (cond [(eq_attr "alternative" "0,1")
6547 (const_string "vector")]
6548 (const_string "direct")))
6549 (set_attr "bdver1_decode" "double")
6550 (set_attr "mode" "HI")])
6551
6552 ;;On AMDFAM10 and BDVER1
6553 ;; MUL reg8 Direct
6554 ;; MUL mem8 Direct
6555
6556 (define_insn "*mulqi3_1"
6557 [(set (match_operand:QI 0 "register_operand" "=a")
6558 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6559 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "TARGET_QIMODE_MATH
6562 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6563 "mul{b}\t%2"
6564 [(set_attr "type" "imul")
6565 (set_attr "length_immediate" "0")
6566 (set (attr "athlon_decode")
6567 (if_then_else (eq_attr "cpu" "athlon")
6568 (const_string "vector")
6569 (const_string "direct")))
6570 (set_attr "amdfam10_decode" "direct")
6571 (set_attr "bdver1_decode" "direct")
6572 (set_attr "mode" "QI")])
6573
6574 ;; Multiply with jump on overflow.
6575 (define_expand "mulv<mode>4"
6576 [(parallel [(set (reg:CCO FLAGS_REG)
6577 (eq:CCO (mult:<DWI>
6578 (sign_extend:<DWI>
6579 (match_operand:SWI48 1 "register_operand"))
6580 (match_dup 4))
6581 (sign_extend:<DWI>
6582 (mult:SWI48 (match_dup 1)
6583 (match_operand:SWI48 2
6584 "<general_operand>")))))
6585 (set (match_operand:SWI48 0 "register_operand")
6586 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6587 (set (pc) (if_then_else
6588 (eq (reg:CCO FLAGS_REG) (const_int 0))
6589 (label_ref (match_operand 3))
6590 (pc)))]
6591 ""
6592 {
6593 if (CONST_INT_P (operands[2]))
6594 operands[4] = operands[2];
6595 else
6596 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6597 })
6598
6599 (define_insn "*mulv<mode>4"
6600 [(set (reg:CCO FLAGS_REG)
6601 (eq:CCO (mult:<DWI>
6602 (sign_extend:<DWI>
6603 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6604 (sign_extend:<DWI>
6605 (match_operand:SWI48 2 "<general_sext_operand>"
6606 "We,mr")))
6607 (sign_extend:<DWI>
6608 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6609 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6610 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6611 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6612 "@
6613 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6614 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6615 [(set_attr "type" "imul")
6616 (set_attr "prefix_0f" "0,1")
6617 (set (attr "athlon_decode")
6618 (cond [(eq_attr "cpu" "athlon")
6619 (const_string "vector")
6620 (eq_attr "alternative" "0")
6621 (const_string "vector")
6622 (and (eq_attr "alternative" "1")
6623 (match_operand 1 "memory_operand"))
6624 (const_string "vector")]
6625 (const_string "direct")))
6626 (set (attr "amdfam10_decode")
6627 (cond [(and (eq_attr "alternative" "1")
6628 (match_operand 1 "memory_operand"))
6629 (const_string "vector")]
6630 (const_string "direct")))
6631 (set_attr "bdver1_decode" "direct")
6632 (set_attr "mode" "<MODE>")])
6633
6634 (define_insn "*mulv<mode>4_1"
6635 [(set (reg:CCO FLAGS_REG)
6636 (eq:CCO (mult:<DWI>
6637 (sign_extend:<DWI>
6638 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6639 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6640 (sign_extend:<DWI>
6641 (mult:SWI48 (match_dup 1)
6642 (match_operand:SWI 2 "x86_64_immediate_operand"
6643 "K,<i>")))))
6644 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6645 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6646 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6647 && CONST_INT_P (operands[2])
6648 && INTVAL (operands[2]) == INTVAL (operands[3])"
6649 "@
6650 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6652 [(set_attr "type" "imul")
6653 (set (attr "athlon_decode")
6654 (cond [(eq_attr "cpu" "athlon")
6655 (const_string "vector")
6656 (eq_attr "alternative" "1")
6657 (const_string "vector")]
6658 (const_string "direct")))
6659 (set (attr "amdfam10_decode")
6660 (cond [(match_operand 1 "memory_operand")
6661 (const_string "vector")]
6662 (const_string "direct")))
6663 (set_attr "bdver1_decode" "direct")
6664 (set_attr "mode" "<MODE>")
6665 (set (attr "length_immediate")
6666 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6667 (const_string "1")
6668 (match_test "<MODE_SIZE> == 8")
6669 (const_string "4")]
6670 (const_string "<MODE_SIZE>")))])
6671
6672 (define_expand "umulv<mode>4"
6673 [(parallel [(set (reg:CCO FLAGS_REG)
6674 (eq:CCO (mult:<DWI>
6675 (zero_extend:<DWI>
6676 (match_operand:SWI48 1
6677 "nonimmediate_operand"))
6678 (zero_extend:<DWI>
6679 (match_operand:SWI48 2
6680 "nonimmediate_operand")))
6681 (zero_extend:<DWI>
6682 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6683 (set (match_operand:SWI48 0 "register_operand")
6684 (mult:SWI48 (match_dup 1) (match_dup 2)))
6685 (clobber (match_scratch:SWI48 4))])
6686 (set (pc) (if_then_else
6687 (eq (reg:CCO FLAGS_REG) (const_int 0))
6688 (label_ref (match_operand 3))
6689 (pc)))]
6690 ""
6691 {
6692 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6693 operands[1] = force_reg (<MODE>mode, operands[1]);
6694 })
6695
6696 (define_insn "*umulv<mode>4"
6697 [(set (reg:CCO FLAGS_REG)
6698 (eq:CCO (mult:<DWI>
6699 (zero_extend:<DWI>
6700 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6701 (zero_extend:<DWI>
6702 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6703 (zero_extend:<DWI>
6704 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6705 (set (match_operand:SWI48 0 "register_operand" "=a")
6706 (mult:SWI48 (match_dup 1) (match_dup 2)))
6707 (clobber (match_scratch:SWI48 3 "=d"))]
6708 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6709 "mul{<imodesuffix>}\t%2"
6710 [(set_attr "type" "imul")
6711 (set_attr "length_immediate" "0")
6712 (set (attr "athlon_decode")
6713 (if_then_else (eq_attr "cpu" "athlon")
6714 (const_string "vector")
6715 (const_string "double")))
6716 (set_attr "amdfam10_decode" "double")
6717 (set_attr "bdver1_decode" "direct")
6718 (set_attr "mode" "<MODE>")])
6719
6720 (define_expand "<u>mulvqi4"
6721 [(parallel [(set (reg:CCO FLAGS_REG)
6722 (eq:CCO (mult:HI
6723 (any_extend:HI
6724 (match_operand:QI 1 "nonimmediate_operand"))
6725 (any_extend:HI
6726 (match_operand:QI 2 "nonimmediate_operand")))
6727 (any_extend:HI
6728 (mult:QI (match_dup 1) (match_dup 2)))))
6729 (set (match_operand:QI 0 "register_operand")
6730 (mult:QI (match_dup 1) (match_dup 2)))])
6731 (set (pc) (if_then_else
6732 (eq (reg:CCO FLAGS_REG) (const_int 0))
6733 (label_ref (match_operand 3))
6734 (pc)))]
6735 "TARGET_QIMODE_MATH"
6736 {
6737 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6738 operands[1] = force_reg (QImode, operands[1]);
6739 })
6740
6741 (define_insn "*<u>mulvqi4"
6742 [(set (reg:CCO FLAGS_REG)
6743 (eq:CCO (mult:HI
6744 (any_extend:HI
6745 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6746 (any_extend:HI
6747 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6748 (any_extend:HI
6749 (mult:QI (match_dup 1) (match_dup 2)))))
6750 (set (match_operand:QI 0 "register_operand" "=a")
6751 (mult:QI (match_dup 1) (match_dup 2)))]
6752 "TARGET_QIMODE_MATH
6753 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6754 "<sgnprefix>mul{b}\t%2"
6755 [(set_attr "type" "imul")
6756 (set_attr "length_immediate" "0")
6757 (set (attr "athlon_decode")
6758 (if_then_else (eq_attr "cpu" "athlon")
6759 (const_string "vector")
6760 (const_string "direct")))
6761 (set_attr "amdfam10_decode" "direct")
6762 (set_attr "bdver1_decode" "direct")
6763 (set_attr "mode" "QI")])
6764
6765 (define_expand "<u>mul<mode><dwi>3"
6766 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6767 (mult:<DWI>
6768 (any_extend:<DWI>
6769 (match_operand:DWIH 1 "nonimmediate_operand"))
6770 (any_extend:<DWI>
6771 (match_operand:DWIH 2 "register_operand"))))
6772 (clobber (reg:CC FLAGS_REG))])])
6773
6774 (define_expand "<u>mulqihi3"
6775 [(parallel [(set (match_operand:HI 0 "register_operand")
6776 (mult:HI
6777 (any_extend:HI
6778 (match_operand:QI 1 "nonimmediate_operand"))
6779 (any_extend:HI
6780 (match_operand:QI 2 "register_operand"))))
6781 (clobber (reg:CC FLAGS_REG))])]
6782 "TARGET_QIMODE_MATH")
6783
6784 (define_insn "*bmi2_umulditi3_1"
6785 [(set (match_operand:DI 0 "register_operand" "=r")
6786 (mult:DI
6787 (match_operand:DI 2 "nonimmediate_operand" "%d")
6788 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6789 (set (match_operand:DI 1 "register_operand" "=r")
6790 (truncate:DI
6791 (lshiftrt:TI
6792 (mult:TI (zero_extend:TI (match_dup 2))
6793 (zero_extend:TI (match_dup 3)))
6794 (const_int 64))))]
6795 "TARGET_64BIT && TARGET_BMI2
6796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6797 "mulx\t{%3, %0, %1|%1, %0, %3}"
6798 [(set_attr "type" "imulx")
6799 (set_attr "prefix" "vex")
6800 (set_attr "mode" "DI")])
6801
6802 (define_insn "*bmi2_umulsidi3_1"
6803 [(set (match_operand:SI 0 "register_operand" "=r")
6804 (mult:SI
6805 (match_operand:SI 2 "nonimmediate_operand" "%d")
6806 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6807 (set (match_operand:SI 1 "register_operand" "=r")
6808 (truncate:SI
6809 (lshiftrt:DI
6810 (mult:DI (zero_extend:DI (match_dup 2))
6811 (zero_extend:DI (match_dup 3)))
6812 (const_int 32))))]
6813 "!TARGET_64BIT && TARGET_BMI2
6814 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6815 "mulx\t{%3, %0, %1|%1, %0, %3}"
6816 [(set_attr "type" "imulx")
6817 (set_attr "prefix" "vex")
6818 (set_attr "mode" "SI")])
6819
6820 (define_insn "*umul<mode><dwi>3_1"
6821 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6822 (mult:<DWI>
6823 (zero_extend:<DWI>
6824 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6825 (zero_extend:<DWI>
6826 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6827 (clobber (reg:CC FLAGS_REG))]
6828 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6829 "@
6830 #
6831 mul{<imodesuffix>}\t%2"
6832 [(set_attr "isa" "bmi2,*")
6833 (set_attr "type" "imulx,imul")
6834 (set_attr "length_immediate" "*,0")
6835 (set (attr "athlon_decode")
6836 (cond [(eq_attr "alternative" "1")
6837 (if_then_else (eq_attr "cpu" "athlon")
6838 (const_string "vector")
6839 (const_string "double"))]
6840 (const_string "*")))
6841 (set_attr "amdfam10_decode" "*,double")
6842 (set_attr "bdver1_decode" "*,direct")
6843 (set_attr "prefix" "vex,orig")
6844 (set_attr "mode" "<MODE>")])
6845
6846 ;; Convert mul to the mulx pattern to avoid flags dependency.
6847 (define_split
6848 [(set (match_operand:<DWI> 0 "register_operand")
6849 (mult:<DWI>
6850 (zero_extend:<DWI>
6851 (match_operand:DWIH 1 "register_operand"))
6852 (zero_extend:<DWI>
6853 (match_operand:DWIH 2 "nonimmediate_operand"))))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "TARGET_BMI2 && reload_completed
6856 && true_regnum (operands[1]) == DX_REG"
6857 [(parallel [(set (match_dup 3)
6858 (mult:DWIH (match_dup 1) (match_dup 2)))
6859 (set (match_dup 4)
6860 (truncate:DWIH
6861 (lshiftrt:<DWI>
6862 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6863 (zero_extend:<DWI> (match_dup 2)))
6864 (match_dup 5))))])]
6865 {
6866 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6867
6868 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6869 })
6870
6871 (define_insn "*mul<mode><dwi>3_1"
6872 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6873 (mult:<DWI>
6874 (sign_extend:<DWI>
6875 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6876 (sign_extend:<DWI>
6877 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6878 (clobber (reg:CC FLAGS_REG))]
6879 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6880 "imul{<imodesuffix>}\t%2"
6881 [(set_attr "type" "imul")
6882 (set_attr "length_immediate" "0")
6883 (set (attr "athlon_decode")
6884 (if_then_else (eq_attr "cpu" "athlon")
6885 (const_string "vector")
6886 (const_string "double")))
6887 (set_attr "amdfam10_decode" "double")
6888 (set_attr "bdver1_decode" "direct")
6889 (set_attr "mode" "<MODE>")])
6890
6891 (define_insn "*<u>mulqihi3_1"
6892 [(set (match_operand:HI 0 "register_operand" "=a")
6893 (mult:HI
6894 (any_extend:HI
6895 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6896 (any_extend:HI
6897 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6898 (clobber (reg:CC FLAGS_REG))]
6899 "TARGET_QIMODE_MATH
6900 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 "<sgnprefix>mul{b}\t%2"
6902 [(set_attr "type" "imul")
6903 (set_attr "length_immediate" "0")
6904 (set (attr "athlon_decode")
6905 (if_then_else (eq_attr "cpu" "athlon")
6906 (const_string "vector")
6907 (const_string "direct")))
6908 (set_attr "amdfam10_decode" "direct")
6909 (set_attr "bdver1_decode" "direct")
6910 (set_attr "mode" "QI")])
6911
6912 (define_expand "<s>mul<mode>3_highpart"
6913 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6914 (truncate:SWI48
6915 (lshiftrt:<DWI>
6916 (mult:<DWI>
6917 (any_extend:<DWI>
6918 (match_operand:SWI48 1 "nonimmediate_operand"))
6919 (any_extend:<DWI>
6920 (match_operand:SWI48 2 "register_operand")))
6921 (match_dup 4))))
6922 (clobber (match_scratch:SWI48 3))
6923 (clobber (reg:CC FLAGS_REG))])]
6924 ""
6925 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6926
6927 (define_insn "*<s>muldi3_highpart_1"
6928 [(set (match_operand:DI 0 "register_operand" "=d")
6929 (truncate:DI
6930 (lshiftrt:TI
6931 (mult:TI
6932 (any_extend:TI
6933 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6934 (any_extend:TI
6935 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6936 (const_int 64))))
6937 (clobber (match_scratch:DI 3 "=1"))
6938 (clobber (reg:CC FLAGS_REG))]
6939 "TARGET_64BIT
6940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941 "<sgnprefix>mul{q}\t%2"
6942 [(set_attr "type" "imul")
6943 (set_attr "length_immediate" "0")
6944 (set (attr "athlon_decode")
6945 (if_then_else (eq_attr "cpu" "athlon")
6946 (const_string "vector")
6947 (const_string "double")))
6948 (set_attr "amdfam10_decode" "double")
6949 (set_attr "bdver1_decode" "direct")
6950 (set_attr "mode" "DI")])
6951
6952 (define_insn "*<s>mulsi3_highpart_1"
6953 [(set (match_operand:SI 0 "register_operand" "=d")
6954 (truncate:SI
6955 (lshiftrt:DI
6956 (mult:DI
6957 (any_extend:DI
6958 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6959 (any_extend:DI
6960 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6961 (const_int 32))))
6962 (clobber (match_scratch:SI 3 "=1"))
6963 (clobber (reg:CC FLAGS_REG))]
6964 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965 "<sgnprefix>mul{l}\t%2"
6966 [(set_attr "type" "imul")
6967 (set_attr "length_immediate" "0")
6968 (set (attr "athlon_decode")
6969 (if_then_else (eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (const_string "double")))
6972 (set_attr "amdfam10_decode" "double")
6973 (set_attr "bdver1_decode" "direct")
6974 (set_attr "mode" "SI")])
6975
6976 (define_insn "*<s>mulsi3_highpart_zext"
6977 [(set (match_operand:DI 0 "register_operand" "=d")
6978 (zero_extend:DI (truncate:SI
6979 (lshiftrt:DI
6980 (mult:DI (any_extend:DI
6981 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6982 (any_extend:DI
6983 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6984 (const_int 32)))))
6985 (clobber (match_scratch:SI 3 "=1"))
6986 (clobber (reg:CC FLAGS_REG))]
6987 "TARGET_64BIT
6988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6989 "<sgnprefix>mul{l}\t%2"
6990 [(set_attr "type" "imul")
6991 (set_attr "length_immediate" "0")
6992 (set (attr "athlon_decode")
6993 (if_then_else (eq_attr "cpu" "athlon")
6994 (const_string "vector")
6995 (const_string "double")))
6996 (set_attr "amdfam10_decode" "double")
6997 (set_attr "bdver1_decode" "direct")
6998 (set_attr "mode" "SI")])
6999
7000 ;; The patterns that match these are at the end of this file.
7001
7002 (define_expand "mulxf3"
7003 [(set (match_operand:XF 0 "register_operand")
7004 (mult:XF (match_operand:XF 1 "register_operand")
7005 (match_operand:XF 2 "register_operand")))]
7006 "TARGET_80387")
7007
7008 (define_expand "mul<mode>3"
7009 [(set (match_operand:MODEF 0 "register_operand")
7010 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7011 (match_operand:MODEF 2 "nonimmediate_operand")))]
7012 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7013 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7014 \f
7015 ;; Divide instructions
7016
7017 ;; The patterns that match these are at the end of this file.
7018
7019 (define_expand "divxf3"
7020 [(set (match_operand:XF 0 "register_operand")
7021 (div:XF (match_operand:XF 1 "register_operand")
7022 (match_operand:XF 2 "register_operand")))]
7023 "TARGET_80387")
7024
7025 (define_expand "divdf3"
7026 [(set (match_operand:DF 0 "register_operand")
7027 (div:DF (match_operand:DF 1 "register_operand")
7028 (match_operand:DF 2 "nonimmediate_operand")))]
7029 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7030 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7031
7032 (define_expand "divsf3"
7033 [(set (match_operand:SF 0 "register_operand")
7034 (div:SF (match_operand:SF 1 "register_operand")
7035 (match_operand:SF 2 "nonimmediate_operand")))]
7036 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7037 || TARGET_SSE_MATH"
7038 {
7039 if (TARGET_SSE_MATH
7040 && TARGET_RECIP_DIV
7041 && optimize_insn_for_speed_p ()
7042 && flag_finite_math_only && !flag_trapping_math
7043 && flag_unsafe_math_optimizations)
7044 {
7045 ix86_emit_swdivsf (operands[0], operands[1],
7046 operands[2], SFmode);
7047 DONE;
7048 }
7049 })
7050 \f
7051 ;; Divmod instructions.
7052
7053 (define_expand "divmod<mode>4"
7054 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7055 (div:SWIM248
7056 (match_operand:SWIM248 1 "register_operand")
7057 (match_operand:SWIM248 2 "nonimmediate_operand")))
7058 (set (match_operand:SWIM248 3 "register_operand")
7059 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7060 (clobber (reg:CC FLAGS_REG))])])
7061
7062 ;; Split with 8bit unsigned divide:
7063 ;; if (dividend an divisor are in [0-255])
7064 ;; use 8bit unsigned integer divide
7065 ;; else
7066 ;; use original integer divide
7067 (define_split
7068 [(set (match_operand:SWI48 0 "register_operand")
7069 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7070 (match_operand:SWI48 3 "nonimmediate_operand")))
7071 (set (match_operand:SWI48 1 "register_operand")
7072 (mod:SWI48 (match_dup 2) (match_dup 3)))
7073 (clobber (reg:CC FLAGS_REG))]
7074 "TARGET_USE_8BIT_IDIV
7075 && TARGET_QIMODE_MATH
7076 && can_create_pseudo_p ()
7077 && !optimize_insn_for_size_p ()"
7078 [(const_int 0)]
7079 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7080
7081 (define_insn_and_split "divmod<mode>4_1"
7082 [(set (match_operand:SWI48 0 "register_operand" "=a")
7083 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7084 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7085 (set (match_operand:SWI48 1 "register_operand" "=&d")
7086 (mod:SWI48 (match_dup 2) (match_dup 3)))
7087 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7088 (clobber (reg:CC FLAGS_REG))]
7089 ""
7090 "#"
7091 "reload_completed"
7092 [(parallel [(set (match_dup 1)
7093 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7094 (clobber (reg:CC FLAGS_REG))])
7095 (parallel [(set (match_dup 0)
7096 (div:SWI48 (match_dup 2) (match_dup 3)))
7097 (set (match_dup 1)
7098 (mod:SWI48 (match_dup 2) (match_dup 3)))
7099 (use (match_dup 1))
7100 (clobber (reg:CC FLAGS_REG))])]
7101 {
7102 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7103
7104 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7105 operands[4] = operands[2];
7106 else
7107 {
7108 /* Avoid use of cltd in favor of a mov+shift. */
7109 emit_move_insn (operands[1], operands[2]);
7110 operands[4] = operands[1];
7111 }
7112 }
7113 [(set_attr "type" "multi")
7114 (set_attr "mode" "<MODE>")])
7115
7116 (define_insn_and_split "*divmod<mode>4"
7117 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7118 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7119 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7120 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7121 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7122 (clobber (reg:CC FLAGS_REG))]
7123 ""
7124 "#"
7125 "reload_completed"
7126 [(parallel [(set (match_dup 1)
7127 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7128 (clobber (reg:CC FLAGS_REG))])
7129 (parallel [(set (match_dup 0)
7130 (div:SWIM248 (match_dup 2) (match_dup 3)))
7131 (set (match_dup 1)
7132 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7133 (use (match_dup 1))
7134 (clobber (reg:CC FLAGS_REG))])]
7135 {
7136 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7137
7138 if (<MODE>mode != HImode
7139 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7140 operands[4] = operands[2];
7141 else
7142 {
7143 /* Avoid use of cltd in favor of a mov+shift. */
7144 emit_move_insn (operands[1], operands[2]);
7145 operands[4] = operands[1];
7146 }
7147 }
7148 [(set_attr "type" "multi")
7149 (set_attr "mode" "<MODE>")])
7150
7151 (define_insn "*divmod<mode>4_noext"
7152 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7153 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7154 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7155 (set (match_operand:SWIM248 1 "register_operand" "=d")
7156 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7157 (use (match_operand:SWIM248 4 "register_operand" "1"))
7158 (clobber (reg:CC FLAGS_REG))]
7159 ""
7160 "idiv{<imodesuffix>}\t%3"
7161 [(set_attr "type" "idiv")
7162 (set_attr "mode" "<MODE>")])
7163
7164 (define_expand "divmodqi4"
7165 [(parallel [(set (match_operand:QI 0 "register_operand")
7166 (div:QI
7167 (match_operand:QI 1 "register_operand")
7168 (match_operand:QI 2 "nonimmediate_operand")))
7169 (set (match_operand:QI 3 "register_operand")
7170 (mod:QI (match_dup 1) (match_dup 2)))
7171 (clobber (reg:CC FLAGS_REG))])]
7172 "TARGET_QIMODE_MATH"
7173 {
7174 rtx div, mod, insn;
7175 rtx tmp0, tmp1;
7176
7177 tmp0 = gen_reg_rtx (HImode);
7178 tmp1 = gen_reg_rtx (HImode);
7179
7180 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7181 in AX. */
7182 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7183 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7184
7185 /* Extract remainder from AH. */
7186 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7187 insn = emit_move_insn (operands[3], tmp1);
7188
7189 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7190 set_unique_reg_note (insn, REG_EQUAL, mod);
7191
7192 /* Extract quotient from AL. */
7193 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7194
7195 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7196 set_unique_reg_note (insn, REG_EQUAL, div);
7197
7198 DONE;
7199 })
7200
7201 ;; Divide AX by r/m8, with result stored in
7202 ;; AL <- Quotient
7203 ;; AH <- Remainder
7204 ;; Change div/mod to HImode and extend the second argument to HImode
7205 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7206 ;; combine may fail.
7207 (define_insn "divmodhiqi3"
7208 [(set (match_operand:HI 0 "register_operand" "=a")
7209 (ior:HI
7210 (ashift:HI
7211 (zero_extend:HI
7212 (truncate:QI
7213 (mod:HI (match_operand:HI 1 "register_operand" "0")
7214 (sign_extend:HI
7215 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7216 (const_int 8))
7217 (zero_extend:HI
7218 (truncate:QI
7219 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "TARGET_QIMODE_MATH"
7222 "idiv{b}\t%2"
7223 [(set_attr "type" "idiv")
7224 (set_attr "mode" "QI")])
7225
7226 (define_expand "udivmod<mode>4"
7227 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7228 (udiv:SWIM248
7229 (match_operand:SWIM248 1 "register_operand")
7230 (match_operand:SWIM248 2 "nonimmediate_operand")))
7231 (set (match_operand:SWIM248 3 "register_operand")
7232 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7233 (clobber (reg:CC FLAGS_REG))])])
7234
7235 ;; Split with 8bit unsigned divide:
7236 ;; if (dividend an divisor are in [0-255])
7237 ;; use 8bit unsigned integer divide
7238 ;; else
7239 ;; use original integer divide
7240 (define_split
7241 [(set (match_operand:SWI48 0 "register_operand")
7242 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7243 (match_operand:SWI48 3 "nonimmediate_operand")))
7244 (set (match_operand:SWI48 1 "register_operand")
7245 (umod:SWI48 (match_dup 2) (match_dup 3)))
7246 (clobber (reg:CC FLAGS_REG))]
7247 "TARGET_USE_8BIT_IDIV
7248 && TARGET_QIMODE_MATH
7249 && can_create_pseudo_p ()
7250 && !optimize_insn_for_size_p ()"
7251 [(const_int 0)]
7252 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7253
7254 (define_insn_and_split "udivmod<mode>4_1"
7255 [(set (match_operand:SWI48 0 "register_operand" "=a")
7256 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7257 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7258 (set (match_operand:SWI48 1 "register_operand" "=&d")
7259 (umod:SWI48 (match_dup 2) (match_dup 3)))
7260 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7261 (clobber (reg:CC FLAGS_REG))]
7262 ""
7263 "#"
7264 "reload_completed"
7265 [(set (match_dup 1) (const_int 0))
7266 (parallel [(set (match_dup 0)
7267 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7268 (set (match_dup 1)
7269 (umod:SWI48 (match_dup 2) (match_dup 3)))
7270 (use (match_dup 1))
7271 (clobber (reg:CC FLAGS_REG))])]
7272 ""
7273 [(set_attr "type" "multi")
7274 (set_attr "mode" "<MODE>")])
7275
7276 (define_insn_and_split "*udivmod<mode>4"
7277 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7278 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7279 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7280 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7281 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7282 (clobber (reg:CC FLAGS_REG))]
7283 ""
7284 "#"
7285 "reload_completed"
7286 [(set (match_dup 1) (const_int 0))
7287 (parallel [(set (match_dup 0)
7288 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7289 (set (match_dup 1)
7290 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7291 (use (match_dup 1))
7292 (clobber (reg:CC FLAGS_REG))])]
7293 ""
7294 [(set_attr "type" "multi")
7295 (set_attr "mode" "<MODE>")])
7296
7297 (define_insn "*udivmod<mode>4_noext"
7298 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7299 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7300 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7301 (set (match_operand:SWIM248 1 "register_operand" "=d")
7302 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7303 (use (match_operand:SWIM248 4 "register_operand" "1"))
7304 (clobber (reg:CC FLAGS_REG))]
7305 ""
7306 "div{<imodesuffix>}\t%3"
7307 [(set_attr "type" "idiv")
7308 (set_attr "mode" "<MODE>")])
7309
7310 (define_expand "udivmodqi4"
7311 [(parallel [(set (match_operand:QI 0 "register_operand")
7312 (udiv:QI
7313 (match_operand:QI 1 "register_operand")
7314 (match_operand:QI 2 "nonimmediate_operand")))
7315 (set (match_operand:QI 3 "register_operand")
7316 (umod:QI (match_dup 1) (match_dup 2)))
7317 (clobber (reg:CC FLAGS_REG))])]
7318 "TARGET_QIMODE_MATH"
7319 {
7320 rtx div, mod, insn;
7321 rtx tmp0, tmp1;
7322
7323 tmp0 = gen_reg_rtx (HImode);
7324 tmp1 = gen_reg_rtx (HImode);
7325
7326 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7327 in AX. */
7328 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7329 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7330
7331 /* Extract remainder from AH. */
7332 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7333 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7334 insn = emit_move_insn (operands[3], tmp1);
7335
7336 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7337 set_unique_reg_note (insn, REG_EQUAL, mod);
7338
7339 /* Extract quotient from AL. */
7340 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7341
7342 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7343 set_unique_reg_note (insn, REG_EQUAL, div);
7344
7345 DONE;
7346 })
7347
7348 (define_insn "udivmodhiqi3"
7349 [(set (match_operand:HI 0 "register_operand" "=a")
7350 (ior:HI
7351 (ashift:HI
7352 (zero_extend:HI
7353 (truncate:QI
7354 (mod:HI (match_operand:HI 1 "register_operand" "0")
7355 (zero_extend:HI
7356 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7357 (const_int 8))
7358 (zero_extend:HI
7359 (truncate:QI
7360 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7361 (clobber (reg:CC FLAGS_REG))]
7362 "TARGET_QIMODE_MATH"
7363 "div{b}\t%2"
7364 [(set_attr "type" "idiv")
7365 (set_attr "mode" "QI")])
7366
7367 ;; We cannot use div/idiv for double division, because it causes
7368 ;; "division by zero" on the overflow and that's not what we expect
7369 ;; from truncate. Because true (non truncating) double division is
7370 ;; never generated, we can't create this insn anyway.
7371 ;
7372 ;(define_insn ""
7373 ; [(set (match_operand:SI 0 "register_operand" "=a")
7374 ; (truncate:SI
7375 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7376 ; (zero_extend:DI
7377 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7378 ; (set (match_operand:SI 3 "register_operand" "=d")
7379 ; (truncate:SI
7380 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7381 ; (clobber (reg:CC FLAGS_REG))]
7382 ; ""
7383 ; "div{l}\t{%2, %0|%0, %2}"
7384 ; [(set_attr "type" "idiv")])
7385 \f
7386 ;;- Logical AND instructions
7387
7388 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7389 ;; Note that this excludes ah.
7390
7391 (define_expand "testsi_ccno_1"
7392 [(set (reg:CCNO FLAGS_REG)
7393 (compare:CCNO
7394 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7395 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7396 (const_int 0)))])
7397
7398 (define_expand "testqi_ccz_1"
7399 [(set (reg:CCZ FLAGS_REG)
7400 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7401 (match_operand:QI 1 "nonmemory_operand"))
7402 (const_int 0)))])
7403
7404 (define_expand "testdi_ccno_1"
7405 [(set (reg:CCNO FLAGS_REG)
7406 (compare:CCNO
7407 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7408 (match_operand:DI 1 "x86_64_szext_general_operand"))
7409 (const_int 0)))]
7410 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7411
7412 (define_insn "*testdi_1"
7413 [(set (reg FLAGS_REG)
7414 (compare
7415 (and:DI
7416 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7417 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7418 (const_int 0)))]
7419 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7421 "@
7422 test{l}\t{%k1, %k0|%k0, %k1}
7423 test{l}\t{%k1, %k0|%k0, %k1}
7424 test{q}\t{%1, %0|%0, %1}
7425 test{q}\t{%1, %0|%0, %1}
7426 test{q}\t{%1, %0|%0, %1}"
7427 [(set_attr "type" "test")
7428 (set_attr "modrm" "0,1,0,1,1")
7429 (set_attr "mode" "SI,SI,DI,DI,DI")])
7430
7431 (define_insn "*testqi_1_maybe_si"
7432 [(set (reg FLAGS_REG)
7433 (compare
7434 (and:QI
7435 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7436 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7437 (const_int 0)))]
7438 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7439 && ix86_match_ccmode (insn,
7440 CONST_INT_P (operands[1])
7441 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7442 {
7443 if (which_alternative == 3)
7444 {
7445 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7446 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7447 return "test{l}\t{%1, %k0|%k0, %1}";
7448 }
7449 return "test{b}\t{%1, %0|%0, %1}";
7450 }
7451 [(set_attr "type" "test")
7452 (set_attr "modrm" "0,1,1,1")
7453 (set_attr "mode" "QI,QI,QI,SI")
7454 (set_attr "pent_pair" "uv,np,uv,np")])
7455
7456 (define_insn "*test<mode>_1"
7457 [(set (reg FLAGS_REG)
7458 (compare
7459 (and:SWI124
7460 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7461 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7462 (const_int 0)))]
7463 "ix86_match_ccmode (insn, CCNOmode)
7464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7465 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7466 [(set_attr "type" "test")
7467 (set_attr "modrm" "0,1,1")
7468 (set_attr "mode" "<MODE>")
7469 (set_attr "pent_pair" "uv,np,uv")])
7470
7471 (define_expand "testqi_ext_ccno_0"
7472 [(set (reg:CCNO FLAGS_REG)
7473 (compare:CCNO
7474 (and:SI
7475 (zero_extract:SI
7476 (match_operand 0 "ext_register_operand")
7477 (const_int 8)
7478 (const_int 8))
7479 (match_operand 1 "const_int_operand"))
7480 (const_int 0)))])
7481
7482 (define_insn "*testqi_ext_0"
7483 [(set (reg FLAGS_REG)
7484 (compare
7485 (and:SI
7486 (zero_extract:SI
7487 (match_operand 0 "ext_register_operand" "Q")
7488 (const_int 8)
7489 (const_int 8))
7490 (match_operand 1 "const_int_operand" "n"))
7491 (const_int 0)))]
7492 "ix86_match_ccmode (insn, CCNOmode)"
7493 "test{b}\t{%1, %h0|%h0, %1}"
7494 [(set_attr "type" "test")
7495 (set_attr "mode" "QI")
7496 (set_attr "length_immediate" "1")
7497 (set_attr "modrm" "1")
7498 (set_attr "pent_pair" "np")])
7499
7500 (define_insn "*testqi_ext_1"
7501 [(set (reg FLAGS_REG)
7502 (compare
7503 (and:SI
7504 (zero_extract:SI
7505 (match_operand 0 "ext_register_operand" "Q,Q")
7506 (const_int 8)
7507 (const_int 8))
7508 (zero_extend:SI
7509 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7510 (const_int 0)))]
7511 "ix86_match_ccmode (insn, CCNOmode)"
7512 "test{b}\t{%1, %h0|%h0, %1}"
7513 [(set_attr "isa" "*,nox64")
7514 (set_attr "type" "test")
7515 (set_attr "mode" "QI")])
7516
7517 (define_insn "*testqi_ext_2"
7518 [(set (reg FLAGS_REG)
7519 (compare
7520 (and:SI
7521 (zero_extract:SI
7522 (match_operand 0 "ext_register_operand" "Q")
7523 (const_int 8)
7524 (const_int 8))
7525 (zero_extract:SI
7526 (match_operand 1 "ext_register_operand" "Q")
7527 (const_int 8)
7528 (const_int 8)))
7529 (const_int 0)))]
7530 "ix86_match_ccmode (insn, CCNOmode)"
7531 "test{b}\t{%h1, %h0|%h0, %h1}"
7532 [(set_attr "type" "test")
7533 (set_attr "mode" "QI")])
7534
7535 ;; Combine likes to form bit extractions for some tests. Humor it.
7536 (define_insn "*testqi_ext_3"
7537 [(set (reg FLAGS_REG)
7538 (compare (zero_extract:SWI48
7539 (match_operand 0 "nonimmediate_operand" "rm")
7540 (match_operand:SWI48 1 "const_int_operand")
7541 (match_operand:SWI48 2 "const_int_operand"))
7542 (const_int 0)))]
7543 "ix86_match_ccmode (insn, CCNOmode)
7544 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7545 || GET_MODE (operands[0]) == SImode
7546 || GET_MODE (operands[0]) == HImode
7547 || GET_MODE (operands[0]) == QImode)
7548 /* Ensure that resulting mask is zero or sign extended operand. */
7549 && INTVAL (operands[2]) >= 0
7550 && ((INTVAL (operands[1]) > 0
7551 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7552 || (<MODE>mode == DImode
7553 && INTVAL (operands[1]) > 32
7554 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7555 "#")
7556
7557 (define_split
7558 [(set (match_operand 0 "flags_reg_operand")
7559 (match_operator 1 "compare_operator"
7560 [(zero_extract
7561 (match_operand 2 "nonimmediate_operand")
7562 (match_operand 3 "const_int_operand")
7563 (match_operand 4 "const_int_operand"))
7564 (const_int 0)]))]
7565 "ix86_match_ccmode (insn, CCNOmode)"
7566 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7567 {
7568 rtx val = operands[2];
7569 HOST_WIDE_INT len = INTVAL (operands[3]);
7570 HOST_WIDE_INT pos = INTVAL (operands[4]);
7571 HOST_WIDE_INT mask;
7572 machine_mode mode, submode;
7573
7574 mode = GET_MODE (val);
7575 if (MEM_P (val))
7576 {
7577 /* ??? Combine likes to put non-volatile mem extractions in QImode
7578 no matter the size of the test. So find a mode that works. */
7579 if (! MEM_VOLATILE_P (val))
7580 {
7581 mode = smallest_mode_for_size (pos + len, MODE_INT);
7582 val = adjust_address (val, mode, 0);
7583 }
7584 }
7585 else if (GET_CODE (val) == SUBREG
7586 && (submode = GET_MODE (SUBREG_REG (val)),
7587 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7588 && pos + len <= GET_MODE_BITSIZE (submode)
7589 && GET_MODE_CLASS (submode) == MODE_INT)
7590 {
7591 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7592 mode = submode;
7593 val = SUBREG_REG (val);
7594 }
7595 else if (mode == HImode && pos + len <= 8)
7596 {
7597 /* Small HImode tests can be converted to QImode. */
7598 mode = QImode;
7599 val = gen_lowpart (QImode, val);
7600 }
7601
7602 if (len == HOST_BITS_PER_WIDE_INT)
7603 mask = -1;
7604 else
7605 mask = ((HOST_WIDE_INT)1 << len) - 1;
7606 mask <<= pos;
7607
7608 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7609 })
7610
7611 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7612 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7613 ;; this is relatively important trick.
7614 ;; Do the conversion only post-reload to avoid limiting of the register class
7615 ;; to QI regs.
7616 (define_split
7617 [(set (match_operand 0 "flags_reg_operand")
7618 (match_operator 1 "compare_operator"
7619 [(and (match_operand 2 "register_operand")
7620 (match_operand 3 "const_int_operand"))
7621 (const_int 0)]))]
7622 "reload_completed
7623 && QI_REG_P (operands[2])
7624 && GET_MODE (operands[2]) != QImode
7625 && ((ix86_match_ccmode (insn, CCZmode)
7626 && !(INTVAL (operands[3]) & ~(255 << 8)))
7627 || (ix86_match_ccmode (insn, CCNOmode)
7628 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7629 [(set (match_dup 0)
7630 (match_op_dup 1
7631 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7632 (match_dup 3))
7633 (const_int 0)]))]
7634 {
7635 operands[2] = gen_lowpart (SImode, operands[2]);
7636 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7637 })
7638
7639 (define_split
7640 [(set (match_operand 0 "flags_reg_operand")
7641 (match_operator 1 "compare_operator"
7642 [(and (match_operand 2 "nonimmediate_operand")
7643 (match_operand 3 "const_int_operand"))
7644 (const_int 0)]))]
7645 "reload_completed
7646 && GET_MODE (operands[2]) != QImode
7647 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7648 && ((ix86_match_ccmode (insn, CCZmode)
7649 && !(INTVAL (operands[3]) & ~255))
7650 || (ix86_match_ccmode (insn, CCNOmode)
7651 && !(INTVAL (operands[3]) & ~127)))"
7652 [(set (match_dup 0)
7653 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7654 (const_int 0)]))]
7655 {
7656 operands[2] = gen_lowpart (QImode, operands[2]);
7657 operands[3] = gen_lowpart (QImode, operands[3]);
7658 })
7659
7660 (define_split
7661 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7662 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7663 (match_operand:SWI1248x 2 "mask_reg_operand")))
7664 (clobber (reg:CC FLAGS_REG))]
7665 "TARGET_AVX512F && reload_completed"
7666 [(set (match_dup 0)
7667 (any_logic:SWI1248x (match_dup 1)
7668 (match_dup 2)))])
7669
7670 (define_insn "*k<logic><mode>"
7671 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7672 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7673 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7674 "TARGET_AVX512F"
7675 {
7676 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7677 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7678 else
7679 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7680 }
7681 [(set_attr "mode" "<MODE>")
7682 (set_attr "type" "msklog")
7683 (set_attr "prefix" "vex")])
7684
7685 ;; %%% This used to optimize known byte-wide and operations to memory,
7686 ;; and sometimes to QImode registers. If this is considered useful,
7687 ;; it should be done with splitters.
7688
7689 (define_expand "and<mode>3"
7690 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7691 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7692 (match_operand:SWIM 2 "<general_szext_operand>")))]
7693 ""
7694 {
7695 machine_mode mode = <MODE>mode;
7696 rtx (*insn) (rtx, rtx);
7697
7698 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7699 {
7700 HOST_WIDE_INT ival = INTVAL (operands[2]);
7701
7702 if (ival == (HOST_WIDE_INT) 0xffffffff)
7703 mode = SImode;
7704 else if (ival == 0xffff)
7705 mode = HImode;
7706 else if (ival == 0xff)
7707 mode = QImode;
7708 }
7709
7710 if (mode == <MODE>mode)
7711 {
7712 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7713 DONE;
7714 }
7715
7716 if (<MODE>mode == DImode)
7717 insn = (mode == SImode)
7718 ? gen_zero_extendsidi2
7719 : (mode == HImode)
7720 ? gen_zero_extendhidi2
7721 : gen_zero_extendqidi2;
7722 else if (<MODE>mode == SImode)
7723 insn = (mode == HImode)
7724 ? gen_zero_extendhisi2
7725 : gen_zero_extendqisi2;
7726 else if (<MODE>mode == HImode)
7727 insn = gen_zero_extendqihi2;
7728 else
7729 gcc_unreachable ();
7730
7731 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7732 DONE;
7733 })
7734
7735 (define_insn "*anddi_1"
7736 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7737 (and:DI
7738 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7739 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7740 (clobber (reg:CC FLAGS_REG))]
7741 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7742 {
7743 switch (get_attr_type (insn))
7744 {
7745 case TYPE_IMOVX:
7746 return "#";
7747
7748 case TYPE_MSKLOG:
7749 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7750
7751 default:
7752 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7753 if (get_attr_mode (insn) == MODE_SI)
7754 return "and{l}\t{%k2, %k0|%k0, %k2}";
7755 else
7756 return "and{q}\t{%2, %0|%0, %2}";
7757 }
7758 }
7759 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7760 (set_attr "length_immediate" "*,*,*,0,0")
7761 (set (attr "prefix_rex")
7762 (if_then_else
7763 (and (eq_attr "type" "imovx")
7764 (and (match_test "INTVAL (operands[2]) == 0xff")
7765 (match_operand 1 "ext_QIreg_operand")))
7766 (const_string "1")
7767 (const_string "*")))
7768 (set_attr "mode" "SI,DI,DI,SI,DI")])
7769
7770 (define_insn "*andsi_1"
7771 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7772 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7773 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7774 (clobber (reg:CC FLAGS_REG))]
7775 "ix86_binary_operator_ok (AND, SImode, operands)"
7776 {
7777 switch (get_attr_type (insn))
7778 {
7779 case TYPE_IMOVX:
7780 return "#";
7781
7782 case TYPE_MSKLOG:
7783 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7784
7785 default:
7786 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7787 return "and{l}\t{%2, %0|%0, %2}";
7788 }
7789 }
7790 [(set_attr "type" "alu,alu,imovx,msklog")
7791 (set (attr "prefix_rex")
7792 (if_then_else
7793 (and (eq_attr "type" "imovx")
7794 (and (match_test "INTVAL (operands[2]) == 0xff")
7795 (match_operand 1 "ext_QIreg_operand")))
7796 (const_string "1")
7797 (const_string "*")))
7798 (set_attr "length_immediate" "*,*,0,0")
7799 (set_attr "mode" "SI")])
7800
7801 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7802 (define_insn "*andsi_1_zext"
7803 [(set (match_operand:DI 0 "register_operand" "=r")
7804 (zero_extend:DI
7805 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7806 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7807 (clobber (reg:CC FLAGS_REG))]
7808 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7809 "and{l}\t{%2, %k0|%k0, %2}"
7810 [(set_attr "type" "alu")
7811 (set_attr "mode" "SI")])
7812
7813 (define_insn "*andhi_1"
7814 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7815 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7816 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7817 (clobber (reg:CC FLAGS_REG))]
7818 "ix86_binary_operator_ok (AND, HImode, operands)"
7819 {
7820 switch (get_attr_type (insn))
7821 {
7822 case TYPE_IMOVX:
7823 return "#";
7824
7825 case TYPE_MSKLOG:
7826 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7827
7828 default:
7829 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7830 return "and{w}\t{%2, %0|%0, %2}";
7831 }
7832 }
7833 [(set_attr "type" "alu,alu,imovx,msklog")
7834 (set_attr "length_immediate" "*,*,0,*")
7835 (set (attr "prefix_rex")
7836 (if_then_else
7837 (and (eq_attr "type" "imovx")
7838 (match_operand 1 "ext_QIreg_operand"))
7839 (const_string "1")
7840 (const_string "*")))
7841 (set_attr "mode" "HI,HI,SI,HI")])
7842
7843 ;; %%% Potential partial reg stall on alternative 2. What to do?
7844 (define_insn "*andqi_1"
7845 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7846 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7847 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "ix86_binary_operator_ok (AND, QImode, operands)"
7850 {
7851 switch (which_alternative)
7852 {
7853 case 0:
7854 case 1:
7855 return "and{b}\t{%2, %0|%0, %2}";
7856 case 2:
7857 return "and{l}\t{%k2, %k0|%k0, %k2}";
7858 case 3:
7859 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7860 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7861 default:
7862 gcc_unreachable ();
7863 }
7864 }
7865 [(set_attr "type" "alu,alu,alu,msklog")
7866 (set_attr "mode" "QI,QI,SI,HI")])
7867
7868 (define_insn "*andqi_1_slp"
7869 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7870 (and:QI (match_dup 0)
7871 (match_operand:QI 1 "general_operand" "qn,qmn")))
7872 (clobber (reg:CC FLAGS_REG))]
7873 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7875 "and{b}\t{%1, %0|%0, %1}"
7876 [(set_attr "type" "alu1")
7877 (set_attr "mode" "QI")])
7878
7879 (define_insn "kandn<mode>"
7880 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7881 (and:SWI12
7882 (not:SWI12
7883 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7884 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "TARGET_AVX512F"
7887 {
7888 switch (which_alternative)
7889 {
7890 case 0:
7891 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7892 case 1:
7893 return "#";
7894 case 2:
7895 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7896 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7897 else
7898 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7899 default:
7900 gcc_unreachable ();
7901 }
7902 }
7903 [(set_attr "isa" "bmi,*,avx512f")
7904 (set_attr "type" "bitmanip,*,msklog")
7905 (set_attr "prefix" "*,*,vex")
7906 (set_attr "btver2_decode" "direct,*,*")
7907 (set_attr "mode" "<MODE>")])
7908
7909 (define_split
7910 [(set (match_operand:SWI12 0 "general_reg_operand")
7911 (and:SWI12
7912 (not:SWI12
7913 (match_dup 0))
7914 (match_operand:SWI12 1 "general_reg_operand")))
7915 (clobber (reg:CC FLAGS_REG))]
7916 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7917 [(set (match_dup 0)
7918 (not:HI (match_dup 0)))
7919 (parallel [(set (match_dup 0)
7920 (and:HI (match_dup 0)
7921 (match_dup 1)))
7922 (clobber (reg:CC FLAGS_REG))])])
7923
7924 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7925 (define_split
7926 [(set (match_operand:DI 0 "register_operand")
7927 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7928 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7929 (clobber (reg:CC FLAGS_REG))]
7930 "TARGET_64BIT"
7931 [(parallel [(set (match_dup 0)
7932 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7933 (clobber (reg:CC FLAGS_REG))])]
7934 "operands[2] = gen_lowpart (SImode, operands[2]);")
7935
7936 (define_split
7937 [(set (match_operand:SWI248 0 "register_operand")
7938 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7939 (match_operand:SWI248 2 "const_int_operand")))
7940 (clobber (reg:CC FLAGS_REG))]
7941 "reload_completed
7942 && true_regnum (operands[0]) != true_regnum (operands[1])"
7943 [(const_int 0)]
7944 {
7945 HOST_WIDE_INT ival = INTVAL (operands[2]);
7946 machine_mode mode;
7947 rtx (*insn) (rtx, rtx);
7948
7949 if (ival == (HOST_WIDE_INT) 0xffffffff)
7950 mode = SImode;
7951 else if (ival == 0xffff)
7952 mode = HImode;
7953 else
7954 {
7955 gcc_assert (ival == 0xff);
7956 mode = QImode;
7957 }
7958
7959 if (<MODE>mode == DImode)
7960 insn = (mode == SImode)
7961 ? gen_zero_extendsidi2
7962 : (mode == HImode)
7963 ? gen_zero_extendhidi2
7964 : gen_zero_extendqidi2;
7965 else
7966 {
7967 if (<MODE>mode != SImode)
7968 /* Zero extend to SImode to avoid partial register stalls. */
7969 operands[0] = gen_lowpart (SImode, operands[0]);
7970
7971 insn = (mode == HImode)
7972 ? gen_zero_extendhisi2
7973 : gen_zero_extendqisi2;
7974 }
7975 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7976 DONE;
7977 })
7978
7979 (define_split
7980 [(set (match_operand 0 "register_operand")
7981 (and (match_dup 0)
7982 (const_int -65536)))
7983 (clobber (reg:CC FLAGS_REG))]
7984 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7985 || optimize_function_for_size_p (cfun)"
7986 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7987 "operands[1] = gen_lowpart (HImode, operands[0]);")
7988
7989 (define_split
7990 [(set (match_operand 0 "ext_register_operand")
7991 (and (match_dup 0)
7992 (const_int -256)))
7993 (clobber (reg:CC FLAGS_REG))]
7994 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7995 && reload_completed"
7996 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7997 "operands[1] = gen_lowpart (QImode, operands[0]);")
7998
7999 (define_split
8000 [(set (match_operand 0 "ext_register_operand")
8001 (and (match_dup 0)
8002 (const_int -65281)))
8003 (clobber (reg:CC FLAGS_REG))]
8004 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005 && reload_completed"
8006 [(parallel [(set (zero_extract:SI (match_dup 0)
8007 (const_int 8)
8008 (const_int 8))
8009 (xor:SI
8010 (zero_extract:SI (match_dup 0)
8011 (const_int 8)
8012 (const_int 8))
8013 (zero_extract:SI (match_dup 0)
8014 (const_int 8)
8015 (const_int 8))))
8016 (clobber (reg:CC FLAGS_REG))])]
8017 "operands[0] = gen_lowpart (SImode, operands[0]);")
8018
8019 (define_insn "*anddi_2"
8020 [(set (reg FLAGS_REG)
8021 (compare
8022 (and:DI
8023 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8024 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8025 (const_int 0)))
8026 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8027 (and:DI (match_dup 1) (match_dup 2)))]
8028 "TARGET_64BIT
8029 && ix86_match_ccmode
8030 (insn,
8031 /* If we are going to emit andl instead of andq, and the operands[2]
8032 constant might have the SImode sign bit set, make sure the sign
8033 flag isn't tested, because the instruction will set the sign flag
8034 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8035 conservatively assume it might have bit 31 set. */
8036 (satisfies_constraint_Z (operands[2])
8037 && (!CONST_INT_P (operands[2])
8038 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8039 ? CCZmode : CCNOmode)
8040 && ix86_binary_operator_ok (AND, DImode, operands)"
8041 "@
8042 and{l}\t{%k2, %k0|%k0, %k2}
8043 and{q}\t{%2, %0|%0, %2}
8044 and{q}\t{%2, %0|%0, %2}"
8045 [(set_attr "type" "alu")
8046 (set_attr "mode" "SI,DI,DI")])
8047
8048 (define_insn "*andqi_2_maybe_si"
8049 [(set (reg FLAGS_REG)
8050 (compare (and:QI
8051 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8052 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8053 (const_int 0)))
8054 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8055 (and:QI (match_dup 1) (match_dup 2)))]
8056 "ix86_binary_operator_ok (AND, QImode, operands)
8057 && ix86_match_ccmode (insn,
8058 CONST_INT_P (operands[2])
8059 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8060 {
8061 if (which_alternative == 2)
8062 {
8063 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8064 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8065 return "and{l}\t{%2, %k0|%k0, %2}";
8066 }
8067 return "and{b}\t{%2, %0|%0, %2}";
8068 }
8069 [(set_attr "type" "alu")
8070 (set_attr "mode" "QI,QI,SI")])
8071
8072 (define_insn "*and<mode>_2"
8073 [(set (reg FLAGS_REG)
8074 (compare (and:SWI124
8075 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8076 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8077 (const_int 0)))
8078 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8079 (and:SWI124 (match_dup 1) (match_dup 2)))]
8080 "ix86_match_ccmode (insn, CCNOmode)
8081 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8082 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8083 [(set_attr "type" "alu")
8084 (set_attr "mode" "<MODE>")])
8085
8086 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8087 (define_insn "*andsi_2_zext"
8088 [(set (reg FLAGS_REG)
8089 (compare (and:SI
8090 (match_operand:SI 1 "nonimmediate_operand" "%0")
8091 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8092 (const_int 0)))
8093 (set (match_operand:DI 0 "register_operand" "=r")
8094 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8095 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8096 && ix86_binary_operator_ok (AND, SImode, operands)"
8097 "and{l}\t{%2, %k0|%k0, %2}"
8098 [(set_attr "type" "alu")
8099 (set_attr "mode" "SI")])
8100
8101 (define_insn "*andqi_2_slp"
8102 [(set (reg FLAGS_REG)
8103 (compare (and:QI
8104 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8105 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8106 (const_int 0)))
8107 (set (strict_low_part (match_dup 0))
8108 (and:QI (match_dup 0) (match_dup 1)))]
8109 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8110 && ix86_match_ccmode (insn, CCNOmode)
8111 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8112 "and{b}\t{%1, %0|%0, %1}"
8113 [(set_attr "type" "alu1")
8114 (set_attr "mode" "QI")])
8115
8116 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8117 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8118 ;; for a QImode operand, which of course failed.
8119 (define_insn "andqi_ext_0"
8120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8121 (const_int 8)
8122 (const_int 8))
8123 (and:SI
8124 (zero_extract:SI
8125 (match_operand 1 "ext_register_operand" "0")
8126 (const_int 8)
8127 (const_int 8))
8128 (match_operand 2 "const_int_operand" "n")))
8129 (clobber (reg:CC FLAGS_REG))]
8130 ""
8131 "and{b}\t{%2, %h0|%h0, %2}"
8132 [(set_attr "type" "alu")
8133 (set_attr "length_immediate" "1")
8134 (set_attr "modrm" "1")
8135 (set_attr "mode" "QI")])
8136
8137 ;; Generated by peephole translating test to and. This shows up
8138 ;; often in fp comparisons.
8139 (define_insn "*andqi_ext_0_cc"
8140 [(set (reg FLAGS_REG)
8141 (compare
8142 (and:SI
8143 (zero_extract:SI
8144 (match_operand 1 "ext_register_operand" "0")
8145 (const_int 8)
8146 (const_int 8))
8147 (match_operand 2 "const_int_operand" "n"))
8148 (const_int 0)))
8149 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8150 (const_int 8)
8151 (const_int 8))
8152 (and:SI
8153 (zero_extract:SI
8154 (match_dup 1)
8155 (const_int 8)
8156 (const_int 8))
8157 (match_dup 2)))]
8158 "ix86_match_ccmode (insn, CCNOmode)"
8159 "and{b}\t{%2, %h0|%h0, %2}"
8160 [(set_attr "type" "alu")
8161 (set_attr "length_immediate" "1")
8162 (set_attr "modrm" "1")
8163 (set_attr "mode" "QI")])
8164
8165 (define_insn "*andqi_ext_1"
8166 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8167 (const_int 8)
8168 (const_int 8))
8169 (and:SI
8170 (zero_extract:SI
8171 (match_operand 1 "ext_register_operand" "0,0")
8172 (const_int 8)
8173 (const_int 8))
8174 (zero_extend:SI
8175 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8176 (clobber (reg:CC FLAGS_REG))]
8177 ""
8178 "and{b}\t{%2, %h0|%h0, %2}"
8179 [(set_attr "isa" "*,nox64")
8180 (set_attr "type" "alu")
8181 (set_attr "length_immediate" "0")
8182 (set_attr "mode" "QI")])
8183
8184 (define_insn "*andqi_ext_2"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8186 (const_int 8)
8187 (const_int 8))
8188 (and:SI
8189 (zero_extract:SI
8190 (match_operand 1 "ext_register_operand" "%0")
8191 (const_int 8)
8192 (const_int 8))
8193 (zero_extract:SI
8194 (match_operand 2 "ext_register_operand" "Q")
8195 (const_int 8)
8196 (const_int 8))))
8197 (clobber (reg:CC FLAGS_REG))]
8198 ""
8199 "and{b}\t{%h2, %h0|%h0, %h2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "length_immediate" "0")
8202 (set_attr "mode" "QI")])
8203
8204 ;; Convert wide AND instructions with immediate operand to shorter QImode
8205 ;; equivalents when possible.
8206 ;; Don't do the splitting with memory operands, since it introduces risk
8207 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8208 ;; for size, but that can (should?) be handled by generic code instead.
8209 (define_split
8210 [(set (match_operand 0 "register_operand")
8211 (and (match_operand 1 "register_operand")
8212 (match_operand 2 "const_int_operand")))
8213 (clobber (reg:CC FLAGS_REG))]
8214 "reload_completed
8215 && QI_REG_P (operands[0])
8216 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8217 && !(~INTVAL (operands[2]) & ~(255 << 8))
8218 && GET_MODE (operands[0]) != QImode"
8219 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8220 (and:SI (zero_extract:SI (match_dup 1)
8221 (const_int 8) (const_int 8))
8222 (match_dup 2)))
8223 (clobber (reg:CC FLAGS_REG))])]
8224 {
8225 operands[0] = gen_lowpart (SImode, operands[0]);
8226 operands[1] = gen_lowpart (SImode, operands[1]);
8227 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8228 })
8229
8230 ;; Since AND can be encoded with sign extended immediate, this is only
8231 ;; profitable when 7th bit is not set.
8232 (define_split
8233 [(set (match_operand 0 "register_operand")
8234 (and (match_operand 1 "general_operand")
8235 (match_operand 2 "const_int_operand")))
8236 (clobber (reg:CC FLAGS_REG))]
8237 "reload_completed
8238 && ANY_QI_REG_P (operands[0])
8239 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8240 && !(~INTVAL (operands[2]) & ~255)
8241 && !(INTVAL (operands[2]) & 128)
8242 && GET_MODE (operands[0]) != QImode"
8243 [(parallel [(set (strict_low_part (match_dup 0))
8244 (and:QI (match_dup 1)
8245 (match_dup 2)))
8246 (clobber (reg:CC FLAGS_REG))])]
8247 {
8248 operands[0] = gen_lowpart (QImode, operands[0]);
8249 operands[1] = gen_lowpart (QImode, operands[1]);
8250 operands[2] = gen_lowpart (QImode, operands[2]);
8251 })
8252 \f
8253 ;; Logical inclusive and exclusive OR instructions
8254
8255 ;; %%% This used to optimize known byte-wide and operations to memory.
8256 ;; If this is considered useful, it should be done with splitters.
8257
8258 (define_expand "<code><mode>3"
8259 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8260 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8261 (match_operand:SWIM 2 "<general_operand>")))]
8262 ""
8263 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8264
8265 (define_insn "*<code><mode>_1"
8266 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8267 (any_or:SWI48
8268 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8269 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8272 "@
8273 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8274 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8275 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8276 [(set_attr "type" "alu,alu,msklog")
8277 (set_attr "mode" "<MODE>")])
8278
8279 (define_insn "*<code>hi_1"
8280 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8281 (any_or:HI
8282 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8283 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8284 (clobber (reg:CC FLAGS_REG))]
8285 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8286 "@
8287 <logic>{w}\t{%2, %0|%0, %2}
8288 <logic>{w}\t{%2, %0|%0, %2}
8289 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8290 [(set_attr "type" "alu,alu,msklog")
8291 (set_attr "mode" "HI")])
8292
8293 ;; %%% Potential partial reg stall on alternative 2. What to do?
8294 (define_insn "*<code>qi_1"
8295 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8296 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8297 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8300 "@
8301 <logic>{b}\t{%2, %0|%0, %2}
8302 <logic>{b}\t{%2, %0|%0, %2}
8303 <logic>{l}\t{%k2, %k0|%k0, %k2}
8304 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8305 [(set_attr "type" "alu,alu,alu,msklog")
8306 (set_attr "mode" "QI,QI,SI,HI")])
8307
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*<code>si_1_zext"
8310 [(set (match_operand:DI 0 "register_operand" "=r")
8311 (zero_extend:DI
8312 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8313 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8316 "<logic>{l}\t{%2, %k0|%k0, %2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "mode" "SI")])
8319
8320 (define_insn "*<code>si_1_zext_imm"
8321 [(set (match_operand:DI 0 "register_operand" "=r")
8322 (any_or:DI
8323 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8324 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8327 "<logic>{l}\t{%2, %k0|%k0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "SI")])
8330
8331 (define_insn "*<code>qi_1_slp"
8332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8333 (any_or:QI (match_dup 0)
8334 (match_operand:QI 1 "general_operand" "qmn,qn")))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8337 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8338 "<logic>{b}\t{%1, %0|%0, %1}"
8339 [(set_attr "type" "alu1")
8340 (set_attr "mode" "QI")])
8341
8342 (define_insn "*<code><mode>_2"
8343 [(set (reg FLAGS_REG)
8344 (compare (any_or:SWI
8345 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8346 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8347 (const_int 0)))
8348 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8349 (any_or:SWI (match_dup 1) (match_dup 2)))]
8350 "ix86_match_ccmode (insn, CCNOmode)
8351 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8352 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "<MODE>")])
8355
8356 (define_insn "kxnor<mode>"
8357 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8358 (not:SWI12
8359 (xor:SWI12
8360 (match_operand:SWI12 1 "register_operand" "0,k")
8361 (match_operand:SWI12 2 "register_operand" "r,k"))))
8362 (clobber (reg:CC FLAGS_REG))]
8363 "TARGET_AVX512F"
8364 {
8365 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8366 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8367 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8368 }
8369 [(set_attr "type" "*,msklog")
8370 (set_attr "prefix" "*,vex")
8371 (set_attr "mode" "<MODE>")])
8372
8373 (define_insn "kxnor<mode>"
8374 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8375 (not:SWI48x
8376 (xor:SWI48x
8377 (match_operand:SWI48x 1 "register_operand" "0,k")
8378 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8379 (clobber (reg:CC FLAGS_REG))]
8380 "TARGET_AVX512BW"
8381 "@
8382 #
8383 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8384 [(set_attr "type" "*,msklog")
8385 (set_attr "prefix" "*,vex")
8386 (set_attr "mode" "<MODE>")])
8387
8388 (define_split
8389 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8390 (not:SWI1248x
8391 (xor:SWI1248x
8392 (match_dup 0)
8393 (match_operand:SWI1248x 1 "general_reg_operand"))))
8394 (clobber (reg:CC FLAGS_REG))]
8395 "TARGET_AVX512F && reload_completed"
8396 [(parallel [(set (match_dup 0)
8397 (xor:HI (match_dup 0)
8398 (match_dup 1)))
8399 (clobber (reg:CC FLAGS_REG))])
8400 (set (match_dup 0)
8401 (not:HI (match_dup 0)))])
8402
8403 ;;There are kortrest[bdq] but no intrinsics for them.
8404 ;;We probably don't need to implement them.
8405 (define_insn "kortestzhi"
8406 [(set (reg:CCZ FLAGS_REG)
8407 (compare:CCZ
8408 (ior:HI
8409 (match_operand:HI 0 "register_operand" "k")
8410 (match_operand:HI 1 "register_operand" "k"))
8411 (const_int 0)))]
8412 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8413 "kortestw\t{%1, %0|%0, %1}"
8414 [(set_attr "mode" "HI")
8415 (set_attr "type" "msklog")
8416 (set_attr "prefix" "vex")])
8417
8418 (define_insn "kortestchi"
8419 [(set (reg:CCC FLAGS_REG)
8420 (compare:CCC
8421 (ior:HI
8422 (match_operand:HI 0 "register_operand" "k")
8423 (match_operand:HI 1 "register_operand" "k"))
8424 (const_int -1)))]
8425 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8426 "kortestw\t{%1, %0|%0, %1}"
8427 [(set_attr "mode" "HI")
8428 (set_attr "type" "msklog")
8429 (set_attr "prefix" "vex")])
8430
8431 (define_insn "kunpckhi"
8432 [(set (match_operand:HI 0 "register_operand" "=k")
8433 (ior:HI
8434 (ashift:HI
8435 (match_operand:HI 1 "register_operand" "k")
8436 (const_int 8))
8437 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8438 "TARGET_AVX512F"
8439 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8440 [(set_attr "mode" "HI")
8441 (set_attr "type" "msklog")
8442 (set_attr "prefix" "vex")])
8443
8444 (define_insn "kunpcksi"
8445 [(set (match_operand:SI 0 "register_operand" "=k")
8446 (ior:SI
8447 (ashift:SI
8448 (match_operand:SI 1 "register_operand" "k")
8449 (const_int 16))
8450 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8451 "TARGET_AVX512BW"
8452 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8453 [(set_attr "mode" "SI")])
8454
8455 (define_insn "kunpckdi"
8456 [(set (match_operand:DI 0 "register_operand" "=k")
8457 (ior:DI
8458 (ashift:DI
8459 (match_operand:DI 1 "register_operand" "k")
8460 (const_int 32))
8461 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8462 "TARGET_AVX512BW"
8463 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8464 [(set_attr "mode" "DI")])
8465
8466 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8467 ;; ??? Special case for immediate operand is missing - it is tricky.
8468 (define_insn "*<code>si_2_zext"
8469 [(set (reg FLAGS_REG)
8470 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8471 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8472 (const_int 0)))
8473 (set (match_operand:DI 0 "register_operand" "=r")
8474 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8475 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8476 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8477 "<logic>{l}\t{%2, %k0|%k0, %2}"
8478 [(set_attr "type" "alu")
8479 (set_attr "mode" "SI")])
8480
8481 (define_insn "*<code>si_2_zext_imm"
8482 [(set (reg FLAGS_REG)
8483 (compare (any_or:SI
8484 (match_operand:SI 1 "nonimmediate_operand" "%0")
8485 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8486 (const_int 0)))
8487 (set (match_operand:DI 0 "register_operand" "=r")
8488 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8489 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8490 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8491 "<logic>{l}\t{%2, %k0|%k0, %2}"
8492 [(set_attr "type" "alu")
8493 (set_attr "mode" "SI")])
8494
8495 (define_insn "*<code>qi_2_slp"
8496 [(set (reg FLAGS_REG)
8497 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8498 (match_operand:QI 1 "general_operand" "qmn,qn"))
8499 (const_int 0)))
8500 (set (strict_low_part (match_dup 0))
8501 (any_or:QI (match_dup 0) (match_dup 1)))]
8502 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8503 && ix86_match_ccmode (insn, CCNOmode)
8504 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8505 "<logic>{b}\t{%1, %0|%0, %1}"
8506 [(set_attr "type" "alu1")
8507 (set_attr "mode" "QI")])
8508
8509 (define_insn "*<code><mode>_3"
8510 [(set (reg FLAGS_REG)
8511 (compare (any_or:SWI
8512 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8513 (match_operand:SWI 2 "<general_operand>" "<g>"))
8514 (const_int 0)))
8515 (clobber (match_scratch:SWI 0 "=<r>"))]
8516 "ix86_match_ccmode (insn, CCNOmode)
8517 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8518 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8519 [(set_attr "type" "alu")
8520 (set_attr "mode" "<MODE>")])
8521
8522 (define_insn "*<code>qi_ext_0"
8523 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8524 (const_int 8)
8525 (const_int 8))
8526 (any_or:SI
8527 (zero_extract:SI
8528 (match_operand 1 "ext_register_operand" "0")
8529 (const_int 8)
8530 (const_int 8))
8531 (match_operand 2 "const_int_operand" "n")))
8532 (clobber (reg:CC FLAGS_REG))]
8533 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8534 "<logic>{b}\t{%2, %h0|%h0, %2}"
8535 [(set_attr "type" "alu")
8536 (set_attr "length_immediate" "1")
8537 (set_attr "modrm" "1")
8538 (set_attr "mode" "QI")])
8539
8540 (define_insn "*<code>qi_ext_1"
8541 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8542 (const_int 8)
8543 (const_int 8))
8544 (any_or:SI
8545 (zero_extract:SI
8546 (match_operand 1 "ext_register_operand" "0,0")
8547 (const_int 8)
8548 (const_int 8))
8549 (zero_extend:SI
8550 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8551 (clobber (reg:CC FLAGS_REG))]
8552 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8553 "<logic>{b}\t{%2, %h0|%h0, %2}"
8554 [(set_attr "isa" "*,nox64")
8555 (set_attr "type" "alu")
8556 (set_attr "length_immediate" "0")
8557 (set_attr "mode" "QI")])
8558
8559 (define_insn "*<code>qi_ext_2"
8560 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8561 (const_int 8)
8562 (const_int 8))
8563 (any_or:SI
8564 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8565 (const_int 8)
8566 (const_int 8))
8567 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8568 (const_int 8)
8569 (const_int 8))))
8570 (clobber (reg:CC FLAGS_REG))]
8571 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8572 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8573 [(set_attr "type" "alu")
8574 (set_attr "length_immediate" "0")
8575 (set_attr "mode" "QI")])
8576
8577 (define_split
8578 [(set (match_operand 0 "register_operand")
8579 (any_or (match_operand 1 "register_operand")
8580 (match_operand 2 "const_int_operand")))
8581 (clobber (reg:CC FLAGS_REG))]
8582 "reload_completed
8583 && QI_REG_P (operands[0])
8584 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8585 && !(INTVAL (operands[2]) & ~(255 << 8))
8586 && GET_MODE (operands[0]) != QImode"
8587 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8588 (any_or:SI (zero_extract:SI (match_dup 1)
8589 (const_int 8) (const_int 8))
8590 (match_dup 2)))
8591 (clobber (reg:CC FLAGS_REG))])]
8592 {
8593 operands[0] = gen_lowpart (SImode, operands[0]);
8594 operands[1] = gen_lowpart (SImode, operands[1]);
8595 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8596 })
8597
8598 ;; Since OR can be encoded with sign extended immediate, this is only
8599 ;; profitable when 7th bit is set.
8600 (define_split
8601 [(set (match_operand 0 "register_operand")
8602 (any_or (match_operand 1 "general_operand")
8603 (match_operand 2 "const_int_operand")))
8604 (clobber (reg:CC FLAGS_REG))]
8605 "reload_completed
8606 && ANY_QI_REG_P (operands[0])
8607 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8608 && !(INTVAL (operands[2]) & ~255)
8609 && (INTVAL (operands[2]) & 128)
8610 && GET_MODE (operands[0]) != QImode"
8611 [(parallel [(set (strict_low_part (match_dup 0))
8612 (any_or:QI (match_dup 1)
8613 (match_dup 2)))
8614 (clobber (reg:CC FLAGS_REG))])]
8615 {
8616 operands[0] = gen_lowpart (QImode, operands[0]);
8617 operands[1] = gen_lowpart (QImode, operands[1]);
8618 operands[2] = gen_lowpart (QImode, operands[2]);
8619 })
8620
8621 (define_expand "xorqi_cc_ext_1"
8622 [(parallel [
8623 (set (reg:CCNO FLAGS_REG)
8624 (compare:CCNO
8625 (xor:SI
8626 (zero_extract:SI
8627 (match_operand 1 "ext_register_operand")
8628 (const_int 8)
8629 (const_int 8))
8630 (match_operand:QI 2 "const_int_operand"))
8631 (const_int 0)))
8632 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8633 (const_int 8)
8634 (const_int 8))
8635 (xor:SI
8636 (zero_extract:SI
8637 (match_dup 1)
8638 (const_int 8)
8639 (const_int 8))
8640 (match_dup 2)))])])
8641
8642 (define_insn "*xorqi_cc_ext_1"
8643 [(set (reg FLAGS_REG)
8644 (compare
8645 (xor:SI
8646 (zero_extract:SI
8647 (match_operand 1 "ext_register_operand" "0,0")
8648 (const_int 8)
8649 (const_int 8))
8650 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8651 (const_int 0)))
8652 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8653 (const_int 8)
8654 (const_int 8))
8655 (xor:SI
8656 (zero_extract:SI
8657 (match_dup 1)
8658 (const_int 8)
8659 (const_int 8))
8660 (match_dup 2)))]
8661 "ix86_match_ccmode (insn, CCNOmode)"
8662 "xor{b}\t{%2, %h0|%h0, %2}"
8663 [(set_attr "isa" "*,nox64")
8664 (set_attr "type" "alu")
8665 (set_attr "modrm" "1")
8666 (set_attr "mode" "QI")])
8667 \f
8668 ;; Negation instructions
8669
8670 (define_expand "neg<mode>2"
8671 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8672 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8673 ""
8674 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8675
8676 (define_insn_and_split "*neg<dwi>2_doubleword"
8677 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8678 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8679 (clobber (reg:CC FLAGS_REG))]
8680 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8681 "#"
8682 "reload_completed"
8683 [(parallel
8684 [(set (reg:CCZ FLAGS_REG)
8685 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8686 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8687 (parallel
8688 [(set (match_dup 2)
8689 (plus:DWIH (match_dup 3)
8690 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8691 (const_int 0))))
8692 (clobber (reg:CC FLAGS_REG))])
8693 (parallel
8694 [(set (match_dup 2)
8695 (neg:DWIH (match_dup 2)))
8696 (clobber (reg:CC FLAGS_REG))])]
8697 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8698
8699 (define_insn "*neg<mode>2_1"
8700 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8701 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8704 "neg{<imodesuffix>}\t%0"
8705 [(set_attr "type" "negnot")
8706 (set_attr "mode" "<MODE>")])
8707
8708 ;; Combine is quite creative about this pattern.
8709 (define_insn "*negsi2_1_zext"
8710 [(set (match_operand:DI 0 "register_operand" "=r")
8711 (lshiftrt:DI
8712 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8713 (const_int 32)))
8714 (const_int 32)))
8715 (clobber (reg:CC FLAGS_REG))]
8716 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8717 "neg{l}\t%k0"
8718 [(set_attr "type" "negnot")
8719 (set_attr "mode" "SI")])
8720
8721 ;; The problem with neg is that it does not perform (compare x 0),
8722 ;; it really performs (compare 0 x), which leaves us with the zero
8723 ;; flag being the only useful item.
8724
8725 (define_insn "*neg<mode>2_cmpz"
8726 [(set (reg:CCZ FLAGS_REG)
8727 (compare:CCZ
8728 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8729 (const_int 0)))
8730 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8731 (neg:SWI (match_dup 1)))]
8732 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8733 "neg{<imodesuffix>}\t%0"
8734 [(set_attr "type" "negnot")
8735 (set_attr "mode" "<MODE>")])
8736
8737 (define_insn "*negsi2_cmpz_zext"
8738 [(set (reg:CCZ FLAGS_REG)
8739 (compare:CCZ
8740 (lshiftrt:DI
8741 (neg:DI (ashift:DI
8742 (match_operand:DI 1 "register_operand" "0")
8743 (const_int 32)))
8744 (const_int 32))
8745 (const_int 0)))
8746 (set (match_operand:DI 0 "register_operand" "=r")
8747 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8748 (const_int 32)))
8749 (const_int 32)))]
8750 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8751 "neg{l}\t%k0"
8752 [(set_attr "type" "negnot")
8753 (set_attr "mode" "SI")])
8754
8755 ;; Negate with jump on overflow.
8756 (define_expand "negv<mode>3"
8757 [(parallel [(set (reg:CCO FLAGS_REG)
8758 (ne:CCO (match_operand:SWI 1 "register_operand")
8759 (match_dup 3)))
8760 (set (match_operand:SWI 0 "register_operand")
8761 (neg:SWI (match_dup 1)))])
8762 (set (pc) (if_then_else
8763 (eq (reg:CCO FLAGS_REG) (const_int 0))
8764 (label_ref (match_operand 2))
8765 (pc)))]
8766 ""
8767 {
8768 operands[3]
8769 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8770 <MODE>mode);
8771 })
8772
8773 (define_insn "*negv<mode>3"
8774 [(set (reg:CCO FLAGS_REG)
8775 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8776 (match_operand:SWI 2 "const_int_operand")))
8777 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8778 (neg:SWI (match_dup 1)))]
8779 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8780 && mode_signbit_p (<MODE>mode, operands[2])"
8781 "neg{<imodesuffix>}\t%0"
8782 [(set_attr "type" "negnot")
8783 (set_attr "mode" "<MODE>")])
8784
8785 ;; Changing of sign for FP values is doable using integer unit too.
8786
8787 (define_expand "<code><mode>2"
8788 [(set (match_operand:X87MODEF 0 "register_operand")
8789 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8790 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8791 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8792
8793 (define_insn "*absneg<mode>2_mixed"
8794 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8795 (match_operator:MODEF 3 "absneg_operator"
8796 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8797 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8798 (clobber (reg:CC FLAGS_REG))]
8799 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8800 "#")
8801
8802 (define_insn "*absneg<mode>2_sse"
8803 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8804 (match_operator:MODEF 3 "absneg_operator"
8805 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8806 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8807 (clobber (reg:CC FLAGS_REG))]
8808 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8809 "#")
8810
8811 (define_insn "*absneg<mode>2_i387"
8812 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8813 (match_operator:X87MODEF 3 "absneg_operator"
8814 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8815 (use (match_operand 2))
8816 (clobber (reg:CC FLAGS_REG))]
8817 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8818 "#")
8819
8820 (define_expand "<code>tf2"
8821 [(set (match_operand:TF 0 "register_operand")
8822 (absneg:TF (match_operand:TF 1 "register_operand")))]
8823 "TARGET_SSE"
8824 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8825
8826 (define_insn "*absnegtf2_sse"
8827 [(set (match_operand:TF 0 "register_operand" "=x,x")
8828 (match_operator:TF 3 "absneg_operator"
8829 [(match_operand:TF 1 "register_operand" "0,x")]))
8830 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8831 (clobber (reg:CC FLAGS_REG))]
8832 "TARGET_SSE"
8833 "#")
8834
8835 ;; Splitters for fp abs and neg.
8836
8837 (define_split
8838 [(set (match_operand 0 "fp_register_operand")
8839 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8840 (use (match_operand 2))
8841 (clobber (reg:CC FLAGS_REG))]
8842 "reload_completed"
8843 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8844
8845 (define_split
8846 [(set (match_operand 0 "register_operand")
8847 (match_operator 3 "absneg_operator"
8848 [(match_operand 1 "register_operand")]))
8849 (use (match_operand 2 "nonimmediate_operand"))
8850 (clobber (reg:CC FLAGS_REG))]
8851 "reload_completed && SSE_REG_P (operands[0])"
8852 [(set (match_dup 0) (match_dup 3))]
8853 {
8854 machine_mode mode = GET_MODE (operands[0]);
8855 machine_mode vmode = GET_MODE (operands[2]);
8856 rtx tmp;
8857
8858 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8859 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8860 if (operands_match_p (operands[0], operands[2]))
8861 std::swap (operands[1], operands[2]);
8862 if (GET_CODE (operands[3]) == ABS)
8863 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8864 else
8865 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8866 operands[3] = tmp;
8867 })
8868
8869 (define_split
8870 [(set (match_operand:SF 0 "register_operand")
8871 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8872 (use (match_operand:V4SF 2))
8873 (clobber (reg:CC FLAGS_REG))]
8874 "reload_completed"
8875 [(parallel [(set (match_dup 0) (match_dup 1))
8876 (clobber (reg:CC FLAGS_REG))])]
8877 {
8878 rtx tmp;
8879 operands[0] = gen_lowpart (SImode, operands[0]);
8880 if (GET_CODE (operands[1]) == ABS)
8881 {
8882 tmp = gen_int_mode (0x7fffffff, SImode);
8883 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8884 }
8885 else
8886 {
8887 tmp = gen_int_mode (0x80000000, SImode);
8888 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8889 }
8890 operands[1] = tmp;
8891 })
8892
8893 (define_split
8894 [(set (match_operand:DF 0 "register_operand")
8895 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8896 (use (match_operand 2))
8897 (clobber (reg:CC FLAGS_REG))]
8898 "reload_completed"
8899 [(parallel [(set (match_dup 0) (match_dup 1))
8900 (clobber (reg:CC FLAGS_REG))])]
8901 {
8902 rtx tmp;
8903 if (TARGET_64BIT)
8904 {
8905 tmp = gen_lowpart (DImode, operands[0]);
8906 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8907 operands[0] = tmp;
8908
8909 if (GET_CODE (operands[1]) == ABS)
8910 tmp = const0_rtx;
8911 else
8912 tmp = gen_rtx_NOT (DImode, tmp);
8913 }
8914 else
8915 {
8916 operands[0] = gen_highpart (SImode, operands[0]);
8917 if (GET_CODE (operands[1]) == ABS)
8918 {
8919 tmp = gen_int_mode (0x7fffffff, SImode);
8920 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8921 }
8922 else
8923 {
8924 tmp = gen_int_mode (0x80000000, SImode);
8925 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8926 }
8927 }
8928 operands[1] = tmp;
8929 })
8930
8931 (define_split
8932 [(set (match_operand:XF 0 "register_operand")
8933 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8934 (use (match_operand 2))
8935 (clobber (reg:CC FLAGS_REG))]
8936 "reload_completed"
8937 [(parallel [(set (match_dup 0) (match_dup 1))
8938 (clobber (reg:CC FLAGS_REG))])]
8939 {
8940 rtx tmp;
8941 operands[0] = gen_rtx_REG (SImode,
8942 true_regnum (operands[0])
8943 + (TARGET_64BIT ? 1 : 2));
8944 if (GET_CODE (operands[1]) == ABS)
8945 {
8946 tmp = GEN_INT (0x7fff);
8947 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8948 }
8949 else
8950 {
8951 tmp = GEN_INT (0x8000);
8952 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8953 }
8954 operands[1] = tmp;
8955 })
8956
8957 ;; Conditionalize these after reload. If they match before reload, we
8958 ;; lose the clobber and ability to use integer instructions.
8959
8960 (define_insn "*<code><mode>2_1"
8961 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8962 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8963 "TARGET_80387
8964 && (reload_completed
8965 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8966 "f<absneg_mnemonic>"
8967 [(set_attr "type" "fsgn")
8968 (set_attr "mode" "<MODE>")])
8969
8970 (define_insn "*<code>extendsfdf2"
8971 [(set (match_operand:DF 0 "register_operand" "=f")
8972 (absneg:DF (float_extend:DF
8973 (match_operand:SF 1 "register_operand" "0"))))]
8974 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8975 "f<absneg_mnemonic>"
8976 [(set_attr "type" "fsgn")
8977 (set_attr "mode" "DF")])
8978
8979 (define_insn "*<code>extendsfxf2"
8980 [(set (match_operand:XF 0 "register_operand" "=f")
8981 (absneg:XF (float_extend:XF
8982 (match_operand:SF 1 "register_operand" "0"))))]
8983 "TARGET_80387"
8984 "f<absneg_mnemonic>"
8985 [(set_attr "type" "fsgn")
8986 (set_attr "mode" "XF")])
8987
8988 (define_insn "*<code>extenddfxf2"
8989 [(set (match_operand:XF 0 "register_operand" "=f")
8990 (absneg:XF (float_extend:XF
8991 (match_operand:DF 1 "register_operand" "0"))))]
8992 "TARGET_80387"
8993 "f<absneg_mnemonic>"
8994 [(set_attr "type" "fsgn")
8995 (set_attr "mode" "XF")])
8996
8997 ;; Copysign instructions
8998
8999 (define_mode_iterator CSGNMODE [SF DF TF])
9000 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9001
9002 (define_expand "copysign<mode>3"
9003 [(match_operand:CSGNMODE 0 "register_operand")
9004 (match_operand:CSGNMODE 1 "nonmemory_operand")
9005 (match_operand:CSGNMODE 2 "register_operand")]
9006 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9007 || (TARGET_SSE && (<MODE>mode == TFmode))"
9008 "ix86_expand_copysign (operands); DONE;")
9009
9010 (define_insn_and_split "copysign<mode>3_const"
9011 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9012 (unspec:CSGNMODE
9013 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9014 (match_operand:CSGNMODE 2 "register_operand" "0")
9015 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9016 UNSPEC_COPYSIGN))]
9017 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9018 || (TARGET_SSE && (<MODE>mode == TFmode))"
9019 "#"
9020 "&& reload_completed"
9021 [(const_int 0)]
9022 "ix86_split_copysign_const (operands); DONE;")
9023
9024 (define_insn "copysign<mode>3_var"
9025 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9026 (unspec:CSGNMODE
9027 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9028 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9029 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9030 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9031 UNSPEC_COPYSIGN))
9032 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9033 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9034 || (TARGET_SSE && (<MODE>mode == TFmode))"
9035 "#")
9036
9037 (define_split
9038 [(set (match_operand:CSGNMODE 0 "register_operand")
9039 (unspec:CSGNMODE
9040 [(match_operand:CSGNMODE 2 "register_operand")
9041 (match_operand:CSGNMODE 3 "register_operand")
9042 (match_operand:<CSGNVMODE> 4)
9043 (match_operand:<CSGNVMODE> 5)]
9044 UNSPEC_COPYSIGN))
9045 (clobber (match_scratch:<CSGNVMODE> 1))]
9046 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9047 || (TARGET_SSE && (<MODE>mode == TFmode)))
9048 && reload_completed"
9049 [(const_int 0)]
9050 "ix86_split_copysign_var (operands); DONE;")
9051 \f
9052 ;; One complement instructions
9053
9054 (define_expand "one_cmpl<mode>2"
9055 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9056 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9057 ""
9058 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9059
9060 (define_insn "*one_cmpl<mode>2_1"
9061 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9062 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9063 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9064 "@
9065 not{<imodesuffix>}\t%0
9066 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9067 [(set_attr "isa" "*,avx512bw")
9068 (set_attr "type" "negnot,msklog")
9069 (set_attr "prefix" "*,vex")
9070 (set_attr "mode" "<MODE>")])
9071
9072 (define_insn "*one_cmplhi2_1"
9073 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9074 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9075 "ix86_unary_operator_ok (NOT, HImode, operands)"
9076 "@
9077 not{w}\t%0
9078 knotw\t{%1, %0|%0, %1}"
9079 [(set_attr "isa" "*,avx512f")
9080 (set_attr "type" "negnot,msklog")
9081 (set_attr "prefix" "*,vex")
9082 (set_attr "mode" "HI")])
9083
9084 ;; %%% Potential partial reg stall on alternative 1. What to do?
9085 (define_insn "*one_cmplqi2_1"
9086 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9087 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9088 "ix86_unary_operator_ok (NOT, QImode, operands)"
9089 {
9090 switch (which_alternative)
9091 {
9092 case 0:
9093 return "not{b}\t%0";
9094 case 1:
9095 return "not{l}\t%k0";
9096 case 2:
9097 if (TARGET_AVX512DQ)
9098 return "knotb\t{%1, %0|%0, %1}";
9099 return "knotw\t{%1, %0|%0, %1}";
9100 default:
9101 gcc_unreachable ();
9102 }
9103 }
9104 [(set_attr "isa" "*,*,avx512f")
9105 (set_attr "type" "negnot,negnot,msklog")
9106 (set_attr "prefix" "*,*,vex")
9107 (set_attr "mode" "QI,SI,QI")])
9108
9109 ;; ??? Currently never generated - xor is used instead.
9110 (define_insn "*one_cmplsi2_1_zext"
9111 [(set (match_operand:DI 0 "register_operand" "=r")
9112 (zero_extend:DI
9113 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9114 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9115 "not{l}\t%k0"
9116 [(set_attr "type" "negnot")
9117 (set_attr "mode" "SI")])
9118
9119 (define_insn "*one_cmpl<mode>2_2"
9120 [(set (reg FLAGS_REG)
9121 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9122 (const_int 0)))
9123 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9124 (not:SWI (match_dup 1)))]
9125 "ix86_match_ccmode (insn, CCNOmode)
9126 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9127 "#"
9128 [(set_attr "type" "alu1")
9129 (set_attr "mode" "<MODE>")])
9130
9131 (define_split
9132 [(set (match_operand 0 "flags_reg_operand")
9133 (match_operator 2 "compare_operator"
9134 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9135 (const_int 0)]))
9136 (set (match_operand:SWI 1 "nonimmediate_operand")
9137 (not:SWI (match_dup 3)))]
9138 "ix86_match_ccmode (insn, CCNOmode)"
9139 [(parallel [(set (match_dup 0)
9140 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9141 (const_int 0)]))
9142 (set (match_dup 1)
9143 (xor:SWI (match_dup 3) (const_int -1)))])])
9144
9145 ;; ??? Currently never generated - xor is used instead.
9146 (define_insn "*one_cmplsi2_2_zext"
9147 [(set (reg FLAGS_REG)
9148 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9149 (const_int 0)))
9150 (set (match_operand:DI 0 "register_operand" "=r")
9151 (zero_extend:DI (not:SI (match_dup 1))))]
9152 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9153 && ix86_unary_operator_ok (NOT, SImode, operands)"
9154 "#"
9155 [(set_attr "type" "alu1")
9156 (set_attr "mode" "SI")])
9157
9158 (define_split
9159 [(set (match_operand 0 "flags_reg_operand")
9160 (match_operator 2 "compare_operator"
9161 [(not:SI (match_operand:SI 3 "register_operand"))
9162 (const_int 0)]))
9163 (set (match_operand:DI 1 "register_operand")
9164 (zero_extend:DI (not:SI (match_dup 3))))]
9165 "ix86_match_ccmode (insn, CCNOmode)"
9166 [(parallel [(set (match_dup 0)
9167 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9168 (const_int 0)]))
9169 (set (match_dup 1)
9170 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9171 \f
9172 ;; Shift instructions
9173
9174 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9175 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9176 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9177 ;; from the assembler input.
9178 ;;
9179 ;; This instruction shifts the target reg/mem as usual, but instead of
9180 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9181 ;; is a left shift double, bits are taken from the high order bits of
9182 ;; reg, else if the insn is a shift right double, bits are taken from the
9183 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9184 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9185 ;;
9186 ;; Since sh[lr]d does not change the `reg' operand, that is done
9187 ;; separately, making all shifts emit pairs of shift double and normal
9188 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9189 ;; support a 63 bit shift, each shift where the count is in a reg expands
9190 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9191 ;;
9192 ;; If the shift count is a constant, we need never emit more than one
9193 ;; shift pair, instead using moves and sign extension for counts greater
9194 ;; than 31.
9195
9196 (define_expand "ashl<mode>3"
9197 [(set (match_operand:SDWIM 0 "<shift_operand>")
9198 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9199 (match_operand:QI 2 "nonmemory_operand")))]
9200 ""
9201 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9202
9203 (define_insn "*ashl<mode>3_doubleword"
9204 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9205 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9206 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9207 (clobber (reg:CC FLAGS_REG))]
9208 ""
9209 "#"
9210 [(set_attr "type" "multi")])
9211
9212 (define_split
9213 [(set (match_operand:DWI 0 "register_operand")
9214 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9215 (match_operand:QI 2 "nonmemory_operand")))
9216 (clobber (reg:CC FLAGS_REG))]
9217 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9218 [(const_int 0)]
9219 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9220
9221 ;; By default we don't ask for a scratch register, because when DWImode
9222 ;; values are manipulated, registers are already at a premium. But if
9223 ;; we have one handy, we won't turn it away.
9224
9225 (define_peephole2
9226 [(match_scratch:DWIH 3 "r")
9227 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9228 (ashift:<DWI>
9229 (match_operand:<DWI> 1 "nonmemory_operand")
9230 (match_operand:QI 2 "nonmemory_operand")))
9231 (clobber (reg:CC FLAGS_REG))])
9232 (match_dup 3)]
9233 "TARGET_CMOVE"
9234 [(const_int 0)]
9235 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9236
9237 (define_insn "x86_64_shld"
9238 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9239 (ior:DI (ashift:DI (match_dup 0)
9240 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9241 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9242 (minus:QI (const_int 64) (match_dup 2)))))
9243 (clobber (reg:CC FLAGS_REG))]
9244 "TARGET_64BIT"
9245 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9246 [(set_attr "type" "ishift")
9247 (set_attr "prefix_0f" "1")
9248 (set_attr "mode" "DI")
9249 (set_attr "athlon_decode" "vector")
9250 (set_attr "amdfam10_decode" "vector")
9251 (set_attr "bdver1_decode" "vector")])
9252
9253 (define_insn "x86_shld"
9254 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9255 (ior:SI (ashift:SI (match_dup 0)
9256 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9257 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9258 (minus:QI (const_int 32) (match_dup 2)))))
9259 (clobber (reg:CC FLAGS_REG))]
9260 ""
9261 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9262 [(set_attr "type" "ishift")
9263 (set_attr "prefix_0f" "1")
9264 (set_attr "mode" "SI")
9265 (set_attr "pent_pair" "np")
9266 (set_attr "athlon_decode" "vector")
9267 (set_attr "amdfam10_decode" "vector")
9268 (set_attr "bdver1_decode" "vector")])
9269
9270 (define_expand "x86_shift<mode>_adj_1"
9271 [(set (reg:CCZ FLAGS_REG)
9272 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9273 (match_dup 4))
9274 (const_int 0)))
9275 (set (match_operand:SWI48 0 "register_operand")
9276 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9277 (match_operand:SWI48 1 "register_operand")
9278 (match_dup 0)))
9279 (set (match_dup 1)
9280 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9281 (match_operand:SWI48 3 "register_operand")
9282 (match_dup 1)))]
9283 "TARGET_CMOVE"
9284 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9285
9286 (define_expand "x86_shift<mode>_adj_2"
9287 [(use (match_operand:SWI48 0 "register_operand"))
9288 (use (match_operand:SWI48 1 "register_operand"))
9289 (use (match_operand:QI 2 "register_operand"))]
9290 ""
9291 {
9292 rtx_code_label *label = gen_label_rtx ();
9293 rtx tmp;
9294
9295 emit_insn (gen_testqi_ccz_1 (operands[2],
9296 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9297
9298 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9299 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9300 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9301 gen_rtx_LABEL_REF (VOIDmode, label),
9302 pc_rtx);
9303 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9304 JUMP_LABEL (tmp) = label;
9305
9306 emit_move_insn (operands[0], operands[1]);
9307 ix86_expand_clear (operands[1]);
9308
9309 emit_label (label);
9310 LABEL_NUSES (label) = 1;
9311
9312 DONE;
9313 })
9314
9315 ;; Avoid useless masking of count operand.
9316 (define_insn "*ashl<mode>3_mask"
9317 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9318 (ashift:SWI48
9319 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9320 (subreg:QI
9321 (and:SI
9322 (match_operand:SI 2 "register_operand" "c")
9323 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9326 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9327 == GET_MODE_BITSIZE (<MODE>mode)-1"
9328 {
9329 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9330 }
9331 [(set_attr "type" "ishift")
9332 (set_attr "mode" "<MODE>")])
9333
9334 (define_insn "*bmi2_ashl<mode>3_1"
9335 [(set (match_operand:SWI48 0 "register_operand" "=r")
9336 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9337 (match_operand:SWI48 2 "register_operand" "r")))]
9338 "TARGET_BMI2"
9339 "shlx\t{%2, %1, %0|%0, %1, %2}"
9340 [(set_attr "type" "ishiftx")
9341 (set_attr "mode" "<MODE>")])
9342
9343 (define_insn "*ashl<mode>3_1"
9344 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9345 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9346 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9347 (clobber (reg:CC FLAGS_REG))]
9348 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9349 {
9350 switch (get_attr_type (insn))
9351 {
9352 case TYPE_LEA:
9353 case TYPE_ISHIFTX:
9354 return "#";
9355
9356 case TYPE_ALU:
9357 gcc_assert (operands[2] == const1_rtx);
9358 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9359 return "add{<imodesuffix>}\t%0, %0";
9360
9361 default:
9362 if (operands[2] == const1_rtx
9363 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9364 return "sal{<imodesuffix>}\t%0";
9365 else
9366 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9367 }
9368 }
9369 [(set_attr "isa" "*,*,bmi2")
9370 (set (attr "type")
9371 (cond [(eq_attr "alternative" "1")
9372 (const_string "lea")
9373 (eq_attr "alternative" "2")
9374 (const_string "ishiftx")
9375 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9376 (match_operand 0 "register_operand"))
9377 (match_operand 2 "const1_operand"))
9378 (const_string "alu")
9379 ]
9380 (const_string "ishift")))
9381 (set (attr "length_immediate")
9382 (if_then_else
9383 (ior (eq_attr "type" "alu")
9384 (and (eq_attr "type" "ishift")
9385 (and (match_operand 2 "const1_operand")
9386 (ior (match_test "TARGET_SHIFT1")
9387 (match_test "optimize_function_for_size_p (cfun)")))))
9388 (const_string "0")
9389 (const_string "*")))
9390 (set_attr "mode" "<MODE>")])
9391
9392 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9393 (define_split
9394 [(set (match_operand:SWI48 0 "register_operand")
9395 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9396 (match_operand:QI 2 "register_operand")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "TARGET_BMI2 && reload_completed"
9399 [(set (match_dup 0)
9400 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9401 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9402
9403 (define_insn "*bmi2_ashlsi3_1_zext"
9404 [(set (match_operand:DI 0 "register_operand" "=r")
9405 (zero_extend:DI
9406 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9407 (match_operand:SI 2 "register_operand" "r"))))]
9408 "TARGET_64BIT && TARGET_BMI2"
9409 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9410 [(set_attr "type" "ishiftx")
9411 (set_attr "mode" "SI")])
9412
9413 (define_insn "*ashlsi3_1_zext"
9414 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9415 (zero_extend:DI
9416 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9417 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9420 {
9421 switch (get_attr_type (insn))
9422 {
9423 case TYPE_LEA:
9424 case TYPE_ISHIFTX:
9425 return "#";
9426
9427 case TYPE_ALU:
9428 gcc_assert (operands[2] == const1_rtx);
9429 return "add{l}\t%k0, %k0";
9430
9431 default:
9432 if (operands[2] == const1_rtx
9433 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9434 return "sal{l}\t%k0";
9435 else
9436 return "sal{l}\t{%2, %k0|%k0, %2}";
9437 }
9438 }
9439 [(set_attr "isa" "*,*,bmi2")
9440 (set (attr "type")
9441 (cond [(eq_attr "alternative" "1")
9442 (const_string "lea")
9443 (eq_attr "alternative" "2")
9444 (const_string "ishiftx")
9445 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9446 (match_operand 2 "const1_operand"))
9447 (const_string "alu")
9448 ]
9449 (const_string "ishift")))
9450 (set (attr "length_immediate")
9451 (if_then_else
9452 (ior (eq_attr "type" "alu")
9453 (and (eq_attr "type" "ishift")
9454 (and (match_operand 2 "const1_operand")
9455 (ior (match_test "TARGET_SHIFT1")
9456 (match_test "optimize_function_for_size_p (cfun)")))))
9457 (const_string "0")
9458 (const_string "*")))
9459 (set_attr "mode" "SI")])
9460
9461 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9462 (define_split
9463 [(set (match_operand:DI 0 "register_operand")
9464 (zero_extend:DI
9465 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9466 (match_operand:QI 2 "register_operand"))))
9467 (clobber (reg:CC FLAGS_REG))]
9468 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9469 [(set (match_dup 0)
9470 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9471 "operands[2] = gen_lowpart (SImode, operands[2]);")
9472
9473 (define_insn "*ashlhi3_1"
9474 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9475 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9476 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9477 (clobber (reg:CC FLAGS_REG))]
9478 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9479 {
9480 switch (get_attr_type (insn))
9481 {
9482 case TYPE_LEA:
9483 return "#";
9484
9485 case TYPE_ALU:
9486 gcc_assert (operands[2] == const1_rtx);
9487 return "add{w}\t%0, %0";
9488
9489 default:
9490 if (operands[2] == const1_rtx
9491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9492 return "sal{w}\t%0";
9493 else
9494 return "sal{w}\t{%2, %0|%0, %2}";
9495 }
9496 }
9497 [(set (attr "type")
9498 (cond [(eq_attr "alternative" "1")
9499 (const_string "lea")
9500 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9501 (match_operand 0 "register_operand"))
9502 (match_operand 2 "const1_operand"))
9503 (const_string "alu")
9504 ]
9505 (const_string "ishift")))
9506 (set (attr "length_immediate")
9507 (if_then_else
9508 (ior (eq_attr "type" "alu")
9509 (and (eq_attr "type" "ishift")
9510 (and (match_operand 2 "const1_operand")
9511 (ior (match_test "TARGET_SHIFT1")
9512 (match_test "optimize_function_for_size_p (cfun)")))))
9513 (const_string "0")
9514 (const_string "*")))
9515 (set_attr "mode" "HI,SI")])
9516
9517 ;; %%% Potential partial reg stall on alternative 1. What to do?
9518 (define_insn "*ashlqi3_1"
9519 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9520 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9521 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9522 (clobber (reg:CC FLAGS_REG))]
9523 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9524 {
9525 switch (get_attr_type (insn))
9526 {
9527 case TYPE_LEA:
9528 return "#";
9529
9530 case TYPE_ALU:
9531 gcc_assert (operands[2] == const1_rtx);
9532 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9533 return "add{l}\t%k0, %k0";
9534 else
9535 return "add{b}\t%0, %0";
9536
9537 default:
9538 if (operands[2] == const1_rtx
9539 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9540 {
9541 if (get_attr_mode (insn) == MODE_SI)
9542 return "sal{l}\t%k0";
9543 else
9544 return "sal{b}\t%0";
9545 }
9546 else
9547 {
9548 if (get_attr_mode (insn) == MODE_SI)
9549 return "sal{l}\t{%2, %k0|%k0, %2}";
9550 else
9551 return "sal{b}\t{%2, %0|%0, %2}";
9552 }
9553 }
9554 }
9555 [(set (attr "type")
9556 (cond [(eq_attr "alternative" "2")
9557 (const_string "lea")
9558 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9559 (match_operand 0 "register_operand"))
9560 (match_operand 2 "const1_operand"))
9561 (const_string "alu")
9562 ]
9563 (const_string "ishift")))
9564 (set (attr "length_immediate")
9565 (if_then_else
9566 (ior (eq_attr "type" "alu")
9567 (and (eq_attr "type" "ishift")
9568 (and (match_operand 2 "const1_operand")
9569 (ior (match_test "TARGET_SHIFT1")
9570 (match_test "optimize_function_for_size_p (cfun)")))))
9571 (const_string "0")
9572 (const_string "*")))
9573 (set_attr "mode" "QI,SI,SI")])
9574
9575 (define_insn "*ashlqi3_1_slp"
9576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9577 (ashift:QI (match_dup 0)
9578 (match_operand:QI 1 "nonmemory_operand" "cI")))
9579 (clobber (reg:CC FLAGS_REG))]
9580 "(optimize_function_for_size_p (cfun)
9581 || !TARGET_PARTIAL_FLAG_REG_STALL
9582 || (operands[1] == const1_rtx
9583 && (TARGET_SHIFT1
9584 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9585 {
9586 switch (get_attr_type (insn))
9587 {
9588 case TYPE_ALU:
9589 gcc_assert (operands[1] == const1_rtx);
9590 return "add{b}\t%0, %0";
9591
9592 default:
9593 if (operands[1] == const1_rtx
9594 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9595 return "sal{b}\t%0";
9596 else
9597 return "sal{b}\t{%1, %0|%0, %1}";
9598 }
9599 }
9600 [(set (attr "type")
9601 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9602 (match_operand 0 "register_operand"))
9603 (match_operand 1 "const1_operand"))
9604 (const_string "alu")
9605 ]
9606 (const_string "ishift1")))
9607 (set (attr "length_immediate")
9608 (if_then_else
9609 (ior (eq_attr "type" "alu")
9610 (and (eq_attr "type" "ishift1")
9611 (and (match_operand 1 "const1_operand")
9612 (ior (match_test "TARGET_SHIFT1")
9613 (match_test "optimize_function_for_size_p (cfun)")))))
9614 (const_string "0")
9615 (const_string "*")))
9616 (set_attr "mode" "QI")])
9617
9618 ;; Convert ashift to the lea pattern to avoid flags dependency.
9619 (define_split
9620 [(set (match_operand 0 "register_operand")
9621 (ashift (match_operand 1 "index_register_operand")
9622 (match_operand:QI 2 "const_int_operand")))
9623 (clobber (reg:CC FLAGS_REG))]
9624 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9625 && reload_completed
9626 && true_regnum (operands[0]) != true_regnum (operands[1])"
9627 [(const_int 0)]
9628 {
9629 machine_mode mode = GET_MODE (operands[0]);
9630 rtx pat;
9631
9632 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9633 {
9634 mode = SImode;
9635 operands[0] = gen_lowpart (mode, operands[0]);
9636 operands[1] = gen_lowpart (mode, operands[1]);
9637 }
9638
9639 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9640
9641 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9642
9643 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9644 DONE;
9645 })
9646
9647 ;; Convert ashift to the lea pattern to avoid flags dependency.
9648 (define_split
9649 [(set (match_operand:DI 0 "register_operand")
9650 (zero_extend:DI
9651 (ashift:SI (match_operand:SI 1 "index_register_operand")
9652 (match_operand:QI 2 "const_int_operand"))))
9653 (clobber (reg:CC FLAGS_REG))]
9654 "TARGET_64BIT && reload_completed
9655 && true_regnum (operands[0]) != true_regnum (operands[1])"
9656 [(set (match_dup 0)
9657 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9658 {
9659 operands[1] = gen_lowpart (SImode, operands[1]);
9660 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9661 })
9662
9663 ;; This pattern can't accept a variable shift count, since shifts by
9664 ;; zero don't affect the flags. We assume that shifts by constant
9665 ;; zero are optimized away.
9666 (define_insn "*ashl<mode>3_cmp"
9667 [(set (reg FLAGS_REG)
9668 (compare
9669 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9670 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9671 (const_int 0)))
9672 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9673 (ashift:SWI (match_dup 1) (match_dup 2)))]
9674 "(optimize_function_for_size_p (cfun)
9675 || !TARGET_PARTIAL_FLAG_REG_STALL
9676 || (operands[2] == const1_rtx
9677 && (TARGET_SHIFT1
9678 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9679 && ix86_match_ccmode (insn, CCGOCmode)
9680 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9681 {
9682 switch (get_attr_type (insn))
9683 {
9684 case TYPE_ALU:
9685 gcc_assert (operands[2] == const1_rtx);
9686 return "add{<imodesuffix>}\t%0, %0";
9687
9688 default:
9689 if (operands[2] == const1_rtx
9690 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9691 return "sal{<imodesuffix>}\t%0";
9692 else
9693 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9694 }
9695 }
9696 [(set (attr "type")
9697 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9698 (match_operand 0 "register_operand"))
9699 (match_operand 2 "const1_operand"))
9700 (const_string "alu")
9701 ]
9702 (const_string "ishift")))
9703 (set (attr "length_immediate")
9704 (if_then_else
9705 (ior (eq_attr "type" "alu")
9706 (and (eq_attr "type" "ishift")
9707 (and (match_operand 2 "const1_operand")
9708 (ior (match_test "TARGET_SHIFT1")
9709 (match_test "optimize_function_for_size_p (cfun)")))))
9710 (const_string "0")
9711 (const_string "*")))
9712 (set_attr "mode" "<MODE>")])
9713
9714 (define_insn "*ashlsi3_cmp_zext"
9715 [(set (reg FLAGS_REG)
9716 (compare
9717 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9718 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9719 (const_int 0)))
9720 (set (match_operand:DI 0 "register_operand" "=r")
9721 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9722 "TARGET_64BIT
9723 && (optimize_function_for_size_p (cfun)
9724 || !TARGET_PARTIAL_FLAG_REG_STALL
9725 || (operands[2] == const1_rtx
9726 && (TARGET_SHIFT1
9727 || TARGET_DOUBLE_WITH_ADD)))
9728 && ix86_match_ccmode (insn, CCGOCmode)
9729 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9730 {
9731 switch (get_attr_type (insn))
9732 {
9733 case TYPE_ALU:
9734 gcc_assert (operands[2] == const1_rtx);
9735 return "add{l}\t%k0, %k0";
9736
9737 default:
9738 if (operands[2] == const1_rtx
9739 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9740 return "sal{l}\t%k0";
9741 else
9742 return "sal{l}\t{%2, %k0|%k0, %2}";
9743 }
9744 }
9745 [(set (attr "type")
9746 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9747 (match_operand 2 "const1_operand"))
9748 (const_string "alu")
9749 ]
9750 (const_string "ishift")))
9751 (set (attr "length_immediate")
9752 (if_then_else
9753 (ior (eq_attr "type" "alu")
9754 (and (eq_attr "type" "ishift")
9755 (and (match_operand 2 "const1_operand")
9756 (ior (match_test "TARGET_SHIFT1")
9757 (match_test "optimize_function_for_size_p (cfun)")))))
9758 (const_string "0")
9759 (const_string "*")))
9760 (set_attr "mode" "SI")])
9761
9762 (define_insn "*ashl<mode>3_cconly"
9763 [(set (reg FLAGS_REG)
9764 (compare
9765 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9766 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9767 (const_int 0)))
9768 (clobber (match_scratch:SWI 0 "=<r>"))]
9769 "(optimize_function_for_size_p (cfun)
9770 || !TARGET_PARTIAL_FLAG_REG_STALL
9771 || (operands[2] == const1_rtx
9772 && (TARGET_SHIFT1
9773 || TARGET_DOUBLE_WITH_ADD)))
9774 && ix86_match_ccmode (insn, CCGOCmode)"
9775 {
9776 switch (get_attr_type (insn))
9777 {
9778 case TYPE_ALU:
9779 gcc_assert (operands[2] == const1_rtx);
9780 return "add{<imodesuffix>}\t%0, %0";
9781
9782 default:
9783 if (operands[2] == const1_rtx
9784 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9785 return "sal{<imodesuffix>}\t%0";
9786 else
9787 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9788 }
9789 }
9790 [(set (attr "type")
9791 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9792 (match_operand 0 "register_operand"))
9793 (match_operand 2 "const1_operand"))
9794 (const_string "alu")
9795 ]
9796 (const_string "ishift")))
9797 (set (attr "length_immediate")
9798 (if_then_else
9799 (ior (eq_attr "type" "alu")
9800 (and (eq_attr "type" "ishift")
9801 (and (match_operand 2 "const1_operand")
9802 (ior (match_test "TARGET_SHIFT1")
9803 (match_test "optimize_function_for_size_p (cfun)")))))
9804 (const_string "0")
9805 (const_string "*")))
9806 (set_attr "mode" "<MODE>")])
9807
9808 ;; See comment above `ashl<mode>3' about how this works.
9809
9810 (define_expand "<shift_insn><mode>3"
9811 [(set (match_operand:SDWIM 0 "<shift_operand>")
9812 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9813 (match_operand:QI 2 "nonmemory_operand")))]
9814 ""
9815 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9816
9817 ;; Avoid useless masking of count operand.
9818 (define_insn "*<shift_insn><mode>3_mask"
9819 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9820 (any_shiftrt:SWI48
9821 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9822 (subreg:QI
9823 (and:SI
9824 (match_operand:SI 2 "register_operand" "c")
9825 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9828 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9829 == GET_MODE_BITSIZE (<MODE>mode)-1"
9830 {
9831 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9832 }
9833 [(set_attr "type" "ishift")
9834 (set_attr "mode" "<MODE>")])
9835
9836 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9837 [(set (match_operand:DWI 0 "register_operand" "=r")
9838 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9839 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9840 (clobber (reg:CC FLAGS_REG))]
9841 ""
9842 "#"
9843 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9844 [(const_int 0)]
9845 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9846 [(set_attr "type" "multi")])
9847
9848 ;; By default we don't ask for a scratch register, because when DWImode
9849 ;; values are manipulated, registers are already at a premium. But if
9850 ;; we have one handy, we won't turn it away.
9851
9852 (define_peephole2
9853 [(match_scratch:DWIH 3 "r")
9854 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9855 (any_shiftrt:<DWI>
9856 (match_operand:<DWI> 1 "register_operand")
9857 (match_operand:QI 2 "nonmemory_operand")))
9858 (clobber (reg:CC FLAGS_REG))])
9859 (match_dup 3)]
9860 "TARGET_CMOVE"
9861 [(const_int 0)]
9862 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9863
9864 (define_insn "x86_64_shrd"
9865 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9866 (ior:DI (lshiftrt:DI (match_dup 0)
9867 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9868 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9869 (minus:QI (const_int 64) (match_dup 2)))))
9870 (clobber (reg:CC FLAGS_REG))]
9871 "TARGET_64BIT"
9872 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9873 [(set_attr "type" "ishift")
9874 (set_attr "prefix_0f" "1")
9875 (set_attr "mode" "DI")
9876 (set_attr "athlon_decode" "vector")
9877 (set_attr "amdfam10_decode" "vector")
9878 (set_attr "bdver1_decode" "vector")])
9879
9880 (define_insn "x86_shrd"
9881 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9882 (ior:SI (lshiftrt:SI (match_dup 0)
9883 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9884 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9885 (minus:QI (const_int 32) (match_dup 2)))))
9886 (clobber (reg:CC FLAGS_REG))]
9887 ""
9888 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9889 [(set_attr "type" "ishift")
9890 (set_attr "prefix_0f" "1")
9891 (set_attr "mode" "SI")
9892 (set_attr "pent_pair" "np")
9893 (set_attr "athlon_decode" "vector")
9894 (set_attr "amdfam10_decode" "vector")
9895 (set_attr "bdver1_decode" "vector")])
9896
9897 (define_insn "ashrdi3_cvt"
9898 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9899 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9900 (match_operand:QI 2 "const_int_operand")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "TARGET_64BIT && INTVAL (operands[2]) == 63
9903 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9904 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9905 "@
9906 {cqto|cqo}
9907 sar{q}\t{%2, %0|%0, %2}"
9908 [(set_attr "type" "imovx,ishift")
9909 (set_attr "prefix_0f" "0,*")
9910 (set_attr "length_immediate" "0,*")
9911 (set_attr "modrm" "0,1")
9912 (set_attr "mode" "DI")])
9913
9914 (define_insn "ashrsi3_cvt"
9915 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9916 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9917 (match_operand:QI 2 "const_int_operand")))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "INTVAL (operands[2]) == 31
9920 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9921 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9922 "@
9923 {cltd|cdq}
9924 sar{l}\t{%2, %0|%0, %2}"
9925 [(set_attr "type" "imovx,ishift")
9926 (set_attr "prefix_0f" "0,*")
9927 (set_attr "length_immediate" "0,*")
9928 (set_attr "modrm" "0,1")
9929 (set_attr "mode" "SI")])
9930
9931 (define_insn "*ashrsi3_cvt_zext"
9932 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9933 (zero_extend:DI
9934 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9935 (match_operand:QI 2 "const_int_operand"))))
9936 (clobber (reg:CC FLAGS_REG))]
9937 "TARGET_64BIT && INTVAL (operands[2]) == 31
9938 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9939 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9940 "@
9941 {cltd|cdq}
9942 sar{l}\t{%2, %k0|%k0, %2}"
9943 [(set_attr "type" "imovx,ishift")
9944 (set_attr "prefix_0f" "0,*")
9945 (set_attr "length_immediate" "0,*")
9946 (set_attr "modrm" "0,1")
9947 (set_attr "mode" "SI")])
9948
9949 (define_expand "x86_shift<mode>_adj_3"
9950 [(use (match_operand:SWI48 0 "register_operand"))
9951 (use (match_operand:SWI48 1 "register_operand"))
9952 (use (match_operand:QI 2 "register_operand"))]
9953 ""
9954 {
9955 rtx_code_label *label = gen_label_rtx ();
9956 rtx tmp;
9957
9958 emit_insn (gen_testqi_ccz_1 (operands[2],
9959 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9960
9961 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9962 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9963 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9964 gen_rtx_LABEL_REF (VOIDmode, label),
9965 pc_rtx);
9966 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9967 JUMP_LABEL (tmp) = label;
9968
9969 emit_move_insn (operands[0], operands[1]);
9970 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9971 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9972 emit_label (label);
9973 LABEL_NUSES (label) = 1;
9974
9975 DONE;
9976 })
9977
9978 (define_insn "*bmi2_<shift_insn><mode>3_1"
9979 [(set (match_operand:SWI48 0 "register_operand" "=r")
9980 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9981 (match_operand:SWI48 2 "register_operand" "r")))]
9982 "TARGET_BMI2"
9983 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9984 [(set_attr "type" "ishiftx")
9985 (set_attr "mode" "<MODE>")])
9986
9987 (define_insn "*<shift_insn><mode>3_1"
9988 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9989 (any_shiftrt:SWI48
9990 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9991 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9992 (clobber (reg:CC FLAGS_REG))]
9993 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9994 {
9995 switch (get_attr_type (insn))
9996 {
9997 case TYPE_ISHIFTX:
9998 return "#";
9999
10000 default:
10001 if (operands[2] == const1_rtx
10002 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10003 return "<shift>{<imodesuffix>}\t%0";
10004 else
10005 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10006 }
10007 }
10008 [(set_attr "isa" "*,bmi2")
10009 (set_attr "type" "ishift,ishiftx")
10010 (set (attr "length_immediate")
10011 (if_then_else
10012 (and (match_operand 2 "const1_operand")
10013 (ior (match_test "TARGET_SHIFT1")
10014 (match_test "optimize_function_for_size_p (cfun)")))
10015 (const_string "0")
10016 (const_string "*")))
10017 (set_attr "mode" "<MODE>")])
10018
10019 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10020 (define_split
10021 [(set (match_operand:SWI48 0 "register_operand")
10022 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10023 (match_operand:QI 2 "register_operand")))
10024 (clobber (reg:CC FLAGS_REG))]
10025 "TARGET_BMI2 && reload_completed"
10026 [(set (match_dup 0)
10027 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10028 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10029
10030 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10031 [(set (match_operand:DI 0 "register_operand" "=r")
10032 (zero_extend:DI
10033 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10034 (match_operand:SI 2 "register_operand" "r"))))]
10035 "TARGET_64BIT && TARGET_BMI2"
10036 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10037 [(set_attr "type" "ishiftx")
10038 (set_attr "mode" "SI")])
10039
10040 (define_insn "*<shift_insn>si3_1_zext"
10041 [(set (match_operand:DI 0 "register_operand" "=r,r")
10042 (zero_extend:DI
10043 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10044 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10045 (clobber (reg:CC FLAGS_REG))]
10046 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10047 {
10048 switch (get_attr_type (insn))
10049 {
10050 case TYPE_ISHIFTX:
10051 return "#";
10052
10053 default:
10054 if (operands[2] == const1_rtx
10055 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10056 return "<shift>{l}\t%k0";
10057 else
10058 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10059 }
10060 }
10061 [(set_attr "isa" "*,bmi2")
10062 (set_attr "type" "ishift,ishiftx")
10063 (set (attr "length_immediate")
10064 (if_then_else
10065 (and (match_operand 2 "const1_operand")
10066 (ior (match_test "TARGET_SHIFT1")
10067 (match_test "optimize_function_for_size_p (cfun)")))
10068 (const_string "0")
10069 (const_string "*")))
10070 (set_attr "mode" "SI")])
10071
10072 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10073 (define_split
10074 [(set (match_operand:DI 0 "register_operand")
10075 (zero_extend:DI
10076 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10077 (match_operand:QI 2 "register_operand"))))
10078 (clobber (reg:CC FLAGS_REG))]
10079 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10080 [(set (match_dup 0)
10081 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10082 "operands[2] = gen_lowpart (SImode, operands[2]);")
10083
10084 (define_insn "*<shift_insn><mode>3_1"
10085 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10086 (any_shiftrt:SWI12
10087 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10088 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10089 (clobber (reg:CC FLAGS_REG))]
10090 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10091 {
10092 if (operands[2] == const1_rtx
10093 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10094 return "<shift>{<imodesuffix>}\t%0";
10095 else
10096 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10097 }
10098 [(set_attr "type" "ishift")
10099 (set (attr "length_immediate")
10100 (if_then_else
10101 (and (match_operand 2 "const1_operand")
10102 (ior (match_test "TARGET_SHIFT1")
10103 (match_test "optimize_function_for_size_p (cfun)")))
10104 (const_string "0")
10105 (const_string "*")))
10106 (set_attr "mode" "<MODE>")])
10107
10108 (define_insn "*<shift_insn>qi3_1_slp"
10109 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10110 (any_shiftrt:QI (match_dup 0)
10111 (match_operand:QI 1 "nonmemory_operand" "cI")))
10112 (clobber (reg:CC FLAGS_REG))]
10113 "(optimize_function_for_size_p (cfun)
10114 || !TARGET_PARTIAL_REG_STALL
10115 || (operands[1] == const1_rtx
10116 && TARGET_SHIFT1))"
10117 {
10118 if (operands[1] == const1_rtx
10119 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10120 return "<shift>{b}\t%0";
10121 else
10122 return "<shift>{b}\t{%1, %0|%0, %1}";
10123 }
10124 [(set_attr "type" "ishift1")
10125 (set (attr "length_immediate")
10126 (if_then_else
10127 (and (match_operand 1 "const1_operand")
10128 (ior (match_test "TARGET_SHIFT1")
10129 (match_test "optimize_function_for_size_p (cfun)")))
10130 (const_string "0")
10131 (const_string "*")))
10132 (set_attr "mode" "QI")])
10133
10134 ;; This pattern can't accept a variable shift count, since shifts by
10135 ;; zero don't affect the flags. We assume that shifts by constant
10136 ;; zero are optimized away.
10137 (define_insn "*<shift_insn><mode>3_cmp"
10138 [(set (reg FLAGS_REG)
10139 (compare
10140 (any_shiftrt:SWI
10141 (match_operand:SWI 1 "nonimmediate_operand" "0")
10142 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10143 (const_int 0)))
10144 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10145 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10146 "(optimize_function_for_size_p (cfun)
10147 || !TARGET_PARTIAL_FLAG_REG_STALL
10148 || (operands[2] == const1_rtx
10149 && TARGET_SHIFT1))
10150 && ix86_match_ccmode (insn, CCGOCmode)
10151 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10152 {
10153 if (operands[2] == const1_rtx
10154 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10155 return "<shift>{<imodesuffix>}\t%0";
10156 else
10157 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10158 }
10159 [(set_attr "type" "ishift")
10160 (set (attr "length_immediate")
10161 (if_then_else
10162 (and (match_operand 2 "const1_operand")
10163 (ior (match_test "TARGET_SHIFT1")
10164 (match_test "optimize_function_for_size_p (cfun)")))
10165 (const_string "0")
10166 (const_string "*")))
10167 (set_attr "mode" "<MODE>")])
10168
10169 (define_insn "*<shift_insn>si3_cmp_zext"
10170 [(set (reg FLAGS_REG)
10171 (compare
10172 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10173 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10174 (const_int 0)))
10175 (set (match_operand:DI 0 "register_operand" "=r")
10176 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10177 "TARGET_64BIT
10178 && (optimize_function_for_size_p (cfun)
10179 || !TARGET_PARTIAL_FLAG_REG_STALL
10180 || (operands[2] == const1_rtx
10181 && TARGET_SHIFT1))
10182 && ix86_match_ccmode (insn, CCGOCmode)
10183 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10184 {
10185 if (operands[2] == const1_rtx
10186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10187 return "<shift>{l}\t%k0";
10188 else
10189 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10190 }
10191 [(set_attr "type" "ishift")
10192 (set (attr "length_immediate")
10193 (if_then_else
10194 (and (match_operand 2 "const1_operand")
10195 (ior (match_test "TARGET_SHIFT1")
10196 (match_test "optimize_function_for_size_p (cfun)")))
10197 (const_string "0")
10198 (const_string "*")))
10199 (set_attr "mode" "SI")])
10200
10201 (define_insn "*<shift_insn><mode>3_cconly"
10202 [(set (reg FLAGS_REG)
10203 (compare
10204 (any_shiftrt:SWI
10205 (match_operand:SWI 1 "register_operand" "0")
10206 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10207 (const_int 0)))
10208 (clobber (match_scratch:SWI 0 "=<r>"))]
10209 "(optimize_function_for_size_p (cfun)
10210 || !TARGET_PARTIAL_FLAG_REG_STALL
10211 || (operands[2] == const1_rtx
10212 && TARGET_SHIFT1))
10213 && ix86_match_ccmode (insn, CCGOCmode)"
10214 {
10215 if (operands[2] == const1_rtx
10216 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10217 return "<shift>{<imodesuffix>}\t%0";
10218 else
10219 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10220 }
10221 [(set_attr "type" "ishift")
10222 (set (attr "length_immediate")
10223 (if_then_else
10224 (and (match_operand 2 "const1_operand")
10225 (ior (match_test "TARGET_SHIFT1")
10226 (match_test "optimize_function_for_size_p (cfun)")))
10227 (const_string "0")
10228 (const_string "*")))
10229 (set_attr "mode" "<MODE>")])
10230 \f
10231 ;; Rotate instructions
10232
10233 (define_expand "<rotate_insn>ti3"
10234 [(set (match_operand:TI 0 "register_operand")
10235 (any_rotate:TI (match_operand:TI 1 "register_operand")
10236 (match_operand:QI 2 "nonmemory_operand")))]
10237 "TARGET_64BIT"
10238 {
10239 if (const_1_to_63_operand (operands[2], VOIDmode))
10240 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10241 (operands[0], operands[1], operands[2]));
10242 else
10243 FAIL;
10244
10245 DONE;
10246 })
10247
10248 (define_expand "<rotate_insn>di3"
10249 [(set (match_operand:DI 0 "shiftdi_operand")
10250 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10251 (match_operand:QI 2 "nonmemory_operand")))]
10252 ""
10253 {
10254 if (TARGET_64BIT)
10255 ix86_expand_binary_operator (<CODE>, DImode, operands);
10256 else if (const_1_to_31_operand (operands[2], VOIDmode))
10257 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10258 (operands[0], operands[1], operands[2]));
10259 else
10260 FAIL;
10261
10262 DONE;
10263 })
10264
10265 (define_expand "<rotate_insn><mode>3"
10266 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10267 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10268 (match_operand:QI 2 "nonmemory_operand")))]
10269 ""
10270 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10271
10272 ;; Avoid useless masking of count operand.
10273 (define_insn "*<rotate_insn><mode>3_mask"
10274 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10275 (any_rotate:SWI48
10276 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10277 (subreg:QI
10278 (and:SI
10279 (match_operand:SI 2 "register_operand" "c")
10280 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10283 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10284 == GET_MODE_BITSIZE (<MODE>mode)-1"
10285 {
10286 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10287 }
10288 [(set_attr "type" "rotate")
10289 (set_attr "mode" "<MODE>")])
10290
10291 ;; Implement rotation using two double-precision
10292 ;; shift instructions and a scratch register.
10293
10294 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10295 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10296 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10297 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10298 (clobber (reg:CC FLAGS_REG))
10299 (clobber (match_scratch:DWIH 3 "=&r"))]
10300 ""
10301 "#"
10302 "reload_completed"
10303 [(set (match_dup 3) (match_dup 4))
10304 (parallel
10305 [(set (match_dup 4)
10306 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10307 (lshiftrt:DWIH (match_dup 5)
10308 (minus:QI (match_dup 6) (match_dup 2)))))
10309 (clobber (reg:CC FLAGS_REG))])
10310 (parallel
10311 [(set (match_dup 5)
10312 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10313 (lshiftrt:DWIH (match_dup 3)
10314 (minus:QI (match_dup 6) (match_dup 2)))))
10315 (clobber (reg:CC FLAGS_REG))])]
10316 {
10317 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10318
10319 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10320 })
10321
10322 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10323 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10324 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10325 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10326 (clobber (reg:CC FLAGS_REG))
10327 (clobber (match_scratch:DWIH 3 "=&r"))]
10328 ""
10329 "#"
10330 "reload_completed"
10331 [(set (match_dup 3) (match_dup 4))
10332 (parallel
10333 [(set (match_dup 4)
10334 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10335 (ashift:DWIH (match_dup 5)
10336 (minus:QI (match_dup 6) (match_dup 2)))))
10337 (clobber (reg:CC FLAGS_REG))])
10338 (parallel
10339 [(set (match_dup 5)
10340 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10341 (ashift:DWIH (match_dup 3)
10342 (minus:QI (match_dup 6) (match_dup 2)))))
10343 (clobber (reg:CC FLAGS_REG))])]
10344 {
10345 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10346
10347 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10348 })
10349
10350 (define_insn "*bmi2_rorx<mode>3_1"
10351 [(set (match_operand:SWI48 0 "register_operand" "=r")
10352 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10353 (match_operand:QI 2 "immediate_operand" "<S>")))]
10354 "TARGET_BMI2"
10355 "rorx\t{%2, %1, %0|%0, %1, %2}"
10356 [(set_attr "type" "rotatex")
10357 (set_attr "mode" "<MODE>")])
10358
10359 (define_insn "*<rotate_insn><mode>3_1"
10360 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10361 (any_rotate:SWI48
10362 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10363 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10366 {
10367 switch (get_attr_type (insn))
10368 {
10369 case TYPE_ROTATEX:
10370 return "#";
10371
10372 default:
10373 if (operands[2] == const1_rtx
10374 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10375 return "<rotate>{<imodesuffix>}\t%0";
10376 else
10377 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10378 }
10379 }
10380 [(set_attr "isa" "*,bmi2")
10381 (set_attr "type" "rotate,rotatex")
10382 (set (attr "length_immediate")
10383 (if_then_else
10384 (and (eq_attr "type" "rotate")
10385 (and (match_operand 2 "const1_operand")
10386 (ior (match_test "TARGET_SHIFT1")
10387 (match_test "optimize_function_for_size_p (cfun)"))))
10388 (const_string "0")
10389 (const_string "*")))
10390 (set_attr "mode" "<MODE>")])
10391
10392 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10393 (define_split
10394 [(set (match_operand:SWI48 0 "register_operand")
10395 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10396 (match_operand:QI 2 "immediate_operand")))
10397 (clobber (reg:CC FLAGS_REG))]
10398 "TARGET_BMI2 && reload_completed"
10399 [(set (match_dup 0)
10400 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10401 {
10402 operands[2]
10403 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10404 })
10405
10406 (define_split
10407 [(set (match_operand:SWI48 0 "register_operand")
10408 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10409 (match_operand:QI 2 "immediate_operand")))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "TARGET_BMI2 && reload_completed"
10412 [(set (match_dup 0)
10413 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10414
10415 (define_insn "*bmi2_rorxsi3_1_zext"
10416 [(set (match_operand:DI 0 "register_operand" "=r")
10417 (zero_extend:DI
10418 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10419 (match_operand:QI 2 "immediate_operand" "I"))))]
10420 "TARGET_64BIT && TARGET_BMI2"
10421 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10422 [(set_attr "type" "rotatex")
10423 (set_attr "mode" "SI")])
10424
10425 (define_insn "*<rotate_insn>si3_1_zext"
10426 [(set (match_operand:DI 0 "register_operand" "=r,r")
10427 (zero_extend:DI
10428 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10429 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10430 (clobber (reg:CC FLAGS_REG))]
10431 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10432 {
10433 switch (get_attr_type (insn))
10434 {
10435 case TYPE_ROTATEX:
10436 return "#";
10437
10438 default:
10439 if (operands[2] == const1_rtx
10440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10441 return "<rotate>{l}\t%k0";
10442 else
10443 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10444 }
10445 }
10446 [(set_attr "isa" "*,bmi2")
10447 (set_attr "type" "rotate,rotatex")
10448 (set (attr "length_immediate")
10449 (if_then_else
10450 (and (eq_attr "type" "rotate")
10451 (and (match_operand 2 "const1_operand")
10452 (ior (match_test "TARGET_SHIFT1")
10453 (match_test "optimize_function_for_size_p (cfun)"))))
10454 (const_string "0")
10455 (const_string "*")))
10456 (set_attr "mode" "SI")])
10457
10458 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10459 (define_split
10460 [(set (match_operand:DI 0 "register_operand")
10461 (zero_extend:DI
10462 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10463 (match_operand:QI 2 "immediate_operand"))))
10464 (clobber (reg:CC FLAGS_REG))]
10465 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10466 [(set (match_dup 0)
10467 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10468 {
10469 operands[2]
10470 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10471 })
10472
10473 (define_split
10474 [(set (match_operand:DI 0 "register_operand")
10475 (zero_extend:DI
10476 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10477 (match_operand:QI 2 "immediate_operand"))))
10478 (clobber (reg:CC FLAGS_REG))]
10479 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10480 [(set (match_dup 0)
10481 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10482
10483 (define_insn "*<rotate_insn><mode>3_1"
10484 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10485 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10486 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10487 (clobber (reg:CC FLAGS_REG))]
10488 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10489 {
10490 if (operands[2] == const1_rtx
10491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10492 return "<rotate>{<imodesuffix>}\t%0";
10493 else
10494 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10495 }
10496 [(set_attr "type" "rotate")
10497 (set (attr "length_immediate")
10498 (if_then_else
10499 (and (match_operand 2 "const1_operand")
10500 (ior (match_test "TARGET_SHIFT1")
10501 (match_test "optimize_function_for_size_p (cfun)")))
10502 (const_string "0")
10503 (const_string "*")))
10504 (set_attr "mode" "<MODE>")])
10505
10506 (define_insn "*<rotate_insn>qi3_1_slp"
10507 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10508 (any_rotate:QI (match_dup 0)
10509 (match_operand:QI 1 "nonmemory_operand" "cI")))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "(optimize_function_for_size_p (cfun)
10512 || !TARGET_PARTIAL_REG_STALL
10513 || (operands[1] == const1_rtx
10514 && TARGET_SHIFT1))"
10515 {
10516 if (operands[1] == const1_rtx
10517 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10518 return "<rotate>{b}\t%0";
10519 else
10520 return "<rotate>{b}\t{%1, %0|%0, %1}";
10521 }
10522 [(set_attr "type" "rotate1")
10523 (set (attr "length_immediate")
10524 (if_then_else
10525 (and (match_operand 1 "const1_operand")
10526 (ior (match_test "TARGET_SHIFT1")
10527 (match_test "optimize_function_for_size_p (cfun)")))
10528 (const_string "0")
10529 (const_string "*")))
10530 (set_attr "mode" "QI")])
10531
10532 (define_split
10533 [(set (match_operand:HI 0 "register_operand")
10534 (any_rotate:HI (match_dup 0) (const_int 8)))
10535 (clobber (reg:CC FLAGS_REG))]
10536 "reload_completed
10537 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10538 [(parallel [(set (strict_low_part (match_dup 0))
10539 (bswap:HI (match_dup 0)))
10540 (clobber (reg:CC FLAGS_REG))])])
10541 \f
10542 ;; Bit set / bit test instructions
10543
10544 (define_expand "extv"
10545 [(set (match_operand:SI 0 "register_operand")
10546 (sign_extract:SI (match_operand:SI 1 "register_operand")
10547 (match_operand:SI 2 "const8_operand")
10548 (match_operand:SI 3 "const8_operand")))]
10549 ""
10550 {
10551 /* Handle extractions from %ah et al. */
10552 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10553 FAIL;
10554
10555 /* From mips.md: extract_bit_field doesn't verify that our source
10556 matches the predicate, so check it again here. */
10557 if (! ext_register_operand (operands[1], VOIDmode))
10558 FAIL;
10559 })
10560
10561 (define_expand "extzv"
10562 [(set (match_operand:SI 0 "register_operand")
10563 (zero_extract:SI (match_operand 1 "ext_register_operand")
10564 (match_operand:SI 2 "const8_operand")
10565 (match_operand:SI 3 "const8_operand")))]
10566 ""
10567 {
10568 /* Handle extractions from %ah et al. */
10569 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10570 FAIL;
10571
10572 /* From mips.md: extract_bit_field doesn't verify that our source
10573 matches the predicate, so check it again here. */
10574 if (! ext_register_operand (operands[1], VOIDmode))
10575 FAIL;
10576 })
10577
10578 (define_expand "insv"
10579 [(set (zero_extract (match_operand 0 "register_operand")
10580 (match_operand 1 "const_int_operand")
10581 (match_operand 2 "const_int_operand"))
10582 (match_operand 3 "register_operand"))]
10583 ""
10584 {
10585 rtx (*gen_mov_insv_1) (rtx, rtx);
10586
10587 if (ix86_expand_pinsr (operands))
10588 DONE;
10589
10590 /* Handle insertions to %ah et al. */
10591 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10592 FAIL;
10593
10594 /* From mips.md: insert_bit_field doesn't verify that our source
10595 matches the predicate, so check it again here. */
10596 if (! ext_register_operand (operands[0], VOIDmode))
10597 FAIL;
10598
10599 gen_mov_insv_1 = (TARGET_64BIT
10600 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10601
10602 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10603 DONE;
10604 })
10605
10606 ;; %%% bts, btr, btc, bt.
10607 ;; In general these instructions are *slow* when applied to memory,
10608 ;; since they enforce atomic operation. When applied to registers,
10609 ;; it depends on the cpu implementation. They're never faster than
10610 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10611 ;; no point. But in 64-bit, we can't hold the relevant immediates
10612 ;; within the instruction itself, so operating on bits in the high
10613 ;; 32-bits of a register becomes easier.
10614 ;;
10615 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10616 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10617 ;; negdf respectively, so they can never be disabled entirely.
10618
10619 (define_insn "*btsq"
10620 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10621 (const_int 1)
10622 (match_operand:DI 1 "const_0_to_63_operand"))
10623 (const_int 1))
10624 (clobber (reg:CC FLAGS_REG))]
10625 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10626 "bts{q}\t{%1, %0|%0, %1}"
10627 [(set_attr "type" "alu1")
10628 (set_attr "prefix_0f" "1")
10629 (set_attr "mode" "DI")])
10630
10631 (define_insn "*btrq"
10632 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10633 (const_int 1)
10634 (match_operand:DI 1 "const_0_to_63_operand"))
10635 (const_int 0))
10636 (clobber (reg:CC FLAGS_REG))]
10637 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10638 "btr{q}\t{%1, %0|%0, %1}"
10639 [(set_attr "type" "alu1")
10640 (set_attr "prefix_0f" "1")
10641 (set_attr "mode" "DI")])
10642
10643 (define_insn "*btcq"
10644 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10645 (const_int 1)
10646 (match_operand:DI 1 "const_0_to_63_operand"))
10647 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10648 (clobber (reg:CC FLAGS_REG))]
10649 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10650 "btc{q}\t{%1, %0|%0, %1}"
10651 [(set_attr "type" "alu1")
10652 (set_attr "prefix_0f" "1")
10653 (set_attr "mode" "DI")])
10654
10655 ;; Allow Nocona to avoid these instructions if a register is available.
10656
10657 (define_peephole2
10658 [(match_scratch:DI 2 "r")
10659 (parallel [(set (zero_extract:DI
10660 (match_operand:DI 0 "register_operand")
10661 (const_int 1)
10662 (match_operand:DI 1 "const_0_to_63_operand"))
10663 (const_int 1))
10664 (clobber (reg:CC FLAGS_REG))])]
10665 "TARGET_64BIT && !TARGET_USE_BT"
10666 [(const_int 0)]
10667 {
10668 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10669 rtx op1;
10670
10671 if (HOST_BITS_PER_WIDE_INT >= 64)
10672 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10673 else if (i < HOST_BITS_PER_WIDE_INT)
10674 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10675 else
10676 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10677
10678 op1 = immed_double_const (lo, hi, DImode);
10679 if (i >= 31)
10680 {
10681 emit_move_insn (operands[2], op1);
10682 op1 = operands[2];
10683 }
10684
10685 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10686 DONE;
10687 })
10688
10689 (define_peephole2
10690 [(match_scratch:DI 2 "r")
10691 (parallel [(set (zero_extract:DI
10692 (match_operand:DI 0 "register_operand")
10693 (const_int 1)
10694 (match_operand:DI 1 "const_0_to_63_operand"))
10695 (const_int 0))
10696 (clobber (reg:CC FLAGS_REG))])]
10697 "TARGET_64BIT && !TARGET_USE_BT"
10698 [(const_int 0)]
10699 {
10700 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10701 rtx op1;
10702
10703 if (HOST_BITS_PER_WIDE_INT >= 64)
10704 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10705 else if (i < HOST_BITS_PER_WIDE_INT)
10706 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10707 else
10708 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10709
10710 op1 = immed_double_const (~lo, ~hi, DImode);
10711 if (i >= 32)
10712 {
10713 emit_move_insn (operands[2], op1);
10714 op1 = operands[2];
10715 }
10716
10717 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10718 DONE;
10719 })
10720
10721 (define_peephole2
10722 [(match_scratch:DI 2 "r")
10723 (parallel [(set (zero_extract:DI
10724 (match_operand:DI 0 "register_operand")
10725 (const_int 1)
10726 (match_operand:DI 1 "const_0_to_63_operand"))
10727 (not:DI (zero_extract:DI
10728 (match_dup 0) (const_int 1) (match_dup 1))))
10729 (clobber (reg:CC FLAGS_REG))])]
10730 "TARGET_64BIT && !TARGET_USE_BT"
10731 [(const_int 0)]
10732 {
10733 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10734 rtx op1;
10735
10736 if (HOST_BITS_PER_WIDE_INT >= 64)
10737 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10738 else if (i < HOST_BITS_PER_WIDE_INT)
10739 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10740 else
10741 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10742
10743 op1 = immed_double_const (lo, hi, DImode);
10744 if (i >= 31)
10745 {
10746 emit_move_insn (operands[2], op1);
10747 op1 = operands[2];
10748 }
10749
10750 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10751 DONE;
10752 })
10753
10754 (define_insn "*bt<mode>"
10755 [(set (reg:CCC FLAGS_REG)
10756 (compare:CCC
10757 (zero_extract:SWI48
10758 (match_operand:SWI48 0 "register_operand" "r")
10759 (const_int 1)
10760 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10761 (const_int 0)))]
10762 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10763 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10764 [(set_attr "type" "alu1")
10765 (set_attr "prefix_0f" "1")
10766 (set_attr "mode" "<MODE>")])
10767 \f
10768 ;; Store-flag instructions.
10769
10770 ;; For all sCOND expanders, also expand the compare or test insn that
10771 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10772
10773 (define_insn_and_split "*setcc_di_1"
10774 [(set (match_operand:DI 0 "register_operand" "=q")
10775 (match_operator:DI 1 "ix86_comparison_operator"
10776 [(reg FLAGS_REG) (const_int 0)]))]
10777 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10778 "#"
10779 "&& reload_completed"
10780 [(set (match_dup 2) (match_dup 1))
10781 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10782 {
10783 PUT_MODE (operands[1], QImode);
10784 operands[2] = gen_lowpart (QImode, operands[0]);
10785 })
10786
10787 (define_insn_and_split "*setcc_si_1_and"
10788 [(set (match_operand:SI 0 "register_operand" "=q")
10789 (match_operator:SI 1 "ix86_comparison_operator"
10790 [(reg FLAGS_REG) (const_int 0)]))
10791 (clobber (reg:CC FLAGS_REG))]
10792 "!TARGET_PARTIAL_REG_STALL
10793 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10794 "#"
10795 "&& reload_completed"
10796 [(set (match_dup 2) (match_dup 1))
10797 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10798 (clobber (reg:CC FLAGS_REG))])]
10799 {
10800 PUT_MODE (operands[1], QImode);
10801 operands[2] = gen_lowpart (QImode, operands[0]);
10802 })
10803
10804 (define_insn_and_split "*setcc_si_1_movzbl"
10805 [(set (match_operand:SI 0 "register_operand" "=q")
10806 (match_operator:SI 1 "ix86_comparison_operator"
10807 [(reg FLAGS_REG) (const_int 0)]))]
10808 "!TARGET_PARTIAL_REG_STALL
10809 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10810 "#"
10811 "&& reload_completed"
10812 [(set (match_dup 2) (match_dup 1))
10813 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10814 {
10815 PUT_MODE (operands[1], QImode);
10816 operands[2] = gen_lowpart (QImode, operands[0]);
10817 })
10818
10819 (define_insn "*setcc_qi"
10820 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10821 (match_operator:QI 1 "ix86_comparison_operator"
10822 [(reg FLAGS_REG) (const_int 0)]))]
10823 ""
10824 "set%C1\t%0"
10825 [(set_attr "type" "setcc")
10826 (set_attr "mode" "QI")])
10827
10828 (define_insn "*setcc_qi_slp"
10829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10830 (match_operator:QI 1 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)]))]
10832 ""
10833 "set%C1\t%0"
10834 [(set_attr "type" "setcc")
10835 (set_attr "mode" "QI")])
10836
10837 ;; In general it is not safe to assume too much about CCmode registers,
10838 ;; so simplify-rtx stops when it sees a second one. Under certain
10839 ;; conditions this is safe on x86, so help combine not create
10840 ;;
10841 ;; seta %al
10842 ;; testb %al, %al
10843 ;; sete %al
10844
10845 (define_split
10846 [(set (match_operand:QI 0 "nonimmediate_operand")
10847 (ne:QI (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10849 (const_int 0)))]
10850 ""
10851 [(set (match_dup 0) (match_dup 1))]
10852 "PUT_MODE (operands[1], QImode);")
10853
10854 (define_split
10855 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10856 (ne:QI (match_operator 1 "ix86_comparison_operator"
10857 [(reg FLAGS_REG) (const_int 0)])
10858 (const_int 0)))]
10859 ""
10860 [(set (match_dup 0) (match_dup 1))]
10861 "PUT_MODE (operands[1], QImode);")
10862
10863 (define_split
10864 [(set (match_operand:QI 0 "nonimmediate_operand")
10865 (eq:QI (match_operator 1 "ix86_comparison_operator"
10866 [(reg FLAGS_REG) (const_int 0)])
10867 (const_int 0)))]
10868 ""
10869 [(set (match_dup 0) (match_dup 1))]
10870 {
10871 rtx new_op1 = copy_rtx (operands[1]);
10872 operands[1] = new_op1;
10873 PUT_MODE (new_op1, QImode);
10874 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10875 GET_MODE (XEXP (new_op1, 0))));
10876
10877 /* Make sure that (a) the CCmode we have for the flags is strong
10878 enough for the reversed compare or (b) we have a valid FP compare. */
10879 if (! ix86_comparison_operator (new_op1, VOIDmode))
10880 FAIL;
10881 })
10882
10883 (define_split
10884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10885 (eq:QI (match_operator 1 "ix86_comparison_operator"
10886 [(reg FLAGS_REG) (const_int 0)])
10887 (const_int 0)))]
10888 ""
10889 [(set (match_dup 0) (match_dup 1))]
10890 {
10891 rtx new_op1 = copy_rtx (operands[1]);
10892 operands[1] = new_op1;
10893 PUT_MODE (new_op1, QImode);
10894 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10895 GET_MODE (XEXP (new_op1, 0))));
10896
10897 /* Make sure that (a) the CCmode we have for the flags is strong
10898 enough for the reversed compare or (b) we have a valid FP compare. */
10899 if (! ix86_comparison_operator (new_op1, VOIDmode))
10900 FAIL;
10901 })
10902
10903 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10904 ;; subsequent logical operations are used to imitate conditional moves.
10905 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10906 ;; it directly.
10907
10908 (define_insn "setcc_<mode>_sse"
10909 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10910 (match_operator:MODEF 3 "sse_comparison_operator"
10911 [(match_operand:MODEF 1 "register_operand" "0,x")
10912 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10913 "SSE_FLOAT_MODE_P (<MODE>mode)"
10914 "@
10915 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10916 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10917 [(set_attr "isa" "noavx,avx")
10918 (set_attr "type" "ssecmp")
10919 (set_attr "length_immediate" "1")
10920 (set_attr "prefix" "orig,vex")
10921 (set_attr "mode" "<MODE>")])
10922 \f
10923 ;; Basic conditional jump instructions.
10924 ;; We ignore the overflow flag for signed branch instructions.
10925
10926 (define_insn "*jcc_1"
10927 [(set (pc)
10928 (if_then_else (match_operator 1 "ix86_comparison_operator"
10929 [(reg FLAGS_REG) (const_int 0)])
10930 (label_ref (match_operand 0))
10931 (pc)))]
10932 ""
10933 "%!%+j%C1\t%l0"
10934 [(set_attr "type" "ibr")
10935 (set_attr "modrm" "0")
10936 (set (attr "length_nobnd")
10937 (if_then_else (and (ge (minus (match_dup 0) (pc))
10938 (const_int -126))
10939 (lt (minus (match_dup 0) (pc))
10940 (const_int 128)))
10941 (const_int 2)
10942 (const_int 6)))])
10943
10944 (define_insn "*jcc_2"
10945 [(set (pc)
10946 (if_then_else (match_operator 1 "ix86_comparison_operator"
10947 [(reg FLAGS_REG) (const_int 0)])
10948 (pc)
10949 (label_ref (match_operand 0))))]
10950 ""
10951 "%!%+j%c1\t%l0"
10952 [(set_attr "type" "ibr")
10953 (set_attr "modrm" "0")
10954 (set (attr "length_nobnd")
10955 (if_then_else (and (ge (minus (match_dup 0) (pc))
10956 (const_int -126))
10957 (lt (minus (match_dup 0) (pc))
10958 (const_int 128)))
10959 (const_int 2)
10960 (const_int 6)))])
10961
10962 ;; In general it is not safe to assume too much about CCmode registers,
10963 ;; so simplify-rtx stops when it sees a second one. Under certain
10964 ;; conditions this is safe on x86, so help combine not create
10965 ;;
10966 ;; seta %al
10967 ;; testb %al, %al
10968 ;; je Lfoo
10969
10970 (define_split
10971 [(set (pc)
10972 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10973 [(reg FLAGS_REG) (const_int 0)])
10974 (const_int 0))
10975 (label_ref (match_operand 1))
10976 (pc)))]
10977 ""
10978 [(set (pc)
10979 (if_then_else (match_dup 0)
10980 (label_ref (match_dup 1))
10981 (pc)))]
10982 "PUT_MODE (operands[0], VOIDmode);")
10983
10984 (define_split
10985 [(set (pc)
10986 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10987 [(reg FLAGS_REG) (const_int 0)])
10988 (const_int 0))
10989 (label_ref (match_operand 1))
10990 (pc)))]
10991 ""
10992 [(set (pc)
10993 (if_then_else (match_dup 0)
10994 (label_ref (match_dup 1))
10995 (pc)))]
10996 {
10997 rtx new_op0 = copy_rtx (operands[0]);
10998 operands[0] = new_op0;
10999 PUT_MODE (new_op0, VOIDmode);
11000 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11001 GET_MODE (XEXP (new_op0, 0))));
11002
11003 /* Make sure that (a) the CCmode we have for the flags is strong
11004 enough for the reversed compare or (b) we have a valid FP compare. */
11005 if (! ix86_comparison_operator (new_op0, VOIDmode))
11006 FAIL;
11007 })
11008
11009 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11010 ;; pass generates from shift insn with QImode operand. Actually, the mode
11011 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11012 ;; appropriate modulo of the bit offset value.
11013
11014 (define_insn_and_split "*jcc_bt<mode>"
11015 [(set (pc)
11016 (if_then_else (match_operator 0 "bt_comparison_operator"
11017 [(zero_extract:SWI48
11018 (match_operand:SWI48 1 "register_operand" "r")
11019 (const_int 1)
11020 (zero_extend:SI
11021 (match_operand:QI 2 "register_operand" "r")))
11022 (const_int 0)])
11023 (label_ref (match_operand 3))
11024 (pc)))
11025 (clobber (reg:CC FLAGS_REG))]
11026 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11027 "#"
11028 "&& 1"
11029 [(set (reg:CCC FLAGS_REG)
11030 (compare:CCC
11031 (zero_extract:SWI48
11032 (match_dup 1)
11033 (const_int 1)
11034 (match_dup 2))
11035 (const_int 0)))
11036 (set (pc)
11037 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11038 (label_ref (match_dup 3))
11039 (pc)))]
11040 {
11041 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11042
11043 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11044 })
11045
11046 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11047 ;; zero extended to SImode.
11048 (define_insn_and_split "*jcc_bt<mode>_1"
11049 [(set (pc)
11050 (if_then_else (match_operator 0 "bt_comparison_operator"
11051 [(zero_extract:SWI48
11052 (match_operand:SWI48 1 "register_operand" "r")
11053 (const_int 1)
11054 (match_operand:SI 2 "register_operand" "r"))
11055 (const_int 0)])
11056 (label_ref (match_operand 3))
11057 (pc)))
11058 (clobber (reg:CC FLAGS_REG))]
11059 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11060 "#"
11061 "&& 1"
11062 [(set (reg:CCC FLAGS_REG)
11063 (compare:CCC
11064 (zero_extract:SWI48
11065 (match_dup 1)
11066 (const_int 1)
11067 (match_dup 2))
11068 (const_int 0)))
11069 (set (pc)
11070 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11071 (label_ref (match_dup 3))
11072 (pc)))]
11073 {
11074 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11075
11076 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11077 })
11078
11079 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11080 ;; also for DImode, this is what combine produces.
11081 (define_insn_and_split "*jcc_bt<mode>_mask"
11082 [(set (pc)
11083 (if_then_else (match_operator 0 "bt_comparison_operator"
11084 [(zero_extract:SWI48
11085 (match_operand:SWI48 1 "register_operand" "r")
11086 (const_int 1)
11087 (and:SI
11088 (match_operand:SI 2 "register_operand" "r")
11089 (match_operand:SI 3 "const_int_operand" "n")))])
11090 (label_ref (match_operand 4))
11091 (pc)))
11092 (clobber (reg:CC FLAGS_REG))]
11093 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11094 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11095 == GET_MODE_BITSIZE (<MODE>mode)-1"
11096 "#"
11097 "&& 1"
11098 [(set (reg:CCC FLAGS_REG)
11099 (compare:CCC
11100 (zero_extract:SWI48
11101 (match_dup 1)
11102 (const_int 1)
11103 (match_dup 2))
11104 (const_int 0)))
11105 (set (pc)
11106 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11107 (label_ref (match_dup 4))
11108 (pc)))]
11109 {
11110 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11111
11112 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11113 })
11114
11115 (define_insn_and_split "*jcc_btsi_1"
11116 [(set (pc)
11117 (if_then_else (match_operator 0 "bt_comparison_operator"
11118 [(and:SI
11119 (lshiftrt:SI
11120 (match_operand:SI 1 "register_operand" "r")
11121 (match_operand:QI 2 "register_operand" "r"))
11122 (const_int 1))
11123 (const_int 0)])
11124 (label_ref (match_operand 3))
11125 (pc)))
11126 (clobber (reg:CC FLAGS_REG))]
11127 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11128 "#"
11129 "&& 1"
11130 [(set (reg:CCC FLAGS_REG)
11131 (compare:CCC
11132 (zero_extract:SI
11133 (match_dup 1)
11134 (const_int 1)
11135 (match_dup 2))
11136 (const_int 0)))
11137 (set (pc)
11138 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11139 (label_ref (match_dup 3))
11140 (pc)))]
11141 {
11142 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11143
11144 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11145 })
11146
11147 ;; avoid useless masking of bit offset operand
11148 (define_insn_and_split "*jcc_btsi_mask_1"
11149 [(set (pc)
11150 (if_then_else
11151 (match_operator 0 "bt_comparison_operator"
11152 [(and:SI
11153 (lshiftrt:SI
11154 (match_operand:SI 1 "register_operand" "r")
11155 (subreg:QI
11156 (and:SI
11157 (match_operand:SI 2 "register_operand" "r")
11158 (match_operand:SI 3 "const_int_operand" "n")) 0))
11159 (const_int 1))
11160 (const_int 0)])
11161 (label_ref (match_operand 4))
11162 (pc)))
11163 (clobber (reg:CC FLAGS_REG))]
11164 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11165 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11166 "#"
11167 "&& 1"
11168 [(set (reg:CCC FLAGS_REG)
11169 (compare:CCC
11170 (zero_extract:SI
11171 (match_dup 1)
11172 (const_int 1)
11173 (match_dup 2))
11174 (const_int 0)))
11175 (set (pc)
11176 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11177 (label_ref (match_dup 4))
11178 (pc)))]
11179 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11180
11181 ;; Define combination compare-and-branch fp compare instructions to help
11182 ;; combine.
11183
11184 (define_insn "*jcc<mode>_0_i387"
11185 [(set (pc)
11186 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11187 [(match_operand:X87MODEF 1 "register_operand" "f")
11188 (match_operand:X87MODEF 2 "const0_operand")])
11189 (label_ref (match_operand 3))
11190 (pc)))
11191 (clobber (reg:CCFP FPSR_REG))
11192 (clobber (reg:CCFP FLAGS_REG))
11193 (clobber (match_scratch:HI 4 "=a"))]
11194 "TARGET_80387 && !TARGET_CMOVE"
11195 "#")
11196
11197 (define_insn "*jcc<mode>_0_r_i387"
11198 [(set (pc)
11199 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11200 [(match_operand:X87MODEF 1 "register_operand" "f")
11201 (match_operand:X87MODEF 2 "const0_operand")])
11202 (pc)
11203 (label_ref (match_operand 3))))
11204 (clobber (reg:CCFP FPSR_REG))
11205 (clobber (reg:CCFP FLAGS_REG))
11206 (clobber (match_scratch:HI 4 "=a"))]
11207 "TARGET_80387 && !TARGET_CMOVE"
11208 "#")
11209
11210 (define_insn "*jccxf_i387"
11211 [(set (pc)
11212 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11213 [(match_operand:XF 1 "register_operand" "f")
11214 (match_operand:XF 2 "register_operand" "f")])
11215 (label_ref (match_operand 3))
11216 (pc)))
11217 (clobber (reg:CCFP FPSR_REG))
11218 (clobber (reg:CCFP FLAGS_REG))
11219 (clobber (match_scratch:HI 4 "=a"))]
11220 "TARGET_80387 && !TARGET_CMOVE"
11221 "#")
11222
11223 (define_insn "*jccxf_r_i387"
11224 [(set (pc)
11225 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11226 [(match_operand:XF 1 "register_operand" "f")
11227 (match_operand:XF 2 "register_operand" "f")])
11228 (pc)
11229 (label_ref (match_operand 3))))
11230 (clobber (reg:CCFP FPSR_REG))
11231 (clobber (reg:CCFP FLAGS_REG))
11232 (clobber (match_scratch:HI 4 "=a"))]
11233 "TARGET_80387 && !TARGET_CMOVE"
11234 "#")
11235
11236 (define_insn "*jcc<mode>_i387"
11237 [(set (pc)
11238 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11239 [(match_operand:MODEF 1 "register_operand" "f")
11240 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11241 (label_ref (match_operand 3))
11242 (pc)))
11243 (clobber (reg:CCFP FPSR_REG))
11244 (clobber (reg:CCFP FLAGS_REG))
11245 (clobber (match_scratch:HI 4 "=a"))]
11246 "TARGET_80387 && !TARGET_CMOVE"
11247 "#")
11248
11249 (define_insn "*jcc<mode>_r_i387"
11250 [(set (pc)
11251 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11252 [(match_operand:MODEF 1 "register_operand" "f")
11253 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11254 (pc)
11255 (label_ref (match_operand 3))))
11256 (clobber (reg:CCFP FPSR_REG))
11257 (clobber (reg:CCFP FLAGS_REG))
11258 (clobber (match_scratch:HI 4 "=a"))]
11259 "TARGET_80387 && !TARGET_CMOVE"
11260 "#")
11261
11262 (define_insn "*jccu<mode>_i387"
11263 [(set (pc)
11264 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11265 [(match_operand:X87MODEF 1 "register_operand" "f")
11266 (match_operand:X87MODEF 2 "register_operand" "f")])
11267 (label_ref (match_operand 3))
11268 (pc)))
11269 (clobber (reg:CCFP FPSR_REG))
11270 (clobber (reg:CCFP FLAGS_REG))
11271 (clobber (match_scratch:HI 4 "=a"))]
11272 "TARGET_80387 && !TARGET_CMOVE"
11273 "#")
11274
11275 (define_insn "*jccu<mode>_r_i387"
11276 [(set (pc)
11277 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11278 [(match_operand:X87MODEF 1 "register_operand" "f")
11279 (match_operand:X87MODEF 2 "register_operand" "f")])
11280 (pc)
11281 (label_ref (match_operand 3))))
11282 (clobber (reg:CCFP FPSR_REG))
11283 (clobber (reg:CCFP FLAGS_REG))
11284 (clobber (match_scratch:HI 4 "=a"))]
11285 "TARGET_80387 && !TARGET_CMOVE"
11286 "#")
11287
11288 (define_split
11289 [(set (pc)
11290 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11291 [(match_operand:X87MODEF 1 "register_operand")
11292 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11293 (match_operand 3)
11294 (match_operand 4)))
11295 (clobber (reg:CCFP FPSR_REG))
11296 (clobber (reg:CCFP FLAGS_REG))]
11297 "TARGET_80387 && !TARGET_CMOVE
11298 && reload_completed"
11299 [(const_int 0)]
11300 {
11301 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11302 operands[3], operands[4], NULL_RTX);
11303 DONE;
11304 })
11305
11306 (define_split
11307 [(set (pc)
11308 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11309 [(match_operand:X87MODEF 1 "register_operand")
11310 (match_operand:X87MODEF 2 "general_operand")])
11311 (match_operand 3)
11312 (match_operand 4)))
11313 (clobber (reg:CCFP FPSR_REG))
11314 (clobber (reg:CCFP FLAGS_REG))
11315 (clobber (match_scratch:HI 5))]
11316 "TARGET_80387 && !TARGET_CMOVE
11317 && reload_completed"
11318 [(const_int 0)]
11319 {
11320 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11321 operands[3], operands[4], operands[5]);
11322 DONE;
11323 })
11324
11325 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11326 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11327 ;; with a precedence over other operators and is always put in the first
11328 ;; place. Swap condition and operands to match ficom instruction.
11329
11330 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11331 [(set (pc)
11332 (if_then_else
11333 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11334 [(match_operator:X87MODEF 1 "float_operator"
11335 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11336 (match_operand:X87MODEF 3 "register_operand" "f")])
11337 (label_ref (match_operand 4))
11338 (pc)))
11339 (clobber (reg:CCFP FPSR_REG))
11340 (clobber (reg:CCFP FLAGS_REG))
11341 (clobber (match_scratch:HI 5 "=a"))]
11342 "TARGET_80387 && !TARGET_CMOVE
11343 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11344 || optimize_function_for_size_p (cfun))"
11345 "#")
11346
11347 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11348 [(set (pc)
11349 (if_then_else
11350 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11351 [(match_operator:X87MODEF 1 "float_operator"
11352 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11353 (match_operand:X87MODEF 3 "register_operand" "f")])
11354 (pc)
11355 (label_ref (match_operand 4))))
11356 (clobber (reg:CCFP FPSR_REG))
11357 (clobber (reg:CCFP FLAGS_REG))
11358 (clobber (match_scratch:HI 5 "=a"))]
11359 "TARGET_80387 && !TARGET_CMOVE
11360 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11361 || optimize_function_for_size_p (cfun))"
11362 "#")
11363
11364 (define_split
11365 [(set (pc)
11366 (if_then_else
11367 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11368 [(match_operator:X87MODEF 1 "float_operator"
11369 [(match_operand:SWI24 2 "memory_operand")])
11370 (match_operand:X87MODEF 3 "register_operand")])
11371 (match_operand 4)
11372 (match_operand 5)))
11373 (clobber (reg:CCFP FPSR_REG))
11374 (clobber (reg:CCFP FLAGS_REG))
11375 (clobber (match_scratch:HI 6))]
11376 "TARGET_80387 && !TARGET_CMOVE
11377 && reload_completed"
11378 [(const_int 0)]
11379 {
11380 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11381 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11382 operands[4], operands[5], operands[6]);
11383 DONE;
11384 })
11385 \f
11386 ;; Unconditional and other jump instructions
11387
11388 (define_insn "jump"
11389 [(set (pc)
11390 (label_ref (match_operand 0)))]
11391 ""
11392 "%!jmp\t%l0"
11393 [(set_attr "type" "ibr")
11394 (set (attr "length_nobnd")
11395 (if_then_else (and (ge (minus (match_dup 0) (pc))
11396 (const_int -126))
11397 (lt (minus (match_dup 0) (pc))
11398 (const_int 128)))
11399 (const_int 2)
11400 (const_int 5)))
11401 (set_attr "modrm" "0")])
11402
11403 (define_expand "indirect_jump"
11404 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11405 ""
11406 {
11407 if (TARGET_X32)
11408 operands[0] = convert_memory_address (word_mode, operands[0]);
11409 })
11410
11411 (define_insn "*indirect_jump"
11412 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11413 ""
11414 "%!jmp\t%A0"
11415 [(set_attr "type" "ibr")
11416 (set_attr "length_immediate" "0")])
11417
11418 (define_expand "tablejump"
11419 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11420 (use (label_ref (match_operand 1)))])]
11421 ""
11422 {
11423 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11424 relative. Convert the relative address to an absolute address. */
11425 if (flag_pic)
11426 {
11427 rtx op0, op1;
11428 enum rtx_code code;
11429
11430 /* We can't use @GOTOFF for text labels on VxWorks;
11431 see gotoff_operand. */
11432 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11433 {
11434 code = PLUS;
11435 op0 = operands[0];
11436 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11437 }
11438 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11439 {
11440 code = PLUS;
11441 op0 = operands[0];
11442 op1 = pic_offset_table_rtx;
11443 }
11444 else
11445 {
11446 code = MINUS;
11447 op0 = pic_offset_table_rtx;
11448 op1 = operands[0];
11449 }
11450
11451 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11452 OPTAB_DIRECT);
11453 }
11454
11455 if (TARGET_X32)
11456 operands[0] = convert_memory_address (word_mode, operands[0]);
11457 })
11458
11459 (define_insn "*tablejump_1"
11460 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11461 (use (label_ref (match_operand 1)))]
11462 ""
11463 "%!jmp\t%A0"
11464 [(set_attr "type" "ibr")
11465 (set_attr "length_immediate" "0")])
11466 \f
11467 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11468
11469 (define_peephole2
11470 [(set (reg FLAGS_REG) (match_operand 0))
11471 (set (match_operand:QI 1 "register_operand")
11472 (match_operator:QI 2 "ix86_comparison_operator"
11473 [(reg FLAGS_REG) (const_int 0)]))
11474 (set (match_operand 3 "q_regs_operand")
11475 (zero_extend (match_dup 1)))]
11476 "(peep2_reg_dead_p (3, operands[1])
11477 || operands_match_p (operands[1], operands[3]))
11478 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11479 [(set (match_dup 4) (match_dup 0))
11480 (set (strict_low_part (match_dup 5))
11481 (match_dup 2))]
11482 {
11483 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11484 operands[5] = gen_lowpart (QImode, operands[3]);
11485 ix86_expand_clear (operands[3]);
11486 })
11487
11488 (define_peephole2
11489 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11490 (match_operand 4)])
11491 (set (match_operand:QI 1 "register_operand")
11492 (match_operator:QI 2 "ix86_comparison_operator"
11493 [(reg FLAGS_REG) (const_int 0)]))
11494 (set (match_operand 3 "q_regs_operand")
11495 (zero_extend (match_dup 1)))]
11496 "(peep2_reg_dead_p (3, operands[1])
11497 || operands_match_p (operands[1], operands[3]))
11498 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11499 [(parallel [(set (match_dup 5) (match_dup 0))
11500 (match_dup 4)])
11501 (set (strict_low_part (match_dup 6))
11502 (match_dup 2))]
11503 {
11504 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11505 operands[6] = gen_lowpart (QImode, operands[3]);
11506 ix86_expand_clear (operands[3]);
11507 })
11508
11509 ;; Similar, but match zero extend with andsi3.
11510
11511 (define_peephole2
11512 [(set (reg FLAGS_REG) (match_operand 0))
11513 (set (match_operand:QI 1 "register_operand")
11514 (match_operator:QI 2 "ix86_comparison_operator"
11515 [(reg FLAGS_REG) (const_int 0)]))
11516 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11517 (and:SI (match_dup 3) (const_int 255)))
11518 (clobber (reg:CC FLAGS_REG))])]
11519 "REGNO (operands[1]) == REGNO (operands[3])
11520 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11521 [(set (match_dup 4) (match_dup 0))
11522 (set (strict_low_part (match_dup 5))
11523 (match_dup 2))]
11524 {
11525 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11526 operands[5] = gen_lowpart (QImode, operands[3]);
11527 ix86_expand_clear (operands[3]);
11528 })
11529
11530 (define_peephole2
11531 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11532 (match_operand 4)])
11533 (set (match_operand:QI 1 "register_operand")
11534 (match_operator:QI 2 "ix86_comparison_operator"
11535 [(reg FLAGS_REG) (const_int 0)]))
11536 (parallel [(set (match_operand 3 "q_regs_operand")
11537 (zero_extend (match_dup 1)))
11538 (clobber (reg:CC FLAGS_REG))])]
11539 "(peep2_reg_dead_p (3, operands[1])
11540 || operands_match_p (operands[1], operands[3]))
11541 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11542 [(parallel [(set (match_dup 5) (match_dup 0))
11543 (match_dup 4)])
11544 (set (strict_low_part (match_dup 6))
11545 (match_dup 2))]
11546 {
11547 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11548 operands[6] = gen_lowpart (QImode, operands[3]);
11549 ix86_expand_clear (operands[3]);
11550 })
11551 \f
11552 ;; Call instructions.
11553
11554 ;; The predicates normally associated with named expanders are not properly
11555 ;; checked for calls. This is a bug in the generic code, but it isn't that
11556 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11557
11558 ;; P6 processors will jump to the address after the decrement when %esp
11559 ;; is used as a call operand, so they will execute return address as a code.
11560 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11561
11562 ;; Register constraint for call instruction.
11563 (define_mode_attr c [(SI "l") (DI "r")])
11564
11565 ;; Call subroutine returning no value.
11566
11567 (define_expand "call"
11568 [(call (match_operand:QI 0)
11569 (match_operand 1))
11570 (use (match_operand 2))]
11571 ""
11572 {
11573 ix86_expand_call (NULL, operands[0], operands[1],
11574 operands[2], NULL, false);
11575 DONE;
11576 })
11577
11578 (define_expand "sibcall"
11579 [(call (match_operand:QI 0)
11580 (match_operand 1))
11581 (use (match_operand 2))]
11582 ""
11583 {
11584 ix86_expand_call (NULL, operands[0], operands[1],
11585 operands[2], NULL, true);
11586 DONE;
11587 })
11588
11589 (define_insn "*call"
11590 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11591 (match_operand 1))]
11592 "!SIBLING_CALL_P (insn)"
11593 "* return ix86_output_call_insn (insn, operands[0]);"
11594 [(set_attr "type" "call")])
11595
11596 (define_insn "*sibcall"
11597 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11598 (match_operand 1))]
11599 "SIBLING_CALL_P (insn)"
11600 "* return ix86_output_call_insn (insn, operands[0]);"
11601 [(set_attr "type" "call")])
11602
11603 (define_insn "*sibcall_memory"
11604 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11605 (match_operand 1))
11606 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11607 "!TARGET_X32"
11608 "* return ix86_output_call_insn (insn, operands[0]);"
11609 [(set_attr "type" "call")])
11610
11611 (define_peephole2
11612 [(set (match_operand:W 0 "register_operand")
11613 (match_operand:W 1 "memory_operand"))
11614 (call (mem:QI (match_dup 0))
11615 (match_operand 3))]
11616 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11617 && peep2_reg_dead_p (2, operands[0])"
11618 [(parallel [(call (mem:QI (match_dup 1))
11619 (match_dup 3))
11620 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11621
11622 (define_peephole2
11623 [(set (match_operand:W 0 "register_operand")
11624 (match_operand:W 1 "memory_operand"))
11625 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11626 (call (mem:QI (match_dup 0))
11627 (match_operand 3))]
11628 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11629 && peep2_reg_dead_p (3, operands[0])"
11630 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11631 (parallel [(call (mem:QI (match_dup 1))
11632 (match_dup 3))
11633 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11634
11635 (define_expand "call_pop"
11636 [(parallel [(call (match_operand:QI 0)
11637 (match_operand:SI 1))
11638 (set (reg:SI SP_REG)
11639 (plus:SI (reg:SI SP_REG)
11640 (match_operand:SI 3)))])]
11641 "!TARGET_64BIT"
11642 {
11643 ix86_expand_call (NULL, operands[0], operands[1],
11644 operands[2], operands[3], false);
11645 DONE;
11646 })
11647
11648 (define_insn "*call_pop"
11649 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11650 (match_operand 1))
11651 (set (reg:SI SP_REG)
11652 (plus:SI (reg:SI SP_REG)
11653 (match_operand:SI 2 "immediate_operand" "i")))]
11654 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11655 "* return ix86_output_call_insn (insn, operands[0]);"
11656 [(set_attr "type" "call")])
11657
11658 (define_insn "*sibcall_pop"
11659 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11660 (match_operand 1))
11661 (set (reg:SI SP_REG)
11662 (plus:SI (reg:SI SP_REG)
11663 (match_operand:SI 2 "immediate_operand" "i")))]
11664 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11665 "* return ix86_output_call_insn (insn, operands[0]);"
11666 [(set_attr "type" "call")])
11667
11668 (define_insn "*sibcall_pop_memory"
11669 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11670 (match_operand 1))
11671 (set (reg:SI SP_REG)
11672 (plus:SI (reg:SI SP_REG)
11673 (match_operand:SI 2 "immediate_operand" "i")))
11674 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11675 "!TARGET_64BIT"
11676 "* return ix86_output_call_insn (insn, operands[0]);"
11677 [(set_attr "type" "call")])
11678
11679 (define_peephole2
11680 [(set (match_operand:SI 0 "register_operand")
11681 (match_operand:SI 1 "memory_operand"))
11682 (parallel [(call (mem:QI (match_dup 0))
11683 (match_operand 3))
11684 (set (reg:SI SP_REG)
11685 (plus:SI (reg:SI SP_REG)
11686 (match_operand:SI 4 "immediate_operand")))])]
11687 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11688 && peep2_reg_dead_p (2, operands[0])"
11689 [(parallel [(call (mem:QI (match_dup 1))
11690 (match_dup 3))
11691 (set (reg:SI SP_REG)
11692 (plus:SI (reg:SI SP_REG)
11693 (match_dup 4)))
11694 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11695
11696 (define_peephole2
11697 [(set (match_operand:SI 0 "register_operand")
11698 (match_operand:SI 1 "memory_operand"))
11699 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11700 (parallel [(call (mem:QI (match_dup 0))
11701 (match_operand 3))
11702 (set (reg:SI SP_REG)
11703 (plus:SI (reg:SI SP_REG)
11704 (match_operand:SI 4 "immediate_operand")))])]
11705 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11706 && peep2_reg_dead_p (3, operands[0])"
11707 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11708 (parallel [(call (mem:QI (match_dup 1))
11709 (match_dup 3))
11710 (set (reg:SI SP_REG)
11711 (plus:SI (reg:SI SP_REG)
11712 (match_dup 4)))
11713 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11714
11715 ;; Combining simple memory jump instruction
11716
11717 (define_peephole2
11718 [(set (match_operand:W 0 "register_operand")
11719 (match_operand:W 1 "memory_operand"))
11720 (set (pc) (match_dup 0))]
11721 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11722 [(set (pc) (match_dup 1))])
11723
11724 ;; Call subroutine, returning value in operand 0
11725
11726 (define_expand "call_value"
11727 [(set (match_operand 0)
11728 (call (match_operand:QI 1)
11729 (match_operand 2)))
11730 (use (match_operand 3))]
11731 ""
11732 {
11733 ix86_expand_call (operands[0], operands[1], operands[2],
11734 operands[3], NULL, false);
11735 DONE;
11736 })
11737
11738 (define_expand "sibcall_value"
11739 [(set (match_operand 0)
11740 (call (match_operand:QI 1)
11741 (match_operand 2)))
11742 (use (match_operand 3))]
11743 ""
11744 {
11745 ix86_expand_call (operands[0], operands[1], operands[2],
11746 operands[3], NULL, true);
11747 DONE;
11748 })
11749
11750 (define_insn "*call_value"
11751 [(set (match_operand 0)
11752 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11753 (match_operand 2)))]
11754 "!SIBLING_CALL_P (insn)"
11755 "* return ix86_output_call_insn (insn, operands[1]);"
11756 [(set_attr "type" "callv")])
11757
11758 (define_insn "*sibcall_value"
11759 [(set (match_operand 0)
11760 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11761 (match_operand 2)))]
11762 "SIBLING_CALL_P (insn)"
11763 "* return ix86_output_call_insn (insn, operands[1]);"
11764 [(set_attr "type" "callv")])
11765
11766 (define_insn "*sibcall_value_memory"
11767 [(set (match_operand 0)
11768 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11769 (match_operand 2)))
11770 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11771 "!TARGET_X32"
11772 "* return ix86_output_call_insn (insn, operands[1]);"
11773 [(set_attr "type" "callv")])
11774
11775 (define_peephole2
11776 [(set (match_operand:W 0 "register_operand")
11777 (match_operand:W 1 "memory_operand"))
11778 (set (match_operand 2)
11779 (call (mem:QI (match_dup 0))
11780 (match_operand 3)))]
11781 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11782 && peep2_reg_dead_p (2, operands[0])"
11783 [(parallel [(set (match_dup 2)
11784 (call (mem:QI (match_dup 1))
11785 (match_dup 3)))
11786 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11787
11788 (define_peephole2
11789 [(set (match_operand:W 0 "register_operand")
11790 (match_operand:W 1 "memory_operand"))
11791 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11792 (set (match_operand 2)
11793 (call (mem:QI (match_dup 0))
11794 (match_operand 3)))]
11795 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11796 && peep2_reg_dead_p (3, operands[0])"
11797 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11798 (parallel [(set (match_dup 2)
11799 (call (mem:QI (match_dup 1))
11800 (match_dup 3)))
11801 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11802
11803 (define_expand "call_value_pop"
11804 [(parallel [(set (match_operand 0)
11805 (call (match_operand:QI 1)
11806 (match_operand:SI 2)))
11807 (set (reg:SI SP_REG)
11808 (plus:SI (reg:SI SP_REG)
11809 (match_operand:SI 4)))])]
11810 "!TARGET_64BIT"
11811 {
11812 ix86_expand_call (operands[0], operands[1], operands[2],
11813 operands[3], operands[4], false);
11814 DONE;
11815 })
11816
11817 (define_insn "*call_value_pop"
11818 [(set (match_operand 0)
11819 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11820 (match_operand 2)))
11821 (set (reg:SI SP_REG)
11822 (plus:SI (reg:SI SP_REG)
11823 (match_operand:SI 3 "immediate_operand" "i")))]
11824 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11825 "* return ix86_output_call_insn (insn, operands[1]);"
11826 [(set_attr "type" "callv")])
11827
11828 (define_insn "*sibcall_value_pop"
11829 [(set (match_operand 0)
11830 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11831 (match_operand 2)))
11832 (set (reg:SI SP_REG)
11833 (plus:SI (reg:SI SP_REG)
11834 (match_operand:SI 3 "immediate_operand" "i")))]
11835 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11836 "* return ix86_output_call_insn (insn, operands[1]);"
11837 [(set_attr "type" "callv")])
11838
11839 (define_insn "*sibcall_value_pop_memory"
11840 [(set (match_operand 0)
11841 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11842 (match_operand 2)))
11843 (set (reg:SI SP_REG)
11844 (plus:SI (reg:SI SP_REG)
11845 (match_operand:SI 3 "immediate_operand" "i")))
11846 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11847 "!TARGET_64BIT"
11848 "* return ix86_output_call_insn (insn, operands[1]);"
11849 [(set_attr "type" "callv")])
11850
11851 (define_peephole2
11852 [(set (match_operand:SI 0 "register_operand")
11853 (match_operand:SI 1 "memory_operand"))
11854 (parallel [(set (match_operand 2)
11855 (call (mem:QI (match_dup 0))
11856 (match_operand 3)))
11857 (set (reg:SI SP_REG)
11858 (plus:SI (reg:SI SP_REG)
11859 (match_operand:SI 4 "immediate_operand")))])]
11860 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11861 && peep2_reg_dead_p (2, operands[0])"
11862 [(parallel [(set (match_dup 2)
11863 (call (mem:QI (match_dup 1))
11864 (match_dup 3)))
11865 (set (reg:SI SP_REG)
11866 (plus:SI (reg:SI SP_REG)
11867 (match_dup 4)))
11868 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11869
11870 (define_peephole2
11871 [(set (match_operand:SI 0 "register_operand")
11872 (match_operand:SI 1 "memory_operand"))
11873 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11874 (parallel [(set (match_operand 2)
11875 (call (mem:QI (match_dup 0))
11876 (match_operand 3)))
11877 (set (reg:SI SP_REG)
11878 (plus:SI (reg:SI SP_REG)
11879 (match_operand:SI 4 "immediate_operand")))])]
11880 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11881 && peep2_reg_dead_p (3, operands[0])"
11882 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11883 (parallel [(set (match_dup 2)
11884 (call (mem:QI (match_dup 1))
11885 (match_dup 3)))
11886 (set (reg:SI SP_REG)
11887 (plus:SI (reg:SI SP_REG)
11888 (match_dup 4)))
11889 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11890
11891 ;; Call subroutine returning any type.
11892
11893 (define_expand "untyped_call"
11894 [(parallel [(call (match_operand 0)
11895 (const_int 0))
11896 (match_operand 1)
11897 (match_operand 2)])]
11898 ""
11899 {
11900 int i;
11901
11902 /* In order to give reg-stack an easier job in validating two
11903 coprocessor registers as containing a possible return value,
11904 simply pretend the untyped call returns a complex long double
11905 value.
11906
11907 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11908 and should have the default ABI. */
11909
11910 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11911 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11912 operands[0], const0_rtx,
11913 GEN_INT ((TARGET_64BIT
11914 ? (ix86_abi == SYSV_ABI
11915 ? X86_64_SSE_REGPARM_MAX
11916 : X86_64_MS_SSE_REGPARM_MAX)
11917 : X86_32_SSE_REGPARM_MAX)
11918 - 1),
11919 NULL, false);
11920
11921 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11922 {
11923 rtx set = XVECEXP (operands[2], 0, i);
11924 emit_move_insn (SET_DEST (set), SET_SRC (set));
11925 }
11926
11927 /* The optimizer does not know that the call sets the function value
11928 registers we stored in the result block. We avoid problems by
11929 claiming that all hard registers are used and clobbered at this
11930 point. */
11931 emit_insn (gen_blockage ());
11932
11933 DONE;
11934 })
11935 \f
11936 ;; Prologue and epilogue instructions
11937
11938 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11939 ;; all of memory. This blocks insns from being moved across this point.
11940
11941 (define_insn "blockage"
11942 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11943 ""
11944 ""
11945 [(set_attr "length" "0")])
11946
11947 ;; Do not schedule instructions accessing memory across this point.
11948
11949 (define_expand "memory_blockage"
11950 [(set (match_dup 0)
11951 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11952 ""
11953 {
11954 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11955 MEM_VOLATILE_P (operands[0]) = 1;
11956 })
11957
11958 (define_insn "*memory_blockage"
11959 [(set (match_operand:BLK 0)
11960 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11961 ""
11962 ""
11963 [(set_attr "length" "0")])
11964
11965 ;; As USE insns aren't meaningful after reload, this is used instead
11966 ;; to prevent deleting instructions setting registers for PIC code
11967 (define_insn "prologue_use"
11968 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11969 ""
11970 ""
11971 [(set_attr "length" "0")])
11972
11973 ;; Insn emitted into the body of a function to return from a function.
11974 ;; This is only done if the function's epilogue is known to be simple.
11975 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11976
11977 (define_expand "return"
11978 [(simple_return)]
11979 "ix86_can_use_return_insn_p ()"
11980 {
11981 if (crtl->args.pops_args)
11982 {
11983 rtx popc = GEN_INT (crtl->args.pops_args);
11984 emit_jump_insn (gen_simple_return_pop_internal (popc));
11985 DONE;
11986 }
11987 })
11988
11989 ;; We need to disable this for TARGET_SEH, as otherwise
11990 ;; shrink-wrapped prologue gets enabled too. This might exceed
11991 ;; the maximum size of prologue in unwind information.
11992
11993 (define_expand "simple_return"
11994 [(simple_return)]
11995 "!TARGET_SEH"
11996 {
11997 if (crtl->args.pops_args)
11998 {
11999 rtx popc = GEN_INT (crtl->args.pops_args);
12000 emit_jump_insn (gen_simple_return_pop_internal (popc));
12001 DONE;
12002 }
12003 })
12004
12005 (define_insn "simple_return_internal"
12006 [(simple_return)]
12007 "reload_completed"
12008 "%!ret"
12009 [(set_attr "length_nobnd" "1")
12010 (set_attr "atom_unit" "jeu")
12011 (set_attr "length_immediate" "0")
12012 (set_attr "modrm" "0")])
12013
12014 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12015 ;; instruction Athlon and K8 have.
12016
12017 (define_insn "simple_return_internal_long"
12018 [(simple_return)
12019 (unspec [(const_int 0)] UNSPEC_REP)]
12020 "reload_completed"
12021 {
12022 if (ix86_bnd_prefixed_insn_p (insn))
12023 return "%!ret";
12024
12025 return "rep%; ret";
12026 }
12027 [(set_attr "length" "2")
12028 (set_attr "atom_unit" "jeu")
12029 (set_attr "length_immediate" "0")
12030 (set_attr "prefix_rep" "1")
12031 (set_attr "modrm" "0")])
12032
12033 (define_insn "simple_return_pop_internal"
12034 [(simple_return)
12035 (use (match_operand:SI 0 "const_int_operand"))]
12036 "reload_completed"
12037 "%!ret\t%0"
12038 [(set_attr "length_nobnd" "3")
12039 (set_attr "atom_unit" "jeu")
12040 (set_attr "length_immediate" "2")
12041 (set_attr "modrm" "0")])
12042
12043 (define_insn "simple_return_indirect_internal"
12044 [(simple_return)
12045 (use (match_operand:SI 0 "register_operand" "r"))]
12046 "reload_completed"
12047 "%!jmp\t%A0"
12048 [(set_attr "type" "ibr")
12049 (set_attr "length_immediate" "0")])
12050
12051 (define_insn "nop"
12052 [(const_int 0)]
12053 ""
12054 "nop"
12055 [(set_attr "length" "1")
12056 (set_attr "length_immediate" "0")
12057 (set_attr "modrm" "0")])
12058
12059 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12060 (define_insn "nops"
12061 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12062 UNSPECV_NOPS)]
12063 "reload_completed"
12064 {
12065 int num = INTVAL (operands[0]);
12066
12067 gcc_assert (IN_RANGE (num, 1, 8));
12068
12069 while (num--)
12070 fputs ("\tnop\n", asm_out_file);
12071
12072 return "";
12073 }
12074 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12075 (set_attr "length_immediate" "0")
12076 (set_attr "modrm" "0")])
12077
12078 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12079 ;; branch prediction penalty for the third jump in a 16-byte
12080 ;; block on K8.
12081
12082 (define_insn "pad"
12083 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12084 ""
12085 {
12086 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12087 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12088 #else
12089 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12090 The align insn is used to avoid 3 jump instructions in the row to improve
12091 branch prediction and the benefits hardly outweigh the cost of extra 8
12092 nops on the average inserted by full alignment pseudo operation. */
12093 #endif
12094 return "";
12095 }
12096 [(set_attr "length" "16")])
12097
12098 (define_expand "prologue"
12099 [(const_int 0)]
12100 ""
12101 "ix86_expand_prologue (); DONE;")
12102
12103 (define_insn "set_got"
12104 [(set (match_operand:SI 0 "register_operand" "=r")
12105 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "!TARGET_64BIT"
12108 "* return output_set_got (operands[0], NULL_RTX);"
12109 [(set_attr "type" "multi")
12110 (set_attr "length" "12")])
12111
12112 (define_insn "set_got_labelled"
12113 [(set (match_operand:SI 0 "register_operand" "=r")
12114 (unspec:SI [(label_ref (match_operand 1))]
12115 UNSPEC_SET_GOT))
12116 (clobber (reg:CC FLAGS_REG))]
12117 "!TARGET_64BIT"
12118 "* return output_set_got (operands[0], operands[1]);"
12119 [(set_attr "type" "multi")
12120 (set_attr "length" "12")])
12121
12122 (define_insn "set_got_rex64"
12123 [(set (match_operand:DI 0 "register_operand" "=r")
12124 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12125 "TARGET_64BIT"
12126 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12127 [(set_attr "type" "lea")
12128 (set_attr "length_address" "4")
12129 (set_attr "mode" "DI")])
12130
12131 (define_insn "set_rip_rex64"
12132 [(set (match_operand:DI 0 "register_operand" "=r")
12133 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12134 "TARGET_64BIT"
12135 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12136 [(set_attr "type" "lea")
12137 (set_attr "length_address" "4")
12138 (set_attr "mode" "DI")])
12139
12140 (define_insn "set_got_offset_rex64"
12141 [(set (match_operand:DI 0 "register_operand" "=r")
12142 (unspec:DI
12143 [(label_ref (match_operand 1))]
12144 UNSPEC_SET_GOT_OFFSET))]
12145 "TARGET_LP64"
12146 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12147 [(set_attr "type" "imov")
12148 (set_attr "length_immediate" "0")
12149 (set_attr "length_address" "8")
12150 (set_attr "mode" "DI")])
12151
12152 (define_expand "epilogue"
12153 [(const_int 0)]
12154 ""
12155 "ix86_expand_epilogue (1); DONE;")
12156
12157 (define_expand "sibcall_epilogue"
12158 [(const_int 0)]
12159 ""
12160 "ix86_expand_epilogue (0); DONE;")
12161
12162 (define_expand "eh_return"
12163 [(use (match_operand 0 "register_operand"))]
12164 ""
12165 {
12166 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12167
12168 /* Tricky bit: we write the address of the handler to which we will
12169 be returning into someone else's stack frame, one word below the
12170 stack address we wish to restore. */
12171 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12172 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12173 tmp = gen_rtx_MEM (Pmode, tmp);
12174 emit_move_insn (tmp, ra);
12175
12176 emit_jump_insn (gen_eh_return_internal ());
12177 emit_barrier ();
12178 DONE;
12179 })
12180
12181 (define_insn_and_split "eh_return_internal"
12182 [(eh_return)]
12183 ""
12184 "#"
12185 "epilogue_completed"
12186 [(const_int 0)]
12187 "ix86_expand_epilogue (2); DONE;")
12188
12189 (define_insn "leave"
12190 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12191 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12192 (clobber (mem:BLK (scratch)))]
12193 "!TARGET_64BIT"
12194 "leave"
12195 [(set_attr "type" "leave")])
12196
12197 (define_insn "leave_rex64"
12198 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12199 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12200 (clobber (mem:BLK (scratch)))]
12201 "TARGET_64BIT"
12202 "leave"
12203 [(set_attr "type" "leave")])
12204 \f
12205 ;; Handle -fsplit-stack.
12206
12207 (define_expand "split_stack_prologue"
12208 [(const_int 0)]
12209 ""
12210 {
12211 ix86_expand_split_stack_prologue ();
12212 DONE;
12213 })
12214
12215 ;; In order to support the call/return predictor, we use a return
12216 ;; instruction which the middle-end doesn't see.
12217 (define_insn "split_stack_return"
12218 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12219 UNSPECV_SPLIT_STACK_RETURN)]
12220 ""
12221 {
12222 if (operands[0] == const0_rtx)
12223 return "ret";
12224 else
12225 return "ret\t%0";
12226 }
12227 [(set_attr "atom_unit" "jeu")
12228 (set_attr "modrm" "0")
12229 (set (attr "length")
12230 (if_then_else (match_operand:SI 0 "const0_operand")
12231 (const_int 1)
12232 (const_int 3)))
12233 (set (attr "length_immediate")
12234 (if_then_else (match_operand:SI 0 "const0_operand")
12235 (const_int 0)
12236 (const_int 2)))])
12237
12238 ;; If there are operand 0 bytes available on the stack, jump to
12239 ;; operand 1.
12240
12241 (define_expand "split_stack_space_check"
12242 [(set (pc) (if_then_else
12243 (ltu (minus (reg SP_REG)
12244 (match_operand 0 "register_operand"))
12245 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12246 (label_ref (match_operand 1))
12247 (pc)))]
12248 ""
12249 {
12250 rtx reg, size, limit;
12251
12252 reg = gen_reg_rtx (Pmode);
12253 size = force_reg (Pmode, operands[0]);
12254 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12255 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12256 UNSPEC_STACK_CHECK);
12257 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12258 ix86_expand_branch (GEU, reg, limit, operands[1]);
12259
12260 DONE;
12261 })
12262 \f
12263 ;; Bit manipulation instructions.
12264
12265 (define_expand "ffs<mode>2"
12266 [(set (match_dup 2) (const_int -1))
12267 (parallel [(set (match_dup 3) (match_dup 4))
12268 (set (match_operand:SWI48 0 "register_operand")
12269 (ctz:SWI48
12270 (match_operand:SWI48 1 "nonimmediate_operand")))])
12271 (set (match_dup 0) (if_then_else:SWI48
12272 (eq (match_dup 3) (const_int 0))
12273 (match_dup 2)
12274 (match_dup 0)))
12275 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12276 (clobber (reg:CC FLAGS_REG))])]
12277 ""
12278 {
12279 machine_mode flags_mode;
12280
12281 if (<MODE>mode == SImode && !TARGET_CMOVE)
12282 {
12283 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12284 DONE;
12285 }
12286
12287 flags_mode
12288 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12289
12290 operands[2] = gen_reg_rtx (<MODE>mode);
12291 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12292 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12293 })
12294
12295 (define_insn_and_split "ffssi2_no_cmove"
12296 [(set (match_operand:SI 0 "register_operand" "=r")
12297 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12298 (clobber (match_scratch:SI 2 "=&q"))
12299 (clobber (reg:CC FLAGS_REG))]
12300 "!TARGET_CMOVE"
12301 "#"
12302 "&& reload_completed"
12303 [(parallel [(set (match_dup 4) (match_dup 5))
12304 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12305 (set (strict_low_part (match_dup 3))
12306 (eq:QI (match_dup 4) (const_int 0)))
12307 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12308 (clobber (reg:CC FLAGS_REG))])
12309 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12310 (clobber (reg:CC FLAGS_REG))])
12311 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12312 (clobber (reg:CC FLAGS_REG))])]
12313 {
12314 machine_mode flags_mode
12315 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12316
12317 operands[3] = gen_lowpart (QImode, operands[2]);
12318 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12319 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12320
12321 ix86_expand_clear (operands[2]);
12322 })
12323
12324 (define_insn "*tzcnt<mode>_1"
12325 [(set (reg:CCC FLAGS_REG)
12326 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12327 (const_int 0)))
12328 (set (match_operand:SWI48 0 "register_operand" "=r")
12329 (ctz:SWI48 (match_dup 1)))]
12330 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12331 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12332 [(set_attr "type" "alu1")
12333 (set_attr "prefix_0f" "1")
12334 (set_attr "prefix_rep" "1")
12335 (set_attr "btver2_decode" "double")
12336 (set_attr "mode" "<MODE>")])
12337
12338 (define_insn "*bsf<mode>_1"
12339 [(set (reg:CCZ FLAGS_REG)
12340 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12341 (const_int 0)))
12342 (set (match_operand:SWI48 0 "register_operand" "=r")
12343 (ctz:SWI48 (match_dup 1)))]
12344 ""
12345 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12346 [(set_attr "type" "alu1")
12347 (set_attr "prefix_0f" "1")
12348 (set_attr "btver2_decode" "double")
12349 (set_attr "mode" "<MODE>")])
12350
12351 (define_expand "ctz<mode>2"
12352 [(parallel
12353 [(set (match_operand:SWI248 0 "register_operand")
12354 (ctz:SWI248
12355 (match_operand:SWI248 1 "nonimmediate_operand")))
12356 (clobber (reg:CC FLAGS_REG))])])
12357
12358 ; False dependency happens when destination is only updated by tzcnt,
12359 ; lzcnt or popcnt. There is no false dependency when destination is
12360 ; also used in source.
12361 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12362 [(set (match_operand:SWI48 0 "register_operand" "=r")
12363 (ctz:SWI48
12364 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "(TARGET_BMI || TARGET_GENERIC)
12367 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12368 "#"
12369 "&& reload_completed"
12370 [(parallel
12371 [(set (match_dup 0)
12372 (ctz:SWI48 (match_dup 1)))
12373 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12374 (clobber (reg:CC FLAGS_REG))])]
12375 {
12376 if (!reg_mentioned_p (operands[0], operands[1]))
12377 ix86_expand_clear (operands[0]);
12378 })
12379
12380 (define_insn "*ctz<mode>2_falsedep"
12381 [(set (match_operand:SWI48 0 "register_operand" "=r")
12382 (ctz:SWI48
12383 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12384 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12385 UNSPEC_INSN_FALSE_DEP)
12386 (clobber (reg:CC FLAGS_REG))]
12387 ""
12388 {
12389 if (TARGET_BMI)
12390 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12391 else if (TARGET_GENERIC)
12392 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12393 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12394 else
12395 gcc_unreachable ();
12396 }
12397 [(set_attr "type" "alu1")
12398 (set_attr "prefix_0f" "1")
12399 (set_attr "prefix_rep" "1")
12400 (set_attr "mode" "<MODE>")])
12401
12402 (define_insn "*ctz<mode>2"
12403 [(set (match_operand:SWI248 0 "register_operand" "=r")
12404 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12405 (clobber (reg:CC FLAGS_REG))]
12406 ""
12407 {
12408 if (TARGET_BMI)
12409 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12410 else if (optimize_function_for_size_p (cfun))
12411 ;
12412 else if (TARGET_GENERIC)
12413 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12414 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12415
12416 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12417 }
12418 [(set_attr "type" "alu1")
12419 (set_attr "prefix_0f" "1")
12420 (set (attr "prefix_rep")
12421 (if_then_else
12422 (ior (match_test "TARGET_BMI")
12423 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12424 (match_test "TARGET_GENERIC")))
12425 (const_string "1")
12426 (const_string "0")))
12427 (set_attr "mode" "<MODE>")])
12428
12429 (define_expand "clz<mode>2"
12430 [(parallel
12431 [(set (match_operand:SWI248 0 "register_operand")
12432 (minus:SWI248
12433 (match_dup 2)
12434 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12435 (clobber (reg:CC FLAGS_REG))])
12436 (parallel
12437 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12438 (clobber (reg:CC FLAGS_REG))])]
12439 ""
12440 {
12441 if (TARGET_LZCNT)
12442 {
12443 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12444 DONE;
12445 }
12446 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12447 })
12448
12449 (define_expand "clz<mode>2_lzcnt"
12450 [(parallel
12451 [(set (match_operand:SWI248 0 "register_operand")
12452 (clz:SWI248
12453 (match_operand:SWI248 1 "nonimmediate_operand")))
12454 (clobber (reg:CC FLAGS_REG))])]
12455 "TARGET_LZCNT")
12456
12457 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12458 [(set (match_operand:SWI48 0 "register_operand" "=r")
12459 (clz:SWI48
12460 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12461 (clobber (reg:CC FLAGS_REG))]
12462 "TARGET_LZCNT
12463 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12464 "#"
12465 "&& reload_completed"
12466 [(parallel
12467 [(set (match_dup 0)
12468 (clz:SWI48 (match_dup 1)))
12469 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12470 (clobber (reg:CC FLAGS_REG))])]
12471 {
12472 if (!reg_mentioned_p (operands[0], operands[1]))
12473 ix86_expand_clear (operands[0]);
12474 })
12475
12476 (define_insn "*clz<mode>2_lzcnt_falsedep"
12477 [(set (match_operand:SWI48 0 "register_operand" "=r")
12478 (clz:SWI48
12479 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12480 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12481 UNSPEC_INSN_FALSE_DEP)
12482 (clobber (reg:CC FLAGS_REG))]
12483 "TARGET_LZCNT"
12484 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12485 [(set_attr "prefix_rep" "1")
12486 (set_attr "type" "bitmanip")
12487 (set_attr "mode" "<MODE>")])
12488
12489 (define_insn "*clz<mode>2_lzcnt"
12490 [(set (match_operand:SWI248 0 "register_operand" "=r")
12491 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12492 (clobber (reg:CC FLAGS_REG))]
12493 "TARGET_LZCNT"
12494 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12495 [(set_attr "prefix_rep" "1")
12496 (set_attr "type" "bitmanip")
12497 (set_attr "mode" "<MODE>")])
12498
12499 ;; BMI instructions.
12500 (define_insn "*bmi_andn_<mode>"
12501 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12502 (and:SWI48
12503 (not:SWI48
12504 (match_operand:SWI48 1 "register_operand" "r,r"))
12505 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12506 (clobber (reg:CC FLAGS_REG))]
12507 "TARGET_BMI"
12508 "andn\t{%2, %1, %0|%0, %1, %2}"
12509 [(set_attr "type" "bitmanip")
12510 (set_attr "btver2_decode" "direct, double")
12511 (set_attr "mode" "<MODE>")])
12512
12513 (define_insn "bmi_bextr_<mode>"
12514 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12515 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12516 (match_operand:SWI48 2 "register_operand" "r,r")]
12517 UNSPEC_BEXTR))
12518 (clobber (reg:CC FLAGS_REG))]
12519 "TARGET_BMI"
12520 "bextr\t{%2, %1, %0|%0, %1, %2}"
12521 [(set_attr "type" "bitmanip")
12522 (set_attr "btver2_decode" "direct, double")
12523 (set_attr "mode" "<MODE>")])
12524
12525 (define_insn "*bmi_blsi_<mode>"
12526 [(set (match_operand:SWI48 0 "register_operand" "=r")
12527 (and:SWI48
12528 (neg:SWI48
12529 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12530 (match_dup 1)))
12531 (clobber (reg:CC FLAGS_REG))]
12532 "TARGET_BMI"
12533 "blsi\t{%1, %0|%0, %1}"
12534 [(set_attr "type" "bitmanip")
12535 (set_attr "btver2_decode" "double")
12536 (set_attr "mode" "<MODE>")])
12537
12538 (define_insn "*bmi_blsmsk_<mode>"
12539 [(set (match_operand:SWI48 0 "register_operand" "=r")
12540 (xor:SWI48
12541 (plus:SWI48
12542 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12543 (const_int -1))
12544 (match_dup 1)))
12545 (clobber (reg:CC FLAGS_REG))]
12546 "TARGET_BMI"
12547 "blsmsk\t{%1, %0|%0, %1}"
12548 [(set_attr "type" "bitmanip")
12549 (set_attr "btver2_decode" "double")
12550 (set_attr "mode" "<MODE>")])
12551
12552 (define_insn "*bmi_blsr_<mode>"
12553 [(set (match_operand:SWI48 0 "register_operand" "=r")
12554 (and:SWI48
12555 (plus:SWI48
12556 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12557 (const_int -1))
12558 (match_dup 1)))
12559 (clobber (reg:CC FLAGS_REG))]
12560 "TARGET_BMI"
12561 "blsr\t{%1, %0|%0, %1}"
12562 [(set_attr "type" "bitmanip")
12563 (set_attr "btver2_decode" "double")
12564 (set_attr "mode" "<MODE>")])
12565
12566 ;; BMI2 instructions.
12567 (define_insn "bmi2_bzhi_<mode>3"
12568 [(set (match_operand:SWI48 0 "register_operand" "=r")
12569 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12570 (match_operand:SWI48 2 "register_operand" "r"))
12571 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12572 (clobber (reg:CC FLAGS_REG))]
12573 "TARGET_BMI2"
12574 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12575 [(set_attr "type" "bitmanip")
12576 (set_attr "prefix" "vex")
12577 (set_attr "mode" "<MODE>")])
12578
12579 (define_insn "bmi2_pdep_<mode>3"
12580 [(set (match_operand:SWI48 0 "register_operand" "=r")
12581 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12582 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12583 UNSPEC_PDEP))]
12584 "TARGET_BMI2"
12585 "pdep\t{%2, %1, %0|%0, %1, %2}"
12586 [(set_attr "type" "bitmanip")
12587 (set_attr "prefix" "vex")
12588 (set_attr "mode" "<MODE>")])
12589
12590 (define_insn "bmi2_pext_<mode>3"
12591 [(set (match_operand:SWI48 0 "register_operand" "=r")
12592 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12593 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12594 UNSPEC_PEXT))]
12595 "TARGET_BMI2"
12596 "pext\t{%2, %1, %0|%0, %1, %2}"
12597 [(set_attr "type" "bitmanip")
12598 (set_attr "prefix" "vex")
12599 (set_attr "mode" "<MODE>")])
12600
12601 ;; TBM instructions.
12602 (define_insn "tbm_bextri_<mode>"
12603 [(set (match_operand:SWI48 0 "register_operand" "=r")
12604 (zero_extract:SWI48
12605 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12606 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12607 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12608 (clobber (reg:CC FLAGS_REG))]
12609 "TARGET_TBM"
12610 {
12611 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12612 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12613 }
12614 [(set_attr "type" "bitmanip")
12615 (set_attr "mode" "<MODE>")])
12616
12617 (define_insn "*tbm_blcfill_<mode>"
12618 [(set (match_operand:SWI48 0 "register_operand" "=r")
12619 (and:SWI48
12620 (plus:SWI48
12621 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12622 (const_int 1))
12623 (match_dup 1)))
12624 (clobber (reg:CC FLAGS_REG))]
12625 "TARGET_TBM"
12626 "blcfill\t{%1, %0|%0, %1}"
12627 [(set_attr "type" "bitmanip")
12628 (set_attr "mode" "<MODE>")])
12629
12630 (define_insn "*tbm_blci_<mode>"
12631 [(set (match_operand:SWI48 0 "register_operand" "=r")
12632 (ior:SWI48
12633 (not:SWI48
12634 (plus:SWI48
12635 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12636 (const_int 1)))
12637 (match_dup 1)))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "TARGET_TBM"
12640 "blci\t{%1, %0|%0, %1}"
12641 [(set_attr "type" "bitmanip")
12642 (set_attr "mode" "<MODE>")])
12643
12644 (define_insn "*tbm_blcic_<mode>"
12645 [(set (match_operand:SWI48 0 "register_operand" "=r")
12646 (and:SWI48
12647 (plus:SWI48
12648 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12649 (const_int 1))
12650 (not:SWI48
12651 (match_dup 1))))
12652 (clobber (reg:CC FLAGS_REG))]
12653 "TARGET_TBM"
12654 "blcic\t{%1, %0|%0, %1}"
12655 [(set_attr "type" "bitmanip")
12656 (set_attr "mode" "<MODE>")])
12657
12658 (define_insn "*tbm_blcmsk_<mode>"
12659 [(set (match_operand:SWI48 0 "register_operand" "=r")
12660 (xor:SWI48
12661 (plus:SWI48
12662 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12663 (const_int 1))
12664 (match_dup 1)))
12665 (clobber (reg:CC FLAGS_REG))]
12666 "TARGET_TBM"
12667 "blcmsk\t{%1, %0|%0, %1}"
12668 [(set_attr "type" "bitmanip")
12669 (set_attr "mode" "<MODE>")])
12670
12671 (define_insn "*tbm_blcs_<mode>"
12672 [(set (match_operand:SWI48 0 "register_operand" "=r")
12673 (ior:SWI48
12674 (plus:SWI48
12675 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12676 (const_int 1))
12677 (match_dup 1)))
12678 (clobber (reg:CC FLAGS_REG))]
12679 "TARGET_TBM"
12680 "blcs\t{%1, %0|%0, %1}"
12681 [(set_attr "type" "bitmanip")
12682 (set_attr "mode" "<MODE>")])
12683
12684 (define_insn "*tbm_blsfill_<mode>"
12685 [(set (match_operand:SWI48 0 "register_operand" "=r")
12686 (ior:SWI48
12687 (plus:SWI48
12688 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12689 (const_int -1))
12690 (match_dup 1)))
12691 (clobber (reg:CC FLAGS_REG))]
12692 "TARGET_TBM"
12693 "blsfill\t{%1, %0|%0, %1}"
12694 [(set_attr "type" "bitmanip")
12695 (set_attr "mode" "<MODE>")])
12696
12697 (define_insn "*tbm_blsic_<mode>"
12698 [(set (match_operand:SWI48 0 "register_operand" "=r")
12699 (ior:SWI48
12700 (plus:SWI48
12701 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12702 (const_int -1))
12703 (not:SWI48
12704 (match_dup 1))))
12705 (clobber (reg:CC FLAGS_REG))]
12706 "TARGET_TBM"
12707 "blsic\t{%1, %0|%0, %1}"
12708 [(set_attr "type" "bitmanip")
12709 (set_attr "mode" "<MODE>")])
12710
12711 (define_insn "*tbm_t1mskc_<mode>"
12712 [(set (match_operand:SWI48 0 "register_operand" "=r")
12713 (ior:SWI48
12714 (plus:SWI48
12715 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12716 (const_int 1))
12717 (not:SWI48
12718 (match_dup 1))))
12719 (clobber (reg:CC FLAGS_REG))]
12720 "TARGET_TBM"
12721 "t1mskc\t{%1, %0|%0, %1}"
12722 [(set_attr "type" "bitmanip")
12723 (set_attr "mode" "<MODE>")])
12724
12725 (define_insn "*tbm_tzmsk_<mode>"
12726 [(set (match_operand:SWI48 0 "register_operand" "=r")
12727 (and:SWI48
12728 (plus:SWI48
12729 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12730 (const_int -1))
12731 (not:SWI48
12732 (match_dup 1))))
12733 (clobber (reg:CC FLAGS_REG))]
12734 "TARGET_TBM"
12735 "tzmsk\t{%1, %0|%0, %1}"
12736 [(set_attr "type" "bitmanip")
12737 (set_attr "mode" "<MODE>")])
12738
12739 (define_insn "bsr_rex64"
12740 [(set (match_operand:DI 0 "register_operand" "=r")
12741 (minus:DI (const_int 63)
12742 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12743 (clobber (reg:CC FLAGS_REG))]
12744 "TARGET_64BIT"
12745 "bsr{q}\t{%1, %0|%0, %1}"
12746 [(set_attr "type" "alu1")
12747 (set_attr "prefix_0f" "1")
12748 (set_attr "mode" "DI")])
12749
12750 (define_insn "bsr"
12751 [(set (match_operand:SI 0 "register_operand" "=r")
12752 (minus:SI (const_int 31)
12753 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12754 (clobber (reg:CC FLAGS_REG))]
12755 ""
12756 "bsr{l}\t{%1, %0|%0, %1}"
12757 [(set_attr "type" "alu1")
12758 (set_attr "prefix_0f" "1")
12759 (set_attr "mode" "SI")])
12760
12761 (define_insn "*bsrhi"
12762 [(set (match_operand:HI 0 "register_operand" "=r")
12763 (minus:HI (const_int 15)
12764 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12765 (clobber (reg:CC FLAGS_REG))]
12766 ""
12767 "bsr{w}\t{%1, %0|%0, %1}"
12768 [(set_attr "type" "alu1")
12769 (set_attr "prefix_0f" "1")
12770 (set_attr "mode" "HI")])
12771
12772 (define_expand "popcount<mode>2"
12773 [(parallel
12774 [(set (match_operand:SWI248 0 "register_operand")
12775 (popcount:SWI248
12776 (match_operand:SWI248 1 "nonimmediate_operand")))
12777 (clobber (reg:CC FLAGS_REG))])]
12778 "TARGET_POPCNT")
12779
12780 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12781 [(set (match_operand:SWI48 0 "register_operand" "=r")
12782 (popcount:SWI48
12783 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12784 (clobber (reg:CC FLAGS_REG))]
12785 "TARGET_POPCNT
12786 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12787 "#"
12788 "&& reload_completed"
12789 [(parallel
12790 [(set (match_dup 0)
12791 (popcount:SWI48 (match_dup 1)))
12792 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12793 (clobber (reg:CC FLAGS_REG))])]
12794 {
12795 if (!reg_mentioned_p (operands[0], operands[1]))
12796 ix86_expand_clear (operands[0]);
12797 })
12798
12799 (define_insn "*popcount<mode>2_falsedep"
12800 [(set (match_operand:SWI48 0 "register_operand" "=r")
12801 (popcount:SWI48
12802 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12803 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12804 UNSPEC_INSN_FALSE_DEP)
12805 (clobber (reg:CC FLAGS_REG))]
12806 "TARGET_POPCNT"
12807 {
12808 #if TARGET_MACHO
12809 return "popcnt\t{%1, %0|%0, %1}";
12810 #else
12811 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12812 #endif
12813 }
12814 [(set_attr "prefix_rep" "1")
12815 (set_attr "type" "bitmanip")
12816 (set_attr "mode" "<MODE>")])
12817
12818 (define_insn "*popcount<mode>2"
12819 [(set (match_operand:SWI248 0 "register_operand" "=r")
12820 (popcount:SWI248
12821 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12822 (clobber (reg:CC FLAGS_REG))]
12823 "TARGET_POPCNT"
12824 {
12825 #if TARGET_MACHO
12826 return "popcnt\t{%1, %0|%0, %1}";
12827 #else
12828 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12829 #endif
12830 }
12831 [(set_attr "prefix_rep" "1")
12832 (set_attr "type" "bitmanip")
12833 (set_attr "mode" "<MODE>")])
12834
12835 (define_expand "bswapdi2"
12836 [(set (match_operand:DI 0 "register_operand")
12837 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12838 "TARGET_64BIT"
12839 {
12840 if (!TARGET_MOVBE)
12841 operands[1] = force_reg (DImode, operands[1]);
12842 })
12843
12844 (define_expand "bswapsi2"
12845 [(set (match_operand:SI 0 "register_operand")
12846 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12847 ""
12848 {
12849 if (TARGET_MOVBE)
12850 ;
12851 else if (TARGET_BSWAP)
12852 operands[1] = force_reg (SImode, operands[1]);
12853 else
12854 {
12855 rtx x = operands[0];
12856
12857 emit_move_insn (x, operands[1]);
12858 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12859 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12860 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12861 DONE;
12862 }
12863 })
12864
12865 (define_insn "*bswap<mode>2_movbe"
12866 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12867 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12868 "TARGET_MOVBE
12869 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12870 "@
12871 bswap\t%0
12872 movbe\t{%1, %0|%0, %1}
12873 movbe\t{%1, %0|%0, %1}"
12874 [(set_attr "type" "bitmanip,imov,imov")
12875 (set_attr "modrm" "0,1,1")
12876 (set_attr "prefix_0f" "*,1,1")
12877 (set_attr "prefix_extra" "*,1,1")
12878 (set_attr "mode" "<MODE>")])
12879
12880 (define_insn "*bswap<mode>2"
12881 [(set (match_operand:SWI48 0 "register_operand" "=r")
12882 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12883 "TARGET_BSWAP"
12884 "bswap\t%0"
12885 [(set_attr "type" "bitmanip")
12886 (set_attr "modrm" "0")
12887 (set_attr "mode" "<MODE>")])
12888
12889 (define_insn "*bswaphi_lowpart_1"
12890 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12891 (bswap:HI (match_dup 0)))
12892 (clobber (reg:CC FLAGS_REG))]
12893 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12894 "@
12895 xchg{b}\t{%h0, %b0|%b0, %h0}
12896 rol{w}\t{$8, %0|%0, 8}"
12897 [(set_attr "length" "2,4")
12898 (set_attr "mode" "QI,HI")])
12899
12900 (define_insn "bswaphi_lowpart"
12901 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12902 (bswap:HI (match_dup 0)))
12903 (clobber (reg:CC FLAGS_REG))]
12904 ""
12905 "rol{w}\t{$8, %0|%0, 8}"
12906 [(set_attr "length" "4")
12907 (set_attr "mode" "HI")])
12908
12909 (define_expand "paritydi2"
12910 [(set (match_operand:DI 0 "register_operand")
12911 (parity:DI (match_operand:DI 1 "register_operand")))]
12912 "! TARGET_POPCNT"
12913 {
12914 rtx scratch = gen_reg_rtx (QImode);
12915 rtx cond;
12916
12917 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12918 NULL_RTX, operands[1]));
12919
12920 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12921 gen_rtx_REG (CCmode, FLAGS_REG),
12922 const0_rtx);
12923 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12924
12925 if (TARGET_64BIT)
12926 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12927 else
12928 {
12929 rtx tmp = gen_reg_rtx (SImode);
12930
12931 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12932 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12933 }
12934 DONE;
12935 })
12936
12937 (define_expand "paritysi2"
12938 [(set (match_operand:SI 0 "register_operand")
12939 (parity:SI (match_operand:SI 1 "register_operand")))]
12940 "! TARGET_POPCNT"
12941 {
12942 rtx scratch = gen_reg_rtx (QImode);
12943 rtx cond;
12944
12945 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12946
12947 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12948 gen_rtx_REG (CCmode, FLAGS_REG),
12949 const0_rtx);
12950 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12951
12952 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12953 DONE;
12954 })
12955
12956 (define_insn_and_split "paritydi2_cmp"
12957 [(set (reg:CC FLAGS_REG)
12958 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12959 UNSPEC_PARITY))
12960 (clobber (match_scratch:DI 0 "=r"))
12961 (clobber (match_scratch:SI 1 "=&r"))
12962 (clobber (match_scratch:HI 2 "=Q"))]
12963 "! TARGET_POPCNT"
12964 "#"
12965 "&& reload_completed"
12966 [(parallel
12967 [(set (match_dup 1)
12968 (xor:SI (match_dup 1) (match_dup 4)))
12969 (clobber (reg:CC FLAGS_REG))])
12970 (parallel
12971 [(set (reg:CC FLAGS_REG)
12972 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12973 (clobber (match_dup 1))
12974 (clobber (match_dup 2))])]
12975 {
12976 operands[4] = gen_lowpart (SImode, operands[3]);
12977
12978 if (TARGET_64BIT)
12979 {
12980 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12981 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12982 }
12983 else
12984 operands[1] = gen_highpart (SImode, operands[3]);
12985 })
12986
12987 (define_insn_and_split "paritysi2_cmp"
12988 [(set (reg:CC FLAGS_REG)
12989 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12990 UNSPEC_PARITY))
12991 (clobber (match_scratch:SI 0 "=r"))
12992 (clobber (match_scratch:HI 1 "=&Q"))]
12993 "! TARGET_POPCNT"
12994 "#"
12995 "&& reload_completed"
12996 [(parallel
12997 [(set (match_dup 1)
12998 (xor:HI (match_dup 1) (match_dup 3)))
12999 (clobber (reg:CC FLAGS_REG))])
13000 (parallel
13001 [(set (reg:CC FLAGS_REG)
13002 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13003 (clobber (match_dup 1))])]
13004 {
13005 operands[3] = gen_lowpart (HImode, operands[2]);
13006
13007 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13008 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13009 })
13010
13011 (define_insn "*parityhi2_cmp"
13012 [(set (reg:CC FLAGS_REG)
13013 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13014 UNSPEC_PARITY))
13015 (clobber (match_scratch:HI 0 "=Q"))]
13016 "! TARGET_POPCNT"
13017 "xor{b}\t{%h0, %b0|%b0, %h0}"
13018 [(set_attr "length" "2")
13019 (set_attr "mode" "HI")])
13020
13021 \f
13022 ;; Thread-local storage patterns for ELF.
13023 ;;
13024 ;; Note that these code sequences must appear exactly as shown
13025 ;; in order to allow linker relaxation.
13026
13027 (define_insn "*tls_global_dynamic_32_gnu"
13028 [(set (match_operand:SI 0 "register_operand" "=a")
13029 (unspec:SI
13030 [(match_operand:SI 1 "register_operand" "b")
13031 (match_operand 2 "tls_symbolic_operand")
13032 (match_operand 3 "constant_call_address_operand" "Bz")
13033 (reg:SI SP_REG)]
13034 UNSPEC_TLS_GD))
13035 (clobber (match_scratch:SI 4 "=d"))
13036 (clobber (match_scratch:SI 5 "=c"))
13037 (clobber (reg:CC FLAGS_REG))]
13038 "!TARGET_64BIT && TARGET_GNU_TLS"
13039 {
13040 output_asm_insn
13041 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13042 if (TARGET_SUN_TLS)
13043 #ifdef HAVE_AS_IX86_TLSGDPLT
13044 return "call\t%a2@tlsgdplt";
13045 #else
13046 return "call\t%p3@plt";
13047 #endif
13048 return "call\t%P3";
13049 }
13050 [(set_attr "type" "multi")
13051 (set_attr "length" "12")])
13052
13053 (define_expand "tls_global_dynamic_32"
13054 [(parallel
13055 [(set (match_operand:SI 0 "register_operand")
13056 (unspec:SI [(match_operand:SI 2 "register_operand")
13057 (match_operand 1 "tls_symbolic_operand")
13058 (match_operand 3 "constant_call_address_operand")
13059 (reg:SI SP_REG)]
13060 UNSPEC_TLS_GD))
13061 (clobber (match_scratch:SI 4))
13062 (clobber (match_scratch:SI 5))
13063 (clobber (reg:CC FLAGS_REG))])]
13064 ""
13065 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13066
13067 (define_insn "*tls_global_dynamic_64_<mode>"
13068 [(set (match_operand:P 0 "register_operand" "=a")
13069 (call:P
13070 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13071 (match_operand 3)))
13072 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13073 UNSPEC_TLS_GD)]
13074 "TARGET_64BIT"
13075 {
13076 if (!TARGET_X32)
13077 fputs (ASM_BYTE "0x66\n", asm_out_file);
13078 output_asm_insn
13079 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13080 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13081 fputs ("\trex64\n", asm_out_file);
13082 if (TARGET_SUN_TLS)
13083 return "call\t%p2@plt";
13084 return "call\t%P2";
13085 }
13086 [(set_attr "type" "multi")
13087 (set (attr "length")
13088 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13089
13090 (define_insn "*tls_global_dynamic_64_largepic"
13091 [(set (match_operand:DI 0 "register_operand" "=a")
13092 (call:DI
13093 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13094 (match_operand:DI 3 "immediate_operand" "i")))
13095 (match_operand 4)))
13096 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13097 UNSPEC_TLS_GD)]
13098 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13099 && GET_CODE (operands[3]) == CONST
13100 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13101 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13102 {
13103 output_asm_insn
13104 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13105 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13106 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13107 return "call\t{*%%rax|rax}";
13108 }
13109 [(set_attr "type" "multi")
13110 (set_attr "length" "22")])
13111
13112 (define_expand "tls_global_dynamic_64_<mode>"
13113 [(parallel
13114 [(set (match_operand:P 0 "register_operand")
13115 (call:P
13116 (mem:QI (match_operand 2))
13117 (const_int 0)))
13118 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13119 UNSPEC_TLS_GD)])]
13120 "TARGET_64BIT"
13121 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13122
13123 (define_insn "*tls_local_dynamic_base_32_gnu"
13124 [(set (match_operand:SI 0 "register_operand" "=a")
13125 (unspec:SI
13126 [(match_operand:SI 1 "register_operand" "b")
13127 (match_operand 2 "constant_call_address_operand" "Bz")
13128 (reg:SI SP_REG)]
13129 UNSPEC_TLS_LD_BASE))
13130 (clobber (match_scratch:SI 3 "=d"))
13131 (clobber (match_scratch:SI 4 "=c"))
13132 (clobber (reg:CC FLAGS_REG))]
13133 "!TARGET_64BIT && TARGET_GNU_TLS"
13134 {
13135 output_asm_insn
13136 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13137 if (TARGET_SUN_TLS)
13138 {
13139 if (HAVE_AS_IX86_TLSLDMPLT)
13140 return "call\t%&@tlsldmplt";
13141 else
13142 return "call\t%p2@plt";
13143 }
13144 return "call\t%P2";
13145 }
13146 [(set_attr "type" "multi")
13147 (set_attr "length" "11")])
13148
13149 (define_expand "tls_local_dynamic_base_32"
13150 [(parallel
13151 [(set (match_operand:SI 0 "register_operand")
13152 (unspec:SI
13153 [(match_operand:SI 1 "register_operand")
13154 (match_operand 2 "constant_call_address_operand")
13155 (reg:SI SP_REG)]
13156 UNSPEC_TLS_LD_BASE))
13157 (clobber (match_scratch:SI 3))
13158 (clobber (match_scratch:SI 4))
13159 (clobber (reg:CC FLAGS_REG))])]
13160 ""
13161 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13162
13163 (define_insn "*tls_local_dynamic_base_64_<mode>"
13164 [(set (match_operand:P 0 "register_operand" "=a")
13165 (call:P
13166 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13167 (match_operand 2)))
13168 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13169 "TARGET_64BIT"
13170 {
13171 output_asm_insn
13172 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13173 if (TARGET_SUN_TLS)
13174 return "call\t%p1@plt";
13175 return "call\t%P1";
13176 }
13177 [(set_attr "type" "multi")
13178 (set_attr "length" "12")])
13179
13180 (define_insn "*tls_local_dynamic_base_64_largepic"
13181 [(set (match_operand:DI 0 "register_operand" "=a")
13182 (call:DI
13183 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13184 (match_operand:DI 2 "immediate_operand" "i")))
13185 (match_operand 3)))
13186 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13187 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13188 && GET_CODE (operands[2]) == CONST
13189 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13190 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13191 {
13192 output_asm_insn
13193 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13194 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13195 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13196 return "call\t{*%%rax|rax}";
13197 }
13198 [(set_attr "type" "multi")
13199 (set_attr "length" "22")])
13200
13201 (define_expand "tls_local_dynamic_base_64_<mode>"
13202 [(parallel
13203 [(set (match_operand:P 0 "register_operand")
13204 (call:P
13205 (mem:QI (match_operand 1))
13206 (const_int 0)))
13207 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13208 "TARGET_64BIT"
13209 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13210
13211 ;; Local dynamic of a single variable is a lose. Show combine how
13212 ;; to convert that back to global dynamic.
13213
13214 (define_insn_and_split "*tls_local_dynamic_32_once"
13215 [(set (match_operand:SI 0 "register_operand" "=a")
13216 (plus:SI
13217 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13218 (match_operand 2 "constant_call_address_operand" "Bz")
13219 (reg:SI SP_REG)]
13220 UNSPEC_TLS_LD_BASE)
13221 (const:SI (unspec:SI
13222 [(match_operand 3 "tls_symbolic_operand")]
13223 UNSPEC_DTPOFF))))
13224 (clobber (match_scratch:SI 4 "=d"))
13225 (clobber (match_scratch:SI 5 "=c"))
13226 (clobber (reg:CC FLAGS_REG))]
13227 ""
13228 "#"
13229 ""
13230 [(parallel
13231 [(set (match_dup 0)
13232 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13233 (reg:SI SP_REG)]
13234 UNSPEC_TLS_GD))
13235 (clobber (match_dup 4))
13236 (clobber (match_dup 5))
13237 (clobber (reg:CC FLAGS_REG))])])
13238
13239 ;; Segment register for the thread base ptr load
13240 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13241
13242 ;; Load and add the thread base pointer from %<tp_seg>:0.
13243 (define_insn "*load_tp_x32"
13244 [(set (match_operand:SI 0 "register_operand" "=r")
13245 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13246 "TARGET_X32"
13247 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13248 [(set_attr "type" "imov")
13249 (set_attr "modrm" "0")
13250 (set_attr "length" "7")
13251 (set_attr "memory" "load")
13252 (set_attr "imm_disp" "false")])
13253
13254 (define_insn "*load_tp_x32_zext"
13255 [(set (match_operand:DI 0 "register_operand" "=r")
13256 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13257 "TARGET_X32"
13258 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13259 [(set_attr "type" "imov")
13260 (set_attr "modrm" "0")
13261 (set_attr "length" "7")
13262 (set_attr "memory" "load")
13263 (set_attr "imm_disp" "false")])
13264
13265 (define_insn "*load_tp_<mode>"
13266 [(set (match_operand:P 0 "register_operand" "=r")
13267 (unspec:P [(const_int 0)] UNSPEC_TP))]
13268 "!TARGET_X32"
13269 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13270 [(set_attr "type" "imov")
13271 (set_attr "modrm" "0")
13272 (set_attr "length" "7")
13273 (set_attr "memory" "load")
13274 (set_attr "imm_disp" "false")])
13275
13276 (define_insn "*add_tp_x32"
13277 [(set (match_operand:SI 0 "register_operand" "=r")
13278 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13279 (match_operand:SI 1 "register_operand" "0")))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "TARGET_X32"
13282 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13283 [(set_attr "type" "alu")
13284 (set_attr "modrm" "0")
13285 (set_attr "length" "7")
13286 (set_attr "memory" "load")
13287 (set_attr "imm_disp" "false")])
13288
13289 (define_insn "*add_tp_x32_zext"
13290 [(set (match_operand:DI 0 "register_operand" "=r")
13291 (zero_extend:DI
13292 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13293 (match_operand:SI 1 "register_operand" "0"))))
13294 (clobber (reg:CC FLAGS_REG))]
13295 "TARGET_X32"
13296 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13297 [(set_attr "type" "alu")
13298 (set_attr "modrm" "0")
13299 (set_attr "length" "7")
13300 (set_attr "memory" "load")
13301 (set_attr "imm_disp" "false")])
13302
13303 (define_insn "*add_tp_<mode>"
13304 [(set (match_operand:P 0 "register_operand" "=r")
13305 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13306 (match_operand:P 1 "register_operand" "0")))
13307 (clobber (reg:CC FLAGS_REG))]
13308 "!TARGET_X32"
13309 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13310 [(set_attr "type" "alu")
13311 (set_attr "modrm" "0")
13312 (set_attr "length" "7")
13313 (set_attr "memory" "load")
13314 (set_attr "imm_disp" "false")])
13315
13316 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13317 ;; %rax as destination of the initial executable code sequence.
13318 (define_insn "tls_initial_exec_64_sun"
13319 [(set (match_operand:DI 0 "register_operand" "=a")
13320 (unspec:DI
13321 [(match_operand 1 "tls_symbolic_operand")]
13322 UNSPEC_TLS_IE_SUN))
13323 (clobber (reg:CC FLAGS_REG))]
13324 "TARGET_64BIT && TARGET_SUN_TLS"
13325 {
13326 output_asm_insn
13327 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13328 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13329 }
13330 [(set_attr "type" "multi")])
13331
13332 ;; GNU2 TLS patterns can be split.
13333
13334 (define_expand "tls_dynamic_gnu2_32"
13335 [(set (match_dup 3)
13336 (plus:SI (match_operand:SI 2 "register_operand")
13337 (const:SI
13338 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13339 UNSPEC_TLSDESC))))
13340 (parallel
13341 [(set (match_operand:SI 0 "register_operand")
13342 (unspec:SI [(match_dup 1) (match_dup 3)
13343 (match_dup 2) (reg:SI SP_REG)]
13344 UNSPEC_TLSDESC))
13345 (clobber (reg:CC FLAGS_REG))])]
13346 "!TARGET_64BIT && TARGET_GNU2_TLS"
13347 {
13348 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13349 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13350 })
13351
13352 (define_insn "*tls_dynamic_gnu2_lea_32"
13353 [(set (match_operand:SI 0 "register_operand" "=r")
13354 (plus:SI (match_operand:SI 1 "register_operand" "b")
13355 (const:SI
13356 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13357 UNSPEC_TLSDESC))))]
13358 "!TARGET_64BIT && TARGET_GNU2_TLS"
13359 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13360 [(set_attr "type" "lea")
13361 (set_attr "mode" "SI")
13362 (set_attr "length" "6")
13363 (set_attr "length_address" "4")])
13364
13365 (define_insn "*tls_dynamic_gnu2_call_32"
13366 [(set (match_operand:SI 0 "register_operand" "=a")
13367 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13368 (match_operand:SI 2 "register_operand" "0")
13369 ;; we have to make sure %ebx still points to the GOT
13370 (match_operand:SI 3 "register_operand" "b")
13371 (reg:SI SP_REG)]
13372 UNSPEC_TLSDESC))
13373 (clobber (reg:CC FLAGS_REG))]
13374 "!TARGET_64BIT && TARGET_GNU2_TLS"
13375 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13376 [(set_attr "type" "call")
13377 (set_attr "length" "2")
13378 (set_attr "length_address" "0")])
13379
13380 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13381 [(set (match_operand:SI 0 "register_operand" "=&a")
13382 (plus:SI
13383 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13384 (match_operand:SI 4)
13385 (match_operand:SI 2 "register_operand" "b")
13386 (reg:SI SP_REG)]
13387 UNSPEC_TLSDESC)
13388 (const:SI (unspec:SI
13389 [(match_operand 1 "tls_symbolic_operand")]
13390 UNSPEC_DTPOFF))))
13391 (clobber (reg:CC FLAGS_REG))]
13392 "!TARGET_64BIT && TARGET_GNU2_TLS"
13393 "#"
13394 ""
13395 [(set (match_dup 0) (match_dup 5))]
13396 {
13397 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13398 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13399 })
13400
13401 (define_expand "tls_dynamic_gnu2_64"
13402 [(set (match_dup 2)
13403 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13404 UNSPEC_TLSDESC))
13405 (parallel
13406 [(set (match_operand:DI 0 "register_operand")
13407 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13408 UNSPEC_TLSDESC))
13409 (clobber (reg:CC FLAGS_REG))])]
13410 "TARGET_64BIT && TARGET_GNU2_TLS"
13411 {
13412 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13413 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13414 })
13415
13416 (define_insn "*tls_dynamic_gnu2_lea_64"
13417 [(set (match_operand:DI 0 "register_operand" "=r")
13418 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13419 UNSPEC_TLSDESC))]
13420 "TARGET_64BIT && TARGET_GNU2_TLS"
13421 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13422 [(set_attr "type" "lea")
13423 (set_attr "mode" "DI")
13424 (set_attr "length" "7")
13425 (set_attr "length_address" "4")])
13426
13427 (define_insn "*tls_dynamic_gnu2_call_64"
13428 [(set (match_operand:DI 0 "register_operand" "=a")
13429 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13430 (match_operand:DI 2 "register_operand" "0")
13431 (reg:DI SP_REG)]
13432 UNSPEC_TLSDESC))
13433 (clobber (reg:CC FLAGS_REG))]
13434 "TARGET_64BIT && TARGET_GNU2_TLS"
13435 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13436 [(set_attr "type" "call")
13437 (set_attr "length" "2")
13438 (set_attr "length_address" "0")])
13439
13440 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13441 [(set (match_operand:DI 0 "register_operand" "=&a")
13442 (plus:DI
13443 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13444 (match_operand:DI 3)
13445 (reg:DI SP_REG)]
13446 UNSPEC_TLSDESC)
13447 (const:DI (unspec:DI
13448 [(match_operand 1 "tls_symbolic_operand")]
13449 UNSPEC_DTPOFF))))
13450 (clobber (reg:CC FLAGS_REG))]
13451 "TARGET_64BIT && TARGET_GNU2_TLS"
13452 "#"
13453 ""
13454 [(set (match_dup 0) (match_dup 4))]
13455 {
13456 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13457 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13458 })
13459 \f
13460 ;; These patterns match the binary 387 instructions for addM3, subM3,
13461 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13462 ;; SFmode. The first is the normal insn, the second the same insn but
13463 ;; with one operand a conversion, and the third the same insn but with
13464 ;; the other operand a conversion. The conversion may be SFmode or
13465 ;; SImode if the target mode DFmode, but only SImode if the target mode
13466 ;; is SFmode.
13467
13468 ;; Gcc is slightly more smart about handling normal two address instructions
13469 ;; so use special patterns for add and mull.
13470
13471 (define_insn "*fop_<mode>_comm_mixed"
13472 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13473 (match_operator:MODEF 3 "binary_fp_operator"
13474 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13475 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13476 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13477 && COMMUTATIVE_ARITH_P (operands[3])
13478 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13479 "* return output_387_binary_op (insn, operands);"
13480 [(set (attr "type")
13481 (if_then_else (eq_attr "alternative" "1,2")
13482 (if_then_else (match_operand:MODEF 3 "mult_operator")
13483 (const_string "ssemul")
13484 (const_string "sseadd"))
13485 (if_then_else (match_operand:MODEF 3 "mult_operator")
13486 (const_string "fmul")
13487 (const_string "fop"))))
13488 (set_attr "isa" "*,noavx,avx")
13489 (set_attr "prefix" "orig,orig,vex")
13490 (set_attr "mode" "<MODE>")])
13491
13492 (define_insn "*fop_<mode>_comm_sse"
13493 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13494 (match_operator:MODEF 3 "binary_fp_operator"
13495 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13496 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13497 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13498 && COMMUTATIVE_ARITH_P (operands[3])
13499 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13500 "* return output_387_binary_op (insn, operands);"
13501 [(set (attr "type")
13502 (if_then_else (match_operand:MODEF 3 "mult_operator")
13503 (const_string "ssemul")
13504 (const_string "sseadd")))
13505 (set_attr "isa" "noavx,avx")
13506 (set_attr "prefix" "orig,vex")
13507 (set_attr "mode" "<MODE>")])
13508
13509 (define_insn "*fop_<mode>_comm_i387"
13510 [(set (match_operand:MODEF 0 "register_operand" "=f")
13511 (match_operator:MODEF 3 "binary_fp_operator"
13512 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13513 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13514 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13515 && COMMUTATIVE_ARITH_P (operands[3])
13516 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13517 "* return output_387_binary_op (insn, operands);"
13518 [(set (attr "type")
13519 (if_then_else (match_operand:MODEF 3 "mult_operator")
13520 (const_string "fmul")
13521 (const_string "fop")))
13522 (set_attr "mode" "<MODE>")])
13523
13524 (define_insn "*fop_<mode>_1_mixed"
13525 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13526 (match_operator:MODEF 3 "binary_fp_operator"
13527 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13528 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13529 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13530 && !COMMUTATIVE_ARITH_P (operands[3])
13531 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13532 "* return output_387_binary_op (insn, operands);"
13533 [(set (attr "type")
13534 (cond [(and (eq_attr "alternative" "2,3")
13535 (match_operand:MODEF 3 "mult_operator"))
13536 (const_string "ssemul")
13537 (and (eq_attr "alternative" "2,3")
13538 (match_operand:MODEF 3 "div_operator"))
13539 (const_string "ssediv")
13540 (eq_attr "alternative" "2,3")
13541 (const_string "sseadd")
13542 (match_operand:MODEF 3 "mult_operator")
13543 (const_string "fmul")
13544 (match_operand:MODEF 3 "div_operator")
13545 (const_string "fdiv")
13546 ]
13547 (const_string "fop")))
13548 (set_attr "isa" "*,*,noavx,avx")
13549 (set_attr "prefix" "orig,orig,orig,vex")
13550 (set_attr "mode" "<MODE>")])
13551
13552 (define_insn "*rcpsf2_sse"
13553 [(set (match_operand:SF 0 "register_operand" "=x")
13554 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13555 UNSPEC_RCP))]
13556 "TARGET_SSE_MATH"
13557 "%vrcpss\t{%1, %d0|%d0, %1}"
13558 [(set_attr "type" "sse")
13559 (set_attr "atom_sse_attr" "rcp")
13560 (set_attr "btver2_sse_attr" "rcp")
13561 (set_attr "prefix" "maybe_vex")
13562 (set_attr "mode" "SF")])
13563
13564 (define_insn "*fop_<mode>_1_sse"
13565 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13566 (match_operator:MODEF 3 "binary_fp_operator"
13567 [(match_operand:MODEF 1 "register_operand" "0,x")
13568 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13569 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13570 && !COMMUTATIVE_ARITH_P (operands[3])"
13571 "* return output_387_binary_op (insn, operands);"
13572 [(set (attr "type")
13573 (cond [(match_operand:MODEF 3 "mult_operator")
13574 (const_string "ssemul")
13575 (match_operand:MODEF 3 "div_operator")
13576 (const_string "ssediv")
13577 ]
13578 (const_string "sseadd")))
13579 (set_attr "isa" "noavx,avx")
13580 (set_attr "prefix" "orig,vex")
13581 (set_attr "mode" "<MODE>")])
13582
13583 ;; This pattern is not fully shadowed by the pattern above.
13584 (define_insn "*fop_<mode>_1_i387"
13585 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13586 (match_operator:MODEF 3 "binary_fp_operator"
13587 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13588 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13589 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13590 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13591 && !COMMUTATIVE_ARITH_P (operands[3])
13592 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13593 "* return output_387_binary_op (insn, operands);"
13594 [(set (attr "type")
13595 (cond [(match_operand:MODEF 3 "mult_operator")
13596 (const_string "fmul")
13597 (match_operand:MODEF 3 "div_operator")
13598 (const_string "fdiv")
13599 ]
13600 (const_string "fop")))
13601 (set_attr "mode" "<MODE>")])
13602
13603 ;; ??? Add SSE splitters for these!
13604 (define_insn "*fop_<MODEF:mode>_2_i387"
13605 [(set (match_operand:MODEF 0 "register_operand" "=f")
13606 (match_operator:MODEF 3 "binary_fp_operator"
13607 [(float:MODEF
13608 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13609 (match_operand:MODEF 2 "register_operand" "0")]))]
13610 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13611 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13612 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13613 || optimize_function_for_size_p (cfun))"
13614 { return output_387_binary_op (insn, operands); }
13615 [(set (attr "type")
13616 (cond [(match_operand:MODEF 3 "mult_operator")
13617 (const_string "fmul")
13618 (match_operand:MODEF 3 "div_operator")
13619 (const_string "fdiv")
13620 ]
13621 (const_string "fop")))
13622 (set_attr "fp_int_src" "true")
13623 (set_attr "mode" "<SWI24:MODE>")])
13624
13625 (define_insn "*fop_<MODEF:mode>_3_i387"
13626 [(set (match_operand:MODEF 0 "register_operand" "=f")
13627 (match_operator:MODEF 3 "binary_fp_operator"
13628 [(match_operand:MODEF 1 "register_operand" "0")
13629 (float:MODEF
13630 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13631 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13632 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13633 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13634 || optimize_function_for_size_p (cfun))"
13635 { return output_387_binary_op (insn, operands); }
13636 [(set (attr "type")
13637 (cond [(match_operand:MODEF 3 "mult_operator")
13638 (const_string "fmul")
13639 (match_operand:MODEF 3 "div_operator")
13640 (const_string "fdiv")
13641 ]
13642 (const_string "fop")))
13643 (set_attr "fp_int_src" "true")
13644 (set_attr "mode" "<MODE>")])
13645
13646 (define_insn "*fop_df_4_i387"
13647 [(set (match_operand:DF 0 "register_operand" "=f,f")
13648 (match_operator:DF 3 "binary_fp_operator"
13649 [(float_extend:DF
13650 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13651 (match_operand:DF 2 "register_operand" "0,f")]))]
13652 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13653 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13654 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13655 "* return output_387_binary_op (insn, operands);"
13656 [(set (attr "type")
13657 (cond [(match_operand:DF 3 "mult_operator")
13658 (const_string "fmul")
13659 (match_operand:DF 3 "div_operator")
13660 (const_string "fdiv")
13661 ]
13662 (const_string "fop")))
13663 (set_attr "mode" "SF")])
13664
13665 (define_insn "*fop_df_5_i387"
13666 [(set (match_operand:DF 0 "register_operand" "=f,f")
13667 (match_operator:DF 3 "binary_fp_operator"
13668 [(match_operand:DF 1 "register_operand" "0,f")
13669 (float_extend:DF
13670 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13671 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13672 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13673 "* return output_387_binary_op (insn, operands);"
13674 [(set (attr "type")
13675 (cond [(match_operand:DF 3 "mult_operator")
13676 (const_string "fmul")
13677 (match_operand:DF 3 "div_operator")
13678 (const_string "fdiv")
13679 ]
13680 (const_string "fop")))
13681 (set_attr "mode" "SF")])
13682
13683 (define_insn "*fop_df_6_i387"
13684 [(set (match_operand:DF 0 "register_operand" "=f,f")
13685 (match_operator:DF 3 "binary_fp_operator"
13686 [(float_extend:DF
13687 (match_operand:SF 1 "register_operand" "0,f"))
13688 (float_extend:DF
13689 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13690 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13691 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13692 "* return output_387_binary_op (insn, operands);"
13693 [(set (attr "type")
13694 (cond [(match_operand:DF 3 "mult_operator")
13695 (const_string "fmul")
13696 (match_operand:DF 3 "div_operator")
13697 (const_string "fdiv")
13698 ]
13699 (const_string "fop")))
13700 (set_attr "mode" "SF")])
13701
13702 (define_insn "*fop_xf_comm_i387"
13703 [(set (match_operand:XF 0 "register_operand" "=f")
13704 (match_operator:XF 3 "binary_fp_operator"
13705 [(match_operand:XF 1 "register_operand" "%0")
13706 (match_operand:XF 2 "register_operand" "f")]))]
13707 "TARGET_80387
13708 && COMMUTATIVE_ARITH_P (operands[3])"
13709 "* return output_387_binary_op (insn, operands);"
13710 [(set (attr "type")
13711 (if_then_else (match_operand:XF 3 "mult_operator")
13712 (const_string "fmul")
13713 (const_string "fop")))
13714 (set_attr "mode" "XF")])
13715
13716 (define_insn "*fop_xf_1_i387"
13717 [(set (match_operand:XF 0 "register_operand" "=f,f")
13718 (match_operator:XF 3 "binary_fp_operator"
13719 [(match_operand:XF 1 "register_operand" "0,f")
13720 (match_operand:XF 2 "register_operand" "f,0")]))]
13721 "TARGET_80387
13722 && !COMMUTATIVE_ARITH_P (operands[3])"
13723 "* return output_387_binary_op (insn, operands);"
13724 [(set (attr "type")
13725 (cond [(match_operand:XF 3 "mult_operator")
13726 (const_string "fmul")
13727 (match_operand:XF 3 "div_operator")
13728 (const_string "fdiv")
13729 ]
13730 (const_string "fop")))
13731 (set_attr "mode" "XF")])
13732
13733 (define_insn "*fop_xf_2_i387"
13734 [(set (match_operand:XF 0 "register_operand" "=f")
13735 (match_operator:XF 3 "binary_fp_operator"
13736 [(float:XF
13737 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13738 (match_operand:XF 2 "register_operand" "0")]))]
13739 "TARGET_80387
13740 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13741 { return output_387_binary_op (insn, operands); }
13742 [(set (attr "type")
13743 (cond [(match_operand:XF 3 "mult_operator")
13744 (const_string "fmul")
13745 (match_operand:XF 3 "div_operator")
13746 (const_string "fdiv")
13747 ]
13748 (const_string "fop")))
13749 (set_attr "fp_int_src" "true")
13750 (set_attr "mode" "<MODE>")])
13751
13752 (define_insn "*fop_xf_3_i387"
13753 [(set (match_operand:XF 0 "register_operand" "=f")
13754 (match_operator:XF 3 "binary_fp_operator"
13755 [(match_operand:XF 1 "register_operand" "0")
13756 (float:XF
13757 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13758 "TARGET_80387
13759 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13760 { return output_387_binary_op (insn, operands); }
13761 [(set (attr "type")
13762 (cond [(match_operand:XF 3 "mult_operator")
13763 (const_string "fmul")
13764 (match_operand:XF 3 "div_operator")
13765 (const_string "fdiv")
13766 ]
13767 (const_string "fop")))
13768 (set_attr "fp_int_src" "true")
13769 (set_attr "mode" "<MODE>")])
13770
13771 (define_insn "*fop_xf_4_i387"
13772 [(set (match_operand:XF 0 "register_operand" "=f,f")
13773 (match_operator:XF 3 "binary_fp_operator"
13774 [(float_extend:XF
13775 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13776 (match_operand:XF 2 "register_operand" "0,f")]))]
13777 "TARGET_80387"
13778 "* return output_387_binary_op (insn, operands);"
13779 [(set (attr "type")
13780 (cond [(match_operand:XF 3 "mult_operator")
13781 (const_string "fmul")
13782 (match_operand:XF 3 "div_operator")
13783 (const_string "fdiv")
13784 ]
13785 (const_string "fop")))
13786 (set_attr "mode" "<MODE>")])
13787
13788 (define_insn "*fop_xf_5_i387"
13789 [(set (match_operand:XF 0 "register_operand" "=f,f")
13790 (match_operator:XF 3 "binary_fp_operator"
13791 [(match_operand:XF 1 "register_operand" "0,f")
13792 (float_extend:XF
13793 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13794 "TARGET_80387"
13795 "* return output_387_binary_op (insn, operands);"
13796 [(set (attr "type")
13797 (cond [(match_operand:XF 3 "mult_operator")
13798 (const_string "fmul")
13799 (match_operand:XF 3 "div_operator")
13800 (const_string "fdiv")
13801 ]
13802 (const_string "fop")))
13803 (set_attr "mode" "<MODE>")])
13804
13805 (define_insn "*fop_xf_6_i387"
13806 [(set (match_operand:XF 0 "register_operand" "=f,f")
13807 (match_operator:XF 3 "binary_fp_operator"
13808 [(float_extend:XF
13809 (match_operand:MODEF 1 "register_operand" "0,f"))
13810 (float_extend:XF
13811 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13812 "TARGET_80387"
13813 "* return output_387_binary_op (insn, operands);"
13814 [(set (attr "type")
13815 (cond [(match_operand:XF 3 "mult_operator")
13816 (const_string "fmul")
13817 (match_operand:XF 3 "div_operator")
13818 (const_string "fdiv")
13819 ]
13820 (const_string "fop")))
13821 (set_attr "mode" "<MODE>")])
13822 \f
13823 ;; FPU special functions.
13824
13825 ;; This pattern implements a no-op XFmode truncation for
13826 ;; all fancy i386 XFmode math functions.
13827
13828 (define_insn "truncxf<mode>2_i387_noop_unspec"
13829 [(set (match_operand:MODEF 0 "register_operand" "=f")
13830 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13831 UNSPEC_TRUNC_NOOP))]
13832 "TARGET_USE_FANCY_MATH_387"
13833 "* return output_387_reg_move (insn, operands);"
13834 [(set_attr "type" "fmov")
13835 (set_attr "mode" "<MODE>")])
13836
13837 (define_insn "sqrtxf2"
13838 [(set (match_operand:XF 0 "register_operand" "=f")
13839 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13840 "TARGET_USE_FANCY_MATH_387"
13841 "fsqrt"
13842 [(set_attr "type" "fpspc")
13843 (set_attr "mode" "XF")
13844 (set_attr "athlon_decode" "direct")
13845 (set_attr "amdfam10_decode" "direct")
13846 (set_attr "bdver1_decode" "direct")])
13847
13848 (define_insn "sqrt_extend<mode>xf2_i387"
13849 [(set (match_operand:XF 0 "register_operand" "=f")
13850 (sqrt:XF
13851 (float_extend:XF
13852 (match_operand:MODEF 1 "register_operand" "0"))))]
13853 "TARGET_USE_FANCY_MATH_387"
13854 "fsqrt"
13855 [(set_attr "type" "fpspc")
13856 (set_attr "mode" "XF")
13857 (set_attr "athlon_decode" "direct")
13858 (set_attr "amdfam10_decode" "direct")
13859 (set_attr "bdver1_decode" "direct")])
13860
13861 (define_insn "*rsqrtsf2_sse"
13862 [(set (match_operand:SF 0 "register_operand" "=x")
13863 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13864 UNSPEC_RSQRT))]
13865 "TARGET_SSE_MATH"
13866 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13867 [(set_attr "type" "sse")
13868 (set_attr "atom_sse_attr" "rcp")
13869 (set_attr "btver2_sse_attr" "rcp")
13870 (set_attr "prefix" "maybe_vex")
13871 (set_attr "mode" "SF")])
13872
13873 (define_expand "rsqrtsf2"
13874 [(set (match_operand:SF 0 "register_operand")
13875 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13876 UNSPEC_RSQRT))]
13877 "TARGET_SSE_MATH"
13878 {
13879 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13880 DONE;
13881 })
13882
13883 (define_insn "*sqrt<mode>2_sse"
13884 [(set (match_operand:MODEF 0 "register_operand" "=x")
13885 (sqrt:MODEF
13886 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13887 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13888 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13889 [(set_attr "type" "sse")
13890 (set_attr "atom_sse_attr" "sqrt")
13891 (set_attr "btver2_sse_attr" "sqrt")
13892 (set_attr "prefix" "maybe_vex")
13893 (set_attr "mode" "<MODE>")
13894 (set_attr "athlon_decode" "*")
13895 (set_attr "amdfam10_decode" "*")
13896 (set_attr "bdver1_decode" "*")])
13897
13898 (define_expand "sqrt<mode>2"
13899 [(set (match_operand:MODEF 0 "register_operand")
13900 (sqrt:MODEF
13901 (match_operand:MODEF 1 "nonimmediate_operand")))]
13902 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13903 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13904 {
13905 if (<MODE>mode == SFmode
13906 && TARGET_SSE_MATH
13907 && TARGET_RECIP_SQRT
13908 && !optimize_function_for_size_p (cfun)
13909 && flag_finite_math_only && !flag_trapping_math
13910 && flag_unsafe_math_optimizations)
13911 {
13912 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13913 DONE;
13914 }
13915
13916 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13917 {
13918 rtx op0 = gen_reg_rtx (XFmode);
13919 rtx op1 = force_reg (<MODE>mode, operands[1]);
13920
13921 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13922 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13923 DONE;
13924 }
13925 })
13926
13927 (define_insn "fpremxf4_i387"
13928 [(set (match_operand:XF 0 "register_operand" "=f")
13929 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13930 (match_operand:XF 3 "register_operand" "1")]
13931 UNSPEC_FPREM_F))
13932 (set (match_operand:XF 1 "register_operand" "=u")
13933 (unspec:XF [(match_dup 2) (match_dup 3)]
13934 UNSPEC_FPREM_U))
13935 (set (reg:CCFP FPSR_REG)
13936 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13937 UNSPEC_C2_FLAG))]
13938 "TARGET_USE_FANCY_MATH_387
13939 && flag_finite_math_only"
13940 "fprem"
13941 [(set_attr "type" "fpspc")
13942 (set_attr "mode" "XF")])
13943
13944 (define_expand "fmodxf3"
13945 [(use (match_operand:XF 0 "register_operand"))
13946 (use (match_operand:XF 1 "general_operand"))
13947 (use (match_operand:XF 2 "general_operand"))]
13948 "TARGET_USE_FANCY_MATH_387
13949 && flag_finite_math_only"
13950 {
13951 rtx_code_label *label = gen_label_rtx ();
13952
13953 rtx op1 = gen_reg_rtx (XFmode);
13954 rtx op2 = gen_reg_rtx (XFmode);
13955
13956 emit_move_insn (op2, operands[2]);
13957 emit_move_insn (op1, operands[1]);
13958
13959 emit_label (label);
13960 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13961 ix86_emit_fp_unordered_jump (label);
13962 LABEL_NUSES (label) = 1;
13963
13964 emit_move_insn (operands[0], op1);
13965 DONE;
13966 })
13967
13968 (define_expand "fmod<mode>3"
13969 [(use (match_operand:MODEF 0 "register_operand"))
13970 (use (match_operand:MODEF 1 "general_operand"))
13971 (use (match_operand:MODEF 2 "general_operand"))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && flag_finite_math_only"
13974 {
13975 rtx (*gen_truncxf) (rtx, rtx);
13976
13977 rtx_code_label *label = gen_label_rtx ();
13978
13979 rtx op1 = gen_reg_rtx (XFmode);
13980 rtx op2 = gen_reg_rtx (XFmode);
13981
13982 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13983 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13984
13985 emit_label (label);
13986 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13987 ix86_emit_fp_unordered_jump (label);
13988 LABEL_NUSES (label) = 1;
13989
13990 /* Truncate the result properly for strict SSE math. */
13991 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13992 && !TARGET_MIX_SSE_I387)
13993 gen_truncxf = gen_truncxf<mode>2;
13994 else
13995 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13996
13997 emit_insn (gen_truncxf (operands[0], op1));
13998 DONE;
13999 })
14000
14001 (define_insn "fprem1xf4_i387"
14002 [(set (match_operand:XF 0 "register_operand" "=f")
14003 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14004 (match_operand:XF 3 "register_operand" "1")]
14005 UNSPEC_FPREM1_F))
14006 (set (match_operand:XF 1 "register_operand" "=u")
14007 (unspec:XF [(match_dup 2) (match_dup 3)]
14008 UNSPEC_FPREM1_U))
14009 (set (reg:CCFP FPSR_REG)
14010 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14011 UNSPEC_C2_FLAG))]
14012 "TARGET_USE_FANCY_MATH_387
14013 && flag_finite_math_only"
14014 "fprem1"
14015 [(set_attr "type" "fpspc")
14016 (set_attr "mode" "XF")])
14017
14018 (define_expand "remainderxf3"
14019 [(use (match_operand:XF 0 "register_operand"))
14020 (use (match_operand:XF 1 "general_operand"))
14021 (use (match_operand:XF 2 "general_operand"))]
14022 "TARGET_USE_FANCY_MATH_387
14023 && flag_finite_math_only"
14024 {
14025 rtx_code_label *label = gen_label_rtx ();
14026
14027 rtx op1 = gen_reg_rtx (XFmode);
14028 rtx op2 = gen_reg_rtx (XFmode);
14029
14030 emit_move_insn (op2, operands[2]);
14031 emit_move_insn (op1, operands[1]);
14032
14033 emit_label (label);
14034 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14035 ix86_emit_fp_unordered_jump (label);
14036 LABEL_NUSES (label) = 1;
14037
14038 emit_move_insn (operands[0], op1);
14039 DONE;
14040 })
14041
14042 (define_expand "remainder<mode>3"
14043 [(use (match_operand:MODEF 0 "register_operand"))
14044 (use (match_operand:MODEF 1 "general_operand"))
14045 (use (match_operand:MODEF 2 "general_operand"))]
14046 "TARGET_USE_FANCY_MATH_387
14047 && flag_finite_math_only"
14048 {
14049 rtx (*gen_truncxf) (rtx, rtx);
14050
14051 rtx_code_label *label = gen_label_rtx ();
14052
14053 rtx op1 = gen_reg_rtx (XFmode);
14054 rtx op2 = gen_reg_rtx (XFmode);
14055
14056 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14057 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14058
14059 emit_label (label);
14060
14061 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14062 ix86_emit_fp_unordered_jump (label);
14063 LABEL_NUSES (label) = 1;
14064
14065 /* Truncate the result properly for strict SSE math. */
14066 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14067 && !TARGET_MIX_SSE_I387)
14068 gen_truncxf = gen_truncxf<mode>2;
14069 else
14070 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14071
14072 emit_insn (gen_truncxf (operands[0], op1));
14073 DONE;
14074 })
14075
14076 (define_int_iterator SINCOS
14077 [UNSPEC_SIN
14078 UNSPEC_COS])
14079
14080 (define_int_attr sincos
14081 [(UNSPEC_SIN "sin")
14082 (UNSPEC_COS "cos")])
14083
14084 (define_insn "*<sincos>xf2_i387"
14085 [(set (match_operand:XF 0 "register_operand" "=f")
14086 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14087 SINCOS))]
14088 "TARGET_USE_FANCY_MATH_387
14089 && flag_unsafe_math_optimizations"
14090 "f<sincos>"
14091 [(set_attr "type" "fpspc")
14092 (set_attr "mode" "XF")])
14093
14094 (define_insn "*<sincos>_extend<mode>xf2_i387"
14095 [(set (match_operand:XF 0 "register_operand" "=f")
14096 (unspec:XF [(float_extend:XF
14097 (match_operand:MODEF 1 "register_operand" "0"))]
14098 SINCOS))]
14099 "TARGET_USE_FANCY_MATH_387
14100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14101 || TARGET_MIX_SSE_I387)
14102 && flag_unsafe_math_optimizations"
14103 "f<sincos>"
14104 [(set_attr "type" "fpspc")
14105 (set_attr "mode" "XF")])
14106
14107 ;; When sincos pattern is defined, sin and cos builtin functions will be
14108 ;; expanded to sincos pattern with one of its outputs left unused.
14109 ;; CSE pass will figure out if two sincos patterns can be combined,
14110 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14111 ;; depending on the unused output.
14112
14113 (define_insn "sincosxf3"
14114 [(set (match_operand:XF 0 "register_operand" "=f")
14115 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14116 UNSPEC_SINCOS_COS))
14117 (set (match_operand:XF 1 "register_operand" "=u")
14118 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14119 "TARGET_USE_FANCY_MATH_387
14120 && flag_unsafe_math_optimizations"
14121 "fsincos"
14122 [(set_attr "type" "fpspc")
14123 (set_attr "mode" "XF")])
14124
14125 (define_split
14126 [(set (match_operand:XF 0 "register_operand")
14127 (unspec:XF [(match_operand:XF 2 "register_operand")]
14128 UNSPEC_SINCOS_COS))
14129 (set (match_operand:XF 1 "register_operand")
14130 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14131 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14132 && can_create_pseudo_p ()"
14133 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14134
14135 (define_split
14136 [(set (match_operand:XF 0 "register_operand")
14137 (unspec:XF [(match_operand:XF 2 "register_operand")]
14138 UNSPEC_SINCOS_COS))
14139 (set (match_operand:XF 1 "register_operand")
14140 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14141 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14142 && can_create_pseudo_p ()"
14143 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14144
14145 (define_insn "sincos_extend<mode>xf3_i387"
14146 [(set (match_operand:XF 0 "register_operand" "=f")
14147 (unspec:XF [(float_extend:XF
14148 (match_operand:MODEF 2 "register_operand" "0"))]
14149 UNSPEC_SINCOS_COS))
14150 (set (match_operand:XF 1 "register_operand" "=u")
14151 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14152 "TARGET_USE_FANCY_MATH_387
14153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14154 || TARGET_MIX_SSE_I387)
14155 && flag_unsafe_math_optimizations"
14156 "fsincos"
14157 [(set_attr "type" "fpspc")
14158 (set_attr "mode" "XF")])
14159
14160 (define_split
14161 [(set (match_operand:XF 0 "register_operand")
14162 (unspec:XF [(float_extend:XF
14163 (match_operand:MODEF 2 "register_operand"))]
14164 UNSPEC_SINCOS_COS))
14165 (set (match_operand:XF 1 "register_operand")
14166 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14167 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14168 && can_create_pseudo_p ()"
14169 [(set (match_dup 1)
14170 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14171
14172 (define_split
14173 [(set (match_operand:XF 0 "register_operand")
14174 (unspec:XF [(float_extend:XF
14175 (match_operand:MODEF 2 "register_operand"))]
14176 UNSPEC_SINCOS_COS))
14177 (set (match_operand:XF 1 "register_operand")
14178 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14179 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14180 && can_create_pseudo_p ()"
14181 [(set (match_dup 0)
14182 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14183
14184 (define_expand "sincos<mode>3"
14185 [(use (match_operand:MODEF 0 "register_operand"))
14186 (use (match_operand:MODEF 1 "register_operand"))
14187 (use (match_operand:MODEF 2 "register_operand"))]
14188 "TARGET_USE_FANCY_MATH_387
14189 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14190 || TARGET_MIX_SSE_I387)
14191 && flag_unsafe_math_optimizations"
14192 {
14193 rtx op0 = gen_reg_rtx (XFmode);
14194 rtx op1 = gen_reg_rtx (XFmode);
14195
14196 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14197 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14198 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14199 DONE;
14200 })
14201
14202 (define_insn "fptanxf4_i387"
14203 [(set (match_operand:XF 0 "register_operand" "=f")
14204 (match_operand:XF 3 "const_double_operand" "F"))
14205 (set (match_operand:XF 1 "register_operand" "=u")
14206 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14207 UNSPEC_TAN))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations
14210 && standard_80387_constant_p (operands[3]) == 2"
14211 "fptan"
14212 [(set_attr "type" "fpspc")
14213 (set_attr "mode" "XF")])
14214
14215 (define_insn "fptan_extend<mode>xf4_i387"
14216 [(set (match_operand:MODEF 0 "register_operand" "=f")
14217 (match_operand:MODEF 3 "const_double_operand" "F"))
14218 (set (match_operand:XF 1 "register_operand" "=u")
14219 (unspec:XF [(float_extend:XF
14220 (match_operand:MODEF 2 "register_operand" "0"))]
14221 UNSPEC_TAN))]
14222 "TARGET_USE_FANCY_MATH_387
14223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14224 || TARGET_MIX_SSE_I387)
14225 && flag_unsafe_math_optimizations
14226 && standard_80387_constant_p (operands[3]) == 2"
14227 "fptan"
14228 [(set_attr "type" "fpspc")
14229 (set_attr "mode" "XF")])
14230
14231 (define_expand "tanxf2"
14232 [(use (match_operand:XF 0 "register_operand"))
14233 (use (match_operand:XF 1 "register_operand"))]
14234 "TARGET_USE_FANCY_MATH_387
14235 && flag_unsafe_math_optimizations"
14236 {
14237 rtx one = gen_reg_rtx (XFmode);
14238 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14239
14240 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14241 DONE;
14242 })
14243
14244 (define_expand "tan<mode>2"
14245 [(use (match_operand:MODEF 0 "register_operand"))
14246 (use (match_operand:MODEF 1 "register_operand"))]
14247 "TARGET_USE_FANCY_MATH_387
14248 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14249 || TARGET_MIX_SSE_I387)
14250 && flag_unsafe_math_optimizations"
14251 {
14252 rtx op0 = gen_reg_rtx (XFmode);
14253
14254 rtx one = gen_reg_rtx (<MODE>mode);
14255 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14256
14257 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14258 operands[1], op2));
14259 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14260 DONE;
14261 })
14262
14263 (define_insn "*fpatanxf3_i387"
14264 [(set (match_operand:XF 0 "register_operand" "=f")
14265 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14266 (match_operand:XF 2 "register_operand" "u")]
14267 UNSPEC_FPATAN))
14268 (clobber (match_scratch:XF 3 "=2"))]
14269 "TARGET_USE_FANCY_MATH_387
14270 && flag_unsafe_math_optimizations"
14271 "fpatan"
14272 [(set_attr "type" "fpspc")
14273 (set_attr "mode" "XF")])
14274
14275 (define_insn "fpatan_extend<mode>xf3_i387"
14276 [(set (match_operand:XF 0 "register_operand" "=f")
14277 (unspec:XF [(float_extend:XF
14278 (match_operand:MODEF 1 "register_operand" "0"))
14279 (float_extend:XF
14280 (match_operand:MODEF 2 "register_operand" "u"))]
14281 UNSPEC_FPATAN))
14282 (clobber (match_scratch:XF 3 "=2"))]
14283 "TARGET_USE_FANCY_MATH_387
14284 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14285 || TARGET_MIX_SSE_I387)
14286 && flag_unsafe_math_optimizations"
14287 "fpatan"
14288 [(set_attr "type" "fpspc")
14289 (set_attr "mode" "XF")])
14290
14291 (define_expand "atan2xf3"
14292 [(parallel [(set (match_operand:XF 0 "register_operand")
14293 (unspec:XF [(match_operand:XF 2 "register_operand")
14294 (match_operand:XF 1 "register_operand")]
14295 UNSPEC_FPATAN))
14296 (clobber (match_scratch:XF 3))])]
14297 "TARGET_USE_FANCY_MATH_387
14298 && flag_unsafe_math_optimizations")
14299
14300 (define_expand "atan2<mode>3"
14301 [(use (match_operand:MODEF 0 "register_operand"))
14302 (use (match_operand:MODEF 1 "register_operand"))
14303 (use (match_operand:MODEF 2 "register_operand"))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14306 || TARGET_MIX_SSE_I387)
14307 && flag_unsafe_math_optimizations"
14308 {
14309 rtx op0 = gen_reg_rtx (XFmode);
14310
14311 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14312 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14313 DONE;
14314 })
14315
14316 (define_expand "atanxf2"
14317 [(parallel [(set (match_operand:XF 0 "register_operand")
14318 (unspec:XF [(match_dup 2)
14319 (match_operand:XF 1 "register_operand")]
14320 UNSPEC_FPATAN))
14321 (clobber (match_scratch:XF 3))])]
14322 "TARGET_USE_FANCY_MATH_387
14323 && flag_unsafe_math_optimizations"
14324 {
14325 operands[2] = gen_reg_rtx (XFmode);
14326 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14327 })
14328
14329 (define_expand "atan<mode>2"
14330 [(use (match_operand:MODEF 0 "register_operand"))
14331 (use (match_operand:MODEF 1 "register_operand"))]
14332 "TARGET_USE_FANCY_MATH_387
14333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14334 || TARGET_MIX_SSE_I387)
14335 && flag_unsafe_math_optimizations"
14336 {
14337 rtx op0 = gen_reg_rtx (XFmode);
14338
14339 rtx op2 = gen_reg_rtx (<MODE>mode);
14340 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14341
14342 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14343 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14344 DONE;
14345 })
14346
14347 (define_expand "asinxf2"
14348 [(set (match_dup 2)
14349 (mult:XF (match_operand:XF 1 "register_operand")
14350 (match_dup 1)))
14351 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14352 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14353 (parallel [(set (match_operand:XF 0 "register_operand")
14354 (unspec:XF [(match_dup 5) (match_dup 1)]
14355 UNSPEC_FPATAN))
14356 (clobber (match_scratch:XF 6))])]
14357 "TARGET_USE_FANCY_MATH_387
14358 && flag_unsafe_math_optimizations"
14359 {
14360 int i;
14361
14362 if (optimize_insn_for_size_p ())
14363 FAIL;
14364
14365 for (i = 2; i < 6; i++)
14366 operands[i] = gen_reg_rtx (XFmode);
14367
14368 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14369 })
14370
14371 (define_expand "asin<mode>2"
14372 [(use (match_operand:MODEF 0 "register_operand"))
14373 (use (match_operand:MODEF 1 "general_operand"))]
14374 "TARGET_USE_FANCY_MATH_387
14375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14376 || TARGET_MIX_SSE_I387)
14377 && flag_unsafe_math_optimizations"
14378 {
14379 rtx op0 = gen_reg_rtx (XFmode);
14380 rtx op1 = gen_reg_rtx (XFmode);
14381
14382 if (optimize_insn_for_size_p ())
14383 FAIL;
14384
14385 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14386 emit_insn (gen_asinxf2 (op0, op1));
14387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14388 DONE;
14389 })
14390
14391 (define_expand "acosxf2"
14392 [(set (match_dup 2)
14393 (mult:XF (match_operand:XF 1 "register_operand")
14394 (match_dup 1)))
14395 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14396 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14397 (parallel [(set (match_operand:XF 0 "register_operand")
14398 (unspec:XF [(match_dup 1) (match_dup 5)]
14399 UNSPEC_FPATAN))
14400 (clobber (match_scratch:XF 6))])]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations"
14403 {
14404 int i;
14405
14406 if (optimize_insn_for_size_p ())
14407 FAIL;
14408
14409 for (i = 2; i < 6; i++)
14410 operands[i] = gen_reg_rtx (XFmode);
14411
14412 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14413 })
14414
14415 (define_expand "acos<mode>2"
14416 [(use (match_operand:MODEF 0 "register_operand"))
14417 (use (match_operand:MODEF 1 "general_operand"))]
14418 "TARGET_USE_FANCY_MATH_387
14419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420 || TARGET_MIX_SSE_I387)
14421 && flag_unsafe_math_optimizations"
14422 {
14423 rtx op0 = gen_reg_rtx (XFmode);
14424 rtx op1 = gen_reg_rtx (XFmode);
14425
14426 if (optimize_insn_for_size_p ())
14427 FAIL;
14428
14429 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14430 emit_insn (gen_acosxf2 (op0, op1));
14431 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14432 DONE;
14433 })
14434
14435 (define_insn "fyl2xxf3_i387"
14436 [(set (match_operand:XF 0 "register_operand" "=f")
14437 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14438 (match_operand:XF 2 "register_operand" "u")]
14439 UNSPEC_FYL2X))
14440 (clobber (match_scratch:XF 3 "=2"))]
14441 "TARGET_USE_FANCY_MATH_387
14442 && flag_unsafe_math_optimizations"
14443 "fyl2x"
14444 [(set_attr "type" "fpspc")
14445 (set_attr "mode" "XF")])
14446
14447 (define_insn "fyl2x_extend<mode>xf3_i387"
14448 [(set (match_operand:XF 0 "register_operand" "=f")
14449 (unspec:XF [(float_extend:XF
14450 (match_operand:MODEF 1 "register_operand" "0"))
14451 (match_operand:XF 2 "register_operand" "u")]
14452 UNSPEC_FYL2X))
14453 (clobber (match_scratch:XF 3 "=2"))]
14454 "TARGET_USE_FANCY_MATH_387
14455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14456 || TARGET_MIX_SSE_I387)
14457 && flag_unsafe_math_optimizations"
14458 "fyl2x"
14459 [(set_attr "type" "fpspc")
14460 (set_attr "mode" "XF")])
14461
14462 (define_expand "logxf2"
14463 [(parallel [(set (match_operand:XF 0 "register_operand")
14464 (unspec:XF [(match_operand:XF 1 "register_operand")
14465 (match_dup 2)] UNSPEC_FYL2X))
14466 (clobber (match_scratch:XF 3))])]
14467 "TARGET_USE_FANCY_MATH_387
14468 && flag_unsafe_math_optimizations"
14469 {
14470 operands[2] = gen_reg_rtx (XFmode);
14471 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14472 })
14473
14474 (define_expand "log<mode>2"
14475 [(use (match_operand:MODEF 0 "register_operand"))
14476 (use (match_operand:MODEF 1 "register_operand"))]
14477 "TARGET_USE_FANCY_MATH_387
14478 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14479 || TARGET_MIX_SSE_I387)
14480 && flag_unsafe_math_optimizations"
14481 {
14482 rtx op0 = gen_reg_rtx (XFmode);
14483
14484 rtx op2 = gen_reg_rtx (XFmode);
14485 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14486
14487 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14488 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14489 DONE;
14490 })
14491
14492 (define_expand "log10xf2"
14493 [(parallel [(set (match_operand:XF 0 "register_operand")
14494 (unspec:XF [(match_operand:XF 1 "register_operand")
14495 (match_dup 2)] UNSPEC_FYL2X))
14496 (clobber (match_scratch:XF 3))])]
14497 "TARGET_USE_FANCY_MATH_387
14498 && flag_unsafe_math_optimizations"
14499 {
14500 operands[2] = gen_reg_rtx (XFmode);
14501 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14502 })
14503
14504 (define_expand "log10<mode>2"
14505 [(use (match_operand:MODEF 0 "register_operand"))
14506 (use (match_operand:MODEF 1 "register_operand"))]
14507 "TARGET_USE_FANCY_MATH_387
14508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509 || TARGET_MIX_SSE_I387)
14510 && flag_unsafe_math_optimizations"
14511 {
14512 rtx op0 = gen_reg_rtx (XFmode);
14513
14514 rtx op2 = gen_reg_rtx (XFmode);
14515 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14516
14517 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14518 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14519 DONE;
14520 })
14521
14522 (define_expand "log2xf2"
14523 [(parallel [(set (match_operand:XF 0 "register_operand")
14524 (unspec:XF [(match_operand:XF 1 "register_operand")
14525 (match_dup 2)] UNSPEC_FYL2X))
14526 (clobber (match_scratch:XF 3))])]
14527 "TARGET_USE_FANCY_MATH_387
14528 && flag_unsafe_math_optimizations"
14529 {
14530 operands[2] = gen_reg_rtx (XFmode);
14531 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14532 })
14533
14534 (define_expand "log2<mode>2"
14535 [(use (match_operand:MODEF 0 "register_operand"))
14536 (use (match_operand:MODEF 1 "register_operand"))]
14537 "TARGET_USE_FANCY_MATH_387
14538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14539 || TARGET_MIX_SSE_I387)
14540 && flag_unsafe_math_optimizations"
14541 {
14542 rtx op0 = gen_reg_rtx (XFmode);
14543
14544 rtx op2 = gen_reg_rtx (XFmode);
14545 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14546
14547 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14548 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14549 DONE;
14550 })
14551
14552 (define_insn "fyl2xp1xf3_i387"
14553 [(set (match_operand:XF 0 "register_operand" "=f")
14554 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14555 (match_operand:XF 2 "register_operand" "u")]
14556 UNSPEC_FYL2XP1))
14557 (clobber (match_scratch:XF 3 "=2"))]
14558 "TARGET_USE_FANCY_MATH_387
14559 && flag_unsafe_math_optimizations"
14560 "fyl2xp1"
14561 [(set_attr "type" "fpspc")
14562 (set_attr "mode" "XF")])
14563
14564 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14565 [(set (match_operand:XF 0 "register_operand" "=f")
14566 (unspec:XF [(float_extend:XF
14567 (match_operand:MODEF 1 "register_operand" "0"))
14568 (match_operand:XF 2 "register_operand" "u")]
14569 UNSPEC_FYL2XP1))
14570 (clobber (match_scratch:XF 3 "=2"))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14573 || TARGET_MIX_SSE_I387)
14574 && flag_unsafe_math_optimizations"
14575 "fyl2xp1"
14576 [(set_attr "type" "fpspc")
14577 (set_attr "mode" "XF")])
14578
14579 (define_expand "log1pxf2"
14580 [(use (match_operand:XF 0 "register_operand"))
14581 (use (match_operand:XF 1 "register_operand"))]
14582 "TARGET_USE_FANCY_MATH_387
14583 && flag_unsafe_math_optimizations"
14584 {
14585 if (optimize_insn_for_size_p ())
14586 FAIL;
14587
14588 ix86_emit_i387_log1p (operands[0], operands[1]);
14589 DONE;
14590 })
14591
14592 (define_expand "log1p<mode>2"
14593 [(use (match_operand:MODEF 0 "register_operand"))
14594 (use (match_operand:MODEF 1 "register_operand"))]
14595 "TARGET_USE_FANCY_MATH_387
14596 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14597 || TARGET_MIX_SSE_I387)
14598 && flag_unsafe_math_optimizations"
14599 {
14600 rtx op0;
14601
14602 if (optimize_insn_for_size_p ())
14603 FAIL;
14604
14605 op0 = gen_reg_rtx (XFmode);
14606
14607 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14608
14609 ix86_emit_i387_log1p (op0, operands[1]);
14610 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14611 DONE;
14612 })
14613
14614 (define_insn "fxtractxf3_i387"
14615 [(set (match_operand:XF 0 "register_operand" "=f")
14616 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14617 UNSPEC_XTRACT_FRACT))
14618 (set (match_operand:XF 1 "register_operand" "=u")
14619 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14620 "TARGET_USE_FANCY_MATH_387
14621 && flag_unsafe_math_optimizations"
14622 "fxtract"
14623 [(set_attr "type" "fpspc")
14624 (set_attr "mode" "XF")])
14625
14626 (define_insn "fxtract_extend<mode>xf3_i387"
14627 [(set (match_operand:XF 0 "register_operand" "=f")
14628 (unspec:XF [(float_extend:XF
14629 (match_operand:MODEF 2 "register_operand" "0"))]
14630 UNSPEC_XTRACT_FRACT))
14631 (set (match_operand:XF 1 "register_operand" "=u")
14632 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14633 "TARGET_USE_FANCY_MATH_387
14634 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14635 || TARGET_MIX_SSE_I387)
14636 && flag_unsafe_math_optimizations"
14637 "fxtract"
14638 [(set_attr "type" "fpspc")
14639 (set_attr "mode" "XF")])
14640
14641 (define_expand "logbxf2"
14642 [(parallel [(set (match_dup 2)
14643 (unspec:XF [(match_operand:XF 1 "register_operand")]
14644 UNSPEC_XTRACT_FRACT))
14645 (set (match_operand:XF 0 "register_operand")
14646 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14647 "TARGET_USE_FANCY_MATH_387
14648 && flag_unsafe_math_optimizations"
14649 "operands[2] = gen_reg_rtx (XFmode);")
14650
14651 (define_expand "logb<mode>2"
14652 [(use (match_operand:MODEF 0 "register_operand"))
14653 (use (match_operand:MODEF 1 "register_operand"))]
14654 "TARGET_USE_FANCY_MATH_387
14655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14656 || TARGET_MIX_SSE_I387)
14657 && flag_unsafe_math_optimizations"
14658 {
14659 rtx op0 = gen_reg_rtx (XFmode);
14660 rtx op1 = gen_reg_rtx (XFmode);
14661
14662 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14663 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14664 DONE;
14665 })
14666
14667 (define_expand "ilogbxf2"
14668 [(use (match_operand:SI 0 "register_operand"))
14669 (use (match_operand:XF 1 "register_operand"))]
14670 "TARGET_USE_FANCY_MATH_387
14671 && flag_unsafe_math_optimizations"
14672 {
14673 rtx op0, op1;
14674
14675 if (optimize_insn_for_size_p ())
14676 FAIL;
14677
14678 op0 = gen_reg_rtx (XFmode);
14679 op1 = gen_reg_rtx (XFmode);
14680
14681 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14682 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14683 DONE;
14684 })
14685
14686 (define_expand "ilogb<mode>2"
14687 [(use (match_operand:SI 0 "register_operand"))
14688 (use (match_operand:MODEF 1 "register_operand"))]
14689 "TARGET_USE_FANCY_MATH_387
14690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14691 || TARGET_MIX_SSE_I387)
14692 && flag_unsafe_math_optimizations"
14693 {
14694 rtx op0, op1;
14695
14696 if (optimize_insn_for_size_p ())
14697 FAIL;
14698
14699 op0 = gen_reg_rtx (XFmode);
14700 op1 = gen_reg_rtx (XFmode);
14701
14702 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14703 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14704 DONE;
14705 })
14706
14707 (define_insn "*f2xm1xf2_i387"
14708 [(set (match_operand:XF 0 "register_operand" "=f")
14709 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14710 UNSPEC_F2XM1))]
14711 "TARGET_USE_FANCY_MATH_387
14712 && flag_unsafe_math_optimizations"
14713 "f2xm1"
14714 [(set_attr "type" "fpspc")
14715 (set_attr "mode" "XF")])
14716
14717 (define_insn "fscalexf4_i387"
14718 [(set (match_operand:XF 0 "register_operand" "=f")
14719 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14720 (match_operand:XF 3 "register_operand" "1")]
14721 UNSPEC_FSCALE_FRACT))
14722 (set (match_operand:XF 1 "register_operand" "=u")
14723 (unspec:XF [(match_dup 2) (match_dup 3)]
14724 UNSPEC_FSCALE_EXP))]
14725 "TARGET_USE_FANCY_MATH_387
14726 && flag_unsafe_math_optimizations"
14727 "fscale"
14728 [(set_attr "type" "fpspc")
14729 (set_attr "mode" "XF")])
14730
14731 (define_expand "expNcorexf3"
14732 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14733 (match_operand:XF 2 "register_operand")))
14734 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14735 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14736 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14737 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14738 (parallel [(set (match_operand:XF 0 "register_operand")
14739 (unspec:XF [(match_dup 8) (match_dup 4)]
14740 UNSPEC_FSCALE_FRACT))
14741 (set (match_dup 9)
14742 (unspec:XF [(match_dup 8) (match_dup 4)]
14743 UNSPEC_FSCALE_EXP))])]
14744 "TARGET_USE_FANCY_MATH_387
14745 && flag_unsafe_math_optimizations"
14746 {
14747 int i;
14748
14749 if (optimize_insn_for_size_p ())
14750 FAIL;
14751
14752 for (i = 3; i < 10; i++)
14753 operands[i] = gen_reg_rtx (XFmode);
14754
14755 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14756 })
14757
14758 (define_expand "expxf2"
14759 [(use (match_operand:XF 0 "register_operand"))
14760 (use (match_operand:XF 1 "register_operand"))]
14761 "TARGET_USE_FANCY_MATH_387
14762 && flag_unsafe_math_optimizations"
14763 {
14764 rtx op2;
14765
14766 if (optimize_insn_for_size_p ())
14767 FAIL;
14768
14769 op2 = gen_reg_rtx (XFmode);
14770 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14771
14772 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14773 DONE;
14774 })
14775
14776 (define_expand "exp<mode>2"
14777 [(use (match_operand:MODEF 0 "register_operand"))
14778 (use (match_operand:MODEF 1 "general_operand"))]
14779 "TARGET_USE_FANCY_MATH_387
14780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14781 || TARGET_MIX_SSE_I387)
14782 && flag_unsafe_math_optimizations"
14783 {
14784 rtx op0, op1;
14785
14786 if (optimize_insn_for_size_p ())
14787 FAIL;
14788
14789 op0 = gen_reg_rtx (XFmode);
14790 op1 = gen_reg_rtx (XFmode);
14791
14792 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14793 emit_insn (gen_expxf2 (op0, op1));
14794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14795 DONE;
14796 })
14797
14798 (define_expand "exp10xf2"
14799 [(use (match_operand:XF 0 "register_operand"))
14800 (use (match_operand:XF 1 "register_operand"))]
14801 "TARGET_USE_FANCY_MATH_387
14802 && flag_unsafe_math_optimizations"
14803 {
14804 rtx op2;
14805
14806 if (optimize_insn_for_size_p ())
14807 FAIL;
14808
14809 op2 = gen_reg_rtx (XFmode);
14810 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14811
14812 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14813 DONE;
14814 })
14815
14816 (define_expand "exp10<mode>2"
14817 [(use (match_operand:MODEF 0 "register_operand"))
14818 (use (match_operand:MODEF 1 "general_operand"))]
14819 "TARGET_USE_FANCY_MATH_387
14820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14821 || TARGET_MIX_SSE_I387)
14822 && flag_unsafe_math_optimizations"
14823 {
14824 rtx op0, op1;
14825
14826 if (optimize_insn_for_size_p ())
14827 FAIL;
14828
14829 op0 = gen_reg_rtx (XFmode);
14830 op1 = gen_reg_rtx (XFmode);
14831
14832 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14833 emit_insn (gen_exp10xf2 (op0, op1));
14834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14835 DONE;
14836 })
14837
14838 (define_expand "exp2xf2"
14839 [(use (match_operand:XF 0 "register_operand"))
14840 (use (match_operand:XF 1 "register_operand"))]
14841 "TARGET_USE_FANCY_MATH_387
14842 && flag_unsafe_math_optimizations"
14843 {
14844 rtx op2;
14845
14846 if (optimize_insn_for_size_p ())
14847 FAIL;
14848
14849 op2 = gen_reg_rtx (XFmode);
14850 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14851
14852 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14853 DONE;
14854 })
14855
14856 (define_expand "exp2<mode>2"
14857 [(use (match_operand:MODEF 0 "register_operand"))
14858 (use (match_operand:MODEF 1 "general_operand"))]
14859 "TARGET_USE_FANCY_MATH_387
14860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14861 || TARGET_MIX_SSE_I387)
14862 && flag_unsafe_math_optimizations"
14863 {
14864 rtx op0, op1;
14865
14866 if (optimize_insn_for_size_p ())
14867 FAIL;
14868
14869 op0 = gen_reg_rtx (XFmode);
14870 op1 = gen_reg_rtx (XFmode);
14871
14872 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14873 emit_insn (gen_exp2xf2 (op0, op1));
14874 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14875 DONE;
14876 })
14877
14878 (define_expand "expm1xf2"
14879 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14880 (match_dup 2)))
14881 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14882 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14883 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14884 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14885 (parallel [(set (match_dup 7)
14886 (unspec:XF [(match_dup 6) (match_dup 4)]
14887 UNSPEC_FSCALE_FRACT))
14888 (set (match_dup 8)
14889 (unspec:XF [(match_dup 6) (match_dup 4)]
14890 UNSPEC_FSCALE_EXP))])
14891 (parallel [(set (match_dup 10)
14892 (unspec:XF [(match_dup 9) (match_dup 8)]
14893 UNSPEC_FSCALE_FRACT))
14894 (set (match_dup 11)
14895 (unspec:XF [(match_dup 9) (match_dup 8)]
14896 UNSPEC_FSCALE_EXP))])
14897 (set (match_dup 12) (minus:XF (match_dup 10)
14898 (float_extend:XF (match_dup 13))))
14899 (set (match_operand:XF 0 "register_operand")
14900 (plus:XF (match_dup 12) (match_dup 7)))]
14901 "TARGET_USE_FANCY_MATH_387
14902 && flag_unsafe_math_optimizations"
14903 {
14904 int i;
14905
14906 if (optimize_insn_for_size_p ())
14907 FAIL;
14908
14909 for (i = 2; i < 13; i++)
14910 operands[i] = gen_reg_rtx (XFmode);
14911
14912 operands[13]
14913 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14914
14915 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14916 })
14917
14918 (define_expand "expm1<mode>2"
14919 [(use (match_operand:MODEF 0 "register_operand"))
14920 (use (match_operand:MODEF 1 "general_operand"))]
14921 "TARGET_USE_FANCY_MATH_387
14922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14923 || TARGET_MIX_SSE_I387)
14924 && flag_unsafe_math_optimizations"
14925 {
14926 rtx op0, op1;
14927
14928 if (optimize_insn_for_size_p ())
14929 FAIL;
14930
14931 op0 = gen_reg_rtx (XFmode);
14932 op1 = gen_reg_rtx (XFmode);
14933
14934 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14935 emit_insn (gen_expm1xf2 (op0, op1));
14936 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14937 DONE;
14938 })
14939
14940 (define_expand "ldexpxf3"
14941 [(match_operand:XF 0 "register_operand")
14942 (match_operand:XF 1 "register_operand")
14943 (match_operand:SI 2 "register_operand")]
14944 "TARGET_USE_FANCY_MATH_387
14945 && flag_unsafe_math_optimizations"
14946 {
14947 rtx tmp1, tmp2;
14948 if (optimize_insn_for_size_p ())
14949 FAIL;
14950
14951 tmp1 = gen_reg_rtx (XFmode);
14952 tmp2 = gen_reg_rtx (XFmode);
14953
14954 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14955 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14956 operands[1], tmp1));
14957 DONE;
14958 })
14959
14960 (define_expand "ldexp<mode>3"
14961 [(use (match_operand:MODEF 0 "register_operand"))
14962 (use (match_operand:MODEF 1 "general_operand"))
14963 (use (match_operand:SI 2 "register_operand"))]
14964 "TARGET_USE_FANCY_MATH_387
14965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14966 || TARGET_MIX_SSE_I387)
14967 && flag_unsafe_math_optimizations"
14968 {
14969 rtx op0, op1;
14970
14971 if (optimize_insn_for_size_p ())
14972 FAIL;
14973
14974 op0 = gen_reg_rtx (XFmode);
14975 op1 = gen_reg_rtx (XFmode);
14976
14977 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14978 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14979 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14980 DONE;
14981 })
14982
14983 (define_expand "scalbxf3"
14984 [(parallel [(set (match_operand:XF 0 " register_operand")
14985 (unspec:XF [(match_operand:XF 1 "register_operand")
14986 (match_operand:XF 2 "register_operand")]
14987 UNSPEC_FSCALE_FRACT))
14988 (set (match_dup 3)
14989 (unspec:XF [(match_dup 1) (match_dup 2)]
14990 UNSPEC_FSCALE_EXP))])]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14993 {
14994 if (optimize_insn_for_size_p ())
14995 FAIL;
14996
14997 operands[3] = gen_reg_rtx (XFmode);
14998 })
14999
15000 (define_expand "scalb<mode>3"
15001 [(use (match_operand:MODEF 0 "register_operand"))
15002 (use (match_operand:MODEF 1 "general_operand"))
15003 (use (match_operand:MODEF 2 "general_operand"))]
15004 "TARGET_USE_FANCY_MATH_387
15005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15006 || TARGET_MIX_SSE_I387)
15007 && flag_unsafe_math_optimizations"
15008 {
15009 rtx op0, op1, op2;
15010
15011 if (optimize_insn_for_size_p ())
15012 FAIL;
15013
15014 op0 = gen_reg_rtx (XFmode);
15015 op1 = gen_reg_rtx (XFmode);
15016 op2 = gen_reg_rtx (XFmode);
15017
15018 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15019 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15020 emit_insn (gen_scalbxf3 (op0, op1, op2));
15021 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15022 DONE;
15023 })
15024
15025 (define_expand "significandxf2"
15026 [(parallel [(set (match_operand:XF 0 "register_operand")
15027 (unspec:XF [(match_operand:XF 1 "register_operand")]
15028 UNSPEC_XTRACT_FRACT))
15029 (set (match_dup 2)
15030 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15031 "TARGET_USE_FANCY_MATH_387
15032 && flag_unsafe_math_optimizations"
15033 "operands[2] = gen_reg_rtx (XFmode);")
15034
15035 (define_expand "significand<mode>2"
15036 [(use (match_operand:MODEF 0 "register_operand"))
15037 (use (match_operand:MODEF 1 "register_operand"))]
15038 "TARGET_USE_FANCY_MATH_387
15039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15040 || TARGET_MIX_SSE_I387)
15041 && flag_unsafe_math_optimizations"
15042 {
15043 rtx op0 = gen_reg_rtx (XFmode);
15044 rtx op1 = gen_reg_rtx (XFmode);
15045
15046 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15047 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15048 DONE;
15049 })
15050 \f
15051
15052 (define_insn "sse4_1_round<mode>2"
15053 [(set (match_operand:MODEF 0 "register_operand" "=x")
15054 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15055 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15056 UNSPEC_ROUND))]
15057 "TARGET_ROUND"
15058 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15059 [(set_attr "type" "ssecvt")
15060 (set_attr "prefix_extra" "1")
15061 (set_attr "prefix" "maybe_vex")
15062 (set_attr "mode" "<MODE>")])
15063
15064 (define_insn "rintxf2"
15065 [(set (match_operand:XF 0 "register_operand" "=f")
15066 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15067 UNSPEC_FRNDINT))]
15068 "TARGET_USE_FANCY_MATH_387
15069 && flag_unsafe_math_optimizations"
15070 "frndint"
15071 [(set_attr "type" "fpspc")
15072 (set_attr "mode" "XF")])
15073
15074 (define_expand "rint<mode>2"
15075 [(use (match_operand:MODEF 0 "register_operand"))
15076 (use (match_operand:MODEF 1 "register_operand"))]
15077 "(TARGET_USE_FANCY_MATH_387
15078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15079 || TARGET_MIX_SSE_I387)
15080 && flag_unsafe_math_optimizations)
15081 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15082 && !flag_trapping_math)"
15083 {
15084 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15085 && !flag_trapping_math)
15086 {
15087 if (TARGET_ROUND)
15088 emit_insn (gen_sse4_1_round<mode>2
15089 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15090 else if (optimize_insn_for_size_p ())
15091 FAIL;
15092 else
15093 ix86_expand_rint (operands[0], operands[1]);
15094 }
15095 else
15096 {
15097 rtx op0 = gen_reg_rtx (XFmode);
15098 rtx op1 = gen_reg_rtx (XFmode);
15099
15100 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15101 emit_insn (gen_rintxf2 (op0, op1));
15102
15103 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15104 }
15105 DONE;
15106 })
15107
15108 (define_expand "round<mode>2"
15109 [(match_operand:X87MODEF 0 "register_operand")
15110 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15111 "(TARGET_USE_FANCY_MATH_387
15112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15113 || TARGET_MIX_SSE_I387)
15114 && flag_unsafe_math_optimizations)
15115 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15116 && !flag_trapping_math && !flag_rounding_math)"
15117 {
15118 if (optimize_insn_for_size_p ())
15119 FAIL;
15120
15121 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15122 && !flag_trapping_math && !flag_rounding_math)
15123 {
15124 if (TARGET_ROUND)
15125 {
15126 operands[1] = force_reg (<MODE>mode, operands[1]);
15127 ix86_expand_round_sse4 (operands[0], operands[1]);
15128 }
15129 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15130 ix86_expand_round (operands[0], operands[1]);
15131 else
15132 ix86_expand_rounddf_32 (operands[0], operands[1]);
15133 }
15134 else
15135 {
15136 operands[1] = force_reg (<MODE>mode, operands[1]);
15137 ix86_emit_i387_round (operands[0], operands[1]);
15138 }
15139 DONE;
15140 })
15141
15142 (define_insn_and_split "*fistdi2_1"
15143 [(set (match_operand:DI 0 "nonimmediate_operand")
15144 (unspec:DI [(match_operand:XF 1 "register_operand")]
15145 UNSPEC_FIST))]
15146 "TARGET_USE_FANCY_MATH_387
15147 && can_create_pseudo_p ()"
15148 "#"
15149 "&& 1"
15150 [(const_int 0)]
15151 {
15152 if (memory_operand (operands[0], VOIDmode))
15153 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15154 else
15155 {
15156 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15157 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15158 operands[2]));
15159 }
15160 DONE;
15161 }
15162 [(set_attr "type" "fpspc")
15163 (set_attr "mode" "DI")])
15164
15165 (define_insn "fistdi2"
15166 [(set (match_operand:DI 0 "memory_operand" "=m")
15167 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15168 UNSPEC_FIST))
15169 (clobber (match_scratch:XF 2 "=&1f"))]
15170 "TARGET_USE_FANCY_MATH_387"
15171 "* return output_fix_trunc (insn, operands, false);"
15172 [(set_attr "type" "fpspc")
15173 (set_attr "mode" "DI")])
15174
15175 (define_insn "fistdi2_with_temp"
15176 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15177 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15178 UNSPEC_FIST))
15179 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15180 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15181 "TARGET_USE_FANCY_MATH_387"
15182 "#"
15183 [(set_attr "type" "fpspc")
15184 (set_attr "mode" "DI")])
15185
15186 (define_split
15187 [(set (match_operand:DI 0 "register_operand")
15188 (unspec:DI [(match_operand:XF 1 "register_operand")]
15189 UNSPEC_FIST))
15190 (clobber (match_operand:DI 2 "memory_operand"))
15191 (clobber (match_scratch 3))]
15192 "reload_completed"
15193 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15194 (clobber (match_dup 3))])
15195 (set (match_dup 0) (match_dup 2))])
15196
15197 (define_split
15198 [(set (match_operand:DI 0 "memory_operand")
15199 (unspec:DI [(match_operand:XF 1 "register_operand")]
15200 UNSPEC_FIST))
15201 (clobber (match_operand:DI 2 "memory_operand"))
15202 (clobber (match_scratch 3))]
15203 "reload_completed"
15204 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15205 (clobber (match_dup 3))])])
15206
15207 (define_insn_and_split "*fist<mode>2_1"
15208 [(set (match_operand:SWI24 0 "register_operand")
15209 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15210 UNSPEC_FIST))]
15211 "TARGET_USE_FANCY_MATH_387
15212 && can_create_pseudo_p ()"
15213 "#"
15214 "&& 1"
15215 [(const_int 0)]
15216 {
15217 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15218 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15219 operands[2]));
15220 DONE;
15221 }
15222 [(set_attr "type" "fpspc")
15223 (set_attr "mode" "<MODE>")])
15224
15225 (define_insn "fist<mode>2"
15226 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15227 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15228 UNSPEC_FIST))]
15229 "TARGET_USE_FANCY_MATH_387"
15230 "* return output_fix_trunc (insn, operands, false);"
15231 [(set_attr "type" "fpspc")
15232 (set_attr "mode" "<MODE>")])
15233
15234 (define_insn "fist<mode>2_with_temp"
15235 [(set (match_operand:SWI24 0 "register_operand" "=r")
15236 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15237 UNSPEC_FIST))
15238 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15239 "TARGET_USE_FANCY_MATH_387"
15240 "#"
15241 [(set_attr "type" "fpspc")
15242 (set_attr "mode" "<MODE>")])
15243
15244 (define_split
15245 [(set (match_operand:SWI24 0 "register_operand")
15246 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15247 UNSPEC_FIST))
15248 (clobber (match_operand:SWI24 2 "memory_operand"))]
15249 "reload_completed"
15250 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15251 (set (match_dup 0) (match_dup 2))])
15252
15253 (define_split
15254 [(set (match_operand:SWI24 0 "memory_operand")
15255 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15256 UNSPEC_FIST))
15257 (clobber (match_operand:SWI24 2 "memory_operand"))]
15258 "reload_completed"
15259 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15260
15261 (define_expand "lrintxf<mode>2"
15262 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15263 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15264 UNSPEC_FIST))]
15265 "TARGET_USE_FANCY_MATH_387")
15266
15267 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15268 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15269 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15270 UNSPEC_FIX_NOTRUNC))]
15271 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15272
15273 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15274 [(match_operand:SWI248x 0 "nonimmediate_operand")
15275 (match_operand:X87MODEF 1 "register_operand")]
15276 "(TARGET_USE_FANCY_MATH_387
15277 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15278 || TARGET_MIX_SSE_I387)
15279 && flag_unsafe_math_optimizations)
15280 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15281 && <SWI248x:MODE>mode != HImode
15282 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15283 && !flag_trapping_math && !flag_rounding_math)"
15284 {
15285 if (optimize_insn_for_size_p ())
15286 FAIL;
15287
15288 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15289 && <SWI248x:MODE>mode != HImode
15290 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15291 && !flag_trapping_math && !flag_rounding_math)
15292 ix86_expand_lround (operands[0], operands[1]);
15293 else
15294 ix86_emit_i387_round (operands[0], operands[1]);
15295 DONE;
15296 })
15297
15298 (define_int_iterator FRNDINT_ROUNDING
15299 [UNSPEC_FRNDINT_FLOOR
15300 UNSPEC_FRNDINT_CEIL
15301 UNSPEC_FRNDINT_TRUNC])
15302
15303 (define_int_iterator FIST_ROUNDING
15304 [UNSPEC_FIST_FLOOR
15305 UNSPEC_FIST_CEIL])
15306
15307 ;; Base name for define_insn
15308 (define_int_attr rounding_insn
15309 [(UNSPEC_FRNDINT_FLOOR "floor")
15310 (UNSPEC_FRNDINT_CEIL "ceil")
15311 (UNSPEC_FRNDINT_TRUNC "btrunc")
15312 (UNSPEC_FIST_FLOOR "floor")
15313 (UNSPEC_FIST_CEIL "ceil")])
15314
15315 (define_int_attr rounding
15316 [(UNSPEC_FRNDINT_FLOOR "floor")
15317 (UNSPEC_FRNDINT_CEIL "ceil")
15318 (UNSPEC_FRNDINT_TRUNC "trunc")
15319 (UNSPEC_FIST_FLOOR "floor")
15320 (UNSPEC_FIST_CEIL "ceil")])
15321
15322 (define_int_attr ROUNDING
15323 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15324 (UNSPEC_FRNDINT_CEIL "CEIL")
15325 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15326 (UNSPEC_FIST_FLOOR "FLOOR")
15327 (UNSPEC_FIST_CEIL "CEIL")])
15328
15329 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15330 (define_insn_and_split "frndintxf2_<rounding>"
15331 [(set (match_operand:XF 0 "register_operand")
15332 (unspec:XF [(match_operand:XF 1 "register_operand")]
15333 FRNDINT_ROUNDING))
15334 (clobber (reg:CC FLAGS_REG))]
15335 "TARGET_USE_FANCY_MATH_387
15336 && flag_unsafe_math_optimizations
15337 && can_create_pseudo_p ()"
15338 "#"
15339 "&& 1"
15340 [(const_int 0)]
15341 {
15342 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15343
15344 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15345 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15346
15347 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15348 operands[2], operands[3]));
15349 DONE;
15350 }
15351 [(set_attr "type" "frndint")
15352 (set_attr "i387_cw" "<rounding>")
15353 (set_attr "mode" "XF")])
15354
15355 (define_insn "frndintxf2_<rounding>_i387"
15356 [(set (match_operand:XF 0 "register_operand" "=f")
15357 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15358 FRNDINT_ROUNDING))
15359 (use (match_operand:HI 2 "memory_operand" "m"))
15360 (use (match_operand:HI 3 "memory_operand" "m"))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_unsafe_math_optimizations"
15363 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15364 [(set_attr "type" "frndint")
15365 (set_attr "i387_cw" "<rounding>")
15366 (set_attr "mode" "XF")])
15367
15368 (define_expand "<rounding_insn>xf2"
15369 [(parallel [(set (match_operand:XF 0 "register_operand")
15370 (unspec:XF [(match_operand:XF 1 "register_operand")]
15371 FRNDINT_ROUNDING))
15372 (clobber (reg:CC FLAGS_REG))])]
15373 "TARGET_USE_FANCY_MATH_387
15374 && flag_unsafe_math_optimizations
15375 && !optimize_insn_for_size_p ()")
15376
15377 (define_expand "<rounding_insn><mode>2"
15378 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15379 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15380 FRNDINT_ROUNDING))
15381 (clobber (reg:CC FLAGS_REG))])]
15382 "(TARGET_USE_FANCY_MATH_387
15383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15384 || TARGET_MIX_SSE_I387)
15385 && flag_unsafe_math_optimizations)
15386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15387 && !flag_trapping_math)"
15388 {
15389 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15390 && !flag_trapping_math)
15391 {
15392 if (TARGET_ROUND)
15393 emit_insn (gen_sse4_1_round<mode>2
15394 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15395 else if (optimize_insn_for_size_p ())
15396 FAIL;
15397 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15398 {
15399 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15400 ix86_expand_floorceil (operands[0], operands[1], true);
15401 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15402 ix86_expand_floorceil (operands[0], operands[1], false);
15403 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15404 ix86_expand_trunc (operands[0], operands[1]);
15405 else
15406 gcc_unreachable ();
15407 }
15408 else
15409 {
15410 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15411 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15412 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15413 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15414 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15415 ix86_expand_truncdf_32 (operands[0], operands[1]);
15416 else
15417 gcc_unreachable ();
15418 }
15419 }
15420 else
15421 {
15422 rtx op0, op1;
15423
15424 if (optimize_insn_for_size_p ())
15425 FAIL;
15426
15427 op0 = gen_reg_rtx (XFmode);
15428 op1 = gen_reg_rtx (XFmode);
15429 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15430 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15431
15432 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15433 }
15434 DONE;
15435 })
15436
15437 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15438 (define_insn_and_split "frndintxf2_mask_pm"
15439 [(set (match_operand:XF 0 "register_operand")
15440 (unspec:XF [(match_operand:XF 1 "register_operand")]
15441 UNSPEC_FRNDINT_MASK_PM))
15442 (clobber (reg:CC FLAGS_REG))]
15443 "TARGET_USE_FANCY_MATH_387
15444 && flag_unsafe_math_optimizations
15445 && can_create_pseudo_p ()"
15446 "#"
15447 "&& 1"
15448 [(const_int 0)]
15449 {
15450 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15451
15452 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15453 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15454
15455 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15456 operands[2], operands[3]));
15457 DONE;
15458 }
15459 [(set_attr "type" "frndint")
15460 (set_attr "i387_cw" "mask_pm")
15461 (set_attr "mode" "XF")])
15462
15463 (define_insn "frndintxf2_mask_pm_i387"
15464 [(set (match_operand:XF 0 "register_operand" "=f")
15465 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15466 UNSPEC_FRNDINT_MASK_PM))
15467 (use (match_operand:HI 2 "memory_operand" "m"))
15468 (use (match_operand:HI 3 "memory_operand" "m"))]
15469 "TARGET_USE_FANCY_MATH_387
15470 && flag_unsafe_math_optimizations"
15471 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15472 [(set_attr "type" "frndint")
15473 (set_attr "i387_cw" "mask_pm")
15474 (set_attr "mode" "XF")])
15475
15476 (define_expand "nearbyintxf2"
15477 [(parallel [(set (match_operand:XF 0 "register_operand")
15478 (unspec:XF [(match_operand:XF 1 "register_operand")]
15479 UNSPEC_FRNDINT_MASK_PM))
15480 (clobber (reg:CC FLAGS_REG))])]
15481 "TARGET_USE_FANCY_MATH_387
15482 && flag_unsafe_math_optimizations")
15483
15484 (define_expand "nearbyint<mode>2"
15485 [(use (match_operand:MODEF 0 "register_operand"))
15486 (use (match_operand:MODEF 1 "register_operand"))]
15487 "TARGET_USE_FANCY_MATH_387
15488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15489 || TARGET_MIX_SSE_I387)
15490 && flag_unsafe_math_optimizations"
15491 {
15492 rtx op0 = gen_reg_rtx (XFmode);
15493 rtx op1 = gen_reg_rtx (XFmode);
15494
15495 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15496 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15497
15498 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15499 DONE;
15500 })
15501
15502 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15503 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15504 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15505 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15506 FIST_ROUNDING))
15507 (clobber (reg:CC FLAGS_REG))]
15508 "TARGET_USE_FANCY_MATH_387
15509 && flag_unsafe_math_optimizations
15510 && can_create_pseudo_p ()"
15511 "#"
15512 "&& 1"
15513 [(const_int 0)]
15514 {
15515 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15516
15517 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15518 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15519 if (memory_operand (operands[0], VOIDmode))
15520 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15521 operands[2], operands[3]));
15522 else
15523 {
15524 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15525 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15526 (operands[0], operands[1], operands[2],
15527 operands[3], operands[4]));
15528 }
15529 DONE;
15530 }
15531 [(set_attr "type" "fistp")
15532 (set_attr "i387_cw" "<rounding>")
15533 (set_attr "mode" "<MODE>")])
15534
15535 (define_insn "fistdi2_<rounding>"
15536 [(set (match_operand:DI 0 "memory_operand" "=m")
15537 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15538 FIST_ROUNDING))
15539 (use (match_operand:HI 2 "memory_operand" "m"))
15540 (use (match_operand:HI 3 "memory_operand" "m"))
15541 (clobber (match_scratch:XF 4 "=&1f"))]
15542 "TARGET_USE_FANCY_MATH_387
15543 && flag_unsafe_math_optimizations"
15544 "* return output_fix_trunc (insn, operands, false);"
15545 [(set_attr "type" "fistp")
15546 (set_attr "i387_cw" "<rounding>")
15547 (set_attr "mode" "DI")])
15548
15549 (define_insn "fistdi2_<rounding>_with_temp"
15550 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15551 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15552 FIST_ROUNDING))
15553 (use (match_operand:HI 2 "memory_operand" "m,m"))
15554 (use (match_operand:HI 3 "memory_operand" "m,m"))
15555 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15556 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15557 "TARGET_USE_FANCY_MATH_387
15558 && flag_unsafe_math_optimizations"
15559 "#"
15560 [(set_attr "type" "fistp")
15561 (set_attr "i387_cw" "<rounding>")
15562 (set_attr "mode" "DI")])
15563
15564 (define_split
15565 [(set (match_operand:DI 0 "register_operand")
15566 (unspec:DI [(match_operand:XF 1 "register_operand")]
15567 FIST_ROUNDING))
15568 (use (match_operand:HI 2 "memory_operand"))
15569 (use (match_operand:HI 3 "memory_operand"))
15570 (clobber (match_operand:DI 4 "memory_operand"))
15571 (clobber (match_scratch 5))]
15572 "reload_completed"
15573 [(parallel [(set (match_dup 4)
15574 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15575 (use (match_dup 2))
15576 (use (match_dup 3))
15577 (clobber (match_dup 5))])
15578 (set (match_dup 0) (match_dup 4))])
15579
15580 (define_split
15581 [(set (match_operand:DI 0 "memory_operand")
15582 (unspec:DI [(match_operand:XF 1 "register_operand")]
15583 FIST_ROUNDING))
15584 (use (match_operand:HI 2 "memory_operand"))
15585 (use (match_operand:HI 3 "memory_operand"))
15586 (clobber (match_operand:DI 4 "memory_operand"))
15587 (clobber (match_scratch 5))]
15588 "reload_completed"
15589 [(parallel [(set (match_dup 0)
15590 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15591 (use (match_dup 2))
15592 (use (match_dup 3))
15593 (clobber (match_dup 5))])])
15594
15595 (define_insn "fist<mode>2_<rounding>"
15596 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15597 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15598 FIST_ROUNDING))
15599 (use (match_operand:HI 2 "memory_operand" "m"))
15600 (use (match_operand:HI 3 "memory_operand" "m"))]
15601 "TARGET_USE_FANCY_MATH_387
15602 && flag_unsafe_math_optimizations"
15603 "* return output_fix_trunc (insn, operands, false);"
15604 [(set_attr "type" "fistp")
15605 (set_attr "i387_cw" "<rounding>")
15606 (set_attr "mode" "<MODE>")])
15607
15608 (define_insn "fist<mode>2_<rounding>_with_temp"
15609 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15610 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15611 FIST_ROUNDING))
15612 (use (match_operand:HI 2 "memory_operand" "m,m"))
15613 (use (match_operand:HI 3 "memory_operand" "m,m"))
15614 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15615 "TARGET_USE_FANCY_MATH_387
15616 && flag_unsafe_math_optimizations"
15617 "#"
15618 [(set_attr "type" "fistp")
15619 (set_attr "i387_cw" "<rounding>")
15620 (set_attr "mode" "<MODE>")])
15621
15622 (define_split
15623 [(set (match_operand:SWI24 0 "register_operand")
15624 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15625 FIST_ROUNDING))
15626 (use (match_operand:HI 2 "memory_operand"))
15627 (use (match_operand:HI 3 "memory_operand"))
15628 (clobber (match_operand:SWI24 4 "memory_operand"))]
15629 "reload_completed"
15630 [(parallel [(set (match_dup 4)
15631 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15632 (use (match_dup 2))
15633 (use (match_dup 3))])
15634 (set (match_dup 0) (match_dup 4))])
15635
15636 (define_split
15637 [(set (match_operand:SWI24 0 "memory_operand")
15638 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15639 FIST_ROUNDING))
15640 (use (match_operand:HI 2 "memory_operand"))
15641 (use (match_operand:HI 3 "memory_operand"))
15642 (clobber (match_operand:SWI24 4 "memory_operand"))]
15643 "reload_completed"
15644 [(parallel [(set (match_dup 0)
15645 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15646 (use (match_dup 2))
15647 (use (match_dup 3))])])
15648
15649 (define_expand "l<rounding_insn>xf<mode>2"
15650 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15651 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15652 FIST_ROUNDING))
15653 (clobber (reg:CC FLAGS_REG))])]
15654 "TARGET_USE_FANCY_MATH_387
15655 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15656 && flag_unsafe_math_optimizations")
15657
15658 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15659 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15660 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15661 FIST_ROUNDING))
15662 (clobber (reg:CC FLAGS_REG))])]
15663 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15664 && !flag_trapping_math"
15665 {
15666 if (TARGET_64BIT && optimize_insn_for_size_p ())
15667 FAIL;
15668
15669 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15670 ix86_expand_lfloorceil (operands[0], operands[1], true);
15671 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15672 ix86_expand_lfloorceil (operands[0], operands[1], false);
15673 else
15674 gcc_unreachable ();
15675
15676 DONE;
15677 })
15678
15679 (define_insn "fxam<mode>2_i387"
15680 [(set (match_operand:HI 0 "register_operand" "=a")
15681 (unspec:HI
15682 [(match_operand:X87MODEF 1 "register_operand" "f")]
15683 UNSPEC_FXAM))]
15684 "TARGET_USE_FANCY_MATH_387"
15685 "fxam\n\tfnstsw\t%0"
15686 [(set_attr "type" "multi")
15687 (set_attr "length" "4")
15688 (set_attr "unit" "i387")
15689 (set_attr "mode" "<MODE>")])
15690
15691 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15692 [(set (match_operand:HI 0 "register_operand")
15693 (unspec:HI
15694 [(match_operand:MODEF 1 "memory_operand")]
15695 UNSPEC_FXAM_MEM))]
15696 "TARGET_USE_FANCY_MATH_387
15697 && can_create_pseudo_p ()"
15698 "#"
15699 "&& 1"
15700 [(set (match_dup 2)(match_dup 1))
15701 (set (match_dup 0)
15702 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15703 {
15704 operands[2] = gen_reg_rtx (<MODE>mode);
15705
15706 MEM_VOLATILE_P (operands[1]) = 1;
15707 }
15708 [(set_attr "type" "multi")
15709 (set_attr "unit" "i387")
15710 (set_attr "mode" "<MODE>")])
15711
15712 (define_expand "isinfxf2"
15713 [(use (match_operand:SI 0 "register_operand"))
15714 (use (match_operand:XF 1 "register_operand"))]
15715 "TARGET_USE_FANCY_MATH_387
15716 && ix86_libc_has_function (function_c99_misc)"
15717 {
15718 rtx mask = GEN_INT (0x45);
15719 rtx val = GEN_INT (0x05);
15720
15721 rtx cond;
15722
15723 rtx scratch = gen_reg_rtx (HImode);
15724 rtx res = gen_reg_rtx (QImode);
15725
15726 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15727
15728 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15729 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15730 cond = gen_rtx_fmt_ee (EQ, QImode,
15731 gen_rtx_REG (CCmode, FLAGS_REG),
15732 const0_rtx);
15733 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15734 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15735 DONE;
15736 })
15737
15738 (define_expand "isinf<mode>2"
15739 [(use (match_operand:SI 0 "register_operand"))
15740 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15741 "TARGET_USE_FANCY_MATH_387
15742 && ix86_libc_has_function (function_c99_misc)
15743 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15744 {
15745 rtx mask = GEN_INT (0x45);
15746 rtx val = GEN_INT (0x05);
15747
15748 rtx cond;
15749
15750 rtx scratch = gen_reg_rtx (HImode);
15751 rtx res = gen_reg_rtx (QImode);
15752
15753 /* Remove excess precision by forcing value through memory. */
15754 if (memory_operand (operands[1], VOIDmode))
15755 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15756 else
15757 {
15758 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15759
15760 emit_move_insn (temp, operands[1]);
15761 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15762 }
15763
15764 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15765 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15766 cond = gen_rtx_fmt_ee (EQ, QImode,
15767 gen_rtx_REG (CCmode, FLAGS_REG),
15768 const0_rtx);
15769 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15770 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15771 DONE;
15772 })
15773
15774 (define_expand "signbitxf2"
15775 [(use (match_operand:SI 0 "register_operand"))
15776 (use (match_operand:XF 1 "register_operand"))]
15777 "TARGET_USE_FANCY_MATH_387"
15778 {
15779 rtx scratch = gen_reg_rtx (HImode);
15780
15781 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15782 emit_insn (gen_andsi3 (operands[0],
15783 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15784 DONE;
15785 })
15786
15787 (define_insn "movmsk_df"
15788 [(set (match_operand:SI 0 "register_operand" "=r")
15789 (unspec:SI
15790 [(match_operand:DF 1 "register_operand" "x")]
15791 UNSPEC_MOVMSK))]
15792 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15793 "%vmovmskpd\t{%1, %0|%0, %1}"
15794 [(set_attr "type" "ssemov")
15795 (set_attr "prefix" "maybe_vex")
15796 (set_attr "mode" "DF")])
15797
15798 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15799 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15800 (define_expand "signbitdf2"
15801 [(use (match_operand:SI 0 "register_operand"))
15802 (use (match_operand:DF 1 "register_operand"))]
15803 "TARGET_USE_FANCY_MATH_387
15804 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15805 {
15806 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15807 {
15808 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15809 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15810 }
15811 else
15812 {
15813 rtx scratch = gen_reg_rtx (HImode);
15814
15815 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15816 emit_insn (gen_andsi3 (operands[0],
15817 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15818 }
15819 DONE;
15820 })
15821
15822 (define_expand "signbitsf2"
15823 [(use (match_operand:SI 0 "register_operand"))
15824 (use (match_operand:SF 1 "register_operand"))]
15825 "TARGET_USE_FANCY_MATH_387
15826 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15827 {
15828 rtx scratch = gen_reg_rtx (HImode);
15829
15830 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15831 emit_insn (gen_andsi3 (operands[0],
15832 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15833 DONE;
15834 })
15835 \f
15836 ;; Block operation instructions
15837
15838 (define_insn "cld"
15839 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15840 ""
15841 "cld"
15842 [(set_attr "length" "1")
15843 (set_attr "length_immediate" "0")
15844 (set_attr "modrm" "0")])
15845
15846 (define_expand "movmem<mode>"
15847 [(use (match_operand:BLK 0 "memory_operand"))
15848 (use (match_operand:BLK 1 "memory_operand"))
15849 (use (match_operand:SWI48 2 "nonmemory_operand"))
15850 (use (match_operand:SWI48 3 "const_int_operand"))
15851 (use (match_operand:SI 4 "const_int_operand"))
15852 (use (match_operand:SI 5 "const_int_operand"))
15853 (use (match_operand:SI 6 ""))
15854 (use (match_operand:SI 7 ""))
15855 (use (match_operand:SI 8 ""))]
15856 ""
15857 {
15858 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15859 operands[2], NULL, operands[3],
15860 operands[4], operands[5],
15861 operands[6], operands[7],
15862 operands[8], false))
15863 DONE;
15864 else
15865 FAIL;
15866 })
15867
15868 ;; Most CPUs don't like single string operations
15869 ;; Handle this case here to simplify previous expander.
15870
15871 (define_expand "strmov"
15872 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15873 (set (match_operand 1 "memory_operand") (match_dup 4))
15874 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15875 (clobber (reg:CC FLAGS_REG))])
15876 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15877 (clobber (reg:CC FLAGS_REG))])]
15878 ""
15879 {
15880 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15881
15882 /* If .md ever supports :P for Pmode, these can be directly
15883 in the pattern above. */
15884 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15885 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15886
15887 /* Can't use this if the user has appropriated esi or edi. */
15888 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15889 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15890 {
15891 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15892 operands[2], operands[3],
15893 operands[5], operands[6]));
15894 DONE;
15895 }
15896
15897 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15898 })
15899
15900 (define_expand "strmov_singleop"
15901 [(parallel [(set (match_operand 1 "memory_operand")
15902 (match_operand 3 "memory_operand"))
15903 (set (match_operand 0 "register_operand")
15904 (match_operand 4))
15905 (set (match_operand 2 "register_operand")
15906 (match_operand 5))])]
15907 ""
15908 "ix86_current_function_needs_cld = 1;")
15909
15910 (define_insn "*strmovdi_rex_1"
15911 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15912 (mem:DI (match_operand:P 3 "register_operand" "1")))
15913 (set (match_operand:P 0 "register_operand" "=D")
15914 (plus:P (match_dup 2)
15915 (const_int 8)))
15916 (set (match_operand:P 1 "register_operand" "=S")
15917 (plus:P (match_dup 3)
15918 (const_int 8)))]
15919 "TARGET_64BIT
15920 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15921 "%^movsq"
15922 [(set_attr "type" "str")
15923 (set_attr "memory" "both")
15924 (set_attr "mode" "DI")])
15925
15926 (define_insn "*strmovsi_1"
15927 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15928 (mem:SI (match_operand:P 3 "register_operand" "1")))
15929 (set (match_operand:P 0 "register_operand" "=D")
15930 (plus:P (match_dup 2)
15931 (const_int 4)))
15932 (set (match_operand:P 1 "register_operand" "=S")
15933 (plus:P (match_dup 3)
15934 (const_int 4)))]
15935 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15936 "%^movs{l|d}"
15937 [(set_attr "type" "str")
15938 (set_attr "memory" "both")
15939 (set_attr "mode" "SI")])
15940
15941 (define_insn "*strmovhi_1"
15942 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15943 (mem:HI (match_operand:P 3 "register_operand" "1")))
15944 (set (match_operand:P 0 "register_operand" "=D")
15945 (plus:P (match_dup 2)
15946 (const_int 2)))
15947 (set (match_operand:P 1 "register_operand" "=S")
15948 (plus:P (match_dup 3)
15949 (const_int 2)))]
15950 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15951 "%^movsw"
15952 [(set_attr "type" "str")
15953 (set_attr "memory" "both")
15954 (set_attr "mode" "HI")])
15955
15956 (define_insn "*strmovqi_1"
15957 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15958 (mem:QI (match_operand:P 3 "register_operand" "1")))
15959 (set (match_operand:P 0 "register_operand" "=D")
15960 (plus:P (match_dup 2)
15961 (const_int 1)))
15962 (set (match_operand:P 1 "register_operand" "=S")
15963 (plus:P (match_dup 3)
15964 (const_int 1)))]
15965 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15966 "%^movsb"
15967 [(set_attr "type" "str")
15968 (set_attr "memory" "both")
15969 (set (attr "prefix_rex")
15970 (if_then_else
15971 (match_test "<P:MODE>mode == DImode")
15972 (const_string "0")
15973 (const_string "*")))
15974 (set_attr "mode" "QI")])
15975
15976 (define_expand "rep_mov"
15977 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15978 (set (match_operand 0 "register_operand")
15979 (match_operand 5))
15980 (set (match_operand 2 "register_operand")
15981 (match_operand 6))
15982 (set (match_operand 1 "memory_operand")
15983 (match_operand 3 "memory_operand"))
15984 (use (match_dup 4))])]
15985 ""
15986 "ix86_current_function_needs_cld = 1;")
15987
15988 (define_insn "*rep_movdi_rex64"
15989 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15990 (set (match_operand:P 0 "register_operand" "=D")
15991 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15992 (const_int 3))
15993 (match_operand:P 3 "register_operand" "0")))
15994 (set (match_operand:P 1 "register_operand" "=S")
15995 (plus:P (ashift:P (match_dup 5) (const_int 3))
15996 (match_operand:P 4 "register_operand" "1")))
15997 (set (mem:BLK (match_dup 3))
15998 (mem:BLK (match_dup 4)))
15999 (use (match_dup 5))]
16000 "TARGET_64BIT
16001 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16002 "%^rep{%;} movsq"
16003 [(set_attr "type" "str")
16004 (set_attr "prefix_rep" "1")
16005 (set_attr "memory" "both")
16006 (set_attr "mode" "DI")])
16007
16008 (define_insn "*rep_movsi"
16009 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16010 (set (match_operand:P 0 "register_operand" "=D")
16011 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16012 (const_int 2))
16013 (match_operand:P 3 "register_operand" "0")))
16014 (set (match_operand:P 1 "register_operand" "=S")
16015 (plus:P (ashift:P (match_dup 5) (const_int 2))
16016 (match_operand:P 4 "register_operand" "1")))
16017 (set (mem:BLK (match_dup 3))
16018 (mem:BLK (match_dup 4)))
16019 (use (match_dup 5))]
16020 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16021 "%^rep{%;} movs{l|d}"
16022 [(set_attr "type" "str")
16023 (set_attr "prefix_rep" "1")
16024 (set_attr "memory" "both")
16025 (set_attr "mode" "SI")])
16026
16027 (define_insn "*rep_movqi"
16028 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16029 (set (match_operand:P 0 "register_operand" "=D")
16030 (plus:P (match_operand:P 3 "register_operand" "0")
16031 (match_operand:P 5 "register_operand" "2")))
16032 (set (match_operand:P 1 "register_operand" "=S")
16033 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16034 (set (mem:BLK (match_dup 3))
16035 (mem:BLK (match_dup 4)))
16036 (use (match_dup 5))]
16037 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16038 "%^rep{%;} movsb"
16039 [(set_attr "type" "str")
16040 (set_attr "prefix_rep" "1")
16041 (set_attr "memory" "both")
16042 (set_attr "mode" "QI")])
16043
16044 (define_expand "setmem<mode>"
16045 [(use (match_operand:BLK 0 "memory_operand"))
16046 (use (match_operand:SWI48 1 "nonmemory_operand"))
16047 (use (match_operand:QI 2 "nonmemory_operand"))
16048 (use (match_operand 3 "const_int_operand"))
16049 (use (match_operand:SI 4 "const_int_operand"))
16050 (use (match_operand:SI 5 "const_int_operand"))
16051 (use (match_operand:SI 6 ""))
16052 (use (match_operand:SI 7 ""))
16053 (use (match_operand:SI 8 ""))]
16054 ""
16055 {
16056 if (ix86_expand_set_or_movmem (operands[0], NULL,
16057 operands[1], operands[2],
16058 operands[3], operands[4],
16059 operands[5], operands[6],
16060 operands[7], operands[8], true))
16061 DONE;
16062 else
16063 FAIL;
16064 })
16065
16066 ;; Most CPUs don't like single string operations
16067 ;; Handle this case here to simplify previous expander.
16068
16069 (define_expand "strset"
16070 [(set (match_operand 1 "memory_operand")
16071 (match_operand 2 "register_operand"))
16072 (parallel [(set (match_operand 0 "register_operand")
16073 (match_dup 3))
16074 (clobber (reg:CC FLAGS_REG))])]
16075 ""
16076 {
16077 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16078 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16079
16080 /* If .md ever supports :P for Pmode, this can be directly
16081 in the pattern above. */
16082 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16083 GEN_INT (GET_MODE_SIZE (GET_MODE
16084 (operands[2]))));
16085 /* Can't use this if the user has appropriated eax or edi. */
16086 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16087 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16088 {
16089 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16090 operands[3]));
16091 DONE;
16092 }
16093 })
16094
16095 (define_expand "strset_singleop"
16096 [(parallel [(set (match_operand 1 "memory_operand")
16097 (match_operand 2 "register_operand"))
16098 (set (match_operand 0 "register_operand")
16099 (match_operand 3))
16100 (unspec [(const_int 0)] UNSPEC_STOS)])]
16101 ""
16102 "ix86_current_function_needs_cld = 1;")
16103
16104 (define_insn "*strsetdi_rex_1"
16105 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16106 (match_operand:DI 2 "register_operand" "a"))
16107 (set (match_operand:P 0 "register_operand" "=D")
16108 (plus:P (match_dup 1)
16109 (const_int 8)))
16110 (unspec [(const_int 0)] UNSPEC_STOS)]
16111 "TARGET_64BIT
16112 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16113 "%^stosq"
16114 [(set_attr "type" "str")
16115 (set_attr "memory" "store")
16116 (set_attr "mode" "DI")])
16117
16118 (define_insn "*strsetsi_1"
16119 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16120 (match_operand:SI 2 "register_operand" "a"))
16121 (set (match_operand:P 0 "register_operand" "=D")
16122 (plus:P (match_dup 1)
16123 (const_int 4)))
16124 (unspec [(const_int 0)] UNSPEC_STOS)]
16125 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16126 "%^stos{l|d}"
16127 [(set_attr "type" "str")
16128 (set_attr "memory" "store")
16129 (set_attr "mode" "SI")])
16130
16131 (define_insn "*strsethi_1"
16132 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16133 (match_operand:HI 2 "register_operand" "a"))
16134 (set (match_operand:P 0 "register_operand" "=D")
16135 (plus:P (match_dup 1)
16136 (const_int 2)))
16137 (unspec [(const_int 0)] UNSPEC_STOS)]
16138 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16139 "%^stosw"
16140 [(set_attr "type" "str")
16141 (set_attr "memory" "store")
16142 (set_attr "mode" "HI")])
16143
16144 (define_insn "*strsetqi_1"
16145 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16146 (match_operand:QI 2 "register_operand" "a"))
16147 (set (match_operand:P 0 "register_operand" "=D")
16148 (plus:P (match_dup 1)
16149 (const_int 1)))
16150 (unspec [(const_int 0)] UNSPEC_STOS)]
16151 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16152 "%^stosb"
16153 [(set_attr "type" "str")
16154 (set_attr "memory" "store")
16155 (set (attr "prefix_rex")
16156 (if_then_else
16157 (match_test "<P:MODE>mode == DImode")
16158 (const_string "0")
16159 (const_string "*")))
16160 (set_attr "mode" "QI")])
16161
16162 (define_expand "rep_stos"
16163 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16164 (set (match_operand 0 "register_operand")
16165 (match_operand 4))
16166 (set (match_operand 2 "memory_operand") (const_int 0))
16167 (use (match_operand 3 "register_operand"))
16168 (use (match_dup 1))])]
16169 ""
16170 "ix86_current_function_needs_cld = 1;")
16171
16172 (define_insn "*rep_stosdi_rex64"
16173 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16174 (set (match_operand:P 0 "register_operand" "=D")
16175 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16176 (const_int 3))
16177 (match_operand:P 3 "register_operand" "0")))
16178 (set (mem:BLK (match_dup 3))
16179 (const_int 0))
16180 (use (match_operand:DI 2 "register_operand" "a"))
16181 (use (match_dup 4))]
16182 "TARGET_64BIT
16183 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16184 "%^rep{%;} stosq"
16185 [(set_attr "type" "str")
16186 (set_attr "prefix_rep" "1")
16187 (set_attr "memory" "store")
16188 (set_attr "mode" "DI")])
16189
16190 (define_insn "*rep_stossi"
16191 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16192 (set (match_operand:P 0 "register_operand" "=D")
16193 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16194 (const_int 2))
16195 (match_operand:P 3 "register_operand" "0")))
16196 (set (mem:BLK (match_dup 3))
16197 (const_int 0))
16198 (use (match_operand:SI 2 "register_operand" "a"))
16199 (use (match_dup 4))]
16200 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16201 "%^rep{%;} stos{l|d}"
16202 [(set_attr "type" "str")
16203 (set_attr "prefix_rep" "1")
16204 (set_attr "memory" "store")
16205 (set_attr "mode" "SI")])
16206
16207 (define_insn "*rep_stosqi"
16208 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16209 (set (match_operand:P 0 "register_operand" "=D")
16210 (plus:P (match_operand:P 3 "register_operand" "0")
16211 (match_operand:P 4 "register_operand" "1")))
16212 (set (mem:BLK (match_dup 3))
16213 (const_int 0))
16214 (use (match_operand:QI 2 "register_operand" "a"))
16215 (use (match_dup 4))]
16216 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16217 "%^rep{%;} stosb"
16218 [(set_attr "type" "str")
16219 (set_attr "prefix_rep" "1")
16220 (set_attr "memory" "store")
16221 (set (attr "prefix_rex")
16222 (if_then_else
16223 (match_test "<P:MODE>mode == DImode")
16224 (const_string "0")
16225 (const_string "*")))
16226 (set_attr "mode" "QI")])
16227
16228 (define_expand "cmpstrnsi"
16229 [(set (match_operand:SI 0 "register_operand")
16230 (compare:SI (match_operand:BLK 1 "general_operand")
16231 (match_operand:BLK 2 "general_operand")))
16232 (use (match_operand 3 "general_operand"))
16233 (use (match_operand 4 "immediate_operand"))]
16234 ""
16235 {
16236 rtx addr1, addr2, out, outlow, count, countreg, align;
16237
16238 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16239 FAIL;
16240
16241 /* Can't use this if the user has appropriated ecx, esi or edi. */
16242 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16243 FAIL;
16244
16245 out = operands[0];
16246 if (!REG_P (out))
16247 out = gen_reg_rtx (SImode);
16248
16249 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16250 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16251 if (addr1 != XEXP (operands[1], 0))
16252 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16253 if (addr2 != XEXP (operands[2], 0))
16254 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16255
16256 count = operands[3];
16257 countreg = ix86_zero_extend_to_Pmode (count);
16258
16259 /* %%% Iff we are testing strict equality, we can use known alignment
16260 to good advantage. This may be possible with combine, particularly
16261 once cc0 is dead. */
16262 align = operands[4];
16263
16264 if (CONST_INT_P (count))
16265 {
16266 if (INTVAL (count) == 0)
16267 {
16268 emit_move_insn (operands[0], const0_rtx);
16269 DONE;
16270 }
16271 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16272 operands[1], operands[2]));
16273 }
16274 else
16275 {
16276 rtx (*gen_cmp) (rtx, rtx);
16277
16278 gen_cmp = (TARGET_64BIT
16279 ? gen_cmpdi_1 : gen_cmpsi_1);
16280
16281 emit_insn (gen_cmp (countreg, countreg));
16282 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16283 operands[1], operands[2]));
16284 }
16285
16286 outlow = gen_lowpart (QImode, out);
16287 emit_insn (gen_cmpintqi (outlow));
16288 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16289
16290 if (operands[0] != out)
16291 emit_move_insn (operands[0], out);
16292
16293 DONE;
16294 })
16295
16296 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16297
16298 (define_expand "cmpintqi"
16299 [(set (match_dup 1)
16300 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16301 (set (match_dup 2)
16302 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16303 (parallel [(set (match_operand:QI 0 "register_operand")
16304 (minus:QI (match_dup 1)
16305 (match_dup 2)))
16306 (clobber (reg:CC FLAGS_REG))])]
16307 ""
16308 {
16309 operands[1] = gen_reg_rtx (QImode);
16310 operands[2] = gen_reg_rtx (QImode);
16311 })
16312
16313 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16314 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16315
16316 (define_expand "cmpstrnqi_nz_1"
16317 [(parallel [(set (reg:CC FLAGS_REG)
16318 (compare:CC (match_operand 4 "memory_operand")
16319 (match_operand 5 "memory_operand")))
16320 (use (match_operand 2 "register_operand"))
16321 (use (match_operand:SI 3 "immediate_operand"))
16322 (clobber (match_operand 0 "register_operand"))
16323 (clobber (match_operand 1 "register_operand"))
16324 (clobber (match_dup 2))])]
16325 ""
16326 "ix86_current_function_needs_cld = 1;")
16327
16328 (define_insn "*cmpstrnqi_nz_1"
16329 [(set (reg:CC FLAGS_REG)
16330 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16331 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16332 (use (match_operand:P 6 "register_operand" "2"))
16333 (use (match_operand:SI 3 "immediate_operand" "i"))
16334 (clobber (match_operand:P 0 "register_operand" "=S"))
16335 (clobber (match_operand:P 1 "register_operand" "=D"))
16336 (clobber (match_operand:P 2 "register_operand" "=c"))]
16337 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16338 "%^repz{%;} cmpsb"
16339 [(set_attr "type" "str")
16340 (set_attr "mode" "QI")
16341 (set (attr "prefix_rex")
16342 (if_then_else
16343 (match_test "<P:MODE>mode == DImode")
16344 (const_string "0")
16345 (const_string "*")))
16346 (set_attr "prefix_rep" "1")])
16347
16348 ;; The same, but the count is not known to not be zero.
16349
16350 (define_expand "cmpstrnqi_1"
16351 [(parallel [(set (reg:CC FLAGS_REG)
16352 (if_then_else:CC (ne (match_operand 2 "register_operand")
16353 (const_int 0))
16354 (compare:CC (match_operand 4 "memory_operand")
16355 (match_operand 5 "memory_operand"))
16356 (const_int 0)))
16357 (use (match_operand:SI 3 "immediate_operand"))
16358 (use (reg:CC FLAGS_REG))
16359 (clobber (match_operand 0 "register_operand"))
16360 (clobber (match_operand 1 "register_operand"))
16361 (clobber (match_dup 2))])]
16362 ""
16363 "ix86_current_function_needs_cld = 1;")
16364
16365 (define_insn "*cmpstrnqi_1"
16366 [(set (reg:CC FLAGS_REG)
16367 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16368 (const_int 0))
16369 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16370 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16371 (const_int 0)))
16372 (use (match_operand:SI 3 "immediate_operand" "i"))
16373 (use (reg:CC FLAGS_REG))
16374 (clobber (match_operand:P 0 "register_operand" "=S"))
16375 (clobber (match_operand:P 1 "register_operand" "=D"))
16376 (clobber (match_operand:P 2 "register_operand" "=c"))]
16377 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16378 "%^repz{%;} cmpsb"
16379 [(set_attr "type" "str")
16380 (set_attr "mode" "QI")
16381 (set (attr "prefix_rex")
16382 (if_then_else
16383 (match_test "<P:MODE>mode == DImode")
16384 (const_string "0")
16385 (const_string "*")))
16386 (set_attr "prefix_rep" "1")])
16387
16388 (define_expand "strlen<mode>"
16389 [(set (match_operand:P 0 "register_operand")
16390 (unspec:P [(match_operand:BLK 1 "general_operand")
16391 (match_operand:QI 2 "immediate_operand")
16392 (match_operand 3 "immediate_operand")]
16393 UNSPEC_SCAS))]
16394 ""
16395 {
16396 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16397 DONE;
16398 else
16399 FAIL;
16400 })
16401
16402 (define_expand "strlenqi_1"
16403 [(parallel [(set (match_operand 0 "register_operand")
16404 (match_operand 2))
16405 (clobber (match_operand 1 "register_operand"))
16406 (clobber (reg:CC FLAGS_REG))])]
16407 ""
16408 "ix86_current_function_needs_cld = 1;")
16409
16410 (define_insn "*strlenqi_1"
16411 [(set (match_operand:P 0 "register_operand" "=&c")
16412 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16413 (match_operand:QI 2 "register_operand" "a")
16414 (match_operand:P 3 "immediate_operand" "i")
16415 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16416 (clobber (match_operand:P 1 "register_operand" "=D"))
16417 (clobber (reg:CC FLAGS_REG))]
16418 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16419 "%^repnz{%;} scasb"
16420 [(set_attr "type" "str")
16421 (set_attr "mode" "QI")
16422 (set (attr "prefix_rex")
16423 (if_then_else
16424 (match_test "<P:MODE>mode == DImode")
16425 (const_string "0")
16426 (const_string "*")))
16427 (set_attr "prefix_rep" "1")])
16428
16429 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16430 ;; handled in combine, but it is not currently up to the task.
16431 ;; When used for their truth value, the cmpstrn* expanders generate
16432 ;; code like this:
16433 ;;
16434 ;; repz cmpsb
16435 ;; seta %al
16436 ;; setb %dl
16437 ;; cmpb %al, %dl
16438 ;; jcc label
16439 ;;
16440 ;; The intermediate three instructions are unnecessary.
16441
16442 ;; This one handles cmpstrn*_nz_1...
16443 (define_peephole2
16444 [(parallel[
16445 (set (reg:CC FLAGS_REG)
16446 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16447 (mem:BLK (match_operand 5 "register_operand"))))
16448 (use (match_operand 6 "register_operand"))
16449 (use (match_operand:SI 3 "immediate_operand"))
16450 (clobber (match_operand 0 "register_operand"))
16451 (clobber (match_operand 1 "register_operand"))
16452 (clobber (match_operand 2 "register_operand"))])
16453 (set (match_operand:QI 7 "register_operand")
16454 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16455 (set (match_operand:QI 8 "register_operand")
16456 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16457 (set (reg FLAGS_REG)
16458 (compare (match_dup 7) (match_dup 8)))
16459 ]
16460 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16461 [(parallel[
16462 (set (reg:CC FLAGS_REG)
16463 (compare:CC (mem:BLK (match_dup 4))
16464 (mem:BLK (match_dup 5))))
16465 (use (match_dup 6))
16466 (use (match_dup 3))
16467 (clobber (match_dup 0))
16468 (clobber (match_dup 1))
16469 (clobber (match_dup 2))])])
16470
16471 ;; ...and this one handles cmpstrn*_1.
16472 (define_peephole2
16473 [(parallel[
16474 (set (reg:CC FLAGS_REG)
16475 (if_then_else:CC (ne (match_operand 6 "register_operand")
16476 (const_int 0))
16477 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16478 (mem:BLK (match_operand 5 "register_operand")))
16479 (const_int 0)))
16480 (use (match_operand:SI 3 "immediate_operand"))
16481 (use (reg:CC FLAGS_REG))
16482 (clobber (match_operand 0 "register_operand"))
16483 (clobber (match_operand 1 "register_operand"))
16484 (clobber (match_operand 2 "register_operand"))])
16485 (set (match_operand:QI 7 "register_operand")
16486 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16487 (set (match_operand:QI 8 "register_operand")
16488 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16489 (set (reg FLAGS_REG)
16490 (compare (match_dup 7) (match_dup 8)))
16491 ]
16492 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16493 [(parallel[
16494 (set (reg:CC FLAGS_REG)
16495 (if_then_else:CC (ne (match_dup 6)
16496 (const_int 0))
16497 (compare:CC (mem:BLK (match_dup 4))
16498 (mem:BLK (match_dup 5)))
16499 (const_int 0)))
16500 (use (match_dup 3))
16501 (use (reg:CC FLAGS_REG))
16502 (clobber (match_dup 0))
16503 (clobber (match_dup 1))
16504 (clobber (match_dup 2))])])
16505 \f
16506 ;; Conditional move instructions.
16507
16508 (define_expand "mov<mode>cc"
16509 [(set (match_operand:SWIM 0 "register_operand")
16510 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16511 (match_operand:SWIM 2 "<general_operand>")
16512 (match_operand:SWIM 3 "<general_operand>")))]
16513 ""
16514 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16515
16516 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16517 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16518 ;; So just document what we're doing explicitly.
16519
16520 (define_expand "x86_mov<mode>cc_0_m1"
16521 [(parallel
16522 [(set (match_operand:SWI48 0 "register_operand")
16523 (if_then_else:SWI48
16524 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16525 [(match_operand 1 "flags_reg_operand")
16526 (const_int 0)])
16527 (const_int -1)
16528 (const_int 0)))
16529 (clobber (reg:CC FLAGS_REG))])])
16530
16531 (define_insn "*x86_mov<mode>cc_0_m1"
16532 [(set (match_operand:SWI48 0 "register_operand" "=r")
16533 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16534 [(reg FLAGS_REG) (const_int 0)])
16535 (const_int -1)
16536 (const_int 0)))
16537 (clobber (reg:CC FLAGS_REG))]
16538 ""
16539 "sbb{<imodesuffix>}\t%0, %0"
16540 ; Since we don't have the proper number of operands for an alu insn,
16541 ; fill in all the blanks.
16542 [(set_attr "type" "alu")
16543 (set_attr "use_carry" "1")
16544 (set_attr "pent_pair" "pu")
16545 (set_attr "memory" "none")
16546 (set_attr "imm_disp" "false")
16547 (set_attr "mode" "<MODE>")
16548 (set_attr "length_immediate" "0")])
16549
16550 (define_insn "*x86_mov<mode>cc_0_m1_se"
16551 [(set (match_operand:SWI48 0 "register_operand" "=r")
16552 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16553 [(reg FLAGS_REG) (const_int 0)])
16554 (const_int 1)
16555 (const_int 0)))
16556 (clobber (reg:CC FLAGS_REG))]
16557 ""
16558 "sbb{<imodesuffix>}\t%0, %0"
16559 [(set_attr "type" "alu")
16560 (set_attr "use_carry" "1")
16561 (set_attr "pent_pair" "pu")
16562 (set_attr "memory" "none")
16563 (set_attr "imm_disp" "false")
16564 (set_attr "mode" "<MODE>")
16565 (set_attr "length_immediate" "0")])
16566
16567 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16568 [(set (match_operand:SWI48 0 "register_operand" "=r")
16569 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16570 [(reg FLAGS_REG) (const_int 0)])))
16571 (clobber (reg:CC FLAGS_REG))]
16572 ""
16573 "sbb{<imodesuffix>}\t%0, %0"
16574 [(set_attr "type" "alu")
16575 (set_attr "use_carry" "1")
16576 (set_attr "pent_pair" "pu")
16577 (set_attr "memory" "none")
16578 (set_attr "imm_disp" "false")
16579 (set_attr "mode" "<MODE>")
16580 (set_attr "length_immediate" "0")])
16581
16582 (define_insn "*mov<mode>cc_noc"
16583 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16584 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16585 [(reg FLAGS_REG) (const_int 0)])
16586 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16587 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16588 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16589 "@
16590 cmov%O2%C1\t{%2, %0|%0, %2}
16591 cmov%O2%c1\t{%3, %0|%0, %3}"
16592 [(set_attr "type" "icmov")
16593 (set_attr "mode" "<MODE>")])
16594
16595 ;; Don't do conditional moves with memory inputs. This splitter helps
16596 ;; register starved x86_32 by forcing inputs into registers before reload.
16597 (define_split
16598 [(set (match_operand:SWI248 0 "register_operand")
16599 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16600 [(reg FLAGS_REG) (const_int 0)])
16601 (match_operand:SWI248 2 "nonimmediate_operand")
16602 (match_operand:SWI248 3 "nonimmediate_operand")))]
16603 "!TARGET_64BIT && TARGET_CMOVE
16604 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16605 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16606 && can_create_pseudo_p ()
16607 && optimize_insn_for_speed_p ()"
16608 [(set (match_dup 0)
16609 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16610 {
16611 if (MEM_P (operands[2]))
16612 operands[2] = force_reg (<MODE>mode, operands[2]);
16613 if (MEM_P (operands[3]))
16614 operands[3] = force_reg (<MODE>mode, operands[3]);
16615 })
16616
16617 (define_insn "*movqicc_noc"
16618 [(set (match_operand:QI 0 "register_operand" "=r,r")
16619 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16620 [(reg FLAGS_REG) (const_int 0)])
16621 (match_operand:QI 2 "register_operand" "r,0")
16622 (match_operand:QI 3 "register_operand" "0,r")))]
16623 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16624 "#"
16625 [(set_attr "type" "icmov")
16626 (set_attr "mode" "QI")])
16627
16628 (define_split
16629 [(set (match_operand:SWI12 0 "register_operand")
16630 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16631 [(reg FLAGS_REG) (const_int 0)])
16632 (match_operand:SWI12 2 "register_operand")
16633 (match_operand:SWI12 3 "register_operand")))]
16634 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16635 && reload_completed"
16636 [(set (match_dup 0)
16637 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16638 {
16639 operands[0] = gen_lowpart (SImode, operands[0]);
16640 operands[2] = gen_lowpart (SImode, operands[2]);
16641 operands[3] = gen_lowpart (SImode, operands[3]);
16642 })
16643
16644 ;; Don't do conditional moves with memory inputs
16645 (define_peephole2
16646 [(match_scratch:SWI248 2 "r")
16647 (set (match_operand:SWI248 0 "register_operand")
16648 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16649 [(reg FLAGS_REG) (const_int 0)])
16650 (match_dup 0)
16651 (match_operand:SWI248 3 "memory_operand")))]
16652 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16653 && optimize_insn_for_speed_p ()"
16654 [(set (match_dup 2) (match_dup 3))
16655 (set (match_dup 0)
16656 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16657
16658 (define_peephole2
16659 [(match_scratch:SWI248 2 "r")
16660 (set (match_operand:SWI248 0 "register_operand")
16661 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16662 [(reg FLAGS_REG) (const_int 0)])
16663 (match_operand:SWI248 3 "memory_operand")
16664 (match_dup 0)))]
16665 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16666 && optimize_insn_for_speed_p ()"
16667 [(set (match_dup 2) (match_dup 3))
16668 (set (match_dup 0)
16669 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16670
16671 (define_expand "mov<mode>cc"
16672 [(set (match_operand:X87MODEF 0 "register_operand")
16673 (if_then_else:X87MODEF
16674 (match_operand 1 "comparison_operator")
16675 (match_operand:X87MODEF 2 "register_operand")
16676 (match_operand:X87MODEF 3 "register_operand")))]
16677 "(TARGET_80387 && TARGET_CMOVE)
16678 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16679 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16680
16681 (define_insn "*movxfcc_1"
16682 [(set (match_operand:XF 0 "register_operand" "=f,f")
16683 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16684 [(reg FLAGS_REG) (const_int 0)])
16685 (match_operand:XF 2 "register_operand" "f,0")
16686 (match_operand:XF 3 "register_operand" "0,f")))]
16687 "TARGET_80387 && TARGET_CMOVE"
16688 "@
16689 fcmov%F1\t{%2, %0|%0, %2}
16690 fcmov%f1\t{%3, %0|%0, %3}"
16691 [(set_attr "type" "fcmov")
16692 (set_attr "mode" "XF")])
16693
16694 (define_insn "*movdfcc_1"
16695 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16696 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16697 [(reg FLAGS_REG) (const_int 0)])
16698 (match_operand:DF 2 "nonimmediate_operand"
16699 "f ,0,rm,0 ,rm,0")
16700 (match_operand:DF 3 "nonimmediate_operand"
16701 "0 ,f,0 ,rm,0, rm")))]
16702 "TARGET_80387 && TARGET_CMOVE
16703 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16704 "@
16705 fcmov%F1\t{%2, %0|%0, %2}
16706 fcmov%f1\t{%3, %0|%0, %3}
16707 #
16708 #
16709 cmov%O2%C1\t{%2, %0|%0, %2}
16710 cmov%O2%c1\t{%3, %0|%0, %3}"
16711 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16712 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16713 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16714
16715 (define_split
16716 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16717 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16718 [(reg FLAGS_REG) (const_int 0)])
16719 (match_operand:DF 2 "nonimmediate_operand")
16720 (match_operand:DF 3 "nonimmediate_operand")))]
16721 "!TARGET_64BIT && reload_completed"
16722 [(set (match_dup 2)
16723 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16724 (set (match_dup 3)
16725 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16726 {
16727 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16728 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16729 })
16730
16731 (define_insn "*movsfcc_1_387"
16732 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16733 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16734 [(reg FLAGS_REG) (const_int 0)])
16735 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16736 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16737 "TARGET_80387 && TARGET_CMOVE
16738 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16739 "@
16740 fcmov%F1\t{%2, %0|%0, %2}
16741 fcmov%f1\t{%3, %0|%0, %3}
16742 cmov%O2%C1\t{%2, %0|%0, %2}
16743 cmov%O2%c1\t{%3, %0|%0, %3}"
16744 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16745 (set_attr "mode" "SF,SF,SI,SI")])
16746
16747 ;; Don't do conditional moves with memory inputs. This splitter helps
16748 ;; register starved x86_32 by forcing inputs into registers before reload.
16749 (define_split
16750 [(set (match_operand:MODEF 0 "register_operand")
16751 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16752 [(reg FLAGS_REG) (const_int 0)])
16753 (match_operand:MODEF 2 "nonimmediate_operand")
16754 (match_operand:MODEF 3 "nonimmediate_operand")))]
16755 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16756 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16757 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16758 && can_create_pseudo_p ()
16759 && optimize_insn_for_speed_p ()"
16760 [(set (match_dup 0)
16761 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16762 {
16763 if (MEM_P (operands[2]))
16764 operands[2] = force_reg (<MODE>mode, operands[2]);
16765 if (MEM_P (operands[3]))
16766 operands[3] = force_reg (<MODE>mode, operands[3]);
16767 })
16768
16769 ;; Don't do conditional moves with memory inputs
16770 (define_peephole2
16771 [(match_scratch:MODEF 2 "r")
16772 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16773 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16774 [(reg FLAGS_REG) (const_int 0)])
16775 (match_dup 0)
16776 (match_operand:MODEF 3 "memory_operand")))]
16777 "(<MODE>mode != DFmode || TARGET_64BIT)
16778 && TARGET_80387 && TARGET_CMOVE
16779 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16780 && optimize_insn_for_speed_p ()"
16781 [(set (match_dup 2) (match_dup 3))
16782 (set (match_dup 0)
16783 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16784
16785 (define_peephole2
16786 [(match_scratch:MODEF 2 "r")
16787 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16788 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16789 [(reg FLAGS_REG) (const_int 0)])
16790 (match_operand:MODEF 3 "memory_operand")
16791 (match_dup 0)))]
16792 "(<MODE>mode != DFmode || TARGET_64BIT)
16793 && TARGET_80387 && TARGET_CMOVE
16794 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16795 && optimize_insn_for_speed_p ()"
16796 [(set (match_dup 2) (match_dup 3))
16797 (set (match_dup 0)
16798 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16799
16800 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16801 ;; the scalar versions to have only XMM registers as operands.
16802
16803 ;; XOP conditional move
16804 (define_insn "*xop_pcmov_<mode>"
16805 [(set (match_operand:MODEF 0 "register_operand" "=x")
16806 (if_then_else:MODEF
16807 (match_operand:MODEF 1 "register_operand" "x")
16808 (match_operand:MODEF 2 "register_operand" "x")
16809 (match_operand:MODEF 3 "register_operand" "x")))]
16810 "TARGET_XOP"
16811 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16812 [(set_attr "type" "sse4arg")])
16813
16814 ;; These versions of the min/max patterns are intentionally ignorant of
16815 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16816 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16817 ;; are undefined in this condition, we're certain this is correct.
16818
16819 (define_insn "<code><mode>3"
16820 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16821 (smaxmin:MODEF
16822 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16823 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16824 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16825 "@
16826 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16827 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16828 [(set_attr "isa" "noavx,avx")
16829 (set_attr "prefix" "orig,vex")
16830 (set_attr "type" "sseadd")
16831 (set_attr "mode" "<MODE>")])
16832
16833 ;; These versions of the min/max patterns implement exactly the operations
16834 ;; min = (op1 < op2 ? op1 : op2)
16835 ;; max = (!(op1 < op2) ? op1 : op2)
16836 ;; Their operands are not commutative, and thus they may be used in the
16837 ;; presence of -0.0 and NaN.
16838
16839 (define_int_iterator IEEE_MAXMIN
16840 [UNSPEC_IEEE_MAX
16841 UNSPEC_IEEE_MIN])
16842
16843 (define_int_attr ieee_maxmin
16844 [(UNSPEC_IEEE_MAX "max")
16845 (UNSPEC_IEEE_MIN "min")])
16846
16847 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16848 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16849 (unspec:MODEF
16850 [(match_operand:MODEF 1 "register_operand" "0,x")
16851 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16852 IEEE_MAXMIN))]
16853 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16854 "@
16855 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16856 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16857 [(set_attr "isa" "noavx,avx")
16858 (set_attr "prefix" "orig,vex")
16859 (set_attr "type" "sseadd")
16860 (set_attr "mode" "<MODE>")])
16861
16862 ;; Make two stack loads independent:
16863 ;; fld aa fld aa
16864 ;; fld %st(0) -> fld bb
16865 ;; fmul bb fmul %st(1), %st
16866 ;;
16867 ;; Actually we only match the last two instructions for simplicity.
16868 (define_peephole2
16869 [(set (match_operand 0 "fp_register_operand")
16870 (match_operand 1 "fp_register_operand"))
16871 (set (match_dup 0)
16872 (match_operator 2 "binary_fp_operator"
16873 [(match_dup 0)
16874 (match_operand 3 "memory_operand")]))]
16875 "REGNO (operands[0]) != REGNO (operands[1])"
16876 [(set (match_dup 0) (match_dup 3))
16877 (set (match_dup 0) (match_dup 4))]
16878
16879 ;; The % modifier is not operational anymore in peephole2's, so we have to
16880 ;; swap the operands manually in the case of addition and multiplication.
16881 {
16882 rtx op0, op1;
16883
16884 if (COMMUTATIVE_ARITH_P (operands[2]))
16885 op0 = operands[0], op1 = operands[1];
16886 else
16887 op0 = operands[1], op1 = operands[0];
16888
16889 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16890 GET_MODE (operands[2]),
16891 op0, op1);
16892 })
16893
16894 ;; Conditional addition patterns
16895 (define_expand "add<mode>cc"
16896 [(match_operand:SWI 0 "register_operand")
16897 (match_operand 1 "ordered_comparison_operator")
16898 (match_operand:SWI 2 "register_operand")
16899 (match_operand:SWI 3 "const_int_operand")]
16900 ""
16901 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16902 \f
16903 ;; Misc patterns (?)
16904
16905 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16906 ;; Otherwise there will be nothing to keep
16907 ;;
16908 ;; [(set (reg ebp) (reg esp))]
16909 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16910 ;; (clobber (eflags)]
16911 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16912 ;;
16913 ;; in proper program order.
16914
16915 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16916 [(set (match_operand:P 0 "register_operand" "=r,r")
16917 (plus:P (match_operand:P 1 "register_operand" "0,r")
16918 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16919 (clobber (reg:CC FLAGS_REG))
16920 (clobber (mem:BLK (scratch)))]
16921 ""
16922 {
16923 switch (get_attr_type (insn))
16924 {
16925 case TYPE_IMOV:
16926 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16927
16928 case TYPE_ALU:
16929 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16930 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16931 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16932
16933 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16934
16935 default:
16936 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16937 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16938 }
16939 }
16940 [(set (attr "type")
16941 (cond [(and (eq_attr "alternative" "0")
16942 (not (match_test "TARGET_OPT_AGU")))
16943 (const_string "alu")
16944 (match_operand:<MODE> 2 "const0_operand")
16945 (const_string "imov")
16946 ]
16947 (const_string "lea")))
16948 (set (attr "length_immediate")
16949 (cond [(eq_attr "type" "imov")
16950 (const_string "0")
16951 (and (eq_attr "type" "alu")
16952 (match_operand 2 "const128_operand"))
16953 (const_string "1")
16954 ]
16955 (const_string "*")))
16956 (set_attr "mode" "<MODE>")])
16957
16958 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16959 [(set (match_operand:P 0 "register_operand" "=r")
16960 (minus:P (match_operand:P 1 "register_operand" "0")
16961 (match_operand:P 2 "register_operand" "r")))
16962 (clobber (reg:CC FLAGS_REG))
16963 (clobber (mem:BLK (scratch)))]
16964 ""
16965 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16966 [(set_attr "type" "alu")
16967 (set_attr "mode" "<MODE>")])
16968
16969 (define_insn "allocate_stack_worker_probe_<mode>"
16970 [(set (match_operand:P 0 "register_operand" "=a")
16971 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16972 UNSPECV_STACK_PROBE))
16973 (clobber (reg:CC FLAGS_REG))]
16974 "ix86_target_stack_probe ()"
16975 "call\t___chkstk_ms"
16976 [(set_attr "type" "multi")
16977 (set_attr "length" "5")])
16978
16979 (define_expand "allocate_stack"
16980 [(match_operand 0 "register_operand")
16981 (match_operand 1 "general_operand")]
16982 "ix86_target_stack_probe ()"
16983 {
16984 rtx x;
16985
16986 #ifndef CHECK_STACK_LIMIT
16987 #define CHECK_STACK_LIMIT 0
16988 #endif
16989
16990 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16991 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16992 x = operands[1];
16993 else
16994 {
16995 rtx (*insn) (rtx, rtx);
16996
16997 x = copy_to_mode_reg (Pmode, operands[1]);
16998
16999 insn = (TARGET_64BIT
17000 ? gen_allocate_stack_worker_probe_di
17001 : gen_allocate_stack_worker_probe_si);
17002
17003 emit_insn (insn (x, x));
17004 }
17005
17006 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17007 stack_pointer_rtx, 0, OPTAB_DIRECT);
17008
17009 if (x != stack_pointer_rtx)
17010 emit_move_insn (stack_pointer_rtx, x);
17011
17012 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17013 DONE;
17014 })
17015
17016 ;; Use IOR for stack probes, this is shorter.
17017 (define_expand "probe_stack"
17018 [(match_operand 0 "memory_operand")]
17019 ""
17020 {
17021 rtx (*gen_ior3) (rtx, rtx, rtx);
17022
17023 gen_ior3 = (GET_MODE (operands[0]) == DImode
17024 ? gen_iordi3 : gen_iorsi3);
17025
17026 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17027 DONE;
17028 })
17029
17030 (define_insn "adjust_stack_and_probe<mode>"
17031 [(set (match_operand:P 0 "register_operand" "=r")
17032 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17033 UNSPECV_PROBE_STACK_RANGE))
17034 (set (reg:P SP_REG)
17035 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17036 (clobber (reg:CC FLAGS_REG))
17037 (clobber (mem:BLK (scratch)))]
17038 ""
17039 "* return output_adjust_stack_and_probe (operands[0]);"
17040 [(set_attr "type" "multi")])
17041
17042 (define_insn "probe_stack_range<mode>"
17043 [(set (match_operand:P 0 "register_operand" "=r")
17044 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17045 (match_operand:P 2 "const_int_operand" "n")]
17046 UNSPECV_PROBE_STACK_RANGE))
17047 (clobber (reg:CC FLAGS_REG))]
17048 ""
17049 "* return output_probe_stack_range (operands[0], operands[2]);"
17050 [(set_attr "type" "multi")])
17051
17052 (define_expand "builtin_setjmp_receiver"
17053 [(label_ref (match_operand 0))]
17054 "!TARGET_64BIT && flag_pic"
17055 {
17056 #if TARGET_MACHO
17057 if (TARGET_MACHO)
17058 {
17059 rtx xops[3];
17060 rtx_code_label *label_rtx = gen_label_rtx ();
17061 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17062 xops[0] = xops[1] = pic_offset_table_rtx;
17063 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17064 ix86_expand_binary_operator (MINUS, SImode, xops);
17065 }
17066 else
17067 #endif
17068 emit_insn (gen_set_got (pic_offset_table_rtx));
17069 DONE;
17070 })
17071
17072 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17073 ;; Do not split instructions with mask registers.
17074 (define_split
17075 [(set (match_operand 0 "general_reg_operand")
17076 (match_operator 3 "promotable_binary_operator"
17077 [(match_operand 1 "general_reg_operand")
17078 (match_operand 2 "aligned_operand")]))
17079 (clobber (reg:CC FLAGS_REG))]
17080 "! TARGET_PARTIAL_REG_STALL && reload_completed
17081 && ((GET_MODE (operands[0]) == HImode
17082 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17083 /* ??? next two lines just !satisfies_constraint_K (...) */
17084 || !CONST_INT_P (operands[2])
17085 || satisfies_constraint_K (operands[2])))
17086 || (GET_MODE (operands[0]) == QImode
17087 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17088 [(parallel [(set (match_dup 0)
17089 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17090 (clobber (reg:CC FLAGS_REG))])]
17091 {
17092 operands[0] = gen_lowpart (SImode, operands[0]);
17093 operands[1] = gen_lowpart (SImode, operands[1]);
17094 if (GET_CODE (operands[3]) != ASHIFT)
17095 operands[2] = gen_lowpart (SImode, operands[2]);
17096 PUT_MODE (operands[3], SImode);
17097 })
17098
17099 ; Promote the QImode tests, as i386 has encoding of the AND
17100 ; instruction with 32-bit sign-extended immediate and thus the
17101 ; instruction size is unchanged, except in the %eax case for
17102 ; which it is increased by one byte, hence the ! optimize_size.
17103 (define_split
17104 [(set (match_operand 0 "flags_reg_operand")
17105 (match_operator 2 "compare_operator"
17106 [(and (match_operand 3 "aligned_operand")
17107 (match_operand 4 "const_int_operand"))
17108 (const_int 0)]))
17109 (set (match_operand 1 "register_operand")
17110 (and (match_dup 3) (match_dup 4)))]
17111 "! TARGET_PARTIAL_REG_STALL && reload_completed
17112 && optimize_insn_for_speed_p ()
17113 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17114 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17115 /* Ensure that the operand will remain sign-extended immediate. */
17116 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17117 [(parallel [(set (match_dup 0)
17118 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17119 (const_int 0)]))
17120 (set (match_dup 1)
17121 (and:SI (match_dup 3) (match_dup 4)))])]
17122 {
17123 operands[4]
17124 = gen_int_mode (INTVAL (operands[4])
17125 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17126 operands[1] = gen_lowpart (SImode, operands[1]);
17127 operands[3] = gen_lowpart (SImode, operands[3]);
17128 })
17129
17130 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17131 ; the TEST instruction with 32-bit sign-extended immediate and thus
17132 ; the instruction size would at least double, which is not what we
17133 ; want even with ! optimize_size.
17134 (define_split
17135 [(set (match_operand 0 "flags_reg_operand")
17136 (match_operator 1 "compare_operator"
17137 [(and (match_operand:HI 2 "aligned_operand")
17138 (match_operand:HI 3 "const_int_operand"))
17139 (const_int 0)]))]
17140 "! TARGET_PARTIAL_REG_STALL && reload_completed
17141 && ! TARGET_FAST_PREFIX
17142 && optimize_insn_for_speed_p ()
17143 /* Ensure that the operand will remain sign-extended immediate. */
17144 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17145 [(set (match_dup 0)
17146 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17147 (const_int 0)]))]
17148 {
17149 operands[3]
17150 = gen_int_mode (INTVAL (operands[3])
17151 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17152 operands[2] = gen_lowpart (SImode, operands[2]);
17153 })
17154
17155 (define_split
17156 [(set (match_operand 0 "register_operand")
17157 (neg (match_operand 1 "register_operand")))
17158 (clobber (reg:CC FLAGS_REG))]
17159 "! TARGET_PARTIAL_REG_STALL && reload_completed
17160 && (GET_MODE (operands[0]) == HImode
17161 || (GET_MODE (operands[0]) == QImode
17162 && (TARGET_PROMOTE_QImode
17163 || optimize_insn_for_size_p ())))"
17164 [(parallel [(set (match_dup 0)
17165 (neg:SI (match_dup 1)))
17166 (clobber (reg:CC FLAGS_REG))])]
17167 {
17168 operands[0] = gen_lowpart (SImode, operands[0]);
17169 operands[1] = gen_lowpart (SImode, operands[1]);
17170 })
17171
17172 ;; Do not split instructions with mask regs.
17173 (define_split
17174 [(set (match_operand 0 "general_reg_operand")
17175 (not (match_operand 1 "general_reg_operand")))]
17176 "! TARGET_PARTIAL_REG_STALL && reload_completed
17177 && (GET_MODE (operands[0]) == HImode
17178 || (GET_MODE (operands[0]) == QImode
17179 && (TARGET_PROMOTE_QImode
17180 || optimize_insn_for_size_p ())))"
17181 [(set (match_dup 0)
17182 (not:SI (match_dup 1)))]
17183 {
17184 operands[0] = gen_lowpart (SImode, operands[0]);
17185 operands[1] = gen_lowpart (SImode, operands[1]);
17186 })
17187 \f
17188 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17189 ;; transform a complex memory operation into two memory to register operations.
17190
17191 ;; Don't push memory operands
17192 (define_peephole2
17193 [(set (match_operand:SWI 0 "push_operand")
17194 (match_operand:SWI 1 "memory_operand"))
17195 (match_scratch:SWI 2 "<r>")]
17196 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17197 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17198 [(set (match_dup 2) (match_dup 1))
17199 (set (match_dup 0) (match_dup 2))])
17200
17201 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17202 ;; SImode pushes.
17203 (define_peephole2
17204 [(set (match_operand:SF 0 "push_operand")
17205 (match_operand:SF 1 "memory_operand"))
17206 (match_scratch:SF 2 "r")]
17207 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17208 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17209 [(set (match_dup 2) (match_dup 1))
17210 (set (match_dup 0) (match_dup 2))])
17211
17212 ;; Don't move an immediate directly to memory when the instruction
17213 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17214 (define_peephole2
17215 [(match_scratch:SWI124 1 "<r>")
17216 (set (match_operand:SWI124 0 "memory_operand")
17217 (const_int 0))]
17218 "optimize_insn_for_speed_p ()
17219 && ((<MODE>mode == HImode
17220 && TARGET_LCP_STALL)
17221 || (!TARGET_USE_MOV0
17222 && TARGET_SPLIT_LONG_MOVES
17223 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17224 && peep2_regno_dead_p (0, FLAGS_REG)"
17225 [(parallel [(set (match_dup 2) (const_int 0))
17226 (clobber (reg:CC FLAGS_REG))])
17227 (set (match_dup 0) (match_dup 1))]
17228 "operands[2] = gen_lowpart (SImode, operands[1]);")
17229
17230 (define_peephole2
17231 [(match_scratch:SWI124 2 "<r>")
17232 (set (match_operand:SWI124 0 "memory_operand")
17233 (match_operand:SWI124 1 "immediate_operand"))]
17234 "optimize_insn_for_speed_p ()
17235 && ((<MODE>mode == HImode
17236 && TARGET_LCP_STALL)
17237 || (TARGET_SPLIT_LONG_MOVES
17238 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17239 [(set (match_dup 2) (match_dup 1))
17240 (set (match_dup 0) (match_dup 2))])
17241
17242 ;; Don't compare memory with zero, load and use a test instead.
17243 (define_peephole2
17244 [(set (match_operand 0 "flags_reg_operand")
17245 (match_operator 1 "compare_operator"
17246 [(match_operand:SI 2 "memory_operand")
17247 (const_int 0)]))
17248 (match_scratch:SI 3 "r")]
17249 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17250 [(set (match_dup 3) (match_dup 2))
17251 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17252
17253 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17254 ;; Don't split NOTs with a displacement operand, because resulting XOR
17255 ;; will not be pairable anyway.
17256 ;;
17257 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17258 ;; represented using a modRM byte. The XOR replacement is long decoded,
17259 ;; so this split helps here as well.
17260 ;;
17261 ;; Note: Can't do this as a regular split because we can't get proper
17262 ;; lifetime information then.
17263
17264 (define_peephole2
17265 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17266 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17267 "optimize_insn_for_speed_p ()
17268 && ((TARGET_NOT_UNPAIRABLE
17269 && (!MEM_P (operands[0])
17270 || !memory_displacement_operand (operands[0], <MODE>mode)))
17271 || (TARGET_NOT_VECTORMODE
17272 && long_memory_operand (operands[0], <MODE>mode)))
17273 && peep2_regno_dead_p (0, FLAGS_REG)"
17274 [(parallel [(set (match_dup 0)
17275 (xor:SWI124 (match_dup 1) (const_int -1)))
17276 (clobber (reg:CC FLAGS_REG))])])
17277
17278 ;; Non pairable "test imm, reg" instructions can be translated to
17279 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17280 ;; byte opcode instead of two, have a short form for byte operands),
17281 ;; so do it for other CPUs as well. Given that the value was dead,
17282 ;; this should not create any new dependencies. Pass on the sub-word
17283 ;; versions if we're concerned about partial register stalls.
17284
17285 (define_peephole2
17286 [(set (match_operand 0 "flags_reg_operand")
17287 (match_operator 1 "compare_operator"
17288 [(and:SI (match_operand:SI 2 "register_operand")
17289 (match_operand:SI 3 "immediate_operand"))
17290 (const_int 0)]))]
17291 "ix86_match_ccmode (insn, CCNOmode)
17292 && (true_regnum (operands[2]) != AX_REG
17293 || satisfies_constraint_K (operands[3]))
17294 && peep2_reg_dead_p (1, operands[2])"
17295 [(parallel
17296 [(set (match_dup 0)
17297 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17298 (const_int 0)]))
17299 (set (match_dup 2)
17300 (and:SI (match_dup 2) (match_dup 3)))])])
17301
17302 ;; We don't need to handle HImode case, because it will be promoted to SImode
17303 ;; on ! TARGET_PARTIAL_REG_STALL
17304
17305 (define_peephole2
17306 [(set (match_operand 0 "flags_reg_operand")
17307 (match_operator 1 "compare_operator"
17308 [(and:QI (match_operand:QI 2 "register_operand")
17309 (match_operand:QI 3 "immediate_operand"))
17310 (const_int 0)]))]
17311 "! TARGET_PARTIAL_REG_STALL
17312 && ix86_match_ccmode (insn, CCNOmode)
17313 && true_regnum (operands[2]) != AX_REG
17314 && peep2_reg_dead_p (1, operands[2])"
17315 [(parallel
17316 [(set (match_dup 0)
17317 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17318 (const_int 0)]))
17319 (set (match_dup 2)
17320 (and:QI (match_dup 2) (match_dup 3)))])])
17321
17322 (define_peephole2
17323 [(set (match_operand 0 "flags_reg_operand")
17324 (match_operator 1 "compare_operator"
17325 [(and:SI
17326 (zero_extract:SI
17327 (match_operand 2 "ext_register_operand")
17328 (const_int 8)
17329 (const_int 8))
17330 (match_operand 3 "const_int_operand"))
17331 (const_int 0)]))]
17332 "! TARGET_PARTIAL_REG_STALL
17333 && ix86_match_ccmode (insn, CCNOmode)
17334 && true_regnum (operands[2]) != AX_REG
17335 && peep2_reg_dead_p (1, operands[2])"
17336 [(parallel [(set (match_dup 0)
17337 (match_op_dup 1
17338 [(and:SI
17339 (zero_extract:SI
17340 (match_dup 2)
17341 (const_int 8)
17342 (const_int 8))
17343 (match_dup 3))
17344 (const_int 0)]))
17345 (set (zero_extract:SI (match_dup 2)
17346 (const_int 8)
17347 (const_int 8))
17348 (and:SI
17349 (zero_extract:SI
17350 (match_dup 2)
17351 (const_int 8)
17352 (const_int 8))
17353 (match_dup 3)))])])
17354
17355 ;; Don't do logical operations with memory inputs.
17356 (define_peephole2
17357 [(match_scratch:SI 2 "r")
17358 (parallel [(set (match_operand:SI 0 "register_operand")
17359 (match_operator:SI 3 "arith_or_logical_operator"
17360 [(match_dup 0)
17361 (match_operand:SI 1 "memory_operand")]))
17362 (clobber (reg:CC FLAGS_REG))])]
17363 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17364 [(set (match_dup 2) (match_dup 1))
17365 (parallel [(set (match_dup 0)
17366 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17367 (clobber (reg:CC FLAGS_REG))])])
17368
17369 (define_peephole2
17370 [(match_scratch:SI 2 "r")
17371 (parallel [(set (match_operand:SI 0 "register_operand")
17372 (match_operator:SI 3 "arith_or_logical_operator"
17373 [(match_operand:SI 1 "memory_operand")
17374 (match_dup 0)]))
17375 (clobber (reg:CC FLAGS_REG))])]
17376 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17377 [(set (match_dup 2) (match_dup 1))
17378 (parallel [(set (match_dup 0)
17379 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17380 (clobber (reg:CC FLAGS_REG))])])
17381
17382 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17383 ;; refers to the destination of the load!
17384
17385 (define_peephole2
17386 [(set (match_operand:SI 0 "register_operand")
17387 (match_operand:SI 1 "register_operand"))
17388 (parallel [(set (match_dup 0)
17389 (match_operator:SI 3 "commutative_operator"
17390 [(match_dup 0)
17391 (match_operand:SI 2 "memory_operand")]))
17392 (clobber (reg:CC FLAGS_REG))])]
17393 "REGNO (operands[0]) != REGNO (operands[1])
17394 && GENERAL_REGNO_P (REGNO (operands[0]))
17395 && GENERAL_REGNO_P (REGNO (operands[1]))"
17396 [(set (match_dup 0) (match_dup 4))
17397 (parallel [(set (match_dup 0)
17398 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17399 (clobber (reg:CC FLAGS_REG))])]
17400 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17401
17402 (define_peephole2
17403 [(set (match_operand 0 "register_operand")
17404 (match_operand 1 "register_operand"))
17405 (set (match_dup 0)
17406 (match_operator 3 "commutative_operator"
17407 [(match_dup 0)
17408 (match_operand 2 "memory_operand")]))]
17409 "REGNO (operands[0]) != REGNO (operands[1])
17410 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17411 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17412 [(set (match_dup 0) (match_dup 2))
17413 (set (match_dup 0)
17414 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17415
17416 ; Don't do logical operations with memory outputs
17417 ;
17418 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17419 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17420 ; the same decoder scheduling characteristics as the original.
17421
17422 (define_peephole2
17423 [(match_scratch:SI 2 "r")
17424 (parallel [(set (match_operand:SI 0 "memory_operand")
17425 (match_operator:SI 3 "arith_or_logical_operator"
17426 [(match_dup 0)
17427 (match_operand:SI 1 "nonmemory_operand")]))
17428 (clobber (reg:CC FLAGS_REG))])]
17429 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17430 /* Do not split stack checking probes. */
17431 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17432 [(set (match_dup 2) (match_dup 0))
17433 (parallel [(set (match_dup 2)
17434 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17435 (clobber (reg:CC FLAGS_REG))])
17436 (set (match_dup 0) (match_dup 2))])
17437
17438 (define_peephole2
17439 [(match_scratch:SI 2 "r")
17440 (parallel [(set (match_operand:SI 0 "memory_operand")
17441 (match_operator:SI 3 "arith_or_logical_operator"
17442 [(match_operand:SI 1 "nonmemory_operand")
17443 (match_dup 0)]))
17444 (clobber (reg:CC FLAGS_REG))])]
17445 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17446 /* Do not split stack checking probes. */
17447 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17448 [(set (match_dup 2) (match_dup 0))
17449 (parallel [(set (match_dup 2)
17450 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17451 (clobber (reg:CC FLAGS_REG))])
17452 (set (match_dup 0) (match_dup 2))])
17453
17454 ;; Attempt to use arith or logical operations with memory outputs with
17455 ;; setting of flags.
17456 (define_peephole2
17457 [(set (match_operand:SWI 0 "register_operand")
17458 (match_operand:SWI 1 "memory_operand"))
17459 (parallel [(set (match_dup 0)
17460 (match_operator:SWI 3 "plusminuslogic_operator"
17461 [(match_dup 0)
17462 (match_operand:SWI 2 "<nonmemory_operand>")]))
17463 (clobber (reg:CC FLAGS_REG))])
17464 (set (match_dup 1) (match_dup 0))
17465 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17466 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17467 && peep2_reg_dead_p (4, operands[0])
17468 && !reg_overlap_mentioned_p (operands[0], operands[1])
17469 && !reg_overlap_mentioned_p (operands[0], operands[2])
17470 && (<MODE>mode != QImode
17471 || immediate_operand (operands[2], QImode)
17472 || q_regs_operand (operands[2], QImode))
17473 && ix86_match_ccmode (peep2_next_insn (3),
17474 (GET_CODE (operands[3]) == PLUS
17475 || GET_CODE (operands[3]) == MINUS)
17476 ? CCGOCmode : CCNOmode)"
17477 [(parallel [(set (match_dup 4) (match_dup 5))
17478 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17479 (match_dup 2)]))])]
17480 {
17481 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17482 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17483 copy_rtx (operands[1]),
17484 copy_rtx (operands[2]));
17485 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17486 operands[5], const0_rtx);
17487 })
17488
17489 (define_peephole2
17490 [(parallel [(set (match_operand:SWI 0 "register_operand")
17491 (match_operator:SWI 2 "plusminuslogic_operator"
17492 [(match_dup 0)
17493 (match_operand:SWI 1 "memory_operand")]))
17494 (clobber (reg:CC FLAGS_REG))])
17495 (set (match_dup 1) (match_dup 0))
17496 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17497 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17498 && GET_CODE (operands[2]) != MINUS
17499 && peep2_reg_dead_p (3, operands[0])
17500 && !reg_overlap_mentioned_p (operands[0], operands[1])
17501 && ix86_match_ccmode (peep2_next_insn (2),
17502 GET_CODE (operands[2]) == PLUS
17503 ? CCGOCmode : CCNOmode)"
17504 [(parallel [(set (match_dup 3) (match_dup 4))
17505 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17506 (match_dup 0)]))])]
17507 {
17508 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17509 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17510 copy_rtx (operands[1]),
17511 copy_rtx (operands[0]));
17512 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17513 operands[4], const0_rtx);
17514 })
17515
17516 (define_peephole2
17517 [(set (match_operand:SWI12 0 "register_operand")
17518 (match_operand:SWI12 1 "memory_operand"))
17519 (parallel [(set (match_operand:SI 4 "register_operand")
17520 (match_operator:SI 3 "plusminuslogic_operator"
17521 [(match_dup 4)
17522 (match_operand:SI 2 "nonmemory_operand")]))
17523 (clobber (reg:CC FLAGS_REG))])
17524 (set (match_dup 1) (match_dup 0))
17525 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17526 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17527 && REG_P (operands[0]) && REG_P (operands[4])
17528 && REGNO (operands[0]) == REGNO (operands[4])
17529 && peep2_reg_dead_p (4, operands[0])
17530 && (<MODE>mode != QImode
17531 || immediate_operand (operands[2], SImode)
17532 || q_regs_operand (operands[2], SImode))
17533 && !reg_overlap_mentioned_p (operands[0], operands[1])
17534 && !reg_overlap_mentioned_p (operands[0], operands[2])
17535 && ix86_match_ccmode (peep2_next_insn (3),
17536 (GET_CODE (operands[3]) == PLUS
17537 || GET_CODE (operands[3]) == MINUS)
17538 ? CCGOCmode : CCNOmode)"
17539 [(parallel [(set (match_dup 4) (match_dup 5))
17540 (set (match_dup 1) (match_dup 6))])]
17541 {
17542 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17543 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17544 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17545 copy_rtx (operands[1]), operands[2]);
17546 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17547 operands[5], const0_rtx);
17548 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17549 copy_rtx (operands[1]),
17550 copy_rtx (operands[2]));
17551 })
17552
17553 ;; Attempt to always use XOR for zeroing registers.
17554 (define_peephole2
17555 [(set (match_operand 0 "register_operand")
17556 (match_operand 1 "const0_operand"))]
17557 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17558 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17559 && GENERAL_REG_P (operands[0])
17560 && peep2_regno_dead_p (0, FLAGS_REG)"
17561 [(parallel [(set (match_dup 0) (const_int 0))
17562 (clobber (reg:CC FLAGS_REG))])]
17563 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17564
17565 (define_peephole2
17566 [(set (strict_low_part (match_operand 0 "register_operand"))
17567 (const_int 0))]
17568 "(GET_MODE (operands[0]) == QImode
17569 || GET_MODE (operands[0]) == HImode)
17570 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17571 && peep2_regno_dead_p (0, FLAGS_REG)"
17572 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17573 (clobber (reg:CC FLAGS_REG))])])
17574
17575 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17576 (define_peephole2
17577 [(set (match_operand:SWI248 0 "register_operand")
17578 (const_int -1))]
17579 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17580 && peep2_regno_dead_p (0, FLAGS_REG)"
17581 [(parallel [(set (match_dup 0) (const_int -1))
17582 (clobber (reg:CC FLAGS_REG))])]
17583 {
17584 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17585 operands[0] = gen_lowpart (SImode, operands[0]);
17586 })
17587
17588 ;; Attempt to convert simple lea to add/shift.
17589 ;; These can be created by move expanders.
17590 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17591 ;; relevant lea instructions were already split.
17592
17593 (define_peephole2
17594 [(set (match_operand:SWI48 0 "register_operand")
17595 (plus:SWI48 (match_dup 0)
17596 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17597 "!TARGET_OPT_AGU
17598 && peep2_regno_dead_p (0, FLAGS_REG)"
17599 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17600 (clobber (reg:CC FLAGS_REG))])])
17601
17602 (define_peephole2
17603 [(set (match_operand:SWI48 0 "register_operand")
17604 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17605 (match_dup 0)))]
17606 "!TARGET_OPT_AGU
17607 && peep2_regno_dead_p (0, FLAGS_REG)"
17608 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17609 (clobber (reg:CC FLAGS_REG))])])
17610
17611 (define_peephole2
17612 [(set (match_operand:DI 0 "register_operand")
17613 (zero_extend:DI
17614 (plus:SI (match_operand:SI 1 "register_operand")
17615 (match_operand:SI 2 "nonmemory_operand"))))]
17616 "TARGET_64BIT && !TARGET_OPT_AGU
17617 && REGNO (operands[0]) == REGNO (operands[1])
17618 && peep2_regno_dead_p (0, FLAGS_REG)"
17619 [(parallel [(set (match_dup 0)
17620 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17621 (clobber (reg:CC FLAGS_REG))])])
17622
17623 (define_peephole2
17624 [(set (match_operand:DI 0 "register_operand")
17625 (zero_extend:DI
17626 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17627 (match_operand:SI 2 "register_operand"))))]
17628 "TARGET_64BIT && !TARGET_OPT_AGU
17629 && REGNO (operands[0]) == REGNO (operands[2])
17630 && peep2_regno_dead_p (0, FLAGS_REG)"
17631 [(parallel [(set (match_dup 0)
17632 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17633 (clobber (reg:CC FLAGS_REG))])])
17634
17635 (define_peephole2
17636 [(set (match_operand:SWI48 0 "register_operand")
17637 (mult:SWI48 (match_dup 0)
17638 (match_operand:SWI48 1 "const_int_operand")))]
17639 "exact_log2 (INTVAL (operands[1])) >= 0
17640 && peep2_regno_dead_p (0, FLAGS_REG)"
17641 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17642 (clobber (reg:CC FLAGS_REG))])]
17643 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17644
17645 (define_peephole2
17646 [(set (match_operand:DI 0 "register_operand")
17647 (zero_extend:DI
17648 (mult:SI (match_operand:SI 1 "register_operand")
17649 (match_operand:SI 2 "const_int_operand"))))]
17650 "TARGET_64BIT
17651 && exact_log2 (INTVAL (operands[2])) >= 0
17652 && REGNO (operands[0]) == REGNO (operands[1])
17653 && peep2_regno_dead_p (0, FLAGS_REG)"
17654 [(parallel [(set (match_dup 0)
17655 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17656 (clobber (reg:CC FLAGS_REG))])]
17657 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17658
17659 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17660 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17661 ;; On many CPUs it is also faster, since special hardware to avoid esp
17662 ;; dependencies is present.
17663
17664 ;; While some of these conversions may be done using splitters, we use
17665 ;; peepholes in order to allow combine_stack_adjustments pass to see
17666 ;; nonobfuscated RTL.
17667
17668 ;; Convert prologue esp subtractions to push.
17669 ;; We need register to push. In order to keep verify_flow_info happy we have
17670 ;; two choices
17671 ;; - use scratch and clobber it in order to avoid dependencies
17672 ;; - use already live register
17673 ;; We can't use the second way right now, since there is no reliable way how to
17674 ;; verify that given register is live. First choice will also most likely in
17675 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17676 ;; call clobbered registers are dead. We may want to use base pointer as an
17677 ;; alternative when no register is available later.
17678
17679 (define_peephole2
17680 [(match_scratch:W 1 "r")
17681 (parallel [(set (reg:P SP_REG)
17682 (plus:P (reg:P SP_REG)
17683 (match_operand:P 0 "const_int_operand")))
17684 (clobber (reg:CC FLAGS_REG))
17685 (clobber (mem:BLK (scratch)))])]
17686 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17687 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17688 [(clobber (match_dup 1))
17689 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17690 (clobber (mem:BLK (scratch)))])])
17691
17692 (define_peephole2
17693 [(match_scratch:W 1 "r")
17694 (parallel [(set (reg:P SP_REG)
17695 (plus:P (reg:P SP_REG)
17696 (match_operand:P 0 "const_int_operand")))
17697 (clobber (reg:CC FLAGS_REG))
17698 (clobber (mem:BLK (scratch)))])]
17699 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17700 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17701 [(clobber (match_dup 1))
17702 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17703 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17704 (clobber (mem:BLK (scratch)))])])
17705
17706 ;; Convert esp subtractions to push.
17707 (define_peephole2
17708 [(match_scratch:W 1 "r")
17709 (parallel [(set (reg:P SP_REG)
17710 (plus:P (reg:P SP_REG)
17711 (match_operand:P 0 "const_int_operand")))
17712 (clobber (reg:CC FLAGS_REG))])]
17713 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17714 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17715 [(clobber (match_dup 1))
17716 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17717
17718 (define_peephole2
17719 [(match_scratch:W 1 "r")
17720 (parallel [(set (reg:P SP_REG)
17721 (plus:P (reg:P SP_REG)
17722 (match_operand:P 0 "const_int_operand")))
17723 (clobber (reg:CC FLAGS_REG))])]
17724 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17725 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17726 [(clobber (match_dup 1))
17727 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17728 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17729
17730 ;; Convert epilogue deallocator to pop.
17731 (define_peephole2
17732 [(match_scratch:W 1 "r")
17733 (parallel [(set (reg:P SP_REG)
17734 (plus:P (reg:P SP_REG)
17735 (match_operand:P 0 "const_int_operand")))
17736 (clobber (reg:CC FLAGS_REG))
17737 (clobber (mem:BLK (scratch)))])]
17738 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17739 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17740 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17741 (clobber (mem:BLK (scratch)))])])
17742
17743 ;; Two pops case is tricky, since pop causes dependency
17744 ;; on destination register. We use two registers if available.
17745 (define_peephole2
17746 [(match_scratch:W 1 "r")
17747 (match_scratch:W 2 "r")
17748 (parallel [(set (reg:P SP_REG)
17749 (plus:P (reg:P SP_REG)
17750 (match_operand:P 0 "const_int_operand")))
17751 (clobber (reg:CC FLAGS_REG))
17752 (clobber (mem:BLK (scratch)))])]
17753 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17754 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17755 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17756 (clobber (mem:BLK (scratch)))])
17757 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17758
17759 (define_peephole2
17760 [(match_scratch:W 1 "r")
17761 (parallel [(set (reg:P SP_REG)
17762 (plus:P (reg:P SP_REG)
17763 (match_operand:P 0 "const_int_operand")))
17764 (clobber (reg:CC FLAGS_REG))
17765 (clobber (mem:BLK (scratch)))])]
17766 "optimize_insn_for_size_p ()
17767 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17768 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17769 (clobber (mem:BLK (scratch)))])
17770 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17771
17772 ;; Convert esp additions to pop.
17773 (define_peephole2
17774 [(match_scratch:W 1 "r")
17775 (parallel [(set (reg:P SP_REG)
17776 (plus:P (reg:P SP_REG)
17777 (match_operand:P 0 "const_int_operand")))
17778 (clobber (reg:CC FLAGS_REG))])]
17779 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17780 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17781
17782 ;; Two pops case is tricky, since pop causes dependency
17783 ;; on destination register. We use two registers if available.
17784 (define_peephole2
17785 [(match_scratch:W 1 "r")
17786 (match_scratch:W 2 "r")
17787 (parallel [(set (reg:P SP_REG)
17788 (plus:P (reg:P SP_REG)
17789 (match_operand:P 0 "const_int_operand")))
17790 (clobber (reg:CC FLAGS_REG))])]
17791 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17792 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17793 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17794
17795 (define_peephole2
17796 [(match_scratch:W 1 "r")
17797 (parallel [(set (reg:P SP_REG)
17798 (plus:P (reg:P SP_REG)
17799 (match_operand:P 0 "const_int_operand")))
17800 (clobber (reg:CC FLAGS_REG))])]
17801 "optimize_insn_for_size_p ()
17802 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17803 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17804 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17805 \f
17806 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17807 ;; required and register dies. Similarly for 128 to -128.
17808 (define_peephole2
17809 [(set (match_operand 0 "flags_reg_operand")
17810 (match_operator 1 "compare_operator"
17811 [(match_operand 2 "register_operand")
17812 (match_operand 3 "const_int_operand")]))]
17813 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17814 && incdec_operand (operands[3], GET_MODE (operands[3])))
17815 || (!TARGET_FUSE_CMP_AND_BRANCH
17816 && INTVAL (operands[3]) == 128))
17817 && ix86_match_ccmode (insn, CCGCmode)
17818 && peep2_reg_dead_p (1, operands[2])"
17819 [(parallel [(set (match_dup 0)
17820 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17821 (clobber (match_dup 2))])])
17822 \f
17823 ;; Convert imul by three, five and nine into lea
17824 (define_peephole2
17825 [(parallel
17826 [(set (match_operand:SWI48 0 "register_operand")
17827 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17828 (match_operand:SWI48 2 "const359_operand")))
17829 (clobber (reg:CC FLAGS_REG))])]
17830 "!TARGET_PARTIAL_REG_STALL
17831 || <MODE>mode == SImode
17832 || optimize_function_for_size_p (cfun)"
17833 [(set (match_dup 0)
17834 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17835 (match_dup 1)))]
17836 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17837
17838 (define_peephole2
17839 [(parallel
17840 [(set (match_operand:SWI48 0 "register_operand")
17841 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17842 (match_operand:SWI48 2 "const359_operand")))
17843 (clobber (reg:CC FLAGS_REG))])]
17844 "optimize_insn_for_speed_p ()
17845 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17846 [(set (match_dup 0) (match_dup 1))
17847 (set (match_dup 0)
17848 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17849 (match_dup 0)))]
17850 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17851
17852 ;; imul $32bit_imm, mem, reg is vector decoded, while
17853 ;; imul $32bit_imm, reg, reg is direct decoded.
17854 (define_peephole2
17855 [(match_scratch:SWI48 3 "r")
17856 (parallel [(set (match_operand:SWI48 0 "register_operand")
17857 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17858 (match_operand:SWI48 2 "immediate_operand")))
17859 (clobber (reg:CC FLAGS_REG))])]
17860 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17861 && !satisfies_constraint_K (operands[2])"
17862 [(set (match_dup 3) (match_dup 1))
17863 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17864 (clobber (reg:CC FLAGS_REG))])])
17865
17866 (define_peephole2
17867 [(match_scratch:SI 3 "r")
17868 (parallel [(set (match_operand:DI 0 "register_operand")
17869 (zero_extend:DI
17870 (mult:SI (match_operand:SI 1 "memory_operand")
17871 (match_operand:SI 2 "immediate_operand"))))
17872 (clobber (reg:CC FLAGS_REG))])]
17873 "TARGET_64BIT
17874 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17875 && !satisfies_constraint_K (operands[2])"
17876 [(set (match_dup 3) (match_dup 1))
17877 (parallel [(set (match_dup 0)
17878 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17879 (clobber (reg:CC FLAGS_REG))])])
17880
17881 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17882 ;; Convert it into imul reg, reg
17883 ;; It would be better to force assembler to encode instruction using long
17884 ;; immediate, but there is apparently no way to do so.
17885 (define_peephole2
17886 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17887 (mult:SWI248
17888 (match_operand:SWI248 1 "nonimmediate_operand")
17889 (match_operand:SWI248 2 "const_int_operand")))
17890 (clobber (reg:CC FLAGS_REG))])
17891 (match_scratch:SWI248 3 "r")]
17892 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17893 && satisfies_constraint_K (operands[2])"
17894 [(set (match_dup 3) (match_dup 2))
17895 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17896 (clobber (reg:CC FLAGS_REG))])]
17897 {
17898 if (!rtx_equal_p (operands[0], operands[1]))
17899 emit_move_insn (operands[0], operands[1]);
17900 })
17901
17902 ;; After splitting up read-modify operations, array accesses with memory
17903 ;; operands might end up in form:
17904 ;; sall $2, %eax
17905 ;; movl 4(%esp), %edx
17906 ;; addl %edx, %eax
17907 ;; instead of pre-splitting:
17908 ;; sall $2, %eax
17909 ;; addl 4(%esp), %eax
17910 ;; Turn it into:
17911 ;; movl 4(%esp), %edx
17912 ;; leal (%edx,%eax,4), %eax
17913
17914 (define_peephole2
17915 [(match_scratch:W 5 "r")
17916 (parallel [(set (match_operand 0 "register_operand")
17917 (ashift (match_operand 1 "register_operand")
17918 (match_operand 2 "const_int_operand")))
17919 (clobber (reg:CC FLAGS_REG))])
17920 (parallel [(set (match_operand 3 "register_operand")
17921 (plus (match_dup 0)
17922 (match_operand 4 "x86_64_general_operand")))
17923 (clobber (reg:CC FLAGS_REG))])]
17924 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17925 /* Validate MODE for lea. */
17926 && ((!TARGET_PARTIAL_REG_STALL
17927 && (GET_MODE (operands[0]) == QImode
17928 || GET_MODE (operands[0]) == HImode))
17929 || GET_MODE (operands[0]) == SImode
17930 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17931 && (rtx_equal_p (operands[0], operands[3])
17932 || peep2_reg_dead_p (2, operands[0]))
17933 /* We reorder load and the shift. */
17934 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17935 [(set (match_dup 5) (match_dup 4))
17936 (set (match_dup 0) (match_dup 1))]
17937 {
17938 machine_mode op1mode = GET_MODE (operands[1]);
17939 machine_mode mode = op1mode == DImode ? DImode : SImode;
17940 int scale = 1 << INTVAL (operands[2]);
17941 rtx index = gen_lowpart (word_mode, operands[1]);
17942 rtx base = gen_lowpart (word_mode, operands[5]);
17943 rtx dest = gen_lowpart (mode, operands[3]);
17944
17945 operands[1] = gen_rtx_PLUS (word_mode, base,
17946 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17947 operands[5] = base;
17948 if (mode != word_mode)
17949 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17950 if (op1mode != word_mode)
17951 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17952 operands[0] = dest;
17953 })
17954 \f
17955 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17956 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17957 ;; caught for use by garbage collectors and the like. Using an insn that
17958 ;; maps to SIGILL makes it more likely the program will rightfully die.
17959 ;; Keeping with tradition, "6" is in honor of #UD.
17960 (define_insn "trap"
17961 [(trap_if (const_int 1) (const_int 6))]
17962 ""
17963 {
17964 #ifdef HAVE_AS_IX86_UD2
17965 return "ud2";
17966 #else
17967 return ASM_SHORT "0x0b0f";
17968 #endif
17969 }
17970 [(set_attr "length" "2")])
17971
17972 (define_expand "prefetch"
17973 [(prefetch (match_operand 0 "address_operand")
17974 (match_operand:SI 1 "const_int_operand")
17975 (match_operand:SI 2 "const_int_operand"))]
17976 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17977 {
17978 bool write = INTVAL (operands[1]) != 0;
17979 int locality = INTVAL (operands[2]);
17980
17981 gcc_assert (IN_RANGE (locality, 0, 3));
17982
17983 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17984 supported by SSE counterpart or the SSE prefetch is not available
17985 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17986 of locality. */
17987 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17988 operands[2] = const2_rtx;
17989 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17990 operands[2] = GEN_INT (3);
17991 else
17992 operands[1] = const0_rtx;
17993 })
17994
17995 (define_insn "*prefetch_sse"
17996 [(prefetch (match_operand 0 "address_operand" "p")
17997 (const_int 0)
17998 (match_operand:SI 1 "const_int_operand"))]
17999 "TARGET_PREFETCH_SSE"
18000 {
18001 static const char * const patterns[4] = {
18002 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18003 };
18004
18005 int locality = INTVAL (operands[1]);
18006 gcc_assert (IN_RANGE (locality, 0, 3));
18007
18008 return patterns[locality];
18009 }
18010 [(set_attr "type" "sse")
18011 (set_attr "atom_sse_attr" "prefetch")
18012 (set (attr "length_address")
18013 (symbol_ref "memory_address_length (operands[0], false)"))
18014 (set_attr "memory" "none")])
18015
18016 (define_insn "*prefetch_3dnow"
18017 [(prefetch (match_operand 0 "address_operand" "p")
18018 (match_operand:SI 1 "const_int_operand" "n")
18019 (const_int 3))]
18020 "TARGET_PRFCHW"
18021 {
18022 if (INTVAL (operands[1]) == 0)
18023 return "prefetch\t%a0";
18024 else
18025 return "prefetchw\t%a0";
18026 }
18027 [(set_attr "type" "mmx")
18028 (set (attr "length_address")
18029 (symbol_ref "memory_address_length (operands[0], false)"))
18030 (set_attr "memory" "none")])
18031
18032 (define_insn "*prefetch_prefetchwt1_<mode>"
18033 [(prefetch (match_operand:P 0 "address_operand" "p")
18034 (const_int 1)
18035 (const_int 2))]
18036 "TARGET_PREFETCHWT1"
18037 "prefetchwt1\t%a0";
18038 [(set_attr "type" "sse")
18039 (set (attr "length_address")
18040 (symbol_ref "memory_address_length (operands[0], false)"))
18041 (set_attr "memory" "none")])
18042
18043 (define_expand "stack_protect_set"
18044 [(match_operand 0 "memory_operand")
18045 (match_operand 1 "memory_operand")]
18046 "TARGET_SSP_TLS_GUARD"
18047 {
18048 rtx (*insn)(rtx, rtx);
18049
18050 #ifdef TARGET_THREAD_SSP_OFFSET
18051 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18052 insn = (TARGET_LP64
18053 ? gen_stack_tls_protect_set_di
18054 : gen_stack_tls_protect_set_si);
18055 #else
18056 insn = (TARGET_LP64
18057 ? gen_stack_protect_set_di
18058 : gen_stack_protect_set_si);
18059 #endif
18060
18061 emit_insn (insn (operands[0], operands[1]));
18062 DONE;
18063 })
18064
18065 (define_insn "stack_protect_set_<mode>"
18066 [(set (match_operand:PTR 0 "memory_operand" "=m")
18067 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18068 UNSPEC_SP_SET))
18069 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18070 (clobber (reg:CC FLAGS_REG))]
18071 "TARGET_SSP_TLS_GUARD"
18072 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18073 [(set_attr "type" "multi")])
18074
18075 (define_insn "stack_tls_protect_set_<mode>"
18076 [(set (match_operand:PTR 0 "memory_operand" "=m")
18077 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18078 UNSPEC_SP_TLS_SET))
18079 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18080 (clobber (reg:CC FLAGS_REG))]
18081 ""
18082 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18083 [(set_attr "type" "multi")])
18084
18085 (define_expand "stack_protect_test"
18086 [(match_operand 0 "memory_operand")
18087 (match_operand 1 "memory_operand")
18088 (match_operand 2)]
18089 "TARGET_SSP_TLS_GUARD"
18090 {
18091 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18092
18093 rtx (*insn)(rtx, rtx, rtx);
18094
18095 #ifdef TARGET_THREAD_SSP_OFFSET
18096 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18097 insn = (TARGET_LP64
18098 ? gen_stack_tls_protect_test_di
18099 : gen_stack_tls_protect_test_si);
18100 #else
18101 insn = (TARGET_LP64
18102 ? gen_stack_protect_test_di
18103 : gen_stack_protect_test_si);
18104 #endif
18105
18106 emit_insn (insn (flags, operands[0], operands[1]));
18107
18108 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18109 flags, const0_rtx, operands[2]));
18110 DONE;
18111 })
18112
18113 (define_insn "stack_protect_test_<mode>"
18114 [(set (match_operand:CCZ 0 "flags_reg_operand")
18115 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18116 (match_operand:PTR 2 "memory_operand" "m")]
18117 UNSPEC_SP_TEST))
18118 (clobber (match_scratch:PTR 3 "=&r"))]
18119 "TARGET_SSP_TLS_GUARD"
18120 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18121 [(set_attr "type" "multi")])
18122
18123 (define_insn "stack_tls_protect_test_<mode>"
18124 [(set (match_operand:CCZ 0 "flags_reg_operand")
18125 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18126 (match_operand:PTR 2 "const_int_operand" "i")]
18127 UNSPEC_SP_TLS_TEST))
18128 (clobber (match_scratch:PTR 3 "=r"))]
18129 ""
18130 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18131 [(set_attr "type" "multi")])
18132
18133 (define_insn "sse4_2_crc32<mode>"
18134 [(set (match_operand:SI 0 "register_operand" "=r")
18135 (unspec:SI
18136 [(match_operand:SI 1 "register_operand" "0")
18137 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18138 UNSPEC_CRC32))]
18139 "TARGET_SSE4_2 || TARGET_CRC32"
18140 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18141 [(set_attr "type" "sselog1")
18142 (set_attr "prefix_rep" "1")
18143 (set_attr "prefix_extra" "1")
18144 (set (attr "prefix_data16")
18145 (if_then_else (match_operand:HI 2)
18146 (const_string "1")
18147 (const_string "*")))
18148 (set (attr "prefix_rex")
18149 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18150 (const_string "1")
18151 (const_string "*")))
18152 (set_attr "mode" "SI")])
18153
18154 (define_insn "sse4_2_crc32di"
18155 [(set (match_operand:DI 0 "register_operand" "=r")
18156 (unspec:DI
18157 [(match_operand:DI 1 "register_operand" "0")
18158 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18159 UNSPEC_CRC32))]
18160 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18161 "crc32{q}\t{%2, %0|%0, %2}"
18162 [(set_attr "type" "sselog1")
18163 (set_attr "prefix_rep" "1")
18164 (set_attr "prefix_extra" "1")
18165 (set_attr "mode" "DI")])
18166
18167 (define_insn "rdpmc"
18168 [(set (match_operand:DI 0 "register_operand" "=A")
18169 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18170 UNSPECV_RDPMC))]
18171 "!TARGET_64BIT"
18172 "rdpmc"
18173 [(set_attr "type" "other")
18174 (set_attr "length" "2")])
18175
18176 (define_insn "rdpmc_rex64"
18177 [(set (match_operand:DI 0 "register_operand" "=a")
18178 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18179 UNSPECV_RDPMC))
18180 (set (match_operand:DI 1 "register_operand" "=d")
18181 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18182 "TARGET_64BIT"
18183 "rdpmc"
18184 [(set_attr "type" "other")
18185 (set_attr "length" "2")])
18186
18187 (define_insn "rdtsc"
18188 [(set (match_operand:DI 0 "register_operand" "=A")
18189 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18190 "!TARGET_64BIT"
18191 "rdtsc"
18192 [(set_attr "type" "other")
18193 (set_attr "length" "2")])
18194
18195 (define_insn "rdtsc_rex64"
18196 [(set (match_operand:DI 0 "register_operand" "=a")
18197 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18198 (set (match_operand:DI 1 "register_operand" "=d")
18199 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18200 "TARGET_64BIT"
18201 "rdtsc"
18202 [(set_attr "type" "other")
18203 (set_attr "length" "2")])
18204
18205 (define_insn "rdtscp"
18206 [(set (match_operand:DI 0 "register_operand" "=A")
18207 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18208 (set (match_operand:SI 1 "register_operand" "=c")
18209 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18210 "!TARGET_64BIT"
18211 "rdtscp"
18212 [(set_attr "type" "other")
18213 (set_attr "length" "3")])
18214
18215 (define_insn "rdtscp_rex64"
18216 [(set (match_operand:DI 0 "register_operand" "=a")
18217 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18218 (set (match_operand:DI 1 "register_operand" "=d")
18219 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18220 (set (match_operand:SI 2 "register_operand" "=c")
18221 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18222 "TARGET_64BIT"
18223 "rdtscp"
18224 [(set_attr "type" "other")
18225 (set_attr "length" "3")])
18226
18227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18228 ;;
18229 ;; FXSR, XSAVE and XSAVEOPT instructions
18230 ;;
18231 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18232
18233 (define_insn "fxsave"
18234 [(set (match_operand:BLK 0 "memory_operand" "=m")
18235 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18236 "TARGET_FXSR"
18237 "fxsave\t%0"
18238 [(set_attr "type" "other")
18239 (set_attr "memory" "store")
18240 (set (attr "length")
18241 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18242
18243 (define_insn "fxsave64"
18244 [(set (match_operand:BLK 0 "memory_operand" "=m")
18245 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18246 "TARGET_64BIT && TARGET_FXSR"
18247 "fxsave64\t%0"
18248 [(set_attr "type" "other")
18249 (set_attr "memory" "store")
18250 (set (attr "length")
18251 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18252
18253 (define_insn "fxrstor"
18254 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18255 UNSPECV_FXRSTOR)]
18256 "TARGET_FXSR"
18257 "fxrstor\t%0"
18258 [(set_attr "type" "other")
18259 (set_attr "memory" "load")
18260 (set (attr "length")
18261 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18262
18263 (define_insn "fxrstor64"
18264 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18265 UNSPECV_FXRSTOR64)]
18266 "TARGET_64BIT && TARGET_FXSR"
18267 "fxrstor64\t%0"
18268 [(set_attr "type" "other")
18269 (set_attr "memory" "load")
18270 (set (attr "length")
18271 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18272
18273 (define_int_iterator ANY_XSAVE
18274 [UNSPECV_XSAVE
18275 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18276 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18277 (UNSPECV_XSAVES "TARGET_XSAVES")])
18278
18279 (define_int_iterator ANY_XSAVE64
18280 [UNSPECV_XSAVE64
18281 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18282 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18283 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18284
18285 (define_int_attr xsave
18286 [(UNSPECV_XSAVE "xsave")
18287 (UNSPECV_XSAVE64 "xsave64")
18288 (UNSPECV_XSAVEOPT "xsaveopt")
18289 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18290 (UNSPECV_XSAVEC "xsavec")
18291 (UNSPECV_XSAVEC64 "xsavec64")
18292 (UNSPECV_XSAVES "xsaves")
18293 (UNSPECV_XSAVES64 "xsaves64")])
18294
18295 (define_int_iterator ANY_XRSTOR
18296 [UNSPECV_XRSTOR
18297 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18298
18299 (define_int_iterator ANY_XRSTOR64
18300 [UNSPECV_XRSTOR64
18301 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18302
18303 (define_int_attr xrstor
18304 [(UNSPECV_XRSTOR "xrstor")
18305 (UNSPECV_XRSTOR64 "xrstor")
18306 (UNSPECV_XRSTORS "xrstors")
18307 (UNSPECV_XRSTORS64 "xrstors")])
18308
18309 (define_insn "<xsave>"
18310 [(set (match_operand:BLK 0 "memory_operand" "=m")
18311 (unspec_volatile:BLK
18312 [(match_operand:DI 1 "register_operand" "A")]
18313 ANY_XSAVE))]
18314 "!TARGET_64BIT && TARGET_XSAVE"
18315 "<xsave>\t%0"
18316 [(set_attr "type" "other")
18317 (set_attr "memory" "store")
18318 (set (attr "length")
18319 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18320
18321 (define_insn "<xsave>_rex64"
18322 [(set (match_operand:BLK 0 "memory_operand" "=m")
18323 (unspec_volatile:BLK
18324 [(match_operand:SI 1 "register_operand" "a")
18325 (match_operand:SI 2 "register_operand" "d")]
18326 ANY_XSAVE))]
18327 "TARGET_64BIT && TARGET_XSAVE"
18328 "<xsave>\t%0"
18329 [(set_attr "type" "other")
18330 (set_attr "memory" "store")
18331 (set (attr "length")
18332 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18333
18334 (define_insn "<xsave>"
18335 [(set (match_operand:BLK 0 "memory_operand" "=m")
18336 (unspec_volatile:BLK
18337 [(match_operand:SI 1 "register_operand" "a")
18338 (match_operand:SI 2 "register_operand" "d")]
18339 ANY_XSAVE64))]
18340 "TARGET_64BIT && TARGET_XSAVE"
18341 "<xsave>\t%0"
18342 [(set_attr "type" "other")
18343 (set_attr "memory" "store")
18344 (set (attr "length")
18345 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18346
18347 (define_insn "<xrstor>"
18348 [(unspec_volatile:BLK
18349 [(match_operand:BLK 0 "memory_operand" "m")
18350 (match_operand:DI 1 "register_operand" "A")]
18351 ANY_XRSTOR)]
18352 "!TARGET_64BIT && TARGET_XSAVE"
18353 "<xrstor>\t%0"
18354 [(set_attr "type" "other")
18355 (set_attr "memory" "load")
18356 (set (attr "length")
18357 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18358
18359 (define_insn "<xrstor>_rex64"
18360 [(unspec_volatile:BLK
18361 [(match_operand:BLK 0 "memory_operand" "m")
18362 (match_operand:SI 1 "register_operand" "a")
18363 (match_operand:SI 2 "register_operand" "d")]
18364 ANY_XRSTOR)]
18365 "TARGET_64BIT && TARGET_XSAVE"
18366 "<xrstor>\t%0"
18367 [(set_attr "type" "other")
18368 (set_attr "memory" "load")
18369 (set (attr "length")
18370 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18371
18372 (define_insn "<xrstor>64"
18373 [(unspec_volatile:BLK
18374 [(match_operand:BLK 0 "memory_operand" "m")
18375 (match_operand:SI 1 "register_operand" "a")
18376 (match_operand:SI 2 "register_operand" "d")]
18377 ANY_XRSTOR64)]
18378 "TARGET_64BIT && TARGET_XSAVE"
18379 "<xrstor>64\t%0"
18380 [(set_attr "type" "other")
18381 (set_attr "memory" "load")
18382 (set (attr "length")
18383 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18384
18385 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18386 ;;
18387 ;; Floating-point instructions for atomic compound assignments
18388 ;;
18389 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18390
18391 ; Clobber all floating-point registers on environment save and restore
18392 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18393 (define_insn "fnstenv"
18394 [(set (match_operand:BLK 0 "memory_operand" "=m")
18395 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18396 (clobber (reg:HI FPCR_REG))
18397 (clobber (reg:XF ST0_REG))
18398 (clobber (reg:XF ST1_REG))
18399 (clobber (reg:XF ST2_REG))
18400 (clobber (reg:XF ST3_REG))
18401 (clobber (reg:XF ST4_REG))
18402 (clobber (reg:XF ST5_REG))
18403 (clobber (reg:XF ST6_REG))
18404 (clobber (reg:XF ST7_REG))]
18405 "TARGET_80387"
18406 "fnstenv\t%0"
18407 [(set_attr "type" "other")
18408 (set_attr "memory" "store")
18409 (set (attr "length")
18410 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18411
18412 (define_insn "fldenv"
18413 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18414 UNSPECV_FLDENV)
18415 (clobber (reg:CCFP FPSR_REG))
18416 (clobber (reg:HI FPCR_REG))
18417 (clobber (reg:XF ST0_REG))
18418 (clobber (reg:XF ST1_REG))
18419 (clobber (reg:XF ST2_REG))
18420 (clobber (reg:XF ST3_REG))
18421 (clobber (reg:XF ST4_REG))
18422 (clobber (reg:XF ST5_REG))
18423 (clobber (reg:XF ST6_REG))
18424 (clobber (reg:XF ST7_REG))]
18425 "TARGET_80387"
18426 "fldenv\t%0"
18427 [(set_attr "type" "other")
18428 (set_attr "memory" "load")
18429 (set (attr "length")
18430 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18431
18432 (define_insn "fnstsw"
18433 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18434 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18435 "TARGET_80387"
18436 "fnstsw\t%0"
18437 [(set_attr "type" "other,other")
18438 (set_attr "memory" "none,store")
18439 (set (attr "length")
18440 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18441
18442 (define_insn "fnclex"
18443 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18444 "TARGET_80387"
18445 "fnclex"
18446 [(set_attr "type" "other")
18447 (set_attr "memory" "none")
18448 (set_attr "length" "2")])
18449
18450 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18451 ;;
18452 ;; LWP instructions
18453 ;;
18454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18455
18456 (define_expand "lwp_llwpcb"
18457 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18458 UNSPECV_LLWP_INTRINSIC)]
18459 "TARGET_LWP")
18460
18461 (define_insn "*lwp_llwpcb<mode>1"
18462 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18463 UNSPECV_LLWP_INTRINSIC)]
18464 "TARGET_LWP"
18465 "llwpcb\t%0"
18466 [(set_attr "type" "lwp")
18467 (set_attr "mode" "<MODE>")
18468 (set_attr "length" "5")])
18469
18470 (define_expand "lwp_slwpcb"
18471 [(set (match_operand 0 "register_operand" "=r")
18472 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18473 "TARGET_LWP"
18474 {
18475 rtx (*insn)(rtx);
18476
18477 insn = (Pmode == DImode
18478 ? gen_lwp_slwpcbdi
18479 : gen_lwp_slwpcbsi);
18480
18481 emit_insn (insn (operands[0]));
18482 DONE;
18483 })
18484
18485 (define_insn "lwp_slwpcb<mode>"
18486 [(set (match_operand:P 0 "register_operand" "=r")
18487 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18488 "TARGET_LWP"
18489 "slwpcb\t%0"
18490 [(set_attr "type" "lwp")
18491 (set_attr "mode" "<MODE>")
18492 (set_attr "length" "5")])
18493
18494 (define_expand "lwp_lwpval<mode>3"
18495 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18496 (match_operand:SI 2 "nonimmediate_operand" "rm")
18497 (match_operand:SI 3 "const_int_operand" "i")]
18498 UNSPECV_LWPVAL_INTRINSIC)]
18499 "TARGET_LWP"
18500 ;; Avoid unused variable warning.
18501 "(void) operands[0];")
18502
18503 (define_insn "*lwp_lwpval<mode>3_1"
18504 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18505 (match_operand:SI 1 "nonimmediate_operand" "rm")
18506 (match_operand:SI 2 "const_int_operand" "i")]
18507 UNSPECV_LWPVAL_INTRINSIC)]
18508 "TARGET_LWP"
18509 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18510 [(set_attr "type" "lwp")
18511 (set_attr "mode" "<MODE>")
18512 (set (attr "length")
18513 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18514
18515 (define_expand "lwp_lwpins<mode>3"
18516 [(set (reg:CCC FLAGS_REG)
18517 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18518 (match_operand:SI 2 "nonimmediate_operand" "rm")
18519 (match_operand:SI 3 "const_int_operand" "i")]
18520 UNSPECV_LWPINS_INTRINSIC))
18521 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18522 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18523 "TARGET_LWP")
18524
18525 (define_insn "*lwp_lwpins<mode>3_1"
18526 [(set (reg:CCC FLAGS_REG)
18527 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18528 (match_operand:SI 1 "nonimmediate_operand" "rm")
18529 (match_operand:SI 2 "const_int_operand" "i")]
18530 UNSPECV_LWPINS_INTRINSIC))]
18531 "TARGET_LWP"
18532 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18533 [(set_attr "type" "lwp")
18534 (set_attr "mode" "<MODE>")
18535 (set (attr "length")
18536 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18537
18538 (define_int_iterator RDFSGSBASE
18539 [UNSPECV_RDFSBASE
18540 UNSPECV_RDGSBASE])
18541
18542 (define_int_iterator WRFSGSBASE
18543 [UNSPECV_WRFSBASE
18544 UNSPECV_WRGSBASE])
18545
18546 (define_int_attr fsgs
18547 [(UNSPECV_RDFSBASE "fs")
18548 (UNSPECV_RDGSBASE "gs")
18549 (UNSPECV_WRFSBASE "fs")
18550 (UNSPECV_WRGSBASE "gs")])
18551
18552 (define_insn "rd<fsgs>base<mode>"
18553 [(set (match_operand:SWI48 0 "register_operand" "=r")
18554 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18555 "TARGET_64BIT && TARGET_FSGSBASE"
18556 "rd<fsgs>base\t%0"
18557 [(set_attr "type" "other")
18558 (set_attr "prefix_extra" "2")])
18559
18560 (define_insn "wr<fsgs>base<mode>"
18561 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18562 WRFSGSBASE)]
18563 "TARGET_64BIT && TARGET_FSGSBASE"
18564 "wr<fsgs>base\t%0"
18565 [(set_attr "type" "other")
18566 (set_attr "prefix_extra" "2")])
18567
18568 (define_insn "rdrand<mode>_1"
18569 [(set (match_operand:SWI248 0 "register_operand" "=r")
18570 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18571 (set (reg:CCC FLAGS_REG)
18572 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18573 "TARGET_RDRND"
18574 "rdrand\t%0"
18575 [(set_attr "type" "other")
18576 (set_attr "prefix_extra" "1")])
18577
18578 (define_insn "rdseed<mode>_1"
18579 [(set (match_operand:SWI248 0 "register_operand" "=r")
18580 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18581 (set (reg:CCC FLAGS_REG)
18582 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18583 "TARGET_RDSEED"
18584 "rdseed\t%0"
18585 [(set_attr "type" "other")
18586 (set_attr "prefix_extra" "1")])
18587
18588 (define_expand "pause"
18589 [(set (match_dup 0)
18590 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18591 ""
18592 {
18593 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18594 MEM_VOLATILE_P (operands[0]) = 1;
18595 })
18596
18597 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18598 ;; They have the same encoding.
18599 (define_insn "*pause"
18600 [(set (match_operand:BLK 0)
18601 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18602 ""
18603 "rep%; nop"
18604 [(set_attr "length" "2")
18605 (set_attr "memory" "unknown")])
18606
18607 (define_expand "xbegin"
18608 [(set (match_operand:SI 0 "register_operand")
18609 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18610 "TARGET_RTM"
18611 {
18612 rtx_code_label *label = gen_label_rtx ();
18613
18614 /* xbegin is emitted as jump_insn, so reload won't be able
18615 to reload its operand. Force the value into AX hard register. */
18616 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18617 emit_move_insn (ax_reg, constm1_rtx);
18618
18619 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18620
18621 emit_label (label);
18622 LABEL_NUSES (label) = 1;
18623
18624 emit_move_insn (operands[0], ax_reg);
18625
18626 DONE;
18627 })
18628
18629 (define_insn "xbegin_1"
18630 [(set (pc)
18631 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18632 (const_int 0))
18633 (label_ref (match_operand 1))
18634 (pc)))
18635 (set (match_operand:SI 0 "register_operand" "+a")
18636 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18637 "TARGET_RTM"
18638 "xbegin\t%l1"
18639 [(set_attr "type" "other")
18640 (set_attr "length" "6")])
18641
18642 (define_insn "xend"
18643 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18644 "TARGET_RTM"
18645 "xend"
18646 [(set_attr "type" "other")
18647 (set_attr "length" "3")])
18648
18649 (define_insn "xabort"
18650 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18651 UNSPECV_XABORT)]
18652 "TARGET_RTM"
18653 "xabort\t%0"
18654 [(set_attr "type" "other")
18655 (set_attr "length" "3")])
18656
18657 (define_expand "xtest"
18658 [(set (match_operand:QI 0 "register_operand")
18659 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18660 "TARGET_RTM"
18661 {
18662 emit_insn (gen_xtest_1 ());
18663
18664 ix86_expand_setcc (operands[0], NE,
18665 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18666 DONE;
18667 })
18668
18669 (define_insn "xtest_1"
18670 [(set (reg:CCZ FLAGS_REG)
18671 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18672 "TARGET_RTM"
18673 "xtest"
18674 [(set_attr "type" "other")
18675 (set_attr "length" "3")])
18676
18677 (define_insn "pcommit"
18678 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18679 "TARGET_PCOMMIT"
18680 "pcommit"
18681 [(set_attr "type" "other")
18682 (set_attr "length" "4")])
18683
18684 (define_insn "clwb"
18685 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18686 UNSPECV_CLWB)]
18687 "TARGET_CLWB"
18688 "clwb\t%a0"
18689 [(set_attr "type" "sse")
18690 (set_attr "atom_sse_attr" "fence")
18691 (set_attr "memory" "unknown")])
18692
18693 (define_insn "clflushopt"
18694 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18695 UNSPECV_CLFLUSHOPT)]
18696 "TARGET_CLFLUSHOPT"
18697 "clflushopt\t%a0"
18698 [(set_attr "type" "sse")
18699 (set_attr "atom_sse_attr" "fence")
18700 (set_attr "memory" "unknown")])
18701
18702 ;; MPX instructions
18703
18704 (define_expand "<mode>_mk"
18705 [(set (match_operand:BND 0 "register_operand")
18706 (unspec:BND
18707 [(mem:<bnd_ptr>
18708 (match_par_dup 3
18709 [(match_operand:<bnd_ptr> 1 "register_operand")
18710 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18711 UNSPEC_BNDMK))]
18712 "TARGET_MPX"
18713 {
18714 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18715 operands[2]),
18716 UNSPEC_BNDMK_ADDR);
18717 })
18718
18719 (define_insn "*<mode>_mk"
18720 [(set (match_operand:BND 0 "register_operand" "=w")
18721 (unspec:BND
18722 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18723 [(unspec:<bnd_ptr>
18724 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18725 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18726 UNSPEC_BNDMK_ADDR)])]
18727 UNSPEC_BNDMK))]
18728 "TARGET_MPX"
18729 "bndmk\t{%3, %0|%0, %3}"
18730 [(set_attr "type" "mpxmk")])
18731
18732 (define_expand "mov<mode>"
18733 [(set (match_operand:BND 0 "general_operand")
18734 (match_operand:BND 1 "general_operand"))]
18735 "TARGET_MPX"
18736 {
18737 ix86_expand_move (<MODE>mode, operands);DONE;
18738 })
18739
18740 (define_insn "*mov<mode>_internal_mpx"
18741 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18742 (match_operand:BND 1 "general_operand" "wm,w"))]
18743 "TARGET_MPX"
18744 "bndmov\t{%1, %0|%0, %1}"
18745 [(set_attr "type" "mpxmov")])
18746
18747 (define_expand "<mode>_<bndcheck>"
18748 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18749 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18750 (set (match_dup 2)
18751 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18752 "TARGET_MPX"
18753 {
18754 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18755 MEM_VOLATILE_P (operands[2]) = 1;
18756 })
18757
18758 (define_insn "*<mode>_<bndcheck>"
18759 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18760 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18761 (set (match_operand:BLK 2 "bnd_mem_operator")
18762 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18763 "TARGET_MPX"
18764 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18765 [(set_attr "type" "mpxchk")])
18766
18767 (define_expand "<mode>_ldx"
18768 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18769 (unspec:BND
18770 [(mem:<bnd_ptr>
18771 (match_par_dup 3
18772 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18773 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18774 UNSPEC_BNDLDX))
18775 (use (mem:BLK (match_dup 1)))])]
18776 "TARGET_MPX"
18777 {
18778 /* Avoid registers which connot be used as index. */
18779 if (!index_register_operand (operands[2], Pmode))
18780 {
18781 rtx temp = gen_reg_rtx (Pmode);
18782 emit_move_insn (temp, operands[2]);
18783 operands[2] = temp;
18784 }
18785
18786 /* If it was a register originally then it may have
18787 mode other than Pmode. We need to extend in such
18788 case because bndldx may work only with Pmode regs. */
18789 if (GET_MODE (operands[2]) != Pmode)
18790 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18791
18792 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18793 operands[2]),
18794 UNSPEC_BNDLDX_ADDR);
18795 })
18796
18797 (define_insn "*<mode>_ldx"
18798 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18799 (unspec:BND
18800 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18801 [(unspec:<bnd_ptr>
18802 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18803 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18804 UNSPEC_BNDLDX_ADDR)])]
18805 UNSPEC_BNDLDX))
18806 (use (mem:BLK (match_dup 1)))])]
18807 "TARGET_MPX"
18808 "bndldx\t{%3, %0|%0, %3}"
18809 [(set_attr "type" "mpxld")])
18810
18811 (define_expand "<mode>_stx"
18812 [(parallel [(unspec [(mem:<bnd_ptr>
18813 (match_par_dup 3
18814 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18815 (match_operand:<bnd_ptr> 1 "register_operand")]))
18816 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18817 (set (match_dup 4)
18818 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18819 "TARGET_MPX"
18820 {
18821 /* Avoid registers which connot be used as index. */
18822 if (!index_register_operand (operands[1], Pmode))
18823 {
18824 rtx temp = gen_reg_rtx (Pmode);
18825 emit_move_insn (temp, operands[1]);
18826 operands[1] = temp;
18827 }
18828
18829 /* If it was a register originally then it may have
18830 mode other than Pmode. We need to extend in such
18831 case because bndstx may work only with Pmode regs. */
18832 if (GET_MODE (operands[1]) != Pmode)
18833 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18834
18835 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18836 operands[1]),
18837 UNSPEC_BNDLDX_ADDR);
18838 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18839 MEM_VOLATILE_P (operands[4]) = 1;
18840 })
18841
18842 (define_insn "*<mode>_stx"
18843 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18844 [(unspec:<bnd_ptr>
18845 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18846 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18847 UNSPEC_BNDLDX_ADDR)])
18848 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18849 (set (match_operand:BLK 4 "bnd_mem_operator")
18850 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18851 "TARGET_MPX"
18852 "bndstx\t{%2, %3|%3, %2}"
18853 [(set_attr "type" "mpxst")])
18854
18855 (define_insn "move_size_reloc_<mode>"
18856 [(set (match_operand:SWI48 0 "register_operand" "=r")
18857 (unspec:SWI48
18858 [(match_operand:SWI48 1 "symbol_operand")]
18859 UNSPEC_SIZEOF))]
18860 "TARGET_MPX"
18861 {
18862 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18863 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18864 else
18865 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18866 }
18867 [(set_attr "type" "imov")
18868 (set_attr "mode" "<MODE>")])
18869
18870 (include "mmx.md")
18871 (include "sse.md")
18872 (include "sync.md")