a67a5e715c157bc734a02ded9c46be8a11bcafd2
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81
82 ;; Prologue support
83 UNSPEC_STACK_ALLOC
84 UNSPEC_SET_GOT
85 UNSPEC_REG_SAVE
86 UNSPEC_DEF_CFA
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_MS_TO_SYSV_CALL
112 UNSPEC_CALL_NEEDS_VZEROUPPER
113 UNSPEC_PAUSE
114
115 ;; For SSE/MMX support:
116 UNSPEC_FIX_NOTRUNC
117 UNSPEC_MASKMOV
118 UNSPEC_MOVMSK
119 UNSPEC_RCP
120 UNSPEC_RSQRT
121 UNSPEC_PSADBW
122
123 ;; Generic math support
124 UNSPEC_COPYSIGN
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
127
128 ;; x87 Floating point
129 UNSPEC_SIN
130 UNSPEC_COS
131 UNSPEC_FPATAN
132 UNSPEC_FYL2X
133 UNSPEC_FYL2XP1
134 UNSPEC_FRNDINT
135 UNSPEC_FIST
136 UNSPEC_F2XM1
137 UNSPEC_TAN
138 UNSPEC_FXAM
139
140 ;; x87 Rounding
141 UNSPEC_FRNDINT_FLOOR
142 UNSPEC_FRNDINT_CEIL
143 UNSPEC_FRNDINT_TRUNC
144 UNSPEC_FRNDINT_MASK_PM
145 UNSPEC_FIST_FLOOR
146 UNSPEC_FIST_CEIL
147
148 ;; x87 Double output FP
149 UNSPEC_SINCOS_COS
150 UNSPEC_SINCOS_SIN
151 UNSPEC_XTRACT_FRACT
152 UNSPEC_XTRACT_EXP
153 UNSPEC_FSCALE_FRACT
154 UNSPEC_FSCALE_EXP
155 UNSPEC_FPREM_F
156 UNSPEC_FPREM_U
157 UNSPEC_FPREM1_F
158 UNSPEC_FPREM1_U
159
160 UNSPEC_C2_FLAG
161 UNSPEC_FXAM_MEM
162
163 ;; SSP patterns
164 UNSPEC_SP_SET
165 UNSPEC_SP_TEST
166 UNSPEC_SP_TLS_SET
167 UNSPEC_SP_TLS_TEST
168
169 ;; For ROUND support
170 UNSPEC_ROUND
171
172 ;; For CRC32 support
173 UNSPEC_CRC32
174
175 ;; For RDRAND support
176 UNSPEC_RDRAND
177
178 ;; For BMI support
179 UNSPEC_BEXTR
180
181 ;; For BMI2 support
182 UNSPEC_PDEP
183 UNSPEC_PEXT
184 ])
185
186 (define_c_enum "unspecv" [
187 UNSPECV_BLOCKAGE
188 UNSPECV_STACK_PROBE
189 UNSPECV_PROBE_STACK_RANGE
190 UNSPECV_ALIGN
191 UNSPECV_PROLOGUE_USE
192 UNSPECV_SPLIT_STACK_RETURN
193 UNSPECV_CLD
194 UNSPECV_NOPS
195 UNSPECV_RDTSC
196 UNSPECV_RDTSCP
197 UNSPECV_RDPMC
198 UNSPECV_LLWP_INTRINSIC
199 UNSPECV_SLWP_INTRINSIC
200 UNSPECV_LWPVAL_INTRINSIC
201 UNSPECV_LWPINS_INTRINSIC
202 UNSPECV_RDFSBASE
203 UNSPECV_RDGSBASE
204 UNSPECV_WRFSBASE
205 UNSPECV_WRGSBASE
206 ])
207
208 ;; Constants to represent rounding modes in the ROUND instruction
209 (define_constants
210 [(ROUND_FLOOR 0x1)
211 (ROUND_CEIL 0x2)
212 (ROUND_TRUNC 0x3)
213 (ROUND_MXCSR 0x4)
214 (ROUND_NO_EXC 0x8)
215 ])
216
217 ;; Constants to represent pcomtrue/pcomfalse variants
218 (define_constants
219 [(PCOM_FALSE 0)
220 (PCOM_TRUE 1)
221 (COM_FALSE_S 2)
222 (COM_FALSE_P 3)
223 (COM_TRUE_S 4)
224 (COM_TRUE_P 5)
225 ])
226
227 ;; Constants used in the XOP pperm instruction
228 (define_constants
229 [(PPERM_SRC 0x00) /* copy source */
230 (PPERM_INVERT 0x20) /* invert source */
231 (PPERM_REVERSE 0x40) /* bit reverse source */
232 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
233 (PPERM_ZERO 0x80) /* all 0's */
234 (PPERM_ONES 0xa0) /* all 1's */
235 (PPERM_SIGN 0xc0) /* propagate sign bit */
236 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
237 (PPERM_SRC1 0x00) /* use first source byte */
238 (PPERM_SRC2 0x10) /* use second source byte */
239 ])
240
241 ;; Registers by name.
242 (define_constants
243 [(AX_REG 0)
244 (DX_REG 1)
245 (CX_REG 2)
246 (BX_REG 3)
247 (SI_REG 4)
248 (DI_REG 5)
249 (BP_REG 6)
250 (SP_REG 7)
251 (ST0_REG 8)
252 (ST1_REG 9)
253 (ST2_REG 10)
254 (ST3_REG 11)
255 (ST4_REG 12)
256 (ST5_REG 13)
257 (ST6_REG 14)
258 (ST7_REG 15)
259 (FLAGS_REG 17)
260 (FPSR_REG 18)
261 (FPCR_REG 19)
262 (XMM0_REG 21)
263 (XMM1_REG 22)
264 (XMM2_REG 23)
265 (XMM3_REG 24)
266 (XMM4_REG 25)
267 (XMM5_REG 26)
268 (XMM6_REG 27)
269 (XMM7_REG 28)
270 (MM0_REG 29)
271 (MM1_REG 30)
272 (MM2_REG 31)
273 (MM3_REG 32)
274 (MM4_REG 33)
275 (MM5_REG 34)
276 (MM6_REG 35)
277 (MM7_REG 36)
278 (R8_REG 37)
279 (R9_REG 38)
280 (R10_REG 39)
281 (R11_REG 40)
282 (R12_REG 41)
283 (R13_REG 42)
284 (XMM8_REG 45)
285 (XMM9_REG 46)
286 (XMM10_REG 47)
287 (XMM11_REG 48)
288 (XMM12_REG 49)
289 (XMM13_REG 50)
290 (XMM14_REG 51)
291 (XMM15_REG 52)
292 ])
293
294 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
295 ;; from i386.c.
296
297 ;; In C guard expressions, put expressions which may be compile-time
298 ;; constants first. This allows for better optimization. For
299 ;; example, write "TARGET_64BIT && reload_completed", not
300 ;; "reload_completed && TARGET_64BIT".
301
302 \f
303 ;; Processor type.
304 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
305 atom,generic64,amdfam10,bdver1,bdver2,btver1"
306 (const (symbol_ref "ix86_schedule")))
307
308 ;; A basic instruction type. Refinements due to arguments to be
309 ;; provided in other attributes.
310 (define_attr "type"
311 "other,multi,
312 alu,alu1,negnot,imov,imovx,lea,
313 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
314 icmp,test,ibr,setcc,icmov,
315 push,pop,call,callv,leave,
316 str,bitmanip,
317 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
318 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
319 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
320 ssemuladd,sse4arg,lwp,
321 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
322 (const_string "other"))
323
324 ;; Main data type used by the insn
325 (define_attr "mode"
326 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
327 (const_string "unknown"))
328
329 ;; The CPU unit operations uses.
330 (define_attr "unit" "integer,i387,sse,mmx,unknown"
331 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
332 (const_string "i387")
333 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
334 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
335 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
336 (const_string "sse")
337 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
338 (const_string "mmx")
339 (eq_attr "type" "other")
340 (const_string "unknown")]
341 (const_string "integer")))
342
343 ;; The (bounding maximum) length of an instruction immediate.
344 (define_attr "length_immediate" ""
345 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
346 bitmanip,imulx")
347 (const_int 0)
348 (eq_attr "unit" "i387,sse,mmx")
349 (const_int 0)
350 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
351 rotate,rotatex,rotate1,imul,icmp,push,pop")
352 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
353 (eq_attr "type" "imov,test")
354 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
355 (eq_attr "type" "call")
356 (if_then_else (match_operand 0 "constant_call_address_operand" "")
357 (const_int 4)
358 (const_int 0))
359 (eq_attr "type" "callv")
360 (if_then_else (match_operand 1 "constant_call_address_operand" "")
361 (const_int 4)
362 (const_int 0))
363 ;; We don't know the size before shorten_branches. Expect
364 ;; the instruction to fit for better scheduling.
365 (eq_attr "type" "ibr")
366 (const_int 1)
367 ]
368 (symbol_ref "/* Update immediate_length and other attributes! */
369 gcc_unreachable (),1")))
370
371 ;; The (bounding maximum) length of an instruction address.
372 (define_attr "length_address" ""
373 (cond [(eq_attr "type" "str,other,multi,fxch")
374 (const_int 0)
375 (and (eq_attr "type" "call")
376 (match_operand 0 "constant_call_address_operand" ""))
377 (const_int 0)
378 (and (eq_attr "type" "callv")
379 (match_operand 1 "constant_call_address_operand" ""))
380 (const_int 0)
381 ]
382 (symbol_ref "ix86_attr_length_address_default (insn)")))
383
384 ;; Set when length prefix is used.
385 (define_attr "prefix_data16" ""
386 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
387 (const_int 0)
388 (eq_attr "mode" "HI")
389 (const_int 1)
390 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
391 (const_int 1)
392 ]
393 (const_int 0)))
394
395 ;; Set when string REP prefix is used.
396 (define_attr "prefix_rep" ""
397 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
398 (const_int 0)
399 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
400 (const_int 1)
401 ]
402 (const_int 0)))
403
404 ;; Set when 0f opcode prefix is used.
405 (define_attr "prefix_0f" ""
406 (if_then_else
407 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
408 (eq_attr "unit" "sse,mmx"))
409 (const_int 1)
410 (const_int 0)))
411
412 ;; Set when REX opcode prefix is used.
413 (define_attr "prefix_rex" ""
414 (cond [(not (match_test "TARGET_64BIT"))
415 (const_int 0)
416 (and (eq_attr "mode" "DI")
417 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
418 (eq_attr "unit" "!mmx")))
419 (const_int 1)
420 (and (eq_attr "mode" "QI")
421 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
422 (const_int 1)
423 (match_test "x86_extended_reg_mentioned_p (insn)")
424 (const_int 1)
425 (and (eq_attr "type" "imovx")
426 (match_operand:QI 1 "ext_QIreg_operand" ""))
427 (const_int 1)
428 ]
429 (const_int 0)))
430
431 ;; There are also additional prefixes in 3DNOW, SSSE3.
432 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
433 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
434 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
435 (define_attr "prefix_extra" ""
436 (cond [(eq_attr "type" "ssemuladd,sse4arg")
437 (const_int 2)
438 (eq_attr "type" "sseiadd1,ssecvt1")
439 (const_int 1)
440 ]
441 (const_int 0)))
442
443 ;; Prefix used: original, VEX or maybe VEX.
444 (define_attr "prefix" "orig,vex,maybe_vex"
445 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
446 (const_string "vex")
447 (const_string "orig")))
448
449 ;; VEX W bit is used.
450 (define_attr "prefix_vex_w" "" (const_int 0))
451
452 ;; The length of VEX prefix
453 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
454 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
455 ;; still prefix_0f 1, with prefix_extra 1.
456 (define_attr "length_vex" ""
457 (if_then_else (and (eq_attr "prefix_0f" "1")
458 (eq_attr "prefix_extra" "0"))
459 (if_then_else (eq_attr "prefix_vex_w" "1")
460 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
461 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
462 (if_then_else (eq_attr "prefix_vex_w" "1")
463 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
464 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
465
466 ;; Set when modrm byte is used.
467 (define_attr "modrm" ""
468 (cond [(eq_attr "type" "str,leave")
469 (const_int 0)
470 (eq_attr "unit" "i387")
471 (const_int 0)
472 (and (eq_attr "type" "incdec")
473 (and (not (match_test "TARGET_64BIT"))
474 (ior (match_operand:SI 1 "register_operand" "")
475 (match_operand:HI 1 "register_operand" ""))))
476 (const_int 0)
477 (and (eq_attr "type" "push")
478 (not (match_operand 1 "memory_operand" "")))
479 (const_int 0)
480 (and (eq_attr "type" "pop")
481 (not (match_operand 0 "memory_operand" "")))
482 (const_int 0)
483 (and (eq_attr "type" "imov")
484 (and (not (eq_attr "mode" "DI"))
485 (ior (and (match_operand 0 "register_operand" "")
486 (match_operand 1 "immediate_operand" ""))
487 (ior (and (match_operand 0 "ax_reg_operand" "")
488 (match_operand 1 "memory_displacement_only_operand" ""))
489 (and (match_operand 0 "memory_displacement_only_operand" "")
490 (match_operand 1 "ax_reg_operand" ""))))))
491 (const_int 0)
492 (and (eq_attr "type" "call")
493 (match_operand 0 "constant_call_address_operand" ""))
494 (const_int 0)
495 (and (eq_attr "type" "callv")
496 (match_operand 1 "constant_call_address_operand" ""))
497 (const_int 0)
498 (and (eq_attr "type" "alu,alu1,icmp,test")
499 (match_operand 0 "ax_reg_operand" ""))
500 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
501 ]
502 (const_int 1)))
503
504 ;; The (bounding maximum) length of an instruction in bytes.
505 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
506 ;; Later we may want to split them and compute proper length as for
507 ;; other insns.
508 (define_attr "length" ""
509 (cond [(eq_attr "type" "other,multi,fistp,frndint")
510 (const_int 16)
511 (eq_attr "type" "fcmp")
512 (const_int 4)
513 (eq_attr "unit" "i387")
514 (plus (const_int 2)
515 (plus (attr "prefix_data16")
516 (attr "length_address")))
517 (ior (eq_attr "prefix" "vex")
518 (and (eq_attr "prefix" "maybe_vex")
519 (match_test "TARGET_AVX")))
520 (plus (attr "length_vex")
521 (plus (attr "length_immediate")
522 (plus (attr "modrm")
523 (attr "length_address"))))]
524 (plus (plus (attr "modrm")
525 (plus (attr "prefix_0f")
526 (plus (attr "prefix_rex")
527 (plus (attr "prefix_extra")
528 (const_int 1)))))
529 (plus (attr "prefix_rep")
530 (plus (attr "prefix_data16")
531 (plus (attr "length_immediate")
532 (attr "length_address")))))))
533
534 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
535 ;; `store' if there is a simple memory reference therein, or `unknown'
536 ;; if the instruction is complex.
537
538 (define_attr "memory" "none,load,store,both,unknown"
539 (cond [(eq_attr "type" "other,multi,str,lwp")
540 (const_string "unknown")
541 (eq_attr "type" "lea,fcmov,fpspc")
542 (const_string "none")
543 (eq_attr "type" "fistp,leave")
544 (const_string "both")
545 (eq_attr "type" "frndint")
546 (const_string "load")
547 (eq_attr "type" "push")
548 (if_then_else (match_operand 1 "memory_operand" "")
549 (const_string "both")
550 (const_string "store"))
551 (eq_attr "type" "pop")
552 (if_then_else (match_operand 0 "memory_operand" "")
553 (const_string "both")
554 (const_string "load"))
555 (eq_attr "type" "setcc")
556 (if_then_else (match_operand 0 "memory_operand" "")
557 (const_string "store")
558 (const_string "none"))
559 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
560 (if_then_else (ior (match_operand 0 "memory_operand" "")
561 (match_operand 1 "memory_operand" ""))
562 (const_string "load")
563 (const_string "none"))
564 (eq_attr "type" "ibr")
565 (if_then_else (match_operand 0 "memory_operand" "")
566 (const_string "load")
567 (const_string "none"))
568 (eq_attr "type" "call")
569 (if_then_else (match_operand 0 "constant_call_address_operand" "")
570 (const_string "none")
571 (const_string "load"))
572 (eq_attr "type" "callv")
573 (if_then_else (match_operand 1 "constant_call_address_operand" "")
574 (const_string "none")
575 (const_string "load"))
576 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
577 (match_operand 1 "memory_operand" ""))
578 (const_string "both")
579 (and (match_operand 0 "memory_operand" "")
580 (match_operand 1 "memory_operand" ""))
581 (const_string "both")
582 (match_operand 0 "memory_operand" "")
583 (const_string "store")
584 (match_operand 1 "memory_operand" "")
585 (const_string "load")
586 (and (eq_attr "type"
587 "!alu1,negnot,ishift1,
588 imov,imovx,icmp,test,bitmanip,
589 fmov,fcmp,fsgn,
590 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
591 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
592 (match_operand 2 "memory_operand" ""))
593 (const_string "load")
594 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
595 (match_operand 3 "memory_operand" ""))
596 (const_string "load")
597 ]
598 (const_string "none")))
599
600 ;; Indicates if an instruction has both an immediate and a displacement.
601
602 (define_attr "imm_disp" "false,true,unknown"
603 (cond [(eq_attr "type" "other,multi")
604 (const_string "unknown")
605 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
606 (and (match_operand 0 "memory_displacement_operand" "")
607 (match_operand 1 "immediate_operand" "")))
608 (const_string "true")
609 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
610 (and (match_operand 0 "memory_displacement_operand" "")
611 (match_operand 2 "immediate_operand" "")))
612 (const_string "true")
613 ]
614 (const_string "false")))
615
616 ;; Indicates if an FP operation has an integer source.
617
618 (define_attr "fp_int_src" "false,true"
619 (const_string "false"))
620
621 ;; Defines rounding mode of an FP operation.
622
623 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
624 (const_string "any"))
625
626 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
627 (define_attr "use_carry" "0,1" (const_string "0"))
628
629 ;; Define attribute to indicate unaligned ssemov insns
630 (define_attr "movu" "0,1" (const_string "0"))
631
632 ;; Used to control the "enabled" attribute on a per-instruction basis.
633 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
634 (const_string "base"))
635
636 (define_attr "enabled" ""
637 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
638 (eq_attr "isa" "sse2_noavx")
639 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
640 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
641 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
642 (eq_attr "isa" "sse4_noavx")
643 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
644 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
645 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
646 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
647 ]
648 (const_int 1)))
649
650 ;; Describe a user's asm statement.
651 (define_asm_attributes
652 [(set_attr "length" "128")
653 (set_attr "type" "multi")])
654
655 (define_code_iterator plusminus [plus minus])
656
657 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
658
659 ;; Base name for define_insn
660 (define_code_attr plusminus_insn
661 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
662 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
663
664 ;; Base name for insn mnemonic.
665 (define_code_attr plusminus_mnemonic
666 [(plus "add") (ss_plus "adds") (us_plus "addus")
667 (minus "sub") (ss_minus "subs") (us_minus "subus")])
668 (define_code_attr plusminus_carry_mnemonic
669 [(plus "adc") (minus "sbb")])
670
671 ;; Mark commutative operators as such in constraints.
672 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
673 (minus "") (ss_minus "") (us_minus "")])
674
675 ;; Mapping of max and min
676 (define_code_iterator maxmin [smax smin umax umin])
677
678 ;; Mapping of signed max and min
679 (define_code_iterator smaxmin [smax smin])
680
681 ;; Mapping of unsigned max and min
682 (define_code_iterator umaxmin [umax umin])
683
684 ;; Base name for integer and FP insn mnemonic
685 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
686 (umax "maxu") (umin "minu")])
687 (define_code_attr maxmin_float [(smax "max") (smin "min")])
688
689 ;; Mapping of logic operators
690 (define_code_iterator any_logic [and ior xor])
691 (define_code_iterator any_or [ior xor])
692
693 ;; Base name for insn mnemonic.
694 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
695
696 ;; Mapping of logic-shift operators
697 (define_code_iterator any_lshift [ashift lshiftrt])
698
699 ;; Mapping of shift-right operators
700 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
701
702 ;; Base name for define_insn
703 (define_code_attr shift_insn
704 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
705
706 ;; Base name for insn mnemonic.
707 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
708 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
709
710 ;; Mapping of rotate operators
711 (define_code_iterator any_rotate [rotate rotatert])
712
713 ;; Base name for define_insn
714 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
715
716 ;; Base name for insn mnemonic.
717 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
718
719 ;; Mapping of abs neg operators
720 (define_code_iterator absneg [abs neg])
721
722 ;; Base name for x87 insn mnemonic.
723 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
724
725 ;; Used in signed and unsigned widening multiplications.
726 (define_code_iterator any_extend [sign_extend zero_extend])
727
728 ;; Prefix for insn menmonic.
729 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
730
731 ;; Prefix for define_insn
732 (define_code_attr u [(sign_extend "") (zero_extend "u")])
733 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
734
735 ;; All integer modes.
736 (define_mode_iterator SWI1248x [QI HI SI DI])
737
738 ;; All integer modes without QImode.
739 (define_mode_iterator SWI248x [HI SI DI])
740
741 ;; All integer modes without QImode and HImode.
742 (define_mode_iterator SWI48x [SI DI])
743
744 ;; All integer modes without SImode and DImode.
745 (define_mode_iterator SWI12 [QI HI])
746
747 ;; All integer modes without DImode.
748 (define_mode_iterator SWI124 [QI HI SI])
749
750 ;; All integer modes without QImode and DImode.
751 (define_mode_iterator SWI24 [HI SI])
752
753 ;; Single word integer modes.
754 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
755
756 ;; Single word integer modes without QImode.
757 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
758
759 ;; Single word integer modes without QImode and HImode.
760 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
761
762 ;; All math-dependant single and double word integer modes.
763 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
764 (HI "TARGET_HIMODE_MATH")
765 SI DI (TI "TARGET_64BIT")])
766
767 ;; Math-dependant single word integer modes.
768 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
769 (HI "TARGET_HIMODE_MATH")
770 SI (DI "TARGET_64BIT")])
771
772 ;; Math-dependant integer modes without DImode.
773 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
774 (HI "TARGET_HIMODE_MATH")
775 SI])
776
777 ;; Math-dependant single word integer modes without QImode.
778 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
779 SI (DI "TARGET_64BIT")])
780
781 ;; Double word integer modes.
782 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
783 (TI "TARGET_64BIT")])
784
785 ;; Double word integer modes as mode attribute.
786 (define_mode_attr DWI [(SI "DI") (DI "TI")])
787 (define_mode_attr dwi [(SI "di") (DI "ti")])
788
789 ;; Half mode for double word integer modes.
790 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
791 (DI "TARGET_64BIT")])
792
793 ;; Instruction suffix for integer modes.
794 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
795
796 ;; Pointer size prefix for integer modes (Intel asm dialect)
797 (define_mode_attr iptrsize [(QI "BYTE")
798 (HI "WORD")
799 (SI "DWORD")
800 (DI "QWORD")])
801
802 ;; Register class for integer modes.
803 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
804
805 ;; Immediate operand constraint for integer modes.
806 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
807
808 ;; General operand constraint for word modes.
809 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
810
811 ;; Immediate operand constraint for double integer modes.
812 (define_mode_attr di [(SI "nF") (DI "e")])
813
814 ;; Immediate operand constraint for shifts.
815 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
816
817 ;; General operand predicate for integer modes.
818 (define_mode_attr general_operand
819 [(QI "general_operand")
820 (HI "general_operand")
821 (SI "x86_64_general_operand")
822 (DI "x86_64_general_operand")
823 (TI "x86_64_general_operand")])
824
825 ;; General sign/zero extend operand predicate for integer modes.
826 (define_mode_attr general_szext_operand
827 [(QI "general_operand")
828 (HI "general_operand")
829 (SI "x86_64_szext_general_operand")
830 (DI "x86_64_szext_general_operand")])
831
832 ;; Immediate operand predicate for integer modes.
833 (define_mode_attr immediate_operand
834 [(QI "immediate_operand")
835 (HI "immediate_operand")
836 (SI "x86_64_immediate_operand")
837 (DI "x86_64_immediate_operand")])
838
839 ;; Nonmemory operand predicate for integer modes.
840 (define_mode_attr nonmemory_operand
841 [(QI "nonmemory_operand")
842 (HI "nonmemory_operand")
843 (SI "x86_64_nonmemory_operand")
844 (DI "x86_64_nonmemory_operand")])
845
846 ;; Operand predicate for shifts.
847 (define_mode_attr shift_operand
848 [(QI "nonimmediate_operand")
849 (HI "nonimmediate_operand")
850 (SI "nonimmediate_operand")
851 (DI "shiftdi_operand")
852 (TI "register_operand")])
853
854 ;; Operand predicate for shift argument.
855 (define_mode_attr shift_immediate_operand
856 [(QI "const_1_to_31_operand")
857 (HI "const_1_to_31_operand")
858 (SI "const_1_to_31_operand")
859 (DI "const_1_to_63_operand")])
860
861 ;; Input operand predicate for arithmetic left shifts.
862 (define_mode_attr ashl_input_operand
863 [(QI "nonimmediate_operand")
864 (HI "nonimmediate_operand")
865 (SI "nonimmediate_operand")
866 (DI "ashldi_input_operand")
867 (TI "reg_or_pm1_operand")])
868
869 ;; SSE and x87 SFmode and DFmode floating point modes
870 (define_mode_iterator MODEF [SF DF])
871
872 ;; All x87 floating point modes
873 (define_mode_iterator X87MODEF [SF DF XF])
874
875 ;; SSE instruction suffix for various modes
876 (define_mode_attr ssemodesuffix
877 [(SF "ss") (DF "sd")
878 (V8SF "ps") (V4DF "pd")
879 (V4SF "ps") (V2DF "pd")
880 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
881 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
882
883 ;; SSE vector suffix for floating point modes
884 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
885
886 ;; SSE vector mode corresponding to a scalar mode
887 (define_mode_attr ssevecmode
888 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
889
890 ;; Instruction suffix for REX 64bit operators.
891 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
892
893 ;; This mode iterator allows :P to be used for patterns that operate on
894 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
895 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
896
897 ;; This mode iterator allows :PTR to be used for patterns that operate on
898 ;; ptr_mode sized quantities.
899 (define_mode_iterator PTR
900 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
901 \f
902 ;; Scheduling descriptions
903
904 (include "pentium.md")
905 (include "ppro.md")
906 (include "k6.md")
907 (include "athlon.md")
908 (include "bdver1.md")
909 (include "geode.md")
910 (include "atom.md")
911 (include "core2.md")
912
913 \f
914 ;; Operand and operator predicates and constraints
915
916 (include "predicates.md")
917 (include "constraints.md")
918
919 \f
920 ;; Compare and branch/compare and store instructions.
921
922 (define_expand "cbranch<mode>4"
923 [(set (reg:CC FLAGS_REG)
924 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
925 (match_operand:SDWIM 2 "<general_operand>" "")))
926 (set (pc) (if_then_else
927 (match_operator 0 "ordered_comparison_operator"
928 [(reg:CC FLAGS_REG) (const_int 0)])
929 (label_ref (match_operand 3 "" ""))
930 (pc)))]
931 ""
932 {
933 if (MEM_P (operands[1]) && MEM_P (operands[2]))
934 operands[1] = force_reg (<MODE>mode, operands[1]);
935 ix86_expand_branch (GET_CODE (operands[0]),
936 operands[1], operands[2], operands[3]);
937 DONE;
938 })
939
940 (define_expand "cstore<mode>4"
941 [(set (reg:CC FLAGS_REG)
942 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
943 (match_operand:SWIM 3 "<general_operand>" "")))
944 (set (match_operand:QI 0 "register_operand" "")
945 (match_operator 1 "ordered_comparison_operator"
946 [(reg:CC FLAGS_REG) (const_int 0)]))]
947 ""
948 {
949 if (MEM_P (operands[2]) && MEM_P (operands[3]))
950 operands[2] = force_reg (<MODE>mode, operands[2]);
951 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
952 operands[2], operands[3]);
953 DONE;
954 })
955
956 (define_expand "cmp<mode>_1"
957 [(set (reg:CC FLAGS_REG)
958 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
959 (match_operand:SWI48 1 "<general_operand>" "")))])
960
961 (define_insn "*cmp<mode>_ccno_1"
962 [(set (reg FLAGS_REG)
963 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
964 (match_operand:SWI 1 "const0_operand" "")))]
965 "ix86_match_ccmode (insn, CCNOmode)"
966 "@
967 test{<imodesuffix>}\t%0, %0
968 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
969 [(set_attr "type" "test,icmp")
970 (set_attr "length_immediate" "0,1")
971 (set_attr "mode" "<MODE>")])
972
973 (define_insn "*cmp<mode>_1"
974 [(set (reg FLAGS_REG)
975 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
976 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
977 "ix86_match_ccmode (insn, CCmode)"
978 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
979 [(set_attr "type" "icmp")
980 (set_attr "mode" "<MODE>")])
981
982 (define_insn "*cmp<mode>_minus_1"
983 [(set (reg FLAGS_REG)
984 (compare
985 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
986 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
987 (const_int 0)))]
988 "ix86_match_ccmode (insn, CCGOCmode)"
989 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
990 [(set_attr "type" "icmp")
991 (set_attr "mode" "<MODE>")])
992
993 (define_insn "*cmpqi_ext_1"
994 [(set (reg FLAGS_REG)
995 (compare
996 (match_operand:QI 0 "general_operand" "Qm")
997 (subreg:QI
998 (zero_extract:SI
999 (match_operand 1 "ext_register_operand" "Q")
1000 (const_int 8)
1001 (const_int 8)) 0)))]
1002 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1003 "cmp{b}\t{%h1, %0|%0, %h1}"
1004 [(set_attr "type" "icmp")
1005 (set_attr "mode" "QI")])
1006
1007 (define_insn "*cmpqi_ext_1_rex64"
1008 [(set (reg FLAGS_REG)
1009 (compare
1010 (match_operand:QI 0 "register_operand" "Q")
1011 (subreg:QI
1012 (zero_extract:SI
1013 (match_operand 1 "ext_register_operand" "Q")
1014 (const_int 8)
1015 (const_int 8)) 0)))]
1016 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1017 "cmp{b}\t{%h1, %0|%0, %h1}"
1018 [(set_attr "type" "icmp")
1019 (set_attr "mode" "QI")])
1020
1021 (define_insn "*cmpqi_ext_2"
1022 [(set (reg FLAGS_REG)
1023 (compare
1024 (subreg:QI
1025 (zero_extract:SI
1026 (match_operand 0 "ext_register_operand" "Q")
1027 (const_int 8)
1028 (const_int 8)) 0)
1029 (match_operand:QI 1 "const0_operand" "")))]
1030 "ix86_match_ccmode (insn, CCNOmode)"
1031 "test{b}\t%h0, %h0"
1032 [(set_attr "type" "test")
1033 (set_attr "length_immediate" "0")
1034 (set_attr "mode" "QI")])
1035
1036 (define_expand "cmpqi_ext_3"
1037 [(set (reg:CC FLAGS_REG)
1038 (compare:CC
1039 (subreg:QI
1040 (zero_extract:SI
1041 (match_operand 0 "ext_register_operand" "")
1042 (const_int 8)
1043 (const_int 8)) 0)
1044 (match_operand:QI 1 "immediate_operand" "")))])
1045
1046 (define_insn "*cmpqi_ext_3_insn"
1047 [(set (reg FLAGS_REG)
1048 (compare
1049 (subreg:QI
1050 (zero_extract:SI
1051 (match_operand 0 "ext_register_operand" "Q")
1052 (const_int 8)
1053 (const_int 8)) 0)
1054 (match_operand:QI 1 "general_operand" "Qmn")))]
1055 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%1, %h0|%h0, %1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "modrm" "1")
1059 (set_attr "mode" "QI")])
1060
1061 (define_insn "*cmpqi_ext_3_insn_rex64"
1062 [(set (reg FLAGS_REG)
1063 (compare
1064 (subreg:QI
1065 (zero_extract:SI
1066 (match_operand 0 "ext_register_operand" "Q")
1067 (const_int 8)
1068 (const_int 8)) 0)
1069 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1070 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1071 "cmp{b}\t{%1, %h0|%h0, %1}"
1072 [(set_attr "type" "icmp")
1073 (set_attr "modrm" "1")
1074 (set_attr "mode" "QI")])
1075
1076 (define_insn "*cmpqi_ext_4"
1077 [(set (reg FLAGS_REG)
1078 (compare
1079 (subreg:QI
1080 (zero_extract:SI
1081 (match_operand 0 "ext_register_operand" "Q")
1082 (const_int 8)
1083 (const_int 8)) 0)
1084 (subreg:QI
1085 (zero_extract:SI
1086 (match_operand 1 "ext_register_operand" "Q")
1087 (const_int 8)
1088 (const_int 8)) 0)))]
1089 "ix86_match_ccmode (insn, CCmode)"
1090 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "mode" "QI")])
1093
1094 ;; These implement float point compares.
1095 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1096 ;; which would allow mix and match FP modes on the compares. Which is what
1097 ;; the old patterns did, but with many more of them.
1098
1099 (define_expand "cbranchxf4"
1100 [(set (reg:CC FLAGS_REG)
1101 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1102 (match_operand:XF 2 "nonmemory_operand" "")))
1103 (set (pc) (if_then_else
1104 (match_operator 0 "ix86_fp_comparison_operator"
1105 [(reg:CC FLAGS_REG)
1106 (const_int 0)])
1107 (label_ref (match_operand 3 "" ""))
1108 (pc)))]
1109 "TARGET_80387"
1110 {
1111 ix86_expand_branch (GET_CODE (operands[0]),
1112 operands[1], operands[2], operands[3]);
1113 DONE;
1114 })
1115
1116 (define_expand "cstorexf4"
1117 [(set (reg:CC FLAGS_REG)
1118 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1119 (match_operand:XF 3 "nonmemory_operand" "")))
1120 (set (match_operand:QI 0 "register_operand" "")
1121 (match_operator 1 "ix86_fp_comparison_operator"
1122 [(reg:CC FLAGS_REG)
1123 (const_int 0)]))]
1124 "TARGET_80387"
1125 {
1126 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1127 operands[2], operands[3]);
1128 DONE;
1129 })
1130
1131 (define_expand "cbranch<mode>4"
1132 [(set (reg:CC FLAGS_REG)
1133 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1134 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1135 (set (pc) (if_then_else
1136 (match_operator 0 "ix86_fp_comparison_operator"
1137 [(reg:CC FLAGS_REG)
1138 (const_int 0)])
1139 (label_ref (match_operand 3 "" ""))
1140 (pc)))]
1141 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1142 {
1143 ix86_expand_branch (GET_CODE (operands[0]),
1144 operands[1], operands[2], operands[3]);
1145 DONE;
1146 })
1147
1148 (define_expand "cstore<mode>4"
1149 [(set (reg:CC FLAGS_REG)
1150 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1151 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1152 (set (match_operand:QI 0 "register_operand" "")
1153 (match_operator 1 "ix86_fp_comparison_operator"
1154 [(reg:CC FLAGS_REG)
1155 (const_int 0)]))]
1156 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157 {
1158 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1159 operands[2], operands[3]);
1160 DONE;
1161 })
1162
1163 (define_expand "cbranchcc4"
1164 [(set (pc) (if_then_else
1165 (match_operator 0 "comparison_operator"
1166 [(match_operand 1 "flags_reg_operand" "")
1167 (match_operand 2 "const0_operand" "")])
1168 (label_ref (match_operand 3 "" ""))
1169 (pc)))]
1170 ""
1171 {
1172 ix86_expand_branch (GET_CODE (operands[0]),
1173 operands[1], operands[2], operands[3]);
1174 DONE;
1175 })
1176
1177 (define_expand "cstorecc4"
1178 [(set (match_operand:QI 0 "register_operand" "")
1179 (match_operator 1 "comparison_operator"
1180 [(match_operand 2 "flags_reg_operand" "")
1181 (match_operand 3 "const0_operand" "")]))]
1182 ""
1183 {
1184 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1185 operands[2], operands[3]);
1186 DONE;
1187 })
1188
1189
1190 ;; FP compares, step 1:
1191 ;; Set the FP condition codes.
1192 ;;
1193 ;; CCFPmode compare with exceptions
1194 ;; CCFPUmode compare with no exceptions
1195
1196 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1197 ;; used to manage the reg stack popping would not be preserved.
1198
1199 (define_insn "*cmpfp_0"
1200 [(set (match_operand:HI 0 "register_operand" "=a")
1201 (unspec:HI
1202 [(compare:CCFP
1203 (match_operand 1 "register_operand" "f")
1204 (match_operand 2 "const0_operand" ""))]
1205 UNSPEC_FNSTSW))]
1206 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1207 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1208 "* return output_fp_compare (insn, operands, false, false);"
1209 [(set_attr "type" "multi")
1210 (set_attr "unit" "i387")
1211 (set (attr "mode")
1212 (cond [(match_operand:SF 1 "" "")
1213 (const_string "SF")
1214 (match_operand:DF 1 "" "")
1215 (const_string "DF")
1216 ]
1217 (const_string "XF")))])
1218
1219 (define_insn_and_split "*cmpfp_0_cc"
1220 [(set (reg:CCFP FLAGS_REG)
1221 (compare:CCFP
1222 (match_operand 1 "register_operand" "f")
1223 (match_operand 2 "const0_operand" "")))
1224 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1225 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1226 && TARGET_SAHF && !TARGET_CMOVE
1227 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1228 "#"
1229 "&& reload_completed"
1230 [(set (match_dup 0)
1231 (unspec:HI
1232 [(compare:CCFP (match_dup 1)(match_dup 2))]
1233 UNSPEC_FNSTSW))
1234 (set (reg:CC FLAGS_REG)
1235 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1236 ""
1237 [(set_attr "type" "multi")
1238 (set_attr "unit" "i387")
1239 (set (attr "mode")
1240 (cond [(match_operand:SF 1 "" "")
1241 (const_string "SF")
1242 (match_operand:DF 1 "" "")
1243 (const_string "DF")
1244 ]
1245 (const_string "XF")))])
1246
1247 (define_insn "*cmpfp_xf"
1248 [(set (match_operand:HI 0 "register_operand" "=a")
1249 (unspec:HI
1250 [(compare:CCFP
1251 (match_operand:XF 1 "register_operand" "f")
1252 (match_operand:XF 2 "register_operand" "f"))]
1253 UNSPEC_FNSTSW))]
1254 "TARGET_80387"
1255 "* return output_fp_compare (insn, operands, false, false);"
1256 [(set_attr "type" "multi")
1257 (set_attr "unit" "i387")
1258 (set_attr "mode" "XF")])
1259
1260 (define_insn_and_split "*cmpfp_xf_cc"
1261 [(set (reg:CCFP FLAGS_REG)
1262 (compare:CCFP
1263 (match_operand:XF 1 "register_operand" "f")
1264 (match_operand:XF 2 "register_operand" "f")))
1265 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1266 "TARGET_80387
1267 && TARGET_SAHF && !TARGET_CMOVE"
1268 "#"
1269 "&& reload_completed"
1270 [(set (match_dup 0)
1271 (unspec:HI
1272 [(compare:CCFP (match_dup 1)(match_dup 2))]
1273 UNSPEC_FNSTSW))
1274 (set (reg:CC FLAGS_REG)
1275 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1276 ""
1277 [(set_attr "type" "multi")
1278 (set_attr "unit" "i387")
1279 (set_attr "mode" "XF")])
1280
1281 (define_insn "*cmpfp_<mode>"
1282 [(set (match_operand:HI 0 "register_operand" "=a")
1283 (unspec:HI
1284 [(compare:CCFP
1285 (match_operand:MODEF 1 "register_operand" "f")
1286 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1287 UNSPEC_FNSTSW))]
1288 "TARGET_80387"
1289 "* return output_fp_compare (insn, operands, false, false);"
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1292 (set_attr "mode" "<MODE>")])
1293
1294 (define_insn_and_split "*cmpfp_<mode>_cc"
1295 [(set (reg:CCFP FLAGS_REG)
1296 (compare:CCFP
1297 (match_operand:MODEF 1 "register_operand" "f")
1298 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1299 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1300 "TARGET_80387
1301 && TARGET_SAHF && !TARGET_CMOVE"
1302 "#"
1303 "&& reload_completed"
1304 [(set (match_dup 0)
1305 (unspec:HI
1306 [(compare:CCFP (match_dup 1)(match_dup 2))]
1307 UNSPEC_FNSTSW))
1308 (set (reg:CC FLAGS_REG)
1309 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1310 ""
1311 [(set_attr "type" "multi")
1312 (set_attr "unit" "i387")
1313 (set_attr "mode" "<MODE>")])
1314
1315 (define_insn "*cmpfp_u"
1316 [(set (match_operand:HI 0 "register_operand" "=a")
1317 (unspec:HI
1318 [(compare:CCFPU
1319 (match_operand 1 "register_operand" "f")
1320 (match_operand 2 "register_operand" "f"))]
1321 UNSPEC_FNSTSW))]
1322 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1323 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1324 "* return output_fp_compare (insn, operands, false, true);"
1325 [(set_attr "type" "multi")
1326 (set_attr "unit" "i387")
1327 (set (attr "mode")
1328 (cond [(match_operand:SF 1 "" "")
1329 (const_string "SF")
1330 (match_operand:DF 1 "" "")
1331 (const_string "DF")
1332 ]
1333 (const_string "XF")))])
1334
1335 (define_insn_and_split "*cmpfp_u_cc"
1336 [(set (reg:CCFPU FLAGS_REG)
1337 (compare:CCFPU
1338 (match_operand 1 "register_operand" "f")
1339 (match_operand 2 "register_operand" "f")))
1340 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1341 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1342 && TARGET_SAHF && !TARGET_CMOVE
1343 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1344 "#"
1345 "&& reload_completed"
1346 [(set (match_dup 0)
1347 (unspec:HI
1348 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1349 UNSPEC_FNSTSW))
1350 (set (reg:CC FLAGS_REG)
1351 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1352 ""
1353 [(set_attr "type" "multi")
1354 (set_attr "unit" "i387")
1355 (set (attr "mode")
1356 (cond [(match_operand:SF 1 "" "")
1357 (const_string "SF")
1358 (match_operand:DF 1 "" "")
1359 (const_string "DF")
1360 ]
1361 (const_string "XF")))])
1362
1363 (define_insn "*cmpfp_<mode>"
1364 [(set (match_operand:HI 0 "register_operand" "=a")
1365 (unspec:HI
1366 [(compare:CCFP
1367 (match_operand 1 "register_operand" "f")
1368 (match_operator 3 "float_operator"
1369 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1370 UNSPEC_FNSTSW))]
1371 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1372 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1373 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1374 "* return output_fp_compare (insn, operands, false, false);"
1375 [(set_attr "type" "multi")
1376 (set_attr "unit" "i387")
1377 (set_attr "fp_int_src" "true")
1378 (set_attr "mode" "<MODE>")])
1379
1380 (define_insn_and_split "*cmpfp_<mode>_cc"
1381 [(set (reg:CCFP FLAGS_REG)
1382 (compare:CCFP
1383 (match_operand 1 "register_operand" "f")
1384 (match_operator 3 "float_operator"
1385 [(match_operand:SWI24 2 "memory_operand" "m")])))
1386 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1387 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1388 && TARGET_SAHF && !TARGET_CMOVE
1389 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1390 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1391 "#"
1392 "&& reload_completed"
1393 [(set (match_dup 0)
1394 (unspec:HI
1395 [(compare:CCFP
1396 (match_dup 1)
1397 (match_op_dup 3 [(match_dup 2)]))]
1398 UNSPEC_FNSTSW))
1399 (set (reg:CC FLAGS_REG)
1400 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1401 ""
1402 [(set_attr "type" "multi")
1403 (set_attr "unit" "i387")
1404 (set_attr "fp_int_src" "true")
1405 (set_attr "mode" "<MODE>")])
1406
1407 ;; FP compares, step 2
1408 ;; Move the fpsw to ax.
1409
1410 (define_insn "x86_fnstsw_1"
1411 [(set (match_operand:HI 0 "register_operand" "=a")
1412 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1413 "TARGET_80387"
1414 "fnstsw\t%0"
1415 [(set (attr "length")
1416 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1417 (set_attr "mode" "SI")
1418 (set_attr "unit" "i387")])
1419
1420 ;; FP compares, step 3
1421 ;; Get ax into flags, general case.
1422
1423 (define_insn "x86_sahf_1"
1424 [(set (reg:CC FLAGS_REG)
1425 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1426 UNSPEC_SAHF))]
1427 "TARGET_SAHF"
1428 {
1429 #ifndef HAVE_AS_IX86_SAHF
1430 if (TARGET_64BIT)
1431 return ASM_BYTE "0x9e";
1432 else
1433 #endif
1434 return "sahf";
1435 }
1436 [(set_attr "length" "1")
1437 (set_attr "athlon_decode" "vector")
1438 (set_attr "amdfam10_decode" "direct")
1439 (set_attr "bdver1_decode" "direct")
1440 (set_attr "mode" "SI")])
1441
1442 ;; Pentium Pro can do steps 1 through 3 in one go.
1443 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1444 ;; (these i387 instructions set flags directly)
1445 (define_insn "*cmpfp_i_mixed"
1446 [(set (reg:CCFP FLAGS_REG)
1447 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1448 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1449 "TARGET_MIX_SSE_I387
1450 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1451 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1452 "* return output_fp_compare (insn, operands, true, false);"
1453 [(set_attr "type" "fcmp,ssecomi")
1454 (set_attr "prefix" "orig,maybe_vex")
1455 (set (attr "mode")
1456 (if_then_else (match_operand:SF 1 "" "")
1457 (const_string "SF")
1458 (const_string "DF")))
1459 (set (attr "prefix_rep")
1460 (if_then_else (eq_attr "type" "ssecomi")
1461 (const_string "0")
1462 (const_string "*")))
1463 (set (attr "prefix_data16")
1464 (cond [(eq_attr "type" "fcmp")
1465 (const_string "*")
1466 (eq_attr "mode" "DF")
1467 (const_string "1")
1468 ]
1469 (const_string "0")))
1470 (set_attr "athlon_decode" "vector")
1471 (set_attr "amdfam10_decode" "direct")
1472 (set_attr "bdver1_decode" "double")])
1473
1474 (define_insn "*cmpfp_i_sse"
1475 [(set (reg:CCFP FLAGS_REG)
1476 (compare:CCFP (match_operand 0 "register_operand" "x")
1477 (match_operand 1 "nonimmediate_operand" "xm")))]
1478 "TARGET_SSE_MATH
1479 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1480 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1481 "* return output_fp_compare (insn, operands, true, false);"
1482 [(set_attr "type" "ssecomi")
1483 (set_attr "prefix" "maybe_vex")
1484 (set (attr "mode")
1485 (if_then_else (match_operand:SF 1 "" "")
1486 (const_string "SF")
1487 (const_string "DF")))
1488 (set_attr "prefix_rep" "0")
1489 (set (attr "prefix_data16")
1490 (if_then_else (eq_attr "mode" "DF")
1491 (const_string "1")
1492 (const_string "0")))
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "double")])
1496
1497 (define_insn "*cmpfp_i_i387"
1498 [(set (reg:CCFP FLAGS_REG)
1499 (compare:CCFP (match_operand 0 "register_operand" "f")
1500 (match_operand 1 "register_operand" "f")))]
1501 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && TARGET_CMOVE
1503 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1504 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1505 "* return output_fp_compare (insn, operands, true, false);"
1506 [(set_attr "type" "fcmp")
1507 (set (attr "mode")
1508 (cond [(match_operand:SF 1 "" "")
1509 (const_string "SF")
1510 (match_operand:DF 1 "" "")
1511 (const_string "DF")
1512 ]
1513 (const_string "XF")))
1514 (set_attr "athlon_decode" "vector")
1515 (set_attr "amdfam10_decode" "direct")
1516 (set_attr "bdver1_decode" "double")])
1517
1518 (define_insn "*cmpfp_iu_mixed"
1519 [(set (reg:CCFPU FLAGS_REG)
1520 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1521 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1522 "TARGET_MIX_SSE_I387
1523 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1524 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525 "* return output_fp_compare (insn, operands, true, true);"
1526 [(set_attr "type" "fcmp,ssecomi")
1527 (set_attr "prefix" "orig,maybe_vex")
1528 (set (attr "mode")
1529 (if_then_else (match_operand:SF 1 "" "")
1530 (const_string "SF")
1531 (const_string "DF")))
1532 (set (attr "prefix_rep")
1533 (if_then_else (eq_attr "type" "ssecomi")
1534 (const_string "0")
1535 (const_string "*")))
1536 (set (attr "prefix_data16")
1537 (cond [(eq_attr "type" "fcmp")
1538 (const_string "*")
1539 (eq_attr "mode" "DF")
1540 (const_string "1")
1541 ]
1542 (const_string "0")))
1543 (set_attr "athlon_decode" "vector")
1544 (set_attr "amdfam10_decode" "direct")
1545 (set_attr "bdver1_decode" "double")])
1546
1547 (define_insn "*cmpfp_iu_sse"
1548 [(set (reg:CCFPU FLAGS_REG)
1549 (compare:CCFPU (match_operand 0 "register_operand" "x")
1550 (match_operand 1 "nonimmediate_operand" "xm")))]
1551 "TARGET_SSE_MATH
1552 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1554 "* return output_fp_compare (insn, operands, true, true);"
1555 [(set_attr "type" "ssecomi")
1556 (set_attr "prefix" "maybe_vex")
1557 (set (attr "mode")
1558 (if_then_else (match_operand:SF 1 "" "")
1559 (const_string "SF")
1560 (const_string "DF")))
1561 (set_attr "prefix_rep" "0")
1562 (set (attr "prefix_data16")
1563 (if_then_else (eq_attr "mode" "DF")
1564 (const_string "1")
1565 (const_string "0")))
1566 (set_attr "athlon_decode" "vector")
1567 (set_attr "amdfam10_decode" "direct")
1568 (set_attr "bdver1_decode" "double")])
1569
1570 (define_insn "*cmpfp_iu_387"
1571 [(set (reg:CCFPU FLAGS_REG)
1572 (compare:CCFPU (match_operand 0 "register_operand" "f")
1573 (match_operand 1 "register_operand" "f")))]
1574 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && TARGET_CMOVE
1576 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1577 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1578 "* return output_fp_compare (insn, operands, true, true);"
1579 [(set_attr "type" "fcmp")
1580 (set (attr "mode")
1581 (cond [(match_operand:SF 1 "" "")
1582 (const_string "SF")
1583 (match_operand:DF 1 "" "")
1584 (const_string "DF")
1585 ]
1586 (const_string "XF")))
1587 (set_attr "athlon_decode" "vector")
1588 (set_attr "amdfam10_decode" "direct")
1589 (set_attr "bdver1_decode" "direct")])
1590 \f
1591 ;; Push/pop instructions.
1592
1593 (define_insn "*push<mode>2"
1594 [(set (match_operand:DWI 0 "push_operand" "=<")
1595 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1596 ""
1597 "#"
1598 [(set_attr "type" "multi")
1599 (set_attr "mode" "<MODE>")])
1600
1601 (define_split
1602 [(set (match_operand:TI 0 "push_operand" "")
1603 (match_operand:TI 1 "general_operand" ""))]
1604 "TARGET_64BIT && reload_completed
1605 && !SSE_REG_P (operands[1])"
1606 [(const_int 0)]
1607 "ix86_split_long_move (operands); DONE;")
1608
1609 (define_insn "*pushdi2_rex64"
1610 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1611 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1612 "TARGET_64BIT"
1613 "@
1614 push{q}\t%1
1615 #"
1616 [(set_attr "type" "push,multi")
1617 (set_attr "mode" "DI")])
1618
1619 ;; Convert impossible pushes of immediate to existing instructions.
1620 ;; First try to get scratch register and go through it. In case this
1621 ;; fails, push sign extended lower part first and then overwrite
1622 ;; upper part by 32bit move.
1623 (define_peephole2
1624 [(match_scratch:DI 2 "r")
1625 (set (match_operand:DI 0 "push_operand" "")
1626 (match_operand:DI 1 "immediate_operand" ""))]
1627 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1628 && !x86_64_immediate_operand (operands[1], DImode)"
1629 [(set (match_dup 2) (match_dup 1))
1630 (set (match_dup 0) (match_dup 2))])
1631
1632 ;; We need to define this as both peepholer and splitter for case
1633 ;; peephole2 pass is not run.
1634 ;; "&& 1" is needed to keep it from matching the previous pattern.
1635 (define_peephole2
1636 [(set (match_operand:DI 0 "push_operand" "")
1637 (match_operand:DI 1 "immediate_operand" ""))]
1638 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1639 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1640 [(set (match_dup 0) (match_dup 1))
1641 (set (match_dup 2) (match_dup 3))]
1642 {
1643 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1644
1645 operands[1] = gen_lowpart (DImode, operands[2]);
1646 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1647 GEN_INT (4)));
1648 })
1649
1650 (define_split
1651 [(set (match_operand:DI 0 "push_operand" "")
1652 (match_operand:DI 1 "immediate_operand" ""))]
1653 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1654 ? epilogue_completed : reload_completed)
1655 && !symbolic_operand (operands[1], DImode)
1656 && !x86_64_immediate_operand (operands[1], DImode)"
1657 [(set (match_dup 0) (match_dup 1))
1658 (set (match_dup 2) (match_dup 3))]
1659 {
1660 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1661
1662 operands[1] = gen_lowpart (DImode, operands[2]);
1663 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1664 GEN_INT (4)));
1665 })
1666
1667 (define_split
1668 [(set (match_operand:DI 0 "push_operand" "")
1669 (match_operand:DI 1 "general_operand" ""))]
1670 "!TARGET_64BIT && reload_completed
1671 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1672 [(const_int 0)]
1673 "ix86_split_long_move (operands); DONE;")
1674
1675 (define_insn "*pushsi2"
1676 [(set (match_operand:SI 0 "push_operand" "=<")
1677 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1678 "!TARGET_64BIT"
1679 "push{l}\t%1"
1680 [(set_attr "type" "push")
1681 (set_attr "mode" "SI")])
1682
1683 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1684 ;; "push a byte/word". But actually we use pushl, which has the effect
1685 ;; of rounding the amount pushed up to a word.
1686
1687 ;; For TARGET_64BIT we always round up to 8 bytes.
1688 (define_insn "*push<mode>2_rex64"
1689 [(set (match_operand:SWI124 0 "push_operand" "=X")
1690 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1691 "TARGET_64BIT"
1692 "push{q}\t%q1"
1693 [(set_attr "type" "push")
1694 (set_attr "mode" "DI")])
1695
1696 (define_insn "*push<mode>2"
1697 [(set (match_operand:SWI12 0 "push_operand" "=X")
1698 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1699 "!TARGET_64BIT"
1700 "push{l}\t%k1"
1701 [(set_attr "type" "push")
1702 (set_attr "mode" "SI")])
1703
1704 (define_insn "*push<mode>2_prologue"
1705 [(set (match_operand:P 0 "push_operand" "=<")
1706 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1707 (clobber (mem:BLK (scratch)))]
1708 ""
1709 "push{<imodesuffix>}\t%1"
1710 [(set_attr "type" "push")
1711 (set_attr "mode" "<MODE>")])
1712
1713 (define_insn "*pop<mode>1"
1714 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1715 (match_operand:P 1 "pop_operand" ">"))]
1716 ""
1717 "pop{<imodesuffix>}\t%0"
1718 [(set_attr "type" "pop")
1719 (set_attr "mode" "<MODE>")])
1720
1721 (define_insn "*pop<mode>1_epilogue"
1722 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1723 (match_operand:P 1 "pop_operand" ">"))
1724 (clobber (mem:BLK (scratch)))]
1725 ""
1726 "pop{<imodesuffix>}\t%0"
1727 [(set_attr "type" "pop")
1728 (set_attr "mode" "<MODE>")])
1729 \f
1730 ;; Move instructions.
1731
1732 (define_expand "movoi"
1733 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1734 (match_operand:OI 1 "general_operand" ""))]
1735 "TARGET_AVX"
1736 "ix86_expand_move (OImode, operands); DONE;")
1737
1738 (define_expand "movti"
1739 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1740 (match_operand:TI 1 "nonimmediate_operand" ""))]
1741 "TARGET_64BIT || TARGET_SSE"
1742 {
1743 if (TARGET_64BIT)
1744 ix86_expand_move (TImode, operands);
1745 else if (push_operand (operands[0], TImode))
1746 ix86_expand_push (TImode, operands[1]);
1747 else
1748 ix86_expand_vector_move (TImode, operands);
1749 DONE;
1750 })
1751
1752 ;; This expands to what emit_move_complex would generate if we didn't
1753 ;; have a movti pattern. Having this avoids problems with reload on
1754 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1755 ;; to have around all the time.
1756 (define_expand "movcdi"
1757 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1758 (match_operand:CDI 1 "general_operand" ""))]
1759 ""
1760 {
1761 if (push_operand (operands[0], CDImode))
1762 emit_move_complex_push (CDImode, operands[0], operands[1]);
1763 else
1764 emit_move_complex_parts (operands[0], operands[1]);
1765 DONE;
1766 })
1767
1768 (define_expand "mov<mode>"
1769 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1770 (match_operand:SWI1248x 1 "general_operand" ""))]
1771 ""
1772 "ix86_expand_move (<MODE>mode, operands); DONE;")
1773
1774 (define_insn "*mov<mode>_xor"
1775 [(set (match_operand:SWI48 0 "register_operand" "=r")
1776 (match_operand:SWI48 1 "const0_operand" ""))
1777 (clobber (reg:CC FLAGS_REG))]
1778 "reload_completed"
1779 "xor{l}\t%k0, %k0"
1780 [(set_attr "type" "alu1")
1781 (set_attr "mode" "SI")
1782 (set_attr "length_immediate" "0")])
1783
1784 (define_insn "*mov<mode>_or"
1785 [(set (match_operand:SWI48 0 "register_operand" "=r")
1786 (match_operand:SWI48 1 "const_int_operand" ""))
1787 (clobber (reg:CC FLAGS_REG))]
1788 "reload_completed
1789 && operands[1] == constm1_rtx"
1790 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1791 [(set_attr "type" "alu1")
1792 (set_attr "mode" "<MODE>")
1793 (set_attr "length_immediate" "1")])
1794
1795 (define_insn "*movoi_internal_avx"
1796 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1797 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1798 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1799 {
1800 switch (which_alternative)
1801 {
1802 case 0:
1803 return standard_sse_constant_opcode (insn, operands[1]);
1804 case 1:
1805 case 2:
1806 if (misaligned_operand (operands[0], OImode)
1807 || misaligned_operand (operands[1], OImode))
1808 return "vmovdqu\t{%1, %0|%0, %1}";
1809 else
1810 return "vmovdqa\t{%1, %0|%0, %1}";
1811 default:
1812 gcc_unreachable ();
1813 }
1814 }
1815 [(set_attr "type" "sselog1,ssemov,ssemov")
1816 (set_attr "prefix" "vex")
1817 (set_attr "mode" "OI")])
1818
1819 (define_insn "*movti_internal_rex64"
1820 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1821 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1822 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1823 {
1824 switch (which_alternative)
1825 {
1826 case 0:
1827 case 1:
1828 return "#";
1829 case 2:
1830 return standard_sse_constant_opcode (insn, operands[1]);
1831 case 3:
1832 case 4:
1833 /* TDmode values are passed as TImode on the stack. Moving them
1834 to stack may result in unaligned memory access. */
1835 if (misaligned_operand (operands[0], TImode)
1836 || misaligned_operand (operands[1], TImode))
1837 {
1838 if (get_attr_mode (insn) == MODE_V4SF)
1839 return "%vmovups\t{%1, %0|%0, %1}";
1840 else
1841 return "%vmovdqu\t{%1, %0|%0, %1}";
1842 }
1843 else
1844 {
1845 if (get_attr_mode (insn) == MODE_V4SF)
1846 return "%vmovaps\t{%1, %0|%0, %1}";
1847 else
1848 return "%vmovdqa\t{%1, %0|%0, %1}";
1849 }
1850 default:
1851 gcc_unreachable ();
1852 }
1853 }
1854 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1855 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1856 (set (attr "mode")
1857 (cond [(eq_attr "alternative" "2,3")
1858 (if_then_else
1859 (match_test "optimize_function_for_size_p (cfun)")
1860 (const_string "V4SF")
1861 (const_string "TI"))
1862 (eq_attr "alternative" "4")
1863 (if_then_else
1864 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1865 (match_test "optimize_function_for_size_p (cfun)"))
1866 (const_string "V4SF")
1867 (const_string "TI"))]
1868 (const_string "DI")))])
1869
1870 (define_split
1871 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1872 (match_operand:TI 1 "general_operand" ""))]
1873 "reload_completed
1874 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1875 [(const_int 0)]
1876 "ix86_split_long_move (operands); DONE;")
1877
1878 (define_insn "*movti_internal_sse"
1879 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1880 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1881 "TARGET_SSE && !TARGET_64BIT
1882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1883 {
1884 switch (which_alternative)
1885 {
1886 case 0:
1887 return standard_sse_constant_opcode (insn, operands[1]);
1888 case 1:
1889 case 2:
1890 /* TDmode values are passed as TImode on the stack. Moving them
1891 to stack may result in unaligned memory access. */
1892 if (misaligned_operand (operands[0], TImode)
1893 || misaligned_operand (operands[1], TImode))
1894 {
1895 if (get_attr_mode (insn) == MODE_V4SF)
1896 return "%vmovups\t{%1, %0|%0, %1}";
1897 else
1898 return "%vmovdqu\t{%1, %0|%0, %1}";
1899 }
1900 else
1901 {
1902 if (get_attr_mode (insn) == MODE_V4SF)
1903 return "%vmovaps\t{%1, %0|%0, %1}";
1904 else
1905 return "%vmovdqa\t{%1, %0|%0, %1}";
1906 }
1907 default:
1908 gcc_unreachable ();
1909 }
1910 }
1911 [(set_attr "type" "sselog1,ssemov,ssemov")
1912 (set_attr "prefix" "maybe_vex")
1913 (set (attr "mode")
1914 (cond [(ior (not (match_test "TARGET_SSE2"))
1915 (match_test "optimize_function_for_size_p (cfun)"))
1916 (const_string "V4SF")
1917 (and (eq_attr "alternative" "2")
1918 (match_test "TARGET_SSE_TYPELESS_STORES"))
1919 (const_string "V4SF")]
1920 (const_string "TI")))])
1921
1922 (define_insn "*movdi_internal_rex64"
1923 [(set (match_operand:DI 0 "nonimmediate_operand"
1924 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1925 (match_operand:DI 1 "general_operand"
1926 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1927 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1928 {
1929 switch (get_attr_type (insn))
1930 {
1931 case TYPE_SSECVT:
1932 if (SSE_REG_P (operands[0]))
1933 return "movq2dq\t{%1, %0|%0, %1}";
1934 else
1935 return "movdq2q\t{%1, %0|%0, %1}";
1936
1937 case TYPE_SSEMOV:
1938 if (get_attr_mode (insn) == MODE_TI)
1939 return "%vmovdqa\t{%1, %0|%0, %1}";
1940 /* Handle broken assemblers that require movd instead of movq. */
1941 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942 return "%vmovd\t{%1, %0|%0, %1}";
1943 else
1944 return "%vmovq\t{%1, %0|%0, %1}";
1945
1946 case TYPE_MMXMOV:
1947 /* Handle broken assemblers that require movd instead of movq. */
1948 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1949 return "movd\t{%1, %0|%0, %1}";
1950 else
1951 return "movq\t{%1, %0|%0, %1}";
1952
1953 case TYPE_SSELOG1:
1954 return standard_sse_constant_opcode (insn, operands[1]);
1955
1956 case TYPE_MMX:
1957 return "pxor\t%0, %0";
1958
1959 case TYPE_MULTI:
1960 return "#";
1961
1962 case TYPE_LEA:
1963 return "lea{q}\t{%a1, %0|%0, %a1}";
1964
1965 default:
1966 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1967 if (get_attr_mode (insn) == MODE_SI)
1968 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1969 else if (which_alternative == 2)
1970 return "movabs{q}\t{%1, %0|%0, %1}";
1971 else if (ix86_use_lea_for_mov (insn, operands))
1972 return "lea{q}\t{%a1, %0|%0, %a1}";
1973 else
1974 return "mov{q}\t{%1, %0|%0, %1}";
1975 }
1976 }
1977 [(set (attr "type")
1978 (cond [(eq_attr "alternative" "4")
1979 (const_string "multi")
1980 (eq_attr "alternative" "5")
1981 (const_string "mmx")
1982 (eq_attr "alternative" "6,7,8,9")
1983 (const_string "mmxmov")
1984 (eq_attr "alternative" "10")
1985 (const_string "sselog1")
1986 (eq_attr "alternative" "11,12,13,14,15")
1987 (const_string "ssemov")
1988 (eq_attr "alternative" "16,17")
1989 (const_string "ssecvt")
1990 (match_operand 1 "pic_32bit_operand" "")
1991 (const_string "lea")
1992 ]
1993 (const_string "imov")))
1994 (set (attr "modrm")
1995 (if_then_else
1996 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1997 (const_string "0")
1998 (const_string "*")))
1999 (set (attr "length_immediate")
2000 (if_then_else
2001 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2002 (const_string "8")
2003 (const_string "*")))
2004 (set (attr "prefix_rex")
2005 (if_then_else (eq_attr "alternative" "8,9")
2006 (const_string "1")
2007 (const_string "*")))
2008 (set (attr "prefix_data16")
2009 (if_then_else (eq_attr "alternative" "11")
2010 (const_string "1")
2011 (const_string "*")))
2012 (set (attr "prefix")
2013 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2014 (const_string "maybe_vex")
2015 (const_string "orig")))
2016 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2017
2018 ;; Reload patterns to support multi-word load/store
2019 ;; with non-offsetable address.
2020 (define_expand "reload_noff_store"
2021 [(parallel [(match_operand 0 "memory_operand" "=m")
2022 (match_operand 1 "register_operand" "r")
2023 (match_operand:DI 2 "register_operand" "=&r")])]
2024 "TARGET_64BIT"
2025 {
2026 rtx mem = operands[0];
2027 rtx addr = XEXP (mem, 0);
2028
2029 emit_move_insn (operands[2], addr);
2030 mem = replace_equiv_address_nv (mem, operands[2]);
2031
2032 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2033 DONE;
2034 })
2035
2036 (define_expand "reload_noff_load"
2037 [(parallel [(match_operand 0 "register_operand" "=r")
2038 (match_operand 1 "memory_operand" "m")
2039 (match_operand:DI 2 "register_operand" "=r")])]
2040 "TARGET_64BIT"
2041 {
2042 rtx mem = operands[1];
2043 rtx addr = XEXP (mem, 0);
2044
2045 emit_move_insn (operands[2], addr);
2046 mem = replace_equiv_address_nv (mem, operands[2]);
2047
2048 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2049 DONE;
2050 })
2051
2052 ;; Convert impossible stores of immediate to existing instructions.
2053 ;; First try to get scratch register and go through it. In case this
2054 ;; fails, move by 32bit parts.
2055 (define_peephole2
2056 [(match_scratch:DI 2 "r")
2057 (set (match_operand:DI 0 "memory_operand" "")
2058 (match_operand:DI 1 "immediate_operand" ""))]
2059 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2060 && !x86_64_immediate_operand (operands[1], DImode)"
2061 [(set (match_dup 2) (match_dup 1))
2062 (set (match_dup 0) (match_dup 2))])
2063
2064 ;; We need to define this as both peepholer and splitter for case
2065 ;; peephole2 pass is not run.
2066 ;; "&& 1" is needed to keep it from matching the previous pattern.
2067 (define_peephole2
2068 [(set (match_operand:DI 0 "memory_operand" "")
2069 (match_operand:DI 1 "immediate_operand" ""))]
2070 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2072 [(set (match_dup 2) (match_dup 3))
2073 (set (match_dup 4) (match_dup 5))]
2074 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2075
2076 (define_split
2077 [(set (match_operand:DI 0 "memory_operand" "")
2078 (match_operand:DI 1 "immediate_operand" ""))]
2079 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2080 ? epilogue_completed : reload_completed)
2081 && !symbolic_operand (operands[1], DImode)
2082 && !x86_64_immediate_operand (operands[1], DImode)"
2083 [(set (match_dup 2) (match_dup 3))
2084 (set (match_dup 4) (match_dup 5))]
2085 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2086
2087 (define_insn "*movdi_internal"
2088 [(set (match_operand:DI 0 "nonimmediate_operand"
2089 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2090 (match_operand:DI 1 "general_operand"
2091 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2092 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2093 {
2094 switch (get_attr_type (insn))
2095 {
2096 case TYPE_SSECVT:
2097 if (SSE_REG_P (operands[0]))
2098 return "movq2dq\t{%1, %0|%0, %1}";
2099 else
2100 return "movdq2q\t{%1, %0|%0, %1}";
2101
2102 case TYPE_SSEMOV:
2103 switch (get_attr_mode (insn))
2104 {
2105 case MODE_TI:
2106 return "%vmovdqa\t{%1, %0|%0, %1}";
2107 case MODE_DI:
2108 return "%vmovq\t{%1, %0|%0, %1}";
2109 case MODE_V4SF:
2110 return "movaps\t{%1, %0|%0, %1}";
2111 case MODE_V2SF:
2112 return "movlps\t{%1, %0|%0, %1}";
2113 default:
2114 gcc_unreachable ();
2115 }
2116
2117 case TYPE_MMXMOV:
2118 return "movq\t{%1, %0|%0, %1}";
2119
2120 case TYPE_SSELOG1:
2121 return standard_sse_constant_opcode (insn, operands[1]);
2122
2123 case TYPE_MMX:
2124 return "pxor\t%0, %0";
2125
2126 case TYPE_MULTI:
2127 return "#";
2128
2129 default:
2130 gcc_unreachable ();
2131 }
2132 }
2133 [(set (attr "isa")
2134 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2135 (const_string "sse2")
2136 (eq_attr "alternative" "9,10,11,12")
2137 (const_string "noavx")
2138 ]
2139 (const_string "*")))
2140 (set (attr "type")
2141 (cond [(eq_attr "alternative" "0,1")
2142 (const_string "multi")
2143 (eq_attr "alternative" "2")
2144 (const_string "mmx")
2145 (eq_attr "alternative" "3,4")
2146 (const_string "mmxmov")
2147 (eq_attr "alternative" "5,9")
2148 (const_string "sselog1")
2149 (eq_attr "alternative" "13,14")
2150 (const_string "ssecvt")
2151 ]
2152 (const_string "ssemov")))
2153 (set (attr "prefix")
2154 (if_then_else (eq_attr "alternative" "5,6,7,8")
2155 (const_string "maybe_vex")
2156 (const_string "orig")))
2157 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2158
2159 (define_split
2160 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2161 (match_operand:DI 1 "general_operand" ""))]
2162 "!TARGET_64BIT && reload_completed
2163 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2164 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2165 [(const_int 0)]
2166 "ix86_split_long_move (operands); DONE;")
2167
2168 (define_insn "*movsi_internal"
2169 [(set (match_operand:SI 0 "nonimmediate_operand"
2170 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2171 (match_operand:SI 1 "general_operand"
2172 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2173 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2174 {
2175 switch (get_attr_type (insn))
2176 {
2177 case TYPE_SSELOG1:
2178 return standard_sse_constant_opcode (insn, operands[1]);
2179
2180 case TYPE_SSEMOV:
2181 switch (get_attr_mode (insn))
2182 {
2183 case MODE_TI:
2184 return "%vmovdqa\t{%1, %0|%0, %1}";
2185 case MODE_V4SF:
2186 return "%vmovaps\t{%1, %0|%0, %1}";
2187 case MODE_SI:
2188 return "%vmovd\t{%1, %0|%0, %1}";
2189 case MODE_SF:
2190 return "%vmovss\t{%1, %0|%0, %1}";
2191 default:
2192 gcc_unreachable ();
2193 }
2194
2195 case TYPE_MMX:
2196 return "pxor\t%0, %0";
2197
2198 case TYPE_MMXMOV:
2199 if (get_attr_mode (insn) == MODE_DI)
2200 return "movq\t{%1, %0|%0, %1}";
2201 return "movd\t{%1, %0|%0, %1}";
2202
2203 case TYPE_LEA:
2204 return "lea{l}\t{%a1, %0|%0, %a1}";
2205
2206 default:
2207 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2208 if (ix86_use_lea_for_mov (insn, operands))
2209 return "lea{l}\t{%a1, %0|%0, %a1}";
2210 else
2211 return "mov{l}\t{%1, %0|%0, %1}";
2212 }
2213 }
2214 [(set (attr "type")
2215 (cond [(eq_attr "alternative" "2")
2216 (const_string "mmx")
2217 (eq_attr "alternative" "3,4,5")
2218 (const_string "mmxmov")
2219 (eq_attr "alternative" "6")
2220 (const_string "sselog1")
2221 (eq_attr "alternative" "7,8,9,10,11")
2222 (const_string "ssemov")
2223 (match_operand 1 "pic_32bit_operand" "")
2224 (const_string "lea")
2225 ]
2226 (const_string "imov")))
2227 (set (attr "prefix")
2228 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2229 (const_string "orig")
2230 (const_string "maybe_vex")))
2231 (set (attr "prefix_data16")
2232 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2233 (const_string "1")
2234 (const_string "*")))
2235 (set (attr "mode")
2236 (cond [(eq_attr "alternative" "2,3")
2237 (const_string "DI")
2238 (eq_attr "alternative" "6,7")
2239 (if_then_else
2240 (not (match_test "TARGET_SSE2"))
2241 (const_string "V4SF")
2242 (const_string "TI"))
2243 (and (eq_attr "alternative" "8,9,10,11")
2244 (not (match_test "TARGET_SSE2")))
2245 (const_string "SF")
2246 ]
2247 (const_string "SI")))])
2248
2249 (define_insn "*movhi_internal"
2250 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2251 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2252 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2253 {
2254 switch (get_attr_type (insn))
2255 {
2256 case TYPE_IMOVX:
2257 /* movzwl is faster than movw on p2 due to partial word stalls,
2258 though not as fast as an aligned movl. */
2259 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2260 default:
2261 if (get_attr_mode (insn) == MODE_SI)
2262 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2263 else
2264 return "mov{w}\t{%1, %0|%0, %1}";
2265 }
2266 }
2267 [(set (attr "type")
2268 (cond [(match_test "optimize_function_for_size_p (cfun)")
2269 (const_string "imov")
2270 (and (eq_attr "alternative" "0")
2271 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2272 (not (match_test "TARGET_HIMODE_MATH"))))
2273 (const_string "imov")
2274 (and (eq_attr "alternative" "1,2")
2275 (match_operand:HI 1 "aligned_operand" ""))
2276 (const_string "imov")
2277 (and (match_test "TARGET_MOVX")
2278 (eq_attr "alternative" "0,2"))
2279 (const_string "imovx")
2280 ]
2281 (const_string "imov")))
2282 (set (attr "mode")
2283 (cond [(eq_attr "type" "imovx")
2284 (const_string "SI")
2285 (and (eq_attr "alternative" "1,2")
2286 (match_operand:HI 1 "aligned_operand" ""))
2287 (const_string "SI")
2288 (and (eq_attr "alternative" "0")
2289 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2290 (not (match_test "TARGET_HIMODE_MATH"))))
2291 (const_string "SI")
2292 ]
2293 (const_string "HI")))])
2294
2295 ;; Situation is quite tricky about when to choose full sized (SImode) move
2296 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2297 ;; partial register dependency machines (such as AMD Athlon), where QImode
2298 ;; moves issue extra dependency and for partial register stalls machines
2299 ;; that don't use QImode patterns (and QImode move cause stall on the next
2300 ;; instruction).
2301 ;;
2302 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2303 ;; register stall machines with, where we use QImode instructions, since
2304 ;; partial register stall can be caused there. Then we use movzx.
2305 (define_insn "*movqi_internal"
2306 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2307 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2308 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2309 {
2310 switch (get_attr_type (insn))
2311 {
2312 case TYPE_IMOVX:
2313 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2314 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2315 default:
2316 if (get_attr_mode (insn) == MODE_SI)
2317 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2318 else
2319 return "mov{b}\t{%1, %0|%0, %1}";
2320 }
2321 }
2322 [(set (attr "type")
2323 (cond [(and (eq_attr "alternative" "5")
2324 (not (match_operand:QI 1 "aligned_operand" "")))
2325 (const_string "imovx")
2326 (match_test "optimize_function_for_size_p (cfun)")
2327 (const_string "imov")
2328 (and (eq_attr "alternative" "3")
2329 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2330 (not (match_test "TARGET_QIMODE_MATH"))))
2331 (const_string "imov")
2332 (eq_attr "alternative" "3,5")
2333 (const_string "imovx")
2334 (and (match_test "TARGET_MOVX")
2335 (eq_attr "alternative" "2"))
2336 (const_string "imovx")
2337 ]
2338 (const_string "imov")))
2339 (set (attr "mode")
2340 (cond [(eq_attr "alternative" "3,4,5")
2341 (const_string "SI")
2342 (eq_attr "alternative" "6")
2343 (const_string "QI")
2344 (eq_attr "type" "imovx")
2345 (const_string "SI")
2346 (and (eq_attr "type" "imov")
2347 (and (eq_attr "alternative" "0,1")
2348 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2349 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2350 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2351 (const_string "SI")
2352 ;; Avoid partial register stalls when not using QImode arithmetic
2353 (and (eq_attr "type" "imov")
2354 (and (eq_attr "alternative" "0,1")
2355 (and (match_test "TARGET_PARTIAL_REG_STALL")
2356 (not (match_test "TARGET_QIMODE_MATH")))))
2357 (const_string "SI")
2358 ]
2359 (const_string "QI")))])
2360
2361 ;; Stores and loads of ax to arbitrary constant address.
2362 ;; We fake an second form of instruction to force reload to load address
2363 ;; into register when rax is not available
2364 (define_insn "*movabs<mode>_1"
2365 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2366 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2367 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2368 "@
2369 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2370 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2371 [(set_attr "type" "imov")
2372 (set_attr "modrm" "0,*")
2373 (set_attr "length_address" "8,0")
2374 (set_attr "length_immediate" "0,*")
2375 (set_attr "memory" "store")
2376 (set_attr "mode" "<MODE>")])
2377
2378 (define_insn "*movabs<mode>_2"
2379 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2380 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2381 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2382 "@
2383 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2384 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2385 [(set_attr "type" "imov")
2386 (set_attr "modrm" "0,*")
2387 (set_attr "length_address" "8,0")
2388 (set_attr "length_immediate" "0")
2389 (set_attr "memory" "load")
2390 (set_attr "mode" "<MODE>")])
2391
2392 (define_insn "*swap<mode>"
2393 [(set (match_operand:SWI48 0 "register_operand" "+r")
2394 (match_operand:SWI48 1 "register_operand" "+r"))
2395 (set (match_dup 1)
2396 (match_dup 0))]
2397 ""
2398 "xchg{<imodesuffix>}\t%1, %0"
2399 [(set_attr "type" "imov")
2400 (set_attr "mode" "<MODE>")
2401 (set_attr "pent_pair" "np")
2402 (set_attr "athlon_decode" "vector")
2403 (set_attr "amdfam10_decode" "double")
2404 (set_attr "bdver1_decode" "double")])
2405
2406 (define_insn "*swap<mode>_1"
2407 [(set (match_operand:SWI12 0 "register_operand" "+r")
2408 (match_operand:SWI12 1 "register_operand" "+r"))
2409 (set (match_dup 1)
2410 (match_dup 0))]
2411 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2412 "xchg{l}\t%k1, %k0"
2413 [(set_attr "type" "imov")
2414 (set_attr "mode" "SI")
2415 (set_attr "pent_pair" "np")
2416 (set_attr "athlon_decode" "vector")
2417 (set_attr "amdfam10_decode" "double")
2418 (set_attr "bdver1_decode" "double")])
2419
2420 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2421 ;; is disabled for AMDFAM10
2422 (define_insn "*swap<mode>_2"
2423 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2424 (match_operand:SWI12 1 "register_operand" "+<r>"))
2425 (set (match_dup 1)
2426 (match_dup 0))]
2427 "TARGET_PARTIAL_REG_STALL"
2428 "xchg{<imodesuffix>}\t%1, %0"
2429 [(set_attr "type" "imov")
2430 (set_attr "mode" "<MODE>")
2431 (set_attr "pent_pair" "np")
2432 (set_attr "athlon_decode" "vector")])
2433
2434 (define_expand "movstrict<mode>"
2435 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2436 (match_operand:SWI12 1 "general_operand" ""))]
2437 ""
2438 {
2439 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2440 FAIL;
2441 if (GET_CODE (operands[0]) == SUBREG
2442 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2443 FAIL;
2444 /* Don't generate memory->memory moves, go through a register */
2445 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2446 operands[1] = force_reg (<MODE>mode, operands[1]);
2447 })
2448
2449 (define_insn "*movstrict<mode>_1"
2450 [(set (strict_low_part
2451 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2452 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2453 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2455 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2456 [(set_attr "type" "imov")
2457 (set_attr "mode" "<MODE>")])
2458
2459 (define_insn "*movstrict<mode>_xor"
2460 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2461 (match_operand:SWI12 1 "const0_operand" ""))
2462 (clobber (reg:CC FLAGS_REG))]
2463 "reload_completed"
2464 "xor{<imodesuffix>}\t%0, %0"
2465 [(set_attr "type" "alu1")
2466 (set_attr "mode" "<MODE>")
2467 (set_attr "length_immediate" "0")])
2468
2469 (define_insn "*mov<mode>_extv_1"
2470 [(set (match_operand:SWI24 0 "register_operand" "=R")
2471 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2472 (const_int 8)
2473 (const_int 8)))]
2474 ""
2475 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2476 [(set_attr "type" "imovx")
2477 (set_attr "mode" "SI")])
2478
2479 (define_insn "*movqi_extv_1_rex64"
2480 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2481 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2482 (const_int 8)
2483 (const_int 8)))]
2484 "TARGET_64BIT"
2485 {
2486 switch (get_attr_type (insn))
2487 {
2488 case TYPE_IMOVX:
2489 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2490 default:
2491 return "mov{b}\t{%h1, %0|%0, %h1}";
2492 }
2493 }
2494 [(set (attr "type")
2495 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2496 (match_test "TARGET_MOVX"))
2497 (const_string "imovx")
2498 (const_string "imov")))
2499 (set (attr "mode")
2500 (if_then_else (eq_attr "type" "imovx")
2501 (const_string "SI")
2502 (const_string "QI")))])
2503
2504 (define_insn "*movqi_extv_1"
2505 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2506 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2507 (const_int 8)
2508 (const_int 8)))]
2509 "!TARGET_64BIT"
2510 {
2511 switch (get_attr_type (insn))
2512 {
2513 case TYPE_IMOVX:
2514 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2515 default:
2516 return "mov{b}\t{%h1, %0|%0, %h1}";
2517 }
2518 }
2519 [(set (attr "type")
2520 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2521 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2522 (match_test "TARGET_MOVX")))
2523 (const_string "imovx")
2524 (const_string "imov")))
2525 (set (attr "mode")
2526 (if_then_else (eq_attr "type" "imovx")
2527 (const_string "SI")
2528 (const_string "QI")))])
2529
2530 (define_insn "*mov<mode>_extzv_1"
2531 [(set (match_operand:SWI48 0 "register_operand" "=R")
2532 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2533 (const_int 8)
2534 (const_int 8)))]
2535 ""
2536 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2537 [(set_attr "type" "imovx")
2538 (set_attr "mode" "SI")])
2539
2540 (define_insn "*movqi_extzv_2_rex64"
2541 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2542 (subreg:QI
2543 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2544 (const_int 8)
2545 (const_int 8)) 0))]
2546 "TARGET_64BIT"
2547 {
2548 switch (get_attr_type (insn))
2549 {
2550 case TYPE_IMOVX:
2551 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2552 default:
2553 return "mov{b}\t{%h1, %0|%0, %h1}";
2554 }
2555 }
2556 [(set (attr "type")
2557 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2558 (match_test "TARGET_MOVX"))
2559 (const_string "imovx")
2560 (const_string "imov")))
2561 (set (attr "mode")
2562 (if_then_else (eq_attr "type" "imovx")
2563 (const_string "SI")
2564 (const_string "QI")))])
2565
2566 (define_insn "*movqi_extzv_2"
2567 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2568 (subreg:QI
2569 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2570 (const_int 8)
2571 (const_int 8)) 0))]
2572 "!TARGET_64BIT"
2573 {
2574 switch (get_attr_type (insn))
2575 {
2576 case TYPE_IMOVX:
2577 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2578 default:
2579 return "mov{b}\t{%h1, %0|%0, %h1}";
2580 }
2581 }
2582 [(set (attr "type")
2583 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2584 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2585 (match_test "TARGET_MOVX")))
2586 (const_string "imovx")
2587 (const_string "imov")))
2588 (set (attr "mode")
2589 (if_then_else (eq_attr "type" "imovx")
2590 (const_string "SI")
2591 (const_string "QI")))])
2592
2593 (define_expand "mov<mode>_insv_1"
2594 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2595 (const_int 8)
2596 (const_int 8))
2597 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2598
2599 (define_insn "*mov<mode>_insv_1_rex64"
2600 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2601 (const_int 8)
2602 (const_int 8))
2603 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2604 "TARGET_64BIT"
2605 "mov{b}\t{%b1, %h0|%h0, %b1}"
2606 [(set_attr "type" "imov")
2607 (set_attr "mode" "QI")])
2608
2609 (define_insn "*movsi_insv_1"
2610 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611 (const_int 8)
2612 (const_int 8))
2613 (match_operand:SI 1 "general_operand" "Qmn"))]
2614 "!TARGET_64BIT"
2615 "mov{b}\t{%b1, %h0|%h0, %b1}"
2616 [(set_attr "type" "imov")
2617 (set_attr "mode" "QI")])
2618
2619 (define_insn "*movqi_insv_2"
2620 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621 (const_int 8)
2622 (const_int 8))
2623 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2624 (const_int 8)))]
2625 ""
2626 "mov{b}\t{%h1, %h0|%h0, %h1}"
2627 [(set_attr "type" "imov")
2628 (set_attr "mode" "QI")])
2629 \f
2630 ;; Floating point push instructions.
2631
2632 (define_insn "*pushtf"
2633 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2634 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2635 "TARGET_SSE2"
2636 {
2637 /* This insn should be already split before reg-stack. */
2638 gcc_unreachable ();
2639 }
2640 [(set_attr "type" "multi")
2641 (set_attr "unit" "sse,*,*")
2642 (set_attr "mode" "TF,SI,SI")])
2643
2644 ;; %%% Kill this when call knows how to work this out.
2645 (define_split
2646 [(set (match_operand:TF 0 "push_operand" "")
2647 (match_operand:TF 1 "sse_reg_operand" ""))]
2648 "TARGET_SSE2 && reload_completed"
2649 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2650 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2651
2652 (define_insn "*pushxf"
2653 [(set (match_operand:XF 0 "push_operand" "=<,<")
2654 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2655 "optimize_function_for_speed_p (cfun)"
2656 {
2657 /* This insn should be already split before reg-stack. */
2658 gcc_unreachable ();
2659 }
2660 [(set_attr "type" "multi")
2661 (set_attr "unit" "i387,*")
2662 (set_attr "mode" "XF,SI")])
2663
2664 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2665 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2666 ;; Pushing using integer instructions is longer except for constants
2667 ;; and direct memory references (assuming that any given constant is pushed
2668 ;; only once, but this ought to be handled elsewhere).
2669
2670 (define_insn "*pushxf_nointeger"
2671 [(set (match_operand:XF 0 "push_operand" "=<,<")
2672 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2673 "optimize_function_for_size_p (cfun)"
2674 {
2675 /* This insn should be already split before reg-stack. */
2676 gcc_unreachable ();
2677 }
2678 [(set_attr "type" "multi")
2679 (set_attr "unit" "i387,*")
2680 (set_attr "mode" "XF,SI")])
2681
2682 ;; %%% Kill this when call knows how to work this out.
2683 (define_split
2684 [(set (match_operand:XF 0 "push_operand" "")
2685 (match_operand:XF 1 "fp_register_operand" ""))]
2686 "reload_completed"
2687 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2688 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2689 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2690
2691 (define_insn "*pushdf_rex64"
2692 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2693 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2694 "TARGET_64BIT"
2695 {
2696 /* This insn should be already split before reg-stack. */
2697 gcc_unreachable ();
2698 }
2699 [(set_attr "type" "multi")
2700 (set_attr "unit" "i387,*,*")
2701 (set_attr "mode" "DF,DI,DF")])
2702
2703 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2704 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2705 ;; On the average, pushdf using integers can be still shorter.
2706
2707 (define_insn "*pushdf"
2708 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2709 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2710 "!TARGET_64BIT"
2711 {
2712 /* This insn should be already split before reg-stack. */
2713 gcc_unreachable ();
2714 }
2715 [(set_attr "isa" "*,*,sse2")
2716 (set_attr "type" "multi")
2717 (set_attr "unit" "i387,*,*")
2718 (set_attr "mode" "DF,DI,DF")])
2719
2720 ;; %%% Kill this when call knows how to work this out.
2721 (define_split
2722 [(set (match_operand:DF 0 "push_operand" "")
2723 (match_operand:DF 1 "any_fp_register_operand" ""))]
2724 "reload_completed"
2725 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2726 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2727
2728 (define_insn "*pushsf_rex64"
2729 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2730 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2731 "TARGET_64BIT"
2732 {
2733 /* Anything else should be already split before reg-stack. */
2734 gcc_assert (which_alternative == 1);
2735 return "push{q}\t%q1";
2736 }
2737 [(set_attr "type" "multi,push,multi")
2738 (set_attr "unit" "i387,*,*")
2739 (set_attr "mode" "SF,DI,SF")])
2740
2741 (define_insn "*pushsf"
2742 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2743 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2744 "!TARGET_64BIT"
2745 {
2746 /* Anything else should be already split before reg-stack. */
2747 gcc_assert (which_alternative == 1);
2748 return "push{l}\t%1";
2749 }
2750 [(set_attr "type" "multi,push,multi")
2751 (set_attr "unit" "i387,*,*")
2752 (set_attr "mode" "SF,SI,SF")])
2753
2754 ;; %%% Kill this when call knows how to work this out.
2755 (define_split
2756 [(set (match_operand:SF 0 "push_operand" "")
2757 (match_operand:SF 1 "any_fp_register_operand" ""))]
2758 "reload_completed"
2759 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2760 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2761 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2762
2763 (define_split
2764 [(set (match_operand:SF 0 "push_operand" "")
2765 (match_operand:SF 1 "memory_operand" ""))]
2766 "reload_completed
2767 && (operands[2] = find_constant_src (insn))"
2768 [(set (match_dup 0) (match_dup 2))])
2769
2770 (define_split
2771 [(set (match_operand 0 "push_operand" "")
2772 (match_operand 1 "general_operand" ""))]
2773 "reload_completed
2774 && (GET_MODE (operands[0]) == TFmode
2775 || GET_MODE (operands[0]) == XFmode
2776 || GET_MODE (operands[0]) == DFmode)
2777 && !ANY_FP_REG_P (operands[1])"
2778 [(const_int 0)]
2779 "ix86_split_long_move (operands); DONE;")
2780 \f
2781 ;; Floating point move instructions.
2782
2783 (define_expand "movtf"
2784 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2785 (match_operand:TF 1 "nonimmediate_operand" ""))]
2786 "TARGET_SSE2"
2787 {
2788 ix86_expand_move (TFmode, operands);
2789 DONE;
2790 })
2791
2792 (define_expand "mov<mode>"
2793 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2794 (match_operand:X87MODEF 1 "general_operand" ""))]
2795 ""
2796 "ix86_expand_move (<MODE>mode, operands); DONE;")
2797
2798 (define_insn "*movtf_internal"
2799 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2800 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2801 "TARGET_SSE2
2802 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2803 && (!can_create_pseudo_p ()
2804 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2805 || GET_CODE (operands[1]) != CONST_DOUBLE
2806 || (optimize_function_for_size_p (cfun)
2807 && standard_sse_constant_p (operands[1])
2808 && !memory_operand (operands[0], TFmode))
2809 || (!TARGET_MEMORY_MISMATCH_STALL
2810 && memory_operand (operands[0], TFmode)))"
2811 {
2812 switch (which_alternative)
2813 {
2814 case 0:
2815 case 1:
2816 /* Handle misaligned load/store since we
2817 don't have movmisaligntf pattern. */
2818 if (misaligned_operand (operands[0], TFmode)
2819 || misaligned_operand (operands[1], TFmode))
2820 {
2821 if (get_attr_mode (insn) == MODE_V4SF)
2822 return "%vmovups\t{%1, %0|%0, %1}";
2823 else
2824 return "%vmovdqu\t{%1, %0|%0, %1}";
2825 }
2826 else
2827 {
2828 if (get_attr_mode (insn) == MODE_V4SF)
2829 return "%vmovaps\t{%1, %0|%0, %1}";
2830 else
2831 return "%vmovdqa\t{%1, %0|%0, %1}";
2832 }
2833
2834 case 2:
2835 return standard_sse_constant_opcode (insn, operands[1]);
2836
2837 case 3:
2838 case 4:
2839 return "#";
2840
2841 default:
2842 gcc_unreachable ();
2843 }
2844 }
2845 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2846 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2847 (set (attr "mode")
2848 (cond [(eq_attr "alternative" "0,2")
2849 (if_then_else
2850 (match_test "optimize_function_for_size_p (cfun)")
2851 (const_string "V4SF")
2852 (const_string "TI"))
2853 (eq_attr "alternative" "1")
2854 (if_then_else
2855 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2856 (match_test "optimize_function_for_size_p (cfun)"))
2857 (const_string "V4SF")
2858 (const_string "TI"))]
2859 (const_string "DI")))])
2860
2861 ;; Possible store forwarding (partial memory) stall in alternative 4.
2862 (define_insn "*movxf_internal"
2863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2864 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2865 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2866 && (!can_create_pseudo_p ()
2867 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2868 || GET_CODE (operands[1]) != CONST_DOUBLE
2869 || (optimize_function_for_size_p (cfun)
2870 && standard_80387_constant_p (operands[1]) > 0
2871 && !memory_operand (operands[0], XFmode))
2872 || (!TARGET_MEMORY_MISMATCH_STALL
2873 && memory_operand (operands[0], XFmode)))"
2874 {
2875 switch (which_alternative)
2876 {
2877 case 0:
2878 case 1:
2879 return output_387_reg_move (insn, operands);
2880
2881 case 2:
2882 return standard_80387_constant_opcode (operands[1]);
2883
2884 case 3:
2885 case 4:
2886 return "#";
2887
2888 default:
2889 gcc_unreachable ();
2890 }
2891 }
2892 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2893 (set_attr "mode" "XF,XF,XF,SI,SI")])
2894
2895 (define_insn "*movdf_internal_rex64"
2896 [(set (match_operand:DF 0 "nonimmediate_operand"
2897 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2898 (match_operand:DF 1 "general_operand"
2899 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2900 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2901 && (!can_create_pseudo_p ()
2902 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2903 || GET_CODE (operands[1]) != CONST_DOUBLE
2904 || (optimize_function_for_size_p (cfun)
2905 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2906 && standard_80387_constant_p (operands[1]) > 0)
2907 || (TARGET_SSE2 && TARGET_SSE_MATH
2908 && standard_sse_constant_p (operands[1]))))
2909 || memory_operand (operands[0], DFmode))"
2910 {
2911 switch (which_alternative)
2912 {
2913 case 0:
2914 case 1:
2915 return output_387_reg_move (insn, operands);
2916
2917 case 2:
2918 return standard_80387_constant_opcode (operands[1]);
2919
2920 case 3:
2921 case 4:
2922 return "mov{q}\t{%1, %0|%0, %1}";
2923
2924 case 5:
2925 return "movabs{q}\t{%1, %0|%0, %1}";
2926
2927 case 6:
2928 return "#";
2929
2930 case 7:
2931 return standard_sse_constant_opcode (insn, operands[1]);
2932
2933 case 8:
2934 case 9:
2935 case 10:
2936 switch (get_attr_mode (insn))
2937 {
2938 case MODE_V2DF:
2939 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2940 return "%vmovapd\t{%1, %0|%0, %1}";
2941 case MODE_V4SF:
2942 return "%vmovaps\t{%1, %0|%0, %1}";
2943
2944 case MODE_DI:
2945 return "%vmovq\t{%1, %0|%0, %1}";
2946 case MODE_DF:
2947 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2948 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2949 return "%vmovsd\t{%1, %0|%0, %1}";
2950 case MODE_V1DF:
2951 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2952 case MODE_V2SF:
2953 return "%vmovlps\t{%1, %d0|%d0, %1}";
2954 default:
2955 gcc_unreachable ();
2956 }
2957
2958 case 11:
2959 case 12:
2960 /* Handle broken assemblers that require movd instead of movq. */
2961 return "%vmovd\t{%1, %0|%0, %1}";
2962
2963 default:
2964 gcc_unreachable();
2965 }
2966 }
2967 [(set (attr "type")
2968 (cond [(eq_attr "alternative" "0,1,2")
2969 (const_string "fmov")
2970 (eq_attr "alternative" "3,4,5")
2971 (const_string "imov")
2972 (eq_attr "alternative" "6")
2973 (const_string "multi")
2974 (eq_attr "alternative" "7")
2975 (const_string "sselog1")
2976 ]
2977 (const_string "ssemov")))
2978 (set (attr "modrm")
2979 (if_then_else
2980 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2981 (const_string "0")
2982 (const_string "*")))
2983 (set (attr "length_immediate")
2984 (if_then_else
2985 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2986 (const_string "8")
2987 (const_string "*")))
2988 (set (attr "prefix")
2989 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2990 (const_string "orig")
2991 (const_string "maybe_vex")))
2992 (set (attr "prefix_data16")
2993 (if_then_else (eq_attr "mode" "V1DF")
2994 (const_string "1")
2995 (const_string "*")))
2996 (set (attr "mode")
2997 (cond [(eq_attr "alternative" "0,1,2")
2998 (const_string "DF")
2999 (eq_attr "alternative" "3,4,5,6,11,12")
3000 (const_string "DI")
3001
3002 /* xorps is one byte shorter. */
3003 (eq_attr "alternative" "7")
3004 (cond [(match_test "optimize_function_for_size_p (cfun)")
3005 (const_string "V4SF")
3006 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3007 (const_string "TI")
3008 ]
3009 (const_string "V2DF"))
3010
3011 /* For architectures resolving dependencies on
3012 whole SSE registers use APD move to break dependency
3013 chains, otherwise use short move to avoid extra work.
3014
3015 movaps encodes one byte shorter. */
3016 (eq_attr "alternative" "8")
3017 (cond
3018 [(match_test "optimize_function_for_size_p (cfun)")
3019 (const_string "V4SF")
3020 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3021 (const_string "V2DF")
3022 ]
3023 (const_string "DF"))
3024 /* For architectures resolving dependencies on register
3025 parts we may avoid extra work to zero out upper part
3026 of register. */
3027 (eq_attr "alternative" "9")
3028 (if_then_else
3029 (match_test "TARGET_SSE_SPLIT_REGS")
3030 (const_string "V1DF")
3031 (const_string "DF"))
3032 ]
3033 (const_string "DF")))])
3034
3035 ;; Possible store forwarding (partial memory) stall in alternative 4.
3036 (define_insn "*movdf_internal"
3037 [(set (match_operand:DF 0 "nonimmediate_operand"
3038 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3039 (match_operand:DF 1 "general_operand"
3040 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3041 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3042 && (!can_create_pseudo_p ()
3043 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3044 || GET_CODE (operands[1]) != CONST_DOUBLE
3045 || (optimize_function_for_size_p (cfun)
3046 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3047 && standard_80387_constant_p (operands[1]) > 0)
3048 || (TARGET_SSE2 && TARGET_SSE_MATH
3049 && standard_sse_constant_p (operands[1])))
3050 && !memory_operand (operands[0], DFmode))
3051 || (!TARGET_MEMORY_MISMATCH_STALL
3052 && memory_operand (operands[0], DFmode)))"
3053 {
3054 switch (which_alternative)
3055 {
3056 case 0:
3057 case 1:
3058 return output_387_reg_move (insn, operands);
3059
3060 case 2:
3061 return standard_80387_constant_opcode (operands[1]);
3062
3063 case 3:
3064 case 4:
3065 return "#";
3066
3067 case 5:
3068 case 9:
3069 return standard_sse_constant_opcode (insn, operands[1]);
3070
3071 case 6:
3072 case 7:
3073 case 8:
3074 case 10:
3075 case 11:
3076 case 12:
3077 switch (get_attr_mode (insn))
3078 {
3079 case MODE_V2DF:
3080 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3081 return "%vmovapd\t{%1, %0|%0, %1}";
3082 case MODE_V4SF:
3083 return "%vmovaps\t{%1, %0|%0, %1}";
3084
3085 case MODE_DI:
3086 return "%vmovq\t{%1, %0|%0, %1}";
3087 case MODE_DF:
3088 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3089 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3090 return "%vmovsd\t{%1, %0|%0, %1}";
3091 case MODE_V1DF:
3092 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3093 case MODE_V2SF:
3094 return "%vmovlps\t{%1, %d0|%d0, %1}";
3095 default:
3096 gcc_unreachable ();
3097 }
3098
3099 default:
3100 gcc_unreachable ();
3101 }
3102 }
3103 [(set (attr "isa")
3104 (if_then_else (eq_attr "alternative" "5,6,7,8")
3105 (const_string "sse2")
3106 (const_string "*")))
3107 (set (attr "type")
3108 (cond [(eq_attr "alternative" "0,1,2")
3109 (const_string "fmov")
3110 (eq_attr "alternative" "3,4")
3111 (const_string "multi")
3112 (eq_attr "alternative" "5,9")
3113 (const_string "sselog1")
3114 ]
3115 (const_string "ssemov")))
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3122 (const_string "1")
3123 (const_string "*")))
3124 (set (attr "mode")
3125 (cond [(eq_attr "alternative" "0,1,2")
3126 (const_string "DF")
3127 (eq_attr "alternative" "3,4")
3128 (const_string "SI")
3129
3130 /* For SSE1, we have many fewer alternatives. */
3131 (not (match_test "TARGET_SSE2"))
3132 (if_then_else
3133 (eq_attr "alternative" "5,6,9,10")
3134 (const_string "V4SF")
3135 (const_string "V2SF"))
3136
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5,9")
3139 (cond [(match_test "optimize_function_for_size_p (cfun)")
3140 (const_string "V4SF")
3141 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3142 (const_string "TI")
3143 ]
3144 (const_string "V2DF"))
3145
3146 /* For architectures resolving dependencies on
3147 whole SSE registers use APD move to break dependency
3148 chains, otherwise use short move to avoid extra work.
3149
3150 movaps encodes one byte shorter. */
3151 (eq_attr "alternative" "6,10")
3152 (cond
3153 [(match_test "optimize_function_for_size_p (cfun)")
3154 (const_string "V4SF")
3155 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3156 (const_string "V2DF")
3157 ]
3158 (const_string "DF"))
3159 /* For architectures resolving dependencies on register
3160 parts we may avoid extra work to zero out upper part
3161 of register. */
3162 (eq_attr "alternative" "7,11")
3163 (if_then_else
3164 (match_test "TARGET_SSE_SPLIT_REGS")
3165 (const_string "V1DF")
3166 (const_string "DF"))
3167 ]
3168 (const_string "DF")))])
3169
3170 (define_insn "*movsf_internal"
3171 [(set (match_operand:SF 0 "nonimmediate_operand"
3172 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3173 (match_operand:SF 1 "general_operand"
3174 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3175 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3176 && (!can_create_pseudo_p ()
3177 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3178 || GET_CODE (operands[1]) != CONST_DOUBLE
3179 || (optimize_function_for_size_p (cfun)
3180 && ((!TARGET_SSE_MATH
3181 && standard_80387_constant_p (operands[1]) > 0)
3182 || (TARGET_SSE_MATH
3183 && standard_sse_constant_p (operands[1]))))
3184 || memory_operand (operands[0], SFmode))"
3185 {
3186 switch (which_alternative)
3187 {
3188 case 0:
3189 case 1:
3190 return output_387_reg_move (insn, operands);
3191
3192 case 2:
3193 return standard_80387_constant_opcode (operands[1]);
3194
3195 case 3:
3196 case 4:
3197 return "mov{l}\t{%1, %0|%0, %1}";
3198
3199 case 5:
3200 return standard_sse_constant_opcode (insn, operands[1]);
3201
3202 case 6:
3203 if (get_attr_mode (insn) == MODE_V4SF)
3204 return "%vmovaps\t{%1, %0|%0, %1}";
3205 if (TARGET_AVX)
3206 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3207
3208 case 7:
3209 case 8:
3210 return "%vmovss\t{%1, %0|%0, %1}";
3211
3212 case 9:
3213 case 10:
3214 case 14:
3215 case 15:
3216 return "movd\t{%1, %0|%0, %1}";
3217
3218 case 11:
3219 return "movq\t{%1, %0|%0, %1}";
3220
3221 case 12:
3222 case 13:
3223 return "%vmovd\t{%1, %0|%0, %1}";
3224
3225 default:
3226 gcc_unreachable ();
3227 }
3228 }
3229 [(set (attr "type")
3230 (cond [(eq_attr "alternative" "0,1,2")
3231 (const_string "fmov")
3232 (eq_attr "alternative" "3,4")
3233 (const_string "multi")
3234 (eq_attr "alternative" "5")
3235 (const_string "sselog1")
3236 (eq_attr "alternative" "9,10,11,14,15")
3237 (const_string "mmxmov")
3238 ]
3239 (const_string "ssemov")))
3240 (set (attr "prefix")
3241 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3242 (const_string "maybe_vex")
3243 (const_string "orig")))
3244 (set (attr "mode")
3245 (cond [(eq_attr "alternative" "3,4,9,10")
3246 (const_string "SI")
3247 (eq_attr "alternative" "5")
3248 (if_then_else
3249 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3250 (match_test "TARGET_SSE2"))
3251 (not (match_test "optimize_function_for_size_p (cfun)")))
3252 (const_string "TI")
3253 (const_string "V4SF"))
3254 /* For architectures resolving dependencies on
3255 whole SSE registers use APS move to break dependency
3256 chains, otherwise use short move to avoid extra work.
3257
3258 Do the same for architectures resolving dependencies on
3259 the parts. While in DF mode it is better to always handle
3260 just register parts, the SF mode is different due to lack
3261 of instructions to load just part of the register. It is
3262 better to maintain the whole registers in single format
3263 to avoid problems on using packed logical operations. */
3264 (eq_attr "alternative" "6")
3265 (if_then_else
3266 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3267 (match_test "TARGET_SSE_SPLIT_REGS"))
3268 (const_string "V4SF")
3269 (const_string "SF"))
3270 (eq_attr "alternative" "11")
3271 (const_string "DI")]
3272 (const_string "SF")))])
3273
3274 (define_split
3275 [(set (match_operand 0 "any_fp_register_operand" "")
3276 (match_operand 1 "memory_operand" ""))]
3277 "reload_completed
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == DFmode
3281 || GET_MODE (operands[0]) == SFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3284 {
3285 rtx c = operands[2];
3286 int r = REGNO (operands[0]);
3287
3288 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3290 FAIL;
3291 })
3292
3293 (define_split
3294 [(set (match_operand 0 "any_fp_register_operand" "")
3295 (float_extend (match_operand 1 "memory_operand" "")))]
3296 "reload_completed
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode)
3300 && (operands[2] = find_constant_src (insn))"
3301 [(set (match_dup 0) (match_dup 2))]
3302 {
3303 rtx c = operands[2];
3304 int r = REGNO (operands[0]);
3305
3306 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3308 FAIL;
3309 })
3310
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3312 (define_split
3313 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3315 "reload_completed
3316 && (standard_80387_constant_p (operands[1]) == 8
3317 || standard_80387_constant_p (operands[1]) == 9)"
3318 [(set (match_dup 0)(match_dup 1))
3319 (set (match_dup 0)
3320 (neg:X87MODEF (match_dup 0)))]
3321 {
3322 REAL_VALUE_TYPE r;
3323
3324 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325 if (real_isnegzero (&r))
3326 operands[1] = CONST0_RTX (<MODE>mode);
3327 else
3328 operands[1] = CONST1_RTX (<MODE>mode);
3329 })
3330
3331 (define_split
3332 [(set (match_operand 0 "nonimmediate_operand" "")
3333 (match_operand 1 "general_operand" ""))]
3334 "reload_completed
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3339 [(const_int 0)]
3340 "ix86_split_long_move (operands); DONE;")
3341
3342 (define_insn "swapxf"
3343 [(set (match_operand:XF 0 "register_operand" "+f")
3344 (match_operand:XF 1 "register_operand" "+f"))
3345 (set (match_dup 1)
3346 (match_dup 0))]
3347 "TARGET_80387"
3348 {
3349 if (STACK_TOP_P (operands[0]))
3350 return "fxch\t%1";
3351 else
3352 return "fxch\t%0";
3353 }
3354 [(set_attr "type" "fxch")
3355 (set_attr "mode" "XF")])
3356
3357 (define_insn "*swap<mode>"
3358 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3360 (set (match_dup 1)
3361 (match_dup 0))]
3362 "TARGET_80387 || reload_completed"
3363 {
3364 if (STACK_TOP_P (operands[0]))
3365 return "fxch\t%1";
3366 else
3367 return "fxch\t%0";
3368 }
3369 [(set_attr "type" "fxch")
3370 (set_attr "mode" "<MODE>")])
3371 \f
3372 ;; Zero extension instructions
3373
3374 (define_expand "zero_extendsidi2"
3375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))])
3377
3378 (define_insn "*zero_extendsidi2_rex64"
3379 [(set (match_operand:DI 0 "nonimmediate_operand"
3380 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3381 (zero_extend:DI
3382 (match_operand:SI 1 "x86_64_zext_general_operand"
3383 "rmZ,0,r ,m ,r ,m*x")))]
3384 "TARGET_64BIT"
3385 "@
3386 mov{l}\t{%1, %k0|%k0, %1}
3387 #
3388 movd\t{%1, %0|%0, %1}
3389 movd\t{%1, %0|%0, %1}
3390 %vmovd\t{%1, %0|%0, %1}
3391 %vmovd\t{%1, %0|%0, %1}"
3392 [(set_attr "isa" "*,*,*,*,*,sse2")
3393 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3394 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3395 (set_attr "prefix_0f" "0,*,*,*,*,*")
3396 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3397
3398 (define_insn "*zero_extendsidi2"
3399 [(set (match_operand:DI 0 "nonimmediate_operand"
3400 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3401 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3402 "0 ,rm,r ,r ,m ,r ,m*x")))]
3403 "!TARGET_64BIT"
3404 "@
3405 #
3406 #
3407 #
3408 movd\t{%1, %0|%0, %1}
3409 movd\t{%1, %0|%0, %1}
3410 %vmovd\t{%1, %0|%0, %1}
3411 %vmovd\t{%1, %0|%0, %1}"
3412 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3413 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3414 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3415 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3416
3417 (define_split
3418 [(set (match_operand:DI 0 "memory_operand" "")
3419 (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))]
3420 "reload_completed"
3421 [(set (match_dup 4) (const_int 0))]
3422 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3423
3424 (define_split
3425 [(set (match_operand:DI 0 "register_operand" "")
3426 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3427 "!TARGET_64BIT && reload_completed
3428 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3429 && true_regnum (operands[0]) == true_regnum (operands[1])"
3430 [(set (match_dup 4) (const_int 0))]
3431 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3432
3433 (define_split
3434 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3435 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3436 "!TARGET_64BIT && reload_completed
3437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3438 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3439 [(set (match_dup 3) (match_dup 1))
3440 (set (match_dup 4) (const_int 0))]
3441 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3442
3443 (define_insn "zero_extend<mode>di2"
3444 [(set (match_operand:DI 0 "register_operand" "=r")
3445 (zero_extend:DI
3446 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3447 "TARGET_64BIT"
3448 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3449 [(set_attr "type" "imovx")
3450 (set_attr "mode" "SI")])
3451
3452 (define_expand "zero_extend<mode>si2"
3453 [(set (match_operand:SI 0 "register_operand" "")
3454 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand" "")))]
3455 ""
3456 {
3457 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3458 {
3459 operands[1] = force_reg (<MODE>mode, operands[1]);
3460 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3461 DONE;
3462 }
3463 })
3464
3465 (define_insn_and_split "zero_extend<mode>si2_and"
3466 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3467 (zero_extend:SI
3468 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3469 (clobber (reg:CC FLAGS_REG))]
3470 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3471 "#"
3472 "&& reload_completed"
3473 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3474 (clobber (reg:CC FLAGS_REG))])]
3475 {
3476 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3477 {
3478 ix86_expand_clear (operands[0]);
3479
3480 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3481 emit_insn (gen_movstrict<mode>
3482 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3483 DONE;
3484 }
3485
3486 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3487 }
3488 [(set_attr "type" "alu1")
3489 (set_attr "mode" "SI")])
3490
3491 (define_insn "*zero_extend<mode>si2"
3492 [(set (match_operand:SI 0 "register_operand" "=r")
3493 (zero_extend:SI
3494 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3495 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3496 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3497 [(set_attr "type" "imovx")
3498 (set_attr "mode" "SI")])
3499
3500 (define_expand "zero_extendqihi2"
3501 [(set (match_operand:HI 0 "register_operand" "")
3502 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3503 ""
3504 {
3505 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3506 {
3507 operands[1] = force_reg (QImode, operands[1]);
3508 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3509 DONE;
3510 }
3511 })
3512
3513 (define_insn_and_split "zero_extendqihi2_and"
3514 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3515 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3516 (clobber (reg:CC FLAGS_REG))]
3517 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3518 "#"
3519 "&& reload_completed"
3520 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3521 (clobber (reg:CC FLAGS_REG))])]
3522 {
3523 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3524 {
3525 ix86_expand_clear (operands[0]);
3526
3527 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3528 emit_insn (gen_movstrictqi
3529 (gen_lowpart (QImode, operands[0]), operands[1]));
3530 DONE;
3531 }
3532
3533 operands[0] = gen_lowpart (SImode, operands[0]);
3534 }
3535 [(set_attr "type" "alu1")
3536 (set_attr "mode" "SI")])
3537
3538 ; zero extend to SImode to avoid partial register stalls
3539 (define_insn "*zero_extendqihi2"
3540 [(set (match_operand:HI 0 "register_operand" "=r")
3541 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3542 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3543 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3544 [(set_attr "type" "imovx")
3545 (set_attr "mode" "SI")])
3546 \f
3547 ;; Sign extension instructions
3548
3549 (define_expand "extendsidi2"
3550 [(set (match_operand:DI 0 "register_operand" "")
3551 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3552 ""
3553 {
3554 if (!TARGET_64BIT)
3555 {
3556 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3557 DONE;
3558 }
3559 })
3560
3561 (define_insn "*extendsidi2_rex64"
3562 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3563 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3564 "TARGET_64BIT"
3565 "@
3566 {cltq|cdqe}
3567 movs{lq|x}\t{%1, %0|%0, %1}"
3568 [(set_attr "type" "imovx")
3569 (set_attr "mode" "DI")
3570 (set_attr "prefix_0f" "0")
3571 (set_attr "modrm" "0,1")])
3572
3573 (define_insn "extendsidi2_1"
3574 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3575 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3576 (clobber (reg:CC FLAGS_REG))
3577 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3578 "!TARGET_64BIT"
3579 "#")
3580
3581 ;; Extend to memory case when source register does die.
3582 (define_split
3583 [(set (match_operand:DI 0 "memory_operand" "")
3584 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3585 (clobber (reg:CC FLAGS_REG))
3586 (clobber (match_operand:SI 2 "register_operand" ""))]
3587 "(reload_completed
3588 && dead_or_set_p (insn, operands[1])
3589 && !reg_mentioned_p (operands[1], operands[0]))"
3590 [(set (match_dup 3) (match_dup 1))
3591 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3592 (clobber (reg:CC FLAGS_REG))])
3593 (set (match_dup 4) (match_dup 1))]
3594 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3595
3596 ;; Extend to memory case when source register does not die.
3597 (define_split
3598 [(set (match_operand:DI 0 "memory_operand" "")
3599 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3600 (clobber (reg:CC FLAGS_REG))
3601 (clobber (match_operand:SI 2 "register_operand" ""))]
3602 "reload_completed"
3603 [(const_int 0)]
3604 {
3605 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3606
3607 emit_move_insn (operands[3], operands[1]);
3608
3609 /* Generate a cltd if possible and doing so it profitable. */
3610 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3611 && true_regnum (operands[1]) == AX_REG
3612 && true_regnum (operands[2]) == DX_REG)
3613 {
3614 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3615 }
3616 else
3617 {
3618 emit_move_insn (operands[2], operands[1]);
3619 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3620 }
3621 emit_move_insn (operands[4], operands[2]);
3622 DONE;
3623 })
3624
3625 ;; Extend to register case. Optimize case where source and destination
3626 ;; registers match and cases where we can use cltd.
3627 (define_split
3628 [(set (match_operand:DI 0 "register_operand" "")
3629 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3630 (clobber (reg:CC FLAGS_REG))
3631 (clobber (match_scratch:SI 2 ""))]
3632 "reload_completed"
3633 [(const_int 0)]
3634 {
3635 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3636
3637 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3638 emit_move_insn (operands[3], operands[1]);
3639
3640 /* Generate a cltd if possible and doing so it profitable. */
3641 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3642 && true_regnum (operands[3]) == AX_REG
3643 && true_regnum (operands[4]) == DX_REG)
3644 {
3645 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3646 DONE;
3647 }
3648
3649 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3650 emit_move_insn (operands[4], operands[1]);
3651
3652 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3653 DONE;
3654 })
3655
3656 (define_insn "extend<mode>di2"
3657 [(set (match_operand:DI 0 "register_operand" "=r")
3658 (sign_extend:DI
3659 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3660 "TARGET_64BIT"
3661 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3662 [(set_attr "type" "imovx")
3663 (set_attr "mode" "DI")])
3664
3665 (define_insn "extendhisi2"
3666 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3667 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3668 ""
3669 {
3670 switch (get_attr_prefix_0f (insn))
3671 {
3672 case 0:
3673 return "{cwtl|cwde}";
3674 default:
3675 return "movs{wl|x}\t{%1, %0|%0, %1}";
3676 }
3677 }
3678 [(set_attr "type" "imovx")
3679 (set_attr "mode" "SI")
3680 (set (attr "prefix_0f")
3681 ;; movsx is short decodable while cwtl is vector decoded.
3682 (if_then_else (and (eq_attr "cpu" "!k6")
3683 (eq_attr "alternative" "0"))
3684 (const_string "0")
3685 (const_string "1")))
3686 (set (attr "modrm")
3687 (if_then_else (eq_attr "prefix_0f" "0")
3688 (const_string "0")
3689 (const_string "1")))])
3690
3691 (define_insn "*extendhisi2_zext"
3692 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3693 (zero_extend:DI
3694 (sign_extend:SI
3695 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3696 "TARGET_64BIT"
3697 {
3698 switch (get_attr_prefix_0f (insn))
3699 {
3700 case 0:
3701 return "{cwtl|cwde}";
3702 default:
3703 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3704 }
3705 }
3706 [(set_attr "type" "imovx")
3707 (set_attr "mode" "SI")
3708 (set (attr "prefix_0f")
3709 ;; movsx is short decodable while cwtl is vector decoded.
3710 (if_then_else (and (eq_attr "cpu" "!k6")
3711 (eq_attr "alternative" "0"))
3712 (const_string "0")
3713 (const_string "1")))
3714 (set (attr "modrm")
3715 (if_then_else (eq_attr "prefix_0f" "0")
3716 (const_string "0")
3717 (const_string "1")))])
3718
3719 (define_insn "extendqisi2"
3720 [(set (match_operand:SI 0 "register_operand" "=r")
3721 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3722 ""
3723 "movs{bl|x}\t{%1, %0|%0, %1}"
3724 [(set_attr "type" "imovx")
3725 (set_attr "mode" "SI")])
3726
3727 (define_insn "*extendqisi2_zext"
3728 [(set (match_operand:DI 0 "register_operand" "=r")
3729 (zero_extend:DI
3730 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3731 "TARGET_64BIT"
3732 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3733 [(set_attr "type" "imovx")
3734 (set_attr "mode" "SI")])
3735
3736 (define_insn "extendqihi2"
3737 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3738 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3739 ""
3740 {
3741 switch (get_attr_prefix_0f (insn))
3742 {
3743 case 0:
3744 return "{cbtw|cbw}";
3745 default:
3746 return "movs{bw|x}\t{%1, %0|%0, %1}";
3747 }
3748 }
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "HI")
3751 (set (attr "prefix_0f")
3752 ;; movsx is short decodable while cwtl is vector decoded.
3753 (if_then_else (and (eq_attr "cpu" "!k6")
3754 (eq_attr "alternative" "0"))
3755 (const_string "0")
3756 (const_string "1")))
3757 (set (attr "modrm")
3758 (if_then_else (eq_attr "prefix_0f" "0")
3759 (const_string "0")
3760 (const_string "1")))])
3761 \f
3762 ;; Conversions between float and double.
3763
3764 ;; These are all no-ops in the model used for the 80387.
3765 ;; So just emit moves.
3766
3767 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3768 (define_split
3769 [(set (match_operand:DF 0 "push_operand" "")
3770 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3771 "reload_completed"
3772 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3773 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3774
3775 (define_split
3776 [(set (match_operand:XF 0 "push_operand" "")
3777 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3778 "reload_completed"
3779 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3780 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3781 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3782
3783 (define_expand "extendsfdf2"
3784 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3785 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3786 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3787 {
3788 /* ??? Needed for compress_float_constant since all fp constants
3789 are TARGET_LEGITIMATE_CONSTANT_P. */
3790 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3791 {
3792 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3793 && standard_80387_constant_p (operands[1]) > 0)
3794 {
3795 operands[1] = simplify_const_unary_operation
3796 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3797 emit_move_insn_1 (operands[0], operands[1]);
3798 DONE;
3799 }
3800 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3801 }
3802 })
3803
3804 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3805 cvtss2sd:
3806 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3807 cvtps2pd xmm2,xmm1
3808 We do the conversion post reload to avoid producing of 128bit spills
3809 that might lead to ICE on 32bit target. The sequence unlikely combine
3810 anyway. */
3811 (define_split
3812 [(set (match_operand:DF 0 "register_operand" "")
3813 (float_extend:DF
3814 (match_operand:SF 1 "nonimmediate_operand" "")))]
3815 "TARGET_USE_VECTOR_FP_CONVERTS
3816 && optimize_insn_for_speed_p ()
3817 && reload_completed && SSE_REG_P (operands[0])"
3818 [(set (match_dup 2)
3819 (float_extend:V2DF
3820 (vec_select:V2SF
3821 (match_dup 3)
3822 (parallel [(const_int 0) (const_int 1)]))))]
3823 {
3824 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3825 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3826 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3827 Try to avoid move when unpacking can be done in source. */
3828 if (REG_P (operands[1]))
3829 {
3830 /* If it is unsafe to overwrite upper half of source, we need
3831 to move to destination and unpack there. */
3832 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3833 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3834 && true_regnum (operands[0]) != true_regnum (operands[1]))
3835 {
3836 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3837 emit_move_insn (tmp, operands[1]);
3838 }
3839 else
3840 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3841 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3842 operands[3]));
3843 }
3844 else
3845 emit_insn (gen_vec_setv4sf_0 (operands[3],
3846 CONST0_RTX (V4SFmode), operands[1]));
3847 })
3848
3849 (define_insn "*extendsfdf2_mixed"
3850 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3851 (float_extend:DF
3852 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3853 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3854 {
3855 switch (which_alternative)
3856 {
3857 case 0:
3858 case 1:
3859 return output_387_reg_move (insn, operands);
3860
3861 case 2:
3862 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3863
3864 default:
3865 gcc_unreachable ();
3866 }
3867 }
3868 [(set_attr "type" "fmov,fmov,ssecvt")
3869 (set_attr "prefix" "orig,orig,maybe_vex")
3870 (set_attr "mode" "SF,XF,DF")])
3871
3872 (define_insn "*extendsfdf2_sse"
3873 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3874 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3875 "TARGET_SSE2 && TARGET_SSE_MATH"
3876 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3877 [(set_attr "type" "ssecvt")
3878 (set_attr "prefix" "maybe_vex")
3879 (set_attr "mode" "DF")])
3880
3881 (define_insn "*extendsfdf2_i387"
3882 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3883 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3884 "TARGET_80387"
3885 "* return output_387_reg_move (insn, operands);"
3886 [(set_attr "type" "fmov")
3887 (set_attr "mode" "SF,XF")])
3888
3889 (define_expand "extend<mode>xf2"
3890 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3891 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3892 "TARGET_80387"
3893 {
3894 /* ??? Needed for compress_float_constant since all fp constants
3895 are TARGET_LEGITIMATE_CONSTANT_P. */
3896 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3897 {
3898 if (standard_80387_constant_p (operands[1]) > 0)
3899 {
3900 operands[1] = simplify_const_unary_operation
3901 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3902 emit_move_insn_1 (operands[0], operands[1]);
3903 DONE;
3904 }
3905 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3906 }
3907 })
3908
3909 (define_insn "*extend<mode>xf2_i387"
3910 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3911 (float_extend:XF
3912 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3913 "TARGET_80387"
3914 "* return output_387_reg_move (insn, operands);"
3915 [(set_attr "type" "fmov")
3916 (set_attr "mode" "<MODE>,XF")])
3917
3918 ;; %%% This seems bad bad news.
3919 ;; This cannot output into an f-reg because there is no way to be sure
3920 ;; of truncating in that case. Otherwise this is just like a simple move
3921 ;; insn. So we pretend we can output to a reg in order to get better
3922 ;; register preferencing, but we really use a stack slot.
3923
3924 ;; Conversion from DFmode to SFmode.
3925
3926 (define_expand "truncdfsf2"
3927 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3928 (float_truncate:SF
3929 (match_operand:DF 1 "nonimmediate_operand" "")))]
3930 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3931 {
3932 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3933 ;
3934 else if (flag_unsafe_math_optimizations)
3935 ;
3936 else
3937 {
3938 enum ix86_stack_slot slot = (virtuals_instantiated
3939 ? SLOT_TEMP
3940 : SLOT_VIRTUAL);
3941 rtx temp = assign_386_stack_local (SFmode, slot);
3942 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3943 DONE;
3944 }
3945 })
3946
3947 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3948 cvtsd2ss:
3949 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3950 cvtpd2ps xmm2,xmm1
3951 We do the conversion post reload to avoid producing of 128bit spills
3952 that might lead to ICE on 32bit target. The sequence unlikely combine
3953 anyway. */
3954 (define_split
3955 [(set (match_operand:SF 0 "register_operand" "")
3956 (float_truncate:SF
3957 (match_operand:DF 1 "nonimmediate_operand" "")))]
3958 "TARGET_USE_VECTOR_FP_CONVERTS
3959 && optimize_insn_for_speed_p ()
3960 && reload_completed && SSE_REG_P (operands[0])"
3961 [(set (match_dup 2)
3962 (vec_concat:V4SF
3963 (float_truncate:V2SF
3964 (match_dup 4))
3965 (match_dup 3)))]
3966 {
3967 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3968 operands[3] = CONST0_RTX (V2SFmode);
3969 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3970 /* Use movsd for loading from memory, unpcklpd for registers.
3971 Try to avoid move when unpacking can be done in source, or SSE3
3972 movddup is available. */
3973 if (REG_P (operands[1]))
3974 {
3975 if (!TARGET_SSE3
3976 && true_regnum (operands[0]) != true_regnum (operands[1])
3977 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3978 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3979 {
3980 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3981 emit_move_insn (tmp, operands[1]);
3982 operands[1] = tmp;
3983 }
3984 else if (!TARGET_SSE3)
3985 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3986 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3987 }
3988 else
3989 emit_insn (gen_sse2_loadlpd (operands[4],
3990 CONST0_RTX (V2DFmode), operands[1]));
3991 })
3992
3993 (define_expand "truncdfsf2_with_temp"
3994 [(parallel [(set (match_operand:SF 0 "" "")
3995 (float_truncate:SF (match_operand:DF 1 "" "")))
3996 (clobber (match_operand:SF 2 "" ""))])])
3997
3998 (define_insn "*truncdfsf_fast_mixed"
3999 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4000 (float_truncate:SF
4001 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4002 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4003 {
4004 switch (which_alternative)
4005 {
4006 case 0:
4007 return output_387_reg_move (insn, operands);
4008 case 1:
4009 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4010 default:
4011 gcc_unreachable ();
4012 }
4013 }
4014 [(set_attr "type" "fmov,ssecvt")
4015 (set_attr "prefix" "orig,maybe_vex")
4016 (set_attr "mode" "SF")])
4017
4018 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4019 ;; because nothing we do here is unsafe.
4020 (define_insn "*truncdfsf_fast_sse"
4021 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4022 (float_truncate:SF
4023 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4024 "TARGET_SSE2 && TARGET_SSE_MATH"
4025 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4026 [(set_attr "type" "ssecvt")
4027 (set_attr "prefix" "maybe_vex")
4028 (set_attr "mode" "SF")])
4029
4030 (define_insn "*truncdfsf_fast_i387"
4031 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4032 (float_truncate:SF
4033 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4034 "TARGET_80387 && flag_unsafe_math_optimizations"
4035 "* return output_387_reg_move (insn, operands);"
4036 [(set_attr "type" "fmov")
4037 (set_attr "mode" "SF")])
4038
4039 (define_insn "*truncdfsf_mixed"
4040 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4041 (float_truncate:SF
4042 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4043 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4044 "TARGET_MIX_SSE_I387"
4045 {
4046 switch (which_alternative)
4047 {
4048 case 0:
4049 return output_387_reg_move (insn, operands);
4050 case 1:
4051 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4052
4053 default:
4054 return "#";
4055 }
4056 }
4057 [(set_attr "isa" "*,sse2,*,*,*")
4058 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4059 (set_attr "unit" "*,*,i387,i387,i387")
4060 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4061 (set_attr "mode" "SF")])
4062
4063 (define_insn "*truncdfsf_i387"
4064 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4065 (float_truncate:SF
4066 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4067 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4068 "TARGET_80387"
4069 {
4070 switch (which_alternative)
4071 {
4072 case 0:
4073 return output_387_reg_move (insn, operands);
4074
4075 default:
4076 return "#";
4077 }
4078 }
4079 [(set_attr "type" "fmov,multi,multi,multi")
4080 (set_attr "unit" "*,i387,i387,i387")
4081 (set_attr "mode" "SF")])
4082
4083 (define_insn "*truncdfsf2_i387_1"
4084 [(set (match_operand:SF 0 "memory_operand" "=m")
4085 (float_truncate:SF
4086 (match_operand:DF 1 "register_operand" "f")))]
4087 "TARGET_80387
4088 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4089 && !TARGET_MIX_SSE_I387"
4090 "* return output_387_reg_move (insn, operands);"
4091 [(set_attr "type" "fmov")
4092 (set_attr "mode" "SF")])
4093
4094 (define_split
4095 [(set (match_operand:SF 0 "register_operand" "")
4096 (float_truncate:SF
4097 (match_operand:DF 1 "fp_register_operand" "")))
4098 (clobber (match_operand 2 "" ""))]
4099 "reload_completed"
4100 [(set (match_dup 2) (match_dup 1))
4101 (set (match_dup 0) (match_dup 2))]
4102 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4103
4104 ;; Conversion from XFmode to {SF,DF}mode
4105
4106 (define_expand "truncxf<mode>2"
4107 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4108 (float_truncate:MODEF
4109 (match_operand:XF 1 "register_operand" "")))
4110 (clobber (match_dup 2))])]
4111 "TARGET_80387"
4112 {
4113 if (flag_unsafe_math_optimizations)
4114 {
4115 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4116 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4117 if (reg != operands[0])
4118 emit_move_insn (operands[0], reg);
4119 DONE;
4120 }
4121 else
4122 {
4123 enum ix86_stack_slot slot = (virtuals_instantiated
4124 ? SLOT_TEMP
4125 : SLOT_VIRTUAL);
4126 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4127 }
4128 })
4129
4130 (define_insn "*truncxfsf2_mixed"
4131 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4132 (float_truncate:SF
4133 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4134 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4135 "TARGET_80387"
4136 {
4137 gcc_assert (!which_alternative);
4138 return output_387_reg_move (insn, operands);
4139 }
4140 [(set_attr "type" "fmov,multi,multi,multi")
4141 (set_attr "unit" "*,i387,i387,i387")
4142 (set_attr "mode" "SF")])
4143
4144 (define_insn "*truncxfdf2_mixed"
4145 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4146 (float_truncate:DF
4147 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4148 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4149 "TARGET_80387"
4150 {
4151 gcc_assert (!which_alternative);
4152 return output_387_reg_move (insn, operands);
4153 }
4154 [(set_attr "isa" "*,*,sse2,*")
4155 (set_attr "type" "fmov,multi,multi,multi")
4156 (set_attr "unit" "*,i387,i387,i387")
4157 (set_attr "mode" "DF")])
4158
4159 (define_insn "truncxf<mode>2_i387_noop"
4160 [(set (match_operand:MODEF 0 "register_operand" "=f")
4161 (float_truncate:MODEF
4162 (match_operand:XF 1 "register_operand" "f")))]
4163 "TARGET_80387 && flag_unsafe_math_optimizations"
4164 "* return output_387_reg_move (insn, operands);"
4165 [(set_attr "type" "fmov")
4166 (set_attr "mode" "<MODE>")])
4167
4168 (define_insn "*truncxf<mode>2_i387"
4169 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4170 (float_truncate:MODEF
4171 (match_operand:XF 1 "register_operand" "f")))]
4172 "TARGET_80387"
4173 "* return output_387_reg_move (insn, operands);"
4174 [(set_attr "type" "fmov")
4175 (set_attr "mode" "<MODE>")])
4176
4177 (define_split
4178 [(set (match_operand:MODEF 0 "register_operand" "")
4179 (float_truncate:MODEF
4180 (match_operand:XF 1 "register_operand" "")))
4181 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4182 "TARGET_80387 && reload_completed"
4183 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4184 (set (match_dup 0) (match_dup 2))])
4185
4186 (define_split
4187 [(set (match_operand:MODEF 0 "memory_operand" "")
4188 (float_truncate:MODEF
4189 (match_operand:XF 1 "register_operand" "")))
4190 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4191 "TARGET_80387"
4192 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4193 \f
4194 ;; Signed conversion to DImode.
4195
4196 (define_expand "fix_truncxfdi2"
4197 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4198 (fix:DI (match_operand:XF 1 "register_operand" "")))
4199 (clobber (reg:CC FLAGS_REG))])]
4200 "TARGET_80387"
4201 {
4202 if (TARGET_FISTTP)
4203 {
4204 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4205 DONE;
4206 }
4207 })
4208
4209 (define_expand "fix_trunc<mode>di2"
4210 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4211 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4212 (clobber (reg:CC FLAGS_REG))])]
4213 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4214 {
4215 if (TARGET_FISTTP
4216 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4217 {
4218 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4219 DONE;
4220 }
4221 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4222 {
4223 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4224 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4225 if (out != operands[0])
4226 emit_move_insn (operands[0], out);
4227 DONE;
4228 }
4229 })
4230
4231 ;; Signed conversion to SImode.
4232
4233 (define_expand "fix_truncxfsi2"
4234 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4235 (fix:SI (match_operand:XF 1 "register_operand" "")))
4236 (clobber (reg:CC FLAGS_REG))])]
4237 "TARGET_80387"
4238 {
4239 if (TARGET_FISTTP)
4240 {
4241 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4242 DONE;
4243 }
4244 })
4245
4246 (define_expand "fix_trunc<mode>si2"
4247 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4248 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4250 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4251 {
4252 if (TARGET_FISTTP
4253 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4254 {
4255 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4256 DONE;
4257 }
4258 if (SSE_FLOAT_MODE_P (<MODE>mode))
4259 {
4260 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4261 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4262 if (out != operands[0])
4263 emit_move_insn (operands[0], out);
4264 DONE;
4265 }
4266 })
4267
4268 ;; Signed conversion to HImode.
4269
4270 (define_expand "fix_trunc<mode>hi2"
4271 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4272 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4273 (clobber (reg:CC FLAGS_REG))])]
4274 "TARGET_80387
4275 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4276 {
4277 if (TARGET_FISTTP)
4278 {
4279 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4280 DONE;
4281 }
4282 })
4283
4284 ;; Unsigned conversion to SImode.
4285
4286 (define_expand "fixuns_trunc<mode>si2"
4287 [(parallel
4288 [(set (match_operand:SI 0 "register_operand" "")
4289 (unsigned_fix:SI
4290 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4291 (use (match_dup 2))
4292 (clobber (match_scratch:<ssevecmode> 3 ""))
4293 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4294 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4295 {
4296 enum machine_mode mode = <MODE>mode;
4297 enum machine_mode vecmode = <ssevecmode>mode;
4298 REAL_VALUE_TYPE TWO31r;
4299 rtx two31;
4300
4301 if (optimize_insn_for_size_p ())
4302 FAIL;
4303
4304 real_ldexp (&TWO31r, &dconst1, 31);
4305 two31 = const_double_from_real_value (TWO31r, mode);
4306 two31 = ix86_build_const_vector (vecmode, true, two31);
4307 operands[2] = force_reg (vecmode, two31);
4308 })
4309
4310 (define_insn_and_split "*fixuns_trunc<mode>_1"
4311 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4312 (unsigned_fix:SI
4313 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4314 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4315 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4316 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4317 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4318 && optimize_function_for_speed_p (cfun)"
4319 "#"
4320 "&& reload_completed"
4321 [(const_int 0)]
4322 {
4323 ix86_split_convert_uns_si_sse (operands);
4324 DONE;
4325 })
4326
4327 ;; Unsigned conversion to HImode.
4328 ;; Without these patterns, we'll try the unsigned SI conversion which
4329 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4330
4331 (define_expand "fixuns_trunc<mode>hi2"
4332 [(set (match_dup 2)
4333 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4334 (set (match_operand:HI 0 "nonimmediate_operand" "")
4335 (subreg:HI (match_dup 2) 0))]
4336 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4337 "operands[2] = gen_reg_rtx (SImode);")
4338
4339 ;; When SSE is available, it is always faster to use it!
4340 (define_insn "fix_trunc<mode>di_sse"
4341 [(set (match_operand:DI 0 "register_operand" "=r,r")
4342 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4343 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4344 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4345 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4346 [(set_attr "type" "sseicvt")
4347 (set_attr "prefix" "maybe_vex")
4348 (set_attr "prefix_rex" "1")
4349 (set_attr "mode" "<MODE>")
4350 (set_attr "athlon_decode" "double,vector")
4351 (set_attr "amdfam10_decode" "double,double")
4352 (set_attr "bdver1_decode" "double,double")])
4353
4354 (define_insn "fix_trunc<mode>si_sse"
4355 [(set (match_operand:SI 0 "register_operand" "=r,r")
4356 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4357 "SSE_FLOAT_MODE_P (<MODE>mode)
4358 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4359 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4360 [(set_attr "type" "sseicvt")
4361 (set_attr "prefix" "maybe_vex")
4362 (set_attr "mode" "<MODE>")
4363 (set_attr "athlon_decode" "double,vector")
4364 (set_attr "amdfam10_decode" "double,double")
4365 (set_attr "bdver1_decode" "double,double")])
4366
4367 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4368 (define_peephole2
4369 [(set (match_operand:MODEF 0 "register_operand" "")
4370 (match_operand:MODEF 1 "memory_operand" ""))
4371 (set (match_operand:SWI48x 2 "register_operand" "")
4372 (fix:SWI48x (match_dup 0)))]
4373 "TARGET_SHORTEN_X87_SSE
4374 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4375 && peep2_reg_dead_p (2, operands[0])"
4376 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4377
4378 ;; Avoid vector decoded forms of the instruction.
4379 (define_peephole2
4380 [(match_scratch:DF 2 "x")
4381 (set (match_operand:SWI48x 0 "register_operand" "")
4382 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4383 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4384 [(set (match_dup 2) (match_dup 1))
4385 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4386
4387 (define_peephole2
4388 [(match_scratch:SF 2 "x")
4389 (set (match_operand:SWI48x 0 "register_operand" "")
4390 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4391 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4392 [(set (match_dup 2) (match_dup 1))
4393 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4394
4395 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4396 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4397 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4399 && TARGET_FISTTP
4400 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4401 && (TARGET_64BIT || <MODE>mode != DImode))
4402 && TARGET_SSE_MATH)
4403 && can_create_pseudo_p ()"
4404 "#"
4405 "&& 1"
4406 [(const_int 0)]
4407 {
4408 if (memory_operand (operands[0], VOIDmode))
4409 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4410 else
4411 {
4412 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4413 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4414 operands[1],
4415 operands[2]));
4416 }
4417 DONE;
4418 }
4419 [(set_attr "type" "fisttp")
4420 (set_attr "mode" "<MODE>")])
4421
4422 (define_insn "fix_trunc<mode>_i387_fisttp"
4423 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4424 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4425 (clobber (match_scratch:XF 2 "=&1f"))]
4426 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4427 && TARGET_FISTTP
4428 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4429 && (TARGET_64BIT || <MODE>mode != DImode))
4430 && TARGET_SSE_MATH)"
4431 "* return output_fix_trunc (insn, operands, true);"
4432 [(set_attr "type" "fisttp")
4433 (set_attr "mode" "<MODE>")])
4434
4435 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4436 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4437 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4438 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4439 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4441 && TARGET_FISTTP
4442 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && (TARGET_64BIT || <MODE>mode != DImode))
4444 && TARGET_SSE_MATH)"
4445 "#"
4446 [(set_attr "type" "fisttp")
4447 (set_attr "mode" "<MODE>")])
4448
4449 (define_split
4450 [(set (match_operand:SWI248x 0 "register_operand" "")
4451 (fix:SWI248x (match_operand 1 "register_operand" "")))
4452 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4453 (clobber (match_scratch 3 ""))]
4454 "reload_completed"
4455 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4456 (clobber (match_dup 3))])
4457 (set (match_dup 0) (match_dup 2))])
4458
4459 (define_split
4460 [(set (match_operand:SWI248x 0 "memory_operand" "")
4461 (fix:SWI248x (match_operand 1 "register_operand" "")))
4462 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4463 (clobber (match_scratch 3 ""))]
4464 "reload_completed"
4465 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4466 (clobber (match_dup 3))])])
4467
4468 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4469 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4470 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4471 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4472 ;; function in i386.c.
4473 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4474 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4475 (fix:SWI248x (match_operand 1 "register_operand" "")))
4476 (clobber (reg:CC FLAGS_REG))]
4477 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4478 && !TARGET_FISTTP
4479 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4480 && (TARGET_64BIT || <MODE>mode != DImode))
4481 && can_create_pseudo_p ()"
4482 "#"
4483 "&& 1"
4484 [(const_int 0)]
4485 {
4486 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4487
4488 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4489 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4490 if (memory_operand (operands[0], VOIDmode))
4491 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4492 operands[2], operands[3]));
4493 else
4494 {
4495 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4496 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4497 operands[2], operands[3],
4498 operands[4]));
4499 }
4500 DONE;
4501 }
4502 [(set_attr "type" "fistp")
4503 (set_attr "i387_cw" "trunc")
4504 (set_attr "mode" "<MODE>")])
4505
4506 (define_insn "fix_truncdi_i387"
4507 [(set (match_operand:DI 0 "memory_operand" "=m")
4508 (fix:DI (match_operand 1 "register_operand" "f")))
4509 (use (match_operand:HI 2 "memory_operand" "m"))
4510 (use (match_operand:HI 3 "memory_operand" "m"))
4511 (clobber (match_scratch:XF 4 "=&1f"))]
4512 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4513 && !TARGET_FISTTP
4514 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4515 "* return output_fix_trunc (insn, operands, false);"
4516 [(set_attr "type" "fistp")
4517 (set_attr "i387_cw" "trunc")
4518 (set_attr "mode" "DI")])
4519
4520 (define_insn "fix_truncdi_i387_with_temp"
4521 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4522 (fix:DI (match_operand 1 "register_operand" "f,f")))
4523 (use (match_operand:HI 2 "memory_operand" "m,m"))
4524 (use (match_operand:HI 3 "memory_operand" "m,m"))
4525 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4526 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && !TARGET_FISTTP
4529 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4530 "#"
4531 [(set_attr "type" "fistp")
4532 (set_attr "i387_cw" "trunc")
4533 (set_attr "mode" "DI")])
4534
4535 (define_split
4536 [(set (match_operand:DI 0 "register_operand" "")
4537 (fix:DI (match_operand 1 "register_operand" "")))
4538 (use (match_operand:HI 2 "memory_operand" ""))
4539 (use (match_operand:HI 3 "memory_operand" ""))
4540 (clobber (match_operand:DI 4 "memory_operand" ""))
4541 (clobber (match_scratch 5 ""))]
4542 "reload_completed"
4543 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4544 (use (match_dup 2))
4545 (use (match_dup 3))
4546 (clobber (match_dup 5))])
4547 (set (match_dup 0) (match_dup 4))])
4548
4549 (define_split
4550 [(set (match_operand:DI 0 "memory_operand" "")
4551 (fix:DI (match_operand 1 "register_operand" "")))
4552 (use (match_operand:HI 2 "memory_operand" ""))
4553 (use (match_operand:HI 3 "memory_operand" ""))
4554 (clobber (match_operand:DI 4 "memory_operand" ""))
4555 (clobber (match_scratch 5 ""))]
4556 "reload_completed"
4557 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4558 (use (match_dup 2))
4559 (use (match_dup 3))
4560 (clobber (match_dup 5))])])
4561
4562 (define_insn "fix_trunc<mode>_i387"
4563 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4564 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4565 (use (match_operand:HI 2 "memory_operand" "m"))
4566 (use (match_operand:HI 3 "memory_operand" "m"))]
4567 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !TARGET_FISTTP
4569 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4570 "* return output_fix_trunc (insn, operands, false);"
4571 [(set_attr "type" "fistp")
4572 (set_attr "i387_cw" "trunc")
4573 (set_attr "mode" "<MODE>")])
4574
4575 (define_insn "fix_trunc<mode>_i387_with_temp"
4576 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4577 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4578 (use (match_operand:HI 2 "memory_operand" "m,m"))
4579 (use (match_operand:HI 3 "memory_operand" "m,m"))
4580 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4581 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4582 && !TARGET_FISTTP
4583 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4584 "#"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "<MODE>")])
4588
4589 (define_split
4590 [(set (match_operand:SWI24 0 "register_operand" "")
4591 (fix:SWI24 (match_operand 1 "register_operand" "")))
4592 (use (match_operand:HI 2 "memory_operand" ""))
4593 (use (match_operand:HI 3 "memory_operand" ""))
4594 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4595 "reload_completed"
4596 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4597 (use (match_dup 2))
4598 (use (match_dup 3))])
4599 (set (match_dup 0) (match_dup 4))])
4600
4601 (define_split
4602 [(set (match_operand:SWI24 0 "memory_operand" "")
4603 (fix:SWI24 (match_operand 1 "register_operand" "")))
4604 (use (match_operand:HI 2 "memory_operand" ""))
4605 (use (match_operand:HI 3 "memory_operand" ""))
4606 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4607 "reload_completed"
4608 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4609 (use (match_dup 2))
4610 (use (match_dup 3))])])
4611
4612 (define_insn "x86_fnstcw_1"
4613 [(set (match_operand:HI 0 "memory_operand" "=m")
4614 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4615 "TARGET_80387"
4616 "fnstcw\t%0"
4617 [(set (attr "length")
4618 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4619 (set_attr "mode" "HI")
4620 (set_attr "unit" "i387")
4621 (set_attr "bdver1_decode" "vector")])
4622
4623 (define_insn "x86_fldcw_1"
4624 [(set (reg:HI FPCR_REG)
4625 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4626 "TARGET_80387"
4627 "fldcw\t%0"
4628 [(set (attr "length")
4629 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4630 (set_attr "mode" "HI")
4631 (set_attr "unit" "i387")
4632 (set_attr "athlon_decode" "vector")
4633 (set_attr "amdfam10_decode" "vector")
4634 (set_attr "bdver1_decode" "vector")])
4635 \f
4636 ;; Conversion between fixed point and floating point.
4637
4638 ;; Even though we only accept memory inputs, the backend _really_
4639 ;; wants to be able to do this between registers.
4640
4641 (define_expand "floathi<mode>2"
4642 [(set (match_operand:X87MODEF 0 "register_operand" "")
4643 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4644 "TARGET_80387
4645 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4646 || TARGET_MIX_SSE_I387)")
4647
4648 ;; Pre-reload splitter to add memory clobber to the pattern.
4649 (define_insn_and_split "*floathi<mode>2_1"
4650 [(set (match_operand:X87MODEF 0 "register_operand" "")
4651 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4652 "TARGET_80387
4653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4654 || TARGET_MIX_SSE_I387)
4655 && can_create_pseudo_p ()"
4656 "#"
4657 "&& 1"
4658 [(parallel [(set (match_dup 0)
4659 (float:X87MODEF (match_dup 1)))
4660 (clobber (match_dup 2))])]
4661 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4662
4663 (define_insn "*floathi<mode>2_i387_with_temp"
4664 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4665 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4666 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4667 "TARGET_80387
4668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669 || TARGET_MIX_SSE_I387)"
4670 "#"
4671 [(set_attr "type" "fmov,multi")
4672 (set_attr "mode" "<MODE>")
4673 (set_attr "unit" "*,i387")
4674 (set_attr "fp_int_src" "true")])
4675
4676 (define_insn "*floathi<mode>2_i387"
4677 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4678 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4679 "TARGET_80387
4680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4681 || TARGET_MIX_SSE_I387)"
4682 "fild%Z1\t%1"
4683 [(set_attr "type" "fmov")
4684 (set_attr "mode" "<MODE>")
4685 (set_attr "fp_int_src" "true")])
4686
4687 (define_split
4688 [(set (match_operand:X87MODEF 0 "register_operand" "")
4689 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4690 (clobber (match_operand:HI 2 "memory_operand" ""))]
4691 "TARGET_80387
4692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4693 || TARGET_MIX_SSE_I387)
4694 && reload_completed"
4695 [(set (match_dup 2) (match_dup 1))
4696 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4697
4698 (define_split
4699 [(set (match_operand:X87MODEF 0 "register_operand" "")
4700 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4701 (clobber (match_operand:HI 2 "memory_operand" ""))]
4702 "TARGET_80387
4703 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4704 || TARGET_MIX_SSE_I387)
4705 && reload_completed"
4706 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4707
4708 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4709 [(set (match_operand:X87MODEF 0 "register_operand" "")
4710 (float:X87MODEF
4711 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4712 "TARGET_80387
4713 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4714 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4715 {
4716 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4717 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4718 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4719 {
4720 rtx reg = gen_reg_rtx (XFmode);
4721 rtx (*insn)(rtx, rtx);
4722
4723 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4724
4725 if (<X87MODEF:MODE>mode == SFmode)
4726 insn = gen_truncxfsf2;
4727 else if (<X87MODEF:MODE>mode == DFmode)
4728 insn = gen_truncxfdf2;
4729 else
4730 gcc_unreachable ();
4731
4732 emit_insn (insn (operands[0], reg));
4733 DONE;
4734 }
4735 })
4736
4737 ;; Pre-reload splitter to add memory clobber to the pattern.
4738 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4739 [(set (match_operand:X87MODEF 0 "register_operand" "")
4740 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4741 "((TARGET_80387
4742 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4743 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4744 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4745 || TARGET_MIX_SSE_I387))
4746 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4747 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4748 && ((<SWI48x:MODE>mode == SImode
4749 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4750 && optimize_function_for_speed_p (cfun)
4751 && flag_trapping_math)
4752 || !(TARGET_INTER_UNIT_CONVERSIONS
4753 || optimize_function_for_size_p (cfun)))))
4754 && can_create_pseudo_p ()"
4755 "#"
4756 "&& 1"
4757 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4758 (clobber (match_dup 2))])]
4759 {
4760 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4761
4762 /* Avoid store forwarding (partial memory) stall penalty
4763 by passing DImode value through XMM registers. */
4764 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4765 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4766 && optimize_function_for_speed_p (cfun))
4767 {
4768 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4769 operands[1],
4770 operands[2]));
4771 DONE;
4772 }
4773 })
4774
4775 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4776 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4777 (float:MODEF
4778 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4779 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4780 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4781 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4782 "#"
4783 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4784 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4785 (set_attr "unit" "*,i387,*,*,*")
4786 (set_attr "athlon_decode" "*,*,double,direct,double")
4787 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4788 (set_attr "bdver1_decode" "*,*,double,direct,double")
4789 (set_attr "fp_int_src" "true")])
4790
4791 (define_insn "*floatsi<mode>2_vector_mixed"
4792 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4793 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4794 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4795 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4796 "@
4797 fild%Z1\t%1
4798 #"
4799 [(set_attr "type" "fmov,sseicvt")
4800 (set_attr "mode" "<MODE>,<ssevecmode>")
4801 (set_attr "unit" "i387,*")
4802 (set_attr "athlon_decode" "*,direct")
4803 (set_attr "amdfam10_decode" "*,double")
4804 (set_attr "bdver1_decode" "*,direct")
4805 (set_attr "fp_int_src" "true")])
4806
4807 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4808 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4809 (float:MODEF
4810 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4811 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4812 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4813 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4814 "#"
4815 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4816 (set_attr "mode" "<MODEF:MODE>")
4817 (set_attr "unit" "*,i387,*,*")
4818 (set_attr "athlon_decode" "*,*,double,direct")
4819 (set_attr "amdfam10_decode" "*,*,vector,double")
4820 (set_attr "bdver1_decode" "*,*,double,direct")
4821 (set_attr "fp_int_src" "true")])
4822
4823 (define_split
4824 [(set (match_operand:MODEF 0 "register_operand" "")
4825 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4826 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4827 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4829 && TARGET_INTER_UNIT_CONVERSIONS
4830 && reload_completed
4831 && (SSE_REG_P (operands[0])
4832 || (GET_CODE (operands[0]) == SUBREG
4833 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4834 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4835
4836 (define_split
4837 [(set (match_operand:MODEF 0 "register_operand" "")
4838 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4839 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4840 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4841 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4842 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4843 && reload_completed
4844 && (SSE_REG_P (operands[0])
4845 || (GET_CODE (operands[0]) == SUBREG
4846 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4847 [(set (match_dup 2) (match_dup 1))
4848 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4849
4850 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4851 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4852 (float:MODEF
4853 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4854 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4855 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4856 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4857 "@
4858 fild%Z1\t%1
4859 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4860 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4861 [(set_attr "type" "fmov,sseicvt,sseicvt")
4862 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4863 (set_attr "mode" "<MODEF:MODE>")
4864 (set (attr "prefix_rex")
4865 (if_then_else
4866 (and (eq_attr "prefix" "maybe_vex")
4867 (match_test "<SWI48x:MODE>mode == DImode"))
4868 (const_string "1")
4869 (const_string "*")))
4870 (set_attr "unit" "i387,*,*")
4871 (set_attr "athlon_decode" "*,double,direct")
4872 (set_attr "amdfam10_decode" "*,vector,double")
4873 (set_attr "bdver1_decode" "*,double,direct")
4874 (set_attr "fp_int_src" "true")])
4875
4876 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4877 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4878 (float:MODEF
4879 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4880 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4881 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4882 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4883 "@
4884 fild%Z1\t%1
4885 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4886 [(set_attr "type" "fmov,sseicvt")
4887 (set_attr "prefix" "orig,maybe_vex")
4888 (set_attr "mode" "<MODEF:MODE>")
4889 (set (attr "prefix_rex")
4890 (if_then_else
4891 (and (eq_attr "prefix" "maybe_vex")
4892 (match_test "<SWI48x:MODE>mode == DImode"))
4893 (const_string "1")
4894 (const_string "*")))
4895 (set_attr "athlon_decode" "*,direct")
4896 (set_attr "amdfam10_decode" "*,double")
4897 (set_attr "bdver1_decode" "*,direct")
4898 (set_attr "fp_int_src" "true")])
4899
4900 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4901 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4902 (float:MODEF
4903 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4904 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4905 "TARGET_SSE2 && TARGET_SSE_MATH
4906 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4907 "#"
4908 [(set_attr "type" "sseicvt")
4909 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4910 (set_attr "athlon_decode" "double,direct,double")
4911 (set_attr "amdfam10_decode" "vector,double,double")
4912 (set_attr "bdver1_decode" "double,direct,double")
4913 (set_attr "fp_int_src" "true")])
4914
4915 (define_insn "*floatsi<mode>2_vector_sse"
4916 [(set (match_operand:MODEF 0 "register_operand" "=x")
4917 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4918 "TARGET_SSE2 && TARGET_SSE_MATH
4919 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4920 "#"
4921 [(set_attr "type" "sseicvt")
4922 (set_attr "mode" "<MODE>")
4923 (set_attr "athlon_decode" "direct")
4924 (set_attr "amdfam10_decode" "double")
4925 (set_attr "bdver1_decode" "direct")
4926 (set_attr "fp_int_src" "true")])
4927
4928 (define_split
4929 [(set (match_operand:MODEF 0 "register_operand" "")
4930 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4931 (clobber (match_operand:SI 2 "memory_operand" ""))]
4932 "TARGET_SSE2 && TARGET_SSE_MATH
4933 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4934 && reload_completed
4935 && (SSE_REG_P (operands[0])
4936 || (GET_CODE (operands[0]) == SUBREG
4937 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4938 [(const_int 0)]
4939 {
4940 rtx op1 = operands[1];
4941
4942 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4943 <MODE>mode, 0);
4944 if (GET_CODE (op1) == SUBREG)
4945 op1 = SUBREG_REG (op1);
4946
4947 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4948 {
4949 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4950 emit_insn (gen_sse2_loadld (operands[4],
4951 CONST0_RTX (V4SImode), operands[1]));
4952 }
4953 /* We can ignore possible trapping value in the
4954 high part of SSE register for non-trapping math. */
4955 else if (SSE_REG_P (op1) && !flag_trapping_math)
4956 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4957 else
4958 {
4959 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4960 emit_move_insn (operands[2], operands[1]);
4961 emit_insn (gen_sse2_loadld (operands[4],
4962 CONST0_RTX (V4SImode), operands[2]));
4963 }
4964 if (<ssevecmode>mode == V4SFmode)
4965 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4966 else
4967 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4968 DONE;
4969 })
4970
4971 (define_split
4972 [(set (match_operand:MODEF 0 "register_operand" "")
4973 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4974 (clobber (match_operand:SI 2 "memory_operand" ""))]
4975 "TARGET_SSE2 && TARGET_SSE_MATH
4976 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4977 && reload_completed
4978 && (SSE_REG_P (operands[0])
4979 || (GET_CODE (operands[0]) == SUBREG
4980 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4981 [(const_int 0)]
4982 {
4983 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4984 <MODE>mode, 0);
4985 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4986
4987 emit_insn (gen_sse2_loadld (operands[4],
4988 CONST0_RTX (V4SImode), operands[1]));
4989 if (<ssevecmode>mode == V4SFmode)
4990 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4991 else
4992 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4993 DONE;
4994 })
4995
4996 (define_split
4997 [(set (match_operand:MODEF 0 "register_operand" "")
4998 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
4999 "TARGET_SSE2 && TARGET_SSE_MATH
5000 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5001 && reload_completed
5002 && (SSE_REG_P (operands[0])
5003 || (GET_CODE (operands[0]) == SUBREG
5004 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5005 [(const_int 0)]
5006 {
5007 rtx op1 = operands[1];
5008
5009 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5010 <MODE>mode, 0);
5011 if (GET_CODE (op1) == SUBREG)
5012 op1 = SUBREG_REG (op1);
5013
5014 if (GENERAL_REG_P (op1))
5015 {
5016 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5017 if (TARGET_INTER_UNIT_MOVES)
5018 emit_insn (gen_sse2_loadld (operands[4],
5019 CONST0_RTX (V4SImode), operands[1]));
5020 else
5021 {
5022 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5023 operands[1]);
5024 emit_insn (gen_sse2_loadld (operands[4],
5025 CONST0_RTX (V4SImode), operands[5]));
5026 ix86_free_from_memory (GET_MODE (operands[1]));
5027 }
5028 }
5029 /* We can ignore possible trapping value in the
5030 high part of SSE register for non-trapping math. */
5031 else if (SSE_REG_P (op1) && !flag_trapping_math)
5032 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5033 else
5034 gcc_unreachable ();
5035 if (<ssevecmode>mode == V4SFmode)
5036 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5037 else
5038 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5039 DONE;
5040 })
5041
5042 (define_split
5043 [(set (match_operand:MODEF 0 "register_operand" "")
5044 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5045 "TARGET_SSE2 && TARGET_SSE_MATH
5046 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047 && reload_completed
5048 && (SSE_REG_P (operands[0])
5049 || (GET_CODE (operands[0]) == SUBREG
5050 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5051 [(const_int 0)]
5052 {
5053 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5054 <MODE>mode, 0);
5055 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5056
5057 emit_insn (gen_sse2_loadld (operands[4],
5058 CONST0_RTX (V4SImode), operands[1]));
5059 if (<ssevecmode>mode == V4SFmode)
5060 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5061 else
5062 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5063 DONE;
5064 })
5065
5066 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5067 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5068 (float:MODEF
5069 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5070 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5071 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5072 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5073 "#"
5074 [(set_attr "type" "sseicvt")
5075 (set_attr "mode" "<MODEF:MODE>")
5076 (set_attr "athlon_decode" "double,direct")
5077 (set_attr "amdfam10_decode" "vector,double")
5078 (set_attr "bdver1_decode" "double,direct")
5079 (set_attr "fp_int_src" "true")])
5080
5081 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5082 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5083 (float:MODEF
5084 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5085 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5086 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5087 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5088 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5089 [(set_attr "type" "sseicvt")
5090 (set_attr "prefix" "maybe_vex")
5091 (set_attr "mode" "<MODEF:MODE>")
5092 (set (attr "prefix_rex")
5093 (if_then_else
5094 (and (eq_attr "prefix" "maybe_vex")
5095 (match_test "<SWI48x:MODE>mode == DImode"))
5096 (const_string "1")
5097 (const_string "*")))
5098 (set_attr "athlon_decode" "double,direct")
5099 (set_attr "amdfam10_decode" "vector,double")
5100 (set_attr "bdver1_decode" "double,direct")
5101 (set_attr "fp_int_src" "true")])
5102
5103 (define_split
5104 [(set (match_operand:MODEF 0 "register_operand" "")
5105 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5106 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5107 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5108 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5109 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5110 && reload_completed
5111 && (SSE_REG_P (operands[0])
5112 || (GET_CODE (operands[0]) == SUBREG
5113 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5114 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5115
5116 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5117 [(set (match_operand:MODEF 0 "register_operand" "=x")
5118 (float:MODEF
5119 (match_operand:SWI48x 1 "memory_operand" "m")))]
5120 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5121 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5122 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5123 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5124 [(set_attr "type" "sseicvt")
5125 (set_attr "prefix" "maybe_vex")
5126 (set_attr "mode" "<MODEF:MODE>")
5127 (set (attr "prefix_rex")
5128 (if_then_else
5129 (and (eq_attr "prefix" "maybe_vex")
5130 (match_test "<SWI48x:MODE>mode == DImode"))
5131 (const_string "1")
5132 (const_string "*")))
5133 (set_attr "athlon_decode" "direct")
5134 (set_attr "amdfam10_decode" "double")
5135 (set_attr "bdver1_decode" "direct")
5136 (set_attr "fp_int_src" "true")])
5137
5138 (define_split
5139 [(set (match_operand:MODEF 0 "register_operand" "")
5140 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5141 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5142 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5143 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5144 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5145 && reload_completed
5146 && (SSE_REG_P (operands[0])
5147 || (GET_CODE (operands[0]) == SUBREG
5148 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5149 [(set (match_dup 2) (match_dup 1))
5150 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5151
5152 (define_split
5153 [(set (match_operand:MODEF 0 "register_operand" "")
5154 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5155 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5156 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5157 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5158 && reload_completed
5159 && (SSE_REG_P (operands[0])
5160 || (GET_CODE (operands[0]) == SUBREG
5161 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5162 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5163
5164 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5165 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5166 (float:X87MODEF
5167 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5168 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5169 "TARGET_80387
5170 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5171 "@
5172 fild%Z1\t%1
5173 #"
5174 [(set_attr "type" "fmov,multi")
5175 (set_attr "mode" "<X87MODEF:MODE>")
5176 (set_attr "unit" "*,i387")
5177 (set_attr "fp_int_src" "true")])
5178
5179 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5180 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5181 (float:X87MODEF
5182 (match_operand:SWI48x 1 "memory_operand" "m")))]
5183 "TARGET_80387
5184 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5185 "fild%Z1\t%1"
5186 [(set_attr "type" "fmov")
5187 (set_attr "mode" "<X87MODEF:MODE>")
5188 (set_attr "fp_int_src" "true")])
5189
5190 (define_split
5191 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5192 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5193 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5194 "TARGET_80387
5195 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5196 && reload_completed"
5197 [(set (match_dup 2) (match_dup 1))
5198 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5199
5200 (define_split
5201 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5202 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5203 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5204 "TARGET_80387
5205 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5206 && reload_completed"
5207 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5208
5209 ;; Avoid store forwarding (partial memory) stall penalty
5210 ;; by passing DImode value through XMM registers. */
5211
5212 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5213 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5214 (float:X87MODEF
5215 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5216 (clobber (match_scratch:V4SI 3 "=X,x"))
5217 (clobber (match_scratch:V4SI 4 "=X,x"))
5218 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5219 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5220 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5221 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5222 "#"
5223 [(set_attr "type" "multi")
5224 (set_attr "mode" "<X87MODEF:MODE>")
5225 (set_attr "unit" "i387")
5226 (set_attr "fp_int_src" "true")])
5227
5228 (define_split
5229 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5230 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5231 (clobber (match_scratch:V4SI 3 ""))
5232 (clobber (match_scratch:V4SI 4 ""))
5233 (clobber (match_operand:DI 2 "memory_operand" ""))]
5234 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5235 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5236 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5237 && reload_completed"
5238 [(set (match_dup 2) (match_dup 3))
5239 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5240 {
5241 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5242 Assemble the 64-bit DImode value in an xmm register. */
5243 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5244 gen_rtx_SUBREG (SImode, operands[1], 0)));
5245 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5246 gen_rtx_SUBREG (SImode, operands[1], 4)));
5247 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5248 operands[4]));
5249
5250 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5251 })
5252
5253 (define_split
5254 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5255 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5256 (clobber (match_scratch:V4SI 3 ""))
5257 (clobber (match_scratch:V4SI 4 ""))
5258 (clobber (match_operand:DI 2 "memory_operand" ""))]
5259 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5260 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5261 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5262 && reload_completed"
5263 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5264
5265 ;; Avoid store forwarding (partial memory) stall penalty by extending
5266 ;; SImode value to DImode through XMM register instead of pushing two
5267 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5268 ;; targets benefit from this optimization. Also note that fild
5269 ;; loads from memory only.
5270
5271 (define_insn "*floatunssi<mode>2_1"
5272 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5273 (unsigned_float:X87MODEF
5274 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5275 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5276 (clobber (match_scratch:SI 3 "=X,x"))]
5277 "!TARGET_64BIT
5278 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5279 && TARGET_SSE"
5280 "#"
5281 [(set_attr "type" "multi")
5282 (set_attr "mode" "<MODE>")])
5283
5284 (define_split
5285 [(set (match_operand:X87MODEF 0 "register_operand" "")
5286 (unsigned_float:X87MODEF
5287 (match_operand:SI 1 "register_operand" "")))
5288 (clobber (match_operand:DI 2 "memory_operand" ""))
5289 (clobber (match_scratch:SI 3 ""))]
5290 "!TARGET_64BIT
5291 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5292 && TARGET_SSE
5293 && reload_completed"
5294 [(set (match_dup 2) (match_dup 1))
5295 (set (match_dup 0)
5296 (float:X87MODEF (match_dup 2)))]
5297 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5298
5299 (define_split
5300 [(set (match_operand:X87MODEF 0 "register_operand" "")
5301 (unsigned_float:X87MODEF
5302 (match_operand:SI 1 "memory_operand" "")))
5303 (clobber (match_operand:DI 2 "memory_operand" ""))
5304 (clobber (match_scratch:SI 3 ""))]
5305 "!TARGET_64BIT
5306 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307 && TARGET_SSE
5308 && reload_completed"
5309 [(set (match_dup 2) (match_dup 3))
5310 (set (match_dup 0)
5311 (float:X87MODEF (match_dup 2)))]
5312 {
5313 emit_move_insn (operands[3], operands[1]);
5314 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5315 })
5316
5317 (define_expand "floatunssi<mode>2"
5318 [(parallel
5319 [(set (match_operand:X87MODEF 0 "register_operand" "")
5320 (unsigned_float:X87MODEF
5321 (match_operand:SI 1 "nonimmediate_operand" "")))
5322 (clobber (match_dup 2))
5323 (clobber (match_scratch:SI 3 ""))])]
5324 "!TARGET_64BIT
5325 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5326 && TARGET_SSE)
5327 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5328 {
5329 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5330 {
5331 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5332 DONE;
5333 }
5334 else
5335 {
5336 enum ix86_stack_slot slot = (virtuals_instantiated
5337 ? SLOT_TEMP
5338 : SLOT_VIRTUAL);
5339 operands[2] = assign_386_stack_local (DImode, slot);
5340 }
5341 })
5342
5343 (define_expand "floatunsdisf2"
5344 [(use (match_operand:SF 0 "register_operand" ""))
5345 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5346 "TARGET_64BIT && TARGET_SSE_MATH"
5347 "x86_emit_floatuns (operands); DONE;")
5348
5349 (define_expand "floatunsdidf2"
5350 [(use (match_operand:DF 0 "register_operand" ""))
5351 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5352 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5353 && TARGET_SSE2 && TARGET_SSE_MATH"
5354 {
5355 if (TARGET_64BIT)
5356 x86_emit_floatuns (operands);
5357 else
5358 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5359 DONE;
5360 })
5361 \f
5362 ;; Add instructions
5363
5364 (define_expand "add<mode>3"
5365 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5366 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5367 (match_operand:SDWIM 2 "<general_operand>" "")))]
5368 ""
5369 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5370
5371 (define_insn_and_split "*add<dwi>3_doubleword"
5372 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5373 (plus:<DWI>
5374 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5375 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5376 (clobber (reg:CC FLAGS_REG))]
5377 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5378 "#"
5379 "reload_completed"
5380 [(parallel [(set (reg:CC FLAGS_REG)
5381 (unspec:CC [(match_dup 1) (match_dup 2)]
5382 UNSPEC_ADD_CARRY))
5383 (set (match_dup 0)
5384 (plus:DWIH (match_dup 1) (match_dup 2)))])
5385 (parallel [(set (match_dup 3)
5386 (plus:DWIH
5387 (match_dup 4)
5388 (plus:DWIH
5389 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5390 (match_dup 5))))
5391 (clobber (reg:CC FLAGS_REG))])]
5392 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5393
5394 (define_insn "*add<mode>3_cc"
5395 [(set (reg:CC FLAGS_REG)
5396 (unspec:CC
5397 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5398 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5399 UNSPEC_ADD_CARRY))
5400 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5401 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5402 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5403 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5404 [(set_attr "type" "alu")
5405 (set_attr "mode" "<MODE>")])
5406
5407 (define_insn "addqi3_cc"
5408 [(set (reg:CC FLAGS_REG)
5409 (unspec:CC
5410 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5411 (match_operand:QI 2 "general_operand" "qn,qm")]
5412 UNSPEC_ADD_CARRY))
5413 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5414 (plus:QI (match_dup 1) (match_dup 2)))]
5415 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5416 "add{b}\t{%2, %0|%0, %2}"
5417 [(set_attr "type" "alu")
5418 (set_attr "mode" "QI")])
5419
5420 (define_insn_and_split "*lea_1"
5421 [(set (match_operand:SI 0 "register_operand" "=r")
5422 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5423 "TARGET_64BIT"
5424 "lea{l}\t{%a1, %0|%0, %a1}"
5425 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5426 [(const_int 0)]
5427 {
5428 ix86_split_lea_for_addr (operands, SImode);
5429 DONE;
5430 }
5431 [(set_attr "type" "lea")
5432 (set_attr "mode" "SI")])
5433
5434 (define_insn_and_split "*lea<mode>_2"
5435 [(set (match_operand:SWI48 0 "register_operand" "=r")
5436 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5437 ""
5438 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5439 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5440 [(const_int 0)]
5441 {
5442 ix86_split_lea_for_addr (operands, <MODE>mode);
5443 DONE;
5444 }
5445 [(set_attr "type" "lea")
5446 (set_attr "mode" "<MODE>")])
5447
5448 (define_insn "*lea_3_zext"
5449 [(set (match_operand:DI 0 "register_operand" "=r")
5450 (zero_extend:DI
5451 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5452 "TARGET_64BIT"
5453 "lea{l}\t{%a1, %k0|%k0, %a1}"
5454 [(set_attr "type" "lea")
5455 (set_attr "mode" "SI")])
5456
5457 (define_insn "*lea_4_zext"
5458 [(set (match_operand:DI 0 "register_operand" "=r")
5459 (zero_extend:DI
5460 (match_operand:SI 1 "lea_address_operand" "j")))]
5461 "TARGET_64BIT"
5462 "lea{l}\t{%a1, %k0|%k0, %a1}"
5463 [(set_attr "type" "lea")
5464 (set_attr "mode" "SI")])
5465
5466 (define_insn "*lea_5_zext"
5467 [(set (match_operand:DI 0 "register_operand" "=r")
5468 (and:DI
5469 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5470 (match_operand:DI 2 "const_32bit_mask" "n")))]
5471 "TARGET_64BIT"
5472 "lea{l}\t{%a1, %k0|%k0, %a1}"
5473 [(set_attr "type" "lea")
5474 (set_attr "mode" "SI")])
5475
5476 (define_insn "*lea_6_zext"
5477 [(set (match_operand:DI 0 "register_operand" "=r")
5478 (and:DI
5479 (match_operand:DI 1 "lea_address_operand" "p")
5480 (match_operand:DI 2 "const_32bit_mask" "n")))]
5481 "TARGET_64BIT"
5482 "lea{l}\t{%a1, %k0|%k0, %a1}"
5483 [(set_attr "type" "lea")
5484 (set_attr "mode" "SI")])
5485
5486 (define_insn "*add<mode>_1"
5487 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5488 (plus:SWI48
5489 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5490 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5491 (clobber (reg:CC FLAGS_REG))]
5492 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5493 {
5494 switch (get_attr_type (insn))
5495 {
5496 case TYPE_LEA:
5497 return "#";
5498
5499 case TYPE_INCDEC:
5500 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5501 if (operands[2] == const1_rtx)
5502 return "inc{<imodesuffix>}\t%0";
5503 else
5504 {
5505 gcc_assert (operands[2] == constm1_rtx);
5506 return "dec{<imodesuffix>}\t%0";
5507 }
5508
5509 default:
5510 /* For most processors, ADD is faster than LEA. This alternative
5511 was added to use ADD as much as possible. */
5512 if (which_alternative == 2)
5513 {
5514 rtx tmp;
5515 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5516 }
5517
5518 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5519 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5520 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5521
5522 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5523 }
5524 }
5525 [(set (attr "type")
5526 (cond [(eq_attr "alternative" "3")
5527 (const_string "lea")
5528 (match_operand:SWI48 2 "incdec_operand" "")
5529 (const_string "incdec")
5530 ]
5531 (const_string "alu")))
5532 (set (attr "length_immediate")
5533 (if_then_else
5534 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5535 (const_string "1")
5536 (const_string "*")))
5537 (set_attr "mode" "<MODE>")])
5538
5539 ;; It may seem that nonimmediate operand is proper one for operand 1.
5540 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5541 ;; we take care in ix86_binary_operator_ok to not allow two memory
5542 ;; operands so proper swapping will be done in reload. This allow
5543 ;; patterns constructed from addsi_1 to match.
5544
5545 (define_insn "addsi_1_zext"
5546 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5547 (zero_extend:DI
5548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5549 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5550 (clobber (reg:CC FLAGS_REG))]
5551 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5552 {
5553 switch (get_attr_type (insn))
5554 {
5555 case TYPE_LEA:
5556 return "#";
5557
5558 case TYPE_INCDEC:
5559 if (operands[2] == const1_rtx)
5560 return "inc{l}\t%k0";
5561 else
5562 {
5563 gcc_assert (operands[2] == constm1_rtx);
5564 return "dec{l}\t%k0";
5565 }
5566
5567 default:
5568 /* For most processors, ADD is faster than LEA. This alternative
5569 was added to use ADD as much as possible. */
5570 if (which_alternative == 1)
5571 {
5572 rtx tmp;
5573 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5574 }
5575
5576 if (x86_maybe_negate_const_int (&operands[2], SImode))
5577 return "sub{l}\t{%2, %k0|%k0, %2}";
5578
5579 return "add{l}\t{%2, %k0|%k0, %2}";
5580 }
5581 }
5582 [(set (attr "type")
5583 (cond [(eq_attr "alternative" "2")
5584 (const_string "lea")
5585 (match_operand:SI 2 "incdec_operand" "")
5586 (const_string "incdec")
5587 ]
5588 (const_string "alu")))
5589 (set (attr "length_immediate")
5590 (if_then_else
5591 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5592 (const_string "1")
5593 (const_string "*")))
5594 (set_attr "mode" "SI")])
5595
5596 (define_insn "*addhi_1"
5597 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5598 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5599 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5600 (clobber (reg:CC FLAGS_REG))]
5601 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5602 {
5603 switch (get_attr_type (insn))
5604 {
5605 case TYPE_LEA:
5606 return "#";
5607
5608 case TYPE_INCDEC:
5609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 if (operands[2] == const1_rtx)
5611 return "inc{w}\t%0";
5612 else
5613 {
5614 gcc_assert (operands[2] == constm1_rtx);
5615 return "dec{w}\t%0";
5616 }
5617
5618 default:
5619 /* For most processors, ADD is faster than LEA. This alternative
5620 was added to use ADD as much as possible. */
5621 if (which_alternative == 2)
5622 {
5623 rtx tmp;
5624 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5625 }
5626
5627 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5628 if (x86_maybe_negate_const_int (&operands[2], HImode))
5629 return "sub{w}\t{%2, %0|%0, %2}";
5630
5631 return "add{w}\t{%2, %0|%0, %2}";
5632 }
5633 }
5634 [(set (attr "type")
5635 (cond [(eq_attr "alternative" "3")
5636 (const_string "lea")
5637 (match_operand:HI 2 "incdec_operand" "")
5638 (const_string "incdec")
5639 ]
5640 (const_string "alu")))
5641 (set (attr "length_immediate")
5642 (if_then_else
5643 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5644 (const_string "1")
5645 (const_string "*")))
5646 (set_attr "mode" "HI,HI,HI,SI")])
5647
5648 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5649 (define_insn "*addqi_1"
5650 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5651 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5652 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5653 (clobber (reg:CC FLAGS_REG))]
5654 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5655 {
5656 bool widen = (which_alternative == 3 || which_alternative == 4);
5657
5658 switch (get_attr_type (insn))
5659 {
5660 case TYPE_LEA:
5661 return "#";
5662
5663 case TYPE_INCDEC:
5664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5665 if (operands[2] == const1_rtx)
5666 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5667 else
5668 {
5669 gcc_assert (operands[2] == constm1_rtx);
5670 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5671 }
5672
5673 default:
5674 /* For most processors, ADD is faster than LEA. These alternatives
5675 were added to use ADD as much as possible. */
5676 if (which_alternative == 2 || which_alternative == 4)
5677 {
5678 rtx tmp;
5679 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5680 }
5681
5682 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5683 if (x86_maybe_negate_const_int (&operands[2], QImode))
5684 {
5685 if (widen)
5686 return "sub{l}\t{%2, %k0|%k0, %2}";
5687 else
5688 return "sub{b}\t{%2, %0|%0, %2}";
5689 }
5690 if (widen)
5691 return "add{l}\t{%k2, %k0|%k0, %k2}";
5692 else
5693 return "add{b}\t{%2, %0|%0, %2}";
5694 }
5695 }
5696 [(set (attr "type")
5697 (cond [(eq_attr "alternative" "5")
5698 (const_string "lea")
5699 (match_operand:QI 2 "incdec_operand" "")
5700 (const_string "incdec")
5701 ]
5702 (const_string "alu")))
5703 (set (attr "length_immediate")
5704 (if_then_else
5705 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5706 (const_string "1")
5707 (const_string "*")))
5708 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5709
5710 (define_insn "*addqi_1_slp"
5711 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5712 (plus:QI (match_dup 0)
5713 (match_operand:QI 1 "general_operand" "qn,qm")))
5714 (clobber (reg:CC FLAGS_REG))]
5715 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5716 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5717 {
5718 switch (get_attr_type (insn))
5719 {
5720 case TYPE_INCDEC:
5721 if (operands[1] == const1_rtx)
5722 return "inc{b}\t%0";
5723 else
5724 {
5725 gcc_assert (operands[1] == constm1_rtx);
5726 return "dec{b}\t%0";
5727 }
5728
5729 default:
5730 if (x86_maybe_negate_const_int (&operands[1], QImode))
5731 return "sub{b}\t{%1, %0|%0, %1}";
5732
5733 return "add{b}\t{%1, %0|%0, %1}";
5734 }
5735 }
5736 [(set (attr "type")
5737 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5738 (const_string "incdec")
5739 (const_string "alu1")))
5740 (set (attr "memory")
5741 (if_then_else (match_operand 1 "memory_operand" "")
5742 (const_string "load")
5743 (const_string "none")))
5744 (set_attr "mode" "QI")])
5745
5746 ;; Split non destructive adds if we cannot use lea.
5747 (define_split
5748 [(set (match_operand:SWI48 0 "register_operand" "")
5749 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5750 (match_operand:SWI48 2 "nonmemory_operand" "")))
5751 (clobber (reg:CC FLAGS_REG))]
5752 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5753 [(set (match_dup 0) (match_dup 1))
5754 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5755 (clobber (reg:CC FLAGS_REG))])])
5756
5757 ;; Convert add to the lea pattern to avoid flags dependency.
5758 (define_split
5759 [(set (match_operand:SWI 0 "register_operand" "")
5760 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5761 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5762 (clobber (reg:CC FLAGS_REG))]
5763 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5764 [(const_int 0)]
5765 {
5766 enum machine_mode mode = <MODE>mode;
5767 rtx pat;
5768
5769 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5770 {
5771 mode = SImode;
5772 operands[0] = gen_lowpart (mode, operands[0]);
5773 operands[1] = gen_lowpart (mode, operands[1]);
5774 operands[2] = gen_lowpart (mode, operands[2]);
5775 }
5776
5777 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5778
5779 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5780 DONE;
5781 })
5782
5783 ;; Convert add to the lea pattern to avoid flags dependency.
5784 (define_split
5785 [(set (match_operand:DI 0 "register_operand" "")
5786 (zero_extend:DI
5787 (plus:SI (match_operand:SI 1 "register_operand" "")
5788 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5789 (clobber (reg:CC FLAGS_REG))]
5790 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5791 [(set (match_dup 0)
5792 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5793
5794 (define_insn "*add<mode>_2"
5795 [(set (reg FLAGS_REG)
5796 (compare
5797 (plus:SWI
5798 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5799 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5800 (const_int 0)))
5801 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5802 (plus:SWI (match_dup 1) (match_dup 2)))]
5803 "ix86_match_ccmode (insn, CCGOCmode)
5804 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5805 {
5806 switch (get_attr_type (insn))
5807 {
5808 case TYPE_INCDEC:
5809 if (operands[2] == const1_rtx)
5810 return "inc{<imodesuffix>}\t%0";
5811 else
5812 {
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{<imodesuffix>}\t%0";
5815 }
5816
5817 default:
5818 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5819 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5820
5821 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5822 }
5823 }
5824 [(set (attr "type")
5825 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5826 (const_string "incdec")
5827 (const_string "alu")))
5828 (set (attr "length_immediate")
5829 (if_then_else
5830 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5831 (const_string "1")
5832 (const_string "*")))
5833 (set_attr "mode" "<MODE>")])
5834
5835 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5836 (define_insn "*addsi_2_zext"
5837 [(set (reg FLAGS_REG)
5838 (compare
5839 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5840 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5841 (const_int 0)))
5842 (set (match_operand:DI 0 "register_operand" "=r")
5843 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5844 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5845 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5846 {
5847 switch (get_attr_type (insn))
5848 {
5849 case TYPE_INCDEC:
5850 if (operands[2] == const1_rtx)
5851 return "inc{l}\t%k0";
5852 else
5853 {
5854 gcc_assert (operands[2] == constm1_rtx);
5855 return "dec{l}\t%k0";
5856 }
5857
5858 default:
5859 if (x86_maybe_negate_const_int (&operands[2], SImode))
5860 return "sub{l}\t{%2, %k0|%k0, %2}";
5861
5862 return "add{l}\t{%2, %k0|%k0, %2}";
5863 }
5864 }
5865 [(set (attr "type")
5866 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5867 (const_string "incdec")
5868 (const_string "alu")))
5869 (set (attr "length_immediate")
5870 (if_then_else
5871 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5872 (const_string "1")
5873 (const_string "*")))
5874 (set_attr "mode" "SI")])
5875
5876 (define_insn "*add<mode>_3"
5877 [(set (reg FLAGS_REG)
5878 (compare
5879 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5880 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5881 (clobber (match_scratch:SWI 0 "=<r>"))]
5882 "ix86_match_ccmode (insn, CCZmode)
5883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5884 {
5885 switch (get_attr_type (insn))
5886 {
5887 case TYPE_INCDEC:
5888 if (operands[2] == const1_rtx)
5889 return "inc{<imodesuffix>}\t%0";
5890 else
5891 {
5892 gcc_assert (operands[2] == constm1_rtx);
5893 return "dec{<imodesuffix>}\t%0";
5894 }
5895
5896 default:
5897 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5898 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5899
5900 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5901 }
5902 }
5903 [(set (attr "type")
5904 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5905 (const_string "incdec")
5906 (const_string "alu")))
5907 (set (attr "length_immediate")
5908 (if_then_else
5909 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5910 (const_string "1")
5911 (const_string "*")))
5912 (set_attr "mode" "<MODE>")])
5913
5914 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5915 (define_insn "*addsi_3_zext"
5916 [(set (reg FLAGS_REG)
5917 (compare
5918 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5919 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5920 (set (match_operand:DI 0 "register_operand" "=r")
5921 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5922 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5923 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5924 {
5925 switch (get_attr_type (insn))
5926 {
5927 case TYPE_INCDEC:
5928 if (operands[2] == const1_rtx)
5929 return "inc{l}\t%k0";
5930 else
5931 {
5932 gcc_assert (operands[2] == constm1_rtx);
5933 return "dec{l}\t%k0";
5934 }
5935
5936 default:
5937 if (x86_maybe_negate_const_int (&operands[2], SImode))
5938 return "sub{l}\t{%2, %k0|%k0, %2}";
5939
5940 return "add{l}\t{%2, %k0|%k0, %2}";
5941 }
5942 }
5943 [(set (attr "type")
5944 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set (attr "length_immediate")
5948 (if_then_else
5949 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5950 (const_string "1")
5951 (const_string "*")))
5952 (set_attr "mode" "SI")])
5953
5954 ; For comparisons against 1, -1 and 128, we may generate better code
5955 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5956 ; is matched then. We can't accept general immediate, because for
5957 ; case of overflows, the result is messed up.
5958 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5959 ; only for comparisons not depending on it.
5960
5961 (define_insn "*adddi_4"
5962 [(set (reg FLAGS_REG)
5963 (compare
5964 (match_operand:DI 1 "nonimmediate_operand" "0")
5965 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5966 (clobber (match_scratch:DI 0 "=rm"))]
5967 "TARGET_64BIT
5968 && ix86_match_ccmode (insn, CCGCmode)"
5969 {
5970 switch (get_attr_type (insn))
5971 {
5972 case TYPE_INCDEC:
5973 if (operands[2] == constm1_rtx)
5974 return "inc{q}\t%0";
5975 else
5976 {
5977 gcc_assert (operands[2] == const1_rtx);
5978 return "dec{q}\t%0";
5979 }
5980
5981 default:
5982 if (x86_maybe_negate_const_int (&operands[2], DImode))
5983 return "add{q}\t{%2, %0|%0, %2}";
5984
5985 return "sub{q}\t{%2, %0|%0, %2}";
5986 }
5987 }
5988 [(set (attr "type")
5989 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5990 (const_string "incdec")
5991 (const_string "alu")))
5992 (set (attr "length_immediate")
5993 (if_then_else
5994 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5995 (const_string "1")
5996 (const_string "*")))
5997 (set_attr "mode" "DI")])
5998
5999 ; For comparisons against 1, -1 and 128, we may generate better code
6000 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6001 ; is matched then. We can't accept general immediate, because for
6002 ; case of overflows, the result is messed up.
6003 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6004 ; only for comparisons not depending on it.
6005
6006 (define_insn "*add<mode>_4"
6007 [(set (reg FLAGS_REG)
6008 (compare
6009 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6010 (match_operand:SWI124 2 "const_int_operand" "n")))
6011 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6012 "ix86_match_ccmode (insn, CCGCmode)"
6013 {
6014 switch (get_attr_type (insn))
6015 {
6016 case TYPE_INCDEC:
6017 if (operands[2] == constm1_rtx)
6018 return "inc{<imodesuffix>}\t%0";
6019 else
6020 {
6021 gcc_assert (operands[2] == const1_rtx);
6022 return "dec{<imodesuffix>}\t%0";
6023 }
6024
6025 default:
6026 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6027 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6028
6029 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6030 }
6031 }
6032 [(set (attr "type")
6033 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6034 (const_string "incdec")
6035 (const_string "alu")))
6036 (set (attr "length_immediate")
6037 (if_then_else
6038 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6039 (const_string "1")
6040 (const_string "*")))
6041 (set_attr "mode" "<MODE>")])
6042
6043 (define_insn "*add<mode>_5"
6044 [(set (reg FLAGS_REG)
6045 (compare
6046 (plus:SWI
6047 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6048 (match_operand:SWI 2 "<general_operand>" "<g>"))
6049 (const_int 0)))
6050 (clobber (match_scratch:SWI 0 "=<r>"))]
6051 "ix86_match_ccmode (insn, CCGOCmode)
6052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6053 {
6054 switch (get_attr_type (insn))
6055 {
6056 case TYPE_INCDEC:
6057 if (operands[2] == const1_rtx)
6058 return "inc{<imodesuffix>}\t%0";
6059 else
6060 {
6061 gcc_assert (operands[2] == constm1_rtx);
6062 return "dec{<imodesuffix>}\t%0";
6063 }
6064
6065 default:
6066 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6067 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6068
6069 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6070 }
6071 }
6072 [(set (attr "type")
6073 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6074 (const_string "incdec")
6075 (const_string "alu")))
6076 (set (attr "length_immediate")
6077 (if_then_else
6078 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6079 (const_string "1")
6080 (const_string "*")))
6081 (set_attr "mode" "<MODE>")])
6082
6083 (define_insn "*addqi_ext_1_rex64"
6084 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6085 (const_int 8)
6086 (const_int 8))
6087 (plus:SI
6088 (zero_extract:SI
6089 (match_operand 1 "ext_register_operand" "0")
6090 (const_int 8)
6091 (const_int 8))
6092 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6093 (clobber (reg:CC FLAGS_REG))]
6094 "TARGET_64BIT"
6095 {
6096 switch (get_attr_type (insn))
6097 {
6098 case TYPE_INCDEC:
6099 if (operands[2] == const1_rtx)
6100 return "inc{b}\t%h0";
6101 else
6102 {
6103 gcc_assert (operands[2] == constm1_rtx);
6104 return "dec{b}\t%h0";
6105 }
6106
6107 default:
6108 return "add{b}\t{%2, %h0|%h0, %2}";
6109 }
6110 }
6111 [(set (attr "type")
6112 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6113 (const_string "incdec")
6114 (const_string "alu")))
6115 (set_attr "modrm" "1")
6116 (set_attr "mode" "QI")])
6117
6118 (define_insn "addqi_ext_1"
6119 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6120 (const_int 8)
6121 (const_int 8))
6122 (plus:SI
6123 (zero_extract:SI
6124 (match_operand 1 "ext_register_operand" "0")
6125 (const_int 8)
6126 (const_int 8))
6127 (match_operand:QI 2 "general_operand" "Qmn")))
6128 (clobber (reg:CC FLAGS_REG))]
6129 "!TARGET_64BIT"
6130 {
6131 switch (get_attr_type (insn))
6132 {
6133 case TYPE_INCDEC:
6134 if (operands[2] == const1_rtx)
6135 return "inc{b}\t%h0";
6136 else
6137 {
6138 gcc_assert (operands[2] == constm1_rtx);
6139 return "dec{b}\t%h0";
6140 }
6141
6142 default:
6143 return "add{b}\t{%2, %h0|%h0, %2}";
6144 }
6145 }
6146 [(set (attr "type")
6147 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu")))
6150 (set_attr "modrm" "1")
6151 (set_attr "mode" "QI")])
6152
6153 (define_insn "*addqi_ext_2"
6154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6155 (const_int 8)
6156 (const_int 8))
6157 (plus:SI
6158 (zero_extract:SI
6159 (match_operand 1 "ext_register_operand" "%0")
6160 (const_int 8)
6161 (const_int 8))
6162 (zero_extract:SI
6163 (match_operand 2 "ext_register_operand" "Q")
6164 (const_int 8)
6165 (const_int 8))))
6166 (clobber (reg:CC FLAGS_REG))]
6167 ""
6168 "add{b}\t{%h2, %h0|%h0, %h2}"
6169 [(set_attr "type" "alu")
6170 (set_attr "mode" "QI")])
6171
6172 ;; The lea patterns for modes less than 32 bits need to be matched by
6173 ;; several insns converted to real lea by splitters.
6174
6175 (define_insn_and_split "*lea_general_1"
6176 [(set (match_operand 0 "register_operand" "=r")
6177 (plus (plus (match_operand 1 "index_register_operand" "l")
6178 (match_operand 2 "register_operand" "r"))
6179 (match_operand 3 "immediate_operand" "i")))]
6180 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6181 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6182 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6183 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6184 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6185 || GET_MODE (operands[3]) == VOIDmode)"
6186 "#"
6187 "&& reload_completed"
6188 [(const_int 0)]
6189 {
6190 enum machine_mode mode = SImode;
6191 rtx pat;
6192
6193 operands[0] = gen_lowpart (mode, operands[0]);
6194 operands[1] = gen_lowpart (mode, operands[1]);
6195 operands[2] = gen_lowpart (mode, operands[2]);
6196 operands[3] = gen_lowpart (mode, operands[3]);
6197
6198 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6199 operands[3]);
6200
6201 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6202 DONE;
6203 }
6204 [(set_attr "type" "lea")
6205 (set_attr "mode" "SI")])
6206
6207 (define_insn_and_split "*lea_general_2"
6208 [(set (match_operand 0 "register_operand" "=r")
6209 (plus (mult (match_operand 1 "index_register_operand" "l")
6210 (match_operand 2 "const248_operand" "n"))
6211 (match_operand 3 "nonmemory_operand" "ri")))]
6212 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6213 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6214 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6215 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6216 || GET_MODE (operands[3]) == VOIDmode)"
6217 "#"
6218 "&& reload_completed"
6219 [(const_int 0)]
6220 {
6221 enum machine_mode mode = SImode;
6222 rtx pat;
6223
6224 operands[0] = gen_lowpart (mode, operands[0]);
6225 operands[1] = gen_lowpart (mode, operands[1]);
6226 operands[3] = gen_lowpart (mode, operands[3]);
6227
6228 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6229 operands[3]);
6230
6231 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6232 DONE;
6233 }
6234 [(set_attr "type" "lea")
6235 (set_attr "mode" "SI")])
6236
6237 (define_insn_and_split "*lea_general_3"
6238 [(set (match_operand 0 "register_operand" "=r")
6239 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6240 (match_operand 2 "const248_operand" "n"))
6241 (match_operand 3 "register_operand" "r"))
6242 (match_operand 4 "immediate_operand" "i")))]
6243 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6244 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6245 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6246 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6247 "#"
6248 "&& reload_completed"
6249 [(const_int 0)]
6250 {
6251 enum machine_mode mode = SImode;
6252 rtx pat;
6253
6254 operands[0] = gen_lowpart (mode, operands[0]);
6255 operands[1] = gen_lowpart (mode, operands[1]);
6256 operands[3] = gen_lowpart (mode, operands[3]);
6257 operands[4] = gen_lowpart (mode, operands[4]);
6258
6259 pat = gen_rtx_PLUS (mode,
6260 gen_rtx_PLUS (mode,
6261 gen_rtx_MULT (mode, operands[1],
6262 operands[2]),
6263 operands[3]),
6264 operands[4]);
6265
6266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6267 DONE;
6268 }
6269 [(set_attr "type" "lea")
6270 (set_attr "mode" "SI")])
6271
6272 (define_insn_and_split "*lea_general_4"
6273 [(set (match_operand 0 "register_operand" "=r")
6274 (any_or (ashift
6275 (match_operand 1 "index_register_operand" "l")
6276 (match_operand 2 "const_int_operand" "n"))
6277 (match_operand 3 "const_int_operand" "n")))]
6278 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6280 || GET_MODE (operands[0]) == SImode
6281 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6282 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6283 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6284 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6285 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6286 "#"
6287 "&& reload_completed"
6288 [(const_int 0)]
6289 {
6290 enum machine_mode mode = GET_MODE (operands[0]);
6291 rtx pat;
6292
6293 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6294 {
6295 mode = SImode;
6296 operands[0] = gen_lowpart (mode, operands[0]);
6297 operands[1] = gen_lowpart (mode, operands[1]);
6298 }
6299
6300 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6301
6302 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6303 INTVAL (operands[3]));
6304
6305 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6306 DONE;
6307 }
6308 [(set_attr "type" "lea")
6309 (set (attr "mode")
6310 (if_then_else (match_operand:DI 0 "" "")
6311 (const_string "DI")
6312 (const_string "SI")))])
6313 \f
6314 ;; Subtract instructions
6315
6316 (define_expand "sub<mode>3"
6317 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6318 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6319 (match_operand:SDWIM 2 "<general_operand>" "")))]
6320 ""
6321 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6322
6323 (define_insn_and_split "*sub<dwi>3_doubleword"
6324 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6325 (minus:<DWI>
6326 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6327 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6328 (clobber (reg:CC FLAGS_REG))]
6329 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6330 "#"
6331 "reload_completed"
6332 [(parallel [(set (reg:CC FLAGS_REG)
6333 (compare:CC (match_dup 1) (match_dup 2)))
6334 (set (match_dup 0)
6335 (minus:DWIH (match_dup 1) (match_dup 2)))])
6336 (parallel [(set (match_dup 3)
6337 (minus:DWIH
6338 (match_dup 4)
6339 (plus:DWIH
6340 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6341 (match_dup 5))))
6342 (clobber (reg:CC FLAGS_REG))])]
6343 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6344
6345 (define_insn "*sub<mode>_1"
6346 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6347 (minus:SWI
6348 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6349 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6350 (clobber (reg:CC FLAGS_REG))]
6351 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6352 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6353 [(set_attr "type" "alu")
6354 (set_attr "mode" "<MODE>")])
6355
6356 (define_insn "*subsi_1_zext"
6357 [(set (match_operand:DI 0 "register_operand" "=r")
6358 (zero_extend:DI
6359 (minus:SI (match_operand:SI 1 "register_operand" "0")
6360 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6361 (clobber (reg:CC FLAGS_REG))]
6362 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6363 "sub{l}\t{%2, %k0|%k0, %2}"
6364 [(set_attr "type" "alu")
6365 (set_attr "mode" "SI")])
6366
6367 (define_insn "*subqi_1_slp"
6368 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6369 (minus:QI (match_dup 0)
6370 (match_operand:QI 1 "general_operand" "qn,qm")))
6371 (clobber (reg:CC FLAGS_REG))]
6372 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6373 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6374 "sub{b}\t{%1, %0|%0, %1}"
6375 [(set_attr "type" "alu1")
6376 (set_attr "mode" "QI")])
6377
6378 (define_insn "*sub<mode>_2"
6379 [(set (reg FLAGS_REG)
6380 (compare
6381 (minus:SWI
6382 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6383 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6384 (const_int 0)))
6385 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6386 (minus:SWI (match_dup 1) (match_dup 2)))]
6387 "ix86_match_ccmode (insn, CCGOCmode)
6388 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6389 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6390 [(set_attr "type" "alu")
6391 (set_attr "mode" "<MODE>")])
6392
6393 (define_insn "*subsi_2_zext"
6394 [(set (reg FLAGS_REG)
6395 (compare
6396 (minus:SI (match_operand:SI 1 "register_operand" "0")
6397 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6398 (const_int 0)))
6399 (set (match_operand:DI 0 "register_operand" "=r")
6400 (zero_extend:DI
6401 (minus:SI (match_dup 1)
6402 (match_dup 2))))]
6403 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6404 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6405 "sub{l}\t{%2, %k0|%k0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "mode" "SI")])
6408
6409 (define_insn "*sub<mode>_3"
6410 [(set (reg FLAGS_REG)
6411 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6412 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6413 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6414 (minus:SWI (match_dup 1) (match_dup 2)))]
6415 "ix86_match_ccmode (insn, CCmode)
6416 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6417 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6418 [(set_attr "type" "alu")
6419 (set_attr "mode" "<MODE>")])
6420
6421 (define_insn "*subsi_3_zext"
6422 [(set (reg FLAGS_REG)
6423 (compare (match_operand:SI 1 "register_operand" "0")
6424 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6425 (set (match_operand:DI 0 "register_operand" "=r")
6426 (zero_extend:DI
6427 (minus:SI (match_dup 1)
6428 (match_dup 2))))]
6429 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6430 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6431 "sub{l}\t{%2, %1|%1, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "SI")])
6434 \f
6435 ;; Add with carry and subtract with borrow
6436
6437 (define_expand "<plusminus_insn><mode>3_carry"
6438 [(parallel
6439 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6440 (plusminus:SWI
6441 (match_operand:SWI 1 "nonimmediate_operand" "")
6442 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6443 [(match_operand 3 "flags_reg_operand" "")
6444 (const_int 0)])
6445 (match_operand:SWI 2 "<general_operand>" ""))))
6446 (clobber (reg:CC FLAGS_REG))])]
6447 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6448
6449 (define_insn "*<plusminus_insn><mode>3_carry"
6450 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6451 (plusminus:SWI
6452 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6453 (plus:SWI
6454 (match_operator 3 "ix86_carry_flag_operator"
6455 [(reg FLAGS_REG) (const_int 0)])
6456 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6457 (clobber (reg:CC FLAGS_REG))]
6458 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6459 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6460 [(set_attr "type" "alu")
6461 (set_attr "use_carry" "1")
6462 (set_attr "pent_pair" "pu")
6463 (set_attr "mode" "<MODE>")])
6464
6465 (define_insn "*addsi3_carry_zext"
6466 [(set (match_operand:DI 0 "register_operand" "=r")
6467 (zero_extend:DI
6468 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6469 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6470 [(reg FLAGS_REG) (const_int 0)])
6471 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6472 (clobber (reg:CC FLAGS_REG))]
6473 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6474 "adc{l}\t{%2, %k0|%k0, %2}"
6475 [(set_attr "type" "alu")
6476 (set_attr "use_carry" "1")
6477 (set_attr "pent_pair" "pu")
6478 (set_attr "mode" "SI")])
6479
6480 (define_insn "*subsi3_carry_zext"
6481 [(set (match_operand:DI 0 "register_operand" "=r")
6482 (zero_extend:DI
6483 (minus:SI (match_operand:SI 1 "register_operand" "0")
6484 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6485 [(reg FLAGS_REG) (const_int 0)])
6486 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6489 "sbb{l}\t{%2, %k0|%k0, %2}"
6490 [(set_attr "type" "alu")
6491 (set_attr "pent_pair" "pu")
6492 (set_attr "mode" "SI")])
6493 \f
6494 ;; Overflow setting add and subtract instructions
6495
6496 (define_insn "*add<mode>3_cconly_overflow"
6497 [(set (reg:CCC FLAGS_REG)
6498 (compare:CCC
6499 (plus:SWI
6500 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6501 (match_operand:SWI 2 "<general_operand>" "<g>"))
6502 (match_dup 1)))
6503 (clobber (match_scratch:SWI 0 "=<r>"))]
6504 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6505 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6508
6509 (define_insn "*sub<mode>3_cconly_overflow"
6510 [(set (reg:CCC FLAGS_REG)
6511 (compare:CCC
6512 (minus:SWI
6513 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6514 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6515 (match_dup 0)))]
6516 ""
6517 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6518 [(set_attr "type" "icmp")
6519 (set_attr "mode" "<MODE>")])
6520
6521 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6522 [(set (reg:CCC FLAGS_REG)
6523 (compare:CCC
6524 (plusminus:SWI
6525 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6526 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6527 (match_dup 1)))
6528 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6529 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6530 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6531 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6532 [(set_attr "type" "alu")
6533 (set_attr "mode" "<MODE>")])
6534
6535 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6536 [(set (reg:CCC FLAGS_REG)
6537 (compare:CCC
6538 (plusminus:SI
6539 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6540 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6541 (match_dup 1)))
6542 (set (match_operand:DI 0 "register_operand" "=r")
6543 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6544 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6545 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6546 [(set_attr "type" "alu")
6547 (set_attr "mode" "SI")])
6548
6549 ;; The patterns that match these are at the end of this file.
6550
6551 (define_expand "<plusminus_insn>xf3"
6552 [(set (match_operand:XF 0 "register_operand" "")
6553 (plusminus:XF
6554 (match_operand:XF 1 "register_operand" "")
6555 (match_operand:XF 2 "register_operand" "")))]
6556 "TARGET_80387")
6557
6558 (define_expand "<plusminus_insn><mode>3"
6559 [(set (match_operand:MODEF 0 "register_operand" "")
6560 (plusminus:MODEF
6561 (match_operand:MODEF 1 "register_operand" "")
6562 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6563 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6564 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6565 \f
6566 ;; Multiply instructions
6567
6568 (define_expand "mul<mode>3"
6569 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6570 (mult:SWIM248
6571 (match_operand:SWIM248 1 "register_operand" "")
6572 (match_operand:SWIM248 2 "<general_operand>" "")))
6573 (clobber (reg:CC FLAGS_REG))])])
6574
6575 (define_expand "mulqi3"
6576 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6577 (mult:QI
6578 (match_operand:QI 1 "register_operand" "")
6579 (match_operand:QI 2 "nonimmediate_operand" "")))
6580 (clobber (reg:CC FLAGS_REG))])]
6581 "TARGET_QIMODE_MATH")
6582
6583 ;; On AMDFAM10
6584 ;; IMUL reg32/64, reg32/64, imm8 Direct
6585 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6586 ;; IMUL reg32/64, reg32/64, imm32 Direct
6587 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6588 ;; IMUL reg32/64, reg32/64 Direct
6589 ;; IMUL reg32/64, mem32/64 Direct
6590 ;;
6591 ;; On BDVER1, all above IMULs use DirectPath
6592
6593 (define_insn "*mul<mode>3_1"
6594 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6595 (mult:SWI48
6596 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6597 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6598 (clobber (reg:CC FLAGS_REG))]
6599 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6600 "@
6601 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6602 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6603 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6604 [(set_attr "type" "imul")
6605 (set_attr "prefix_0f" "0,0,1")
6606 (set (attr "athlon_decode")
6607 (cond [(eq_attr "cpu" "athlon")
6608 (const_string "vector")
6609 (eq_attr "alternative" "1")
6610 (const_string "vector")
6611 (and (eq_attr "alternative" "2")
6612 (match_operand 1 "memory_operand" ""))
6613 (const_string "vector")]
6614 (const_string "direct")))
6615 (set (attr "amdfam10_decode")
6616 (cond [(and (eq_attr "alternative" "0,1")
6617 (match_operand 1 "memory_operand" ""))
6618 (const_string "vector")]
6619 (const_string "direct")))
6620 (set_attr "bdver1_decode" "direct")
6621 (set_attr "mode" "<MODE>")])
6622
6623 (define_insn "*mulsi3_1_zext"
6624 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6625 (zero_extend:DI
6626 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6627 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6628 (clobber (reg:CC FLAGS_REG))]
6629 "TARGET_64BIT
6630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6631 "@
6632 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6633 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6634 imul{l}\t{%2, %k0|%k0, %2}"
6635 [(set_attr "type" "imul")
6636 (set_attr "prefix_0f" "0,0,1")
6637 (set (attr "athlon_decode")
6638 (cond [(eq_attr "cpu" "athlon")
6639 (const_string "vector")
6640 (eq_attr "alternative" "1")
6641 (const_string "vector")
6642 (and (eq_attr "alternative" "2")
6643 (match_operand 1 "memory_operand" ""))
6644 (const_string "vector")]
6645 (const_string "direct")))
6646 (set (attr "amdfam10_decode")
6647 (cond [(and (eq_attr "alternative" "0,1")
6648 (match_operand 1 "memory_operand" ""))
6649 (const_string "vector")]
6650 (const_string "direct")))
6651 (set_attr "bdver1_decode" "direct")
6652 (set_attr "mode" "SI")])
6653
6654 ;; On AMDFAM10
6655 ;; IMUL reg16, reg16, imm8 VectorPath
6656 ;; IMUL reg16, mem16, imm8 VectorPath
6657 ;; IMUL reg16, reg16, imm16 VectorPath
6658 ;; IMUL reg16, mem16, imm16 VectorPath
6659 ;; IMUL reg16, reg16 Direct
6660 ;; IMUL reg16, mem16 Direct
6661 ;;
6662 ;; On BDVER1, all HI MULs use DoublePath
6663
6664 (define_insn "*mulhi3_1"
6665 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6666 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6667 (match_operand:HI 2 "general_operand" "K,n,mr")))
6668 (clobber (reg:CC FLAGS_REG))]
6669 "TARGET_HIMODE_MATH
6670 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6671 "@
6672 imul{w}\t{%2, %1, %0|%0, %1, %2}
6673 imul{w}\t{%2, %1, %0|%0, %1, %2}
6674 imul{w}\t{%2, %0|%0, %2}"
6675 [(set_attr "type" "imul")
6676 (set_attr "prefix_0f" "0,0,1")
6677 (set (attr "athlon_decode")
6678 (cond [(eq_attr "cpu" "athlon")
6679 (const_string "vector")
6680 (eq_attr "alternative" "1,2")
6681 (const_string "vector")]
6682 (const_string "direct")))
6683 (set (attr "amdfam10_decode")
6684 (cond [(eq_attr "alternative" "0,1")
6685 (const_string "vector")]
6686 (const_string "direct")))
6687 (set_attr "bdver1_decode" "double")
6688 (set_attr "mode" "HI")])
6689
6690 ;;On AMDFAM10 and BDVER1
6691 ;; MUL reg8 Direct
6692 ;; MUL mem8 Direct
6693
6694 (define_insn "*mulqi3_1"
6695 [(set (match_operand:QI 0 "register_operand" "=a")
6696 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6697 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6698 (clobber (reg:CC FLAGS_REG))]
6699 "TARGET_QIMODE_MATH
6700 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6701 "mul{b}\t%2"
6702 [(set_attr "type" "imul")
6703 (set_attr "length_immediate" "0")
6704 (set (attr "athlon_decode")
6705 (if_then_else (eq_attr "cpu" "athlon")
6706 (const_string "vector")
6707 (const_string "direct")))
6708 (set_attr "amdfam10_decode" "direct")
6709 (set_attr "bdver1_decode" "direct")
6710 (set_attr "mode" "QI")])
6711
6712 (define_expand "<u>mul<mode><dwi>3"
6713 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6714 (mult:<DWI>
6715 (any_extend:<DWI>
6716 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6717 (any_extend:<DWI>
6718 (match_operand:DWIH 2 "register_operand" ""))))
6719 (clobber (reg:CC FLAGS_REG))])])
6720
6721 (define_expand "<u>mulqihi3"
6722 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6723 (mult:HI
6724 (any_extend:HI
6725 (match_operand:QI 1 "nonimmediate_operand" ""))
6726 (any_extend:HI
6727 (match_operand:QI 2 "register_operand" ""))))
6728 (clobber (reg:CC FLAGS_REG))])]
6729 "TARGET_QIMODE_MATH")
6730
6731 (define_insn "*bmi2_umulditi3_1"
6732 [(set (match_operand:DI 0 "register_operand" "=r")
6733 (mult:DI
6734 (match_operand:DI 2 "nonimmediate_operand" "%d")
6735 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6736 (set (match_operand:DI 1 "register_operand" "=r")
6737 (truncate:DI
6738 (lshiftrt:TI
6739 (mult:TI (zero_extend:TI (match_dup 2))
6740 (zero_extend:TI (match_dup 3)))
6741 (const_int 64))))]
6742 "TARGET_64BIT && TARGET_BMI2
6743 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6744 "mulx\t{%3, %0, %1|%1, %0, %3}"
6745 [(set_attr "type" "imulx")
6746 (set_attr "prefix" "vex")
6747 (set_attr "mode" "DI")])
6748
6749 (define_insn "*bmi2_umulsidi3_1"
6750 [(set (match_operand:SI 0 "register_operand" "=r")
6751 (mult:SI
6752 (match_operand:SI 2 "nonimmediate_operand" "%d")
6753 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6754 (set (match_operand:SI 1 "register_operand" "=r")
6755 (truncate:SI
6756 (lshiftrt:DI
6757 (mult:DI (zero_extend:DI (match_dup 2))
6758 (zero_extend:DI (match_dup 3)))
6759 (const_int 32))))]
6760 "!TARGET_64BIT && TARGET_BMI2
6761 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6762 "mulx\t{%3, %0, %1|%1, %0, %3}"
6763 [(set_attr "type" "imulx")
6764 (set_attr "prefix" "vex")
6765 (set_attr "mode" "SI")])
6766
6767 (define_insn "*umul<mode><dwi>3_1"
6768 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6769 (mult:<DWI>
6770 (zero_extend:<DWI>
6771 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6772 (zero_extend:<DWI>
6773 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6774 (clobber (reg:CC FLAGS_REG))]
6775 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6776 "@
6777 mul{<imodesuffix>}\t%2
6778 #"
6779 [(set_attr "isa" "*,bmi2")
6780 (set_attr "type" "imul,imulx")
6781 (set_attr "length_immediate" "0,*")
6782 (set (attr "athlon_decode")
6783 (cond [(eq_attr "alternative" "0")
6784 (if_then_else (eq_attr "cpu" "athlon")
6785 (const_string "vector")
6786 (const_string "double"))]
6787 (const_string "*")))
6788 (set_attr "amdfam10_decode" "double,*")
6789 (set_attr "bdver1_decode" "direct,*")
6790 (set_attr "prefix" "orig,vex")
6791 (set_attr "mode" "<MODE>")])
6792
6793 ;; Convert mul to the mulx pattern to avoid flags dependency.
6794 (define_split
6795 [(set (match_operand:<DWI> 0 "register_operand" "")
6796 (mult:<DWI>
6797 (zero_extend:<DWI>
6798 (match_operand:DWIH 1 "register_operand" ""))
6799 (zero_extend:<DWI>
6800 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6801 (clobber (reg:CC FLAGS_REG))]
6802 "TARGET_BMI2 && reload_completed
6803 && true_regnum (operands[1]) == DX_REG"
6804 [(parallel [(set (match_dup 3)
6805 (mult:DWIH (match_dup 1) (match_dup 2)))
6806 (set (match_dup 4)
6807 (truncate:DWIH
6808 (lshiftrt:<DWI>
6809 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6810 (zero_extend:<DWI> (match_dup 2)))
6811 (match_dup 5))))])]
6812 {
6813 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6814
6815 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6816 })
6817
6818 (define_insn "*mul<mode><dwi>3_1"
6819 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6820 (mult:<DWI>
6821 (sign_extend:<DWI>
6822 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6823 (sign_extend:<DWI>
6824 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6825 (clobber (reg:CC FLAGS_REG))]
6826 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6827 "imul{<imodesuffix>}\t%2"
6828 [(set_attr "type" "imul")
6829 (set_attr "length_immediate" "0")
6830 (set (attr "athlon_decode")
6831 (if_then_else (eq_attr "cpu" "athlon")
6832 (const_string "vector")
6833 (const_string "double")))
6834 (set_attr "amdfam10_decode" "double")
6835 (set_attr "bdver1_decode" "direct")
6836 (set_attr "mode" "<MODE>")])
6837
6838 (define_insn "*<u>mulqihi3_1"
6839 [(set (match_operand:HI 0 "register_operand" "=a")
6840 (mult:HI
6841 (any_extend:HI
6842 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6843 (any_extend:HI
6844 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6845 (clobber (reg:CC FLAGS_REG))]
6846 "TARGET_QIMODE_MATH
6847 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6848 "<sgnprefix>mul{b}\t%2"
6849 [(set_attr "type" "imul")
6850 (set_attr "length_immediate" "0")
6851 (set (attr "athlon_decode")
6852 (if_then_else (eq_attr "cpu" "athlon")
6853 (const_string "vector")
6854 (const_string "direct")))
6855 (set_attr "amdfam10_decode" "direct")
6856 (set_attr "bdver1_decode" "direct")
6857 (set_attr "mode" "QI")])
6858
6859 (define_expand "<s>mul<mode>3_highpart"
6860 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6861 (truncate:SWI48
6862 (lshiftrt:<DWI>
6863 (mult:<DWI>
6864 (any_extend:<DWI>
6865 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6866 (any_extend:<DWI>
6867 (match_operand:SWI48 2 "register_operand" "")))
6868 (match_dup 4))))
6869 (clobber (match_scratch:SWI48 3 ""))
6870 (clobber (reg:CC FLAGS_REG))])]
6871 ""
6872 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6873
6874 (define_insn "*<s>muldi3_highpart_1"
6875 [(set (match_operand:DI 0 "register_operand" "=d")
6876 (truncate:DI
6877 (lshiftrt:TI
6878 (mult:TI
6879 (any_extend:TI
6880 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6881 (any_extend:TI
6882 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6883 (const_int 64))))
6884 (clobber (match_scratch:DI 3 "=1"))
6885 (clobber (reg:CC FLAGS_REG))]
6886 "TARGET_64BIT
6887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888 "<sgnprefix>mul{q}\t%2"
6889 [(set_attr "type" "imul")
6890 (set_attr "length_immediate" "0")
6891 (set (attr "athlon_decode")
6892 (if_then_else (eq_attr "cpu" "athlon")
6893 (const_string "vector")
6894 (const_string "double")))
6895 (set_attr "amdfam10_decode" "double")
6896 (set_attr "bdver1_decode" "direct")
6897 (set_attr "mode" "DI")])
6898
6899 (define_insn "*<s>mulsi3_highpart_1"
6900 [(set (match_operand:SI 0 "register_operand" "=d")
6901 (truncate:SI
6902 (lshiftrt:DI
6903 (mult:DI
6904 (any_extend:DI
6905 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6906 (any_extend:DI
6907 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6908 (const_int 32))))
6909 (clobber (match_scratch:SI 3 "=1"))
6910 (clobber (reg:CC FLAGS_REG))]
6911 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6912 "<sgnprefix>mul{l}\t%2"
6913 [(set_attr "type" "imul")
6914 (set_attr "length_immediate" "0")
6915 (set (attr "athlon_decode")
6916 (if_then_else (eq_attr "cpu" "athlon")
6917 (const_string "vector")
6918 (const_string "double")))
6919 (set_attr "amdfam10_decode" "double")
6920 (set_attr "bdver1_decode" "direct")
6921 (set_attr "mode" "SI")])
6922
6923 (define_insn "*<s>mulsi3_highpart_zext"
6924 [(set (match_operand:DI 0 "register_operand" "=d")
6925 (zero_extend:DI (truncate:SI
6926 (lshiftrt:DI
6927 (mult:DI (any_extend:DI
6928 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6929 (any_extend:DI
6930 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6931 (const_int 32)))))
6932 (clobber (match_scratch:SI 3 "=1"))
6933 (clobber (reg:CC FLAGS_REG))]
6934 "TARGET_64BIT
6935 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6936 "<sgnprefix>mul{l}\t%2"
6937 [(set_attr "type" "imul")
6938 (set_attr "length_immediate" "0")
6939 (set (attr "athlon_decode")
6940 (if_then_else (eq_attr "cpu" "athlon")
6941 (const_string "vector")
6942 (const_string "double")))
6943 (set_attr "amdfam10_decode" "double")
6944 (set_attr "bdver1_decode" "direct")
6945 (set_attr "mode" "SI")])
6946
6947 ;; The patterns that match these are at the end of this file.
6948
6949 (define_expand "mulxf3"
6950 [(set (match_operand:XF 0 "register_operand" "")
6951 (mult:XF (match_operand:XF 1 "register_operand" "")
6952 (match_operand:XF 2 "register_operand" "")))]
6953 "TARGET_80387")
6954
6955 (define_expand "mul<mode>3"
6956 [(set (match_operand:MODEF 0 "register_operand" "")
6957 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6958 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6959 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6960 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6961 \f
6962 ;; Divide instructions
6963
6964 ;; The patterns that match these are at the end of this file.
6965
6966 (define_expand "divxf3"
6967 [(set (match_operand:XF 0 "register_operand" "")
6968 (div:XF (match_operand:XF 1 "register_operand" "")
6969 (match_operand:XF 2 "register_operand" "")))]
6970 "TARGET_80387")
6971
6972 (define_expand "divdf3"
6973 [(set (match_operand:DF 0 "register_operand" "")
6974 (div:DF (match_operand:DF 1 "register_operand" "")
6975 (match_operand:DF 2 "nonimmediate_operand" "")))]
6976 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6977 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6978
6979 (define_expand "divsf3"
6980 [(set (match_operand:SF 0 "register_operand" "")
6981 (div:SF (match_operand:SF 1 "register_operand" "")
6982 (match_operand:SF 2 "nonimmediate_operand" "")))]
6983 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6984 || TARGET_SSE_MATH"
6985 {
6986 if (TARGET_SSE_MATH
6987 && TARGET_RECIP_DIV
6988 && optimize_insn_for_speed_p ()
6989 && flag_finite_math_only && !flag_trapping_math
6990 && flag_unsafe_math_optimizations)
6991 {
6992 ix86_emit_swdivsf (operands[0], operands[1],
6993 operands[2], SFmode);
6994 DONE;
6995 }
6996 })
6997 \f
6998 ;; Divmod instructions.
6999
7000 (define_expand "divmod<mode>4"
7001 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7002 (div:SWIM248
7003 (match_operand:SWIM248 1 "register_operand" "")
7004 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7005 (set (match_operand:SWIM248 3 "register_operand" "")
7006 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7007 (clobber (reg:CC FLAGS_REG))])])
7008
7009 ;; Split with 8bit unsigned divide:
7010 ;; if (dividend an divisor are in [0-255])
7011 ;; use 8bit unsigned integer divide
7012 ;; else
7013 ;; use original integer divide
7014 (define_split
7015 [(set (match_operand:SWI48 0 "register_operand" "")
7016 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7017 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7018 (set (match_operand:SWI48 1 "register_operand" "")
7019 (mod:SWI48 (match_dup 2) (match_dup 3)))
7020 (clobber (reg:CC FLAGS_REG))]
7021 "TARGET_USE_8BIT_IDIV
7022 && TARGET_QIMODE_MATH
7023 && can_create_pseudo_p ()
7024 && !optimize_insn_for_size_p ()"
7025 [(const_int 0)]
7026 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7027
7028 (define_insn_and_split "divmod<mode>4_1"
7029 [(set (match_operand:SWI48 0 "register_operand" "=a")
7030 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7031 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7032 (set (match_operand:SWI48 1 "register_operand" "=&d")
7033 (mod:SWI48 (match_dup 2) (match_dup 3)))
7034 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7035 (clobber (reg:CC FLAGS_REG))]
7036 ""
7037 "#"
7038 "reload_completed"
7039 [(parallel [(set (match_dup 1)
7040 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7041 (clobber (reg:CC FLAGS_REG))])
7042 (parallel [(set (match_dup 0)
7043 (div:SWI48 (match_dup 2) (match_dup 3)))
7044 (set (match_dup 1)
7045 (mod:SWI48 (match_dup 2) (match_dup 3)))
7046 (use (match_dup 1))
7047 (clobber (reg:CC FLAGS_REG))])]
7048 {
7049 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7050
7051 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7052 operands[4] = operands[2];
7053 else
7054 {
7055 /* Avoid use of cltd in favor of a mov+shift. */
7056 emit_move_insn (operands[1], operands[2]);
7057 operands[4] = operands[1];
7058 }
7059 }
7060 [(set_attr "type" "multi")
7061 (set_attr "mode" "<MODE>")])
7062
7063 (define_insn_and_split "*divmod<mode>4"
7064 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7065 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7066 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7067 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7068 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7069 (clobber (reg:CC FLAGS_REG))]
7070 ""
7071 "#"
7072 "reload_completed"
7073 [(parallel [(set (match_dup 1)
7074 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7075 (clobber (reg:CC FLAGS_REG))])
7076 (parallel [(set (match_dup 0)
7077 (div:SWIM248 (match_dup 2) (match_dup 3)))
7078 (set (match_dup 1)
7079 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7080 (use (match_dup 1))
7081 (clobber (reg:CC FLAGS_REG))])]
7082 {
7083 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7084
7085 if (<MODE>mode != HImode
7086 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7087 operands[4] = operands[2];
7088 else
7089 {
7090 /* Avoid use of cltd in favor of a mov+shift. */
7091 emit_move_insn (operands[1], operands[2]);
7092 operands[4] = operands[1];
7093 }
7094 }
7095 [(set_attr "type" "multi")
7096 (set_attr "mode" "<MODE>")])
7097
7098 (define_insn "*divmod<mode>4_noext"
7099 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7100 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7101 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7102 (set (match_operand:SWIM248 1 "register_operand" "=d")
7103 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7104 (use (match_operand:SWIM248 4 "register_operand" "1"))
7105 (clobber (reg:CC FLAGS_REG))]
7106 ""
7107 "idiv{<imodesuffix>}\t%3"
7108 [(set_attr "type" "idiv")
7109 (set_attr "mode" "<MODE>")])
7110
7111 (define_expand "divmodqi4"
7112 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7113 (div:QI
7114 (match_operand:QI 1 "register_operand" "")
7115 (match_operand:QI 2 "nonimmediate_operand" "")))
7116 (set (match_operand:QI 3 "register_operand" "")
7117 (mod:QI (match_dup 1) (match_dup 2)))
7118 (clobber (reg:CC FLAGS_REG))])]
7119 "TARGET_QIMODE_MATH"
7120 {
7121 rtx div, mod, insn;
7122 rtx tmp0, tmp1;
7123
7124 tmp0 = gen_reg_rtx (HImode);
7125 tmp1 = gen_reg_rtx (HImode);
7126
7127 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7128 in AX. */
7129 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7130 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7131
7132 /* Extract remainder from AH. */
7133 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7134 insn = emit_move_insn (operands[3], tmp1);
7135
7136 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7137 set_unique_reg_note (insn, REG_EQUAL, mod);
7138
7139 /* Extract quotient from AL. */
7140 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7141
7142 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7143 set_unique_reg_note (insn, REG_EQUAL, div);
7144
7145 DONE;
7146 })
7147
7148 ;; Divide AX by r/m8, with result stored in
7149 ;; AL <- Quotient
7150 ;; AH <- Remainder
7151 ;; Change div/mod to HImode and extend the second argument to HImode
7152 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7153 ;; combine may fail.
7154 (define_insn "divmodhiqi3"
7155 [(set (match_operand:HI 0 "register_operand" "=a")
7156 (ior:HI
7157 (ashift:HI
7158 (zero_extend:HI
7159 (truncate:QI
7160 (mod:HI (match_operand:HI 1 "register_operand" "0")
7161 (sign_extend:HI
7162 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7163 (const_int 8))
7164 (zero_extend:HI
7165 (truncate:QI
7166 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7167 (clobber (reg:CC FLAGS_REG))]
7168 "TARGET_QIMODE_MATH"
7169 "idiv{b}\t%2"
7170 [(set_attr "type" "idiv")
7171 (set_attr "mode" "QI")])
7172
7173 (define_expand "udivmod<mode>4"
7174 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7175 (udiv:SWIM248
7176 (match_operand:SWIM248 1 "register_operand" "")
7177 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7178 (set (match_operand:SWIM248 3 "register_operand" "")
7179 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7180 (clobber (reg:CC FLAGS_REG))])])
7181
7182 ;; Split with 8bit unsigned divide:
7183 ;; if (dividend an divisor are in [0-255])
7184 ;; use 8bit unsigned integer divide
7185 ;; else
7186 ;; use original integer divide
7187 (define_split
7188 [(set (match_operand:SWI48 0 "register_operand" "")
7189 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7190 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7191 (set (match_operand:SWI48 1 "register_operand" "")
7192 (umod:SWI48 (match_dup 2) (match_dup 3)))
7193 (clobber (reg:CC FLAGS_REG))]
7194 "TARGET_USE_8BIT_IDIV
7195 && TARGET_QIMODE_MATH
7196 && can_create_pseudo_p ()
7197 && !optimize_insn_for_size_p ()"
7198 [(const_int 0)]
7199 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7200
7201 (define_insn_and_split "udivmod<mode>4_1"
7202 [(set (match_operand:SWI48 0 "register_operand" "=a")
7203 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7204 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7205 (set (match_operand:SWI48 1 "register_operand" "=&d")
7206 (umod:SWI48 (match_dup 2) (match_dup 3)))
7207 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7208 (clobber (reg:CC FLAGS_REG))]
7209 ""
7210 "#"
7211 "reload_completed"
7212 [(set (match_dup 1) (const_int 0))
7213 (parallel [(set (match_dup 0)
7214 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7215 (set (match_dup 1)
7216 (umod:SWI48 (match_dup 2) (match_dup 3)))
7217 (use (match_dup 1))
7218 (clobber (reg:CC FLAGS_REG))])]
7219 ""
7220 [(set_attr "type" "multi")
7221 (set_attr "mode" "<MODE>")])
7222
7223 (define_insn_and_split "*udivmod<mode>4"
7224 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7225 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7226 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7227 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7228 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7229 (clobber (reg:CC FLAGS_REG))]
7230 ""
7231 "#"
7232 "reload_completed"
7233 [(set (match_dup 1) (const_int 0))
7234 (parallel [(set (match_dup 0)
7235 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7236 (set (match_dup 1)
7237 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7238 (use (match_dup 1))
7239 (clobber (reg:CC FLAGS_REG))])]
7240 ""
7241 [(set_attr "type" "multi")
7242 (set_attr "mode" "<MODE>")])
7243
7244 (define_insn "*udivmod<mode>4_noext"
7245 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7246 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7247 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7248 (set (match_operand:SWIM248 1 "register_operand" "=d")
7249 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7250 (use (match_operand:SWIM248 4 "register_operand" "1"))
7251 (clobber (reg:CC FLAGS_REG))]
7252 ""
7253 "div{<imodesuffix>}\t%3"
7254 [(set_attr "type" "idiv")
7255 (set_attr "mode" "<MODE>")])
7256
7257 (define_expand "udivmodqi4"
7258 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7259 (udiv:QI
7260 (match_operand:QI 1 "register_operand" "")
7261 (match_operand:QI 2 "nonimmediate_operand" "")))
7262 (set (match_operand:QI 3 "register_operand" "")
7263 (umod:QI (match_dup 1) (match_dup 2)))
7264 (clobber (reg:CC FLAGS_REG))])]
7265 "TARGET_QIMODE_MATH"
7266 {
7267 rtx div, mod, insn;
7268 rtx tmp0, tmp1;
7269
7270 tmp0 = gen_reg_rtx (HImode);
7271 tmp1 = gen_reg_rtx (HImode);
7272
7273 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7274 in AX. */
7275 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7276 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7277
7278 /* Extract remainder from AH. */
7279 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7280 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7281 insn = emit_move_insn (operands[3], tmp1);
7282
7283 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7284 set_unique_reg_note (insn, REG_EQUAL, mod);
7285
7286 /* Extract quotient from AL. */
7287 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7288
7289 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7290 set_unique_reg_note (insn, REG_EQUAL, div);
7291
7292 DONE;
7293 })
7294
7295 (define_insn "udivmodhiqi3"
7296 [(set (match_operand:HI 0 "register_operand" "=a")
7297 (ior:HI
7298 (ashift:HI
7299 (zero_extend:HI
7300 (truncate:QI
7301 (mod:HI (match_operand:HI 1 "register_operand" "0")
7302 (zero_extend:HI
7303 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7304 (const_int 8))
7305 (zero_extend:HI
7306 (truncate:QI
7307 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7308 (clobber (reg:CC FLAGS_REG))]
7309 "TARGET_QIMODE_MATH"
7310 "div{b}\t%2"
7311 [(set_attr "type" "idiv")
7312 (set_attr "mode" "QI")])
7313
7314 ;; We cannot use div/idiv for double division, because it causes
7315 ;; "division by zero" on the overflow and that's not what we expect
7316 ;; from truncate. Because true (non truncating) double division is
7317 ;; never generated, we can't create this insn anyway.
7318 ;
7319 ;(define_insn ""
7320 ; [(set (match_operand:SI 0 "register_operand" "=a")
7321 ; (truncate:SI
7322 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7323 ; (zero_extend:DI
7324 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7325 ; (set (match_operand:SI 3 "register_operand" "=d")
7326 ; (truncate:SI
7327 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7328 ; (clobber (reg:CC FLAGS_REG))]
7329 ; ""
7330 ; "div{l}\t{%2, %0|%0, %2}"
7331 ; [(set_attr "type" "idiv")])
7332 \f
7333 ;;- Logical AND instructions
7334
7335 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7336 ;; Note that this excludes ah.
7337
7338 (define_expand "testsi_ccno_1"
7339 [(set (reg:CCNO FLAGS_REG)
7340 (compare:CCNO
7341 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7342 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7343 (const_int 0)))])
7344
7345 (define_expand "testqi_ccz_1"
7346 [(set (reg:CCZ FLAGS_REG)
7347 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7348 (match_operand:QI 1 "nonmemory_operand" ""))
7349 (const_int 0)))])
7350
7351 (define_expand "testdi_ccno_1"
7352 [(set (reg:CCNO FLAGS_REG)
7353 (compare:CCNO
7354 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7355 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7356 (const_int 0)))]
7357 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7358
7359 (define_insn "*testdi_1"
7360 [(set (reg FLAGS_REG)
7361 (compare
7362 (and:DI
7363 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7364 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7365 (const_int 0)))]
7366 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7367 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7368 "@
7369 test{l}\t{%k1, %k0|%k0, %k1}
7370 test{l}\t{%k1, %k0|%k0, %k1}
7371 test{q}\t{%1, %0|%0, %1}
7372 test{q}\t{%1, %0|%0, %1}
7373 test{q}\t{%1, %0|%0, %1}"
7374 [(set_attr "type" "test")
7375 (set_attr "modrm" "0,1,0,1,1")
7376 (set_attr "mode" "SI,SI,DI,DI,DI")])
7377
7378 (define_insn "*testqi_1_maybe_si"
7379 [(set (reg FLAGS_REG)
7380 (compare
7381 (and:QI
7382 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7383 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7384 (const_int 0)))]
7385 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7386 && ix86_match_ccmode (insn,
7387 CONST_INT_P (operands[1])
7388 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7389 {
7390 if (which_alternative == 3)
7391 {
7392 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7393 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7394 return "test{l}\t{%1, %k0|%k0, %1}";
7395 }
7396 return "test{b}\t{%1, %0|%0, %1}";
7397 }
7398 [(set_attr "type" "test")
7399 (set_attr "modrm" "0,1,1,1")
7400 (set_attr "mode" "QI,QI,QI,SI")
7401 (set_attr "pent_pair" "uv,np,uv,np")])
7402
7403 (define_insn "*test<mode>_1"
7404 [(set (reg FLAGS_REG)
7405 (compare
7406 (and:SWI124
7407 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7408 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7409 (const_int 0)))]
7410 "ix86_match_ccmode (insn, CCNOmode)
7411 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7412 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7413 [(set_attr "type" "test")
7414 (set_attr "modrm" "0,1,1")
7415 (set_attr "mode" "<MODE>")
7416 (set_attr "pent_pair" "uv,np,uv")])
7417
7418 (define_expand "testqi_ext_ccno_0"
7419 [(set (reg:CCNO FLAGS_REG)
7420 (compare:CCNO
7421 (and:SI
7422 (zero_extract:SI
7423 (match_operand 0 "ext_register_operand" "")
7424 (const_int 8)
7425 (const_int 8))
7426 (match_operand 1 "const_int_operand" ""))
7427 (const_int 0)))])
7428
7429 (define_insn "*testqi_ext_0"
7430 [(set (reg FLAGS_REG)
7431 (compare
7432 (and:SI
7433 (zero_extract:SI
7434 (match_operand 0 "ext_register_operand" "Q")
7435 (const_int 8)
7436 (const_int 8))
7437 (match_operand 1 "const_int_operand" "n"))
7438 (const_int 0)))]
7439 "ix86_match_ccmode (insn, CCNOmode)"
7440 "test{b}\t{%1, %h0|%h0, %1}"
7441 [(set_attr "type" "test")
7442 (set_attr "mode" "QI")
7443 (set_attr "length_immediate" "1")
7444 (set_attr "modrm" "1")
7445 (set_attr "pent_pair" "np")])
7446
7447 (define_insn "*testqi_ext_1_rex64"
7448 [(set (reg FLAGS_REG)
7449 (compare
7450 (and:SI
7451 (zero_extract:SI
7452 (match_operand 0 "ext_register_operand" "Q")
7453 (const_int 8)
7454 (const_int 8))
7455 (zero_extend:SI
7456 (match_operand:QI 1 "register_operand" "Q")))
7457 (const_int 0)))]
7458 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7459 "test{b}\t{%1, %h0|%h0, %1}"
7460 [(set_attr "type" "test")
7461 (set_attr "mode" "QI")])
7462
7463 (define_insn "*testqi_ext_1"
7464 [(set (reg FLAGS_REG)
7465 (compare
7466 (and:SI
7467 (zero_extract:SI
7468 (match_operand 0 "ext_register_operand" "Q")
7469 (const_int 8)
7470 (const_int 8))
7471 (zero_extend:SI
7472 (match_operand:QI 1 "general_operand" "Qm")))
7473 (const_int 0)))]
7474 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7475 "test{b}\t{%1, %h0|%h0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "mode" "QI")])
7478
7479 (define_insn "*testqi_ext_2"
7480 [(set (reg FLAGS_REG)
7481 (compare
7482 (and:SI
7483 (zero_extract:SI
7484 (match_operand 0 "ext_register_operand" "Q")
7485 (const_int 8)
7486 (const_int 8))
7487 (zero_extract:SI
7488 (match_operand 1 "ext_register_operand" "Q")
7489 (const_int 8)
7490 (const_int 8)))
7491 (const_int 0)))]
7492 "ix86_match_ccmode (insn, CCNOmode)"
7493 "test{b}\t{%h1, %h0|%h0, %h1}"
7494 [(set_attr "type" "test")
7495 (set_attr "mode" "QI")])
7496
7497 (define_insn "*testqi_ext_3_rex64"
7498 [(set (reg FLAGS_REG)
7499 (compare (zero_extract:DI
7500 (match_operand 0 "nonimmediate_operand" "rm")
7501 (match_operand:DI 1 "const_int_operand" "")
7502 (match_operand:DI 2 "const_int_operand" ""))
7503 (const_int 0)))]
7504 "TARGET_64BIT
7505 && ix86_match_ccmode (insn, CCNOmode)
7506 && INTVAL (operands[1]) > 0
7507 && INTVAL (operands[2]) >= 0
7508 /* Ensure that resulting mask is zero or sign extended operand. */
7509 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7510 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7511 && INTVAL (operands[1]) > 32))
7512 && (GET_MODE (operands[0]) == SImode
7513 || GET_MODE (operands[0]) == DImode
7514 || GET_MODE (operands[0]) == HImode
7515 || GET_MODE (operands[0]) == QImode)"
7516 "#")
7517
7518 ;; Combine likes to form bit extractions for some tests. Humor it.
7519 (define_insn "*testqi_ext_3"
7520 [(set (reg FLAGS_REG)
7521 (compare (zero_extract:SI
7522 (match_operand 0 "nonimmediate_operand" "rm")
7523 (match_operand:SI 1 "const_int_operand" "")
7524 (match_operand:SI 2 "const_int_operand" ""))
7525 (const_int 0)))]
7526 "ix86_match_ccmode (insn, CCNOmode)
7527 && INTVAL (operands[1]) > 0
7528 && INTVAL (operands[2]) >= 0
7529 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7530 && (GET_MODE (operands[0]) == SImode
7531 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7532 || GET_MODE (operands[0]) == HImode
7533 || GET_MODE (operands[0]) == QImode)"
7534 "#")
7535
7536 (define_split
7537 [(set (match_operand 0 "flags_reg_operand" "")
7538 (match_operator 1 "compare_operator"
7539 [(zero_extract
7540 (match_operand 2 "nonimmediate_operand" "")
7541 (match_operand 3 "const_int_operand" "")
7542 (match_operand 4 "const_int_operand" ""))
7543 (const_int 0)]))]
7544 "ix86_match_ccmode (insn, CCNOmode)"
7545 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7546 {
7547 rtx val = operands[2];
7548 HOST_WIDE_INT len = INTVAL (operands[3]);
7549 HOST_WIDE_INT pos = INTVAL (operands[4]);
7550 HOST_WIDE_INT mask;
7551 enum machine_mode mode, submode;
7552
7553 mode = GET_MODE (val);
7554 if (MEM_P (val))
7555 {
7556 /* ??? Combine likes to put non-volatile mem extractions in QImode
7557 no matter the size of the test. So find a mode that works. */
7558 if (! MEM_VOLATILE_P (val))
7559 {
7560 mode = smallest_mode_for_size (pos + len, MODE_INT);
7561 val = adjust_address (val, mode, 0);
7562 }
7563 }
7564 else if (GET_CODE (val) == SUBREG
7565 && (submode = GET_MODE (SUBREG_REG (val)),
7566 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7567 && pos + len <= GET_MODE_BITSIZE (submode)
7568 && GET_MODE_CLASS (submode) == MODE_INT)
7569 {
7570 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7571 mode = submode;
7572 val = SUBREG_REG (val);
7573 }
7574 else if (mode == HImode && pos + len <= 8)
7575 {
7576 /* Small HImode tests can be converted to QImode. */
7577 mode = QImode;
7578 val = gen_lowpart (QImode, val);
7579 }
7580
7581 if (len == HOST_BITS_PER_WIDE_INT)
7582 mask = -1;
7583 else
7584 mask = ((HOST_WIDE_INT)1 << len) - 1;
7585 mask <<= pos;
7586
7587 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7588 })
7589
7590 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7591 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7592 ;; this is relatively important trick.
7593 ;; Do the conversion only post-reload to avoid limiting of the register class
7594 ;; to QI regs.
7595 (define_split
7596 [(set (match_operand 0 "flags_reg_operand" "")
7597 (match_operator 1 "compare_operator"
7598 [(and (match_operand 2 "register_operand" "")
7599 (match_operand 3 "const_int_operand" ""))
7600 (const_int 0)]))]
7601 "reload_completed
7602 && QI_REG_P (operands[2])
7603 && GET_MODE (operands[2]) != QImode
7604 && ((ix86_match_ccmode (insn, CCZmode)
7605 && !(INTVAL (operands[3]) & ~(255 << 8)))
7606 || (ix86_match_ccmode (insn, CCNOmode)
7607 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7608 [(set (match_dup 0)
7609 (match_op_dup 1
7610 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7611 (match_dup 3))
7612 (const_int 0)]))]
7613 {
7614 operands[2] = gen_lowpart (SImode, operands[2]);
7615 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7616 })
7617
7618 (define_split
7619 [(set (match_operand 0 "flags_reg_operand" "")
7620 (match_operator 1 "compare_operator"
7621 [(and (match_operand 2 "nonimmediate_operand" "")
7622 (match_operand 3 "const_int_operand" ""))
7623 (const_int 0)]))]
7624 "reload_completed
7625 && GET_MODE (operands[2]) != QImode
7626 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7627 && ((ix86_match_ccmode (insn, CCZmode)
7628 && !(INTVAL (operands[3]) & ~255))
7629 || (ix86_match_ccmode (insn, CCNOmode)
7630 && !(INTVAL (operands[3]) & ~127)))"
7631 [(set (match_dup 0)
7632 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7633 (const_int 0)]))]
7634 {
7635 operands[2] = gen_lowpart (QImode, operands[2]);
7636 operands[3] = gen_lowpart (QImode, operands[3]);
7637 })
7638
7639 ;; %%% This used to optimize known byte-wide and operations to memory,
7640 ;; and sometimes to QImode registers. If this is considered useful,
7641 ;; it should be done with splitters.
7642
7643 (define_expand "and<mode>3"
7644 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7645 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7646 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7647 ""
7648 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7649
7650 (define_insn "*anddi_1"
7651 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7652 (and:DI
7653 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7654 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7655 (clobber (reg:CC FLAGS_REG))]
7656 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7657 {
7658 switch (get_attr_type (insn))
7659 {
7660 case TYPE_IMOVX:
7661 return "#";
7662
7663 default:
7664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7665 if (get_attr_mode (insn) == MODE_SI)
7666 return "and{l}\t{%k2, %k0|%k0, %k2}";
7667 else
7668 return "and{q}\t{%2, %0|%0, %2}";
7669 }
7670 }
7671 [(set_attr "type" "alu,alu,alu,imovx")
7672 (set_attr "length_immediate" "*,*,*,0")
7673 (set (attr "prefix_rex")
7674 (if_then_else
7675 (and (eq_attr "type" "imovx")
7676 (and (match_test "INTVAL (operands[2]) == 0xff")
7677 (match_operand 1 "ext_QIreg_operand" "")))
7678 (const_string "1")
7679 (const_string "*")))
7680 (set_attr "mode" "SI,DI,DI,SI")])
7681
7682 (define_insn "*andsi_1"
7683 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7684 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7685 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7686 (clobber (reg:CC FLAGS_REG))]
7687 "ix86_binary_operator_ok (AND, SImode, operands)"
7688 {
7689 switch (get_attr_type (insn))
7690 {
7691 case TYPE_IMOVX:
7692 return "#";
7693
7694 default:
7695 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7696 return "and{l}\t{%2, %0|%0, %2}";
7697 }
7698 }
7699 [(set_attr "type" "alu,alu,imovx")
7700 (set (attr "prefix_rex")
7701 (if_then_else
7702 (and (eq_attr "type" "imovx")
7703 (and (match_test "INTVAL (operands[2]) == 0xff")
7704 (match_operand 1 "ext_QIreg_operand" "")))
7705 (const_string "1")
7706 (const_string "*")))
7707 (set_attr "length_immediate" "*,*,0")
7708 (set_attr "mode" "SI")])
7709
7710 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7711 (define_insn "*andsi_1_zext"
7712 [(set (match_operand:DI 0 "register_operand" "=r")
7713 (zero_extend:DI
7714 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7715 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7716 (clobber (reg:CC FLAGS_REG))]
7717 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7718 "and{l}\t{%2, %k0|%k0, %2}"
7719 [(set_attr "type" "alu")
7720 (set_attr "mode" "SI")])
7721
7722 (define_insn "*andhi_1"
7723 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7724 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7725 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7726 (clobber (reg:CC FLAGS_REG))]
7727 "ix86_binary_operator_ok (AND, HImode, operands)"
7728 {
7729 switch (get_attr_type (insn))
7730 {
7731 case TYPE_IMOVX:
7732 return "#";
7733
7734 default:
7735 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7736 return "and{w}\t{%2, %0|%0, %2}";
7737 }
7738 }
7739 [(set_attr "type" "alu,alu,imovx")
7740 (set_attr "length_immediate" "*,*,0")
7741 (set (attr "prefix_rex")
7742 (if_then_else
7743 (and (eq_attr "type" "imovx")
7744 (match_operand 1 "ext_QIreg_operand" ""))
7745 (const_string "1")
7746 (const_string "*")))
7747 (set_attr "mode" "HI,HI,SI")])
7748
7749 ;; %%% Potential partial reg stall on alternative 2. What to do?
7750 (define_insn "*andqi_1"
7751 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7752 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7753 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7754 (clobber (reg:CC FLAGS_REG))]
7755 "ix86_binary_operator_ok (AND, QImode, operands)"
7756 "@
7757 and{b}\t{%2, %0|%0, %2}
7758 and{b}\t{%2, %0|%0, %2}
7759 and{l}\t{%k2, %k0|%k0, %k2}"
7760 [(set_attr "type" "alu")
7761 (set_attr "mode" "QI,QI,SI")])
7762
7763 (define_insn "*andqi_1_slp"
7764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7765 (and:QI (match_dup 0)
7766 (match_operand:QI 1 "general_operand" "qn,qmn")))
7767 (clobber (reg:CC FLAGS_REG))]
7768 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7769 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7770 "and{b}\t{%1, %0|%0, %1}"
7771 [(set_attr "type" "alu1")
7772 (set_attr "mode" "QI")])
7773
7774 (define_split
7775 [(set (match_operand:SWI248 0 "register_operand" "")
7776 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")
7777 (match_operand:SWI248 2 "const_int_operand" "")))
7778 (clobber (reg:CC FLAGS_REG))]
7779 "reload_completed
7780 && true_regnum (operands[0]) != true_regnum (operands[1])"
7781 [(const_int 0)]
7782 {
7783 enum machine_mode mode;
7784
7785 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7786 mode = SImode;
7787 else if (INTVAL (operands[2]) == 0xffff)
7788 mode = HImode;
7789 else
7790 {
7791 gcc_assert (INTVAL (operands[2]) == 0xff);
7792 mode = QImode;
7793 }
7794
7795 operands[1] = gen_lowpart (mode, operands[1]);
7796
7797 if (mode == SImode)
7798 emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
7799 else
7800 {
7801 rtx (*insn) (rtx, rtx);
7802
7803 /* Zero extend to SImode to avoid partial register stalls. */
7804 operands[0] = gen_lowpart (SImode, operands[0]);
7805
7806 insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2;
7807 emit_insn (insn (operands[0], operands[1]));
7808 }
7809 DONE;
7810 })
7811
7812 (define_split
7813 [(set (match_operand 0 "register_operand" "")
7814 (and (match_dup 0)
7815 (const_int -65536)))
7816 (clobber (reg:CC FLAGS_REG))]
7817 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7818 || optimize_function_for_size_p (cfun)"
7819 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7820 "operands[1] = gen_lowpart (HImode, operands[0]);")
7821
7822 (define_split
7823 [(set (match_operand 0 "ext_register_operand" "")
7824 (and (match_dup 0)
7825 (const_int -256)))
7826 (clobber (reg:CC FLAGS_REG))]
7827 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7828 && reload_completed"
7829 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7830 "operands[1] = gen_lowpart (QImode, operands[0]);")
7831
7832 (define_split
7833 [(set (match_operand 0 "ext_register_operand" "")
7834 (and (match_dup 0)
7835 (const_int -65281)))
7836 (clobber (reg:CC FLAGS_REG))]
7837 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7838 && reload_completed"
7839 [(parallel [(set (zero_extract:SI (match_dup 0)
7840 (const_int 8)
7841 (const_int 8))
7842 (xor:SI
7843 (zero_extract:SI (match_dup 0)
7844 (const_int 8)
7845 (const_int 8))
7846 (zero_extract:SI (match_dup 0)
7847 (const_int 8)
7848 (const_int 8))))
7849 (clobber (reg:CC FLAGS_REG))])]
7850 "operands[0] = gen_lowpart (SImode, operands[0]);")
7851
7852 (define_insn "*anddi_2"
7853 [(set (reg FLAGS_REG)
7854 (compare
7855 (and:DI
7856 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7857 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7858 (const_int 0)))
7859 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7860 (and:DI (match_dup 1) (match_dup 2)))]
7861 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7862 && ix86_binary_operator_ok (AND, DImode, operands)"
7863 "@
7864 and{l}\t{%k2, %k0|%k0, %k2}
7865 and{q}\t{%2, %0|%0, %2}
7866 and{q}\t{%2, %0|%0, %2}"
7867 [(set_attr "type" "alu")
7868 (set_attr "mode" "SI,DI,DI")])
7869
7870 (define_insn "*andqi_2_maybe_si"
7871 [(set (reg FLAGS_REG)
7872 (compare (and:QI
7873 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7874 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7875 (const_int 0)))
7876 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7877 (and:QI (match_dup 1) (match_dup 2)))]
7878 "ix86_binary_operator_ok (AND, QImode, operands)
7879 && ix86_match_ccmode (insn,
7880 CONST_INT_P (operands[2])
7881 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7882 {
7883 if (which_alternative == 2)
7884 {
7885 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7886 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7887 return "and{l}\t{%2, %k0|%k0, %2}";
7888 }
7889 return "and{b}\t{%2, %0|%0, %2}";
7890 }
7891 [(set_attr "type" "alu")
7892 (set_attr "mode" "QI,QI,SI")])
7893
7894 (define_insn "*and<mode>_2"
7895 [(set (reg FLAGS_REG)
7896 (compare (and:SWI124
7897 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7898 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7899 (const_int 0)))
7900 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7901 (and:SWI124 (match_dup 1) (match_dup 2)))]
7902 "ix86_match_ccmode (insn, CCNOmode)
7903 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7904 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7905 [(set_attr "type" "alu")
7906 (set_attr "mode" "<MODE>")])
7907
7908 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7909 (define_insn "*andsi_2_zext"
7910 [(set (reg FLAGS_REG)
7911 (compare (and:SI
7912 (match_operand:SI 1 "nonimmediate_operand" "%0")
7913 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7914 (const_int 0)))
7915 (set (match_operand:DI 0 "register_operand" "=r")
7916 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7917 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7918 && ix86_binary_operator_ok (AND, SImode, operands)"
7919 "and{l}\t{%2, %k0|%k0, %2}"
7920 [(set_attr "type" "alu")
7921 (set_attr "mode" "SI")])
7922
7923 (define_insn "*andqi_2_slp"
7924 [(set (reg FLAGS_REG)
7925 (compare (and:QI
7926 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7927 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7928 (const_int 0)))
7929 (set (strict_low_part (match_dup 0))
7930 (and:QI (match_dup 0) (match_dup 1)))]
7931 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7932 && ix86_match_ccmode (insn, CCNOmode)
7933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7934 "and{b}\t{%1, %0|%0, %1}"
7935 [(set_attr "type" "alu1")
7936 (set_attr "mode" "QI")])
7937
7938 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7939 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7940 ;; for a QImode operand, which of course failed.
7941 (define_insn "andqi_ext_0"
7942 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7943 (const_int 8)
7944 (const_int 8))
7945 (and:SI
7946 (zero_extract:SI
7947 (match_operand 1 "ext_register_operand" "0")
7948 (const_int 8)
7949 (const_int 8))
7950 (match_operand 2 "const_int_operand" "n")))
7951 (clobber (reg:CC FLAGS_REG))]
7952 ""
7953 "and{b}\t{%2, %h0|%h0, %2}"
7954 [(set_attr "type" "alu")
7955 (set_attr "length_immediate" "1")
7956 (set_attr "modrm" "1")
7957 (set_attr "mode" "QI")])
7958
7959 ;; Generated by peephole translating test to and. This shows up
7960 ;; often in fp comparisons.
7961 (define_insn "*andqi_ext_0_cc"
7962 [(set (reg FLAGS_REG)
7963 (compare
7964 (and:SI
7965 (zero_extract:SI
7966 (match_operand 1 "ext_register_operand" "0")
7967 (const_int 8)
7968 (const_int 8))
7969 (match_operand 2 "const_int_operand" "n"))
7970 (const_int 0)))
7971 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7972 (const_int 8)
7973 (const_int 8))
7974 (and:SI
7975 (zero_extract:SI
7976 (match_dup 1)
7977 (const_int 8)
7978 (const_int 8))
7979 (match_dup 2)))]
7980 "ix86_match_ccmode (insn, CCNOmode)"
7981 "and{b}\t{%2, %h0|%h0, %2}"
7982 [(set_attr "type" "alu")
7983 (set_attr "length_immediate" "1")
7984 (set_attr "modrm" "1")
7985 (set_attr "mode" "QI")])
7986
7987 (define_insn "*andqi_ext_1_rex64"
7988 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7989 (const_int 8)
7990 (const_int 8))
7991 (and:SI
7992 (zero_extract:SI
7993 (match_operand 1 "ext_register_operand" "0")
7994 (const_int 8)
7995 (const_int 8))
7996 (zero_extend:SI
7997 (match_operand 2 "ext_register_operand" "Q"))))
7998 (clobber (reg:CC FLAGS_REG))]
7999 "TARGET_64BIT"
8000 "and{b}\t{%2, %h0|%h0, %2}"
8001 [(set_attr "type" "alu")
8002 (set_attr "length_immediate" "0")
8003 (set_attr "mode" "QI")])
8004
8005 (define_insn "*andqi_ext_1"
8006 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8007 (const_int 8)
8008 (const_int 8))
8009 (and:SI
8010 (zero_extract:SI
8011 (match_operand 1 "ext_register_operand" "0")
8012 (const_int 8)
8013 (const_int 8))
8014 (zero_extend:SI
8015 (match_operand:QI 2 "general_operand" "Qm"))))
8016 (clobber (reg:CC FLAGS_REG))]
8017 "!TARGET_64BIT"
8018 "and{b}\t{%2, %h0|%h0, %2}"
8019 [(set_attr "type" "alu")
8020 (set_attr "length_immediate" "0")
8021 (set_attr "mode" "QI")])
8022
8023 (define_insn "*andqi_ext_2"
8024 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8025 (const_int 8)
8026 (const_int 8))
8027 (and:SI
8028 (zero_extract:SI
8029 (match_operand 1 "ext_register_operand" "%0")
8030 (const_int 8)
8031 (const_int 8))
8032 (zero_extract:SI
8033 (match_operand 2 "ext_register_operand" "Q")
8034 (const_int 8)
8035 (const_int 8))))
8036 (clobber (reg:CC FLAGS_REG))]
8037 ""
8038 "and{b}\t{%h2, %h0|%h0, %h2}"
8039 [(set_attr "type" "alu")
8040 (set_attr "length_immediate" "0")
8041 (set_attr "mode" "QI")])
8042
8043 ;; Convert wide AND instructions with immediate operand to shorter QImode
8044 ;; equivalents when possible.
8045 ;; Don't do the splitting with memory operands, since it introduces risk
8046 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8047 ;; for size, but that can (should?) be handled by generic code instead.
8048 (define_split
8049 [(set (match_operand 0 "register_operand" "")
8050 (and (match_operand 1 "register_operand" "")
8051 (match_operand 2 "const_int_operand" "")))
8052 (clobber (reg:CC FLAGS_REG))]
8053 "reload_completed
8054 && QI_REG_P (operands[0])
8055 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8056 && !(~INTVAL (operands[2]) & ~(255 << 8))
8057 && GET_MODE (operands[0]) != QImode"
8058 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8059 (and:SI (zero_extract:SI (match_dup 1)
8060 (const_int 8) (const_int 8))
8061 (match_dup 2)))
8062 (clobber (reg:CC FLAGS_REG))])]
8063 {
8064 operands[0] = gen_lowpart (SImode, operands[0]);
8065 operands[1] = gen_lowpart (SImode, operands[1]);
8066 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8067 })
8068
8069 ;; Since AND can be encoded with sign extended immediate, this is only
8070 ;; profitable when 7th bit is not set.
8071 (define_split
8072 [(set (match_operand 0 "register_operand" "")
8073 (and (match_operand 1 "general_operand" "")
8074 (match_operand 2 "const_int_operand" "")))
8075 (clobber (reg:CC FLAGS_REG))]
8076 "reload_completed
8077 && ANY_QI_REG_P (operands[0])
8078 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8079 && !(~INTVAL (operands[2]) & ~255)
8080 && !(INTVAL (operands[2]) & 128)
8081 && GET_MODE (operands[0]) != QImode"
8082 [(parallel [(set (strict_low_part (match_dup 0))
8083 (and:QI (match_dup 1)
8084 (match_dup 2)))
8085 (clobber (reg:CC FLAGS_REG))])]
8086 {
8087 operands[0] = gen_lowpart (QImode, operands[0]);
8088 operands[1] = gen_lowpart (QImode, operands[1]);
8089 operands[2] = gen_lowpart (QImode, operands[2]);
8090 })
8091 \f
8092 ;; Logical inclusive and exclusive OR instructions
8093
8094 ;; %%% This used to optimize known byte-wide and operations to memory.
8095 ;; If this is considered useful, it should be done with splitters.
8096
8097 (define_expand "<code><mode>3"
8098 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8099 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8100 (match_operand:SWIM 2 "<general_operand>" "")))]
8101 ""
8102 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8103
8104 (define_insn "*<code><mode>_1"
8105 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8106 (any_or:SWI248
8107 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8108 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8109 (clobber (reg:CC FLAGS_REG))]
8110 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8111 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8112 [(set_attr "type" "alu")
8113 (set_attr "mode" "<MODE>")])
8114
8115 ;; %%% Potential partial reg stall on alternative 2. What to do?
8116 (define_insn "*<code>qi_1"
8117 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8118 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8119 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8120 (clobber (reg:CC FLAGS_REG))]
8121 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8122 "@
8123 <logic>{b}\t{%2, %0|%0, %2}
8124 <logic>{b}\t{%2, %0|%0, %2}
8125 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8126 [(set_attr "type" "alu")
8127 (set_attr "mode" "QI,QI,SI")])
8128
8129 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8130 (define_insn "*<code>si_1_zext"
8131 [(set (match_operand:DI 0 "register_operand" "=r")
8132 (zero_extend:DI
8133 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8134 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8137 "<logic>{l}\t{%2, %k0|%k0, %2}"
8138 [(set_attr "type" "alu")
8139 (set_attr "mode" "SI")])
8140
8141 (define_insn "*<code>si_1_zext_imm"
8142 [(set (match_operand:DI 0 "register_operand" "=r")
8143 (any_or:DI
8144 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8145 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8146 (clobber (reg:CC FLAGS_REG))]
8147 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8148 "<logic>{l}\t{%2, %k0|%k0, %2}"
8149 [(set_attr "type" "alu")
8150 (set_attr "mode" "SI")])
8151
8152 (define_insn "*<code>qi_1_slp"
8153 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8154 (any_or:QI (match_dup 0)
8155 (match_operand:QI 1 "general_operand" "qmn,qn")))
8156 (clobber (reg:CC FLAGS_REG))]
8157 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8158 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8159 "<logic>{b}\t{%1, %0|%0, %1}"
8160 [(set_attr "type" "alu1")
8161 (set_attr "mode" "QI")])
8162
8163 (define_insn "*<code><mode>_2"
8164 [(set (reg FLAGS_REG)
8165 (compare (any_or:SWI
8166 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8167 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8168 (const_int 0)))
8169 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8170 (any_or:SWI (match_dup 1) (match_dup 2)))]
8171 "ix86_match_ccmode (insn, CCNOmode)
8172 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8173 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8174 [(set_attr "type" "alu")
8175 (set_attr "mode" "<MODE>")])
8176
8177 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8178 ;; ??? Special case for immediate operand is missing - it is tricky.
8179 (define_insn "*<code>si_2_zext"
8180 [(set (reg FLAGS_REG)
8181 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8182 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8183 (const_int 0)))
8184 (set (match_operand:DI 0 "register_operand" "=r")
8185 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8186 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8187 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8188 "<logic>{l}\t{%2, %k0|%k0, %2}"
8189 [(set_attr "type" "alu")
8190 (set_attr "mode" "SI")])
8191
8192 (define_insn "*<code>si_2_zext_imm"
8193 [(set (reg FLAGS_REG)
8194 (compare (any_or:SI
8195 (match_operand:SI 1 "nonimmediate_operand" "%0")
8196 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8197 (const_int 0)))
8198 (set (match_operand:DI 0 "register_operand" "=r")
8199 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8200 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8201 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8202 "<logic>{l}\t{%2, %k0|%k0, %2}"
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "SI")])
8205
8206 (define_insn "*<code>qi_2_slp"
8207 [(set (reg FLAGS_REG)
8208 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8209 (match_operand:QI 1 "general_operand" "qmn,qn"))
8210 (const_int 0)))
8211 (set (strict_low_part (match_dup 0))
8212 (any_or:QI (match_dup 0) (match_dup 1)))]
8213 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8214 && ix86_match_ccmode (insn, CCNOmode)
8215 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8216 "<logic>{b}\t{%1, %0|%0, %1}"
8217 [(set_attr "type" "alu1")
8218 (set_attr "mode" "QI")])
8219
8220 (define_insn "*<code><mode>_3"
8221 [(set (reg FLAGS_REG)
8222 (compare (any_or:SWI
8223 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8224 (match_operand:SWI 2 "<general_operand>" "<g>"))
8225 (const_int 0)))
8226 (clobber (match_scratch:SWI 0 "=<r>"))]
8227 "ix86_match_ccmode (insn, CCNOmode)
8228 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8229 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8230 [(set_attr "type" "alu")
8231 (set_attr "mode" "<MODE>")])
8232
8233 (define_insn "*<code>qi_ext_0"
8234 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8235 (const_int 8)
8236 (const_int 8))
8237 (any_or:SI
8238 (zero_extract:SI
8239 (match_operand 1 "ext_register_operand" "0")
8240 (const_int 8)
8241 (const_int 8))
8242 (match_operand 2 "const_int_operand" "n")))
8243 (clobber (reg:CC FLAGS_REG))]
8244 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8245 "<logic>{b}\t{%2, %h0|%h0, %2}"
8246 [(set_attr "type" "alu")
8247 (set_attr "length_immediate" "1")
8248 (set_attr "modrm" "1")
8249 (set_attr "mode" "QI")])
8250
8251 (define_insn "*<code>qi_ext_1_rex64"
8252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253 (const_int 8)
8254 (const_int 8))
8255 (any_or:SI
8256 (zero_extract:SI
8257 (match_operand 1 "ext_register_operand" "0")
8258 (const_int 8)
8259 (const_int 8))
8260 (zero_extend:SI
8261 (match_operand 2 "ext_register_operand" "Q"))))
8262 (clobber (reg:CC FLAGS_REG))]
8263 "TARGET_64BIT
8264 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8265 "<logic>{b}\t{%2, %h0|%h0, %2}"
8266 [(set_attr "type" "alu")
8267 (set_attr "length_immediate" "0")
8268 (set_attr "mode" "QI")])
8269
8270 (define_insn "*<code>qi_ext_1"
8271 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272 (const_int 8)
8273 (const_int 8))
8274 (any_or:SI
8275 (zero_extract:SI
8276 (match_operand 1 "ext_register_operand" "0")
8277 (const_int 8)
8278 (const_int 8))
8279 (zero_extend:SI
8280 (match_operand:QI 2 "general_operand" "Qm"))))
8281 (clobber (reg:CC FLAGS_REG))]
8282 "!TARGET_64BIT
8283 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8284 "<logic>{b}\t{%2, %h0|%h0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "length_immediate" "0")
8287 (set_attr "mode" "QI")])
8288
8289 (define_insn "*<code>qi_ext_2"
8290 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8291 (const_int 8)
8292 (const_int 8))
8293 (any_or:SI
8294 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8295 (const_int 8)
8296 (const_int 8))
8297 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8298 (const_int 8)
8299 (const_int 8))))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8302 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "length_immediate" "0")
8305 (set_attr "mode" "QI")])
8306
8307 (define_split
8308 [(set (match_operand 0 "register_operand" "")
8309 (any_or (match_operand 1 "register_operand" "")
8310 (match_operand 2 "const_int_operand" "")))
8311 (clobber (reg:CC FLAGS_REG))]
8312 "reload_completed
8313 && QI_REG_P (operands[0])
8314 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8315 && !(INTVAL (operands[2]) & ~(255 << 8))
8316 && GET_MODE (operands[0]) != QImode"
8317 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8318 (any_or:SI (zero_extract:SI (match_dup 1)
8319 (const_int 8) (const_int 8))
8320 (match_dup 2)))
8321 (clobber (reg:CC FLAGS_REG))])]
8322 {
8323 operands[0] = gen_lowpart (SImode, operands[0]);
8324 operands[1] = gen_lowpart (SImode, operands[1]);
8325 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8326 })
8327
8328 ;; Since OR can be encoded with sign extended immediate, this is only
8329 ;; profitable when 7th bit is set.
8330 (define_split
8331 [(set (match_operand 0 "register_operand" "")
8332 (any_or (match_operand 1 "general_operand" "")
8333 (match_operand 2 "const_int_operand" "")))
8334 (clobber (reg:CC FLAGS_REG))]
8335 "reload_completed
8336 && ANY_QI_REG_P (operands[0])
8337 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8338 && !(INTVAL (operands[2]) & ~255)
8339 && (INTVAL (operands[2]) & 128)
8340 && GET_MODE (operands[0]) != QImode"
8341 [(parallel [(set (strict_low_part (match_dup 0))
8342 (any_or:QI (match_dup 1)
8343 (match_dup 2)))
8344 (clobber (reg:CC FLAGS_REG))])]
8345 {
8346 operands[0] = gen_lowpart (QImode, operands[0]);
8347 operands[1] = gen_lowpart (QImode, operands[1]);
8348 operands[2] = gen_lowpart (QImode, operands[2]);
8349 })
8350
8351 (define_expand "xorqi_cc_ext_1"
8352 [(parallel [
8353 (set (reg:CCNO FLAGS_REG)
8354 (compare:CCNO
8355 (xor:SI
8356 (zero_extract:SI
8357 (match_operand 1 "ext_register_operand" "")
8358 (const_int 8)
8359 (const_int 8))
8360 (match_operand:QI 2 "general_operand" ""))
8361 (const_int 0)))
8362 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8363 (const_int 8)
8364 (const_int 8))
8365 (xor:SI
8366 (zero_extract:SI
8367 (match_dup 1)
8368 (const_int 8)
8369 (const_int 8))
8370 (match_dup 2)))])])
8371
8372 (define_insn "*xorqi_cc_ext_1_rex64"
8373 [(set (reg FLAGS_REG)
8374 (compare
8375 (xor:SI
8376 (zero_extract:SI
8377 (match_operand 1 "ext_register_operand" "0")
8378 (const_int 8)
8379 (const_int 8))
8380 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8381 (const_int 0)))
8382 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8383 (const_int 8)
8384 (const_int 8))
8385 (xor:SI
8386 (zero_extract:SI
8387 (match_dup 1)
8388 (const_int 8)
8389 (const_int 8))
8390 (match_dup 2)))]
8391 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8392 "xor{b}\t{%2, %h0|%h0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "modrm" "1")
8395 (set_attr "mode" "QI")])
8396
8397 (define_insn "*xorqi_cc_ext_1"
8398 [(set (reg FLAGS_REG)
8399 (compare
8400 (xor:SI
8401 (zero_extract:SI
8402 (match_operand 1 "ext_register_operand" "0")
8403 (const_int 8)
8404 (const_int 8))
8405 (match_operand:QI 2 "general_operand" "qmn"))
8406 (const_int 0)))
8407 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8408 (const_int 8)
8409 (const_int 8))
8410 (xor:SI
8411 (zero_extract:SI
8412 (match_dup 1)
8413 (const_int 8)
8414 (const_int 8))
8415 (match_dup 2)))]
8416 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8417 "xor{b}\t{%2, %h0|%h0, %2}"
8418 [(set_attr "type" "alu")
8419 (set_attr "modrm" "1")
8420 (set_attr "mode" "QI")])
8421 \f
8422 ;; Negation instructions
8423
8424 (define_expand "neg<mode>2"
8425 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8426 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8427 ""
8428 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8429
8430 (define_insn_and_split "*neg<dwi>2_doubleword"
8431 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8432 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8433 (clobber (reg:CC FLAGS_REG))]
8434 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8435 "#"
8436 "reload_completed"
8437 [(parallel
8438 [(set (reg:CCZ FLAGS_REG)
8439 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8440 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8441 (parallel
8442 [(set (match_dup 2)
8443 (plus:DWIH (match_dup 3)
8444 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8445 (const_int 0))))
8446 (clobber (reg:CC FLAGS_REG))])
8447 (parallel
8448 [(set (match_dup 2)
8449 (neg:DWIH (match_dup 2)))
8450 (clobber (reg:CC FLAGS_REG))])]
8451 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8452
8453 (define_insn "*neg<mode>2_1"
8454 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8455 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8456 (clobber (reg:CC FLAGS_REG))]
8457 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8458 "neg{<imodesuffix>}\t%0"
8459 [(set_attr "type" "negnot")
8460 (set_attr "mode" "<MODE>")])
8461
8462 ;; Combine is quite creative about this pattern.
8463 (define_insn "*negsi2_1_zext"
8464 [(set (match_operand:DI 0 "register_operand" "=r")
8465 (lshiftrt:DI
8466 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8467 (const_int 32)))
8468 (const_int 32)))
8469 (clobber (reg:CC FLAGS_REG))]
8470 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8471 "neg{l}\t%k0"
8472 [(set_attr "type" "negnot")
8473 (set_attr "mode" "SI")])
8474
8475 ;; The problem with neg is that it does not perform (compare x 0),
8476 ;; it really performs (compare 0 x), which leaves us with the zero
8477 ;; flag being the only useful item.
8478
8479 (define_insn "*neg<mode>2_cmpz"
8480 [(set (reg:CCZ FLAGS_REG)
8481 (compare:CCZ
8482 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8483 (const_int 0)))
8484 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8485 (neg:SWI (match_dup 1)))]
8486 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8487 "neg{<imodesuffix>}\t%0"
8488 [(set_attr "type" "negnot")
8489 (set_attr "mode" "<MODE>")])
8490
8491 (define_insn "*negsi2_cmpz_zext"
8492 [(set (reg:CCZ FLAGS_REG)
8493 (compare:CCZ
8494 (lshiftrt:DI
8495 (neg:DI (ashift:DI
8496 (match_operand:DI 1 "register_operand" "0")
8497 (const_int 32)))
8498 (const_int 32))
8499 (const_int 0)))
8500 (set (match_operand:DI 0 "register_operand" "=r")
8501 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8502 (const_int 32)))
8503 (const_int 32)))]
8504 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8505 "neg{l}\t%k0"
8506 [(set_attr "type" "negnot")
8507 (set_attr "mode" "SI")])
8508
8509 ;; Changing of sign for FP values is doable using integer unit too.
8510
8511 (define_expand "<code><mode>2"
8512 [(set (match_operand:X87MODEF 0 "register_operand" "")
8513 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8514 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8515 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8516
8517 (define_insn "*absneg<mode>2_mixed"
8518 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8519 (match_operator:MODEF 3 "absneg_operator"
8520 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8521 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8522 (clobber (reg:CC FLAGS_REG))]
8523 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8524 "#")
8525
8526 (define_insn "*absneg<mode>2_sse"
8527 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8528 (match_operator:MODEF 3 "absneg_operator"
8529 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8530 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8531 (clobber (reg:CC FLAGS_REG))]
8532 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8533 "#")
8534
8535 (define_insn "*absneg<mode>2_i387"
8536 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8537 (match_operator:X87MODEF 3 "absneg_operator"
8538 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8539 (use (match_operand 2 "" ""))
8540 (clobber (reg:CC FLAGS_REG))]
8541 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8542 "#")
8543
8544 (define_expand "<code>tf2"
8545 [(set (match_operand:TF 0 "register_operand" "")
8546 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8547 "TARGET_SSE2"
8548 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8549
8550 (define_insn "*absnegtf2_sse"
8551 [(set (match_operand:TF 0 "register_operand" "=x,x")
8552 (match_operator:TF 3 "absneg_operator"
8553 [(match_operand:TF 1 "register_operand" "0,x")]))
8554 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8555 (clobber (reg:CC FLAGS_REG))]
8556 "TARGET_SSE2"
8557 "#")
8558
8559 ;; Splitters for fp abs and neg.
8560
8561 (define_split
8562 [(set (match_operand 0 "fp_register_operand" "")
8563 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8564 (use (match_operand 2 "" ""))
8565 (clobber (reg:CC FLAGS_REG))]
8566 "reload_completed"
8567 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8568
8569 (define_split
8570 [(set (match_operand 0 "register_operand" "")
8571 (match_operator 3 "absneg_operator"
8572 [(match_operand 1 "register_operand" "")]))
8573 (use (match_operand 2 "nonimmediate_operand" ""))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "reload_completed && SSE_REG_P (operands[0])"
8576 [(set (match_dup 0) (match_dup 3))]
8577 {
8578 enum machine_mode mode = GET_MODE (operands[0]);
8579 enum machine_mode vmode = GET_MODE (operands[2]);
8580 rtx tmp;
8581
8582 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8583 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8584 if (operands_match_p (operands[0], operands[2]))
8585 {
8586 tmp = operands[1];
8587 operands[1] = operands[2];
8588 operands[2] = tmp;
8589 }
8590 if (GET_CODE (operands[3]) == ABS)
8591 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8592 else
8593 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8594 operands[3] = tmp;
8595 })
8596
8597 (define_split
8598 [(set (match_operand:SF 0 "register_operand" "")
8599 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8600 (use (match_operand:V4SF 2 "" ""))
8601 (clobber (reg:CC FLAGS_REG))]
8602 "reload_completed"
8603 [(parallel [(set (match_dup 0) (match_dup 1))
8604 (clobber (reg:CC FLAGS_REG))])]
8605 {
8606 rtx tmp;
8607 operands[0] = gen_lowpart (SImode, operands[0]);
8608 if (GET_CODE (operands[1]) == ABS)
8609 {
8610 tmp = gen_int_mode (0x7fffffff, SImode);
8611 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8612 }
8613 else
8614 {
8615 tmp = gen_int_mode (0x80000000, SImode);
8616 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8617 }
8618 operands[1] = tmp;
8619 })
8620
8621 (define_split
8622 [(set (match_operand:DF 0 "register_operand" "")
8623 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8624 (use (match_operand 2 "" ""))
8625 (clobber (reg:CC FLAGS_REG))]
8626 "reload_completed"
8627 [(parallel [(set (match_dup 0) (match_dup 1))
8628 (clobber (reg:CC FLAGS_REG))])]
8629 {
8630 rtx tmp;
8631 if (TARGET_64BIT)
8632 {
8633 tmp = gen_lowpart (DImode, operands[0]);
8634 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8635 operands[0] = tmp;
8636
8637 if (GET_CODE (operands[1]) == ABS)
8638 tmp = const0_rtx;
8639 else
8640 tmp = gen_rtx_NOT (DImode, tmp);
8641 }
8642 else
8643 {
8644 operands[0] = gen_highpart (SImode, operands[0]);
8645 if (GET_CODE (operands[1]) == ABS)
8646 {
8647 tmp = gen_int_mode (0x7fffffff, SImode);
8648 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8649 }
8650 else
8651 {
8652 tmp = gen_int_mode (0x80000000, SImode);
8653 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8654 }
8655 }
8656 operands[1] = tmp;
8657 })
8658
8659 (define_split
8660 [(set (match_operand:XF 0 "register_operand" "")
8661 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8662 (use (match_operand 2 "" ""))
8663 (clobber (reg:CC FLAGS_REG))]
8664 "reload_completed"
8665 [(parallel [(set (match_dup 0) (match_dup 1))
8666 (clobber (reg:CC FLAGS_REG))])]
8667 {
8668 rtx tmp;
8669 operands[0] = gen_rtx_REG (SImode,
8670 true_regnum (operands[0])
8671 + (TARGET_64BIT ? 1 : 2));
8672 if (GET_CODE (operands[1]) == ABS)
8673 {
8674 tmp = GEN_INT (0x7fff);
8675 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8676 }
8677 else
8678 {
8679 tmp = GEN_INT (0x8000);
8680 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8681 }
8682 operands[1] = tmp;
8683 })
8684
8685 ;; Conditionalize these after reload. If they match before reload, we
8686 ;; lose the clobber and ability to use integer instructions.
8687
8688 (define_insn "*<code><mode>2_1"
8689 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8690 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8691 "TARGET_80387
8692 && (reload_completed
8693 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8694 "f<absneg_mnemonic>"
8695 [(set_attr "type" "fsgn")
8696 (set_attr "mode" "<MODE>")])
8697
8698 (define_insn "*<code>extendsfdf2"
8699 [(set (match_operand:DF 0 "register_operand" "=f")
8700 (absneg:DF (float_extend:DF
8701 (match_operand:SF 1 "register_operand" "0"))))]
8702 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8703 "f<absneg_mnemonic>"
8704 [(set_attr "type" "fsgn")
8705 (set_attr "mode" "DF")])
8706
8707 (define_insn "*<code>extendsfxf2"
8708 [(set (match_operand:XF 0 "register_operand" "=f")
8709 (absneg:XF (float_extend:XF
8710 (match_operand:SF 1 "register_operand" "0"))))]
8711 "TARGET_80387"
8712 "f<absneg_mnemonic>"
8713 [(set_attr "type" "fsgn")
8714 (set_attr "mode" "XF")])
8715
8716 (define_insn "*<code>extenddfxf2"
8717 [(set (match_operand:XF 0 "register_operand" "=f")
8718 (absneg:XF (float_extend:XF
8719 (match_operand:DF 1 "register_operand" "0"))))]
8720 "TARGET_80387"
8721 "f<absneg_mnemonic>"
8722 [(set_attr "type" "fsgn")
8723 (set_attr "mode" "XF")])
8724
8725 ;; Copysign instructions
8726
8727 (define_mode_iterator CSGNMODE [SF DF TF])
8728 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8729
8730 (define_expand "copysign<mode>3"
8731 [(match_operand:CSGNMODE 0 "register_operand" "")
8732 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8733 (match_operand:CSGNMODE 2 "register_operand" "")]
8734 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8735 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8736 "ix86_expand_copysign (operands); DONE;")
8737
8738 (define_insn_and_split "copysign<mode>3_const"
8739 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8740 (unspec:CSGNMODE
8741 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8742 (match_operand:CSGNMODE 2 "register_operand" "0")
8743 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8744 UNSPEC_COPYSIGN))]
8745 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8746 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8747 "#"
8748 "&& reload_completed"
8749 [(const_int 0)]
8750 "ix86_split_copysign_const (operands); DONE;")
8751
8752 (define_insn "copysign<mode>3_var"
8753 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8754 (unspec:CSGNMODE
8755 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8756 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8757 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8758 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8759 UNSPEC_COPYSIGN))
8760 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8761 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8762 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8763 "#")
8764
8765 (define_split
8766 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8767 (unspec:CSGNMODE
8768 [(match_operand:CSGNMODE 2 "register_operand" "")
8769 (match_operand:CSGNMODE 3 "register_operand" "")
8770 (match_operand:<CSGNVMODE> 4 "" "")
8771 (match_operand:<CSGNVMODE> 5 "" "")]
8772 UNSPEC_COPYSIGN))
8773 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8774 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8775 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8776 && reload_completed"
8777 [(const_int 0)]
8778 "ix86_split_copysign_var (operands); DONE;")
8779 \f
8780 ;; One complement instructions
8781
8782 (define_expand "one_cmpl<mode>2"
8783 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8784 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8785 ""
8786 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8787
8788 (define_insn "*one_cmpl<mode>2_1"
8789 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8790 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8791 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8792 "not{<imodesuffix>}\t%0"
8793 [(set_attr "type" "negnot")
8794 (set_attr "mode" "<MODE>")])
8795
8796 ;; %%% Potential partial reg stall on alternative 1. What to do?
8797 (define_insn "*one_cmplqi2_1"
8798 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8799 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8800 "ix86_unary_operator_ok (NOT, QImode, operands)"
8801 "@
8802 not{b}\t%0
8803 not{l}\t%k0"
8804 [(set_attr "type" "negnot")
8805 (set_attr "mode" "QI,SI")])
8806
8807 ;; ??? Currently never generated - xor is used instead.
8808 (define_insn "*one_cmplsi2_1_zext"
8809 [(set (match_operand:DI 0 "register_operand" "=r")
8810 (zero_extend:DI
8811 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8812 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8813 "not{l}\t%k0"
8814 [(set_attr "type" "negnot")
8815 (set_attr "mode" "SI")])
8816
8817 (define_insn "*one_cmpl<mode>2_2"
8818 [(set (reg FLAGS_REG)
8819 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8820 (const_int 0)))
8821 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8822 (not:SWI (match_dup 1)))]
8823 "ix86_match_ccmode (insn, CCNOmode)
8824 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8825 "#"
8826 [(set_attr "type" "alu1")
8827 (set_attr "mode" "<MODE>")])
8828
8829 (define_split
8830 [(set (match_operand 0 "flags_reg_operand" "")
8831 (match_operator 2 "compare_operator"
8832 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8833 (const_int 0)]))
8834 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8835 (not:SWI (match_dup 3)))]
8836 "ix86_match_ccmode (insn, CCNOmode)"
8837 [(parallel [(set (match_dup 0)
8838 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8839 (const_int 0)]))
8840 (set (match_dup 1)
8841 (xor:SWI (match_dup 3) (const_int -1)))])])
8842
8843 ;; ??? Currently never generated - xor is used instead.
8844 (define_insn "*one_cmplsi2_2_zext"
8845 [(set (reg FLAGS_REG)
8846 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8847 (const_int 0)))
8848 (set (match_operand:DI 0 "register_operand" "=r")
8849 (zero_extend:DI (not:SI (match_dup 1))))]
8850 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8851 && ix86_unary_operator_ok (NOT, SImode, operands)"
8852 "#"
8853 [(set_attr "type" "alu1")
8854 (set_attr "mode" "SI")])
8855
8856 (define_split
8857 [(set (match_operand 0 "flags_reg_operand" "")
8858 (match_operator 2 "compare_operator"
8859 [(not:SI (match_operand:SI 3 "register_operand" ""))
8860 (const_int 0)]))
8861 (set (match_operand:DI 1 "register_operand" "")
8862 (zero_extend:DI (not:SI (match_dup 3))))]
8863 "ix86_match_ccmode (insn, CCNOmode)"
8864 [(parallel [(set (match_dup 0)
8865 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8866 (const_int 0)]))
8867 (set (match_dup 1)
8868 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8869 \f
8870 ;; Shift instructions
8871
8872 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8873 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8874 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8875 ;; from the assembler input.
8876 ;;
8877 ;; This instruction shifts the target reg/mem as usual, but instead of
8878 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8879 ;; is a left shift double, bits are taken from the high order bits of
8880 ;; reg, else if the insn is a shift right double, bits are taken from the
8881 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8882 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8883 ;;
8884 ;; Since sh[lr]d does not change the `reg' operand, that is done
8885 ;; separately, making all shifts emit pairs of shift double and normal
8886 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8887 ;; support a 63 bit shift, each shift where the count is in a reg expands
8888 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8889 ;;
8890 ;; If the shift count is a constant, we need never emit more than one
8891 ;; shift pair, instead using moves and sign extension for counts greater
8892 ;; than 31.
8893
8894 (define_expand "ashl<mode>3"
8895 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8896 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8897 (match_operand:QI 2 "nonmemory_operand" "")))]
8898 ""
8899 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8900
8901 (define_insn "*ashl<mode>3_doubleword"
8902 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8903 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8904 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8905 (clobber (reg:CC FLAGS_REG))]
8906 ""
8907 "#"
8908 [(set_attr "type" "multi")])
8909
8910 (define_split
8911 [(set (match_operand:DWI 0 "register_operand" "")
8912 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8913 (match_operand:QI 2 "nonmemory_operand" "")))
8914 (clobber (reg:CC FLAGS_REG))]
8915 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8916 [(const_int 0)]
8917 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8918
8919 ;; By default we don't ask for a scratch register, because when DWImode
8920 ;; values are manipulated, registers are already at a premium. But if
8921 ;; we have one handy, we won't turn it away.
8922
8923 (define_peephole2
8924 [(match_scratch:DWIH 3 "r")
8925 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8926 (ashift:<DWI>
8927 (match_operand:<DWI> 1 "nonmemory_operand" "")
8928 (match_operand:QI 2 "nonmemory_operand" "")))
8929 (clobber (reg:CC FLAGS_REG))])
8930 (match_dup 3)]
8931 "TARGET_CMOVE"
8932 [(const_int 0)]
8933 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8934
8935 (define_insn "x86_64_shld"
8936 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8937 (ior:DI (ashift:DI (match_dup 0)
8938 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8939 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8940 (minus:QI (const_int 64) (match_dup 2)))))
8941 (clobber (reg:CC FLAGS_REG))]
8942 "TARGET_64BIT"
8943 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8944 [(set_attr "type" "ishift")
8945 (set_attr "prefix_0f" "1")
8946 (set_attr "mode" "DI")
8947 (set_attr "athlon_decode" "vector")
8948 (set_attr "amdfam10_decode" "vector")
8949 (set_attr "bdver1_decode" "vector")])
8950
8951 (define_insn "x86_shld"
8952 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8953 (ior:SI (ashift:SI (match_dup 0)
8954 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8955 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8956 (minus:QI (const_int 32) (match_dup 2)))))
8957 (clobber (reg:CC FLAGS_REG))]
8958 ""
8959 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8960 [(set_attr "type" "ishift")
8961 (set_attr "prefix_0f" "1")
8962 (set_attr "mode" "SI")
8963 (set_attr "pent_pair" "np")
8964 (set_attr "athlon_decode" "vector")
8965 (set_attr "amdfam10_decode" "vector")
8966 (set_attr "bdver1_decode" "vector")])
8967
8968 (define_expand "x86_shift<mode>_adj_1"
8969 [(set (reg:CCZ FLAGS_REG)
8970 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8971 (match_dup 4))
8972 (const_int 0)))
8973 (set (match_operand:SWI48 0 "register_operand" "")
8974 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8975 (match_operand:SWI48 1 "register_operand" "")
8976 (match_dup 0)))
8977 (set (match_dup 1)
8978 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8979 (match_operand:SWI48 3 "register_operand" "")
8980 (match_dup 1)))]
8981 "TARGET_CMOVE"
8982 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8983
8984 (define_expand "x86_shift<mode>_adj_2"
8985 [(use (match_operand:SWI48 0 "register_operand" ""))
8986 (use (match_operand:SWI48 1 "register_operand" ""))
8987 (use (match_operand:QI 2 "register_operand" ""))]
8988 ""
8989 {
8990 rtx label = gen_label_rtx ();
8991 rtx tmp;
8992
8993 emit_insn (gen_testqi_ccz_1 (operands[2],
8994 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8995
8996 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8997 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8998 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8999 gen_rtx_LABEL_REF (VOIDmode, label),
9000 pc_rtx);
9001 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9002 JUMP_LABEL (tmp) = label;
9003
9004 emit_move_insn (operands[0], operands[1]);
9005 ix86_expand_clear (operands[1]);
9006
9007 emit_label (label);
9008 LABEL_NUSES (label) = 1;
9009
9010 DONE;
9011 })
9012
9013 ;; Avoid useless masking of count operand.
9014 (define_insn_and_split "*ashl<mode>3_mask"
9015 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9016 (ashift:SWI48
9017 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9018 (subreg:QI
9019 (and:SI
9020 (match_operand:SI 2 "nonimmediate_operand" "c")
9021 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9024 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9025 == GET_MODE_BITSIZE (<MODE>mode)-1"
9026 "#"
9027 "&& 1"
9028 [(parallel [(set (match_dup 0)
9029 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9030 (clobber (reg:CC FLAGS_REG))])]
9031 {
9032 if (can_create_pseudo_p ())
9033 operands [2] = force_reg (SImode, operands[2]);
9034
9035 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9036 }
9037 [(set_attr "type" "ishift")
9038 (set_attr "mode" "<MODE>")])
9039
9040 (define_insn "*bmi2_ashl<mode>3_1"
9041 [(set (match_operand:SWI48 0 "register_operand" "=r")
9042 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9043 (match_operand:SWI48 2 "register_operand" "r")))]
9044 "TARGET_BMI2"
9045 "shlx\t{%2, %1, %0|%0, %1, %2}"
9046 [(set_attr "type" "ishiftx")
9047 (set_attr "mode" "<MODE>")])
9048
9049 (define_insn "*ashl<mode>3_1"
9050 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9051 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9052 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9055 {
9056 switch (get_attr_type (insn))
9057 {
9058 case TYPE_LEA:
9059 case TYPE_ISHIFTX:
9060 return "#";
9061
9062 case TYPE_ALU:
9063 gcc_assert (operands[2] == const1_rtx);
9064 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9065 return "add{<imodesuffix>}\t%0, %0";
9066
9067 default:
9068 if (operands[2] == const1_rtx
9069 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9070 return "sal{<imodesuffix>}\t%0";
9071 else
9072 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9073 }
9074 }
9075 [(set_attr "isa" "*,*,bmi2")
9076 (set (attr "type")
9077 (cond [(eq_attr "alternative" "1")
9078 (const_string "lea")
9079 (eq_attr "alternative" "2")
9080 (const_string "ishiftx")
9081 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9082 (match_operand 0 "register_operand" ""))
9083 (match_operand 2 "const1_operand" ""))
9084 (const_string "alu")
9085 ]
9086 (const_string "ishift")))
9087 (set (attr "length_immediate")
9088 (if_then_else
9089 (ior (eq_attr "type" "alu")
9090 (and (eq_attr "type" "ishift")
9091 (and (match_operand 2 "const1_operand" "")
9092 (ior (match_test "TARGET_SHIFT1")
9093 (match_test "optimize_function_for_size_p (cfun)")))))
9094 (const_string "0")
9095 (const_string "*")))
9096 (set_attr "mode" "<MODE>")])
9097
9098 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9099 (define_split
9100 [(set (match_operand:SWI48 0 "register_operand" "")
9101 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9102 (match_operand:QI 2 "register_operand" "")))
9103 (clobber (reg:CC FLAGS_REG))]
9104 "TARGET_BMI2 && reload_completed"
9105 [(set (match_dup 0)
9106 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9107 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9108
9109 (define_insn "*bmi2_ashlsi3_1_zext"
9110 [(set (match_operand:DI 0 "register_operand" "=r")
9111 (zero_extend:DI
9112 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9113 (match_operand:SI 2 "register_operand" "r"))))]
9114 "TARGET_64BIT && TARGET_BMI2"
9115 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9116 [(set_attr "type" "ishiftx")
9117 (set_attr "mode" "SI")])
9118
9119 (define_insn "*ashlsi3_1_zext"
9120 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9121 (zero_extend:DI
9122 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9123 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9126 {
9127 switch (get_attr_type (insn))
9128 {
9129 case TYPE_LEA:
9130 case TYPE_ISHIFTX:
9131 return "#";
9132
9133 case TYPE_ALU:
9134 gcc_assert (operands[2] == const1_rtx);
9135 return "add{l}\t%k0, %k0";
9136
9137 default:
9138 if (operands[2] == const1_rtx
9139 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9140 return "sal{l}\t%k0";
9141 else
9142 return "sal{l}\t{%2, %k0|%k0, %2}";
9143 }
9144 }
9145 [(set_attr "isa" "*,*,bmi2")
9146 (set (attr "type")
9147 (cond [(eq_attr "alternative" "1")
9148 (const_string "lea")
9149 (eq_attr "alternative" "2")
9150 (const_string "ishiftx")
9151 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9152 (match_operand 2 "const1_operand" ""))
9153 (const_string "alu")
9154 ]
9155 (const_string "ishift")))
9156 (set (attr "length_immediate")
9157 (if_then_else
9158 (ior (eq_attr "type" "alu")
9159 (and (eq_attr "type" "ishift")
9160 (and (match_operand 2 "const1_operand" "")
9161 (ior (match_test "TARGET_SHIFT1")
9162 (match_test "optimize_function_for_size_p (cfun)")))))
9163 (const_string "0")
9164 (const_string "*")))
9165 (set_attr "mode" "SI")])
9166
9167 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9168 (define_split
9169 [(set (match_operand:DI 0 "register_operand" "")
9170 (zero_extend:DI
9171 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9172 (match_operand:QI 2 "register_operand" ""))))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9175 [(set (match_dup 0)
9176 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9177 "operands[2] = gen_lowpart (SImode, operands[2]);")
9178
9179 (define_insn "*ashlhi3_1"
9180 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9181 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9182 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9183 (clobber (reg:CC FLAGS_REG))]
9184 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9185 {
9186 switch (get_attr_type (insn))
9187 {
9188 case TYPE_LEA:
9189 return "#";
9190
9191 case TYPE_ALU:
9192 gcc_assert (operands[2] == const1_rtx);
9193 return "add{w}\t%0, %0";
9194
9195 default:
9196 if (operands[2] == const1_rtx
9197 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9198 return "sal{w}\t%0";
9199 else
9200 return "sal{w}\t{%2, %0|%0, %2}";
9201 }
9202 }
9203 [(set (attr "type")
9204 (cond [(eq_attr "alternative" "1")
9205 (const_string "lea")
9206 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9207 (match_operand 0 "register_operand" ""))
9208 (match_operand 2 "const1_operand" ""))
9209 (const_string "alu")
9210 ]
9211 (const_string "ishift")))
9212 (set (attr "length_immediate")
9213 (if_then_else
9214 (ior (eq_attr "type" "alu")
9215 (and (eq_attr "type" "ishift")
9216 (and (match_operand 2 "const1_operand" "")
9217 (ior (match_test "TARGET_SHIFT1")
9218 (match_test "optimize_function_for_size_p (cfun)")))))
9219 (const_string "0")
9220 (const_string "*")))
9221 (set_attr "mode" "HI,SI")])
9222
9223 ;; %%% Potential partial reg stall on alternative 1. What to do?
9224 (define_insn "*ashlqi3_1"
9225 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9226 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9227 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9228 (clobber (reg:CC FLAGS_REG))]
9229 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9230 {
9231 switch (get_attr_type (insn))
9232 {
9233 case TYPE_LEA:
9234 return "#";
9235
9236 case TYPE_ALU:
9237 gcc_assert (operands[2] == const1_rtx);
9238 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9239 return "add{l}\t%k0, %k0";
9240 else
9241 return "add{b}\t%0, %0";
9242
9243 default:
9244 if (operands[2] == const1_rtx
9245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9246 {
9247 if (get_attr_mode (insn) == MODE_SI)
9248 return "sal{l}\t%k0";
9249 else
9250 return "sal{b}\t%0";
9251 }
9252 else
9253 {
9254 if (get_attr_mode (insn) == MODE_SI)
9255 return "sal{l}\t{%2, %k0|%k0, %2}";
9256 else
9257 return "sal{b}\t{%2, %0|%0, %2}";
9258 }
9259 }
9260 }
9261 [(set (attr "type")
9262 (cond [(eq_attr "alternative" "2")
9263 (const_string "lea")
9264 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9265 (match_operand 0 "register_operand" ""))
9266 (match_operand 2 "const1_operand" ""))
9267 (const_string "alu")
9268 ]
9269 (const_string "ishift")))
9270 (set (attr "length_immediate")
9271 (if_then_else
9272 (ior (eq_attr "type" "alu")
9273 (and (eq_attr "type" "ishift")
9274 (and (match_operand 2 "const1_operand" "")
9275 (ior (match_test "TARGET_SHIFT1")
9276 (match_test "optimize_function_for_size_p (cfun)")))))
9277 (const_string "0")
9278 (const_string "*")))
9279 (set_attr "mode" "QI,SI,SI")])
9280
9281 (define_insn "*ashlqi3_1_slp"
9282 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9283 (ashift:QI (match_dup 0)
9284 (match_operand:QI 1 "nonmemory_operand" "cI")))
9285 (clobber (reg:CC FLAGS_REG))]
9286 "(optimize_function_for_size_p (cfun)
9287 || !TARGET_PARTIAL_FLAG_REG_STALL
9288 || (operands[1] == const1_rtx
9289 && (TARGET_SHIFT1
9290 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9291 {
9292 switch (get_attr_type (insn))
9293 {
9294 case TYPE_ALU:
9295 gcc_assert (operands[1] == const1_rtx);
9296 return "add{b}\t%0, %0";
9297
9298 default:
9299 if (operands[1] == const1_rtx
9300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9301 return "sal{b}\t%0";
9302 else
9303 return "sal{b}\t{%1, %0|%0, %1}";
9304 }
9305 }
9306 [(set (attr "type")
9307 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9308 (match_operand 0 "register_operand" ""))
9309 (match_operand 1 "const1_operand" ""))
9310 (const_string "alu")
9311 ]
9312 (const_string "ishift1")))
9313 (set (attr "length_immediate")
9314 (if_then_else
9315 (ior (eq_attr "type" "alu")
9316 (and (eq_attr "type" "ishift1")
9317 (and (match_operand 1 "const1_operand" "")
9318 (ior (match_test "TARGET_SHIFT1")
9319 (match_test "optimize_function_for_size_p (cfun)")))))
9320 (const_string "0")
9321 (const_string "*")))
9322 (set_attr "mode" "QI")])
9323
9324 ;; Convert ashift to the lea pattern to avoid flags dependency.
9325 (define_split
9326 [(set (match_operand 0 "register_operand" "")
9327 (ashift (match_operand 1 "index_register_operand" "")
9328 (match_operand:QI 2 "const_int_operand" "")))
9329 (clobber (reg:CC FLAGS_REG))]
9330 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9331 && reload_completed
9332 && true_regnum (operands[0]) != true_regnum (operands[1])"
9333 [(const_int 0)]
9334 {
9335 enum machine_mode mode = GET_MODE (operands[0]);
9336 rtx pat;
9337
9338 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9339 {
9340 mode = SImode;
9341 operands[0] = gen_lowpart (mode, operands[0]);
9342 operands[1] = gen_lowpart (mode, operands[1]);
9343 }
9344
9345 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9346
9347 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9348
9349 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9350 DONE;
9351 })
9352
9353 ;; Convert ashift to the lea pattern to avoid flags dependency.
9354 (define_split
9355 [(set (match_operand:DI 0 "register_operand" "")
9356 (zero_extend:DI
9357 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9358 (match_operand:QI 2 "const_int_operand" ""))))
9359 (clobber (reg:CC FLAGS_REG))]
9360 "TARGET_64BIT && reload_completed
9361 && true_regnum (operands[0]) != true_regnum (operands[1])"
9362 [(set (match_dup 0)
9363 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9364 {
9365 operands[1] = gen_lowpart (DImode, operands[1]);
9366 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9367 })
9368
9369 ;; This pattern can't accept a variable shift count, since shifts by
9370 ;; zero don't affect the flags. We assume that shifts by constant
9371 ;; zero are optimized away.
9372 (define_insn "*ashl<mode>3_cmp"
9373 [(set (reg FLAGS_REG)
9374 (compare
9375 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9376 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9377 (const_int 0)))
9378 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9379 (ashift:SWI (match_dup 1) (match_dup 2)))]
9380 "(optimize_function_for_size_p (cfun)
9381 || !TARGET_PARTIAL_FLAG_REG_STALL
9382 || (operands[2] == const1_rtx
9383 && (TARGET_SHIFT1
9384 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9385 && ix86_match_ccmode (insn, CCGOCmode)
9386 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9387 {
9388 switch (get_attr_type (insn))
9389 {
9390 case TYPE_ALU:
9391 gcc_assert (operands[2] == const1_rtx);
9392 return "add{<imodesuffix>}\t%0, %0";
9393
9394 default:
9395 if (operands[2] == const1_rtx
9396 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9397 return "sal{<imodesuffix>}\t%0";
9398 else
9399 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9400 }
9401 }
9402 [(set (attr "type")
9403 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9404 (match_operand 0 "register_operand" ""))
9405 (match_operand 2 "const1_operand" ""))
9406 (const_string "alu")
9407 ]
9408 (const_string "ishift")))
9409 (set (attr "length_immediate")
9410 (if_then_else
9411 (ior (eq_attr "type" "alu")
9412 (and (eq_attr "type" "ishift")
9413 (and (match_operand 2 "const1_operand" "")
9414 (ior (match_test "TARGET_SHIFT1")
9415 (match_test "optimize_function_for_size_p (cfun)")))))
9416 (const_string "0")
9417 (const_string "*")))
9418 (set_attr "mode" "<MODE>")])
9419
9420 (define_insn "*ashlsi3_cmp_zext"
9421 [(set (reg FLAGS_REG)
9422 (compare
9423 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9424 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9425 (const_int 0)))
9426 (set (match_operand:DI 0 "register_operand" "=r")
9427 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9428 "TARGET_64BIT
9429 && (optimize_function_for_size_p (cfun)
9430 || !TARGET_PARTIAL_FLAG_REG_STALL
9431 || (operands[2] == const1_rtx
9432 && (TARGET_SHIFT1
9433 || TARGET_DOUBLE_WITH_ADD)))
9434 && ix86_match_ccmode (insn, CCGOCmode)
9435 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9436 {
9437 switch (get_attr_type (insn))
9438 {
9439 case TYPE_ALU:
9440 gcc_assert (operands[2] == const1_rtx);
9441 return "add{l}\t%k0, %k0";
9442
9443 default:
9444 if (operands[2] == const1_rtx
9445 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9446 return "sal{l}\t%k0";
9447 else
9448 return "sal{l}\t{%2, %k0|%k0, %2}";
9449 }
9450 }
9451 [(set (attr "type")
9452 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9453 (match_operand 2 "const1_operand" ""))
9454 (const_string "alu")
9455 ]
9456 (const_string "ishift")))
9457 (set (attr "length_immediate")
9458 (if_then_else
9459 (ior (eq_attr "type" "alu")
9460 (and (eq_attr "type" "ishift")
9461 (and (match_operand 2 "const1_operand" "")
9462 (ior (match_test "TARGET_SHIFT1")
9463 (match_test "optimize_function_for_size_p (cfun)")))))
9464 (const_string "0")
9465 (const_string "*")))
9466 (set_attr "mode" "SI")])
9467
9468 (define_insn "*ashl<mode>3_cconly"
9469 [(set (reg FLAGS_REG)
9470 (compare
9471 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9472 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9473 (const_int 0)))
9474 (clobber (match_scratch:SWI 0 "=<r>"))]
9475 "(optimize_function_for_size_p (cfun)
9476 || !TARGET_PARTIAL_FLAG_REG_STALL
9477 || (operands[2] == const1_rtx
9478 && (TARGET_SHIFT1
9479 || TARGET_DOUBLE_WITH_ADD)))
9480 && ix86_match_ccmode (insn, CCGOCmode)"
9481 {
9482 switch (get_attr_type (insn))
9483 {
9484 case TYPE_ALU:
9485 gcc_assert (operands[2] == const1_rtx);
9486 return "add{<imodesuffix>}\t%0, %0";
9487
9488 default:
9489 if (operands[2] == const1_rtx
9490 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9491 return "sal{<imodesuffix>}\t%0";
9492 else
9493 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9494 }
9495 }
9496 [(set (attr "type")
9497 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9498 (match_operand 0 "register_operand" ""))
9499 (match_operand 2 "const1_operand" ""))
9500 (const_string "alu")
9501 ]
9502 (const_string "ishift")))
9503 (set (attr "length_immediate")
9504 (if_then_else
9505 (ior (eq_attr "type" "alu")
9506 (and (eq_attr "type" "ishift")
9507 (and (match_operand 2 "const1_operand" "")
9508 (ior (match_test "TARGET_SHIFT1")
9509 (match_test "optimize_function_for_size_p (cfun)")))))
9510 (const_string "0")
9511 (const_string "*")))
9512 (set_attr "mode" "<MODE>")])
9513
9514 ;; See comment above `ashl<mode>3' about how this works.
9515
9516 (define_expand "<shift_insn><mode>3"
9517 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9518 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9519 (match_operand:QI 2 "nonmemory_operand" "")))]
9520 ""
9521 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9522
9523 ;; Avoid useless masking of count operand.
9524 (define_insn_and_split "*<shift_insn><mode>3_mask"
9525 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9526 (any_shiftrt:SWI48
9527 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9528 (subreg:QI
9529 (and:SI
9530 (match_operand:SI 2 "nonimmediate_operand" "c")
9531 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9532 (clobber (reg:CC FLAGS_REG))]
9533 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9534 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9535 == GET_MODE_BITSIZE (<MODE>mode)-1"
9536 "#"
9537 "&& 1"
9538 [(parallel [(set (match_dup 0)
9539 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9540 (clobber (reg:CC FLAGS_REG))])]
9541 {
9542 if (can_create_pseudo_p ())
9543 operands [2] = force_reg (SImode, operands[2]);
9544
9545 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9546 }
9547 [(set_attr "type" "ishift")
9548 (set_attr "mode" "<MODE>")])
9549
9550 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9551 [(set (match_operand:DWI 0 "register_operand" "=r")
9552 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9553 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9554 (clobber (reg:CC FLAGS_REG))]
9555 ""
9556 "#"
9557 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9558 [(const_int 0)]
9559 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9560 [(set_attr "type" "multi")])
9561
9562 ;; By default we don't ask for a scratch register, because when DWImode
9563 ;; values are manipulated, registers are already at a premium. But if
9564 ;; we have one handy, we won't turn it away.
9565
9566 (define_peephole2
9567 [(match_scratch:DWIH 3 "r")
9568 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9569 (any_shiftrt:<DWI>
9570 (match_operand:<DWI> 1 "register_operand" "")
9571 (match_operand:QI 2 "nonmemory_operand" "")))
9572 (clobber (reg:CC FLAGS_REG))])
9573 (match_dup 3)]
9574 "TARGET_CMOVE"
9575 [(const_int 0)]
9576 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9577
9578 (define_insn "x86_64_shrd"
9579 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9580 (ior:DI (ashiftrt:DI (match_dup 0)
9581 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9582 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9583 (minus:QI (const_int 64) (match_dup 2)))))
9584 (clobber (reg:CC FLAGS_REG))]
9585 "TARGET_64BIT"
9586 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9587 [(set_attr "type" "ishift")
9588 (set_attr "prefix_0f" "1")
9589 (set_attr "mode" "DI")
9590 (set_attr "athlon_decode" "vector")
9591 (set_attr "amdfam10_decode" "vector")
9592 (set_attr "bdver1_decode" "vector")])
9593
9594 (define_insn "x86_shrd"
9595 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9596 (ior:SI (ashiftrt:SI (match_dup 0)
9597 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9598 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9599 (minus:QI (const_int 32) (match_dup 2)))))
9600 (clobber (reg:CC FLAGS_REG))]
9601 ""
9602 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9603 [(set_attr "type" "ishift")
9604 (set_attr "prefix_0f" "1")
9605 (set_attr "mode" "SI")
9606 (set_attr "pent_pair" "np")
9607 (set_attr "athlon_decode" "vector")
9608 (set_attr "amdfam10_decode" "vector")
9609 (set_attr "bdver1_decode" "vector")])
9610
9611 (define_insn "ashrdi3_cvt"
9612 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9613 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9614 (match_operand:QI 2 "const_int_operand" "")))
9615 (clobber (reg:CC FLAGS_REG))]
9616 "TARGET_64BIT && INTVAL (operands[2]) == 63
9617 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9618 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9619 "@
9620 {cqto|cqo}
9621 sar{q}\t{%2, %0|%0, %2}"
9622 [(set_attr "type" "imovx,ishift")
9623 (set_attr "prefix_0f" "0,*")
9624 (set_attr "length_immediate" "0,*")
9625 (set_attr "modrm" "0,1")
9626 (set_attr "mode" "DI")])
9627
9628 (define_insn "ashrsi3_cvt"
9629 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9630 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9631 (match_operand:QI 2 "const_int_operand" "")))
9632 (clobber (reg:CC FLAGS_REG))]
9633 "INTVAL (operands[2]) == 31
9634 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9635 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9636 "@
9637 {cltd|cdq}
9638 sar{l}\t{%2, %0|%0, %2}"
9639 [(set_attr "type" "imovx,ishift")
9640 (set_attr "prefix_0f" "0,*")
9641 (set_attr "length_immediate" "0,*")
9642 (set_attr "modrm" "0,1")
9643 (set_attr "mode" "SI")])
9644
9645 (define_insn "*ashrsi3_cvt_zext"
9646 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9647 (zero_extend:DI
9648 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9649 (match_operand:QI 2 "const_int_operand" ""))))
9650 (clobber (reg:CC FLAGS_REG))]
9651 "TARGET_64BIT && INTVAL (operands[2]) == 31
9652 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9653 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9654 "@
9655 {cltd|cdq}
9656 sar{l}\t{%2, %k0|%k0, %2}"
9657 [(set_attr "type" "imovx,ishift")
9658 (set_attr "prefix_0f" "0,*")
9659 (set_attr "length_immediate" "0,*")
9660 (set_attr "modrm" "0,1")
9661 (set_attr "mode" "SI")])
9662
9663 (define_expand "x86_shift<mode>_adj_3"
9664 [(use (match_operand:SWI48 0 "register_operand" ""))
9665 (use (match_operand:SWI48 1 "register_operand" ""))
9666 (use (match_operand:QI 2 "register_operand" ""))]
9667 ""
9668 {
9669 rtx label = gen_label_rtx ();
9670 rtx tmp;
9671
9672 emit_insn (gen_testqi_ccz_1 (operands[2],
9673 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9674
9675 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9676 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9677 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9678 gen_rtx_LABEL_REF (VOIDmode, label),
9679 pc_rtx);
9680 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9681 JUMP_LABEL (tmp) = label;
9682
9683 emit_move_insn (operands[0], operands[1]);
9684 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9685 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9686 emit_label (label);
9687 LABEL_NUSES (label) = 1;
9688
9689 DONE;
9690 })
9691
9692 (define_insn "*bmi2_<shift_insn><mode>3_1"
9693 [(set (match_operand:SWI48 0 "register_operand" "=r")
9694 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9695 (match_operand:SWI48 2 "register_operand" "r")))]
9696 "TARGET_BMI2"
9697 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9698 [(set_attr "type" "ishiftx")
9699 (set_attr "mode" "<MODE>")])
9700
9701 (define_insn "*<shift_insn><mode>3_1"
9702 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9703 (any_shiftrt:SWI48
9704 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9705 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9706 (clobber (reg:CC FLAGS_REG))]
9707 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9708 {
9709 switch (get_attr_type (insn))
9710 {
9711 case TYPE_ISHIFTX:
9712 return "#";
9713
9714 default:
9715 if (operands[2] == const1_rtx
9716 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9717 return "<shift>{<imodesuffix>}\t%0";
9718 else
9719 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9720 }
9721 }
9722 [(set_attr "isa" "*,bmi2")
9723 (set_attr "type" "ishift,ishiftx")
9724 (set (attr "length_immediate")
9725 (if_then_else
9726 (and (match_operand 2 "const1_operand" "")
9727 (ior (match_test "TARGET_SHIFT1")
9728 (match_test "optimize_function_for_size_p (cfun)")))
9729 (const_string "0")
9730 (const_string "*")))
9731 (set_attr "mode" "<MODE>")])
9732
9733 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9734 (define_split
9735 [(set (match_operand:SWI48 0 "register_operand" "")
9736 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9737 (match_operand:QI 2 "register_operand" "")))
9738 (clobber (reg:CC FLAGS_REG))]
9739 "TARGET_BMI2 && reload_completed"
9740 [(set (match_dup 0)
9741 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9742 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9743
9744 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9745 [(set (match_operand:DI 0 "register_operand" "=r")
9746 (zero_extend:DI
9747 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9748 (match_operand:SI 2 "register_operand" "r"))))]
9749 "TARGET_64BIT && TARGET_BMI2"
9750 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9751 [(set_attr "type" "ishiftx")
9752 (set_attr "mode" "SI")])
9753
9754 (define_insn "*<shift_insn>si3_1_zext"
9755 [(set (match_operand:DI 0 "register_operand" "=r,r")
9756 (zero_extend:DI
9757 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9758 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9759 (clobber (reg:CC FLAGS_REG))]
9760 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9761 {
9762 switch (get_attr_type (insn))
9763 {
9764 case TYPE_ISHIFTX:
9765 return "#";
9766
9767 default:
9768 if (operands[2] == const1_rtx
9769 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9770 return "<shift>{l}\t%k0";
9771 else
9772 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9773 }
9774 }
9775 [(set_attr "isa" "*,bmi2")
9776 (set_attr "type" "ishift,ishiftx")
9777 (set (attr "length_immediate")
9778 (if_then_else
9779 (and (match_operand 2 "const1_operand" "")
9780 (ior (match_test "TARGET_SHIFT1")
9781 (match_test "optimize_function_for_size_p (cfun)")))
9782 (const_string "0")
9783 (const_string "*")))
9784 (set_attr "mode" "SI")])
9785
9786 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9787 (define_split
9788 [(set (match_operand:DI 0 "register_operand" "")
9789 (zero_extend:DI
9790 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9791 (match_operand:QI 2 "register_operand" ""))))
9792 (clobber (reg:CC FLAGS_REG))]
9793 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9794 [(set (match_dup 0)
9795 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9796 "operands[2] = gen_lowpart (SImode, operands[2]);")
9797
9798 (define_insn "*<shift_insn><mode>3_1"
9799 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9800 (any_shiftrt:SWI12
9801 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9802 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9803 (clobber (reg:CC FLAGS_REG))]
9804 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9805 {
9806 if (operands[2] == const1_rtx
9807 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9808 return "<shift>{<imodesuffix>}\t%0";
9809 else
9810 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9811 }
9812 [(set_attr "type" "ishift")
9813 (set (attr "length_immediate")
9814 (if_then_else
9815 (and (match_operand 2 "const1_operand" "")
9816 (ior (match_test "TARGET_SHIFT1")
9817 (match_test "optimize_function_for_size_p (cfun)")))
9818 (const_string "0")
9819 (const_string "*")))
9820 (set_attr "mode" "<MODE>")])
9821
9822 (define_insn "*<shift_insn>qi3_1_slp"
9823 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9824 (any_shiftrt:QI (match_dup 0)
9825 (match_operand:QI 1 "nonmemory_operand" "cI")))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "(optimize_function_for_size_p (cfun)
9828 || !TARGET_PARTIAL_REG_STALL
9829 || (operands[1] == const1_rtx
9830 && TARGET_SHIFT1))"
9831 {
9832 if (operands[1] == const1_rtx
9833 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9834 return "<shift>{b}\t%0";
9835 else
9836 return "<shift>{b}\t{%1, %0|%0, %1}";
9837 }
9838 [(set_attr "type" "ishift1")
9839 (set (attr "length_immediate")
9840 (if_then_else
9841 (and (match_operand 1 "const1_operand" "")
9842 (ior (match_test "TARGET_SHIFT1")
9843 (match_test "optimize_function_for_size_p (cfun)")))
9844 (const_string "0")
9845 (const_string "*")))
9846 (set_attr "mode" "QI")])
9847
9848 ;; This pattern can't accept a variable shift count, since shifts by
9849 ;; zero don't affect the flags. We assume that shifts by constant
9850 ;; zero are optimized away.
9851 (define_insn "*<shift_insn><mode>3_cmp"
9852 [(set (reg FLAGS_REG)
9853 (compare
9854 (any_shiftrt:SWI
9855 (match_operand:SWI 1 "nonimmediate_operand" "0")
9856 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9857 (const_int 0)))
9858 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9859 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9860 "(optimize_function_for_size_p (cfun)
9861 || !TARGET_PARTIAL_FLAG_REG_STALL
9862 || (operands[2] == const1_rtx
9863 && TARGET_SHIFT1))
9864 && ix86_match_ccmode (insn, CCGOCmode)
9865 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9866 {
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869 return "<shift>{<imodesuffix>}\t%0";
9870 else
9871 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9872 }
9873 [(set_attr "type" "ishift")
9874 (set (attr "length_immediate")
9875 (if_then_else
9876 (and (match_operand 2 "const1_operand" "")
9877 (ior (match_test "TARGET_SHIFT1")
9878 (match_test "optimize_function_for_size_p (cfun)")))
9879 (const_string "0")
9880 (const_string "*")))
9881 (set_attr "mode" "<MODE>")])
9882
9883 (define_insn "*<shift_insn>si3_cmp_zext"
9884 [(set (reg FLAGS_REG)
9885 (compare
9886 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9887 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9888 (const_int 0)))
9889 (set (match_operand:DI 0 "register_operand" "=r")
9890 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9891 "TARGET_64BIT
9892 && (optimize_function_for_size_p (cfun)
9893 || !TARGET_PARTIAL_FLAG_REG_STALL
9894 || (operands[2] == const1_rtx
9895 && TARGET_SHIFT1))
9896 && ix86_match_ccmode (insn, CCGOCmode)
9897 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9898 {
9899 if (operands[2] == const1_rtx
9900 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9901 return "<shift>{l}\t%k0";
9902 else
9903 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9904 }
9905 [(set_attr "type" "ishift")
9906 (set (attr "length_immediate")
9907 (if_then_else
9908 (and (match_operand 2 "const1_operand" "")
9909 (ior (match_test "TARGET_SHIFT1")
9910 (match_test "optimize_function_for_size_p (cfun)")))
9911 (const_string "0")
9912 (const_string "*")))
9913 (set_attr "mode" "SI")])
9914
9915 (define_insn "*<shift_insn><mode>3_cconly"
9916 [(set (reg FLAGS_REG)
9917 (compare
9918 (any_shiftrt:SWI
9919 (match_operand:SWI 1 "register_operand" "0")
9920 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9921 (const_int 0)))
9922 (clobber (match_scratch:SWI 0 "=<r>"))]
9923 "(optimize_function_for_size_p (cfun)
9924 || !TARGET_PARTIAL_FLAG_REG_STALL
9925 || (operands[2] == const1_rtx
9926 && TARGET_SHIFT1))
9927 && ix86_match_ccmode (insn, CCGOCmode)"
9928 {
9929 if (operands[2] == const1_rtx
9930 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9931 return "<shift>{<imodesuffix>}\t%0";
9932 else
9933 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9934 }
9935 [(set_attr "type" "ishift")
9936 (set (attr "length_immediate")
9937 (if_then_else
9938 (and (match_operand 2 "const1_operand" "")
9939 (ior (match_test "TARGET_SHIFT1")
9940 (match_test "optimize_function_for_size_p (cfun)")))
9941 (const_string "0")
9942 (const_string "*")))
9943 (set_attr "mode" "<MODE>")])
9944 \f
9945 ;; Rotate instructions
9946
9947 (define_expand "<rotate_insn>ti3"
9948 [(set (match_operand:TI 0 "register_operand" "")
9949 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9950 (match_operand:QI 2 "nonmemory_operand" "")))]
9951 "TARGET_64BIT"
9952 {
9953 if (const_1_to_63_operand (operands[2], VOIDmode))
9954 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9955 (operands[0], operands[1], operands[2]));
9956 else
9957 FAIL;
9958
9959 DONE;
9960 })
9961
9962 (define_expand "<rotate_insn>di3"
9963 [(set (match_operand:DI 0 "shiftdi_operand" "")
9964 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9965 (match_operand:QI 2 "nonmemory_operand" "")))]
9966 ""
9967 {
9968 if (TARGET_64BIT)
9969 ix86_expand_binary_operator (<CODE>, DImode, operands);
9970 else if (const_1_to_31_operand (operands[2], VOIDmode))
9971 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9972 (operands[0], operands[1], operands[2]));
9973 else
9974 FAIL;
9975
9976 DONE;
9977 })
9978
9979 (define_expand "<rotate_insn><mode>3"
9980 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9981 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9982 (match_operand:QI 2 "nonmemory_operand" "")))]
9983 ""
9984 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9985
9986 ;; Avoid useless masking of count operand.
9987 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9988 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9989 (any_rotate:SWI48
9990 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9991 (subreg:QI
9992 (and:SI
9993 (match_operand:SI 2 "nonimmediate_operand" "c")
9994 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9995 (clobber (reg:CC FLAGS_REG))]
9996 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9997 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9998 == GET_MODE_BITSIZE (<MODE>mode)-1"
9999 "#"
10000 "&& 1"
10001 [(parallel [(set (match_dup 0)
10002 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10003 (clobber (reg:CC FLAGS_REG))])]
10004 {
10005 if (can_create_pseudo_p ())
10006 operands [2] = force_reg (SImode, operands[2]);
10007
10008 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10009 }
10010 [(set_attr "type" "rotate")
10011 (set_attr "mode" "<MODE>")])
10012
10013 ;; Implement rotation using two double-precision
10014 ;; shift instructions and a scratch register.
10015
10016 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10017 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10018 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10019 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10020 (clobber (reg:CC FLAGS_REG))
10021 (clobber (match_scratch:DWIH 3 "=&r"))]
10022 ""
10023 "#"
10024 "reload_completed"
10025 [(set (match_dup 3) (match_dup 4))
10026 (parallel
10027 [(set (match_dup 4)
10028 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10029 (lshiftrt:DWIH (match_dup 5)
10030 (minus:QI (match_dup 6) (match_dup 2)))))
10031 (clobber (reg:CC FLAGS_REG))])
10032 (parallel
10033 [(set (match_dup 5)
10034 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10035 (lshiftrt:DWIH (match_dup 3)
10036 (minus:QI (match_dup 6) (match_dup 2)))))
10037 (clobber (reg:CC FLAGS_REG))])]
10038 {
10039 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10040
10041 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10042 })
10043
10044 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10045 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10046 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10047 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10048 (clobber (reg:CC FLAGS_REG))
10049 (clobber (match_scratch:DWIH 3 "=&r"))]
10050 ""
10051 "#"
10052 "reload_completed"
10053 [(set (match_dup 3) (match_dup 4))
10054 (parallel
10055 [(set (match_dup 4)
10056 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10057 (ashift:DWIH (match_dup 5)
10058 (minus:QI (match_dup 6) (match_dup 2)))))
10059 (clobber (reg:CC FLAGS_REG))])
10060 (parallel
10061 [(set (match_dup 5)
10062 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10063 (ashift:DWIH (match_dup 3)
10064 (minus:QI (match_dup 6) (match_dup 2)))))
10065 (clobber (reg:CC FLAGS_REG))])]
10066 {
10067 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10068
10069 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10070 })
10071
10072 (define_insn "*bmi2_rorx<mode>3_1"
10073 [(set (match_operand:SWI48 0 "register_operand" "=r")
10074 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10075 (match_operand:QI 2 "immediate_operand" "<S>")))]
10076 "TARGET_BMI2"
10077 "rorx\t{%2, %1, %0|%0, %1, %2}"
10078 [(set_attr "type" "rotatex")
10079 (set_attr "mode" "<MODE>")])
10080
10081 (define_insn "*<rotate_insn><mode>3_1"
10082 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10083 (any_rotate:SWI48
10084 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10085 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10086 (clobber (reg:CC FLAGS_REG))]
10087 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10088 {
10089 switch (get_attr_type (insn))
10090 {
10091 case TYPE_ROTATEX:
10092 return "#";
10093
10094 default:
10095 if (operands[2] == const1_rtx
10096 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10097 return "<rotate>{<imodesuffix>}\t%0";
10098 else
10099 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10100 }
10101 }
10102 [(set_attr "isa" "*,bmi2")
10103 (set_attr "type" "rotate,rotatex")
10104 (set (attr "length_immediate")
10105 (if_then_else
10106 (and (eq_attr "type" "rotate")
10107 (and (match_operand 2 "const1_operand" "")
10108 (ior (match_test "TARGET_SHIFT1")
10109 (match_test "optimize_function_for_size_p (cfun)"))))
10110 (const_string "0")
10111 (const_string "*")))
10112 (set_attr "mode" "<MODE>")])
10113
10114 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10115 (define_split
10116 [(set (match_operand:SWI48 0 "register_operand" "")
10117 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10118 (match_operand:QI 2 "immediate_operand" "")))
10119 (clobber (reg:CC FLAGS_REG))]
10120 "TARGET_BMI2 && reload_completed"
10121 [(set (match_dup 0)
10122 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10123 {
10124 operands[2]
10125 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10126 })
10127
10128 (define_split
10129 [(set (match_operand:SWI48 0 "register_operand" "")
10130 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10131 (match_operand:QI 2 "immediate_operand" "")))
10132 (clobber (reg:CC FLAGS_REG))]
10133 "TARGET_BMI2 && reload_completed"
10134 [(set (match_dup 0)
10135 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10136
10137 (define_insn "*bmi2_rorxsi3_1_zext"
10138 [(set (match_operand:DI 0 "register_operand" "=r")
10139 (zero_extend:DI
10140 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10141 (match_operand:QI 2 "immediate_operand" "I"))))]
10142 "TARGET_64BIT && TARGET_BMI2"
10143 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10144 [(set_attr "type" "rotatex")
10145 (set_attr "mode" "SI")])
10146
10147 (define_insn "*<rotate_insn>si3_1_zext"
10148 [(set (match_operand:DI 0 "register_operand" "=r,r")
10149 (zero_extend:DI
10150 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10151 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10152 (clobber (reg:CC FLAGS_REG))]
10153 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10154 {
10155 switch (get_attr_type (insn))
10156 {
10157 case TYPE_ROTATEX:
10158 return "#";
10159
10160 default:
10161 if (operands[2] == const1_rtx
10162 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10163 return "<rotate>{l}\t%k0";
10164 else
10165 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10166 }
10167 }
10168 [(set_attr "isa" "*,bmi2")
10169 (set_attr "type" "rotate,rotatex")
10170 (set (attr "length_immediate")
10171 (if_then_else
10172 (and (eq_attr "type" "rotate")
10173 (and (match_operand 2 "const1_operand" "")
10174 (ior (match_test "TARGET_SHIFT1")
10175 (match_test "optimize_function_for_size_p (cfun)"))))
10176 (const_string "0")
10177 (const_string "*")))
10178 (set_attr "mode" "SI")])
10179
10180 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10181 (define_split
10182 [(set (match_operand:DI 0 "register_operand" "")
10183 (zero_extend:DI
10184 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10185 (match_operand:QI 2 "immediate_operand" ""))))
10186 (clobber (reg:CC FLAGS_REG))]
10187 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10188 [(set (match_dup 0)
10189 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10190 {
10191 operands[2]
10192 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10193 })
10194
10195 (define_split
10196 [(set (match_operand:DI 0 "register_operand" "")
10197 (zero_extend:DI
10198 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10199 (match_operand:QI 2 "immediate_operand" ""))))
10200 (clobber (reg:CC FLAGS_REG))]
10201 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10202 [(set (match_dup 0)
10203 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10204
10205 (define_insn "*<rotate_insn><mode>3_1"
10206 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10207 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10208 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10209 (clobber (reg:CC FLAGS_REG))]
10210 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10211 {
10212 if (operands[2] == const1_rtx
10213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10214 return "<rotate>{<imodesuffix>}\t%0";
10215 else
10216 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10217 }
10218 [(set_attr "type" "rotate")
10219 (set (attr "length_immediate")
10220 (if_then_else
10221 (and (match_operand 2 "const1_operand" "")
10222 (ior (match_test "TARGET_SHIFT1")
10223 (match_test "optimize_function_for_size_p (cfun)")))
10224 (const_string "0")
10225 (const_string "*")))
10226 (set_attr "mode" "<MODE>")])
10227
10228 (define_insn "*<rotate_insn>qi3_1_slp"
10229 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10230 (any_rotate:QI (match_dup 0)
10231 (match_operand:QI 1 "nonmemory_operand" "cI")))
10232 (clobber (reg:CC FLAGS_REG))]
10233 "(optimize_function_for_size_p (cfun)
10234 || !TARGET_PARTIAL_REG_STALL
10235 || (operands[1] == const1_rtx
10236 && TARGET_SHIFT1))"
10237 {
10238 if (operands[1] == const1_rtx
10239 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10240 return "<rotate>{b}\t%0";
10241 else
10242 return "<rotate>{b}\t{%1, %0|%0, %1}";
10243 }
10244 [(set_attr "type" "rotate1")
10245 (set (attr "length_immediate")
10246 (if_then_else
10247 (and (match_operand 1 "const1_operand" "")
10248 (ior (match_test "TARGET_SHIFT1")
10249 (match_test "optimize_function_for_size_p (cfun)")))
10250 (const_string "0")
10251 (const_string "*")))
10252 (set_attr "mode" "QI")])
10253
10254 (define_split
10255 [(set (match_operand:HI 0 "register_operand" "")
10256 (any_rotate:HI (match_dup 0) (const_int 8)))
10257 (clobber (reg:CC FLAGS_REG))]
10258 "reload_completed
10259 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10260 [(parallel [(set (strict_low_part (match_dup 0))
10261 (bswap:HI (match_dup 0)))
10262 (clobber (reg:CC FLAGS_REG))])])
10263 \f
10264 ;; Bit set / bit test instructions
10265
10266 (define_expand "extv"
10267 [(set (match_operand:SI 0 "register_operand" "")
10268 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10269 (match_operand:SI 2 "const8_operand" "")
10270 (match_operand:SI 3 "const8_operand" "")))]
10271 ""
10272 {
10273 /* Handle extractions from %ah et al. */
10274 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10275 FAIL;
10276
10277 /* From mips.md: extract_bit_field doesn't verify that our source
10278 matches the predicate, so check it again here. */
10279 if (! ext_register_operand (operands[1], VOIDmode))
10280 FAIL;
10281 })
10282
10283 (define_expand "extzv"
10284 [(set (match_operand:SI 0 "register_operand" "")
10285 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10286 (match_operand:SI 2 "const8_operand" "")
10287 (match_operand:SI 3 "const8_operand" "")))]
10288 ""
10289 {
10290 /* Handle extractions from %ah et al. */
10291 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10292 FAIL;
10293
10294 /* From mips.md: extract_bit_field doesn't verify that our source
10295 matches the predicate, so check it again here. */
10296 if (! ext_register_operand (operands[1], VOIDmode))
10297 FAIL;
10298 })
10299
10300 (define_expand "insv"
10301 [(set (zero_extract (match_operand 0 "register_operand" "")
10302 (match_operand 1 "const_int_operand" "")
10303 (match_operand 2 "const_int_operand" ""))
10304 (match_operand 3 "register_operand" ""))]
10305 ""
10306 {
10307 rtx (*gen_mov_insv_1) (rtx, rtx);
10308
10309 if (ix86_expand_pinsr (operands))
10310 DONE;
10311
10312 /* Handle insertions to %ah et al. */
10313 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10314 FAIL;
10315
10316 /* From mips.md: insert_bit_field doesn't verify that our source
10317 matches the predicate, so check it again here. */
10318 if (! ext_register_operand (operands[0], VOIDmode))
10319 FAIL;
10320
10321 gen_mov_insv_1 = (TARGET_64BIT
10322 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10323
10324 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10325 DONE;
10326 })
10327
10328 ;; %%% bts, btr, btc, bt.
10329 ;; In general these instructions are *slow* when applied to memory,
10330 ;; since they enforce atomic operation. When applied to registers,
10331 ;; it depends on the cpu implementation. They're never faster than
10332 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10333 ;; no point. But in 64-bit, we can't hold the relevant immediates
10334 ;; within the instruction itself, so operating on bits in the high
10335 ;; 32-bits of a register becomes easier.
10336 ;;
10337 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10338 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10339 ;; negdf respectively, so they can never be disabled entirely.
10340
10341 (define_insn "*btsq"
10342 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10343 (const_int 1)
10344 (match_operand:DI 1 "const_0_to_63_operand" ""))
10345 (const_int 1))
10346 (clobber (reg:CC FLAGS_REG))]
10347 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10348 "bts{q}\t{%1, %0|%0, %1}"
10349 [(set_attr "type" "alu1")
10350 (set_attr "prefix_0f" "1")
10351 (set_attr "mode" "DI")])
10352
10353 (define_insn "*btrq"
10354 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10355 (const_int 1)
10356 (match_operand:DI 1 "const_0_to_63_operand" ""))
10357 (const_int 0))
10358 (clobber (reg:CC FLAGS_REG))]
10359 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10360 "btr{q}\t{%1, %0|%0, %1}"
10361 [(set_attr "type" "alu1")
10362 (set_attr "prefix_0f" "1")
10363 (set_attr "mode" "DI")])
10364
10365 (define_insn "*btcq"
10366 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10367 (const_int 1)
10368 (match_operand:DI 1 "const_0_to_63_operand" ""))
10369 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10370 (clobber (reg:CC FLAGS_REG))]
10371 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10372 "btc{q}\t{%1, %0|%0, %1}"
10373 [(set_attr "type" "alu1")
10374 (set_attr "prefix_0f" "1")
10375 (set_attr "mode" "DI")])
10376
10377 ;; Allow Nocona to avoid these instructions if a register is available.
10378
10379 (define_peephole2
10380 [(match_scratch:DI 2 "r")
10381 (parallel [(set (zero_extract:DI
10382 (match_operand:DI 0 "register_operand" "")
10383 (const_int 1)
10384 (match_operand:DI 1 "const_0_to_63_operand" ""))
10385 (const_int 1))
10386 (clobber (reg:CC FLAGS_REG))])]
10387 "TARGET_64BIT && !TARGET_USE_BT"
10388 [(const_int 0)]
10389 {
10390 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10391 rtx op1;
10392
10393 if (HOST_BITS_PER_WIDE_INT >= 64)
10394 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10395 else if (i < HOST_BITS_PER_WIDE_INT)
10396 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10397 else
10398 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10399
10400 op1 = immed_double_const (lo, hi, DImode);
10401 if (i >= 31)
10402 {
10403 emit_move_insn (operands[2], op1);
10404 op1 = operands[2];
10405 }
10406
10407 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10408 DONE;
10409 })
10410
10411 (define_peephole2
10412 [(match_scratch:DI 2 "r")
10413 (parallel [(set (zero_extract:DI
10414 (match_operand:DI 0 "register_operand" "")
10415 (const_int 1)
10416 (match_operand:DI 1 "const_0_to_63_operand" ""))
10417 (const_int 0))
10418 (clobber (reg:CC FLAGS_REG))])]
10419 "TARGET_64BIT && !TARGET_USE_BT"
10420 [(const_int 0)]
10421 {
10422 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10423 rtx op1;
10424
10425 if (HOST_BITS_PER_WIDE_INT >= 64)
10426 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10427 else if (i < HOST_BITS_PER_WIDE_INT)
10428 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10429 else
10430 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10431
10432 op1 = immed_double_const (~lo, ~hi, DImode);
10433 if (i >= 32)
10434 {
10435 emit_move_insn (operands[2], op1);
10436 op1 = operands[2];
10437 }
10438
10439 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10440 DONE;
10441 })
10442
10443 (define_peephole2
10444 [(match_scratch:DI 2 "r")
10445 (parallel [(set (zero_extract:DI
10446 (match_operand:DI 0 "register_operand" "")
10447 (const_int 1)
10448 (match_operand:DI 1 "const_0_to_63_operand" ""))
10449 (not:DI (zero_extract:DI
10450 (match_dup 0) (const_int 1) (match_dup 1))))
10451 (clobber (reg:CC FLAGS_REG))])]
10452 "TARGET_64BIT && !TARGET_USE_BT"
10453 [(const_int 0)]
10454 {
10455 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10456 rtx op1;
10457
10458 if (HOST_BITS_PER_WIDE_INT >= 64)
10459 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10460 else if (i < HOST_BITS_PER_WIDE_INT)
10461 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10462 else
10463 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10464
10465 op1 = immed_double_const (lo, hi, DImode);
10466 if (i >= 31)
10467 {
10468 emit_move_insn (operands[2], op1);
10469 op1 = operands[2];
10470 }
10471
10472 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10473 DONE;
10474 })
10475
10476 (define_insn "*bt<mode>"
10477 [(set (reg:CCC FLAGS_REG)
10478 (compare:CCC
10479 (zero_extract:SWI48
10480 (match_operand:SWI48 0 "register_operand" "r")
10481 (const_int 1)
10482 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10483 (const_int 0)))]
10484 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10485 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10486 [(set_attr "type" "alu1")
10487 (set_attr "prefix_0f" "1")
10488 (set_attr "mode" "<MODE>")])
10489 \f
10490 ;; Store-flag instructions.
10491
10492 ;; For all sCOND expanders, also expand the compare or test insn that
10493 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10494
10495 (define_insn_and_split "*setcc_di_1"
10496 [(set (match_operand:DI 0 "register_operand" "=q")
10497 (match_operator:DI 1 "ix86_comparison_operator"
10498 [(reg FLAGS_REG) (const_int 0)]))]
10499 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10500 "#"
10501 "&& reload_completed"
10502 [(set (match_dup 2) (match_dup 1))
10503 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10504 {
10505 PUT_MODE (operands[1], QImode);
10506 operands[2] = gen_lowpart (QImode, operands[0]);
10507 })
10508
10509 (define_insn_and_split "*setcc_si_1_and"
10510 [(set (match_operand:SI 0 "register_operand" "=q")
10511 (match_operator:SI 1 "ix86_comparison_operator"
10512 [(reg FLAGS_REG) (const_int 0)]))
10513 (clobber (reg:CC FLAGS_REG))]
10514 "!TARGET_PARTIAL_REG_STALL
10515 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10516 "#"
10517 "&& reload_completed"
10518 [(set (match_dup 2) (match_dup 1))
10519 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10520 (clobber (reg:CC FLAGS_REG))])]
10521 {
10522 PUT_MODE (operands[1], QImode);
10523 operands[2] = gen_lowpart (QImode, operands[0]);
10524 })
10525
10526 (define_insn_and_split "*setcc_si_1_movzbl"
10527 [(set (match_operand:SI 0 "register_operand" "=q")
10528 (match_operator:SI 1 "ix86_comparison_operator"
10529 [(reg FLAGS_REG) (const_int 0)]))]
10530 "!TARGET_PARTIAL_REG_STALL
10531 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10532 "#"
10533 "&& reload_completed"
10534 [(set (match_dup 2) (match_dup 1))
10535 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10536 {
10537 PUT_MODE (operands[1], QImode);
10538 operands[2] = gen_lowpart (QImode, operands[0]);
10539 })
10540
10541 (define_insn "*setcc_qi"
10542 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10543 (match_operator:QI 1 "ix86_comparison_operator"
10544 [(reg FLAGS_REG) (const_int 0)]))]
10545 ""
10546 "set%C1\t%0"
10547 [(set_attr "type" "setcc")
10548 (set_attr "mode" "QI")])
10549
10550 (define_insn "*setcc_qi_slp"
10551 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10552 (match_operator:QI 1 "ix86_comparison_operator"
10553 [(reg FLAGS_REG) (const_int 0)]))]
10554 ""
10555 "set%C1\t%0"
10556 [(set_attr "type" "setcc")
10557 (set_attr "mode" "QI")])
10558
10559 ;; In general it is not safe to assume too much about CCmode registers,
10560 ;; so simplify-rtx stops when it sees a second one. Under certain
10561 ;; conditions this is safe on x86, so help combine not create
10562 ;;
10563 ;; seta %al
10564 ;; testb %al, %al
10565 ;; sete %al
10566
10567 (define_split
10568 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10569 (ne:QI (match_operator 1 "ix86_comparison_operator"
10570 [(reg FLAGS_REG) (const_int 0)])
10571 (const_int 0)))]
10572 ""
10573 [(set (match_dup 0) (match_dup 1))]
10574 "PUT_MODE (operands[1], QImode);")
10575
10576 (define_split
10577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10578 (ne:QI (match_operator 1 "ix86_comparison_operator"
10579 [(reg FLAGS_REG) (const_int 0)])
10580 (const_int 0)))]
10581 ""
10582 [(set (match_dup 0) (match_dup 1))]
10583 "PUT_MODE (operands[1], QImode);")
10584
10585 (define_split
10586 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10587 (eq:QI (match_operator 1 "ix86_comparison_operator"
10588 [(reg FLAGS_REG) (const_int 0)])
10589 (const_int 0)))]
10590 ""
10591 [(set (match_dup 0) (match_dup 1))]
10592 {
10593 rtx new_op1 = copy_rtx (operands[1]);
10594 operands[1] = new_op1;
10595 PUT_MODE (new_op1, QImode);
10596 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10597 GET_MODE (XEXP (new_op1, 0))));
10598
10599 /* Make sure that (a) the CCmode we have for the flags is strong
10600 enough for the reversed compare or (b) we have a valid FP compare. */
10601 if (! ix86_comparison_operator (new_op1, VOIDmode))
10602 FAIL;
10603 })
10604
10605 (define_split
10606 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10607 (eq:QI (match_operator 1 "ix86_comparison_operator"
10608 [(reg FLAGS_REG) (const_int 0)])
10609 (const_int 0)))]
10610 ""
10611 [(set (match_dup 0) (match_dup 1))]
10612 {
10613 rtx new_op1 = copy_rtx (operands[1]);
10614 operands[1] = new_op1;
10615 PUT_MODE (new_op1, QImode);
10616 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10617 GET_MODE (XEXP (new_op1, 0))));
10618
10619 /* Make sure that (a) the CCmode we have for the flags is strong
10620 enough for the reversed compare or (b) we have a valid FP compare. */
10621 if (! ix86_comparison_operator (new_op1, VOIDmode))
10622 FAIL;
10623 })
10624
10625 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10626 ;; subsequent logical operations are used to imitate conditional moves.
10627 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10628 ;; it directly.
10629
10630 (define_insn "setcc_<mode>_sse"
10631 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10632 (match_operator:MODEF 3 "sse_comparison_operator"
10633 [(match_operand:MODEF 1 "register_operand" "0,x")
10634 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10635 "SSE_FLOAT_MODE_P (<MODE>mode)"
10636 "@
10637 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10638 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10639 [(set_attr "isa" "noavx,avx")
10640 (set_attr "type" "ssecmp")
10641 (set_attr "length_immediate" "1")
10642 (set_attr "prefix" "orig,vex")
10643 (set_attr "mode" "<MODE>")])
10644 \f
10645 ;; Basic conditional jump instructions.
10646 ;; We ignore the overflow flag for signed branch instructions.
10647
10648 (define_insn "*jcc_1"
10649 [(set (pc)
10650 (if_then_else (match_operator 1 "ix86_comparison_operator"
10651 [(reg FLAGS_REG) (const_int 0)])
10652 (label_ref (match_operand 0 "" ""))
10653 (pc)))]
10654 ""
10655 "%+j%C1\t%l0"
10656 [(set_attr "type" "ibr")
10657 (set_attr "modrm" "0")
10658 (set (attr "length")
10659 (if_then_else (and (ge (minus (match_dup 0) (pc))
10660 (const_int -126))
10661 (lt (minus (match_dup 0) (pc))
10662 (const_int 128)))
10663 (const_int 2)
10664 (const_int 6)))])
10665
10666 (define_insn "*jcc_2"
10667 [(set (pc)
10668 (if_then_else (match_operator 1 "ix86_comparison_operator"
10669 [(reg FLAGS_REG) (const_int 0)])
10670 (pc)
10671 (label_ref (match_operand 0 "" ""))))]
10672 ""
10673 "%+j%c1\t%l0"
10674 [(set_attr "type" "ibr")
10675 (set_attr "modrm" "0")
10676 (set (attr "length")
10677 (if_then_else (and (ge (minus (match_dup 0) (pc))
10678 (const_int -126))
10679 (lt (minus (match_dup 0) (pc))
10680 (const_int 128)))
10681 (const_int 2)
10682 (const_int 6)))])
10683
10684 ;; In general it is not safe to assume too much about CCmode registers,
10685 ;; so simplify-rtx stops when it sees a second one. Under certain
10686 ;; conditions this is safe on x86, so help combine not create
10687 ;;
10688 ;; seta %al
10689 ;; testb %al, %al
10690 ;; je Lfoo
10691
10692 (define_split
10693 [(set (pc)
10694 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10695 [(reg FLAGS_REG) (const_int 0)])
10696 (const_int 0))
10697 (label_ref (match_operand 1 "" ""))
10698 (pc)))]
10699 ""
10700 [(set (pc)
10701 (if_then_else (match_dup 0)
10702 (label_ref (match_dup 1))
10703 (pc)))]
10704 "PUT_MODE (operands[0], VOIDmode);")
10705
10706 (define_split
10707 [(set (pc)
10708 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10709 [(reg FLAGS_REG) (const_int 0)])
10710 (const_int 0))
10711 (label_ref (match_operand 1 "" ""))
10712 (pc)))]
10713 ""
10714 [(set (pc)
10715 (if_then_else (match_dup 0)
10716 (label_ref (match_dup 1))
10717 (pc)))]
10718 {
10719 rtx new_op0 = copy_rtx (operands[0]);
10720 operands[0] = new_op0;
10721 PUT_MODE (new_op0, VOIDmode);
10722 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10723 GET_MODE (XEXP (new_op0, 0))));
10724
10725 /* Make sure that (a) the CCmode we have for the flags is strong
10726 enough for the reversed compare or (b) we have a valid FP compare. */
10727 if (! ix86_comparison_operator (new_op0, VOIDmode))
10728 FAIL;
10729 })
10730
10731 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10732 ;; pass generates from shift insn with QImode operand. Actually, the mode
10733 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10734 ;; appropriate modulo of the bit offset value.
10735
10736 (define_insn_and_split "*jcc_bt<mode>"
10737 [(set (pc)
10738 (if_then_else (match_operator 0 "bt_comparison_operator"
10739 [(zero_extract:SWI48
10740 (match_operand:SWI48 1 "register_operand" "r")
10741 (const_int 1)
10742 (zero_extend:SI
10743 (match_operand:QI 2 "register_operand" "r")))
10744 (const_int 0)])
10745 (label_ref (match_operand 3 "" ""))
10746 (pc)))
10747 (clobber (reg:CC FLAGS_REG))]
10748 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10749 "#"
10750 "&& 1"
10751 [(set (reg:CCC FLAGS_REG)
10752 (compare:CCC
10753 (zero_extract:SWI48
10754 (match_dup 1)
10755 (const_int 1)
10756 (match_dup 2))
10757 (const_int 0)))
10758 (set (pc)
10759 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10760 (label_ref (match_dup 3))
10761 (pc)))]
10762 {
10763 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10764
10765 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10766 })
10767
10768 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10769 ;; also for DImode, this is what combine produces.
10770 (define_insn_and_split "*jcc_bt<mode>_mask"
10771 [(set (pc)
10772 (if_then_else (match_operator 0 "bt_comparison_operator"
10773 [(zero_extract:SWI48
10774 (match_operand:SWI48 1 "register_operand" "r")
10775 (const_int 1)
10776 (and:SI
10777 (match_operand:SI 2 "register_operand" "r")
10778 (match_operand:SI 3 "const_int_operand" "n")))])
10779 (label_ref (match_operand 4 "" ""))
10780 (pc)))
10781 (clobber (reg:CC FLAGS_REG))]
10782 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10783 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10784 == GET_MODE_BITSIZE (<MODE>mode)-1"
10785 "#"
10786 "&& 1"
10787 [(set (reg:CCC FLAGS_REG)
10788 (compare:CCC
10789 (zero_extract:SWI48
10790 (match_dup 1)
10791 (const_int 1)
10792 (match_dup 2))
10793 (const_int 0)))
10794 (set (pc)
10795 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10796 (label_ref (match_dup 4))
10797 (pc)))]
10798 {
10799 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10800
10801 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10802 })
10803
10804 (define_insn_and_split "*jcc_btsi_1"
10805 [(set (pc)
10806 (if_then_else (match_operator 0 "bt_comparison_operator"
10807 [(and:SI
10808 (lshiftrt:SI
10809 (match_operand:SI 1 "register_operand" "r")
10810 (match_operand:QI 2 "register_operand" "r"))
10811 (const_int 1))
10812 (const_int 0)])
10813 (label_ref (match_operand 3 "" ""))
10814 (pc)))
10815 (clobber (reg:CC FLAGS_REG))]
10816 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10817 "#"
10818 "&& 1"
10819 [(set (reg:CCC FLAGS_REG)
10820 (compare:CCC
10821 (zero_extract:SI
10822 (match_dup 1)
10823 (const_int 1)
10824 (match_dup 2))
10825 (const_int 0)))
10826 (set (pc)
10827 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10828 (label_ref (match_dup 3))
10829 (pc)))]
10830 {
10831 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10832
10833 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10834 })
10835
10836 ;; avoid useless masking of bit offset operand
10837 (define_insn_and_split "*jcc_btsi_mask_1"
10838 [(set (pc)
10839 (if_then_else
10840 (match_operator 0 "bt_comparison_operator"
10841 [(and:SI
10842 (lshiftrt:SI
10843 (match_operand:SI 1 "register_operand" "r")
10844 (subreg:QI
10845 (and:SI
10846 (match_operand:SI 2 "register_operand" "r")
10847 (match_operand:SI 3 "const_int_operand" "n")) 0))
10848 (const_int 1))
10849 (const_int 0)])
10850 (label_ref (match_operand 4 "" ""))
10851 (pc)))
10852 (clobber (reg:CC FLAGS_REG))]
10853 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10854 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10855 "#"
10856 "&& 1"
10857 [(set (reg:CCC FLAGS_REG)
10858 (compare:CCC
10859 (zero_extract:SI
10860 (match_dup 1)
10861 (const_int 1)
10862 (match_dup 2))
10863 (const_int 0)))
10864 (set (pc)
10865 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10866 (label_ref (match_dup 4))
10867 (pc)))]
10868 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10869
10870 ;; Define combination compare-and-branch fp compare instructions to help
10871 ;; combine.
10872
10873 (define_insn "*fp_jcc_1_387"
10874 [(set (pc)
10875 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10876 [(match_operand 1 "register_operand" "f")
10877 (match_operand 2 "nonimmediate_operand" "fm")])
10878 (label_ref (match_operand 3 "" ""))
10879 (pc)))
10880 (clobber (reg:CCFP FPSR_REG))
10881 (clobber (reg:CCFP FLAGS_REG))
10882 (clobber (match_scratch:HI 4 "=a"))]
10883 "TARGET_80387
10884 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10885 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10886 && SELECT_CC_MODE (GET_CODE (operands[0]),
10887 operands[1], operands[2]) == CCFPmode
10888 && !TARGET_CMOVE"
10889 "#")
10890
10891 (define_insn "*fp_jcc_1r_387"
10892 [(set (pc)
10893 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10894 [(match_operand 1 "register_operand" "f")
10895 (match_operand 2 "nonimmediate_operand" "fm")])
10896 (pc)
10897 (label_ref (match_operand 3 "" ""))))
10898 (clobber (reg:CCFP FPSR_REG))
10899 (clobber (reg:CCFP FLAGS_REG))
10900 (clobber (match_scratch:HI 4 "=a"))]
10901 "TARGET_80387
10902 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10903 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10904 && SELECT_CC_MODE (GET_CODE (operands[0]),
10905 operands[1], operands[2]) == CCFPmode
10906 && !TARGET_CMOVE"
10907 "#")
10908
10909 (define_insn "*fp_jcc_2_387"
10910 [(set (pc)
10911 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10912 [(match_operand 1 "register_operand" "f")
10913 (match_operand 2 "register_operand" "f")])
10914 (label_ref (match_operand 3 "" ""))
10915 (pc)))
10916 (clobber (reg:CCFP FPSR_REG))
10917 (clobber (reg:CCFP FLAGS_REG))
10918 (clobber (match_scratch:HI 4 "=a"))]
10919 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10920 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10921 && !TARGET_CMOVE"
10922 "#")
10923
10924 (define_insn "*fp_jcc_2r_387"
10925 [(set (pc)
10926 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10927 [(match_operand 1 "register_operand" "f")
10928 (match_operand 2 "register_operand" "f")])
10929 (pc)
10930 (label_ref (match_operand 3 "" ""))))
10931 (clobber (reg:CCFP FPSR_REG))
10932 (clobber (reg:CCFP FLAGS_REG))
10933 (clobber (match_scratch:HI 4 "=a"))]
10934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10935 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10936 && !TARGET_CMOVE"
10937 "#")
10938
10939 (define_insn "*fp_jcc_3_387"
10940 [(set (pc)
10941 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10942 [(match_operand 1 "register_operand" "f")
10943 (match_operand 2 "const0_operand" "")])
10944 (label_ref (match_operand 3 "" ""))
10945 (pc)))
10946 (clobber (reg:CCFP FPSR_REG))
10947 (clobber (reg:CCFP FLAGS_REG))
10948 (clobber (match_scratch:HI 4 "=a"))]
10949 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10950 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10951 && SELECT_CC_MODE (GET_CODE (operands[0]),
10952 operands[1], operands[2]) == CCFPmode
10953 && !TARGET_CMOVE"
10954 "#")
10955
10956 (define_split
10957 [(set (pc)
10958 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10959 [(match_operand 1 "register_operand" "")
10960 (match_operand 2 "nonimmediate_operand" "")])
10961 (match_operand 3 "" "")
10962 (match_operand 4 "" "")))
10963 (clobber (reg:CCFP FPSR_REG))
10964 (clobber (reg:CCFP FLAGS_REG))]
10965 "reload_completed"
10966 [(const_int 0)]
10967 {
10968 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10969 operands[3], operands[4], NULL_RTX, NULL_RTX);
10970 DONE;
10971 })
10972
10973 (define_split
10974 [(set (pc)
10975 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10976 [(match_operand 1 "register_operand" "")
10977 (match_operand 2 "general_operand" "")])
10978 (match_operand 3 "" "")
10979 (match_operand 4 "" "")))
10980 (clobber (reg:CCFP FPSR_REG))
10981 (clobber (reg:CCFP FLAGS_REG))
10982 (clobber (match_scratch:HI 5 "=a"))]
10983 "reload_completed"
10984 [(const_int 0)]
10985 {
10986 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10987 operands[3], operands[4], operands[5], NULL_RTX);
10988 DONE;
10989 })
10990
10991 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10992 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10993 ;; with a precedence over other operators and is always put in the first
10994 ;; place. Swap condition and operands to match ficom instruction.
10995
10996 (define_insn "*fp_jcc_4_<mode>_387"
10997 [(set (pc)
10998 (if_then_else
10999 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11000 [(match_operator 1 "float_operator"
11001 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11002 (match_operand 3 "register_operand" "f,f")])
11003 (label_ref (match_operand 4 "" ""))
11004 (pc)))
11005 (clobber (reg:CCFP FPSR_REG))
11006 (clobber (reg:CCFP FLAGS_REG))
11007 (clobber (match_scratch:HI 5 "=a,a"))]
11008 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11009 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11010 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11011 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11012 && !TARGET_CMOVE"
11013 "#")
11014
11015 (define_split
11016 [(set (pc)
11017 (if_then_else
11018 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11019 [(match_operator 1 "float_operator"
11020 [(match_operand:SWI24 2 "memory_operand" "")])
11021 (match_operand 3 "register_operand" "")])
11022 (match_operand 4 "" "")
11023 (match_operand 5 "" "")))
11024 (clobber (reg:CCFP FPSR_REG))
11025 (clobber (reg:CCFP FLAGS_REG))
11026 (clobber (match_scratch:HI 6 "=a"))]
11027 "reload_completed"
11028 [(const_int 0)]
11029 {
11030 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11031
11032 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11033 operands[3], operands[7],
11034 operands[4], operands[5], operands[6], NULL_RTX);
11035 DONE;
11036 })
11037
11038 ;; %%% Kill this when reload knows how to do it.
11039 (define_split
11040 [(set (pc)
11041 (if_then_else
11042 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11043 [(match_operator 1 "float_operator"
11044 [(match_operand:SWI24 2 "register_operand" "")])
11045 (match_operand 3 "register_operand" "")])
11046 (match_operand 4 "" "")
11047 (match_operand 5 "" "")))
11048 (clobber (reg:CCFP FPSR_REG))
11049 (clobber (reg:CCFP FLAGS_REG))
11050 (clobber (match_scratch:HI 6 "=a"))]
11051 "reload_completed"
11052 [(const_int 0)]
11053 {
11054 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11055 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11056
11057 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11058 operands[3], operands[7],
11059 operands[4], operands[5], operands[6], operands[2]);
11060 DONE;
11061 })
11062 \f
11063 ;; Unconditional and other jump instructions
11064
11065 (define_insn "jump"
11066 [(set (pc)
11067 (label_ref (match_operand 0 "" "")))]
11068 ""
11069 "jmp\t%l0"
11070 [(set_attr "type" "ibr")
11071 (set (attr "length")
11072 (if_then_else (and (ge (minus (match_dup 0) (pc))
11073 (const_int -126))
11074 (lt (minus (match_dup 0) (pc))
11075 (const_int 128)))
11076 (const_int 2)
11077 (const_int 5)))
11078 (set_attr "modrm" "0")])
11079
11080 (define_expand "indirect_jump"
11081 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11082
11083 (define_insn "*indirect_jump"
11084 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11085 ""
11086 "jmp\t%A0"
11087 [(set_attr "type" "ibr")
11088 (set_attr "length_immediate" "0")])
11089
11090 (define_expand "tablejump"
11091 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11092 (use (label_ref (match_operand 1 "" "")))])]
11093 ""
11094 {
11095 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11096 relative. Convert the relative address to an absolute address. */
11097 if (flag_pic)
11098 {
11099 rtx op0, op1;
11100 enum rtx_code code;
11101
11102 /* We can't use @GOTOFF for text labels on VxWorks;
11103 see gotoff_operand. */
11104 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11105 {
11106 code = PLUS;
11107 op0 = operands[0];
11108 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11109 }
11110 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11111 {
11112 code = PLUS;
11113 op0 = operands[0];
11114 op1 = pic_offset_table_rtx;
11115 }
11116 else
11117 {
11118 code = MINUS;
11119 op0 = pic_offset_table_rtx;
11120 op1 = operands[0];
11121 }
11122
11123 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11124 OPTAB_DIRECT);
11125 }
11126 else if (TARGET_X32)
11127 operands[0] = convert_memory_address (Pmode, operands[0]);
11128 })
11129
11130 (define_insn "*tablejump_1"
11131 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11132 (use (label_ref (match_operand 1 "" "")))]
11133 ""
11134 "jmp\t%A0"
11135 [(set_attr "type" "ibr")
11136 (set_attr "length_immediate" "0")])
11137 \f
11138 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11139
11140 (define_peephole2
11141 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11142 (set (match_operand:QI 1 "register_operand" "")
11143 (match_operator:QI 2 "ix86_comparison_operator"
11144 [(reg FLAGS_REG) (const_int 0)]))
11145 (set (match_operand 3 "q_regs_operand" "")
11146 (zero_extend (match_dup 1)))]
11147 "(peep2_reg_dead_p (3, operands[1])
11148 || operands_match_p (operands[1], operands[3]))
11149 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11150 [(set (match_dup 4) (match_dup 0))
11151 (set (strict_low_part (match_dup 5))
11152 (match_dup 2))]
11153 {
11154 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11155 operands[5] = gen_lowpart (QImode, operands[3]);
11156 ix86_expand_clear (operands[3]);
11157 })
11158
11159 ;; Similar, but match zero extend with andsi3.
11160
11161 (define_peephole2
11162 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11163 (set (match_operand:QI 1 "register_operand" "")
11164 (match_operator:QI 2 "ix86_comparison_operator"
11165 [(reg FLAGS_REG) (const_int 0)]))
11166 (parallel [(set (match_operand:SI 3 "q_regs_operand" "")
11167 (and:SI (match_dup 3) (const_int 255)))
11168 (clobber (reg:CC FLAGS_REG))])]
11169 "REGNO (operands[1]) == REGNO (operands[3])
11170 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11171 [(set (match_dup 4) (match_dup 0))
11172 (set (strict_low_part (match_dup 5))
11173 (match_dup 2))]
11174 {
11175 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11176 operands[5] = gen_lowpart (QImode, operands[3]);
11177 ix86_expand_clear (operands[3]);
11178 })
11179 \f
11180 ;; Call instructions.
11181
11182 ;; The predicates normally associated with named expanders are not properly
11183 ;; checked for calls. This is a bug in the generic code, but it isn't that
11184 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11185
11186 ;; P6 processors will jump to the address after the decrement when %esp
11187 ;; is used as a call operand, so they will execute return address as a code.
11188 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11189
11190 ;; Register constraint for call instruction.
11191 (define_mode_attr c [(SI "l") (DI "r")])
11192
11193 ;; Call subroutine returning no value.
11194
11195 (define_expand "call"
11196 [(call (match_operand:QI 0 "" "")
11197 (match_operand 1 "" ""))
11198 (use (match_operand 2 "" ""))]
11199 ""
11200 {
11201 ix86_expand_call (NULL, operands[0], operands[1],
11202 operands[2], NULL, false);
11203 DONE;
11204 })
11205
11206 (define_expand "sibcall"
11207 [(call (match_operand:QI 0 "" "")
11208 (match_operand 1 "" ""))
11209 (use (match_operand 2 "" ""))]
11210 ""
11211 {
11212 ix86_expand_call (NULL, operands[0], operands[1],
11213 operands[2], NULL, true);
11214 DONE;
11215 })
11216
11217 (define_insn_and_split "*call_vzeroupper"
11218 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11219 (match_operand 1 "" ""))
11220 (unspec [(match_operand 2 "const_int_operand" "")]
11221 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11222 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11223 "#"
11224 "&& reload_completed"
11225 [(const_int 0)]
11226 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11227 [(set_attr "type" "call")])
11228
11229 (define_insn "*call"
11230 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11231 (match_operand 1 "" ""))]
11232 "!SIBLING_CALL_P (insn)"
11233 "* return ix86_output_call_insn (insn, operands[0]);"
11234 [(set_attr "type" "call")])
11235
11236 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11237 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11238 (match_operand 1 "" ""))
11239 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11240 (clobber (reg:TI XMM6_REG))
11241 (clobber (reg:TI XMM7_REG))
11242 (clobber (reg:TI XMM8_REG))
11243 (clobber (reg:TI XMM9_REG))
11244 (clobber (reg:TI XMM10_REG))
11245 (clobber (reg:TI XMM11_REG))
11246 (clobber (reg:TI XMM12_REG))
11247 (clobber (reg:TI XMM13_REG))
11248 (clobber (reg:TI XMM14_REG))
11249 (clobber (reg:TI XMM15_REG))
11250 (clobber (reg:DI SI_REG))
11251 (clobber (reg:DI DI_REG))
11252 (unspec [(match_operand 2 "const_int_operand" "")]
11253 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11254 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11255 "#"
11256 "&& reload_completed"
11257 [(const_int 0)]
11258 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11259 [(set_attr "type" "call")])
11260
11261 (define_insn "*call_rex64_ms_sysv"
11262 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11263 (match_operand 1 "" ""))
11264 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11265 (clobber (reg:TI XMM6_REG))
11266 (clobber (reg:TI XMM7_REG))
11267 (clobber (reg:TI XMM8_REG))
11268 (clobber (reg:TI XMM9_REG))
11269 (clobber (reg:TI XMM10_REG))
11270 (clobber (reg:TI XMM11_REG))
11271 (clobber (reg:TI XMM12_REG))
11272 (clobber (reg:TI XMM13_REG))
11273 (clobber (reg:TI XMM14_REG))
11274 (clobber (reg:TI XMM15_REG))
11275 (clobber (reg:DI SI_REG))
11276 (clobber (reg:DI DI_REG))]
11277 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11278 "* return ix86_output_call_insn (insn, operands[0]);"
11279 [(set_attr "type" "call")])
11280
11281 (define_insn_and_split "*sibcall_vzeroupper"
11282 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11283 (match_operand 1 "" ""))
11284 (unspec [(match_operand 2 "const_int_operand" "")]
11285 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11286 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11287 "#"
11288 "&& reload_completed"
11289 [(const_int 0)]
11290 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11291 [(set_attr "type" "call")])
11292
11293 (define_insn "*sibcall"
11294 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11295 (match_operand 1 "" ""))]
11296 "SIBLING_CALL_P (insn)"
11297 "* return ix86_output_call_insn (insn, operands[0]);"
11298 [(set_attr "type" "call")])
11299
11300 (define_expand "call_pop"
11301 [(parallel [(call (match_operand:QI 0 "" "")
11302 (match_operand:SI 1 "" ""))
11303 (set (reg:SI SP_REG)
11304 (plus:SI (reg:SI SP_REG)
11305 (match_operand:SI 3 "" "")))])]
11306 "!TARGET_64BIT"
11307 {
11308 ix86_expand_call (NULL, operands[0], operands[1],
11309 operands[2], operands[3], false);
11310 DONE;
11311 })
11312
11313 (define_insn_and_split "*call_pop_vzeroupper"
11314 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11315 (match_operand:SI 1 "" ""))
11316 (set (reg:SI SP_REG)
11317 (plus:SI (reg:SI SP_REG)
11318 (match_operand:SI 2 "immediate_operand" "i")))
11319 (unspec [(match_operand 3 "const_int_operand" "")]
11320 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11321 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11322 "#"
11323 "&& reload_completed"
11324 [(const_int 0)]
11325 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11326 [(set_attr "type" "call")])
11327
11328 (define_insn "*call_pop"
11329 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11330 (match_operand 1 "" ""))
11331 (set (reg:SI SP_REG)
11332 (plus:SI (reg:SI SP_REG)
11333 (match_operand:SI 2 "immediate_operand" "i")))]
11334 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11335 "* return ix86_output_call_insn (insn, operands[0]);"
11336 [(set_attr "type" "call")])
11337
11338 (define_insn_and_split "*sibcall_pop_vzeroupper"
11339 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11340 (match_operand 1 "" ""))
11341 (set (reg:SI SP_REG)
11342 (plus:SI (reg:SI SP_REG)
11343 (match_operand:SI 2 "immediate_operand" "i")))
11344 (unspec [(match_operand 3 "const_int_operand" "")]
11345 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11346 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11347 "#"
11348 "&& reload_completed"
11349 [(const_int 0)]
11350 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11351 [(set_attr "type" "call")])
11352
11353 (define_insn "*sibcall_pop"
11354 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11355 (match_operand 1 "" ""))
11356 (set (reg:SI SP_REG)
11357 (plus:SI (reg:SI SP_REG)
11358 (match_operand:SI 2 "immediate_operand" "i")))]
11359 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11360 "* return ix86_output_call_insn (insn, operands[0]);"
11361 [(set_attr "type" "call")])
11362
11363 ;; Call subroutine, returning value in operand 0
11364
11365 (define_expand "call_value"
11366 [(set (match_operand 0 "" "")
11367 (call (match_operand:QI 1 "" "")
11368 (match_operand 2 "" "")))
11369 (use (match_operand 3 "" ""))]
11370 ""
11371 {
11372 ix86_expand_call (operands[0], operands[1], operands[2],
11373 operands[3], NULL, false);
11374 DONE;
11375 })
11376
11377 (define_expand "sibcall_value"
11378 [(set (match_operand 0 "" "")
11379 (call (match_operand:QI 1 "" "")
11380 (match_operand 2 "" "")))
11381 (use (match_operand 3 "" ""))]
11382 ""
11383 {
11384 ix86_expand_call (operands[0], operands[1], operands[2],
11385 operands[3], NULL, true);
11386 DONE;
11387 })
11388
11389 (define_insn_and_split "*call_value_vzeroupper"
11390 [(set (match_operand 0 "" "")
11391 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11392 (match_operand 2 "" "")))
11393 (unspec [(match_operand 3 "const_int_operand" "")]
11394 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11395 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11396 "#"
11397 "&& reload_completed"
11398 [(const_int 0)]
11399 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11400 [(set_attr "type" "callv")])
11401
11402 (define_insn "*call_value"
11403 [(set (match_operand 0 "" "")
11404 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11405 (match_operand 2 "" "")))]
11406 "!SIBLING_CALL_P (insn)"
11407 "* return ix86_output_call_insn (insn, operands[1]);"
11408 [(set_attr "type" "callv")])
11409
11410 (define_insn_and_split "*sibcall_value_vzeroupper"
11411 [(set (match_operand 0 "" "")
11412 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11413 (match_operand 2 "" "")))
11414 (unspec [(match_operand 3 "const_int_operand" "")]
11415 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11416 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11417 "#"
11418 "&& reload_completed"
11419 [(const_int 0)]
11420 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11421 [(set_attr "type" "callv")])
11422
11423 (define_insn "*sibcall_value"
11424 [(set (match_operand 0 "" "")
11425 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11426 (match_operand 2 "" "")))]
11427 "SIBLING_CALL_P (insn)"
11428 "* return ix86_output_call_insn (insn, operands[1]);"
11429 [(set_attr "type" "callv")])
11430
11431 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11432 [(set (match_operand 0 "" "")
11433 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11434 (match_operand 2 "" "")))
11435 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11436 (clobber (reg:TI XMM6_REG))
11437 (clobber (reg:TI XMM7_REG))
11438 (clobber (reg:TI XMM8_REG))
11439 (clobber (reg:TI XMM9_REG))
11440 (clobber (reg:TI XMM10_REG))
11441 (clobber (reg:TI XMM11_REG))
11442 (clobber (reg:TI XMM12_REG))
11443 (clobber (reg:TI XMM13_REG))
11444 (clobber (reg:TI XMM14_REG))
11445 (clobber (reg:TI XMM15_REG))
11446 (clobber (reg:DI SI_REG))
11447 (clobber (reg:DI DI_REG))
11448 (unspec [(match_operand 3 "const_int_operand" "")]
11449 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11450 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11451 "#"
11452 "&& reload_completed"
11453 [(const_int 0)]
11454 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11455 [(set_attr "type" "callv")])
11456
11457 (define_insn "*call_value_rex64_ms_sysv"
11458 [(set (match_operand 0 "" "")
11459 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11460 (match_operand 2 "" "")))
11461 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11462 (clobber (reg:TI XMM6_REG))
11463 (clobber (reg:TI XMM7_REG))
11464 (clobber (reg:TI XMM8_REG))
11465 (clobber (reg:TI XMM9_REG))
11466 (clobber (reg:TI XMM10_REG))
11467 (clobber (reg:TI XMM11_REG))
11468 (clobber (reg:TI XMM12_REG))
11469 (clobber (reg:TI XMM13_REG))
11470 (clobber (reg:TI XMM14_REG))
11471 (clobber (reg:TI XMM15_REG))
11472 (clobber (reg:DI SI_REG))
11473 (clobber (reg:DI DI_REG))]
11474 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11475 "* return ix86_output_call_insn (insn, operands[1]);"
11476 [(set_attr "type" "callv")])
11477
11478 (define_expand "call_value_pop"
11479 [(parallel [(set (match_operand 0 "" "")
11480 (call (match_operand:QI 1 "" "")
11481 (match_operand:SI 2 "" "")))
11482 (set (reg:SI SP_REG)
11483 (plus:SI (reg:SI SP_REG)
11484 (match_operand:SI 4 "" "")))])]
11485 "!TARGET_64BIT"
11486 {
11487 ix86_expand_call (operands[0], operands[1], operands[2],
11488 operands[3], operands[4], false);
11489 DONE;
11490 })
11491
11492 (define_insn_and_split "*call_value_pop_vzeroupper"
11493 [(set (match_operand 0 "" "")
11494 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11495 (match_operand 2 "" "")))
11496 (set (reg:SI SP_REG)
11497 (plus:SI (reg:SI SP_REG)
11498 (match_operand:SI 3 "immediate_operand" "i")))
11499 (unspec [(match_operand 4 "const_int_operand" "")]
11500 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11501 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11502 "#"
11503 "&& reload_completed"
11504 [(const_int 0)]
11505 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11506 [(set_attr "type" "callv")])
11507
11508 (define_insn "*call_value_pop"
11509 [(set (match_operand 0 "" "")
11510 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11511 (match_operand 2 "" "")))
11512 (set (reg:SI SP_REG)
11513 (plus:SI (reg:SI SP_REG)
11514 (match_operand:SI 3 "immediate_operand" "i")))]
11515 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11516 "* return ix86_output_call_insn (insn, operands[1]);"
11517 [(set_attr "type" "callv")])
11518
11519 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11520 [(set (match_operand 0 "" "")
11521 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11522 (match_operand 2 "" "")))
11523 (set (reg:SI SP_REG)
11524 (plus:SI (reg:SI SP_REG)
11525 (match_operand:SI 3 "immediate_operand" "i")))
11526 (unspec [(match_operand 4 "const_int_operand" "")]
11527 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11528 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11529 "#"
11530 "&& reload_completed"
11531 [(const_int 0)]
11532 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11533 [(set_attr "type" "callv")])
11534
11535 (define_insn "*sibcall_value_pop"
11536 [(set (match_operand 0 "" "")
11537 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11538 (match_operand 2 "" "")))
11539 (set (reg:SI SP_REG)
11540 (plus:SI (reg:SI SP_REG)
11541 (match_operand:SI 3 "immediate_operand" "i")))]
11542 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11543 "* return ix86_output_call_insn (insn, operands[1]);"
11544 [(set_attr "type" "callv")])
11545
11546 ;; Call subroutine returning any type.
11547
11548 (define_expand "untyped_call"
11549 [(parallel [(call (match_operand 0 "" "")
11550 (const_int 0))
11551 (match_operand 1 "" "")
11552 (match_operand 2 "" "")])]
11553 ""
11554 {
11555 int i;
11556
11557 /* In order to give reg-stack an easier job in validating two
11558 coprocessor registers as containing a possible return value,
11559 simply pretend the untyped call returns a complex long double
11560 value.
11561
11562 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11563 and should have the default ABI. */
11564
11565 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11566 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11567 operands[0], const0_rtx,
11568 GEN_INT ((TARGET_64BIT
11569 ? (ix86_abi == SYSV_ABI
11570 ? X86_64_SSE_REGPARM_MAX
11571 : X86_64_MS_SSE_REGPARM_MAX)
11572 : X86_32_SSE_REGPARM_MAX)
11573 - 1),
11574 NULL, false);
11575
11576 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11577 {
11578 rtx set = XVECEXP (operands[2], 0, i);
11579 emit_move_insn (SET_DEST (set), SET_SRC (set));
11580 }
11581
11582 /* The optimizer does not know that the call sets the function value
11583 registers we stored in the result block. We avoid problems by
11584 claiming that all hard registers are used and clobbered at this
11585 point. */
11586 emit_insn (gen_blockage ());
11587
11588 DONE;
11589 })
11590 \f
11591 ;; Prologue and epilogue instructions
11592
11593 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11594 ;; all of memory. This blocks insns from being moved across this point.
11595
11596 (define_insn "blockage"
11597 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11598 ""
11599 ""
11600 [(set_attr "length" "0")])
11601
11602 ;; Do not schedule instructions accessing memory across this point.
11603
11604 (define_expand "memory_blockage"
11605 [(set (match_dup 0)
11606 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11607 ""
11608 {
11609 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11610 MEM_VOLATILE_P (operands[0]) = 1;
11611 })
11612
11613 (define_insn "*memory_blockage"
11614 [(set (match_operand:BLK 0 "" "")
11615 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11616 ""
11617 ""
11618 [(set_attr "length" "0")])
11619
11620 ;; As USE insns aren't meaningful after reload, this is used instead
11621 ;; to prevent deleting instructions setting registers for PIC code
11622 (define_insn "prologue_use"
11623 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11624 ""
11625 ""
11626 [(set_attr "length" "0")])
11627
11628 ;; Insn emitted into the body of a function to return from a function.
11629 ;; This is only done if the function's epilogue is known to be simple.
11630 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11631
11632 (define_expand "return"
11633 [(simple_return)]
11634 "ix86_can_use_return_insn_p ()"
11635 {
11636 ix86_maybe_emit_epilogue_vzeroupper ();
11637 if (crtl->args.pops_args)
11638 {
11639 rtx popc = GEN_INT (crtl->args.pops_args);
11640 emit_jump_insn (gen_simple_return_pop_internal (popc));
11641 DONE;
11642 }
11643 })
11644
11645 ;; We need to disable this for TARGET_SEH, as otherwise
11646 ;; shrink-wrapped prologue gets enabled too. This might exceed
11647 ;; the maximum size of prologue in unwind information.
11648
11649 (define_expand "simple_return"
11650 [(simple_return)]
11651 "!TARGET_SEH"
11652 {
11653 ix86_maybe_emit_epilogue_vzeroupper ();
11654 if (crtl->args.pops_args)
11655 {
11656 rtx popc = GEN_INT (crtl->args.pops_args);
11657 emit_jump_insn (gen_simple_return_pop_internal (popc));
11658 DONE;
11659 }
11660 })
11661
11662 (define_insn "simple_return_internal"
11663 [(simple_return)]
11664 "reload_completed"
11665 "ret"
11666 [(set_attr "length" "1")
11667 (set_attr "atom_unit" "jeu")
11668 (set_attr "length_immediate" "0")
11669 (set_attr "modrm" "0")])
11670
11671 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11672 ;; instruction Athlon and K8 have.
11673
11674 (define_insn "simple_return_internal_long"
11675 [(simple_return)
11676 (unspec [(const_int 0)] UNSPEC_REP)]
11677 "reload_completed"
11678 "rep\;ret"
11679 [(set_attr "length" "2")
11680 (set_attr "atom_unit" "jeu")
11681 (set_attr "length_immediate" "0")
11682 (set_attr "prefix_rep" "1")
11683 (set_attr "modrm" "0")])
11684
11685 (define_insn "simple_return_pop_internal"
11686 [(simple_return)
11687 (use (match_operand:SI 0 "const_int_operand" ""))]
11688 "reload_completed"
11689 "ret\t%0"
11690 [(set_attr "length" "3")
11691 (set_attr "atom_unit" "jeu")
11692 (set_attr "length_immediate" "2")
11693 (set_attr "modrm" "0")])
11694
11695 (define_insn "simple_return_indirect_internal"
11696 [(simple_return)
11697 (use (match_operand:SI 0 "register_operand" "r"))]
11698 "reload_completed"
11699 "jmp\t%A0"
11700 [(set_attr "type" "ibr")
11701 (set_attr "length_immediate" "0")])
11702
11703 (define_insn "nop"
11704 [(const_int 0)]
11705 ""
11706 "nop"
11707 [(set_attr "length" "1")
11708 (set_attr "length_immediate" "0")
11709 (set_attr "modrm" "0")])
11710
11711 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11712 (define_insn "nops"
11713 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11714 UNSPECV_NOPS)]
11715 "reload_completed"
11716 {
11717 int num = INTVAL (operands[0]);
11718
11719 gcc_assert (num >= 1 && num <= 8);
11720
11721 while (num--)
11722 fputs ("\tnop\n", asm_out_file);
11723
11724 return "";
11725 }
11726 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11727 (set_attr "length_immediate" "0")
11728 (set_attr "modrm" "0")])
11729
11730 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11731 ;; branch prediction penalty for the third jump in a 16-byte
11732 ;; block on K8.
11733
11734 (define_insn "pad"
11735 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11736 ""
11737 {
11738 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11739 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11740 #else
11741 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11742 The align insn is used to avoid 3 jump instructions in the row to improve
11743 branch prediction and the benefits hardly outweigh the cost of extra 8
11744 nops on the average inserted by full alignment pseudo operation. */
11745 #endif
11746 return "";
11747 }
11748 [(set_attr "length" "16")])
11749
11750 (define_expand "prologue"
11751 [(const_int 0)]
11752 ""
11753 "ix86_expand_prologue (); DONE;")
11754
11755 (define_insn "set_got"
11756 [(set (match_operand:SI 0 "register_operand" "=r")
11757 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11758 (clobber (reg:CC FLAGS_REG))]
11759 "!TARGET_64BIT"
11760 "* return output_set_got (operands[0], NULL_RTX);"
11761 [(set_attr "type" "multi")
11762 (set_attr "length" "12")])
11763
11764 (define_insn "set_got_labelled"
11765 [(set (match_operand:SI 0 "register_operand" "=r")
11766 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11767 UNSPEC_SET_GOT))
11768 (clobber (reg:CC FLAGS_REG))]
11769 "!TARGET_64BIT"
11770 "* return output_set_got (operands[0], operands[1]);"
11771 [(set_attr "type" "multi")
11772 (set_attr "length" "12")])
11773
11774 (define_insn "set_got_rex64"
11775 [(set (match_operand:DI 0 "register_operand" "=r")
11776 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11777 "TARGET_64BIT"
11778 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11779 [(set_attr "type" "lea")
11780 (set_attr "length_address" "4")
11781 (set_attr "mode" "DI")])
11782
11783 (define_insn "set_rip_rex64"
11784 [(set (match_operand:DI 0 "register_operand" "=r")
11785 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11786 "TARGET_64BIT"
11787 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11788 [(set_attr "type" "lea")
11789 (set_attr "length_address" "4")
11790 (set_attr "mode" "DI")])
11791
11792 (define_insn "set_got_offset_rex64"
11793 [(set (match_operand:DI 0 "register_operand" "=r")
11794 (unspec:DI
11795 [(label_ref (match_operand 1 "" ""))]
11796 UNSPEC_SET_GOT_OFFSET))]
11797 "TARGET_LP64"
11798 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11799 [(set_attr "type" "imov")
11800 (set_attr "length_immediate" "0")
11801 (set_attr "length_address" "8")
11802 (set_attr "mode" "DI")])
11803
11804 (define_expand "epilogue"
11805 [(const_int 0)]
11806 ""
11807 "ix86_expand_epilogue (1); DONE;")
11808
11809 (define_expand "sibcall_epilogue"
11810 [(const_int 0)]
11811 ""
11812 "ix86_expand_epilogue (0); DONE;")
11813
11814 (define_expand "eh_return"
11815 [(use (match_operand 0 "register_operand" ""))]
11816 ""
11817 {
11818 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11819
11820 /* Tricky bit: we write the address of the handler to which we will
11821 be returning into someone else's stack frame, one word below the
11822 stack address we wish to restore. */
11823 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11824 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11825 tmp = gen_rtx_MEM (Pmode, tmp);
11826 emit_move_insn (tmp, ra);
11827
11828 emit_jump_insn (gen_eh_return_internal ());
11829 emit_barrier ();
11830 DONE;
11831 })
11832
11833 (define_insn_and_split "eh_return_internal"
11834 [(eh_return)]
11835 ""
11836 "#"
11837 "epilogue_completed"
11838 [(const_int 0)]
11839 "ix86_expand_epilogue (2); DONE;")
11840
11841 (define_insn "leave"
11842 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11843 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11844 (clobber (mem:BLK (scratch)))]
11845 "!TARGET_64BIT"
11846 "leave"
11847 [(set_attr "type" "leave")])
11848
11849 (define_insn "leave_rex64"
11850 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11851 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11852 (clobber (mem:BLK (scratch)))]
11853 "TARGET_64BIT"
11854 "leave"
11855 [(set_attr "type" "leave")])
11856 \f
11857 ;; Handle -fsplit-stack.
11858
11859 (define_expand "split_stack_prologue"
11860 [(const_int 0)]
11861 ""
11862 {
11863 ix86_expand_split_stack_prologue ();
11864 DONE;
11865 })
11866
11867 ;; In order to support the call/return predictor, we use a return
11868 ;; instruction which the middle-end doesn't see.
11869 (define_insn "split_stack_return"
11870 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11871 UNSPECV_SPLIT_STACK_RETURN)]
11872 ""
11873 {
11874 if (operands[0] == const0_rtx)
11875 return "ret";
11876 else
11877 return "ret\t%0";
11878 }
11879 [(set_attr "atom_unit" "jeu")
11880 (set_attr "modrm" "0")
11881 (set (attr "length")
11882 (if_then_else (match_operand:SI 0 "const0_operand" "")
11883 (const_int 1)
11884 (const_int 3)))
11885 (set (attr "length_immediate")
11886 (if_then_else (match_operand:SI 0 "const0_operand" "")
11887 (const_int 0)
11888 (const_int 2)))])
11889
11890 ;; If there are operand 0 bytes available on the stack, jump to
11891 ;; operand 1.
11892
11893 (define_expand "split_stack_space_check"
11894 [(set (pc) (if_then_else
11895 (ltu (minus (reg SP_REG)
11896 (match_operand 0 "register_operand" ""))
11897 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11898 (label_ref (match_operand 1 "" ""))
11899 (pc)))]
11900 ""
11901 {
11902 rtx reg, size, limit;
11903
11904 reg = gen_reg_rtx (Pmode);
11905 size = force_reg (Pmode, operands[0]);
11906 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11907 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11908 UNSPEC_STACK_CHECK);
11909 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11910 ix86_expand_branch (GEU, reg, limit, operands[1]);
11911
11912 DONE;
11913 })
11914 \f
11915 ;; Bit manipulation instructions.
11916
11917 (define_expand "ffs<mode>2"
11918 [(set (match_dup 2) (const_int -1))
11919 (parallel [(set (reg:CCZ FLAGS_REG)
11920 (compare:CCZ
11921 (match_operand:SWI48 1 "nonimmediate_operand" "")
11922 (const_int 0)))
11923 (set (match_operand:SWI48 0 "register_operand" "")
11924 (ctz:SWI48 (match_dup 1)))])
11925 (set (match_dup 0) (if_then_else:SWI48
11926 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11927 (match_dup 2)
11928 (match_dup 0)))
11929 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11930 (clobber (reg:CC FLAGS_REG))])]
11931 ""
11932 {
11933 if (<MODE>mode == SImode && !TARGET_CMOVE)
11934 {
11935 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11936 DONE;
11937 }
11938 operands[2] = gen_reg_rtx (<MODE>mode);
11939 })
11940
11941 (define_insn_and_split "ffssi2_no_cmove"
11942 [(set (match_operand:SI 0 "register_operand" "=r")
11943 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11944 (clobber (match_scratch:SI 2 "=&q"))
11945 (clobber (reg:CC FLAGS_REG))]
11946 "!TARGET_CMOVE"
11947 "#"
11948 "&& reload_completed"
11949 [(parallel [(set (reg:CCZ FLAGS_REG)
11950 (compare:CCZ (match_dup 1) (const_int 0)))
11951 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11952 (set (strict_low_part (match_dup 3))
11953 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11954 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11955 (clobber (reg:CC FLAGS_REG))])
11956 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11957 (clobber (reg:CC FLAGS_REG))])
11958 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11959 (clobber (reg:CC FLAGS_REG))])]
11960 {
11961 operands[3] = gen_lowpart (QImode, operands[2]);
11962 ix86_expand_clear (operands[2]);
11963 })
11964
11965 (define_insn "*ffs<mode>_1"
11966 [(set (reg:CCZ FLAGS_REG)
11967 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11968 (const_int 0)))
11969 (set (match_operand:SWI48 0 "register_operand" "=r")
11970 (ctz:SWI48 (match_dup 1)))]
11971 ""
11972 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11973 [(set_attr "type" "alu1")
11974 (set_attr "prefix_0f" "1")
11975 (set_attr "mode" "<MODE>")])
11976
11977 (define_insn "ctz<mode>2"
11978 [(set (match_operand:SWI248 0 "register_operand" "=r")
11979 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11980 (clobber (reg:CC FLAGS_REG))]
11981 ""
11982 {
11983 if (TARGET_BMI)
11984 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11985 else
11986 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11987 }
11988 [(set_attr "type" "alu1")
11989 (set_attr "prefix_0f" "1")
11990 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11991 (set_attr "mode" "<MODE>")])
11992
11993 (define_expand "clz<mode>2"
11994 [(parallel
11995 [(set (match_operand:SWI248 0 "register_operand" "")
11996 (minus:SWI248
11997 (match_dup 2)
11998 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11999 (clobber (reg:CC FLAGS_REG))])
12000 (parallel
12001 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12002 (clobber (reg:CC FLAGS_REG))])]
12003 ""
12004 {
12005 if (TARGET_LZCNT)
12006 {
12007 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12008 DONE;
12009 }
12010 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12011 })
12012
12013 (define_insn "clz<mode>2_lzcnt"
12014 [(set (match_operand:SWI248 0 "register_operand" "=r")
12015 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12016 (clobber (reg:CC FLAGS_REG))]
12017 "TARGET_LZCNT"
12018 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12019 [(set_attr "prefix_rep" "1")
12020 (set_attr "type" "bitmanip")
12021 (set_attr "mode" "<MODE>")])
12022
12023 ;; BMI instructions.
12024 (define_insn "*bmi_andn_<mode>"
12025 [(set (match_operand:SWI48 0 "register_operand" "=r")
12026 (and:SWI48
12027 (not:SWI48
12028 (match_operand:SWI48 1 "register_operand" "r"))
12029 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12030 (clobber (reg:CC FLAGS_REG))]
12031 "TARGET_BMI"
12032 "andn\t{%2, %1, %0|%0, %1, %2}"
12033 [(set_attr "type" "bitmanip")
12034 (set_attr "mode" "<MODE>")])
12035
12036 (define_insn "bmi_bextr_<mode>"
12037 [(set (match_operand:SWI48 0 "register_operand" "=r")
12038 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12039 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12040 UNSPEC_BEXTR))
12041 (clobber (reg:CC FLAGS_REG))]
12042 "TARGET_BMI"
12043 "bextr\t{%2, %1, %0|%0, %1, %2}"
12044 [(set_attr "type" "bitmanip")
12045 (set_attr "mode" "<MODE>")])
12046
12047 (define_insn "*bmi_blsi_<mode>"
12048 [(set (match_operand:SWI48 0 "register_operand" "=r")
12049 (and:SWI48
12050 (neg:SWI48
12051 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12052 (match_dup 1)))
12053 (clobber (reg:CC FLAGS_REG))]
12054 "TARGET_BMI"
12055 "blsi\t{%1, %0|%0, %1}"
12056 [(set_attr "type" "bitmanip")
12057 (set_attr "mode" "<MODE>")])
12058
12059 (define_insn "*bmi_blsmsk_<mode>"
12060 [(set (match_operand:SWI48 0 "register_operand" "=r")
12061 (xor:SWI48
12062 (plus:SWI48
12063 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12064 (const_int -1))
12065 (match_dup 1)))
12066 (clobber (reg:CC FLAGS_REG))]
12067 "TARGET_BMI"
12068 "blsmsk\t{%1, %0|%0, %1}"
12069 [(set_attr "type" "bitmanip")
12070 (set_attr "mode" "<MODE>")])
12071
12072 (define_insn "*bmi_blsr_<mode>"
12073 [(set (match_operand:SWI48 0 "register_operand" "=r")
12074 (and:SWI48
12075 (plus:SWI48
12076 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12077 (const_int -1))
12078 (match_dup 1)))
12079 (clobber (reg:CC FLAGS_REG))]
12080 "TARGET_BMI"
12081 "blsr\t{%1, %0|%0, %1}"
12082 [(set_attr "type" "bitmanip")
12083 (set_attr "mode" "<MODE>")])
12084
12085 ;; BMI2 instructions.
12086 (define_insn "bmi2_bzhi_<mode>3"
12087 [(set (match_operand:SWI48 0 "register_operand" "=r")
12088 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12089 (lshiftrt:SWI48 (const_int -1)
12090 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12091 (clobber (reg:CC FLAGS_REG))]
12092 "TARGET_BMI2"
12093 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12094 [(set_attr "type" "bitmanip")
12095 (set_attr "prefix" "vex")
12096 (set_attr "mode" "<MODE>")])
12097
12098 (define_insn "bmi2_pdep_<mode>3"
12099 [(set (match_operand:SWI48 0 "register_operand" "=r")
12100 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12101 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12102 UNSPEC_PDEP))]
12103 "TARGET_BMI2"
12104 "pdep\t{%2, %1, %0|%0, %1, %2}"
12105 [(set_attr "type" "bitmanip")
12106 (set_attr "prefix" "vex")
12107 (set_attr "mode" "<MODE>")])
12108
12109 (define_insn "bmi2_pext_<mode>3"
12110 [(set (match_operand:SWI48 0 "register_operand" "=r")
12111 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12112 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12113 UNSPEC_PEXT))]
12114 "TARGET_BMI2"
12115 "pext\t{%2, %1, %0|%0, %1, %2}"
12116 [(set_attr "type" "bitmanip")
12117 (set_attr "prefix" "vex")
12118 (set_attr "mode" "<MODE>")])
12119
12120 ;; TBM instructions.
12121 (define_insn "tbm_bextri_<mode>"
12122 [(set (match_operand:SWI48 0 "register_operand" "=r")
12123 (zero_extract:SWI48
12124 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12125 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12126 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "TARGET_TBM"
12129 {
12130 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12131 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12132 }
12133 [(set_attr "type" "bitmanip")
12134 (set_attr "mode" "<MODE>")])
12135
12136 (define_insn "*tbm_blcfill_<mode>"
12137 [(set (match_operand:SWI48 0 "register_operand" "=r")
12138 (and:SWI48
12139 (plus:SWI48
12140 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12141 (const_int 1))
12142 (match_dup 1)))
12143 (clobber (reg:CC FLAGS_REG))]
12144 "TARGET_TBM"
12145 "blcfill\t{%1, %0|%0, %1}"
12146 [(set_attr "type" "bitmanip")
12147 (set_attr "mode" "<MODE>")])
12148
12149 (define_insn "*tbm_blci_<mode>"
12150 [(set (match_operand:SWI48 0 "register_operand" "=r")
12151 (ior:SWI48
12152 (not:SWI48
12153 (plus:SWI48
12154 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12155 (const_int 1)))
12156 (match_dup 1)))
12157 (clobber (reg:CC FLAGS_REG))]
12158 "TARGET_TBM"
12159 "blci\t{%1, %0|%0, %1}"
12160 [(set_attr "type" "bitmanip")
12161 (set_attr "mode" "<MODE>")])
12162
12163 (define_insn "*tbm_blcic_<mode>"
12164 [(set (match_operand:SWI48 0 "register_operand" "=r")
12165 (and:SWI48
12166 (plus:SWI48
12167 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12168 (const_int 1))
12169 (not:SWI48
12170 (match_dup 1))))
12171 (clobber (reg:CC FLAGS_REG))]
12172 "TARGET_TBM"
12173 "blcic\t{%1, %0|%0, %1}"
12174 [(set_attr "type" "bitmanip")
12175 (set_attr "mode" "<MODE>")])
12176
12177 (define_insn "*tbm_blcmsk_<mode>"
12178 [(set (match_operand:SWI48 0 "register_operand" "=r")
12179 (xor:SWI48
12180 (plus:SWI48
12181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12182 (const_int 1))
12183 (match_dup 1)))
12184 (clobber (reg:CC FLAGS_REG))]
12185 "TARGET_TBM"
12186 "blcmsk\t{%1, %0|%0, %1}"
12187 [(set_attr "type" "bitmanip")
12188 (set_attr "mode" "<MODE>")])
12189
12190 (define_insn "*tbm_blcs_<mode>"
12191 [(set (match_operand:SWI48 0 "register_operand" "=r")
12192 (ior:SWI48
12193 (plus:SWI48
12194 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12195 (const_int 1))
12196 (match_dup 1)))
12197 (clobber (reg:CC FLAGS_REG))]
12198 "TARGET_TBM"
12199 "blcs\t{%1, %0|%0, %1}"
12200 [(set_attr "type" "bitmanip")
12201 (set_attr "mode" "<MODE>")])
12202
12203 (define_insn "*tbm_blsfill_<mode>"
12204 [(set (match_operand:SWI48 0 "register_operand" "=r")
12205 (ior:SWI48
12206 (plus:SWI48
12207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12208 (const_int -1))
12209 (match_dup 1)))
12210 (clobber (reg:CC FLAGS_REG))]
12211 "TARGET_TBM"
12212 "blsfill\t{%1, %0|%0, %1}"
12213 [(set_attr "type" "bitmanip")
12214 (set_attr "mode" "<MODE>")])
12215
12216 (define_insn "*tbm_blsic_<mode>"
12217 [(set (match_operand:SWI48 0 "register_operand" "=r")
12218 (ior:SWI48
12219 (plus:SWI48
12220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221 (const_int -1))
12222 (not:SWI48
12223 (match_dup 1))))
12224 (clobber (reg:CC FLAGS_REG))]
12225 "TARGET_TBM"
12226 "blsic\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12229
12230 (define_insn "*tbm_t1mskc_<mode>"
12231 [(set (match_operand:SWI48 0 "register_operand" "=r")
12232 (ior:SWI48
12233 (plus:SWI48
12234 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235 (const_int 1))
12236 (not:SWI48
12237 (match_dup 1))))
12238 (clobber (reg:CC FLAGS_REG))]
12239 "TARGET_TBM"
12240 "t1mskc\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip")
12242 (set_attr "mode" "<MODE>")])
12243
12244 (define_insn "*tbm_tzmsk_<mode>"
12245 [(set (match_operand:SWI48 0 "register_operand" "=r")
12246 (and:SWI48
12247 (plus:SWI48
12248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12249 (const_int -1))
12250 (not:SWI48
12251 (match_dup 1))))
12252 (clobber (reg:CC FLAGS_REG))]
12253 "TARGET_TBM"
12254 "tzmsk\t{%1, %0|%0, %1}"
12255 [(set_attr "type" "bitmanip")
12256 (set_attr "mode" "<MODE>")])
12257
12258 (define_insn "bsr_rex64"
12259 [(set (match_operand:DI 0 "register_operand" "=r")
12260 (minus:DI (const_int 63)
12261 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12262 (clobber (reg:CC FLAGS_REG))]
12263 "TARGET_64BIT"
12264 "bsr{q}\t{%1, %0|%0, %1}"
12265 [(set_attr "type" "alu1")
12266 (set_attr "prefix_0f" "1")
12267 (set_attr "mode" "DI")])
12268
12269 (define_insn "bsr"
12270 [(set (match_operand:SI 0 "register_operand" "=r")
12271 (minus:SI (const_int 31)
12272 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12273 (clobber (reg:CC FLAGS_REG))]
12274 ""
12275 "bsr{l}\t{%1, %0|%0, %1}"
12276 [(set_attr "type" "alu1")
12277 (set_attr "prefix_0f" "1")
12278 (set_attr "mode" "SI")])
12279
12280 (define_insn "*bsrhi"
12281 [(set (match_operand:HI 0 "register_operand" "=r")
12282 (minus:HI (const_int 15)
12283 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12284 (clobber (reg:CC FLAGS_REG))]
12285 ""
12286 "bsr{w}\t{%1, %0|%0, %1}"
12287 [(set_attr "type" "alu1")
12288 (set_attr "prefix_0f" "1")
12289 (set_attr "mode" "HI")])
12290
12291 (define_insn "popcount<mode>2"
12292 [(set (match_operand:SWI248 0 "register_operand" "=r")
12293 (popcount:SWI248
12294 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12295 (clobber (reg:CC FLAGS_REG))]
12296 "TARGET_POPCNT"
12297 {
12298 #if TARGET_MACHO
12299 return "popcnt\t{%1, %0|%0, %1}";
12300 #else
12301 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12302 #endif
12303 }
12304 [(set_attr "prefix_rep" "1")
12305 (set_attr "type" "bitmanip")
12306 (set_attr "mode" "<MODE>")])
12307
12308 (define_insn "*popcount<mode>2_cmp"
12309 [(set (reg FLAGS_REG)
12310 (compare
12311 (popcount:SWI248
12312 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12313 (const_int 0)))
12314 (set (match_operand:SWI248 0 "register_operand" "=r")
12315 (popcount:SWI248 (match_dup 1)))]
12316 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12317 {
12318 #if TARGET_MACHO
12319 return "popcnt\t{%1, %0|%0, %1}";
12320 #else
12321 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12322 #endif
12323 }
12324 [(set_attr "prefix_rep" "1")
12325 (set_attr "type" "bitmanip")
12326 (set_attr "mode" "<MODE>")])
12327
12328 (define_insn "*popcountsi2_cmp_zext"
12329 [(set (reg FLAGS_REG)
12330 (compare
12331 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12332 (const_int 0)))
12333 (set (match_operand:DI 0 "register_operand" "=r")
12334 (zero_extend:DI(popcount:SI (match_dup 1))))]
12335 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12336 {
12337 #if TARGET_MACHO
12338 return "popcnt\t{%1, %0|%0, %1}";
12339 #else
12340 return "popcnt{l}\t{%1, %0|%0, %1}";
12341 #endif
12342 }
12343 [(set_attr "prefix_rep" "1")
12344 (set_attr "type" "bitmanip")
12345 (set_attr "mode" "SI")])
12346
12347 (define_expand "bswap<mode>2"
12348 [(set (match_operand:SWI48 0 "register_operand" "")
12349 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12350 ""
12351 {
12352 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12353 {
12354 rtx x = operands[0];
12355
12356 emit_move_insn (x, operands[1]);
12357 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12358 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12359 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12360 DONE;
12361 }
12362 })
12363
12364 (define_insn "*bswap<mode>2_movbe"
12365 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12366 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12367 "TARGET_MOVBE
12368 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12369 "@
12370 bswap\t%0
12371 movbe\t{%1, %0|%0, %1}
12372 movbe\t{%1, %0|%0, %1}"
12373 [(set_attr "type" "bitmanip,imov,imov")
12374 (set_attr "modrm" "0,1,1")
12375 (set_attr "prefix_0f" "*,1,1")
12376 (set_attr "prefix_extra" "*,1,1")
12377 (set_attr "mode" "<MODE>")])
12378
12379 (define_insn "*bswap<mode>2_1"
12380 [(set (match_operand:SWI48 0 "register_operand" "=r")
12381 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12382 "TARGET_BSWAP"
12383 "bswap\t%0"
12384 [(set_attr "type" "bitmanip")
12385 (set_attr "modrm" "0")
12386 (set_attr "mode" "<MODE>")])
12387
12388 (define_insn "*bswaphi_lowpart_1"
12389 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12390 (bswap:HI (match_dup 0)))
12391 (clobber (reg:CC FLAGS_REG))]
12392 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12393 "@
12394 xchg{b}\t{%h0, %b0|%b0, %h0}
12395 rol{w}\t{$8, %0|%0, 8}"
12396 [(set_attr "length" "2,4")
12397 (set_attr "mode" "QI,HI")])
12398
12399 (define_insn "bswaphi_lowpart"
12400 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12401 (bswap:HI (match_dup 0)))
12402 (clobber (reg:CC FLAGS_REG))]
12403 ""
12404 "rol{w}\t{$8, %0|%0, 8}"
12405 [(set_attr "length" "4")
12406 (set_attr "mode" "HI")])
12407
12408 (define_expand "paritydi2"
12409 [(set (match_operand:DI 0 "register_operand" "")
12410 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12411 "! TARGET_POPCNT"
12412 {
12413 rtx scratch = gen_reg_rtx (QImode);
12414 rtx cond;
12415
12416 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12417 NULL_RTX, operands[1]));
12418
12419 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12420 gen_rtx_REG (CCmode, FLAGS_REG),
12421 const0_rtx);
12422 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12423
12424 if (TARGET_64BIT)
12425 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12426 else
12427 {
12428 rtx tmp = gen_reg_rtx (SImode);
12429
12430 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12431 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12432 }
12433 DONE;
12434 })
12435
12436 (define_expand "paritysi2"
12437 [(set (match_operand:SI 0 "register_operand" "")
12438 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12439 "! TARGET_POPCNT"
12440 {
12441 rtx scratch = gen_reg_rtx (QImode);
12442 rtx cond;
12443
12444 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12445
12446 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12447 gen_rtx_REG (CCmode, FLAGS_REG),
12448 const0_rtx);
12449 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12450
12451 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12452 DONE;
12453 })
12454
12455 (define_insn_and_split "paritydi2_cmp"
12456 [(set (reg:CC FLAGS_REG)
12457 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12458 UNSPEC_PARITY))
12459 (clobber (match_scratch:DI 0 "=r"))
12460 (clobber (match_scratch:SI 1 "=&r"))
12461 (clobber (match_scratch:HI 2 "=Q"))]
12462 "! TARGET_POPCNT"
12463 "#"
12464 "&& reload_completed"
12465 [(parallel
12466 [(set (match_dup 1)
12467 (xor:SI (match_dup 1) (match_dup 4)))
12468 (clobber (reg:CC FLAGS_REG))])
12469 (parallel
12470 [(set (reg:CC FLAGS_REG)
12471 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12472 (clobber (match_dup 1))
12473 (clobber (match_dup 2))])]
12474 {
12475 operands[4] = gen_lowpart (SImode, operands[3]);
12476
12477 if (TARGET_64BIT)
12478 {
12479 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12480 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12481 }
12482 else
12483 operands[1] = gen_highpart (SImode, operands[3]);
12484 })
12485
12486 (define_insn_and_split "paritysi2_cmp"
12487 [(set (reg:CC FLAGS_REG)
12488 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12489 UNSPEC_PARITY))
12490 (clobber (match_scratch:SI 0 "=r"))
12491 (clobber (match_scratch:HI 1 "=&Q"))]
12492 "! TARGET_POPCNT"
12493 "#"
12494 "&& reload_completed"
12495 [(parallel
12496 [(set (match_dup 1)
12497 (xor:HI (match_dup 1) (match_dup 3)))
12498 (clobber (reg:CC FLAGS_REG))])
12499 (parallel
12500 [(set (reg:CC FLAGS_REG)
12501 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12502 (clobber (match_dup 1))])]
12503 {
12504 operands[3] = gen_lowpart (HImode, operands[2]);
12505
12506 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12507 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12508 })
12509
12510 (define_insn "*parityhi2_cmp"
12511 [(set (reg:CC FLAGS_REG)
12512 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12513 UNSPEC_PARITY))
12514 (clobber (match_scratch:HI 0 "=Q"))]
12515 "! TARGET_POPCNT"
12516 "xor{b}\t{%h0, %b0|%b0, %h0}"
12517 [(set_attr "length" "2")
12518 (set_attr "mode" "HI")])
12519
12520 \f
12521 ;; Thread-local storage patterns for ELF.
12522 ;;
12523 ;; Note that these code sequences must appear exactly as shown
12524 ;; in order to allow linker relaxation.
12525
12526 (define_insn "*tls_global_dynamic_32_gnu"
12527 [(set (match_operand:SI 0 "register_operand" "=a")
12528 (unspec:SI
12529 [(match_operand:SI 1 "register_operand" "b")
12530 (match_operand:SI 2 "tls_symbolic_operand" "")
12531 (match_operand:SI 3 "constant_call_address_operand" "z")]
12532 UNSPEC_TLS_GD))
12533 (clobber (match_scratch:SI 4 "=d"))
12534 (clobber (match_scratch:SI 5 "=c"))
12535 (clobber (reg:CC FLAGS_REG))]
12536 "!TARGET_64BIT && TARGET_GNU_TLS"
12537 {
12538 output_asm_insn
12539 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12540 if (TARGET_SUN_TLS)
12541 #ifdef HAVE_AS_IX86_TLSGDPLT
12542 return "call\t%a2@tlsgdplt";
12543 #else
12544 return "call\t%p3@plt";
12545 #endif
12546 return "call\t%P3";
12547 }
12548 [(set_attr "type" "multi")
12549 (set_attr "length" "12")])
12550
12551 (define_expand "tls_global_dynamic_32"
12552 [(parallel
12553 [(set (match_operand:SI 0 "register_operand" "")
12554 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12555 (match_operand:SI 1 "tls_symbolic_operand" "")
12556 (match_operand:SI 3 "constant_call_address_operand" "")]
12557 UNSPEC_TLS_GD))
12558 (clobber (match_scratch:SI 4 ""))
12559 (clobber (match_scratch:SI 5 ""))
12560 (clobber (reg:CC FLAGS_REG))])])
12561
12562 (define_insn "*tls_global_dynamic_64"
12563 [(set (match_operand:DI 0 "register_operand" "=a")
12564 (call:DI
12565 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12566 (match_operand:DI 3 "" "")))
12567 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12568 UNSPEC_TLS_GD)]
12569 "TARGET_64BIT"
12570 {
12571 if (!TARGET_X32)
12572 fputs (ASM_BYTE "0x66\n", asm_out_file);
12573 output_asm_insn
12574 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12575 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12576 fputs ("\trex64\n", asm_out_file);
12577 if (TARGET_SUN_TLS)
12578 return "call\t%p2@plt";
12579 return "call\t%P2";
12580 }
12581 [(set_attr "type" "multi")
12582 (set (attr "length")
12583 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12584
12585 (define_expand "tls_global_dynamic_64"
12586 [(parallel
12587 [(set (match_operand:DI 0 "register_operand" "")
12588 (call:DI
12589 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12590 (const_int 0)))
12591 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12592 UNSPEC_TLS_GD)])])
12593
12594 (define_insn "*tls_local_dynamic_base_32_gnu"
12595 [(set (match_operand:SI 0 "register_operand" "=a")
12596 (unspec:SI
12597 [(match_operand:SI 1 "register_operand" "b")
12598 (match_operand:SI 2 "constant_call_address_operand" "z")]
12599 UNSPEC_TLS_LD_BASE))
12600 (clobber (match_scratch:SI 3 "=d"))
12601 (clobber (match_scratch:SI 4 "=c"))
12602 (clobber (reg:CC FLAGS_REG))]
12603 "!TARGET_64BIT && TARGET_GNU_TLS"
12604 {
12605 output_asm_insn
12606 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12607 if (TARGET_SUN_TLS)
12608 #ifdef HAVE_AS_IX86_TLSLDMPLT
12609 return "call\t%&@tlsldmplt";
12610 #else
12611 return "call\t%p2@plt";
12612 #endif
12613 return "call\t%P2";
12614 }
12615 [(set_attr "type" "multi")
12616 (set_attr "length" "11")])
12617
12618 (define_expand "tls_local_dynamic_base_32"
12619 [(parallel
12620 [(set (match_operand:SI 0 "register_operand" "")
12621 (unspec:SI
12622 [(match_operand:SI 1 "register_operand" "")
12623 (match_operand:SI 2 "constant_call_address_operand" "")]
12624 UNSPEC_TLS_LD_BASE))
12625 (clobber (match_scratch:SI 3 ""))
12626 (clobber (match_scratch:SI 4 ""))
12627 (clobber (reg:CC FLAGS_REG))])])
12628
12629 (define_insn "*tls_local_dynamic_base_64"
12630 [(set (match_operand:DI 0 "register_operand" "=a")
12631 (call:DI
12632 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12633 (match_operand:DI 2 "" "")))
12634 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12635 "TARGET_64BIT"
12636 {
12637 output_asm_insn
12638 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12639 if (TARGET_SUN_TLS)
12640 return "call\t%p1@plt";
12641 return "call\t%P1";
12642 }
12643 [(set_attr "type" "multi")
12644 (set_attr "length" "12")])
12645
12646 (define_expand "tls_local_dynamic_base_64"
12647 [(parallel
12648 [(set (match_operand:DI 0 "register_operand" "")
12649 (call:DI
12650 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12651 (const_int 0)))
12652 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12653
12654 ;; Local dynamic of a single variable is a lose. Show combine how
12655 ;; to convert that back to global dynamic.
12656
12657 (define_insn_and_split "*tls_local_dynamic_32_once"
12658 [(set (match_operand:SI 0 "register_operand" "=a")
12659 (plus:SI
12660 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12661 (match_operand:SI 2 "constant_call_address_operand" "z")]
12662 UNSPEC_TLS_LD_BASE)
12663 (const:SI (unspec:SI
12664 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12665 UNSPEC_DTPOFF))))
12666 (clobber (match_scratch:SI 4 "=d"))
12667 (clobber (match_scratch:SI 5 "=c"))
12668 (clobber (reg:CC FLAGS_REG))]
12669 ""
12670 "#"
12671 ""
12672 [(parallel
12673 [(set (match_dup 0)
12674 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12675 UNSPEC_TLS_GD))
12676 (clobber (match_dup 4))
12677 (clobber (match_dup 5))
12678 (clobber (reg:CC FLAGS_REG))])])
12679
12680 ;; Segment register for the thread base ptr load
12681 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12682
12683 ;; Load and add the thread base pointer from %<tp_seg>:0.
12684 (define_insn "*load_tp_x32"
12685 [(set (match_operand:SI 0 "register_operand" "=r")
12686 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12687 "TARGET_X32"
12688 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12689 [(set_attr "type" "imov")
12690 (set_attr "modrm" "0")
12691 (set_attr "length" "7")
12692 (set_attr "memory" "load")
12693 (set_attr "imm_disp" "false")])
12694
12695 (define_insn "*load_tp_x32_zext"
12696 [(set (match_operand:DI 0 "register_operand" "=r")
12697 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12698 "TARGET_X32"
12699 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12700 [(set_attr "type" "imov")
12701 (set_attr "modrm" "0")
12702 (set_attr "length" "7")
12703 (set_attr "memory" "load")
12704 (set_attr "imm_disp" "false")])
12705
12706 (define_insn "*load_tp_<mode>"
12707 [(set (match_operand:P 0 "register_operand" "=r")
12708 (unspec:P [(const_int 0)] UNSPEC_TP))]
12709 "!TARGET_X32"
12710 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12711 [(set_attr "type" "imov")
12712 (set_attr "modrm" "0")
12713 (set_attr "length" "7")
12714 (set_attr "memory" "load")
12715 (set_attr "imm_disp" "false")])
12716
12717 (define_insn "*add_tp_x32"
12718 [(set (match_operand:SI 0 "register_operand" "=r")
12719 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12720 (match_operand:SI 1 "register_operand" "0")))
12721 (clobber (reg:CC FLAGS_REG))]
12722 "TARGET_X32"
12723 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12724 [(set_attr "type" "alu")
12725 (set_attr "modrm" "0")
12726 (set_attr "length" "7")
12727 (set_attr "memory" "load")
12728 (set_attr "imm_disp" "false")])
12729
12730 (define_insn "*add_tp_x32_zext"
12731 [(set (match_operand:DI 0 "register_operand" "=r")
12732 (zero_extend:DI
12733 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12734 (match_operand:SI 1 "register_operand" "0"))))
12735 (clobber (reg:CC FLAGS_REG))]
12736 "TARGET_X32"
12737 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12738 [(set_attr "type" "alu")
12739 (set_attr "modrm" "0")
12740 (set_attr "length" "7")
12741 (set_attr "memory" "load")
12742 (set_attr "imm_disp" "false")])
12743
12744 (define_insn "*add_tp_<mode>"
12745 [(set (match_operand:P 0 "register_operand" "=r")
12746 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12747 (match_operand:P 1 "register_operand" "0")))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "!TARGET_X32"
12750 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12751 [(set_attr "type" "alu")
12752 (set_attr "modrm" "0")
12753 (set_attr "length" "7")
12754 (set_attr "memory" "load")
12755 (set_attr "imm_disp" "false")])
12756
12757 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12758 ;; %rax as destination of the initial executable code sequence.
12759 (define_insn "tls_initial_exec_64_sun"
12760 [(set (match_operand:DI 0 "register_operand" "=a")
12761 (unspec:DI
12762 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12763 UNSPEC_TLS_IE_SUN))
12764 (clobber (reg:CC FLAGS_REG))]
12765 "TARGET_64BIT && TARGET_SUN_TLS"
12766 {
12767 output_asm_insn
12768 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12769 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12770 }
12771 [(set_attr "type" "multi")])
12772
12773 ;; GNU2 TLS patterns can be split.
12774
12775 (define_expand "tls_dynamic_gnu2_32"
12776 [(set (match_dup 3)
12777 (plus:SI (match_operand:SI 2 "register_operand" "")
12778 (const:SI
12779 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12780 UNSPEC_TLSDESC))))
12781 (parallel
12782 [(set (match_operand:SI 0 "register_operand" "")
12783 (unspec:SI [(match_dup 1) (match_dup 3)
12784 (match_dup 2) (reg:SI SP_REG)]
12785 UNSPEC_TLSDESC))
12786 (clobber (reg:CC FLAGS_REG))])]
12787 "!TARGET_64BIT && TARGET_GNU2_TLS"
12788 {
12789 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12790 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12791 })
12792
12793 (define_insn "*tls_dynamic_gnu2_lea_32"
12794 [(set (match_operand:SI 0 "register_operand" "=r")
12795 (plus:SI (match_operand:SI 1 "register_operand" "b")
12796 (const:SI
12797 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12798 UNSPEC_TLSDESC))))]
12799 "!TARGET_64BIT && TARGET_GNU2_TLS"
12800 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12801 [(set_attr "type" "lea")
12802 (set_attr "mode" "SI")
12803 (set_attr "length" "6")
12804 (set_attr "length_address" "4")])
12805
12806 (define_insn "*tls_dynamic_gnu2_call_32"
12807 [(set (match_operand:SI 0 "register_operand" "=a")
12808 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12809 (match_operand:SI 2 "register_operand" "0")
12810 ;; we have to make sure %ebx still points to the GOT
12811 (match_operand:SI 3 "register_operand" "b")
12812 (reg:SI SP_REG)]
12813 UNSPEC_TLSDESC))
12814 (clobber (reg:CC FLAGS_REG))]
12815 "!TARGET_64BIT && TARGET_GNU2_TLS"
12816 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12817 [(set_attr "type" "call")
12818 (set_attr "length" "2")
12819 (set_attr "length_address" "0")])
12820
12821 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12822 [(set (match_operand:SI 0 "register_operand" "=&a")
12823 (plus:SI
12824 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12825 (match_operand:SI 4 "" "")
12826 (match_operand:SI 2 "register_operand" "b")
12827 (reg:SI SP_REG)]
12828 UNSPEC_TLSDESC)
12829 (const:SI (unspec:SI
12830 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12831 UNSPEC_DTPOFF))))
12832 (clobber (reg:CC FLAGS_REG))]
12833 "!TARGET_64BIT && TARGET_GNU2_TLS"
12834 "#"
12835 ""
12836 [(set (match_dup 0) (match_dup 5))]
12837 {
12838 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12839 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12840 })
12841
12842 (define_expand "tls_dynamic_gnu2_64"
12843 [(set (match_dup 2)
12844 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12845 UNSPEC_TLSDESC))
12846 (parallel
12847 [(set (match_operand:DI 0 "register_operand" "")
12848 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12849 UNSPEC_TLSDESC))
12850 (clobber (reg:CC FLAGS_REG))])]
12851 "TARGET_64BIT && TARGET_GNU2_TLS"
12852 {
12853 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12854 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12855 })
12856
12857 (define_insn "*tls_dynamic_gnu2_lea_64"
12858 [(set (match_operand:DI 0 "register_operand" "=r")
12859 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12860 UNSPEC_TLSDESC))]
12861 "TARGET_64BIT && TARGET_GNU2_TLS"
12862 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12863 [(set_attr "type" "lea")
12864 (set_attr "mode" "DI")
12865 (set_attr "length" "7")
12866 (set_attr "length_address" "4")])
12867
12868 (define_insn "*tls_dynamic_gnu2_call_64"
12869 [(set (match_operand:DI 0 "register_operand" "=a")
12870 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12871 (match_operand:DI 2 "register_operand" "0")
12872 (reg:DI SP_REG)]
12873 UNSPEC_TLSDESC))
12874 (clobber (reg:CC FLAGS_REG))]
12875 "TARGET_64BIT && TARGET_GNU2_TLS"
12876 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12877 [(set_attr "type" "call")
12878 (set_attr "length" "2")
12879 (set_attr "length_address" "0")])
12880
12881 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12882 [(set (match_operand:DI 0 "register_operand" "=&a")
12883 (plus:DI
12884 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12885 (match_operand:DI 3 "" "")
12886 (reg:DI SP_REG)]
12887 UNSPEC_TLSDESC)
12888 (const:DI (unspec:DI
12889 [(match_operand 1 "tls_symbolic_operand" "")]
12890 UNSPEC_DTPOFF))))
12891 (clobber (reg:CC FLAGS_REG))]
12892 "TARGET_64BIT && TARGET_GNU2_TLS"
12893 "#"
12894 ""
12895 [(set (match_dup 0) (match_dup 4))]
12896 {
12897 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12898 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12899 })
12900 \f
12901 ;; These patterns match the binary 387 instructions for addM3, subM3,
12902 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12903 ;; SFmode. The first is the normal insn, the second the same insn but
12904 ;; with one operand a conversion, and the third the same insn but with
12905 ;; the other operand a conversion. The conversion may be SFmode or
12906 ;; SImode if the target mode DFmode, but only SImode if the target mode
12907 ;; is SFmode.
12908
12909 ;; Gcc is slightly more smart about handling normal two address instructions
12910 ;; so use special patterns for add and mull.
12911
12912 (define_insn "*fop_<mode>_comm_mixed"
12913 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12914 (match_operator:MODEF 3 "binary_fp_operator"
12915 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12916 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12917 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12918 && COMMUTATIVE_ARITH_P (operands[3])
12919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12920 "* return output_387_binary_op (insn, operands);"
12921 [(set (attr "type")
12922 (if_then_else (eq_attr "alternative" "1,2")
12923 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12924 (const_string "ssemul")
12925 (const_string "sseadd"))
12926 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12927 (const_string "fmul")
12928 (const_string "fop"))))
12929 (set_attr "isa" "*,noavx,avx")
12930 (set_attr "prefix" "orig,orig,vex")
12931 (set_attr "mode" "<MODE>")])
12932
12933 (define_insn "*fop_<mode>_comm_sse"
12934 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12935 (match_operator:MODEF 3 "binary_fp_operator"
12936 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12937 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12938 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12939 && COMMUTATIVE_ARITH_P (operands[3])
12940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12941 "* return output_387_binary_op (insn, operands);"
12942 [(set (attr "type")
12943 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12944 (const_string "ssemul")
12945 (const_string "sseadd")))
12946 (set_attr "isa" "noavx,avx")
12947 (set_attr "prefix" "orig,vex")
12948 (set_attr "mode" "<MODE>")])
12949
12950 (define_insn "*fop_<mode>_comm_i387"
12951 [(set (match_operand:MODEF 0 "register_operand" "=f")
12952 (match_operator:MODEF 3 "binary_fp_operator"
12953 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12954 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12955 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12956 && COMMUTATIVE_ARITH_P (operands[3])
12957 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12958 "* return output_387_binary_op (insn, operands);"
12959 [(set (attr "type")
12960 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12961 (const_string "fmul")
12962 (const_string "fop")))
12963 (set_attr "mode" "<MODE>")])
12964
12965 (define_insn "*fop_<mode>_1_mixed"
12966 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12967 (match_operator:MODEF 3 "binary_fp_operator"
12968 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12969 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12971 && !COMMUTATIVE_ARITH_P (operands[3])
12972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12973 "* return output_387_binary_op (insn, operands);"
12974 [(set (attr "type")
12975 (cond [(and (eq_attr "alternative" "2,3")
12976 (match_operand:MODEF 3 "mult_operator" ""))
12977 (const_string "ssemul")
12978 (and (eq_attr "alternative" "2,3")
12979 (match_operand:MODEF 3 "div_operator" ""))
12980 (const_string "ssediv")
12981 (eq_attr "alternative" "2,3")
12982 (const_string "sseadd")
12983 (match_operand:MODEF 3 "mult_operator" "")
12984 (const_string "fmul")
12985 (match_operand:MODEF 3 "div_operator" "")
12986 (const_string "fdiv")
12987 ]
12988 (const_string "fop")))
12989 (set_attr "isa" "*,*,noavx,avx")
12990 (set_attr "prefix" "orig,orig,orig,vex")
12991 (set_attr "mode" "<MODE>")])
12992
12993 (define_insn "*rcpsf2_sse"
12994 [(set (match_operand:SF 0 "register_operand" "=x")
12995 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12996 UNSPEC_RCP))]
12997 "TARGET_SSE_MATH"
12998 "%vrcpss\t{%1, %d0|%d0, %1}"
12999 [(set_attr "type" "sse")
13000 (set_attr "atom_sse_attr" "rcp")
13001 (set_attr "prefix" "maybe_vex")
13002 (set_attr "mode" "SF")])
13003
13004 (define_insn "*fop_<mode>_1_sse"
13005 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13006 (match_operator:MODEF 3 "binary_fp_operator"
13007 [(match_operand:MODEF 1 "register_operand" "0,x")
13008 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13009 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13010 && !COMMUTATIVE_ARITH_P (operands[3])"
13011 "* return output_387_binary_op (insn, operands);"
13012 [(set (attr "type")
13013 (cond [(match_operand:MODEF 3 "mult_operator" "")
13014 (const_string "ssemul")
13015 (match_operand:MODEF 3 "div_operator" "")
13016 (const_string "ssediv")
13017 ]
13018 (const_string "sseadd")))
13019 (set_attr "isa" "noavx,avx")
13020 (set_attr "prefix" "orig,vex")
13021 (set_attr "mode" "<MODE>")])
13022
13023 ;; This pattern is not fully shadowed by the pattern above.
13024 (define_insn "*fop_<mode>_1_i387"
13025 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13026 (match_operator:MODEF 3 "binary_fp_operator"
13027 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13028 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13029 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13030 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13031 && !COMMUTATIVE_ARITH_P (operands[3])
13032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13033 "* return output_387_binary_op (insn, operands);"
13034 [(set (attr "type")
13035 (cond [(match_operand:MODEF 3 "mult_operator" "")
13036 (const_string "fmul")
13037 (match_operand:MODEF 3 "div_operator" "")
13038 (const_string "fdiv")
13039 ]
13040 (const_string "fop")))
13041 (set_attr "mode" "<MODE>")])
13042
13043 ;; ??? Add SSE splitters for these!
13044 (define_insn "*fop_<MODEF:mode>_2_i387"
13045 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13046 (match_operator:MODEF 3 "binary_fp_operator"
13047 [(float:MODEF
13048 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13049 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13050 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13051 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13052 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13053 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13054 [(set (attr "type")
13055 (cond [(match_operand:MODEF 3 "mult_operator" "")
13056 (const_string "fmul")
13057 (match_operand:MODEF 3 "div_operator" "")
13058 (const_string "fdiv")
13059 ]
13060 (const_string "fop")))
13061 (set_attr "fp_int_src" "true")
13062 (set_attr "mode" "<SWI24:MODE>")])
13063
13064 (define_insn "*fop_<MODEF:mode>_3_i387"
13065 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13067 [(match_operand:MODEF 1 "register_operand" "0,0")
13068 (float:MODEF
13069 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13070 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13071 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13072 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13073 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13074 [(set (attr "type")
13075 (cond [(match_operand:MODEF 3 "mult_operator" "")
13076 (const_string "fmul")
13077 (match_operand:MODEF 3 "div_operator" "")
13078 (const_string "fdiv")
13079 ]
13080 (const_string "fop")))
13081 (set_attr "fp_int_src" "true")
13082 (set_attr "mode" "<MODE>")])
13083
13084 (define_insn "*fop_df_4_i387"
13085 [(set (match_operand:DF 0 "register_operand" "=f,f")
13086 (match_operator:DF 3 "binary_fp_operator"
13087 [(float_extend:DF
13088 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13089 (match_operand:DF 2 "register_operand" "0,f")]))]
13090 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13091 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13092 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13093 "* return output_387_binary_op (insn, operands);"
13094 [(set (attr "type")
13095 (cond [(match_operand:DF 3 "mult_operator" "")
13096 (const_string "fmul")
13097 (match_operand:DF 3 "div_operator" "")
13098 (const_string "fdiv")
13099 ]
13100 (const_string "fop")))
13101 (set_attr "mode" "SF")])
13102
13103 (define_insn "*fop_df_5_i387"
13104 [(set (match_operand:DF 0 "register_operand" "=f,f")
13105 (match_operator:DF 3 "binary_fp_operator"
13106 [(match_operand:DF 1 "register_operand" "0,f")
13107 (float_extend:DF
13108 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13109 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13110 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13111 "* return output_387_binary_op (insn, operands);"
13112 [(set (attr "type")
13113 (cond [(match_operand:DF 3 "mult_operator" "")
13114 (const_string "fmul")
13115 (match_operand:DF 3 "div_operator" "")
13116 (const_string "fdiv")
13117 ]
13118 (const_string "fop")))
13119 (set_attr "mode" "SF")])
13120
13121 (define_insn "*fop_df_6_i387"
13122 [(set (match_operand:DF 0 "register_operand" "=f,f")
13123 (match_operator:DF 3 "binary_fp_operator"
13124 [(float_extend:DF
13125 (match_operand:SF 1 "register_operand" "0,f"))
13126 (float_extend:DF
13127 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13128 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13129 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13130 "* return output_387_binary_op (insn, operands);"
13131 [(set (attr "type")
13132 (cond [(match_operand:DF 3 "mult_operator" "")
13133 (const_string "fmul")
13134 (match_operand:DF 3 "div_operator" "")
13135 (const_string "fdiv")
13136 ]
13137 (const_string "fop")))
13138 (set_attr "mode" "SF")])
13139
13140 (define_insn "*fop_xf_comm_i387"
13141 [(set (match_operand:XF 0 "register_operand" "=f")
13142 (match_operator:XF 3 "binary_fp_operator"
13143 [(match_operand:XF 1 "register_operand" "%0")
13144 (match_operand:XF 2 "register_operand" "f")]))]
13145 "TARGET_80387
13146 && COMMUTATIVE_ARITH_P (operands[3])"
13147 "* return output_387_binary_op (insn, operands);"
13148 [(set (attr "type")
13149 (if_then_else (match_operand:XF 3 "mult_operator" "")
13150 (const_string "fmul")
13151 (const_string "fop")))
13152 (set_attr "mode" "XF")])
13153
13154 (define_insn "*fop_xf_1_i387"
13155 [(set (match_operand:XF 0 "register_operand" "=f,f")
13156 (match_operator:XF 3 "binary_fp_operator"
13157 [(match_operand:XF 1 "register_operand" "0,f")
13158 (match_operand:XF 2 "register_operand" "f,0")]))]
13159 "TARGET_80387
13160 && !COMMUTATIVE_ARITH_P (operands[3])"
13161 "* return output_387_binary_op (insn, operands);"
13162 [(set (attr "type")
13163 (cond [(match_operand:XF 3 "mult_operator" "")
13164 (const_string "fmul")
13165 (match_operand:XF 3 "div_operator" "")
13166 (const_string "fdiv")
13167 ]
13168 (const_string "fop")))
13169 (set_attr "mode" "XF")])
13170
13171 (define_insn "*fop_xf_2_i387"
13172 [(set (match_operand:XF 0 "register_operand" "=f,f")
13173 (match_operator:XF 3 "binary_fp_operator"
13174 [(float:XF
13175 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13176 (match_operand:XF 2 "register_operand" "0,0")]))]
13177 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13178 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13179 [(set (attr "type")
13180 (cond [(match_operand:XF 3 "mult_operator" "")
13181 (const_string "fmul")
13182 (match_operand:XF 3 "div_operator" "")
13183 (const_string "fdiv")
13184 ]
13185 (const_string "fop")))
13186 (set_attr "fp_int_src" "true")
13187 (set_attr "mode" "<MODE>")])
13188
13189 (define_insn "*fop_xf_3_i387"
13190 [(set (match_operand:XF 0 "register_operand" "=f,f")
13191 (match_operator:XF 3 "binary_fp_operator"
13192 [(match_operand:XF 1 "register_operand" "0,0")
13193 (float:XF
13194 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13195 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13196 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13197 [(set (attr "type")
13198 (cond [(match_operand:XF 3 "mult_operator" "")
13199 (const_string "fmul")
13200 (match_operand:XF 3 "div_operator" "")
13201 (const_string "fdiv")
13202 ]
13203 (const_string "fop")))
13204 (set_attr "fp_int_src" "true")
13205 (set_attr "mode" "<MODE>")])
13206
13207 (define_insn "*fop_xf_4_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f,f")
13209 (match_operator:XF 3 "binary_fp_operator"
13210 [(float_extend:XF
13211 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13212 (match_operand:XF 2 "register_operand" "0,f")]))]
13213 "TARGET_80387"
13214 "* return output_387_binary_op (insn, operands);"
13215 [(set (attr "type")
13216 (cond [(match_operand:XF 3 "mult_operator" "")
13217 (const_string "fmul")
13218 (match_operand:XF 3 "div_operator" "")
13219 (const_string "fdiv")
13220 ]
13221 (const_string "fop")))
13222 (set_attr "mode" "<MODE>")])
13223
13224 (define_insn "*fop_xf_5_i387"
13225 [(set (match_operand:XF 0 "register_operand" "=f,f")
13226 (match_operator:XF 3 "binary_fp_operator"
13227 [(match_operand:XF 1 "register_operand" "0,f")
13228 (float_extend:XF
13229 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13230 "TARGET_80387"
13231 "* return output_387_binary_op (insn, operands);"
13232 [(set (attr "type")
13233 (cond [(match_operand:XF 3 "mult_operator" "")
13234 (const_string "fmul")
13235 (match_operand:XF 3 "div_operator" "")
13236 (const_string "fdiv")
13237 ]
13238 (const_string "fop")))
13239 (set_attr "mode" "<MODE>")])
13240
13241 (define_insn "*fop_xf_6_i387"
13242 [(set (match_operand:XF 0 "register_operand" "=f,f")
13243 (match_operator:XF 3 "binary_fp_operator"
13244 [(float_extend:XF
13245 (match_operand:MODEF 1 "register_operand" "0,f"))
13246 (float_extend:XF
13247 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13248 "TARGET_80387"
13249 "* return output_387_binary_op (insn, operands);"
13250 [(set (attr "type")
13251 (cond [(match_operand:XF 3 "mult_operator" "")
13252 (const_string "fmul")
13253 (match_operand:XF 3 "div_operator" "")
13254 (const_string "fdiv")
13255 ]
13256 (const_string "fop")))
13257 (set_attr "mode" "<MODE>")])
13258
13259 (define_split
13260 [(set (match_operand 0 "register_operand" "")
13261 (match_operator 3 "binary_fp_operator"
13262 [(float (match_operand:SWI24 1 "register_operand" ""))
13263 (match_operand 2 "register_operand" "")]))]
13264 "reload_completed
13265 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13266 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13267 [(const_int 0)]
13268 {
13269 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13270 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13271 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13272 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13273 GET_MODE (operands[3]),
13274 operands[4],
13275 operands[2])));
13276 ix86_free_from_memory (GET_MODE (operands[1]));
13277 DONE;
13278 })
13279
13280 (define_split
13281 [(set (match_operand 0 "register_operand" "")
13282 (match_operator 3 "binary_fp_operator"
13283 [(match_operand 1 "register_operand" "")
13284 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13285 "reload_completed
13286 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13287 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13288 [(const_int 0)]
13289 {
13290 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13291 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13292 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13293 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13294 GET_MODE (operands[3]),
13295 operands[1],
13296 operands[4])));
13297 ix86_free_from_memory (GET_MODE (operands[2]));
13298 DONE;
13299 })
13300 \f
13301 ;; FPU special functions.
13302
13303 ;; This pattern implements a no-op XFmode truncation for
13304 ;; all fancy i386 XFmode math functions.
13305
13306 (define_insn "truncxf<mode>2_i387_noop_unspec"
13307 [(set (match_operand:MODEF 0 "register_operand" "=f")
13308 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13309 UNSPEC_TRUNC_NOOP))]
13310 "TARGET_USE_FANCY_MATH_387"
13311 "* return output_387_reg_move (insn, operands);"
13312 [(set_attr "type" "fmov")
13313 (set_attr "mode" "<MODE>")])
13314
13315 (define_insn "sqrtxf2"
13316 [(set (match_operand:XF 0 "register_operand" "=f")
13317 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13318 "TARGET_USE_FANCY_MATH_387"
13319 "fsqrt"
13320 [(set_attr "type" "fpspc")
13321 (set_attr "mode" "XF")
13322 (set_attr "athlon_decode" "direct")
13323 (set_attr "amdfam10_decode" "direct")
13324 (set_attr "bdver1_decode" "direct")])
13325
13326 (define_insn "sqrt_extend<mode>xf2_i387"
13327 [(set (match_operand:XF 0 "register_operand" "=f")
13328 (sqrt:XF
13329 (float_extend:XF
13330 (match_operand:MODEF 1 "register_operand" "0"))))]
13331 "TARGET_USE_FANCY_MATH_387"
13332 "fsqrt"
13333 [(set_attr "type" "fpspc")
13334 (set_attr "mode" "XF")
13335 (set_attr "athlon_decode" "direct")
13336 (set_attr "amdfam10_decode" "direct")
13337 (set_attr "bdver1_decode" "direct")])
13338
13339 (define_insn "*rsqrtsf2_sse"
13340 [(set (match_operand:SF 0 "register_operand" "=x")
13341 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13342 UNSPEC_RSQRT))]
13343 "TARGET_SSE_MATH"
13344 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13345 [(set_attr "type" "sse")
13346 (set_attr "atom_sse_attr" "rcp")
13347 (set_attr "prefix" "maybe_vex")
13348 (set_attr "mode" "SF")])
13349
13350 (define_expand "rsqrtsf2"
13351 [(set (match_operand:SF 0 "register_operand" "")
13352 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13353 UNSPEC_RSQRT))]
13354 "TARGET_SSE_MATH"
13355 {
13356 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13357 DONE;
13358 })
13359
13360 (define_insn "*sqrt<mode>2_sse"
13361 [(set (match_operand:MODEF 0 "register_operand" "=x")
13362 (sqrt:MODEF
13363 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13364 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13365 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13366 [(set_attr "type" "sse")
13367 (set_attr "atom_sse_attr" "sqrt")
13368 (set_attr "prefix" "maybe_vex")
13369 (set_attr "mode" "<MODE>")
13370 (set_attr "athlon_decode" "*")
13371 (set_attr "amdfam10_decode" "*")
13372 (set_attr "bdver1_decode" "*")])
13373
13374 (define_expand "sqrt<mode>2"
13375 [(set (match_operand:MODEF 0 "register_operand" "")
13376 (sqrt:MODEF
13377 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13378 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13379 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13380 {
13381 if (<MODE>mode == SFmode
13382 && TARGET_SSE_MATH
13383 && TARGET_RECIP_SQRT
13384 && !optimize_function_for_size_p (cfun)
13385 && flag_finite_math_only && !flag_trapping_math
13386 && flag_unsafe_math_optimizations)
13387 {
13388 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13389 DONE;
13390 }
13391
13392 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13393 {
13394 rtx op0 = gen_reg_rtx (XFmode);
13395 rtx op1 = force_reg (<MODE>mode, operands[1]);
13396
13397 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13398 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13399 DONE;
13400 }
13401 })
13402
13403 (define_insn "fpremxf4_i387"
13404 [(set (match_operand:XF 0 "register_operand" "=f")
13405 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13406 (match_operand:XF 3 "register_operand" "1")]
13407 UNSPEC_FPREM_F))
13408 (set (match_operand:XF 1 "register_operand" "=u")
13409 (unspec:XF [(match_dup 2) (match_dup 3)]
13410 UNSPEC_FPREM_U))
13411 (set (reg:CCFP FPSR_REG)
13412 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13413 UNSPEC_C2_FLAG))]
13414 "TARGET_USE_FANCY_MATH_387"
13415 "fprem"
13416 [(set_attr "type" "fpspc")
13417 (set_attr "mode" "XF")])
13418
13419 (define_expand "fmodxf3"
13420 [(use (match_operand:XF 0 "register_operand" ""))
13421 (use (match_operand:XF 1 "general_operand" ""))
13422 (use (match_operand:XF 2 "general_operand" ""))]
13423 "TARGET_USE_FANCY_MATH_387"
13424 {
13425 rtx label = gen_label_rtx ();
13426
13427 rtx op1 = gen_reg_rtx (XFmode);
13428 rtx op2 = gen_reg_rtx (XFmode);
13429
13430 emit_move_insn (op2, operands[2]);
13431 emit_move_insn (op1, operands[1]);
13432
13433 emit_label (label);
13434 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13435 ix86_emit_fp_unordered_jump (label);
13436 LABEL_NUSES (label) = 1;
13437
13438 emit_move_insn (operands[0], op1);
13439 DONE;
13440 })
13441
13442 (define_expand "fmod<mode>3"
13443 [(use (match_operand:MODEF 0 "register_operand" ""))
13444 (use (match_operand:MODEF 1 "general_operand" ""))
13445 (use (match_operand:MODEF 2 "general_operand" ""))]
13446 "TARGET_USE_FANCY_MATH_387"
13447 {
13448 rtx (*gen_truncxf) (rtx, rtx);
13449
13450 rtx label = gen_label_rtx ();
13451
13452 rtx op1 = gen_reg_rtx (XFmode);
13453 rtx op2 = gen_reg_rtx (XFmode);
13454
13455 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13457
13458 emit_label (label);
13459 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13460 ix86_emit_fp_unordered_jump (label);
13461 LABEL_NUSES (label) = 1;
13462
13463 /* Truncate the result properly for strict SSE math. */
13464 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13465 && !TARGET_MIX_SSE_I387)
13466 gen_truncxf = gen_truncxf<mode>2;
13467 else
13468 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13469
13470 emit_insn (gen_truncxf (operands[0], op1));
13471 DONE;
13472 })
13473
13474 (define_insn "fprem1xf4_i387"
13475 [(set (match_operand:XF 0 "register_operand" "=f")
13476 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13477 (match_operand:XF 3 "register_operand" "1")]
13478 UNSPEC_FPREM1_F))
13479 (set (match_operand:XF 1 "register_operand" "=u")
13480 (unspec:XF [(match_dup 2) (match_dup 3)]
13481 UNSPEC_FPREM1_U))
13482 (set (reg:CCFP FPSR_REG)
13483 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13484 UNSPEC_C2_FLAG))]
13485 "TARGET_USE_FANCY_MATH_387"
13486 "fprem1"
13487 [(set_attr "type" "fpspc")
13488 (set_attr "mode" "XF")])
13489
13490 (define_expand "remainderxf3"
13491 [(use (match_operand:XF 0 "register_operand" ""))
13492 (use (match_operand:XF 1 "general_operand" ""))
13493 (use (match_operand:XF 2 "general_operand" ""))]
13494 "TARGET_USE_FANCY_MATH_387"
13495 {
13496 rtx label = gen_label_rtx ();
13497
13498 rtx op1 = gen_reg_rtx (XFmode);
13499 rtx op2 = gen_reg_rtx (XFmode);
13500
13501 emit_move_insn (op2, operands[2]);
13502 emit_move_insn (op1, operands[1]);
13503
13504 emit_label (label);
13505 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13506 ix86_emit_fp_unordered_jump (label);
13507 LABEL_NUSES (label) = 1;
13508
13509 emit_move_insn (operands[0], op1);
13510 DONE;
13511 })
13512
13513 (define_expand "remainder<mode>3"
13514 [(use (match_operand:MODEF 0 "register_operand" ""))
13515 (use (match_operand:MODEF 1 "general_operand" ""))
13516 (use (match_operand:MODEF 2 "general_operand" ""))]
13517 "TARGET_USE_FANCY_MATH_387"
13518 {
13519 rtx (*gen_truncxf) (rtx, rtx);
13520
13521 rtx label = gen_label_rtx ();
13522
13523 rtx op1 = gen_reg_rtx (XFmode);
13524 rtx op2 = gen_reg_rtx (XFmode);
13525
13526 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13527 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13528
13529 emit_label (label);
13530
13531 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13532 ix86_emit_fp_unordered_jump (label);
13533 LABEL_NUSES (label) = 1;
13534
13535 /* Truncate the result properly for strict SSE math. */
13536 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13537 && !TARGET_MIX_SSE_I387)
13538 gen_truncxf = gen_truncxf<mode>2;
13539 else
13540 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13541
13542 emit_insn (gen_truncxf (operands[0], op1));
13543 DONE;
13544 })
13545
13546 (define_insn "*sinxf2_i387"
13547 [(set (match_operand:XF 0 "register_operand" "=f")
13548 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13549 "TARGET_USE_FANCY_MATH_387
13550 && flag_unsafe_math_optimizations"
13551 "fsin"
13552 [(set_attr "type" "fpspc")
13553 (set_attr "mode" "XF")])
13554
13555 (define_insn "*sin_extend<mode>xf2_i387"
13556 [(set (match_operand:XF 0 "register_operand" "=f")
13557 (unspec:XF [(float_extend:XF
13558 (match_operand:MODEF 1 "register_operand" "0"))]
13559 UNSPEC_SIN))]
13560 "TARGET_USE_FANCY_MATH_387
13561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13562 || TARGET_MIX_SSE_I387)
13563 && flag_unsafe_math_optimizations"
13564 "fsin"
13565 [(set_attr "type" "fpspc")
13566 (set_attr "mode" "XF")])
13567
13568 (define_insn "*cosxf2_i387"
13569 [(set (match_operand:XF 0 "register_operand" "=f")
13570 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13571 "TARGET_USE_FANCY_MATH_387
13572 && flag_unsafe_math_optimizations"
13573 "fcos"
13574 [(set_attr "type" "fpspc")
13575 (set_attr "mode" "XF")])
13576
13577 (define_insn "*cos_extend<mode>xf2_i387"
13578 [(set (match_operand:XF 0 "register_operand" "=f")
13579 (unspec:XF [(float_extend:XF
13580 (match_operand:MODEF 1 "register_operand" "0"))]
13581 UNSPEC_COS))]
13582 "TARGET_USE_FANCY_MATH_387
13583 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13584 || TARGET_MIX_SSE_I387)
13585 && flag_unsafe_math_optimizations"
13586 "fcos"
13587 [(set_attr "type" "fpspc")
13588 (set_attr "mode" "XF")])
13589
13590 ;; When sincos pattern is defined, sin and cos builtin functions will be
13591 ;; expanded to sincos pattern with one of its outputs left unused.
13592 ;; CSE pass will figure out if two sincos patterns can be combined,
13593 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13594 ;; depending on the unused output.
13595
13596 (define_insn "sincosxf3"
13597 [(set (match_operand:XF 0 "register_operand" "=f")
13598 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13599 UNSPEC_SINCOS_COS))
13600 (set (match_operand:XF 1 "register_operand" "=u")
13601 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && flag_unsafe_math_optimizations"
13604 "fsincos"
13605 [(set_attr "type" "fpspc")
13606 (set_attr "mode" "XF")])
13607
13608 (define_split
13609 [(set (match_operand:XF 0 "register_operand" "")
13610 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13611 UNSPEC_SINCOS_COS))
13612 (set (match_operand:XF 1 "register_operand" "")
13613 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13614 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13615 && can_create_pseudo_p ()"
13616 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13617
13618 (define_split
13619 [(set (match_operand:XF 0 "register_operand" "")
13620 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13621 UNSPEC_SINCOS_COS))
13622 (set (match_operand:XF 1 "register_operand" "")
13623 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13624 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13625 && can_create_pseudo_p ()"
13626 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13627
13628 (define_insn "sincos_extend<mode>xf3_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(float_extend:XF
13631 (match_operand:MODEF 2 "register_operand" "0"))]
13632 UNSPEC_SINCOS_COS))
13633 (set (match_operand:XF 1 "register_operand" "=u")
13634 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637 || TARGET_MIX_SSE_I387)
13638 && flag_unsafe_math_optimizations"
13639 "fsincos"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13642
13643 (define_split
13644 [(set (match_operand:XF 0 "register_operand" "")
13645 (unspec:XF [(float_extend:XF
13646 (match_operand:MODEF 2 "register_operand" ""))]
13647 UNSPEC_SINCOS_COS))
13648 (set (match_operand:XF 1 "register_operand" "")
13649 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13650 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13651 && can_create_pseudo_p ()"
13652 [(set (match_dup 1)
13653 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13654
13655 (define_split
13656 [(set (match_operand:XF 0 "register_operand" "")
13657 (unspec:XF [(float_extend:XF
13658 (match_operand:MODEF 2 "register_operand" ""))]
13659 UNSPEC_SINCOS_COS))
13660 (set (match_operand:XF 1 "register_operand" "")
13661 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13662 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13663 && can_create_pseudo_p ()"
13664 [(set (match_dup 0)
13665 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13666
13667 (define_expand "sincos<mode>3"
13668 [(use (match_operand:MODEF 0 "register_operand" ""))
13669 (use (match_operand:MODEF 1 "register_operand" ""))
13670 (use (match_operand:MODEF 2 "register_operand" ""))]
13671 "TARGET_USE_FANCY_MATH_387
13672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13673 || TARGET_MIX_SSE_I387)
13674 && flag_unsafe_math_optimizations"
13675 {
13676 rtx op0 = gen_reg_rtx (XFmode);
13677 rtx op1 = gen_reg_rtx (XFmode);
13678
13679 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13680 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13682 DONE;
13683 })
13684
13685 (define_insn "fptanxf4_i387"
13686 [(set (match_operand:XF 0 "register_operand" "=f")
13687 (match_operand:XF 3 "const_double_operand" "F"))
13688 (set (match_operand:XF 1 "register_operand" "=u")
13689 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13690 UNSPEC_TAN))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && flag_unsafe_math_optimizations
13693 && standard_80387_constant_p (operands[3]) == 2"
13694 "fptan"
13695 [(set_attr "type" "fpspc")
13696 (set_attr "mode" "XF")])
13697
13698 (define_insn "fptan_extend<mode>xf4_i387"
13699 [(set (match_operand:MODEF 0 "register_operand" "=f")
13700 (match_operand:MODEF 3 "const_double_operand" "F"))
13701 (set (match_operand:XF 1 "register_operand" "=u")
13702 (unspec:XF [(float_extend:XF
13703 (match_operand:MODEF 2 "register_operand" "0"))]
13704 UNSPEC_TAN))]
13705 "TARGET_USE_FANCY_MATH_387
13706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13707 || TARGET_MIX_SSE_I387)
13708 && flag_unsafe_math_optimizations
13709 && standard_80387_constant_p (operands[3]) == 2"
13710 "fptan"
13711 [(set_attr "type" "fpspc")
13712 (set_attr "mode" "XF")])
13713
13714 (define_expand "tanxf2"
13715 [(use (match_operand:XF 0 "register_operand" ""))
13716 (use (match_operand:XF 1 "register_operand" ""))]
13717 "TARGET_USE_FANCY_MATH_387
13718 && flag_unsafe_math_optimizations"
13719 {
13720 rtx one = gen_reg_rtx (XFmode);
13721 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13722
13723 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13724 DONE;
13725 })
13726
13727 (define_expand "tan<mode>2"
13728 [(use (match_operand:MODEF 0 "register_operand" ""))
13729 (use (match_operand:MODEF 1 "register_operand" ""))]
13730 "TARGET_USE_FANCY_MATH_387
13731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13732 || TARGET_MIX_SSE_I387)
13733 && flag_unsafe_math_optimizations"
13734 {
13735 rtx op0 = gen_reg_rtx (XFmode);
13736
13737 rtx one = gen_reg_rtx (<MODE>mode);
13738 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13739
13740 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13741 operands[1], op2));
13742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13743 DONE;
13744 })
13745
13746 (define_insn "*fpatanxf3_i387"
13747 [(set (match_operand:XF 0 "register_operand" "=f")
13748 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13749 (match_operand:XF 2 "register_operand" "u")]
13750 UNSPEC_FPATAN))
13751 (clobber (match_scratch:XF 3 "=2"))]
13752 "TARGET_USE_FANCY_MATH_387
13753 && flag_unsafe_math_optimizations"
13754 "fpatan"
13755 [(set_attr "type" "fpspc")
13756 (set_attr "mode" "XF")])
13757
13758 (define_insn "fpatan_extend<mode>xf3_i387"
13759 [(set (match_operand:XF 0 "register_operand" "=f")
13760 (unspec:XF [(float_extend:XF
13761 (match_operand:MODEF 1 "register_operand" "0"))
13762 (float_extend:XF
13763 (match_operand:MODEF 2 "register_operand" "u"))]
13764 UNSPEC_FPATAN))
13765 (clobber (match_scratch:XF 3 "=2"))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768 || TARGET_MIX_SSE_I387)
13769 && flag_unsafe_math_optimizations"
13770 "fpatan"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13773
13774 (define_expand "atan2xf3"
13775 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13776 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13777 (match_operand:XF 1 "register_operand" "")]
13778 UNSPEC_FPATAN))
13779 (clobber (match_scratch:XF 3 ""))])]
13780 "TARGET_USE_FANCY_MATH_387
13781 && flag_unsafe_math_optimizations")
13782
13783 (define_expand "atan2<mode>3"
13784 [(use (match_operand:MODEF 0 "register_operand" ""))
13785 (use (match_operand:MODEF 1 "register_operand" ""))
13786 (use (match_operand:MODEF 2 "register_operand" ""))]
13787 "TARGET_USE_FANCY_MATH_387
13788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789 || TARGET_MIX_SSE_I387)
13790 && flag_unsafe_math_optimizations"
13791 {
13792 rtx op0 = gen_reg_rtx (XFmode);
13793
13794 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13796 DONE;
13797 })
13798
13799 (define_expand "atanxf2"
13800 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13801 (unspec:XF [(match_dup 2)
13802 (match_operand:XF 1 "register_operand" "")]
13803 UNSPEC_FPATAN))
13804 (clobber (match_scratch:XF 3 ""))])]
13805 "TARGET_USE_FANCY_MATH_387
13806 && flag_unsafe_math_optimizations"
13807 {
13808 operands[2] = gen_reg_rtx (XFmode);
13809 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13810 })
13811
13812 (define_expand "atan<mode>2"
13813 [(use (match_operand:MODEF 0 "register_operand" ""))
13814 (use (match_operand:MODEF 1 "register_operand" ""))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817 || TARGET_MIX_SSE_I387)
13818 && flag_unsafe_math_optimizations"
13819 {
13820 rtx op0 = gen_reg_rtx (XFmode);
13821
13822 rtx op2 = gen_reg_rtx (<MODE>mode);
13823 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13824
13825 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13826 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13827 DONE;
13828 })
13829
13830 (define_expand "asinxf2"
13831 [(set (match_dup 2)
13832 (mult:XF (match_operand:XF 1 "register_operand" "")
13833 (match_dup 1)))
13834 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13835 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13836 (parallel [(set (match_operand:XF 0 "register_operand" "")
13837 (unspec:XF [(match_dup 5) (match_dup 1)]
13838 UNSPEC_FPATAN))
13839 (clobber (match_scratch:XF 6 ""))])]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations"
13842 {
13843 int i;
13844
13845 if (optimize_insn_for_size_p ())
13846 FAIL;
13847
13848 for (i = 2; i < 6; i++)
13849 operands[i] = gen_reg_rtx (XFmode);
13850
13851 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13852 })
13853
13854 (define_expand "asin<mode>2"
13855 [(use (match_operand:MODEF 0 "register_operand" ""))
13856 (use (match_operand:MODEF 1 "general_operand" ""))]
13857 "TARGET_USE_FANCY_MATH_387
13858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13859 || TARGET_MIX_SSE_I387)
13860 && flag_unsafe_math_optimizations"
13861 {
13862 rtx op0 = gen_reg_rtx (XFmode);
13863 rtx op1 = gen_reg_rtx (XFmode);
13864
13865 if (optimize_insn_for_size_p ())
13866 FAIL;
13867
13868 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13869 emit_insn (gen_asinxf2 (op0, op1));
13870 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13871 DONE;
13872 })
13873
13874 (define_expand "acosxf2"
13875 [(set (match_dup 2)
13876 (mult:XF (match_operand:XF 1 "register_operand" "")
13877 (match_dup 1)))
13878 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13879 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13880 (parallel [(set (match_operand:XF 0 "register_operand" "")
13881 (unspec:XF [(match_dup 1) (match_dup 5)]
13882 UNSPEC_FPATAN))
13883 (clobber (match_scratch:XF 6 ""))])]
13884 "TARGET_USE_FANCY_MATH_387
13885 && flag_unsafe_math_optimizations"
13886 {
13887 int i;
13888
13889 if (optimize_insn_for_size_p ())
13890 FAIL;
13891
13892 for (i = 2; i < 6; i++)
13893 operands[i] = gen_reg_rtx (XFmode);
13894
13895 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13896 })
13897
13898 (define_expand "acos<mode>2"
13899 [(use (match_operand:MODEF 0 "register_operand" ""))
13900 (use (match_operand:MODEF 1 "general_operand" ""))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903 || TARGET_MIX_SSE_I387)
13904 && flag_unsafe_math_optimizations"
13905 {
13906 rtx op0 = gen_reg_rtx (XFmode);
13907 rtx op1 = gen_reg_rtx (XFmode);
13908
13909 if (optimize_insn_for_size_p ())
13910 FAIL;
13911
13912 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13913 emit_insn (gen_acosxf2 (op0, op1));
13914 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13915 DONE;
13916 })
13917
13918 (define_insn "fyl2xxf3_i387"
13919 [(set (match_operand:XF 0 "register_operand" "=f")
13920 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13921 (match_operand:XF 2 "register_operand" "u")]
13922 UNSPEC_FYL2X))
13923 (clobber (match_scratch:XF 3 "=2"))]
13924 "TARGET_USE_FANCY_MATH_387
13925 && flag_unsafe_math_optimizations"
13926 "fyl2x"
13927 [(set_attr "type" "fpspc")
13928 (set_attr "mode" "XF")])
13929
13930 (define_insn "fyl2x_extend<mode>xf3_i387"
13931 [(set (match_operand:XF 0 "register_operand" "=f")
13932 (unspec:XF [(float_extend:XF
13933 (match_operand:MODEF 1 "register_operand" "0"))
13934 (match_operand:XF 2 "register_operand" "u")]
13935 UNSPEC_FYL2X))
13936 (clobber (match_scratch:XF 3 "=2"))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13939 || TARGET_MIX_SSE_I387)
13940 && flag_unsafe_math_optimizations"
13941 "fyl2x"
13942 [(set_attr "type" "fpspc")
13943 (set_attr "mode" "XF")])
13944
13945 (define_expand "logxf2"
13946 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13947 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13948 (match_dup 2)] UNSPEC_FYL2X))
13949 (clobber (match_scratch:XF 3 ""))])]
13950 "TARGET_USE_FANCY_MATH_387
13951 && flag_unsafe_math_optimizations"
13952 {
13953 operands[2] = gen_reg_rtx (XFmode);
13954 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13955 })
13956
13957 (define_expand "log<mode>2"
13958 [(use (match_operand:MODEF 0 "register_operand" ""))
13959 (use (match_operand:MODEF 1 "register_operand" ""))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13962 || TARGET_MIX_SSE_I387)
13963 && flag_unsafe_math_optimizations"
13964 {
13965 rtx op0 = gen_reg_rtx (XFmode);
13966
13967 rtx op2 = gen_reg_rtx (XFmode);
13968 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13969
13970 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13971 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13972 DONE;
13973 })
13974
13975 (define_expand "log10xf2"
13976 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13977 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13978 (match_dup 2)] UNSPEC_FYL2X))
13979 (clobber (match_scratch:XF 3 ""))])]
13980 "TARGET_USE_FANCY_MATH_387
13981 && flag_unsafe_math_optimizations"
13982 {
13983 operands[2] = gen_reg_rtx (XFmode);
13984 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13985 })
13986
13987 (define_expand "log10<mode>2"
13988 [(use (match_operand:MODEF 0 "register_operand" ""))
13989 (use (match_operand:MODEF 1 "register_operand" ""))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13992 || TARGET_MIX_SSE_I387)
13993 && flag_unsafe_math_optimizations"
13994 {
13995 rtx op0 = gen_reg_rtx (XFmode);
13996
13997 rtx op2 = gen_reg_rtx (XFmode);
13998 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13999
14000 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14001 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14002 DONE;
14003 })
14004
14005 (define_expand "log2xf2"
14006 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14007 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14008 (match_dup 2)] UNSPEC_FYL2X))
14009 (clobber (match_scratch:XF 3 ""))])]
14010 "TARGET_USE_FANCY_MATH_387
14011 && flag_unsafe_math_optimizations"
14012 {
14013 operands[2] = gen_reg_rtx (XFmode);
14014 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14015 })
14016
14017 (define_expand "log2<mode>2"
14018 [(use (match_operand:MODEF 0 "register_operand" ""))
14019 (use (match_operand:MODEF 1 "register_operand" ""))]
14020 "TARGET_USE_FANCY_MATH_387
14021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14022 || TARGET_MIX_SSE_I387)
14023 && flag_unsafe_math_optimizations"
14024 {
14025 rtx op0 = gen_reg_rtx (XFmode);
14026
14027 rtx op2 = gen_reg_rtx (XFmode);
14028 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14029
14030 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14031 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14032 DONE;
14033 })
14034
14035 (define_insn "fyl2xp1xf3_i387"
14036 [(set (match_operand:XF 0 "register_operand" "=f")
14037 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14038 (match_operand:XF 2 "register_operand" "u")]
14039 UNSPEC_FYL2XP1))
14040 (clobber (match_scratch:XF 3 "=2"))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14043 "fyl2xp1"
14044 [(set_attr "type" "fpspc")
14045 (set_attr "mode" "XF")])
14046
14047 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14048 [(set (match_operand:XF 0 "register_operand" "=f")
14049 (unspec:XF [(float_extend:XF
14050 (match_operand:MODEF 1 "register_operand" "0"))
14051 (match_operand:XF 2 "register_operand" "u")]
14052 UNSPEC_FYL2XP1))
14053 (clobber (match_scratch:XF 3 "=2"))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14058 "fyl2xp1"
14059 [(set_attr "type" "fpspc")
14060 (set_attr "mode" "XF")])
14061
14062 (define_expand "log1pxf2"
14063 [(use (match_operand:XF 0 "register_operand" ""))
14064 (use (match_operand:XF 1 "register_operand" ""))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && flag_unsafe_math_optimizations"
14067 {
14068 if (optimize_insn_for_size_p ())
14069 FAIL;
14070
14071 ix86_emit_i387_log1p (operands[0], operands[1]);
14072 DONE;
14073 })
14074
14075 (define_expand "log1p<mode>2"
14076 [(use (match_operand:MODEF 0 "register_operand" ""))
14077 (use (match_operand:MODEF 1 "register_operand" ""))]
14078 "TARGET_USE_FANCY_MATH_387
14079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14080 || TARGET_MIX_SSE_I387)
14081 && flag_unsafe_math_optimizations"
14082 {
14083 rtx op0;
14084
14085 if (optimize_insn_for_size_p ())
14086 FAIL;
14087
14088 op0 = gen_reg_rtx (XFmode);
14089
14090 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14091
14092 ix86_emit_i387_log1p (op0, operands[1]);
14093 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14094 DONE;
14095 })
14096
14097 (define_insn "fxtractxf3_i387"
14098 [(set (match_operand:XF 0 "register_operand" "=f")
14099 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14100 UNSPEC_XTRACT_FRACT))
14101 (set (match_operand:XF 1 "register_operand" "=u")
14102 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && flag_unsafe_math_optimizations"
14105 "fxtract"
14106 [(set_attr "type" "fpspc")
14107 (set_attr "mode" "XF")])
14108
14109 (define_insn "fxtract_extend<mode>xf3_i387"
14110 [(set (match_operand:XF 0 "register_operand" "=f")
14111 (unspec:XF [(float_extend:XF
14112 (match_operand:MODEF 2 "register_operand" "0"))]
14113 UNSPEC_XTRACT_FRACT))
14114 (set (match_operand:XF 1 "register_operand" "=u")
14115 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations"
14120 "fxtract"
14121 [(set_attr "type" "fpspc")
14122 (set_attr "mode" "XF")])
14123
14124 (define_expand "logbxf2"
14125 [(parallel [(set (match_dup 2)
14126 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14127 UNSPEC_XTRACT_FRACT))
14128 (set (match_operand:XF 0 "register_operand" "")
14129 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14130 "TARGET_USE_FANCY_MATH_387
14131 && flag_unsafe_math_optimizations"
14132 "operands[2] = gen_reg_rtx (XFmode);")
14133
14134 (define_expand "logb<mode>2"
14135 [(use (match_operand:MODEF 0 "register_operand" ""))
14136 (use (match_operand:MODEF 1 "register_operand" ""))]
14137 "TARGET_USE_FANCY_MATH_387
14138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14139 || TARGET_MIX_SSE_I387)
14140 && flag_unsafe_math_optimizations"
14141 {
14142 rtx op0 = gen_reg_rtx (XFmode);
14143 rtx op1 = gen_reg_rtx (XFmode);
14144
14145 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14147 DONE;
14148 })
14149
14150 (define_expand "ilogbxf2"
14151 [(use (match_operand:SI 0 "register_operand" ""))
14152 (use (match_operand:XF 1 "register_operand" ""))]
14153 "TARGET_USE_FANCY_MATH_387
14154 && flag_unsafe_math_optimizations"
14155 {
14156 rtx op0, op1;
14157
14158 if (optimize_insn_for_size_p ())
14159 FAIL;
14160
14161 op0 = gen_reg_rtx (XFmode);
14162 op1 = gen_reg_rtx (XFmode);
14163
14164 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14165 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14166 DONE;
14167 })
14168
14169 (define_expand "ilogb<mode>2"
14170 [(use (match_operand:SI 0 "register_operand" ""))
14171 (use (match_operand:MODEF 1 "register_operand" ""))]
14172 "TARGET_USE_FANCY_MATH_387
14173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14174 || TARGET_MIX_SSE_I387)
14175 && flag_unsafe_math_optimizations"
14176 {
14177 rtx op0, op1;
14178
14179 if (optimize_insn_for_size_p ())
14180 FAIL;
14181
14182 op0 = gen_reg_rtx (XFmode);
14183 op1 = gen_reg_rtx (XFmode);
14184
14185 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14186 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14187 DONE;
14188 })
14189
14190 (define_insn "*f2xm1xf2_i387"
14191 [(set (match_operand:XF 0 "register_operand" "=f")
14192 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14193 UNSPEC_F2XM1))]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14196 "f2xm1"
14197 [(set_attr "type" "fpspc")
14198 (set_attr "mode" "XF")])
14199
14200 (define_insn "*fscalexf4_i387"
14201 [(set (match_operand:XF 0 "register_operand" "=f")
14202 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14203 (match_operand:XF 3 "register_operand" "1")]
14204 UNSPEC_FSCALE_FRACT))
14205 (set (match_operand:XF 1 "register_operand" "=u")
14206 (unspec:XF [(match_dup 2) (match_dup 3)]
14207 UNSPEC_FSCALE_EXP))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14210 "fscale"
14211 [(set_attr "type" "fpspc")
14212 (set_attr "mode" "XF")])
14213
14214 (define_expand "expNcorexf3"
14215 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14216 (match_operand:XF 2 "register_operand" "")))
14217 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14218 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14219 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14220 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14221 (parallel [(set (match_operand:XF 0 "register_operand" "")
14222 (unspec:XF [(match_dup 8) (match_dup 4)]
14223 UNSPEC_FSCALE_FRACT))
14224 (set (match_dup 9)
14225 (unspec:XF [(match_dup 8) (match_dup 4)]
14226 UNSPEC_FSCALE_EXP))])]
14227 "TARGET_USE_FANCY_MATH_387
14228 && flag_unsafe_math_optimizations"
14229 {
14230 int i;
14231
14232 if (optimize_insn_for_size_p ())
14233 FAIL;
14234
14235 for (i = 3; i < 10; i++)
14236 operands[i] = gen_reg_rtx (XFmode);
14237
14238 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14239 })
14240
14241 (define_expand "expxf2"
14242 [(use (match_operand:XF 0 "register_operand" ""))
14243 (use (match_operand:XF 1 "register_operand" ""))]
14244 "TARGET_USE_FANCY_MATH_387
14245 && flag_unsafe_math_optimizations"
14246 {
14247 rtx op2;
14248
14249 if (optimize_insn_for_size_p ())
14250 FAIL;
14251
14252 op2 = gen_reg_rtx (XFmode);
14253 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14254
14255 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14256 DONE;
14257 })
14258
14259 (define_expand "exp<mode>2"
14260 [(use (match_operand:MODEF 0 "register_operand" ""))
14261 (use (match_operand:MODEF 1 "general_operand" ""))]
14262 "TARGET_USE_FANCY_MATH_387
14263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264 || TARGET_MIX_SSE_I387)
14265 && flag_unsafe_math_optimizations"
14266 {
14267 rtx op0, op1;
14268
14269 if (optimize_insn_for_size_p ())
14270 FAIL;
14271
14272 op0 = gen_reg_rtx (XFmode);
14273 op1 = gen_reg_rtx (XFmode);
14274
14275 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14276 emit_insn (gen_expxf2 (op0, op1));
14277 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14278 DONE;
14279 })
14280
14281 (define_expand "exp10xf2"
14282 [(use (match_operand:XF 0 "register_operand" ""))
14283 (use (match_operand:XF 1 "register_operand" ""))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && flag_unsafe_math_optimizations"
14286 {
14287 rtx op2;
14288
14289 if (optimize_insn_for_size_p ())
14290 FAIL;
14291
14292 op2 = gen_reg_rtx (XFmode);
14293 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14294
14295 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14296 DONE;
14297 })
14298
14299 (define_expand "exp10<mode>2"
14300 [(use (match_operand:MODEF 0 "register_operand" ""))
14301 (use (match_operand:MODEF 1 "general_operand" ""))]
14302 "TARGET_USE_FANCY_MATH_387
14303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14304 || TARGET_MIX_SSE_I387)
14305 && flag_unsafe_math_optimizations"
14306 {
14307 rtx op0, op1;
14308
14309 if (optimize_insn_for_size_p ())
14310 FAIL;
14311
14312 op0 = gen_reg_rtx (XFmode);
14313 op1 = gen_reg_rtx (XFmode);
14314
14315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14316 emit_insn (gen_exp10xf2 (op0, op1));
14317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14318 DONE;
14319 })
14320
14321 (define_expand "exp2xf2"
14322 [(use (match_operand:XF 0 "register_operand" ""))
14323 (use (match_operand:XF 1 "register_operand" ""))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && flag_unsafe_math_optimizations"
14326 {
14327 rtx op2;
14328
14329 if (optimize_insn_for_size_p ())
14330 FAIL;
14331
14332 op2 = gen_reg_rtx (XFmode);
14333 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14334
14335 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14336 DONE;
14337 })
14338
14339 (define_expand "exp2<mode>2"
14340 [(use (match_operand:MODEF 0 "register_operand" ""))
14341 (use (match_operand:MODEF 1 "general_operand" ""))]
14342 "TARGET_USE_FANCY_MATH_387
14343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14344 || TARGET_MIX_SSE_I387)
14345 && flag_unsafe_math_optimizations"
14346 {
14347 rtx op0, op1;
14348
14349 if (optimize_insn_for_size_p ())
14350 FAIL;
14351
14352 op0 = gen_reg_rtx (XFmode);
14353 op1 = gen_reg_rtx (XFmode);
14354
14355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14356 emit_insn (gen_exp2xf2 (op0, op1));
14357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14358 DONE;
14359 })
14360
14361 (define_expand "expm1xf2"
14362 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14363 (match_dup 2)))
14364 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14365 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14366 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14367 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14368 (parallel [(set (match_dup 7)
14369 (unspec:XF [(match_dup 6) (match_dup 4)]
14370 UNSPEC_FSCALE_FRACT))
14371 (set (match_dup 8)
14372 (unspec:XF [(match_dup 6) (match_dup 4)]
14373 UNSPEC_FSCALE_EXP))])
14374 (parallel [(set (match_dup 10)
14375 (unspec:XF [(match_dup 9) (match_dup 8)]
14376 UNSPEC_FSCALE_FRACT))
14377 (set (match_dup 11)
14378 (unspec:XF [(match_dup 9) (match_dup 8)]
14379 UNSPEC_FSCALE_EXP))])
14380 (set (match_dup 12) (minus:XF (match_dup 10)
14381 (float_extend:XF (match_dup 13))))
14382 (set (match_operand:XF 0 "register_operand" "")
14383 (plus:XF (match_dup 12) (match_dup 7)))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14386 {
14387 int i;
14388
14389 if (optimize_insn_for_size_p ())
14390 FAIL;
14391
14392 for (i = 2; i < 13; i++)
14393 operands[i] = gen_reg_rtx (XFmode);
14394
14395 operands[13]
14396 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14397
14398 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14399 })
14400
14401 (define_expand "expm1<mode>2"
14402 [(use (match_operand:MODEF 0 "register_operand" ""))
14403 (use (match_operand:MODEF 1 "general_operand" ""))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14406 || TARGET_MIX_SSE_I387)
14407 && flag_unsafe_math_optimizations"
14408 {
14409 rtx op0, op1;
14410
14411 if (optimize_insn_for_size_p ())
14412 FAIL;
14413
14414 op0 = gen_reg_rtx (XFmode);
14415 op1 = gen_reg_rtx (XFmode);
14416
14417 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14418 emit_insn (gen_expm1xf2 (op0, op1));
14419 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14420 DONE;
14421 })
14422
14423 (define_expand "ldexpxf3"
14424 [(set (match_dup 3)
14425 (float:XF (match_operand:SI 2 "register_operand" "")))
14426 (parallel [(set (match_operand:XF 0 " register_operand" "")
14427 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14428 (match_dup 3)]
14429 UNSPEC_FSCALE_FRACT))
14430 (set (match_dup 4)
14431 (unspec:XF [(match_dup 1) (match_dup 3)]
14432 UNSPEC_FSCALE_EXP))])]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_unsafe_math_optimizations"
14435 {
14436 if (optimize_insn_for_size_p ())
14437 FAIL;
14438
14439 operands[3] = gen_reg_rtx (XFmode);
14440 operands[4] = gen_reg_rtx (XFmode);
14441 })
14442
14443 (define_expand "ldexp<mode>3"
14444 [(use (match_operand:MODEF 0 "register_operand" ""))
14445 (use (match_operand:MODEF 1 "general_operand" ""))
14446 (use (match_operand:SI 2 "register_operand" ""))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449 || TARGET_MIX_SSE_I387)
14450 && flag_unsafe_math_optimizations"
14451 {
14452 rtx op0, op1;
14453
14454 if (optimize_insn_for_size_p ())
14455 FAIL;
14456
14457 op0 = gen_reg_rtx (XFmode);
14458 op1 = gen_reg_rtx (XFmode);
14459
14460 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14461 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14462 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14463 DONE;
14464 })
14465
14466 (define_expand "scalbxf3"
14467 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14468 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14469 (match_operand:XF 2 "register_operand" "")]
14470 UNSPEC_FSCALE_FRACT))
14471 (set (match_dup 3)
14472 (unspec:XF [(match_dup 1) (match_dup 2)]
14473 UNSPEC_FSCALE_EXP))])]
14474 "TARGET_USE_FANCY_MATH_387
14475 && flag_unsafe_math_optimizations"
14476 {
14477 if (optimize_insn_for_size_p ())
14478 FAIL;
14479
14480 operands[3] = gen_reg_rtx (XFmode);
14481 })
14482
14483 (define_expand "scalb<mode>3"
14484 [(use (match_operand:MODEF 0 "register_operand" ""))
14485 (use (match_operand:MODEF 1 "general_operand" ""))
14486 (use (match_operand:MODEF 2 "general_operand" ""))]
14487 "TARGET_USE_FANCY_MATH_387
14488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14489 || TARGET_MIX_SSE_I387)
14490 && flag_unsafe_math_optimizations"
14491 {
14492 rtx op0, op1, op2;
14493
14494 if (optimize_insn_for_size_p ())
14495 FAIL;
14496
14497 op0 = gen_reg_rtx (XFmode);
14498 op1 = gen_reg_rtx (XFmode);
14499 op2 = gen_reg_rtx (XFmode);
14500
14501 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14502 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14503 emit_insn (gen_scalbxf3 (op0, op1, op2));
14504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14505 DONE;
14506 })
14507
14508 (define_expand "significandxf2"
14509 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14510 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14511 UNSPEC_XTRACT_FRACT))
14512 (set (match_dup 2)
14513 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14514 "TARGET_USE_FANCY_MATH_387
14515 && flag_unsafe_math_optimizations"
14516 "operands[2] = gen_reg_rtx (XFmode);")
14517
14518 (define_expand "significand<mode>2"
14519 [(use (match_operand:MODEF 0 "register_operand" ""))
14520 (use (match_operand:MODEF 1 "register_operand" ""))]
14521 "TARGET_USE_FANCY_MATH_387
14522 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14523 || TARGET_MIX_SSE_I387)
14524 && flag_unsafe_math_optimizations"
14525 {
14526 rtx op0 = gen_reg_rtx (XFmode);
14527 rtx op1 = gen_reg_rtx (XFmode);
14528
14529 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14530 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14531 DONE;
14532 })
14533 \f
14534
14535 (define_insn "sse4_1_round<mode>2"
14536 [(set (match_operand:MODEF 0 "register_operand" "=x")
14537 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14538 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14539 UNSPEC_ROUND))]
14540 "TARGET_ROUND"
14541 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14542 [(set_attr "type" "ssecvt")
14543 (set_attr "prefix_extra" "1")
14544 (set_attr "prefix" "maybe_vex")
14545 (set_attr "mode" "<MODE>")])
14546
14547 (define_insn "rintxf2"
14548 [(set (match_operand:XF 0 "register_operand" "=f")
14549 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14550 UNSPEC_FRNDINT))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14553 "frndint"
14554 [(set_attr "type" "fpspc")
14555 (set_attr "mode" "XF")])
14556
14557 (define_expand "rint<mode>2"
14558 [(use (match_operand:MODEF 0 "register_operand" ""))
14559 (use (match_operand:MODEF 1 "register_operand" ""))]
14560 "(TARGET_USE_FANCY_MATH_387
14561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14562 || TARGET_MIX_SSE_I387)
14563 && flag_unsafe_math_optimizations)
14564 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14565 && !flag_trapping_math)"
14566 {
14567 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14568 && !flag_trapping_math)
14569 {
14570 if (TARGET_ROUND)
14571 emit_insn (gen_sse4_1_round<mode>2
14572 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14573 else if (optimize_insn_for_size_p ())
14574 FAIL;
14575 else
14576 ix86_expand_rint (operands[0], operands[1]);
14577 }
14578 else
14579 {
14580 rtx op0 = gen_reg_rtx (XFmode);
14581 rtx op1 = gen_reg_rtx (XFmode);
14582
14583 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14584 emit_insn (gen_rintxf2 (op0, op1));
14585
14586 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14587 }
14588 DONE;
14589 })
14590
14591 (define_expand "round<mode>2"
14592 [(match_operand:X87MODEF 0 "register_operand" "")
14593 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14594 "(TARGET_USE_FANCY_MATH_387
14595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14596 || TARGET_MIX_SSE_I387)
14597 && flag_unsafe_math_optimizations)
14598 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14599 && !flag_trapping_math && !flag_rounding_math)"
14600 {
14601 if (optimize_insn_for_size_p ())
14602 FAIL;
14603
14604 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14605 && !flag_trapping_math && !flag_rounding_math)
14606 {
14607 if (TARGET_ROUND)
14608 {
14609 operands[1] = force_reg (<MODE>mode, operands[1]);
14610 ix86_expand_round_sse4 (operands[0], operands[1]);
14611 }
14612 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14613 ix86_expand_round (operands[0], operands[1]);
14614 else
14615 ix86_expand_rounddf_32 (operands[0], operands[1]);
14616 }
14617 else
14618 {
14619 operands[1] = force_reg (<MODE>mode, operands[1]);
14620 ix86_emit_i387_round (operands[0], operands[1]);
14621 }
14622 DONE;
14623 })
14624
14625 (define_insn_and_split "*fistdi2_1"
14626 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14627 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14628 UNSPEC_FIST))]
14629 "TARGET_USE_FANCY_MATH_387
14630 && can_create_pseudo_p ()"
14631 "#"
14632 "&& 1"
14633 [(const_int 0)]
14634 {
14635 if (memory_operand (operands[0], VOIDmode))
14636 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14637 else
14638 {
14639 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14640 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14641 operands[2]));
14642 }
14643 DONE;
14644 }
14645 [(set_attr "type" "fpspc")
14646 (set_attr "mode" "DI")])
14647
14648 (define_insn "fistdi2"
14649 [(set (match_operand:DI 0 "memory_operand" "=m")
14650 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14651 UNSPEC_FIST))
14652 (clobber (match_scratch:XF 2 "=&1f"))]
14653 "TARGET_USE_FANCY_MATH_387"
14654 "* return output_fix_trunc (insn, operands, false);"
14655 [(set_attr "type" "fpspc")
14656 (set_attr "mode" "DI")])
14657
14658 (define_insn "fistdi2_with_temp"
14659 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14660 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14661 UNSPEC_FIST))
14662 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14663 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14664 "TARGET_USE_FANCY_MATH_387"
14665 "#"
14666 [(set_attr "type" "fpspc")
14667 (set_attr "mode" "DI")])
14668
14669 (define_split
14670 [(set (match_operand:DI 0 "register_operand" "")
14671 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14672 UNSPEC_FIST))
14673 (clobber (match_operand:DI 2 "memory_operand" ""))
14674 (clobber (match_scratch 3 ""))]
14675 "reload_completed"
14676 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14677 (clobber (match_dup 3))])
14678 (set (match_dup 0) (match_dup 2))])
14679
14680 (define_split
14681 [(set (match_operand:DI 0 "memory_operand" "")
14682 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14683 UNSPEC_FIST))
14684 (clobber (match_operand:DI 2 "memory_operand" ""))
14685 (clobber (match_scratch 3 ""))]
14686 "reload_completed"
14687 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14688 (clobber (match_dup 3))])])
14689
14690 (define_insn_and_split "*fist<mode>2_1"
14691 [(set (match_operand:SWI24 0 "register_operand" "")
14692 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14693 UNSPEC_FIST))]
14694 "TARGET_USE_FANCY_MATH_387
14695 && can_create_pseudo_p ()"
14696 "#"
14697 "&& 1"
14698 [(const_int 0)]
14699 {
14700 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14701 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14702 operands[2]));
14703 DONE;
14704 }
14705 [(set_attr "type" "fpspc")
14706 (set_attr "mode" "<MODE>")])
14707
14708 (define_insn "fist<mode>2"
14709 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14710 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14711 UNSPEC_FIST))]
14712 "TARGET_USE_FANCY_MATH_387"
14713 "* return output_fix_trunc (insn, operands, false);"
14714 [(set_attr "type" "fpspc")
14715 (set_attr "mode" "<MODE>")])
14716
14717 (define_insn "fist<mode>2_with_temp"
14718 [(set (match_operand:SWI24 0 "register_operand" "=r")
14719 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14720 UNSPEC_FIST))
14721 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14722 "TARGET_USE_FANCY_MATH_387"
14723 "#"
14724 [(set_attr "type" "fpspc")
14725 (set_attr "mode" "<MODE>")])
14726
14727 (define_split
14728 [(set (match_operand:SWI24 0 "register_operand" "")
14729 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14730 UNSPEC_FIST))
14731 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14732 "reload_completed"
14733 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14734 (set (match_dup 0) (match_dup 2))])
14735
14736 (define_split
14737 [(set (match_operand:SWI24 0 "memory_operand" "")
14738 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14739 UNSPEC_FIST))
14740 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14741 "reload_completed"
14742 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14743
14744 (define_expand "lrintxf<mode>2"
14745 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14746 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14747 UNSPEC_FIST))]
14748 "TARGET_USE_FANCY_MATH_387")
14749
14750 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14751 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14752 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14753 UNSPEC_FIX_NOTRUNC))]
14754 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14755 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14756
14757 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14758 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14759 (match_operand:X87MODEF 1 "register_operand" "")]
14760 "(TARGET_USE_FANCY_MATH_387
14761 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14762 || TARGET_MIX_SSE_I387)
14763 && flag_unsafe_math_optimizations)
14764 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14765 && <SWI248x:MODE>mode != HImode
14766 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14767 && !flag_trapping_math && !flag_rounding_math)"
14768 {
14769 if (optimize_insn_for_size_p ())
14770 FAIL;
14771
14772 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14773 && <SWI248x:MODE>mode != HImode
14774 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14775 && !flag_trapping_math && !flag_rounding_math)
14776 ix86_expand_lround (operands[0], operands[1]);
14777 else
14778 ix86_emit_i387_round (operands[0], operands[1]);
14779 DONE;
14780 })
14781
14782 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14783 (define_insn_and_split "frndintxf2_floor"
14784 [(set (match_operand:XF 0 "register_operand" "")
14785 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14786 UNSPEC_FRNDINT_FLOOR))
14787 (clobber (reg:CC FLAGS_REG))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations
14790 && can_create_pseudo_p ()"
14791 "#"
14792 "&& 1"
14793 [(const_int 0)]
14794 {
14795 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14796
14797 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14798 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14799
14800 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14801 operands[2], operands[3]));
14802 DONE;
14803 }
14804 [(set_attr "type" "frndint")
14805 (set_attr "i387_cw" "floor")
14806 (set_attr "mode" "XF")])
14807
14808 (define_insn "frndintxf2_floor_i387"
14809 [(set (match_operand:XF 0 "register_operand" "=f")
14810 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14811 UNSPEC_FRNDINT_FLOOR))
14812 (use (match_operand:HI 2 "memory_operand" "m"))
14813 (use (match_operand:HI 3 "memory_operand" "m"))]
14814 "TARGET_USE_FANCY_MATH_387
14815 && flag_unsafe_math_optimizations"
14816 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14817 [(set_attr "type" "frndint")
14818 (set_attr "i387_cw" "floor")
14819 (set_attr "mode" "XF")])
14820
14821 (define_expand "floorxf2"
14822 [(use (match_operand:XF 0 "register_operand" ""))
14823 (use (match_operand:XF 1 "register_operand" ""))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14826 {
14827 if (optimize_insn_for_size_p ())
14828 FAIL;
14829 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14830 DONE;
14831 })
14832
14833 (define_expand "floor<mode>2"
14834 [(use (match_operand:MODEF 0 "register_operand" ""))
14835 (use (match_operand:MODEF 1 "register_operand" ""))]
14836 "(TARGET_USE_FANCY_MATH_387
14837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838 || TARGET_MIX_SSE_I387)
14839 && flag_unsafe_math_optimizations)
14840 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14841 && !flag_trapping_math)"
14842 {
14843 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844 && !flag_trapping_math)
14845 {
14846 if (TARGET_ROUND)
14847 emit_insn (gen_sse4_1_round<mode>2
14848 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14849 else if (optimize_insn_for_size_p ())
14850 FAIL;
14851 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14852 ix86_expand_floorceil (operands[0], operands[1], true);
14853 else
14854 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14855 }
14856 else
14857 {
14858 rtx op0, op1;
14859
14860 if (optimize_insn_for_size_p ())
14861 FAIL;
14862
14863 op0 = gen_reg_rtx (XFmode);
14864 op1 = gen_reg_rtx (XFmode);
14865 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14866 emit_insn (gen_frndintxf2_floor (op0, op1));
14867
14868 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14869 }
14870 DONE;
14871 })
14872
14873 (define_insn_and_split "*fist<mode>2_floor_1"
14874 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14875 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14876 UNSPEC_FIST_FLOOR))
14877 (clobber (reg:CC FLAGS_REG))]
14878 "TARGET_USE_FANCY_MATH_387
14879 && flag_unsafe_math_optimizations
14880 && can_create_pseudo_p ()"
14881 "#"
14882 "&& 1"
14883 [(const_int 0)]
14884 {
14885 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14886
14887 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14888 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14889 if (memory_operand (operands[0], VOIDmode))
14890 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14891 operands[2], operands[3]));
14892 else
14893 {
14894 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14895 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14896 operands[2], operands[3],
14897 operands[4]));
14898 }
14899 DONE;
14900 }
14901 [(set_attr "type" "fistp")
14902 (set_attr "i387_cw" "floor")
14903 (set_attr "mode" "<MODE>")])
14904
14905 (define_insn "fistdi2_floor"
14906 [(set (match_operand:DI 0 "memory_operand" "=m")
14907 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14908 UNSPEC_FIST_FLOOR))
14909 (use (match_operand:HI 2 "memory_operand" "m"))
14910 (use (match_operand:HI 3 "memory_operand" "m"))
14911 (clobber (match_scratch:XF 4 "=&1f"))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14914 "* return output_fix_trunc (insn, operands, false);"
14915 [(set_attr "type" "fistp")
14916 (set_attr "i387_cw" "floor")
14917 (set_attr "mode" "DI")])
14918
14919 (define_insn "fistdi2_floor_with_temp"
14920 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14921 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14922 UNSPEC_FIST_FLOOR))
14923 (use (match_operand:HI 2 "memory_operand" "m,m"))
14924 (use (match_operand:HI 3 "memory_operand" "m,m"))
14925 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14926 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && flag_unsafe_math_optimizations"
14929 "#"
14930 [(set_attr "type" "fistp")
14931 (set_attr "i387_cw" "floor")
14932 (set_attr "mode" "DI")])
14933
14934 (define_split
14935 [(set (match_operand:DI 0 "register_operand" "")
14936 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14937 UNSPEC_FIST_FLOOR))
14938 (use (match_operand:HI 2 "memory_operand" ""))
14939 (use (match_operand:HI 3 "memory_operand" ""))
14940 (clobber (match_operand:DI 4 "memory_operand" ""))
14941 (clobber (match_scratch 5 ""))]
14942 "reload_completed"
14943 [(parallel [(set (match_dup 4)
14944 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14945 (use (match_dup 2))
14946 (use (match_dup 3))
14947 (clobber (match_dup 5))])
14948 (set (match_dup 0) (match_dup 4))])
14949
14950 (define_split
14951 [(set (match_operand:DI 0 "memory_operand" "")
14952 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14953 UNSPEC_FIST_FLOOR))
14954 (use (match_operand:HI 2 "memory_operand" ""))
14955 (use (match_operand:HI 3 "memory_operand" ""))
14956 (clobber (match_operand:DI 4 "memory_operand" ""))
14957 (clobber (match_scratch 5 ""))]
14958 "reload_completed"
14959 [(parallel [(set (match_dup 0)
14960 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14961 (use (match_dup 2))
14962 (use (match_dup 3))
14963 (clobber (match_dup 5))])])
14964
14965 (define_insn "fist<mode>2_floor"
14966 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14967 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14968 UNSPEC_FIST_FLOOR))
14969 (use (match_operand:HI 2 "memory_operand" "m"))
14970 (use (match_operand:HI 3 "memory_operand" "m"))]
14971 "TARGET_USE_FANCY_MATH_387
14972 && flag_unsafe_math_optimizations"
14973 "* return output_fix_trunc (insn, operands, false);"
14974 [(set_attr "type" "fistp")
14975 (set_attr "i387_cw" "floor")
14976 (set_attr "mode" "<MODE>")])
14977
14978 (define_insn "fist<mode>2_floor_with_temp"
14979 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14980 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14981 UNSPEC_FIST_FLOOR))
14982 (use (match_operand:HI 2 "memory_operand" "m,m"))
14983 (use (match_operand:HI 3 "memory_operand" "m,m"))
14984 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14985 "TARGET_USE_FANCY_MATH_387
14986 && flag_unsafe_math_optimizations"
14987 "#"
14988 [(set_attr "type" "fistp")
14989 (set_attr "i387_cw" "floor")
14990 (set_attr "mode" "<MODE>")])
14991
14992 (define_split
14993 [(set (match_operand:SWI24 0 "register_operand" "")
14994 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14995 UNSPEC_FIST_FLOOR))
14996 (use (match_operand:HI 2 "memory_operand" ""))
14997 (use (match_operand:HI 3 "memory_operand" ""))
14998 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14999 "reload_completed"
15000 [(parallel [(set (match_dup 4)
15001 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15002 (use (match_dup 2))
15003 (use (match_dup 3))])
15004 (set (match_dup 0) (match_dup 4))])
15005
15006 (define_split
15007 [(set (match_operand:SWI24 0 "memory_operand" "")
15008 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15009 UNSPEC_FIST_FLOOR))
15010 (use (match_operand:HI 2 "memory_operand" ""))
15011 (use (match_operand:HI 3 "memory_operand" ""))
15012 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15013 "reload_completed"
15014 [(parallel [(set (match_dup 0)
15015 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15016 (use (match_dup 2))
15017 (use (match_dup 3))])])
15018
15019 (define_expand "lfloorxf<mode>2"
15020 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15021 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15022 UNSPEC_FIST_FLOOR))
15023 (clobber (reg:CC FLAGS_REG))])]
15024 "TARGET_USE_FANCY_MATH_387
15025 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15026 && flag_unsafe_math_optimizations")
15027
15028 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15029 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15030 (match_operand:MODEF 1 "register_operand" "")]
15031 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15032 && !flag_trapping_math"
15033 {
15034 if (TARGET_64BIT && optimize_insn_for_size_p ())
15035 FAIL;
15036 ix86_expand_lfloorceil (operands[0], operands[1], true);
15037 DONE;
15038 })
15039
15040 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15041 (define_insn_and_split "frndintxf2_ceil"
15042 [(set (match_operand:XF 0 "register_operand" "")
15043 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15044 UNSPEC_FRNDINT_CEIL))
15045 (clobber (reg:CC FLAGS_REG))]
15046 "TARGET_USE_FANCY_MATH_387
15047 && flag_unsafe_math_optimizations
15048 && can_create_pseudo_p ()"
15049 "#"
15050 "&& 1"
15051 [(const_int 0)]
15052 {
15053 ix86_optimize_mode_switching[I387_CEIL] = 1;
15054
15055 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15056 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15057
15058 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15059 operands[2], operands[3]));
15060 DONE;
15061 }
15062 [(set_attr "type" "frndint")
15063 (set_attr "i387_cw" "ceil")
15064 (set_attr "mode" "XF")])
15065
15066 (define_insn "frndintxf2_ceil_i387"
15067 [(set (match_operand:XF 0 "register_operand" "=f")
15068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15069 UNSPEC_FRNDINT_CEIL))
15070 (use (match_operand:HI 2 "memory_operand" "m"))
15071 (use (match_operand:HI 3 "memory_operand" "m"))]
15072 "TARGET_USE_FANCY_MATH_387
15073 && flag_unsafe_math_optimizations"
15074 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15075 [(set_attr "type" "frndint")
15076 (set_attr "i387_cw" "ceil")
15077 (set_attr "mode" "XF")])
15078
15079 (define_expand "ceilxf2"
15080 [(use (match_operand:XF 0 "register_operand" ""))
15081 (use (match_operand:XF 1 "register_operand" ""))]
15082 "TARGET_USE_FANCY_MATH_387
15083 && flag_unsafe_math_optimizations"
15084 {
15085 if (optimize_insn_for_size_p ())
15086 FAIL;
15087 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15088 DONE;
15089 })
15090
15091 (define_expand "ceil<mode>2"
15092 [(use (match_operand:MODEF 0 "register_operand" ""))
15093 (use (match_operand:MODEF 1 "register_operand" ""))]
15094 "(TARGET_USE_FANCY_MATH_387
15095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15096 || TARGET_MIX_SSE_I387)
15097 && flag_unsafe_math_optimizations)
15098 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15099 && !flag_trapping_math)"
15100 {
15101 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15102 && !flag_trapping_math)
15103 {
15104 if (TARGET_ROUND)
15105 emit_insn (gen_sse4_1_round<mode>2
15106 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15107 else if (optimize_insn_for_size_p ())
15108 FAIL;
15109 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15110 ix86_expand_floorceil (operands[0], operands[1], false);
15111 else
15112 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15113 }
15114 else
15115 {
15116 rtx op0, op1;
15117
15118 if (optimize_insn_for_size_p ())
15119 FAIL;
15120
15121 op0 = gen_reg_rtx (XFmode);
15122 op1 = gen_reg_rtx (XFmode);
15123 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15124 emit_insn (gen_frndintxf2_ceil (op0, op1));
15125
15126 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15127 }
15128 DONE;
15129 })
15130
15131 (define_insn_and_split "*fist<mode>2_ceil_1"
15132 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15133 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15134 UNSPEC_FIST_CEIL))
15135 (clobber (reg:CC FLAGS_REG))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && flag_unsafe_math_optimizations
15138 && can_create_pseudo_p ()"
15139 "#"
15140 "&& 1"
15141 [(const_int 0)]
15142 {
15143 ix86_optimize_mode_switching[I387_CEIL] = 1;
15144
15145 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15146 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15147 if (memory_operand (operands[0], VOIDmode))
15148 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15149 operands[2], operands[3]));
15150 else
15151 {
15152 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15153 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15154 operands[2], operands[3],
15155 operands[4]));
15156 }
15157 DONE;
15158 }
15159 [(set_attr "type" "fistp")
15160 (set_attr "i387_cw" "ceil")
15161 (set_attr "mode" "<MODE>")])
15162
15163 (define_insn "fistdi2_ceil"
15164 [(set (match_operand:DI 0 "memory_operand" "=m")
15165 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15166 UNSPEC_FIST_CEIL))
15167 (use (match_operand:HI 2 "memory_operand" "m"))
15168 (use (match_operand:HI 3 "memory_operand" "m"))
15169 (clobber (match_scratch:XF 4 "=&1f"))]
15170 "TARGET_USE_FANCY_MATH_387
15171 && flag_unsafe_math_optimizations"
15172 "* return output_fix_trunc (insn, operands, false);"
15173 [(set_attr "type" "fistp")
15174 (set_attr "i387_cw" "ceil")
15175 (set_attr "mode" "DI")])
15176
15177 (define_insn "fistdi2_ceil_with_temp"
15178 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15179 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15180 UNSPEC_FIST_CEIL))
15181 (use (match_operand:HI 2 "memory_operand" "m,m"))
15182 (use (match_operand:HI 3 "memory_operand" "m,m"))
15183 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15184 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15185 "TARGET_USE_FANCY_MATH_387
15186 && flag_unsafe_math_optimizations"
15187 "#"
15188 [(set_attr "type" "fistp")
15189 (set_attr "i387_cw" "ceil")
15190 (set_attr "mode" "DI")])
15191
15192 (define_split
15193 [(set (match_operand:DI 0 "register_operand" "")
15194 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15195 UNSPEC_FIST_CEIL))
15196 (use (match_operand:HI 2 "memory_operand" ""))
15197 (use (match_operand:HI 3 "memory_operand" ""))
15198 (clobber (match_operand:DI 4 "memory_operand" ""))
15199 (clobber (match_scratch 5 ""))]
15200 "reload_completed"
15201 [(parallel [(set (match_dup 4)
15202 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15203 (use (match_dup 2))
15204 (use (match_dup 3))
15205 (clobber (match_dup 5))])
15206 (set (match_dup 0) (match_dup 4))])
15207
15208 (define_split
15209 [(set (match_operand:DI 0 "memory_operand" "")
15210 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15211 UNSPEC_FIST_CEIL))
15212 (use (match_operand:HI 2 "memory_operand" ""))
15213 (use (match_operand:HI 3 "memory_operand" ""))
15214 (clobber (match_operand:DI 4 "memory_operand" ""))
15215 (clobber (match_scratch 5 ""))]
15216 "reload_completed"
15217 [(parallel [(set (match_dup 0)
15218 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15219 (use (match_dup 2))
15220 (use (match_dup 3))
15221 (clobber (match_dup 5))])])
15222
15223 (define_insn "fist<mode>2_ceil"
15224 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15225 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15226 UNSPEC_FIST_CEIL))
15227 (use (match_operand:HI 2 "memory_operand" "m"))
15228 (use (match_operand:HI 3 "memory_operand" "m"))]
15229 "TARGET_USE_FANCY_MATH_387
15230 && flag_unsafe_math_optimizations"
15231 "* return output_fix_trunc (insn, operands, false);"
15232 [(set_attr "type" "fistp")
15233 (set_attr "i387_cw" "ceil")
15234 (set_attr "mode" "<MODE>")])
15235
15236 (define_insn "fist<mode>2_ceil_with_temp"
15237 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15238 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15239 UNSPEC_FIST_CEIL))
15240 (use (match_operand:HI 2 "memory_operand" "m,m"))
15241 (use (match_operand:HI 3 "memory_operand" "m,m"))
15242 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15243 "TARGET_USE_FANCY_MATH_387
15244 && flag_unsafe_math_optimizations"
15245 "#"
15246 [(set_attr "type" "fistp")
15247 (set_attr "i387_cw" "ceil")
15248 (set_attr "mode" "<MODE>")])
15249
15250 (define_split
15251 [(set (match_operand:SWI24 0 "register_operand" "")
15252 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15253 UNSPEC_FIST_CEIL))
15254 (use (match_operand:HI 2 "memory_operand" ""))
15255 (use (match_operand:HI 3 "memory_operand" ""))
15256 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15257 "reload_completed"
15258 [(parallel [(set (match_dup 4)
15259 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15260 (use (match_dup 2))
15261 (use (match_dup 3))])
15262 (set (match_dup 0) (match_dup 4))])
15263
15264 (define_split
15265 [(set (match_operand:SWI24 0 "memory_operand" "")
15266 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15267 UNSPEC_FIST_CEIL))
15268 (use (match_operand:HI 2 "memory_operand" ""))
15269 (use (match_operand:HI 3 "memory_operand" ""))
15270 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15271 "reload_completed"
15272 [(parallel [(set (match_dup 0)
15273 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15274 (use (match_dup 2))
15275 (use (match_dup 3))])])
15276
15277 (define_expand "lceilxf<mode>2"
15278 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15279 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15280 UNSPEC_FIST_CEIL))
15281 (clobber (reg:CC FLAGS_REG))])]
15282 "TARGET_USE_FANCY_MATH_387
15283 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15284 && flag_unsafe_math_optimizations")
15285
15286 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15287 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15288 (match_operand:MODEF 1 "register_operand" "")]
15289 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15290 && !flag_trapping_math"
15291 {
15292 ix86_expand_lfloorceil (operands[0], operands[1], false);
15293 DONE;
15294 })
15295
15296 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15297 (define_insn_and_split "frndintxf2_trunc"
15298 [(set (match_operand:XF 0 "register_operand" "")
15299 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15300 UNSPEC_FRNDINT_TRUNC))
15301 (clobber (reg:CC FLAGS_REG))]
15302 "TARGET_USE_FANCY_MATH_387
15303 && flag_unsafe_math_optimizations
15304 && can_create_pseudo_p ()"
15305 "#"
15306 "&& 1"
15307 [(const_int 0)]
15308 {
15309 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15310
15311 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15312 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15313
15314 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15315 operands[2], operands[3]));
15316 DONE;
15317 }
15318 [(set_attr "type" "frndint")
15319 (set_attr "i387_cw" "trunc")
15320 (set_attr "mode" "XF")])
15321
15322 (define_insn "frndintxf2_trunc_i387"
15323 [(set (match_operand:XF 0 "register_operand" "=f")
15324 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15325 UNSPEC_FRNDINT_TRUNC))
15326 (use (match_operand:HI 2 "memory_operand" "m"))
15327 (use (match_operand:HI 3 "memory_operand" "m"))]
15328 "TARGET_USE_FANCY_MATH_387
15329 && flag_unsafe_math_optimizations"
15330 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15331 [(set_attr "type" "frndint")
15332 (set_attr "i387_cw" "trunc")
15333 (set_attr "mode" "XF")])
15334
15335 (define_expand "btruncxf2"
15336 [(use (match_operand:XF 0 "register_operand" ""))
15337 (use (match_operand:XF 1 "register_operand" ""))]
15338 "TARGET_USE_FANCY_MATH_387
15339 && flag_unsafe_math_optimizations"
15340 {
15341 if (optimize_insn_for_size_p ())
15342 FAIL;
15343 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15344 DONE;
15345 })
15346
15347 (define_expand "btrunc<mode>2"
15348 [(use (match_operand:MODEF 0 "register_operand" ""))
15349 (use (match_operand:MODEF 1 "register_operand" ""))]
15350 "(TARGET_USE_FANCY_MATH_387
15351 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15352 || TARGET_MIX_SSE_I387)
15353 && flag_unsafe_math_optimizations)
15354 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15355 && !flag_trapping_math)"
15356 {
15357 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15358 && !flag_trapping_math)
15359 {
15360 if (TARGET_ROUND)
15361 emit_insn (gen_sse4_1_round<mode>2
15362 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15363 else if (optimize_insn_for_size_p ())
15364 FAIL;
15365 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15366 ix86_expand_trunc (operands[0], operands[1]);
15367 else
15368 ix86_expand_truncdf_32 (operands[0], operands[1]);
15369 }
15370 else
15371 {
15372 rtx op0, op1;
15373
15374 if (optimize_insn_for_size_p ())
15375 FAIL;
15376
15377 op0 = gen_reg_rtx (XFmode);
15378 op1 = gen_reg_rtx (XFmode);
15379 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15380 emit_insn (gen_frndintxf2_trunc (op0, op1));
15381
15382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15383 }
15384 DONE;
15385 })
15386
15387 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15388 (define_insn_and_split "frndintxf2_mask_pm"
15389 [(set (match_operand:XF 0 "register_operand" "")
15390 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15391 UNSPEC_FRNDINT_MASK_PM))
15392 (clobber (reg:CC FLAGS_REG))]
15393 "TARGET_USE_FANCY_MATH_387
15394 && flag_unsafe_math_optimizations
15395 && can_create_pseudo_p ()"
15396 "#"
15397 "&& 1"
15398 [(const_int 0)]
15399 {
15400 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15401
15402 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15403 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15404
15405 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15406 operands[2], operands[3]));
15407 DONE;
15408 }
15409 [(set_attr "type" "frndint")
15410 (set_attr "i387_cw" "mask_pm")
15411 (set_attr "mode" "XF")])
15412
15413 (define_insn "frndintxf2_mask_pm_i387"
15414 [(set (match_operand:XF 0 "register_operand" "=f")
15415 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15416 UNSPEC_FRNDINT_MASK_PM))
15417 (use (match_operand:HI 2 "memory_operand" "m"))
15418 (use (match_operand:HI 3 "memory_operand" "m"))]
15419 "TARGET_USE_FANCY_MATH_387
15420 && flag_unsafe_math_optimizations"
15421 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15422 [(set_attr "type" "frndint")
15423 (set_attr "i387_cw" "mask_pm")
15424 (set_attr "mode" "XF")])
15425
15426 (define_expand "nearbyintxf2"
15427 [(use (match_operand:XF 0 "register_operand" ""))
15428 (use (match_operand:XF 1 "register_operand" ""))]
15429 "TARGET_USE_FANCY_MATH_387
15430 && flag_unsafe_math_optimizations"
15431 {
15432 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15433 DONE;
15434 })
15435
15436 (define_expand "nearbyint<mode>2"
15437 [(use (match_operand:MODEF 0 "register_operand" ""))
15438 (use (match_operand:MODEF 1 "register_operand" ""))]
15439 "TARGET_USE_FANCY_MATH_387
15440 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15441 || TARGET_MIX_SSE_I387)
15442 && flag_unsafe_math_optimizations"
15443 {
15444 rtx op0 = gen_reg_rtx (XFmode);
15445 rtx op1 = gen_reg_rtx (XFmode);
15446
15447 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15448 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15449
15450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15451 DONE;
15452 })
15453
15454 (define_insn "fxam<mode>2_i387"
15455 [(set (match_operand:HI 0 "register_operand" "=a")
15456 (unspec:HI
15457 [(match_operand:X87MODEF 1 "register_operand" "f")]
15458 UNSPEC_FXAM))]
15459 "TARGET_USE_FANCY_MATH_387"
15460 "fxam\n\tfnstsw\t%0"
15461 [(set_attr "type" "multi")
15462 (set_attr "length" "4")
15463 (set_attr "unit" "i387")
15464 (set_attr "mode" "<MODE>")])
15465
15466 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15467 [(set (match_operand:HI 0 "register_operand" "")
15468 (unspec:HI
15469 [(match_operand:MODEF 1 "memory_operand" "")]
15470 UNSPEC_FXAM_MEM))]
15471 "TARGET_USE_FANCY_MATH_387
15472 && can_create_pseudo_p ()"
15473 "#"
15474 "&& 1"
15475 [(set (match_dup 2)(match_dup 1))
15476 (set (match_dup 0)
15477 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15478 {
15479 operands[2] = gen_reg_rtx (<MODE>mode);
15480
15481 MEM_VOLATILE_P (operands[1]) = 1;
15482 }
15483 [(set_attr "type" "multi")
15484 (set_attr "unit" "i387")
15485 (set_attr "mode" "<MODE>")])
15486
15487 (define_expand "isinfxf2"
15488 [(use (match_operand:SI 0 "register_operand" ""))
15489 (use (match_operand:XF 1 "register_operand" ""))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && TARGET_C99_FUNCTIONS"
15492 {
15493 rtx mask = GEN_INT (0x45);
15494 rtx val = GEN_INT (0x05);
15495
15496 rtx cond;
15497
15498 rtx scratch = gen_reg_rtx (HImode);
15499 rtx res = gen_reg_rtx (QImode);
15500
15501 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15502
15503 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15504 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15505 cond = gen_rtx_fmt_ee (EQ, QImode,
15506 gen_rtx_REG (CCmode, FLAGS_REG),
15507 const0_rtx);
15508 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15509 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15510 DONE;
15511 })
15512
15513 (define_expand "isinf<mode>2"
15514 [(use (match_operand:SI 0 "register_operand" ""))
15515 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15516 "TARGET_USE_FANCY_MATH_387
15517 && TARGET_C99_FUNCTIONS
15518 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15519 {
15520 rtx mask = GEN_INT (0x45);
15521 rtx val = GEN_INT (0x05);
15522
15523 rtx cond;
15524
15525 rtx scratch = gen_reg_rtx (HImode);
15526 rtx res = gen_reg_rtx (QImode);
15527
15528 /* Remove excess precision by forcing value through memory. */
15529 if (memory_operand (operands[1], VOIDmode))
15530 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15531 else
15532 {
15533 enum ix86_stack_slot slot = (virtuals_instantiated
15534 ? SLOT_TEMP
15535 : SLOT_VIRTUAL);
15536 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15537
15538 emit_move_insn (temp, operands[1]);
15539 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15540 }
15541
15542 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15543 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15544 cond = gen_rtx_fmt_ee (EQ, QImode,
15545 gen_rtx_REG (CCmode, FLAGS_REG),
15546 const0_rtx);
15547 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15548 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15549 DONE;
15550 })
15551
15552 (define_expand "signbitxf2"
15553 [(use (match_operand:SI 0 "register_operand" ""))
15554 (use (match_operand:XF 1 "register_operand" ""))]
15555 "TARGET_USE_FANCY_MATH_387"
15556 {
15557 rtx scratch = gen_reg_rtx (HImode);
15558
15559 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15560 emit_insn (gen_andsi3 (operands[0],
15561 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15562 DONE;
15563 })
15564
15565 (define_insn "movmsk_df"
15566 [(set (match_operand:SI 0 "register_operand" "=r")
15567 (unspec:SI
15568 [(match_operand:DF 1 "register_operand" "x")]
15569 UNSPEC_MOVMSK))]
15570 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15571 "%vmovmskpd\t{%1, %0|%0, %1}"
15572 [(set_attr "type" "ssemov")
15573 (set_attr "prefix" "maybe_vex")
15574 (set_attr "mode" "DF")])
15575
15576 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15577 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15578 (define_expand "signbitdf2"
15579 [(use (match_operand:SI 0 "register_operand" ""))
15580 (use (match_operand:DF 1 "register_operand" ""))]
15581 "TARGET_USE_FANCY_MATH_387
15582 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15583 {
15584 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15585 {
15586 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15587 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15588 }
15589 else
15590 {
15591 rtx scratch = gen_reg_rtx (HImode);
15592
15593 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15594 emit_insn (gen_andsi3 (operands[0],
15595 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15596 }
15597 DONE;
15598 })
15599
15600 (define_expand "signbitsf2"
15601 [(use (match_operand:SI 0 "register_operand" ""))
15602 (use (match_operand:SF 1 "register_operand" ""))]
15603 "TARGET_USE_FANCY_MATH_387
15604 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15605 {
15606 rtx scratch = gen_reg_rtx (HImode);
15607
15608 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15609 emit_insn (gen_andsi3 (operands[0],
15610 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15611 DONE;
15612 })
15613 \f
15614 ;; Block operation instructions
15615
15616 (define_insn "cld"
15617 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15618 ""
15619 "cld"
15620 [(set_attr "length" "1")
15621 (set_attr "length_immediate" "0")
15622 (set_attr "modrm" "0")])
15623
15624 (define_expand "movmem<mode>"
15625 [(use (match_operand:BLK 0 "memory_operand" ""))
15626 (use (match_operand:BLK 1 "memory_operand" ""))
15627 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15628 (use (match_operand:SWI48 3 "const_int_operand" ""))
15629 (use (match_operand:SI 4 "const_int_operand" ""))
15630 (use (match_operand:SI 5 "const_int_operand" ""))]
15631 ""
15632 {
15633 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15634 operands[4], operands[5]))
15635 DONE;
15636 else
15637 FAIL;
15638 })
15639
15640 ;; Most CPUs don't like single string operations
15641 ;; Handle this case here to simplify previous expander.
15642
15643 (define_expand "strmov"
15644 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15645 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15646 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15647 (clobber (reg:CC FLAGS_REG))])
15648 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15649 (clobber (reg:CC FLAGS_REG))])]
15650 ""
15651 {
15652 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15653
15654 /* If .md ever supports :P for Pmode, these can be directly
15655 in the pattern above. */
15656 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15657 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15658
15659 /* Can't use this if the user has appropriated esi or edi. */
15660 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15661 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15662 {
15663 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15664 operands[2], operands[3],
15665 operands[5], operands[6]));
15666 DONE;
15667 }
15668
15669 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15670 })
15671
15672 (define_expand "strmov_singleop"
15673 [(parallel [(set (match_operand 1 "memory_operand" "")
15674 (match_operand 3 "memory_operand" ""))
15675 (set (match_operand 0 "register_operand" "")
15676 (match_operand 4 "" ""))
15677 (set (match_operand 2 "register_operand" "")
15678 (match_operand 5 "" ""))])]
15679 ""
15680 "ix86_current_function_needs_cld = 1;")
15681
15682 (define_insn "*strmovdi_rex_1"
15683 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15684 (mem:DI (match_operand:P 3 "register_operand" "1")))
15685 (set (match_operand:P 0 "register_operand" "=D")
15686 (plus:P (match_dup 2)
15687 (const_int 8)))
15688 (set (match_operand:P 1 "register_operand" "=S")
15689 (plus:P (match_dup 3)
15690 (const_int 8)))]
15691 "TARGET_64BIT
15692 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15693 "%^movsq"
15694 [(set_attr "type" "str")
15695 (set_attr "memory" "both")
15696 (set_attr "mode" "DI")])
15697
15698 (define_insn "*strmovsi_1"
15699 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15700 (mem:SI (match_operand:P 3 "register_operand" "1")))
15701 (set (match_operand:P 0 "register_operand" "=D")
15702 (plus:P (match_dup 2)
15703 (const_int 4)))
15704 (set (match_operand:P 1 "register_operand" "=S")
15705 (plus:P (match_dup 3)
15706 (const_int 4)))]
15707 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15708 "%^movs{l|d}"
15709 [(set_attr "type" "str")
15710 (set_attr "memory" "both")
15711 (set_attr "mode" "SI")])
15712
15713 (define_insn "*strmovhi_1"
15714 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15715 (mem:HI (match_operand:P 3 "register_operand" "1")))
15716 (set (match_operand:P 0 "register_operand" "=D")
15717 (plus:P (match_dup 2)
15718 (const_int 2)))
15719 (set (match_operand:P 1 "register_operand" "=S")
15720 (plus:P (match_dup 3)
15721 (const_int 2)))]
15722 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15723 "%^movsw"
15724 [(set_attr "type" "str")
15725 (set_attr "memory" "both")
15726 (set_attr "mode" "HI")])
15727
15728 (define_insn "*strmovqi_1"
15729 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15730 (mem:QI (match_operand:P 3 "register_operand" "1")))
15731 (set (match_operand:P 0 "register_operand" "=D")
15732 (plus:P (match_dup 2)
15733 (const_int 1)))
15734 (set (match_operand:P 1 "register_operand" "=S")
15735 (plus:P (match_dup 3)
15736 (const_int 1)))]
15737 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15738 "%^movsb"
15739 [(set_attr "type" "str")
15740 (set_attr "memory" "both")
15741 (set (attr "prefix_rex")
15742 (if_then_else
15743 (match_test "<P:MODE>mode == DImode")
15744 (const_string "0")
15745 (const_string "*")))
15746 (set_attr "mode" "QI")])
15747
15748 (define_expand "rep_mov"
15749 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15750 (set (match_operand 0 "register_operand" "")
15751 (match_operand 5 "" ""))
15752 (set (match_operand 2 "register_operand" "")
15753 (match_operand 6 "" ""))
15754 (set (match_operand 1 "memory_operand" "")
15755 (match_operand 3 "memory_operand" ""))
15756 (use (match_dup 4))])]
15757 ""
15758 "ix86_current_function_needs_cld = 1;")
15759
15760 (define_insn "*rep_movdi_rex64"
15761 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15762 (set (match_operand:P 0 "register_operand" "=D")
15763 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15764 (const_int 3))
15765 (match_operand:P 3 "register_operand" "0")))
15766 (set (match_operand:P 1 "register_operand" "=S")
15767 (plus:P (ashift:P (match_dup 5) (const_int 3))
15768 (match_operand:P 4 "register_operand" "1")))
15769 (set (mem:BLK (match_dup 3))
15770 (mem:BLK (match_dup 4)))
15771 (use (match_dup 5))]
15772 "TARGET_64BIT
15773 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774 "%^rep{%;} movsq"
15775 [(set_attr "type" "str")
15776 (set_attr "prefix_rep" "1")
15777 (set_attr "memory" "both")
15778 (set_attr "mode" "DI")])
15779
15780 (define_insn "*rep_movsi"
15781 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15782 (set (match_operand:P 0 "register_operand" "=D")
15783 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15784 (const_int 2))
15785 (match_operand:P 3 "register_operand" "0")))
15786 (set (match_operand:P 1 "register_operand" "=S")
15787 (plus:P (ashift:P (match_dup 5) (const_int 2))
15788 (match_operand:P 4 "register_operand" "1")))
15789 (set (mem:BLK (match_dup 3))
15790 (mem:BLK (match_dup 4)))
15791 (use (match_dup 5))]
15792 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15793 "%^rep{%;} movs{l|d}"
15794 [(set_attr "type" "str")
15795 (set_attr "prefix_rep" "1")
15796 (set_attr "memory" "both")
15797 (set_attr "mode" "SI")])
15798
15799 (define_insn "*rep_movqi"
15800 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15801 (set (match_operand:P 0 "register_operand" "=D")
15802 (plus:P (match_operand:P 3 "register_operand" "0")
15803 (match_operand:P 5 "register_operand" "2")))
15804 (set (match_operand:P 1 "register_operand" "=S")
15805 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15806 (set (mem:BLK (match_dup 3))
15807 (mem:BLK (match_dup 4)))
15808 (use (match_dup 5))]
15809 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15810 "%^rep{%;} movsb"
15811 [(set_attr "type" "str")
15812 (set_attr "prefix_rep" "1")
15813 (set_attr "memory" "both")
15814 (set_attr "mode" "QI")])
15815
15816 (define_expand "setmem<mode>"
15817 [(use (match_operand:BLK 0 "memory_operand" ""))
15818 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15819 (use (match_operand:QI 2 "nonmemory_operand" ""))
15820 (use (match_operand 3 "const_int_operand" ""))
15821 (use (match_operand:SI 4 "const_int_operand" ""))
15822 (use (match_operand:SI 5 "const_int_operand" ""))]
15823 ""
15824 {
15825 if (ix86_expand_setmem (operands[0], operands[1],
15826 operands[2], operands[3],
15827 operands[4], operands[5]))
15828 DONE;
15829 else
15830 FAIL;
15831 })
15832
15833 ;; Most CPUs don't like single string operations
15834 ;; Handle this case here to simplify previous expander.
15835
15836 (define_expand "strset"
15837 [(set (match_operand 1 "memory_operand" "")
15838 (match_operand 2 "register_operand" ""))
15839 (parallel [(set (match_operand 0 "register_operand" "")
15840 (match_dup 3))
15841 (clobber (reg:CC FLAGS_REG))])]
15842 ""
15843 {
15844 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15845 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15846
15847 /* If .md ever supports :P for Pmode, this can be directly
15848 in the pattern above. */
15849 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15850 GEN_INT (GET_MODE_SIZE (GET_MODE
15851 (operands[2]))));
15852 /* Can't use this if the user has appropriated eax or edi. */
15853 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15854 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15855 {
15856 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15857 operands[3]));
15858 DONE;
15859 }
15860 })
15861
15862 (define_expand "strset_singleop"
15863 [(parallel [(set (match_operand 1 "memory_operand" "")
15864 (match_operand 2 "register_operand" ""))
15865 (set (match_operand 0 "register_operand" "")
15866 (match_operand 3 "" ""))])]
15867 ""
15868 "ix86_current_function_needs_cld = 1;")
15869
15870 (define_insn "*strsetdi_rex_1"
15871 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15872 (match_operand:DI 2 "register_operand" "a"))
15873 (set (match_operand:P 0 "register_operand" "=D")
15874 (plus:P (match_dup 1)
15875 (const_int 8)))]
15876 "TARGET_64BIT
15877 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15878 "%^stosq"
15879 [(set_attr "type" "str")
15880 (set_attr "memory" "store")
15881 (set_attr "mode" "DI")])
15882
15883 (define_insn "*strsetsi_1"
15884 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15885 (match_operand:SI 2 "register_operand" "a"))
15886 (set (match_operand:P 0 "register_operand" "=D")
15887 (plus:P (match_dup 1)
15888 (const_int 4)))]
15889 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15890 "%^stos{l|d}"
15891 [(set_attr "type" "str")
15892 (set_attr "memory" "store")
15893 (set_attr "mode" "SI")])
15894
15895 (define_insn "*strsethi_1"
15896 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15897 (match_operand:HI 2 "register_operand" "a"))
15898 (set (match_operand:P 0 "register_operand" "=D")
15899 (plus:P (match_dup 1)
15900 (const_int 2)))]
15901 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15902 "%^stosw"
15903 [(set_attr "type" "str")
15904 (set_attr "memory" "store")
15905 (set_attr "mode" "HI")])
15906
15907 (define_insn "*strsetqi_1"
15908 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15909 (match_operand:QI 2 "register_operand" "a"))
15910 (set (match_operand:P 0 "register_operand" "=D")
15911 (plus:P (match_dup 1)
15912 (const_int 1)))]
15913 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15914 "%^stosb"
15915 [(set_attr "type" "str")
15916 (set_attr "memory" "store")
15917 (set (attr "prefix_rex")
15918 (if_then_else
15919 (match_test "<P:MODE>mode == DImode")
15920 (const_string "0")
15921 (const_string "*")))
15922 (set_attr "mode" "QI")])
15923
15924 (define_expand "rep_stos"
15925 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15926 (set (match_operand 0 "register_operand" "")
15927 (match_operand 4 "" ""))
15928 (set (match_operand 2 "memory_operand" "") (const_int 0))
15929 (use (match_operand 3 "register_operand" ""))
15930 (use (match_dup 1))])]
15931 ""
15932 "ix86_current_function_needs_cld = 1;")
15933
15934 (define_insn "*rep_stosdi_rex64"
15935 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15936 (set (match_operand:P 0 "register_operand" "=D")
15937 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15938 (const_int 3))
15939 (match_operand:P 3 "register_operand" "0")))
15940 (set (mem:BLK (match_dup 3))
15941 (const_int 0))
15942 (use (match_operand:DI 2 "register_operand" "a"))
15943 (use (match_dup 4))]
15944 "TARGET_64BIT
15945 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15946 "%^rep{%;} stosq"
15947 [(set_attr "type" "str")
15948 (set_attr "prefix_rep" "1")
15949 (set_attr "memory" "store")
15950 (set_attr "mode" "DI")])
15951
15952 (define_insn "*rep_stossi"
15953 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15954 (set (match_operand:P 0 "register_operand" "=D")
15955 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15956 (const_int 2))
15957 (match_operand:P 3 "register_operand" "0")))
15958 (set (mem:BLK (match_dup 3))
15959 (const_int 0))
15960 (use (match_operand:SI 2 "register_operand" "a"))
15961 (use (match_dup 4))]
15962 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15963 "%^rep{%;} stos{l|d}"
15964 [(set_attr "type" "str")
15965 (set_attr "prefix_rep" "1")
15966 (set_attr "memory" "store")
15967 (set_attr "mode" "SI")])
15968
15969 (define_insn "*rep_stosqi"
15970 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15971 (set (match_operand:P 0 "register_operand" "=D")
15972 (plus:P (match_operand:P 3 "register_operand" "0")
15973 (match_operand:P 4 "register_operand" "1")))
15974 (set (mem:BLK (match_dup 3))
15975 (const_int 0))
15976 (use (match_operand:QI 2 "register_operand" "a"))
15977 (use (match_dup 4))]
15978 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15979 "%^rep{%;} stosb"
15980 [(set_attr "type" "str")
15981 (set_attr "prefix_rep" "1")
15982 (set_attr "memory" "store")
15983 (set (attr "prefix_rex")
15984 (if_then_else
15985 (match_test "<P:MODE>mode == DImode")
15986 (const_string "0")
15987 (const_string "*")))
15988 (set_attr "mode" "QI")])
15989
15990 (define_expand "cmpstrnsi"
15991 [(set (match_operand:SI 0 "register_operand" "")
15992 (compare:SI (match_operand:BLK 1 "general_operand" "")
15993 (match_operand:BLK 2 "general_operand" "")))
15994 (use (match_operand 3 "general_operand" ""))
15995 (use (match_operand 4 "immediate_operand" ""))]
15996 ""
15997 {
15998 rtx addr1, addr2, out, outlow, count, countreg, align;
15999
16000 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16001 FAIL;
16002
16003 /* Can't use this if the user has appropriated ecx, esi or edi. */
16004 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16005 FAIL;
16006
16007 out = operands[0];
16008 if (!REG_P (out))
16009 out = gen_reg_rtx (SImode);
16010
16011 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16012 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16013 if (addr1 != XEXP (operands[1], 0))
16014 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16015 if (addr2 != XEXP (operands[2], 0))
16016 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16017
16018 count = operands[3];
16019 countreg = ix86_zero_extend_to_Pmode (count);
16020
16021 /* %%% Iff we are testing strict equality, we can use known alignment
16022 to good advantage. This may be possible with combine, particularly
16023 once cc0 is dead. */
16024 align = operands[4];
16025
16026 if (CONST_INT_P (count))
16027 {
16028 if (INTVAL (count) == 0)
16029 {
16030 emit_move_insn (operands[0], const0_rtx);
16031 DONE;
16032 }
16033 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16034 operands[1], operands[2]));
16035 }
16036 else
16037 {
16038 rtx (*gen_cmp) (rtx, rtx);
16039
16040 gen_cmp = (TARGET_64BIT
16041 ? gen_cmpdi_1 : gen_cmpsi_1);
16042
16043 emit_insn (gen_cmp (countreg, countreg));
16044 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16045 operands[1], operands[2]));
16046 }
16047
16048 outlow = gen_lowpart (QImode, out);
16049 emit_insn (gen_cmpintqi (outlow));
16050 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16051
16052 if (operands[0] != out)
16053 emit_move_insn (operands[0], out);
16054
16055 DONE;
16056 })
16057
16058 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16059
16060 (define_expand "cmpintqi"
16061 [(set (match_dup 1)
16062 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16063 (set (match_dup 2)
16064 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16065 (parallel [(set (match_operand:QI 0 "register_operand" "")
16066 (minus:QI (match_dup 1)
16067 (match_dup 2)))
16068 (clobber (reg:CC FLAGS_REG))])]
16069 ""
16070 {
16071 operands[1] = gen_reg_rtx (QImode);
16072 operands[2] = gen_reg_rtx (QImode);
16073 })
16074
16075 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16076 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16077
16078 (define_expand "cmpstrnqi_nz_1"
16079 [(parallel [(set (reg:CC FLAGS_REG)
16080 (compare:CC (match_operand 4 "memory_operand" "")
16081 (match_operand 5 "memory_operand" "")))
16082 (use (match_operand 2 "register_operand" ""))
16083 (use (match_operand:SI 3 "immediate_operand" ""))
16084 (clobber (match_operand 0 "register_operand" ""))
16085 (clobber (match_operand 1 "register_operand" ""))
16086 (clobber (match_dup 2))])]
16087 ""
16088 "ix86_current_function_needs_cld = 1;")
16089
16090 (define_insn "*cmpstrnqi_nz_1"
16091 [(set (reg:CC FLAGS_REG)
16092 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16093 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16094 (use (match_operand:P 6 "register_operand" "2"))
16095 (use (match_operand:SI 3 "immediate_operand" "i"))
16096 (clobber (match_operand:P 0 "register_operand" "=S"))
16097 (clobber (match_operand:P 1 "register_operand" "=D"))
16098 (clobber (match_operand:P 2 "register_operand" "=c"))]
16099 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16100 "%^repz{%;} cmpsb"
16101 [(set_attr "type" "str")
16102 (set_attr "mode" "QI")
16103 (set (attr "prefix_rex")
16104 (if_then_else
16105 (match_test "<P:MODE>mode == DImode")
16106 (const_string "0")
16107 (const_string "*")))
16108 (set_attr "prefix_rep" "1")])
16109
16110 ;; The same, but the count is not known to not be zero.
16111
16112 (define_expand "cmpstrnqi_1"
16113 [(parallel [(set (reg:CC FLAGS_REG)
16114 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16115 (const_int 0))
16116 (compare:CC (match_operand 4 "memory_operand" "")
16117 (match_operand 5 "memory_operand" ""))
16118 (const_int 0)))
16119 (use (match_operand:SI 3 "immediate_operand" ""))
16120 (use (reg:CC FLAGS_REG))
16121 (clobber (match_operand 0 "register_operand" ""))
16122 (clobber (match_operand 1 "register_operand" ""))
16123 (clobber (match_dup 2))])]
16124 ""
16125 "ix86_current_function_needs_cld = 1;")
16126
16127 (define_insn "*cmpstrnqi_1"
16128 [(set (reg:CC FLAGS_REG)
16129 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16130 (const_int 0))
16131 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16132 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16133 (const_int 0)))
16134 (use (match_operand:SI 3 "immediate_operand" "i"))
16135 (use (reg:CC FLAGS_REG))
16136 (clobber (match_operand:P 0 "register_operand" "=S"))
16137 (clobber (match_operand:P 1 "register_operand" "=D"))
16138 (clobber (match_operand:P 2 "register_operand" "=c"))]
16139 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16140 "%^repz{%;} cmpsb"
16141 [(set_attr "type" "str")
16142 (set_attr "mode" "QI")
16143 (set (attr "prefix_rex")
16144 (if_then_else
16145 (match_test "<P:MODE>mode == DImode")
16146 (const_string "0")
16147 (const_string "*")))
16148 (set_attr "prefix_rep" "1")])
16149
16150 (define_expand "strlen<mode>"
16151 [(set (match_operand:P 0 "register_operand" "")
16152 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16153 (match_operand:QI 2 "immediate_operand" "")
16154 (match_operand 3 "immediate_operand" "")]
16155 UNSPEC_SCAS))]
16156 ""
16157 {
16158 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16159 DONE;
16160 else
16161 FAIL;
16162 })
16163
16164 (define_expand "strlenqi_1"
16165 [(parallel [(set (match_operand 0 "register_operand" "")
16166 (match_operand 2 "" ""))
16167 (clobber (match_operand 1 "register_operand" ""))
16168 (clobber (reg:CC FLAGS_REG))])]
16169 ""
16170 "ix86_current_function_needs_cld = 1;")
16171
16172 (define_insn "*strlenqi_1"
16173 [(set (match_operand:P 0 "register_operand" "=&c")
16174 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16175 (match_operand:QI 2 "register_operand" "a")
16176 (match_operand:P 3 "immediate_operand" "i")
16177 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16178 (clobber (match_operand:P 1 "register_operand" "=D"))
16179 (clobber (reg:CC FLAGS_REG))]
16180 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16181 "%^repnz{%;} scasb"
16182 [(set_attr "type" "str")
16183 (set_attr "mode" "QI")
16184 (set (attr "prefix_rex")
16185 (if_then_else
16186 (match_test "<P:MODE>mode == DImode")
16187 (const_string "0")
16188 (const_string "*")))
16189 (set_attr "prefix_rep" "1")])
16190
16191 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16192 ;; handled in combine, but it is not currently up to the task.
16193 ;; When used for their truth value, the cmpstrn* expanders generate
16194 ;; code like this:
16195 ;;
16196 ;; repz cmpsb
16197 ;; seta %al
16198 ;; setb %dl
16199 ;; cmpb %al, %dl
16200 ;; jcc label
16201 ;;
16202 ;; The intermediate three instructions are unnecessary.
16203
16204 ;; This one handles cmpstrn*_nz_1...
16205 (define_peephole2
16206 [(parallel[
16207 (set (reg:CC FLAGS_REG)
16208 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16209 (mem:BLK (match_operand 5 "register_operand" ""))))
16210 (use (match_operand 6 "register_operand" ""))
16211 (use (match_operand:SI 3 "immediate_operand" ""))
16212 (clobber (match_operand 0 "register_operand" ""))
16213 (clobber (match_operand 1 "register_operand" ""))
16214 (clobber (match_operand 2 "register_operand" ""))])
16215 (set (match_operand:QI 7 "register_operand" "")
16216 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16217 (set (match_operand:QI 8 "register_operand" "")
16218 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16219 (set (reg FLAGS_REG)
16220 (compare (match_dup 7) (match_dup 8)))
16221 ]
16222 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16223 [(parallel[
16224 (set (reg:CC FLAGS_REG)
16225 (compare:CC (mem:BLK (match_dup 4))
16226 (mem:BLK (match_dup 5))))
16227 (use (match_dup 6))
16228 (use (match_dup 3))
16229 (clobber (match_dup 0))
16230 (clobber (match_dup 1))
16231 (clobber (match_dup 2))])])
16232
16233 ;; ...and this one handles cmpstrn*_1.
16234 (define_peephole2
16235 [(parallel[
16236 (set (reg:CC FLAGS_REG)
16237 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16238 (const_int 0))
16239 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16240 (mem:BLK (match_operand 5 "register_operand" "")))
16241 (const_int 0)))
16242 (use (match_operand:SI 3 "immediate_operand" ""))
16243 (use (reg:CC FLAGS_REG))
16244 (clobber (match_operand 0 "register_operand" ""))
16245 (clobber (match_operand 1 "register_operand" ""))
16246 (clobber (match_operand 2 "register_operand" ""))])
16247 (set (match_operand:QI 7 "register_operand" "")
16248 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16249 (set (match_operand:QI 8 "register_operand" "")
16250 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16251 (set (reg FLAGS_REG)
16252 (compare (match_dup 7) (match_dup 8)))
16253 ]
16254 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16255 [(parallel[
16256 (set (reg:CC FLAGS_REG)
16257 (if_then_else:CC (ne (match_dup 6)
16258 (const_int 0))
16259 (compare:CC (mem:BLK (match_dup 4))
16260 (mem:BLK (match_dup 5)))
16261 (const_int 0)))
16262 (use (match_dup 3))
16263 (use (reg:CC FLAGS_REG))
16264 (clobber (match_dup 0))
16265 (clobber (match_dup 1))
16266 (clobber (match_dup 2))])])
16267 \f
16268 ;; Conditional move instructions.
16269
16270 (define_expand "mov<mode>cc"
16271 [(set (match_operand:SWIM 0 "register_operand" "")
16272 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16273 (match_operand:SWIM 2 "<general_operand>" "")
16274 (match_operand:SWIM 3 "<general_operand>" "")))]
16275 ""
16276 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16277
16278 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16279 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16280 ;; So just document what we're doing explicitly.
16281
16282 (define_expand "x86_mov<mode>cc_0_m1"
16283 [(parallel
16284 [(set (match_operand:SWI48 0 "register_operand" "")
16285 (if_then_else:SWI48
16286 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16287 [(match_operand 1 "flags_reg_operand" "")
16288 (const_int 0)])
16289 (const_int -1)
16290 (const_int 0)))
16291 (clobber (reg:CC FLAGS_REG))])])
16292
16293 (define_insn "*x86_mov<mode>cc_0_m1"
16294 [(set (match_operand:SWI48 0 "register_operand" "=r")
16295 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16296 [(reg FLAGS_REG) (const_int 0)])
16297 (const_int -1)
16298 (const_int 0)))
16299 (clobber (reg:CC FLAGS_REG))]
16300 ""
16301 "sbb{<imodesuffix>}\t%0, %0"
16302 ; Since we don't have the proper number of operands for an alu insn,
16303 ; fill in all the blanks.
16304 [(set_attr "type" "alu")
16305 (set_attr "use_carry" "1")
16306 (set_attr "pent_pair" "pu")
16307 (set_attr "memory" "none")
16308 (set_attr "imm_disp" "false")
16309 (set_attr "mode" "<MODE>")
16310 (set_attr "length_immediate" "0")])
16311
16312 (define_insn "*x86_mov<mode>cc_0_m1_se"
16313 [(set (match_operand:SWI48 0 "register_operand" "=r")
16314 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16315 [(reg FLAGS_REG) (const_int 0)])
16316 (const_int 1)
16317 (const_int 0)))
16318 (clobber (reg:CC FLAGS_REG))]
16319 ""
16320 "sbb{<imodesuffix>}\t%0, %0"
16321 [(set_attr "type" "alu")
16322 (set_attr "use_carry" "1")
16323 (set_attr "pent_pair" "pu")
16324 (set_attr "memory" "none")
16325 (set_attr "imm_disp" "false")
16326 (set_attr "mode" "<MODE>")
16327 (set_attr "length_immediate" "0")])
16328
16329 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16330 [(set (match_operand:SWI48 0 "register_operand" "=r")
16331 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16332 [(reg FLAGS_REG) (const_int 0)])))]
16333 ""
16334 "sbb{<imodesuffix>}\t%0, %0"
16335 [(set_attr "type" "alu")
16336 (set_attr "use_carry" "1")
16337 (set_attr "pent_pair" "pu")
16338 (set_attr "memory" "none")
16339 (set_attr "imm_disp" "false")
16340 (set_attr "mode" "<MODE>")
16341 (set_attr "length_immediate" "0")])
16342
16343 (define_insn "*mov<mode>cc_noc"
16344 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16345 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16346 [(reg FLAGS_REG) (const_int 0)])
16347 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16348 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16349 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16350 "@
16351 cmov%O2%C1\t{%2, %0|%0, %2}
16352 cmov%O2%c1\t{%3, %0|%0, %3}"
16353 [(set_attr "type" "icmov")
16354 (set_attr "mode" "<MODE>")])
16355
16356 (define_insn_and_split "*movqicc_noc"
16357 [(set (match_operand:QI 0 "register_operand" "=r,r")
16358 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16359 [(match_operand 4 "flags_reg_operand" "")
16360 (const_int 0)])
16361 (match_operand:QI 2 "register_operand" "r,0")
16362 (match_operand:QI 3 "register_operand" "0,r")))]
16363 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16364 "#"
16365 "&& reload_completed"
16366 [(set (match_dup 0)
16367 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16368 (match_dup 2)
16369 (match_dup 3)))]
16370 "operands[0] = gen_lowpart (SImode, operands[0]);
16371 operands[2] = gen_lowpart (SImode, operands[2]);
16372 operands[3] = gen_lowpart (SImode, operands[3]);"
16373 [(set_attr "type" "icmov")
16374 (set_attr "mode" "SI")])
16375
16376 (define_expand "mov<mode>cc"
16377 [(set (match_operand:X87MODEF 0 "register_operand" "")
16378 (if_then_else:X87MODEF
16379 (match_operand 1 "ix86_fp_comparison_operator" "")
16380 (match_operand:X87MODEF 2 "register_operand" "")
16381 (match_operand:X87MODEF 3 "register_operand" "")))]
16382 "(TARGET_80387 && TARGET_CMOVE)
16383 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16384 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16385
16386 (define_insn "*movxfcc_1"
16387 [(set (match_operand:XF 0 "register_operand" "=f,f")
16388 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16389 [(reg FLAGS_REG) (const_int 0)])
16390 (match_operand:XF 2 "register_operand" "f,0")
16391 (match_operand:XF 3 "register_operand" "0,f")))]
16392 "TARGET_80387 && TARGET_CMOVE"
16393 "@
16394 fcmov%F1\t{%2, %0|%0, %2}
16395 fcmov%f1\t{%3, %0|%0, %3}"
16396 [(set_attr "type" "fcmov")
16397 (set_attr "mode" "XF")])
16398
16399 (define_insn "*movdfcc_1_rex64"
16400 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16401 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16402 [(reg FLAGS_REG) (const_int 0)])
16403 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16404 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16405 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16406 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16407 "@
16408 fcmov%F1\t{%2, %0|%0, %2}
16409 fcmov%f1\t{%3, %0|%0, %3}
16410 cmov%O2%C1\t{%2, %0|%0, %2}
16411 cmov%O2%c1\t{%3, %0|%0, %3}"
16412 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16413 (set_attr "mode" "DF,DF,DI,DI")])
16414
16415 (define_insn "*movdfcc_1"
16416 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16417 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16418 [(reg FLAGS_REG) (const_int 0)])
16419 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16420 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16421 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16422 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16423 "@
16424 fcmov%F1\t{%2, %0|%0, %2}
16425 fcmov%f1\t{%3, %0|%0, %3}
16426 #
16427 #"
16428 [(set_attr "type" "fcmov,fcmov,multi,multi")
16429 (set_attr "mode" "DF,DF,DI,DI")])
16430
16431 (define_split
16432 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16433 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16434 [(match_operand 4 "flags_reg_operand" "")
16435 (const_int 0)])
16436 (match_operand:DF 2 "nonimmediate_operand" "")
16437 (match_operand:DF 3 "nonimmediate_operand" "")))]
16438 "!TARGET_64BIT && reload_completed"
16439 [(set (match_dup 2)
16440 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16441 (match_dup 5)
16442 (match_dup 6)))
16443 (set (match_dup 3)
16444 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16445 (match_dup 7)
16446 (match_dup 8)))]
16447 {
16448 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16449 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16450 })
16451
16452 (define_insn "*movsfcc_1_387"
16453 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16454 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16455 [(reg FLAGS_REG) (const_int 0)])
16456 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16457 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16458 "TARGET_80387 && TARGET_CMOVE
16459 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16460 "@
16461 fcmov%F1\t{%2, %0|%0, %2}
16462 fcmov%f1\t{%3, %0|%0, %3}
16463 cmov%O2%C1\t{%2, %0|%0, %2}
16464 cmov%O2%c1\t{%3, %0|%0, %3}"
16465 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16466 (set_attr "mode" "SF,SF,SI,SI")])
16467
16468 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16469 ;; the scalar versions to have only XMM registers as operands.
16470
16471 ;; XOP conditional move
16472 (define_insn "*xop_pcmov_<mode>"
16473 [(set (match_operand:MODEF 0 "register_operand" "=x")
16474 (if_then_else:MODEF
16475 (match_operand:MODEF 1 "register_operand" "x")
16476 (match_operand:MODEF 2 "register_operand" "x")
16477 (match_operand:MODEF 3 "register_operand" "x")))]
16478 "TARGET_XOP"
16479 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16480 [(set_attr "type" "sse4arg")])
16481
16482 ;; These versions of the min/max patterns are intentionally ignorant of
16483 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16484 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16485 ;; are undefined in this condition, we're certain this is correct.
16486
16487 (define_insn "<code><mode>3"
16488 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16489 (smaxmin:MODEF
16490 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16491 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16492 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16493 "@
16494 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16495 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16496 [(set_attr "isa" "noavx,avx")
16497 (set_attr "prefix" "orig,vex")
16498 (set_attr "type" "sseadd")
16499 (set_attr "mode" "<MODE>")])
16500
16501 ;; These versions of the min/max patterns implement exactly the operations
16502 ;; min = (op1 < op2 ? op1 : op2)
16503 ;; max = (!(op1 < op2) ? op1 : op2)
16504 ;; Their operands are not commutative, and thus they may be used in the
16505 ;; presence of -0.0 and NaN.
16506
16507 (define_insn "*ieee_smin<mode>3"
16508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16509 (unspec:MODEF
16510 [(match_operand:MODEF 1 "register_operand" "0,x")
16511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16512 UNSPEC_IEEE_MIN))]
16513 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16514 "@
16515 min<ssemodesuffix>\t{%2, %0|%0, %2}
16516 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16517 [(set_attr "isa" "noavx,avx")
16518 (set_attr "prefix" "orig,vex")
16519 (set_attr "type" "sseadd")
16520 (set_attr "mode" "<MODE>")])
16521
16522 (define_insn "*ieee_smax<mode>3"
16523 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16524 (unspec:MODEF
16525 [(match_operand:MODEF 1 "register_operand" "0,x")
16526 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16527 UNSPEC_IEEE_MAX))]
16528 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16529 "@
16530 max<ssemodesuffix>\t{%2, %0|%0, %2}
16531 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16532 [(set_attr "isa" "noavx,avx")
16533 (set_attr "prefix" "orig,vex")
16534 (set_attr "type" "sseadd")
16535 (set_attr "mode" "<MODE>")])
16536
16537 ;; Make two stack loads independent:
16538 ;; fld aa fld aa
16539 ;; fld %st(0) -> fld bb
16540 ;; fmul bb fmul %st(1), %st
16541 ;;
16542 ;; Actually we only match the last two instructions for simplicity.
16543 (define_peephole2
16544 [(set (match_operand 0 "fp_register_operand" "")
16545 (match_operand 1 "fp_register_operand" ""))
16546 (set (match_dup 0)
16547 (match_operator 2 "binary_fp_operator"
16548 [(match_dup 0)
16549 (match_operand 3 "memory_operand" "")]))]
16550 "REGNO (operands[0]) != REGNO (operands[1])"
16551 [(set (match_dup 0) (match_dup 3))
16552 (set (match_dup 0) (match_dup 4))]
16553
16554 ;; The % modifier is not operational anymore in peephole2's, so we have to
16555 ;; swap the operands manually in the case of addition and multiplication.
16556 {
16557 rtx op0, op1;
16558
16559 if (COMMUTATIVE_ARITH_P (operands[2]))
16560 op0 = operands[0], op1 = operands[1];
16561 else
16562 op0 = operands[1], op1 = operands[0];
16563
16564 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16565 GET_MODE (operands[2]),
16566 op0, op1);
16567 })
16568
16569 ;; Conditional addition patterns
16570 (define_expand "add<mode>cc"
16571 [(match_operand:SWI 0 "register_operand" "")
16572 (match_operand 1 "ordered_comparison_operator" "")
16573 (match_operand:SWI 2 "register_operand" "")
16574 (match_operand:SWI 3 "const_int_operand" "")]
16575 ""
16576 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16577 \f
16578 ;; Misc patterns (?)
16579
16580 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16581 ;; Otherwise there will be nothing to keep
16582 ;;
16583 ;; [(set (reg ebp) (reg esp))]
16584 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16585 ;; (clobber (eflags)]
16586 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16587 ;;
16588 ;; in proper program order.
16589
16590 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16591 [(set (match_operand:P 0 "register_operand" "=r,r")
16592 (plus:P (match_operand:P 1 "register_operand" "0,r")
16593 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16594 (clobber (reg:CC FLAGS_REG))
16595 (clobber (mem:BLK (scratch)))]
16596 ""
16597 {
16598 switch (get_attr_type (insn))
16599 {
16600 case TYPE_IMOV:
16601 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16602
16603 case TYPE_ALU:
16604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16605 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16606 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16607
16608 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16609
16610 default:
16611 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16612 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16613 }
16614 }
16615 [(set (attr "type")
16616 (cond [(and (eq_attr "alternative" "0")
16617 (not (match_test "TARGET_OPT_AGU")))
16618 (const_string "alu")
16619 (match_operand:<MODE> 2 "const0_operand" "")
16620 (const_string "imov")
16621 ]
16622 (const_string "lea")))
16623 (set (attr "length_immediate")
16624 (cond [(eq_attr "type" "imov")
16625 (const_string "0")
16626 (and (eq_attr "type" "alu")
16627 (match_operand 2 "const128_operand" ""))
16628 (const_string "1")
16629 ]
16630 (const_string "*")))
16631 (set_attr "mode" "<MODE>")])
16632
16633 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16634 [(set (match_operand:P 0 "register_operand" "=r")
16635 (minus:P (match_operand:P 1 "register_operand" "0")
16636 (match_operand:P 2 "register_operand" "r")))
16637 (clobber (reg:CC FLAGS_REG))
16638 (clobber (mem:BLK (scratch)))]
16639 ""
16640 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16641 [(set_attr "type" "alu")
16642 (set_attr "mode" "<MODE>")])
16643
16644 (define_insn "allocate_stack_worker_probe_<mode>"
16645 [(set (match_operand:P 0 "register_operand" "=a")
16646 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16647 UNSPECV_STACK_PROBE))
16648 (clobber (reg:CC FLAGS_REG))]
16649 "ix86_target_stack_probe ()"
16650 "call\t___chkstk_ms"
16651 [(set_attr "type" "multi")
16652 (set_attr "length" "5")])
16653
16654 (define_expand "allocate_stack"
16655 [(match_operand 0 "register_operand" "")
16656 (match_operand 1 "general_operand" "")]
16657 "ix86_target_stack_probe ()"
16658 {
16659 rtx x;
16660
16661 #ifndef CHECK_STACK_LIMIT
16662 #define CHECK_STACK_LIMIT 0
16663 #endif
16664
16665 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16666 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16667 {
16668 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16669 stack_pointer_rtx, 0, OPTAB_DIRECT);
16670 if (x != stack_pointer_rtx)
16671 emit_move_insn (stack_pointer_rtx, x);
16672 }
16673 else
16674 {
16675 x = copy_to_mode_reg (Pmode, operands[1]);
16676 if (TARGET_64BIT)
16677 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16678 else
16679 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16680 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16681 stack_pointer_rtx, 0, OPTAB_DIRECT);
16682 if (x != stack_pointer_rtx)
16683 emit_move_insn (stack_pointer_rtx, x);
16684 }
16685
16686 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16687 DONE;
16688 })
16689
16690 ;; Use IOR for stack probes, this is shorter.
16691 (define_expand "probe_stack"
16692 [(match_operand 0 "memory_operand" "")]
16693 ""
16694 {
16695 rtx (*gen_ior3) (rtx, rtx, rtx);
16696
16697 gen_ior3 = (GET_MODE (operands[0]) == DImode
16698 ? gen_iordi3 : gen_iorsi3);
16699
16700 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16701 DONE;
16702 })
16703
16704 (define_insn "adjust_stack_and_probe<mode>"
16705 [(set (match_operand:P 0 "register_operand" "=r")
16706 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16707 UNSPECV_PROBE_STACK_RANGE))
16708 (set (reg:P SP_REG)
16709 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16710 (clobber (reg:CC FLAGS_REG))
16711 (clobber (mem:BLK (scratch)))]
16712 ""
16713 "* return output_adjust_stack_and_probe (operands[0]);"
16714 [(set_attr "type" "multi")])
16715
16716 (define_insn "probe_stack_range<mode>"
16717 [(set (match_operand:P 0 "register_operand" "=r")
16718 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16719 (match_operand:P 2 "const_int_operand" "n")]
16720 UNSPECV_PROBE_STACK_RANGE))
16721 (clobber (reg:CC FLAGS_REG))]
16722 ""
16723 "* return output_probe_stack_range (operands[0], operands[2]);"
16724 [(set_attr "type" "multi")])
16725
16726 (define_expand "builtin_setjmp_receiver"
16727 [(label_ref (match_operand 0 "" ""))]
16728 "!TARGET_64BIT && flag_pic"
16729 {
16730 #if TARGET_MACHO
16731 if (TARGET_MACHO)
16732 {
16733 rtx xops[3];
16734 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16735 rtx label_rtx = gen_label_rtx ();
16736 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16737 xops[0] = xops[1] = picreg;
16738 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16739 ix86_expand_binary_operator (MINUS, SImode, xops);
16740 }
16741 else
16742 #endif
16743 emit_insn (gen_set_got (pic_offset_table_rtx));
16744 DONE;
16745 })
16746 \f
16747 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16748
16749 (define_split
16750 [(set (match_operand 0 "register_operand" "")
16751 (match_operator 3 "promotable_binary_operator"
16752 [(match_operand 1 "register_operand" "")
16753 (match_operand 2 "aligned_operand" "")]))
16754 (clobber (reg:CC FLAGS_REG))]
16755 "! TARGET_PARTIAL_REG_STALL && reload_completed
16756 && ((GET_MODE (operands[0]) == HImode
16757 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16758 /* ??? next two lines just !satisfies_constraint_K (...) */
16759 || !CONST_INT_P (operands[2])
16760 || satisfies_constraint_K (operands[2])))
16761 || (GET_MODE (operands[0]) == QImode
16762 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16763 [(parallel [(set (match_dup 0)
16764 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16765 (clobber (reg:CC FLAGS_REG))])]
16766 {
16767 operands[0] = gen_lowpart (SImode, operands[0]);
16768 operands[1] = gen_lowpart (SImode, operands[1]);
16769 if (GET_CODE (operands[3]) != ASHIFT)
16770 operands[2] = gen_lowpart (SImode, operands[2]);
16771 PUT_MODE (operands[3], SImode);
16772 })
16773
16774 ; Promote the QImode tests, as i386 has encoding of the AND
16775 ; instruction with 32-bit sign-extended immediate and thus the
16776 ; instruction size is unchanged, except in the %eax case for
16777 ; which it is increased by one byte, hence the ! optimize_size.
16778 (define_split
16779 [(set (match_operand 0 "flags_reg_operand" "")
16780 (match_operator 2 "compare_operator"
16781 [(and (match_operand 3 "aligned_operand" "")
16782 (match_operand 4 "const_int_operand" ""))
16783 (const_int 0)]))
16784 (set (match_operand 1 "register_operand" "")
16785 (and (match_dup 3) (match_dup 4)))]
16786 "! TARGET_PARTIAL_REG_STALL && reload_completed
16787 && optimize_insn_for_speed_p ()
16788 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16789 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16790 /* Ensure that the operand will remain sign-extended immediate. */
16791 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16792 [(parallel [(set (match_dup 0)
16793 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16794 (const_int 0)]))
16795 (set (match_dup 1)
16796 (and:SI (match_dup 3) (match_dup 4)))])]
16797 {
16798 operands[4]
16799 = gen_int_mode (INTVAL (operands[4])
16800 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16801 operands[1] = gen_lowpart (SImode, operands[1]);
16802 operands[3] = gen_lowpart (SImode, operands[3]);
16803 })
16804
16805 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16806 ; the TEST instruction with 32-bit sign-extended immediate and thus
16807 ; the instruction size would at least double, which is not what we
16808 ; want even with ! optimize_size.
16809 (define_split
16810 [(set (match_operand 0 "flags_reg_operand" "")
16811 (match_operator 1 "compare_operator"
16812 [(and (match_operand:HI 2 "aligned_operand" "")
16813 (match_operand:HI 3 "const_int_operand" ""))
16814 (const_int 0)]))]
16815 "! TARGET_PARTIAL_REG_STALL && reload_completed
16816 && ! TARGET_FAST_PREFIX
16817 && optimize_insn_for_speed_p ()
16818 /* Ensure that the operand will remain sign-extended immediate. */
16819 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16820 [(set (match_dup 0)
16821 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16822 (const_int 0)]))]
16823 {
16824 operands[3]
16825 = gen_int_mode (INTVAL (operands[3])
16826 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16827 operands[2] = gen_lowpart (SImode, operands[2]);
16828 })
16829
16830 (define_split
16831 [(set (match_operand 0 "register_operand" "")
16832 (neg (match_operand 1 "register_operand" "")))
16833 (clobber (reg:CC FLAGS_REG))]
16834 "! TARGET_PARTIAL_REG_STALL && reload_completed
16835 && (GET_MODE (operands[0]) == HImode
16836 || (GET_MODE (operands[0]) == QImode
16837 && (TARGET_PROMOTE_QImode
16838 || optimize_insn_for_size_p ())))"
16839 [(parallel [(set (match_dup 0)
16840 (neg:SI (match_dup 1)))
16841 (clobber (reg:CC FLAGS_REG))])]
16842 {
16843 operands[0] = gen_lowpart (SImode, operands[0]);
16844 operands[1] = gen_lowpart (SImode, operands[1]);
16845 })
16846
16847 (define_split
16848 [(set (match_operand 0 "register_operand" "")
16849 (not (match_operand 1 "register_operand" "")))]
16850 "! TARGET_PARTIAL_REG_STALL && reload_completed
16851 && (GET_MODE (operands[0]) == HImode
16852 || (GET_MODE (operands[0]) == QImode
16853 && (TARGET_PROMOTE_QImode
16854 || optimize_insn_for_size_p ())))"
16855 [(set (match_dup 0)
16856 (not:SI (match_dup 1)))]
16857 {
16858 operands[0] = gen_lowpart (SImode, operands[0]);
16859 operands[1] = gen_lowpart (SImode, operands[1]);
16860 })
16861
16862 (define_split
16863 [(set (match_operand 0 "register_operand" "")
16864 (if_then_else (match_operator 1 "ordered_comparison_operator"
16865 [(reg FLAGS_REG) (const_int 0)])
16866 (match_operand 2 "register_operand" "")
16867 (match_operand 3 "register_operand" "")))]
16868 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16869 && (GET_MODE (operands[0]) == HImode
16870 || (GET_MODE (operands[0]) == QImode
16871 && (TARGET_PROMOTE_QImode
16872 || optimize_insn_for_size_p ())))"
16873 [(set (match_dup 0)
16874 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16875 {
16876 operands[0] = gen_lowpart (SImode, operands[0]);
16877 operands[2] = gen_lowpart (SImode, operands[2]);
16878 operands[3] = gen_lowpart (SImode, operands[3]);
16879 })
16880 \f
16881 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16882 ;; transform a complex memory operation into two memory to register operations.
16883
16884 ;; Don't push memory operands
16885 (define_peephole2
16886 [(set (match_operand:SWI 0 "push_operand" "")
16887 (match_operand:SWI 1 "memory_operand" ""))
16888 (match_scratch:SWI 2 "<r>")]
16889 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16890 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16891 [(set (match_dup 2) (match_dup 1))
16892 (set (match_dup 0) (match_dup 2))])
16893
16894 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16895 ;; SImode pushes.
16896 (define_peephole2
16897 [(set (match_operand:SF 0 "push_operand" "")
16898 (match_operand:SF 1 "memory_operand" ""))
16899 (match_scratch:SF 2 "r")]
16900 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16901 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16902 [(set (match_dup 2) (match_dup 1))
16903 (set (match_dup 0) (match_dup 2))])
16904
16905 ;; Don't move an immediate directly to memory when the instruction
16906 ;; gets too big.
16907 (define_peephole2
16908 [(match_scratch:SWI124 1 "<r>")
16909 (set (match_operand:SWI124 0 "memory_operand" "")
16910 (const_int 0))]
16911 "optimize_insn_for_speed_p ()
16912 && !TARGET_USE_MOV0
16913 && TARGET_SPLIT_LONG_MOVES
16914 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16915 && peep2_regno_dead_p (0, FLAGS_REG)"
16916 [(parallel [(set (match_dup 2) (const_int 0))
16917 (clobber (reg:CC FLAGS_REG))])
16918 (set (match_dup 0) (match_dup 1))]
16919 "operands[2] = gen_lowpart (SImode, operands[1]);")
16920
16921 (define_peephole2
16922 [(match_scratch:SWI124 2 "<r>")
16923 (set (match_operand:SWI124 0 "memory_operand" "")
16924 (match_operand:SWI124 1 "immediate_operand" ""))]
16925 "optimize_insn_for_speed_p ()
16926 && TARGET_SPLIT_LONG_MOVES
16927 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16928 [(set (match_dup 2) (match_dup 1))
16929 (set (match_dup 0) (match_dup 2))])
16930
16931 ;; Don't compare memory with zero, load and use a test instead.
16932 (define_peephole2
16933 [(set (match_operand 0 "flags_reg_operand" "")
16934 (match_operator 1 "compare_operator"
16935 [(match_operand:SI 2 "memory_operand" "")
16936 (const_int 0)]))
16937 (match_scratch:SI 3 "r")]
16938 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16939 [(set (match_dup 3) (match_dup 2))
16940 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16941
16942 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16943 ;; Don't split NOTs with a displacement operand, because resulting XOR
16944 ;; will not be pairable anyway.
16945 ;;
16946 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16947 ;; represented using a modRM byte. The XOR replacement is long decoded,
16948 ;; so this split helps here as well.
16949 ;;
16950 ;; Note: Can't do this as a regular split because we can't get proper
16951 ;; lifetime information then.
16952
16953 (define_peephole2
16954 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16955 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16956 "optimize_insn_for_speed_p ()
16957 && ((TARGET_NOT_UNPAIRABLE
16958 && (!MEM_P (operands[0])
16959 || !memory_displacement_operand (operands[0], <MODE>mode)))
16960 || (TARGET_NOT_VECTORMODE
16961 && long_memory_operand (operands[0], <MODE>mode)))
16962 && peep2_regno_dead_p (0, FLAGS_REG)"
16963 [(parallel [(set (match_dup 0)
16964 (xor:SWI124 (match_dup 1) (const_int -1)))
16965 (clobber (reg:CC FLAGS_REG))])])
16966
16967 ;; Non pairable "test imm, reg" instructions can be translated to
16968 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16969 ;; byte opcode instead of two, have a short form for byte operands),
16970 ;; so do it for other CPUs as well. Given that the value was dead,
16971 ;; this should not create any new dependencies. Pass on the sub-word
16972 ;; versions if we're concerned about partial register stalls.
16973
16974 (define_peephole2
16975 [(set (match_operand 0 "flags_reg_operand" "")
16976 (match_operator 1 "compare_operator"
16977 [(and:SI (match_operand:SI 2 "register_operand" "")
16978 (match_operand:SI 3 "immediate_operand" ""))
16979 (const_int 0)]))]
16980 "ix86_match_ccmode (insn, CCNOmode)
16981 && (true_regnum (operands[2]) != AX_REG
16982 || satisfies_constraint_K (operands[3]))
16983 && peep2_reg_dead_p (1, operands[2])"
16984 [(parallel
16985 [(set (match_dup 0)
16986 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16987 (const_int 0)]))
16988 (set (match_dup 2)
16989 (and:SI (match_dup 2) (match_dup 3)))])])
16990
16991 ;; We don't need to handle HImode case, because it will be promoted to SImode
16992 ;; on ! TARGET_PARTIAL_REG_STALL
16993
16994 (define_peephole2
16995 [(set (match_operand 0 "flags_reg_operand" "")
16996 (match_operator 1 "compare_operator"
16997 [(and:QI (match_operand:QI 2 "register_operand" "")
16998 (match_operand:QI 3 "immediate_operand" ""))
16999 (const_int 0)]))]
17000 "! TARGET_PARTIAL_REG_STALL
17001 && ix86_match_ccmode (insn, CCNOmode)
17002 && true_regnum (operands[2]) != AX_REG
17003 && peep2_reg_dead_p (1, operands[2])"
17004 [(parallel
17005 [(set (match_dup 0)
17006 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17007 (const_int 0)]))
17008 (set (match_dup 2)
17009 (and:QI (match_dup 2) (match_dup 3)))])])
17010
17011 (define_peephole2
17012 [(set (match_operand 0 "flags_reg_operand" "")
17013 (match_operator 1 "compare_operator"
17014 [(and:SI
17015 (zero_extract:SI
17016 (match_operand 2 "ext_register_operand" "")
17017 (const_int 8)
17018 (const_int 8))
17019 (match_operand 3 "const_int_operand" ""))
17020 (const_int 0)]))]
17021 "! TARGET_PARTIAL_REG_STALL
17022 && ix86_match_ccmode (insn, CCNOmode)
17023 && true_regnum (operands[2]) != AX_REG
17024 && peep2_reg_dead_p (1, operands[2])"
17025 [(parallel [(set (match_dup 0)
17026 (match_op_dup 1
17027 [(and:SI
17028 (zero_extract:SI
17029 (match_dup 2)
17030 (const_int 8)
17031 (const_int 8))
17032 (match_dup 3))
17033 (const_int 0)]))
17034 (set (zero_extract:SI (match_dup 2)
17035 (const_int 8)
17036 (const_int 8))
17037 (and:SI
17038 (zero_extract:SI
17039 (match_dup 2)
17040 (const_int 8)
17041 (const_int 8))
17042 (match_dup 3)))])])
17043
17044 ;; Don't do logical operations with memory inputs.
17045 (define_peephole2
17046 [(match_scratch:SI 2 "r")
17047 (parallel [(set (match_operand:SI 0 "register_operand" "")
17048 (match_operator:SI 3 "arith_or_logical_operator"
17049 [(match_dup 0)
17050 (match_operand:SI 1 "memory_operand" "")]))
17051 (clobber (reg:CC FLAGS_REG))])]
17052 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17053 [(set (match_dup 2) (match_dup 1))
17054 (parallel [(set (match_dup 0)
17055 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17056 (clobber (reg:CC FLAGS_REG))])])
17057
17058 (define_peephole2
17059 [(match_scratch:SI 2 "r")
17060 (parallel [(set (match_operand:SI 0 "register_operand" "")
17061 (match_operator:SI 3 "arith_or_logical_operator"
17062 [(match_operand:SI 1 "memory_operand" "")
17063 (match_dup 0)]))
17064 (clobber (reg:CC FLAGS_REG))])]
17065 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17066 [(set (match_dup 2) (match_dup 1))
17067 (parallel [(set (match_dup 0)
17068 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17069 (clobber (reg:CC FLAGS_REG))])])
17070
17071 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17072 ;; refers to the destination of the load!
17073
17074 (define_peephole2
17075 [(set (match_operand:SI 0 "register_operand" "")
17076 (match_operand:SI 1 "register_operand" ""))
17077 (parallel [(set (match_dup 0)
17078 (match_operator:SI 3 "commutative_operator"
17079 [(match_dup 0)
17080 (match_operand:SI 2 "memory_operand" "")]))
17081 (clobber (reg:CC FLAGS_REG))])]
17082 "REGNO (operands[0]) != REGNO (operands[1])
17083 && GENERAL_REGNO_P (REGNO (operands[0]))
17084 && GENERAL_REGNO_P (REGNO (operands[1]))"
17085 [(set (match_dup 0) (match_dup 4))
17086 (parallel [(set (match_dup 0)
17087 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17088 (clobber (reg:CC FLAGS_REG))])]
17089 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17090
17091 (define_peephole2
17092 [(set (match_operand 0 "register_operand" "")
17093 (match_operand 1 "register_operand" ""))
17094 (set (match_dup 0)
17095 (match_operator 3 "commutative_operator"
17096 [(match_dup 0)
17097 (match_operand 2 "memory_operand" "")]))]
17098 "REGNO (operands[0]) != REGNO (operands[1])
17099 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17100 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17101 [(set (match_dup 0) (match_dup 2))
17102 (set (match_dup 0)
17103 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17104
17105 ; Don't do logical operations with memory outputs
17106 ;
17107 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17108 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17109 ; the same decoder scheduling characteristics as the original.
17110
17111 (define_peephole2
17112 [(match_scratch:SI 2 "r")
17113 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17114 (match_operator:SI 3 "arith_or_logical_operator"
17115 [(match_dup 0)
17116 (match_operand:SI 1 "nonmemory_operand" "")]))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17119 /* Do not split stack checking probes. */
17120 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17121 [(set (match_dup 2) (match_dup 0))
17122 (parallel [(set (match_dup 2)
17123 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17124 (clobber (reg:CC FLAGS_REG))])
17125 (set (match_dup 0) (match_dup 2))])
17126
17127 (define_peephole2
17128 [(match_scratch:SI 2 "r")
17129 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17130 (match_operator:SI 3 "arith_or_logical_operator"
17131 [(match_operand:SI 1 "nonmemory_operand" "")
17132 (match_dup 0)]))
17133 (clobber (reg:CC FLAGS_REG))])]
17134 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17135 /* Do not split stack checking probes. */
17136 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17137 [(set (match_dup 2) (match_dup 0))
17138 (parallel [(set (match_dup 2)
17139 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17140 (clobber (reg:CC FLAGS_REG))])
17141 (set (match_dup 0) (match_dup 2))])
17142
17143 ;; Attempt to use arith or logical operations with memory outputs with
17144 ;; setting of flags.
17145 (define_peephole2
17146 [(set (match_operand:SWI 0 "register_operand" "")
17147 (match_operand:SWI 1 "memory_operand" ""))
17148 (parallel [(set (match_dup 0)
17149 (match_operator:SWI 3 "plusminuslogic_operator"
17150 [(match_dup 0)
17151 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17152 (clobber (reg:CC FLAGS_REG))])
17153 (set (match_dup 1) (match_dup 0))
17154 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17155 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17156 && peep2_reg_dead_p (4, operands[0])
17157 && !reg_overlap_mentioned_p (operands[0], operands[1])
17158 && ix86_match_ccmode (peep2_next_insn (3),
17159 (GET_CODE (operands[3]) == PLUS
17160 || GET_CODE (operands[3]) == MINUS)
17161 ? CCGOCmode : CCNOmode)"
17162 [(parallel [(set (match_dup 4) (match_dup 5))
17163 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17164 (match_dup 2)]))])]
17165 {
17166 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17167 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17168 copy_rtx (operands[1]),
17169 copy_rtx (operands[2]));
17170 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17171 operands[5], const0_rtx);
17172 })
17173
17174 (define_peephole2
17175 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17176 (match_operator:SWI 2 "plusminuslogic_operator"
17177 [(match_dup 0)
17178 (match_operand:SWI 1 "memory_operand" "")]))
17179 (clobber (reg:CC FLAGS_REG))])
17180 (set (match_dup 1) (match_dup 0))
17181 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17182 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17183 && GET_CODE (operands[2]) != MINUS
17184 && peep2_reg_dead_p (3, operands[0])
17185 && !reg_overlap_mentioned_p (operands[0], operands[1])
17186 && ix86_match_ccmode (peep2_next_insn (2),
17187 GET_CODE (operands[2]) == PLUS
17188 ? CCGOCmode : CCNOmode)"
17189 [(parallel [(set (match_dup 3) (match_dup 4))
17190 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17191 (match_dup 0)]))])]
17192 {
17193 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17194 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17195 copy_rtx (operands[1]),
17196 copy_rtx (operands[0]));
17197 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17198 operands[4], const0_rtx);
17199 })
17200
17201 (define_peephole2
17202 [(set (match_operand:SWI12 0 "register_operand" "")
17203 (match_operand:SWI12 1 "memory_operand" ""))
17204 (parallel [(set (match_operand:SI 4 "register_operand" "")
17205 (match_operator:SI 3 "plusminuslogic_operator"
17206 [(match_dup 4)
17207 (match_operand:SI 2 "nonmemory_operand" "")]))
17208 (clobber (reg:CC FLAGS_REG))])
17209 (set (match_dup 1) (match_dup 0))
17210 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17211 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17212 && REG_P (operands[0]) && REG_P (operands[4])
17213 && REGNO (operands[0]) == REGNO (operands[4])
17214 && peep2_reg_dead_p (4, operands[0])
17215 && (<MODE>mode != QImode
17216 || immediate_operand (operands[2], SImode)
17217 || q_regs_operand (operands[2], SImode))
17218 && !reg_overlap_mentioned_p (operands[0], operands[1])
17219 && ix86_match_ccmode (peep2_next_insn (3),
17220 (GET_CODE (operands[3]) == PLUS
17221 || GET_CODE (operands[3]) == MINUS)
17222 ? CCGOCmode : CCNOmode)"
17223 [(parallel [(set (match_dup 4) (match_dup 5))
17224 (set (match_dup 1) (match_dup 6))])]
17225 {
17226 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17227 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17228 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17229 copy_rtx (operands[1]), operands[2]);
17230 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17231 operands[5], const0_rtx);
17232 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17233 copy_rtx (operands[1]),
17234 copy_rtx (operands[2]));
17235 })
17236
17237 ;; Attempt to always use XOR for zeroing registers.
17238 (define_peephole2
17239 [(set (match_operand 0 "register_operand" "")
17240 (match_operand 1 "const0_operand" ""))]
17241 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17242 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17243 && GENERAL_REG_P (operands[0])
17244 && peep2_regno_dead_p (0, FLAGS_REG)"
17245 [(parallel [(set (match_dup 0) (const_int 0))
17246 (clobber (reg:CC FLAGS_REG))])]
17247 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17248
17249 (define_peephole2
17250 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17251 (const_int 0))]
17252 "(GET_MODE (operands[0]) == QImode
17253 || GET_MODE (operands[0]) == HImode)
17254 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17255 && peep2_regno_dead_p (0, FLAGS_REG)"
17256 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17257 (clobber (reg:CC FLAGS_REG))])])
17258
17259 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17260 (define_peephole2
17261 [(set (match_operand:SWI248 0 "register_operand" "")
17262 (const_int -1))]
17263 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17264 && peep2_regno_dead_p (0, FLAGS_REG)"
17265 [(parallel [(set (match_dup 0) (const_int -1))
17266 (clobber (reg:CC FLAGS_REG))])]
17267 {
17268 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17269 operands[0] = gen_lowpart (SImode, operands[0]);
17270 })
17271
17272 ;; Attempt to convert simple lea to add/shift.
17273 ;; These can be created by move expanders.
17274
17275 (define_peephole2
17276 [(set (match_operand:SWI48 0 "register_operand" "")
17277 (plus:SWI48 (match_dup 0)
17278 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17279 "peep2_regno_dead_p (0, FLAGS_REG)"
17280 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17281 (clobber (reg:CC FLAGS_REG))])])
17282
17283 (define_peephole2
17284 [(set (match_operand:SI 0 "register_operand" "")
17285 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17286 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17287 "TARGET_64BIT
17288 && peep2_regno_dead_p (0, FLAGS_REG)
17289 && REGNO (operands[0]) == REGNO (operands[1])"
17290 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17291 (clobber (reg:CC FLAGS_REG))])]
17292 "operands[2] = gen_lowpart (SImode, operands[2]);")
17293
17294 (define_peephole2
17295 [(set (match_operand:SWI48 0 "register_operand" "")
17296 (mult:SWI48 (match_dup 0)
17297 (match_operand:SWI48 1 "const_int_operand" "")))]
17298 "exact_log2 (INTVAL (operands[1])) >= 0
17299 && peep2_regno_dead_p (0, FLAGS_REG)"
17300 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17301 (clobber (reg:CC FLAGS_REG))])]
17302 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17303
17304 (define_peephole2
17305 [(set (match_operand:SI 0 "register_operand" "")
17306 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17307 (match_operand:DI 2 "const_int_operand" "")) 0))]
17308 "TARGET_64BIT
17309 && exact_log2 (INTVAL (operands[2])) >= 0
17310 && REGNO (operands[0]) == REGNO (operands[1])
17311 && peep2_regno_dead_p (0, FLAGS_REG)"
17312 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17313 (clobber (reg:CC FLAGS_REG))])]
17314 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17315
17316 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17317 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17318 ;; On many CPUs it is also faster, since special hardware to avoid esp
17319 ;; dependencies is present.
17320
17321 ;; While some of these conversions may be done using splitters, we use
17322 ;; peepholes in order to allow combine_stack_adjustments pass to see
17323 ;; nonobfuscated RTL.
17324
17325 ;; Convert prologue esp subtractions to push.
17326 ;; We need register to push. In order to keep verify_flow_info happy we have
17327 ;; two choices
17328 ;; - use scratch and clobber it in order to avoid dependencies
17329 ;; - use already live register
17330 ;; We can't use the second way right now, since there is no reliable way how to
17331 ;; verify that given register is live. First choice will also most likely in
17332 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17333 ;; call clobbered registers are dead. We may want to use base pointer as an
17334 ;; alternative when no register is available later.
17335
17336 (define_peephole2
17337 [(match_scratch:P 1 "r")
17338 (parallel [(set (reg:P SP_REG)
17339 (plus:P (reg:P SP_REG)
17340 (match_operand:P 0 "const_int_operand" "")))
17341 (clobber (reg:CC FLAGS_REG))
17342 (clobber (mem:BLK (scratch)))])]
17343 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17344 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17345 [(clobber (match_dup 1))
17346 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17347 (clobber (mem:BLK (scratch)))])])
17348
17349 (define_peephole2
17350 [(match_scratch:P 1 "r")
17351 (parallel [(set (reg:P SP_REG)
17352 (plus:P (reg:P SP_REG)
17353 (match_operand:P 0 "const_int_operand" "")))
17354 (clobber (reg:CC FLAGS_REG))
17355 (clobber (mem:BLK (scratch)))])]
17356 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17357 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17358 [(clobber (match_dup 1))
17359 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17360 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17361 (clobber (mem:BLK (scratch)))])])
17362
17363 ;; Convert esp subtractions to push.
17364 (define_peephole2
17365 [(match_scratch:P 1 "r")
17366 (parallel [(set (reg:P SP_REG)
17367 (plus:P (reg:P SP_REG)
17368 (match_operand:P 0 "const_int_operand" "")))
17369 (clobber (reg:CC FLAGS_REG))])]
17370 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17371 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17372 [(clobber (match_dup 1))
17373 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17374
17375 (define_peephole2
17376 [(match_scratch:P 1 "r")
17377 (parallel [(set (reg:P SP_REG)
17378 (plus:P (reg:P SP_REG)
17379 (match_operand:P 0 "const_int_operand" "")))
17380 (clobber (reg:CC FLAGS_REG))])]
17381 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17382 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17383 [(clobber (match_dup 1))
17384 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17385 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17386
17387 ;; Convert epilogue deallocator to pop.
17388 (define_peephole2
17389 [(match_scratch:P 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand" "")))
17393 (clobber (reg:CC FLAGS_REG))
17394 (clobber (mem:BLK (scratch)))])]
17395 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17396 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17397 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17398 (clobber (mem:BLK (scratch)))])])
17399
17400 ;; Two pops case is tricky, since pop causes dependency
17401 ;; on destination register. We use two registers if available.
17402 (define_peephole2
17403 [(match_scratch:P 1 "r")
17404 (match_scratch:P 2 "r")
17405 (parallel [(set (reg:P SP_REG)
17406 (plus:P (reg:P SP_REG)
17407 (match_operand:P 0 "const_int_operand" "")))
17408 (clobber (reg:CC FLAGS_REG))
17409 (clobber (mem:BLK (scratch)))])]
17410 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17411 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17412 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17413 (clobber (mem:BLK (scratch)))])
17414 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17415
17416 (define_peephole2
17417 [(match_scratch:P 1 "r")
17418 (parallel [(set (reg:P SP_REG)
17419 (plus:P (reg:P SP_REG)
17420 (match_operand:P 0 "const_int_operand" "")))
17421 (clobber (reg:CC FLAGS_REG))
17422 (clobber (mem:BLK (scratch)))])]
17423 "optimize_insn_for_size_p ()
17424 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17425 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17426 (clobber (mem:BLK (scratch)))])
17427 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17428
17429 ;; Convert esp additions to pop.
17430 (define_peephole2
17431 [(match_scratch:P 1 "r")
17432 (parallel [(set (reg:P SP_REG)
17433 (plus:P (reg:P SP_REG)
17434 (match_operand:P 0 "const_int_operand" "")))
17435 (clobber (reg:CC FLAGS_REG))])]
17436 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17437 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17438
17439 ;; Two pops case is tricky, since pop causes dependency
17440 ;; on destination register. We use two registers if available.
17441 (define_peephole2
17442 [(match_scratch:P 1 "r")
17443 (match_scratch:P 2 "r")
17444 (parallel [(set (reg:P SP_REG)
17445 (plus:P (reg:P SP_REG)
17446 (match_operand:P 0 "const_int_operand" "")))
17447 (clobber (reg:CC FLAGS_REG))])]
17448 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17449 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17450 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17451
17452 (define_peephole2
17453 [(match_scratch:P 1 "r")
17454 (parallel [(set (reg:P SP_REG)
17455 (plus:P (reg:P SP_REG)
17456 (match_operand:P 0 "const_int_operand" "")))
17457 (clobber (reg:CC FLAGS_REG))])]
17458 "optimize_insn_for_size_p ()
17459 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17460 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17461 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17462 \f
17463 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17464 ;; required and register dies. Similarly for 128 to -128.
17465 (define_peephole2
17466 [(set (match_operand 0 "flags_reg_operand" "")
17467 (match_operator 1 "compare_operator"
17468 [(match_operand 2 "register_operand" "")
17469 (match_operand 3 "const_int_operand" "")]))]
17470 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17471 && incdec_operand (operands[3], GET_MODE (operands[3])))
17472 || (!TARGET_FUSE_CMP_AND_BRANCH
17473 && INTVAL (operands[3]) == 128))
17474 && ix86_match_ccmode (insn, CCGCmode)
17475 && peep2_reg_dead_p (1, operands[2])"
17476 [(parallel [(set (match_dup 0)
17477 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17478 (clobber (match_dup 2))])])
17479 \f
17480 ;; Convert imul by three, five and nine into lea
17481 (define_peephole2
17482 [(parallel
17483 [(set (match_operand:SWI48 0 "register_operand" "")
17484 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17485 (match_operand:SWI48 2 "const359_operand" "")))
17486 (clobber (reg:CC FLAGS_REG))])]
17487 "!TARGET_PARTIAL_REG_STALL
17488 || <MODE>mode == SImode
17489 || optimize_function_for_size_p (cfun)"
17490 [(set (match_dup 0)
17491 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17492 (match_dup 1)))]
17493 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17494
17495 (define_peephole2
17496 [(parallel
17497 [(set (match_operand:SWI48 0 "register_operand" "")
17498 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17499 (match_operand:SWI48 2 "const359_operand" "")))
17500 (clobber (reg:CC FLAGS_REG))])]
17501 "optimize_insn_for_speed_p ()
17502 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17503 [(set (match_dup 0) (match_dup 1))
17504 (set (match_dup 0)
17505 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17506 (match_dup 0)))]
17507 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17508
17509 ;; imul $32bit_imm, mem, reg is vector decoded, while
17510 ;; imul $32bit_imm, reg, reg is direct decoded.
17511 (define_peephole2
17512 [(match_scratch:SWI48 3 "r")
17513 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17514 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17515 (match_operand:SWI48 2 "immediate_operand" "")))
17516 (clobber (reg:CC FLAGS_REG))])]
17517 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17518 && !satisfies_constraint_K (operands[2])"
17519 [(set (match_dup 3) (match_dup 1))
17520 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17521 (clobber (reg:CC FLAGS_REG))])])
17522
17523 (define_peephole2
17524 [(match_scratch:SI 3 "r")
17525 (parallel [(set (match_operand:DI 0 "register_operand" "")
17526 (zero_extend:DI
17527 (mult:SI (match_operand:SI 1 "memory_operand" "")
17528 (match_operand:SI 2 "immediate_operand" ""))))
17529 (clobber (reg:CC FLAGS_REG))])]
17530 "TARGET_64BIT
17531 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17532 && !satisfies_constraint_K (operands[2])"
17533 [(set (match_dup 3) (match_dup 1))
17534 (parallel [(set (match_dup 0)
17535 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17536 (clobber (reg:CC FLAGS_REG))])])
17537
17538 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17539 ;; Convert it into imul reg, reg
17540 ;; It would be better to force assembler to encode instruction using long
17541 ;; immediate, but there is apparently no way to do so.
17542 (define_peephole2
17543 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17544 (mult:SWI248
17545 (match_operand:SWI248 1 "nonimmediate_operand" "")
17546 (match_operand:SWI248 2 "const_int_operand" "")))
17547 (clobber (reg:CC FLAGS_REG))])
17548 (match_scratch:SWI248 3 "r")]
17549 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17550 && satisfies_constraint_K (operands[2])"
17551 [(set (match_dup 3) (match_dup 2))
17552 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17553 (clobber (reg:CC FLAGS_REG))])]
17554 {
17555 if (!rtx_equal_p (operands[0], operands[1]))
17556 emit_move_insn (operands[0], operands[1]);
17557 })
17558
17559 ;; After splitting up read-modify operations, array accesses with memory
17560 ;; operands might end up in form:
17561 ;; sall $2, %eax
17562 ;; movl 4(%esp), %edx
17563 ;; addl %edx, %eax
17564 ;; instead of pre-splitting:
17565 ;; sall $2, %eax
17566 ;; addl 4(%esp), %eax
17567 ;; Turn it into:
17568 ;; movl 4(%esp), %edx
17569 ;; leal (%edx,%eax,4), %eax
17570
17571 (define_peephole2
17572 [(match_scratch:P 5 "r")
17573 (parallel [(set (match_operand 0 "register_operand" "")
17574 (ashift (match_operand 1 "register_operand" "")
17575 (match_operand 2 "const_int_operand" "")))
17576 (clobber (reg:CC FLAGS_REG))])
17577 (parallel [(set (match_operand 3 "register_operand" "")
17578 (plus (match_dup 0)
17579 (match_operand 4 "x86_64_general_operand" "")))
17580 (clobber (reg:CC FLAGS_REG))])]
17581 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17582 /* Validate MODE for lea. */
17583 && ((!TARGET_PARTIAL_REG_STALL
17584 && (GET_MODE (operands[0]) == QImode
17585 || GET_MODE (operands[0]) == HImode))
17586 || GET_MODE (operands[0]) == SImode
17587 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17588 && (rtx_equal_p (operands[0], operands[3])
17589 || peep2_reg_dead_p (2, operands[0]))
17590 /* We reorder load and the shift. */
17591 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17592 [(set (match_dup 5) (match_dup 4))
17593 (set (match_dup 0) (match_dup 1))]
17594 {
17595 enum machine_mode op1mode = GET_MODE (operands[1]);
17596 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17597 int scale = 1 << INTVAL (operands[2]);
17598 rtx index = gen_lowpart (Pmode, operands[1]);
17599 rtx base = gen_lowpart (Pmode, operands[5]);
17600 rtx dest = gen_lowpart (mode, operands[3]);
17601
17602 operands[1] = gen_rtx_PLUS (Pmode, base,
17603 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17604 operands[5] = base;
17605 if (mode != Pmode)
17606 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17607 if (op1mode != Pmode)
17608 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17609 operands[0] = dest;
17610 })
17611 \f
17612 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17613 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17614 ;; caught for use by garbage collectors and the like. Using an insn that
17615 ;; maps to SIGILL makes it more likely the program will rightfully die.
17616 ;; Keeping with tradition, "6" is in honor of #UD.
17617 (define_insn "trap"
17618 [(trap_if (const_int 1) (const_int 6))]
17619 ""
17620 { return ASM_SHORT "0x0b0f"; }
17621 [(set_attr "length" "2")])
17622
17623 (define_expand "prefetch"
17624 [(prefetch (match_operand 0 "address_operand" "")
17625 (match_operand:SI 1 "const_int_operand" "")
17626 (match_operand:SI 2 "const_int_operand" ""))]
17627 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17628 {
17629 int rw = INTVAL (operands[1]);
17630 int locality = INTVAL (operands[2]);
17631
17632 gcc_assert (rw == 0 || rw == 1);
17633 gcc_assert (locality >= 0 && locality <= 3);
17634 gcc_assert (GET_MODE (operands[0]) == Pmode
17635 || GET_MODE (operands[0]) == VOIDmode);
17636
17637 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17638 supported by SSE counterpart or the SSE prefetch is not available
17639 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17640 of locality. */
17641 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17642 operands[2] = GEN_INT (3);
17643 else
17644 operands[1] = const0_rtx;
17645 })
17646
17647 (define_insn "*prefetch_sse_<mode>"
17648 [(prefetch (match_operand:P 0 "address_operand" "p")
17649 (const_int 0)
17650 (match_operand:SI 1 "const_int_operand" ""))]
17651 "TARGET_PREFETCH_SSE"
17652 {
17653 static const char * const patterns[4] = {
17654 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17655 };
17656
17657 int locality = INTVAL (operands[1]);
17658 gcc_assert (locality >= 0 && locality <= 3);
17659
17660 return patterns[locality];
17661 }
17662 [(set_attr "type" "sse")
17663 (set_attr "atom_sse_attr" "prefetch")
17664 (set (attr "length_address")
17665 (symbol_ref "memory_address_length (operands[0])"))
17666 (set_attr "memory" "none")])
17667
17668 (define_insn "*prefetch_3dnow_<mode>"
17669 [(prefetch (match_operand:P 0 "address_operand" "p")
17670 (match_operand:SI 1 "const_int_operand" "n")
17671 (const_int 3))]
17672 "TARGET_3DNOW"
17673 {
17674 if (INTVAL (operands[1]) == 0)
17675 return "prefetch\t%a0";
17676 else
17677 return "prefetchw\t%a0";
17678 }
17679 [(set_attr "type" "mmx")
17680 (set (attr "length_address")
17681 (symbol_ref "memory_address_length (operands[0])"))
17682 (set_attr "memory" "none")])
17683
17684 (define_expand "stack_protect_set"
17685 [(match_operand 0 "memory_operand" "")
17686 (match_operand 1 "memory_operand" "")]
17687 ""
17688 {
17689 rtx (*insn)(rtx, rtx);
17690
17691 #ifdef TARGET_THREAD_SSP_OFFSET
17692 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17693 insn = (TARGET_LP64
17694 ? gen_stack_tls_protect_set_di
17695 : gen_stack_tls_protect_set_si);
17696 #else
17697 insn = (TARGET_LP64
17698 ? gen_stack_protect_set_di
17699 : gen_stack_protect_set_si);
17700 #endif
17701
17702 emit_insn (insn (operands[0], operands[1]));
17703 DONE;
17704 })
17705
17706 (define_insn "stack_protect_set_<mode>"
17707 [(set (match_operand:PTR 0 "memory_operand" "=m")
17708 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17709 UNSPEC_SP_SET))
17710 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17711 (clobber (reg:CC FLAGS_REG))]
17712 ""
17713 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17714 [(set_attr "type" "multi")])
17715
17716 (define_insn "stack_tls_protect_set_<mode>"
17717 [(set (match_operand:PTR 0 "memory_operand" "=m")
17718 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17719 UNSPEC_SP_TLS_SET))
17720 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17721 (clobber (reg:CC FLAGS_REG))]
17722 ""
17723 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17724 [(set_attr "type" "multi")])
17725
17726 (define_expand "stack_protect_test"
17727 [(match_operand 0 "memory_operand" "")
17728 (match_operand 1 "memory_operand" "")
17729 (match_operand 2 "" "")]
17730 ""
17731 {
17732 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17733
17734 rtx (*insn)(rtx, rtx, rtx);
17735
17736 #ifdef TARGET_THREAD_SSP_OFFSET
17737 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17738 insn = (TARGET_LP64
17739 ? gen_stack_tls_protect_test_di
17740 : gen_stack_tls_protect_test_si);
17741 #else
17742 insn = (TARGET_LP64
17743 ? gen_stack_protect_test_di
17744 : gen_stack_protect_test_si);
17745 #endif
17746
17747 emit_insn (insn (flags, operands[0], operands[1]));
17748
17749 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17750 flags, const0_rtx, operands[2]));
17751 DONE;
17752 })
17753
17754 (define_insn "stack_protect_test_<mode>"
17755 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17756 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17757 (match_operand:PTR 2 "memory_operand" "m")]
17758 UNSPEC_SP_TEST))
17759 (clobber (match_scratch:PTR 3 "=&r"))]
17760 ""
17761 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17762 [(set_attr "type" "multi")])
17763
17764 (define_insn "stack_tls_protect_test_<mode>"
17765 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17766 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17767 (match_operand:PTR 2 "const_int_operand" "i")]
17768 UNSPEC_SP_TLS_TEST))
17769 (clobber (match_scratch:PTR 3 "=r"))]
17770 ""
17771 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17772 [(set_attr "type" "multi")])
17773
17774 (define_insn "sse4_2_crc32<mode>"
17775 [(set (match_operand:SI 0 "register_operand" "=r")
17776 (unspec:SI
17777 [(match_operand:SI 1 "register_operand" "0")
17778 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17779 UNSPEC_CRC32))]
17780 "TARGET_SSE4_2 || TARGET_CRC32"
17781 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17782 [(set_attr "type" "sselog1")
17783 (set_attr "prefix_rep" "1")
17784 (set_attr "prefix_extra" "1")
17785 (set (attr "prefix_data16")
17786 (if_then_else (match_operand:HI 2 "" "")
17787 (const_string "1")
17788 (const_string "*")))
17789 (set (attr "prefix_rex")
17790 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17791 (const_string "1")
17792 (const_string "*")))
17793 (set_attr "mode" "SI")])
17794
17795 (define_insn "sse4_2_crc32di"
17796 [(set (match_operand:DI 0 "register_operand" "=r")
17797 (unspec:DI
17798 [(match_operand:DI 1 "register_operand" "0")
17799 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17800 UNSPEC_CRC32))]
17801 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17802 "crc32{q}\t{%2, %0|%0, %2}"
17803 [(set_attr "type" "sselog1")
17804 (set_attr "prefix_rep" "1")
17805 (set_attr "prefix_extra" "1")
17806 (set_attr "mode" "DI")])
17807
17808 (define_expand "rdpmc"
17809 [(match_operand:DI 0 "register_operand" "")
17810 (match_operand:SI 1 "register_operand" "")]
17811 ""
17812 {
17813 rtx reg = gen_reg_rtx (DImode);
17814 rtx si;
17815
17816 /* Force operand 1 into ECX. */
17817 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17818 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17819 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17820 UNSPECV_RDPMC);
17821
17822 if (TARGET_64BIT)
17823 {
17824 rtvec vec = rtvec_alloc (2);
17825 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17826 rtx upper = gen_reg_rtx (DImode);
17827 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17828 gen_rtvec (1, const0_rtx),
17829 UNSPECV_RDPMC);
17830 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17831 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17832 emit_insn (load);
17833 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17834 NULL, 1, OPTAB_DIRECT);
17835 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17836 OPTAB_DIRECT);
17837 }
17838 else
17839 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17840 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17841 DONE;
17842 })
17843
17844 (define_insn "*rdpmc"
17845 [(set (match_operand:DI 0 "register_operand" "=A")
17846 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17847 UNSPECV_RDPMC))]
17848 "!TARGET_64BIT"
17849 "rdpmc"
17850 [(set_attr "type" "other")
17851 (set_attr "length" "2")])
17852
17853 (define_insn "*rdpmc_rex64"
17854 [(set (match_operand:DI 0 "register_operand" "=a")
17855 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17856 UNSPECV_RDPMC))
17857 (set (match_operand:DI 1 "register_operand" "=d")
17858 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17859 "TARGET_64BIT"
17860 "rdpmc"
17861 [(set_attr "type" "other")
17862 (set_attr "length" "2")])
17863
17864 (define_expand "rdtsc"
17865 [(set (match_operand:DI 0 "register_operand" "")
17866 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17867 ""
17868 {
17869 if (TARGET_64BIT)
17870 {
17871 rtvec vec = rtvec_alloc (2);
17872 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17873 rtx upper = gen_reg_rtx (DImode);
17874 rtx lower = gen_reg_rtx (DImode);
17875 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17876 gen_rtvec (1, const0_rtx),
17877 UNSPECV_RDTSC);
17878 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17879 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17880 emit_insn (load);
17881 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17882 NULL, 1, OPTAB_DIRECT);
17883 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17884 OPTAB_DIRECT);
17885 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17886 DONE;
17887 }
17888 })
17889
17890 (define_insn "*rdtsc"
17891 [(set (match_operand:DI 0 "register_operand" "=A")
17892 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17893 "!TARGET_64BIT"
17894 "rdtsc"
17895 [(set_attr "type" "other")
17896 (set_attr "length" "2")])
17897
17898 (define_insn "*rdtsc_rex64"
17899 [(set (match_operand:DI 0 "register_operand" "=a")
17900 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17901 (set (match_operand:DI 1 "register_operand" "=d")
17902 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17903 "TARGET_64BIT"
17904 "rdtsc"
17905 [(set_attr "type" "other")
17906 (set_attr "length" "2")])
17907
17908 (define_expand "rdtscp"
17909 [(match_operand:DI 0 "register_operand" "")
17910 (match_operand:SI 1 "memory_operand" "")]
17911 ""
17912 {
17913 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17914 gen_rtvec (1, const0_rtx),
17915 UNSPECV_RDTSCP);
17916 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17917 gen_rtvec (1, const0_rtx),
17918 UNSPECV_RDTSCP);
17919 rtx reg = gen_reg_rtx (DImode);
17920 rtx tmp = gen_reg_rtx (SImode);
17921
17922 if (TARGET_64BIT)
17923 {
17924 rtvec vec = rtvec_alloc (3);
17925 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17926 rtx upper = gen_reg_rtx (DImode);
17927 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17928 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17929 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17930 emit_insn (load);
17931 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17932 NULL, 1, OPTAB_DIRECT);
17933 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17934 OPTAB_DIRECT);
17935 }
17936 else
17937 {
17938 rtvec vec = rtvec_alloc (2);
17939 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17940 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17941 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17942 emit_insn (load);
17943 }
17944 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17945 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17946 DONE;
17947 })
17948
17949 (define_insn "*rdtscp"
17950 [(set (match_operand:DI 0 "register_operand" "=A")
17951 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17952 (set (match_operand:SI 1 "register_operand" "=c")
17953 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17954 "!TARGET_64BIT"
17955 "rdtscp"
17956 [(set_attr "type" "other")
17957 (set_attr "length" "3")])
17958
17959 (define_insn "*rdtscp_rex64"
17960 [(set (match_operand:DI 0 "register_operand" "=a")
17961 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17962 (set (match_operand:DI 1 "register_operand" "=d")
17963 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17964 (set (match_operand:SI 2 "register_operand" "=c")
17965 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17966 "TARGET_64BIT"
17967 "rdtscp"
17968 [(set_attr "type" "other")
17969 (set_attr "length" "3")])
17970
17971 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17972 ;;
17973 ;; LWP instructions
17974 ;;
17975 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17976
17977 (define_expand "lwp_llwpcb"
17978 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17979 UNSPECV_LLWP_INTRINSIC)]
17980 "TARGET_LWP")
17981
17982 (define_insn "*lwp_llwpcb<mode>1"
17983 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17984 UNSPECV_LLWP_INTRINSIC)]
17985 "TARGET_LWP"
17986 "llwpcb\t%0"
17987 [(set_attr "type" "lwp")
17988 (set_attr "mode" "<MODE>")
17989 (set_attr "length" "5")])
17990
17991 (define_expand "lwp_slwpcb"
17992 [(set (match_operand 0 "register_operand" "=r")
17993 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17994 "TARGET_LWP"
17995 {
17996 rtx (*insn)(rtx);
17997
17998 insn = (TARGET_64BIT
17999 ? gen_lwp_slwpcbdi
18000 : gen_lwp_slwpcbsi);
18001
18002 emit_insn (insn (operands[0]));
18003 DONE;
18004 })
18005
18006 (define_insn "lwp_slwpcb<mode>"
18007 [(set (match_operand:P 0 "register_operand" "=r")
18008 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18009 "TARGET_LWP"
18010 "slwpcb\t%0"
18011 [(set_attr "type" "lwp")
18012 (set_attr "mode" "<MODE>")
18013 (set_attr "length" "5")])
18014
18015 (define_expand "lwp_lwpval<mode>3"
18016 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18017 (match_operand:SI 2 "nonimmediate_operand" "rm")
18018 (match_operand:SI 3 "const_int_operand" "i")]
18019 UNSPECV_LWPVAL_INTRINSIC)]
18020 "TARGET_LWP"
18021 ;; Avoid unused variable warning.
18022 "(void) operands[0];")
18023
18024 (define_insn "*lwp_lwpval<mode>3_1"
18025 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18026 (match_operand:SI 1 "nonimmediate_operand" "rm")
18027 (match_operand:SI 2 "const_int_operand" "i")]
18028 UNSPECV_LWPVAL_INTRINSIC)]
18029 "TARGET_LWP"
18030 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18031 [(set_attr "type" "lwp")
18032 (set_attr "mode" "<MODE>")
18033 (set (attr "length")
18034 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18035
18036 (define_expand "lwp_lwpins<mode>3"
18037 [(set (reg:CCC FLAGS_REG)
18038 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18039 (match_operand:SI 2 "nonimmediate_operand" "rm")
18040 (match_operand:SI 3 "const_int_operand" "i")]
18041 UNSPECV_LWPINS_INTRINSIC))
18042 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18043 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18044 "TARGET_LWP")
18045
18046 (define_insn "*lwp_lwpins<mode>3_1"
18047 [(set (reg:CCC FLAGS_REG)
18048 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18049 (match_operand:SI 1 "nonimmediate_operand" "rm")
18050 (match_operand:SI 2 "const_int_operand" "i")]
18051 UNSPECV_LWPINS_INTRINSIC))]
18052 "TARGET_LWP"
18053 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18054 [(set_attr "type" "lwp")
18055 (set_attr "mode" "<MODE>")
18056 (set (attr "length")
18057 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18058
18059 (define_insn "rdfsbase<mode>"
18060 [(set (match_operand:SWI48 0 "register_operand" "=r")
18061 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18062 "TARGET_64BIT && TARGET_FSGSBASE"
18063 "rdfsbase %0"
18064 [(set_attr "type" "other")
18065 (set_attr "prefix_extra" "2")])
18066
18067 (define_insn "rdgsbase<mode>"
18068 [(set (match_operand:SWI48 0 "register_operand" "=r")
18069 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18070 "TARGET_64BIT && TARGET_FSGSBASE"
18071 "rdgsbase %0"
18072 [(set_attr "type" "other")
18073 (set_attr "prefix_extra" "2")])
18074
18075 (define_insn "wrfsbase<mode>"
18076 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18077 UNSPECV_WRFSBASE)]
18078 "TARGET_64BIT && TARGET_FSGSBASE"
18079 "wrfsbase %0"
18080 [(set_attr "type" "other")
18081 (set_attr "prefix_extra" "2")])
18082
18083 (define_insn "wrgsbase<mode>"
18084 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18085 UNSPECV_WRGSBASE)]
18086 "TARGET_64BIT && TARGET_FSGSBASE"
18087 "wrgsbase %0"
18088 [(set_attr "type" "other")
18089 (set_attr "prefix_extra" "2")])
18090
18091 (define_insn "rdrand<mode>_1"
18092 [(set (match_operand:SWI248 0 "register_operand" "=r")
18093 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18094 (set (reg:CCC FLAGS_REG)
18095 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18096 "TARGET_RDRND"
18097 "rdrand\t%0"
18098 [(set_attr "type" "other")
18099 (set_attr "prefix_extra" "1")])
18100
18101 (define_expand "pause"
18102 [(set (match_dup 0)
18103 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18104 ""
18105 {
18106 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18107 MEM_VOLATILE_P (operands[0]) = 1;
18108 })
18109
18110 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18111 ;; They have the same encoding.
18112 (define_insn "*pause"
18113 [(set (match_operand:BLK 0 "" "")
18114 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18115 ""
18116 "rep; nop"
18117 [(set_attr "length" "2")
18118 (set_attr "memory" "unknown")])
18119
18120 (include "mmx.md")
18121 (include "sse.md")
18122 (include "sync.md")