predicates.md (call_insn_operand): Allow constant_call_address_operand in Pmode only.
[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 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
65 ;; @ -- print a segment register of thread base pointer load
66 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
67
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
70 UNSPEC_GOT
71 UNSPEC_GOTOFF
72 UNSPEC_GOTPCREL
73 UNSPEC_GOTTPOFF
74 UNSPEC_TPOFF
75 UNSPEC_NTPOFF
76 UNSPEC_DTPOFF
77 UNSPEC_GOTNTPOFF
78 UNSPEC_INDNTPOFF
79 UNSPEC_PLTOFF
80 UNSPEC_MACHOPIC_OFFSET
81 UNSPEC_PCREL
82
83 ;; Prologue support
84 UNSPEC_STACK_ALLOC
85 UNSPEC_SET_GOT
86 UNSPEC_REG_SAVE
87 UNSPEC_DEF_CFA
88 UNSPEC_SET_RIP
89 UNSPEC_SET_GOT_OFFSET
90 UNSPEC_MEMORY_BLOCKAGE
91 UNSPEC_STACK_CHECK
92
93 ;; TLS support
94 UNSPEC_TP
95 UNSPEC_TLS_GD
96 UNSPEC_TLS_LD_BASE
97 UNSPEC_TLSDESC
98 UNSPEC_TLS_IE_SUN
99 UNSPEC_TLS_IE_X32
100
101 ;; Other random patterns
102 UNSPEC_SCAS
103 UNSPEC_FNSTSW
104 UNSPEC_SAHF
105 UNSPEC_PARITY
106 UNSPEC_FSTCW
107 UNSPEC_ADD_CARRY
108 UNSPEC_FLDCW
109 UNSPEC_REP
110 UNSPEC_LD_MPIC ; load_macho_picbase
111 UNSPEC_TRUNC_NOOP
112 UNSPEC_DIV_ALREADY_SPLIT
113 UNSPEC_MS_TO_SYSV_CALL
114 UNSPEC_CALL_NEEDS_VZEROUPPER
115 UNSPEC_PAUSE
116 UNSPEC_LEA_ADDR
117
118 ;; For SSE/MMX support:
119 UNSPEC_FIX_NOTRUNC
120 UNSPEC_MASKMOV
121 UNSPEC_MOVMSK
122 UNSPEC_RCP
123 UNSPEC_RSQRT
124 UNSPEC_PSADBW
125
126 ;; Generic math support
127 UNSPEC_COPYSIGN
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
130
131 ;; x87 Floating point
132 UNSPEC_SIN
133 UNSPEC_COS
134 UNSPEC_FPATAN
135 UNSPEC_FYL2X
136 UNSPEC_FYL2XP1
137 UNSPEC_FRNDINT
138 UNSPEC_FIST
139 UNSPEC_F2XM1
140 UNSPEC_TAN
141 UNSPEC_FXAM
142
143 ;; x87 Rounding
144 UNSPEC_FRNDINT_FLOOR
145 UNSPEC_FRNDINT_CEIL
146 UNSPEC_FRNDINT_TRUNC
147 UNSPEC_FRNDINT_MASK_PM
148 UNSPEC_FIST_FLOOR
149 UNSPEC_FIST_CEIL
150
151 ;; x87 Double output FP
152 UNSPEC_SINCOS_COS
153 UNSPEC_SINCOS_SIN
154 UNSPEC_XTRACT_FRACT
155 UNSPEC_XTRACT_EXP
156 UNSPEC_FSCALE_FRACT
157 UNSPEC_FSCALE_EXP
158 UNSPEC_FPREM_F
159 UNSPEC_FPREM_U
160 UNSPEC_FPREM1_F
161 UNSPEC_FPREM1_U
162
163 UNSPEC_C2_FLAG
164 UNSPEC_FXAM_MEM
165
166 ;; SSP patterns
167 UNSPEC_SP_SET
168 UNSPEC_SP_TEST
169 UNSPEC_SP_TLS_SET
170 UNSPEC_SP_TLS_TEST
171
172 ;; For ROUND support
173 UNSPEC_ROUND
174
175 ;; For CRC32 support
176 UNSPEC_CRC32
177
178 ;; For RDRAND support
179 UNSPEC_RDRAND
180
181 ;; For BMI support
182 UNSPEC_BEXTR
183
184 ;; For BMI2 support
185 UNSPEC_PDEP
186 UNSPEC_PEXT
187 ])
188
189 (define_c_enum "unspecv" [
190 UNSPECV_BLOCKAGE
191 UNSPECV_STACK_PROBE
192 UNSPECV_PROBE_STACK_RANGE
193 UNSPECV_ALIGN
194 UNSPECV_PROLOGUE_USE
195 UNSPECV_SPLIT_STACK_RETURN
196 UNSPECV_CLD
197 UNSPECV_NOPS
198 UNSPECV_RDTSC
199 UNSPECV_RDTSCP
200 UNSPECV_RDPMC
201 UNSPECV_LLWP_INTRINSIC
202 UNSPECV_SLWP_INTRINSIC
203 UNSPECV_LWPVAL_INTRINSIC
204 UNSPECV_LWPINS_INTRINSIC
205 UNSPECV_RDFSBASE
206 UNSPECV_RDGSBASE
207 UNSPECV_WRFSBASE
208 UNSPECV_WRGSBASE
209 ])
210
211 ;; Constants to represent rounding modes in the ROUND instruction
212 (define_constants
213 [(ROUND_FLOOR 0x1)
214 (ROUND_CEIL 0x2)
215 (ROUND_TRUNC 0x3)
216 (ROUND_MXCSR 0x4)
217 (ROUND_NO_EXC 0x8)
218 ])
219
220 ;; Constants to represent pcomtrue/pcomfalse variants
221 (define_constants
222 [(PCOM_FALSE 0)
223 (PCOM_TRUE 1)
224 (COM_FALSE_S 2)
225 (COM_FALSE_P 3)
226 (COM_TRUE_S 4)
227 (COM_TRUE_P 5)
228 ])
229
230 ;; Constants used in the XOP pperm instruction
231 (define_constants
232 [(PPERM_SRC 0x00) /* copy source */
233 (PPERM_INVERT 0x20) /* invert source */
234 (PPERM_REVERSE 0x40) /* bit reverse source */
235 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
236 (PPERM_ZERO 0x80) /* all 0's */
237 (PPERM_ONES 0xa0) /* all 1's */
238 (PPERM_SIGN 0xc0) /* propagate sign bit */
239 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
240 (PPERM_SRC1 0x00) /* use first source byte */
241 (PPERM_SRC2 0x10) /* use second source byte */
242 ])
243
244 ;; Registers by name.
245 (define_constants
246 [(AX_REG 0)
247 (DX_REG 1)
248 (CX_REG 2)
249 (BX_REG 3)
250 (SI_REG 4)
251 (DI_REG 5)
252 (BP_REG 6)
253 (SP_REG 7)
254 (ST0_REG 8)
255 (ST1_REG 9)
256 (ST2_REG 10)
257 (ST3_REG 11)
258 (ST4_REG 12)
259 (ST5_REG 13)
260 (ST6_REG 14)
261 (ST7_REG 15)
262 (FLAGS_REG 17)
263 (FPSR_REG 18)
264 (FPCR_REG 19)
265 (XMM0_REG 21)
266 (XMM1_REG 22)
267 (XMM2_REG 23)
268 (XMM3_REG 24)
269 (XMM4_REG 25)
270 (XMM5_REG 26)
271 (XMM6_REG 27)
272 (XMM7_REG 28)
273 (MM0_REG 29)
274 (MM1_REG 30)
275 (MM2_REG 31)
276 (MM3_REG 32)
277 (MM4_REG 33)
278 (MM5_REG 34)
279 (MM6_REG 35)
280 (MM7_REG 36)
281 (R8_REG 37)
282 (R9_REG 38)
283 (R10_REG 39)
284 (R11_REG 40)
285 (R12_REG 41)
286 (R13_REG 42)
287 (XMM8_REG 45)
288 (XMM9_REG 46)
289 (XMM10_REG 47)
290 (XMM11_REG 48)
291 (XMM12_REG 49)
292 (XMM13_REG 50)
293 (XMM14_REG 51)
294 (XMM15_REG 52)
295 ])
296
297 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
298 ;; from i386.c.
299
300 ;; In C guard expressions, put expressions which may be compile-time
301 ;; constants first. This allows for better optimization. For
302 ;; example, write "TARGET_64BIT && reload_completed", not
303 ;; "reload_completed && TARGET_64BIT".
304
305 \f
306 ;; Processor type.
307 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
308 atom,generic64,amdfam10,bdver1,bdver2,btver1"
309 (const (symbol_ref "ix86_schedule")))
310
311 ;; A basic instruction type. Refinements due to arguments to be
312 ;; provided in other attributes.
313 (define_attr "type"
314 "other,multi,
315 alu,alu1,negnot,imov,imovx,lea,
316 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
317 icmp,test,ibr,setcc,icmov,
318 push,pop,call,callv,leave,
319 str,bitmanip,
320 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
321 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
322 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
323 ssemuladd,sse4arg,lwp,
324 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
325 (const_string "other"))
326
327 ;; Main data type used by the insn
328 (define_attr "mode"
329 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
330 (const_string "unknown"))
331
332 ;; The CPU unit operations uses.
333 (define_attr "unit" "integer,i387,sse,mmx,unknown"
334 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
335 (const_string "i387")
336 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
337 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
338 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
339 (const_string "sse")
340 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
341 (const_string "mmx")
342 (eq_attr "type" "other")
343 (const_string "unknown")]
344 (const_string "integer")))
345
346 ;; The (bounding maximum) length of an instruction immediate.
347 (define_attr "length_immediate" ""
348 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
349 bitmanip,imulx")
350 (const_int 0)
351 (eq_attr "unit" "i387,sse,mmx")
352 (const_int 0)
353 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
354 rotate,rotatex,rotate1,imul,icmp,push,pop")
355 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
356 (eq_attr "type" "imov,test")
357 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
358 (eq_attr "type" "call")
359 (if_then_else (match_operand 0 "constant_call_address_operand" "")
360 (const_int 4)
361 (const_int 0))
362 (eq_attr "type" "callv")
363 (if_then_else (match_operand 1 "constant_call_address_operand" "")
364 (const_int 4)
365 (const_int 0))
366 ;; We don't know the size before shorten_branches. Expect
367 ;; the instruction to fit for better scheduling.
368 (eq_attr "type" "ibr")
369 (const_int 1)
370 ]
371 (symbol_ref "/* Update immediate_length and other attributes! */
372 gcc_unreachable (),1")))
373
374 ;; The (bounding maximum) length of an instruction address.
375 (define_attr "length_address" ""
376 (cond [(eq_attr "type" "str,other,multi,fxch")
377 (const_int 0)
378 (and (eq_attr "type" "call")
379 (match_operand 0 "constant_call_address_operand" ""))
380 (const_int 0)
381 (and (eq_attr "type" "callv")
382 (match_operand 1 "constant_call_address_operand" ""))
383 (const_int 0)
384 ]
385 (symbol_ref "ix86_attr_length_address_default (insn)")))
386
387 ;; Set when length prefix is used.
388 (define_attr "prefix_data16" ""
389 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
390 (const_int 0)
391 (eq_attr "mode" "HI")
392 (const_int 1)
393 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
394 (const_int 1)
395 ]
396 (const_int 0)))
397
398 ;; Set when string REP prefix is used.
399 (define_attr "prefix_rep" ""
400 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
401 (const_int 0)
402 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
403 (const_int 1)
404 ]
405 (const_int 0)))
406
407 ;; Set when 0f opcode prefix is used.
408 (define_attr "prefix_0f" ""
409 (if_then_else
410 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
411 (eq_attr "unit" "sse,mmx"))
412 (const_int 1)
413 (const_int 0)))
414
415 ;; Set when REX opcode prefix is used.
416 (define_attr "prefix_rex" ""
417 (cond [(not (match_test "TARGET_64BIT"))
418 (const_int 0)
419 (and (eq_attr "mode" "DI")
420 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
421 (eq_attr "unit" "!mmx")))
422 (const_int 1)
423 (and (eq_attr "mode" "QI")
424 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
425 (const_int 1)
426 (match_test "x86_extended_reg_mentioned_p (insn)")
427 (const_int 1)
428 (and (eq_attr "type" "imovx")
429 (match_operand:QI 1 "ext_QIreg_operand" ""))
430 (const_int 1)
431 ]
432 (const_int 0)))
433
434 ;; There are also additional prefixes in 3DNOW, SSSE3.
435 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
436 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
437 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
438 (define_attr "prefix_extra" ""
439 (cond [(eq_attr "type" "ssemuladd,sse4arg")
440 (const_int 2)
441 (eq_attr "type" "sseiadd1,ssecvt1")
442 (const_int 1)
443 ]
444 (const_int 0)))
445
446 ;; Prefix used: original, VEX or maybe VEX.
447 (define_attr "prefix" "orig,vex,maybe_vex"
448 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
449 (const_string "vex")
450 (const_string "orig")))
451
452 ;; VEX W bit is used.
453 (define_attr "prefix_vex_w" "" (const_int 0))
454
455 ;; The length of VEX prefix
456 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
457 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
458 ;; still prefix_0f 1, with prefix_extra 1.
459 (define_attr "length_vex" ""
460 (if_then_else (and (eq_attr "prefix_0f" "1")
461 (eq_attr "prefix_extra" "0"))
462 (if_then_else (eq_attr "prefix_vex_w" "1")
463 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
464 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
465 (if_then_else (eq_attr "prefix_vex_w" "1")
466 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
467 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
468
469 ;; Set when modrm byte is used.
470 (define_attr "modrm" ""
471 (cond [(eq_attr "type" "str,leave")
472 (const_int 0)
473 (eq_attr "unit" "i387")
474 (const_int 0)
475 (and (eq_attr "type" "incdec")
476 (and (not (match_test "TARGET_64BIT"))
477 (ior (match_operand:SI 1 "register_operand" "")
478 (match_operand:HI 1 "register_operand" ""))))
479 (const_int 0)
480 (and (eq_attr "type" "push")
481 (not (match_operand 1 "memory_operand" "")))
482 (const_int 0)
483 (and (eq_attr "type" "pop")
484 (not (match_operand 0 "memory_operand" "")))
485 (const_int 0)
486 (and (eq_attr "type" "imov")
487 (and (not (eq_attr "mode" "DI"))
488 (ior (and (match_operand 0 "register_operand" "")
489 (match_operand 1 "immediate_operand" ""))
490 (ior (and (match_operand 0 "ax_reg_operand" "")
491 (match_operand 1 "memory_displacement_only_operand" ""))
492 (and (match_operand 0 "memory_displacement_only_operand" "")
493 (match_operand 1 "ax_reg_operand" ""))))))
494 (const_int 0)
495 (and (eq_attr "type" "call")
496 (match_operand 0 "constant_call_address_operand" ""))
497 (const_int 0)
498 (and (eq_attr "type" "callv")
499 (match_operand 1 "constant_call_address_operand" ""))
500 (const_int 0)
501 (and (eq_attr "type" "alu,alu1,icmp,test")
502 (match_operand 0 "ax_reg_operand" ""))
503 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
504 ]
505 (const_int 1)))
506
507 ;; The (bounding maximum) length of an instruction in bytes.
508 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
509 ;; Later we may want to split them and compute proper length as for
510 ;; other insns.
511 (define_attr "length" ""
512 (cond [(eq_attr "type" "other,multi,fistp,frndint")
513 (const_int 16)
514 (eq_attr "type" "fcmp")
515 (const_int 4)
516 (eq_attr "unit" "i387")
517 (plus (const_int 2)
518 (plus (attr "prefix_data16")
519 (attr "length_address")))
520 (ior (eq_attr "prefix" "vex")
521 (and (eq_attr "prefix" "maybe_vex")
522 (match_test "TARGET_AVX")))
523 (plus (attr "length_vex")
524 (plus (attr "length_immediate")
525 (plus (attr "modrm")
526 (attr "length_address"))))]
527 (plus (plus (attr "modrm")
528 (plus (attr "prefix_0f")
529 (plus (attr "prefix_rex")
530 (plus (attr "prefix_extra")
531 (const_int 1)))))
532 (plus (attr "prefix_rep")
533 (plus (attr "prefix_data16")
534 (plus (attr "length_immediate")
535 (attr "length_address")))))))
536
537 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
538 ;; `store' if there is a simple memory reference therein, or `unknown'
539 ;; if the instruction is complex.
540
541 (define_attr "memory" "none,load,store,both,unknown"
542 (cond [(eq_attr "type" "other,multi,str,lwp")
543 (const_string "unknown")
544 (eq_attr "type" "lea,fcmov,fpspc")
545 (const_string "none")
546 (eq_attr "type" "fistp,leave")
547 (const_string "both")
548 (eq_attr "type" "frndint")
549 (const_string "load")
550 (eq_attr "type" "push")
551 (if_then_else (match_operand 1 "memory_operand" "")
552 (const_string "both")
553 (const_string "store"))
554 (eq_attr "type" "pop")
555 (if_then_else (match_operand 0 "memory_operand" "")
556 (const_string "both")
557 (const_string "load"))
558 (eq_attr "type" "setcc")
559 (if_then_else (match_operand 0 "memory_operand" "")
560 (const_string "store")
561 (const_string "none"))
562 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
563 (if_then_else (ior (match_operand 0 "memory_operand" "")
564 (match_operand 1 "memory_operand" ""))
565 (const_string "load")
566 (const_string "none"))
567 (eq_attr "type" "ibr")
568 (if_then_else (match_operand 0 "memory_operand" "")
569 (const_string "load")
570 (const_string "none"))
571 (eq_attr "type" "call")
572 (if_then_else (match_operand 0 "constant_call_address_operand" "")
573 (const_string "none")
574 (const_string "load"))
575 (eq_attr "type" "callv")
576 (if_then_else (match_operand 1 "constant_call_address_operand" "")
577 (const_string "none")
578 (const_string "load"))
579 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
580 (match_operand 1 "memory_operand" ""))
581 (const_string "both")
582 (and (match_operand 0 "memory_operand" "")
583 (match_operand 1 "memory_operand" ""))
584 (const_string "both")
585 (match_operand 0 "memory_operand" "")
586 (const_string "store")
587 (match_operand 1 "memory_operand" "")
588 (const_string "load")
589 (and (eq_attr "type"
590 "!alu1,negnot,ishift1,
591 imov,imovx,icmp,test,bitmanip,
592 fmov,fcmp,fsgn,
593 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
594 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
595 (match_operand 2 "memory_operand" ""))
596 (const_string "load")
597 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
598 (match_operand 3 "memory_operand" ""))
599 (const_string "load")
600 ]
601 (const_string "none")))
602
603 ;; Indicates if an instruction has both an immediate and a displacement.
604
605 (define_attr "imm_disp" "false,true,unknown"
606 (cond [(eq_attr "type" "other,multi")
607 (const_string "unknown")
608 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
609 (and (match_operand 0 "memory_displacement_operand" "")
610 (match_operand 1 "immediate_operand" "")))
611 (const_string "true")
612 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
613 (and (match_operand 0 "memory_displacement_operand" "")
614 (match_operand 2 "immediate_operand" "")))
615 (const_string "true")
616 ]
617 (const_string "false")))
618
619 ;; Indicates if an FP operation has an integer source.
620
621 (define_attr "fp_int_src" "false,true"
622 (const_string "false"))
623
624 ;; Defines rounding mode of an FP operation.
625
626 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
627 (const_string "any"))
628
629 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
630 (define_attr "use_carry" "0,1" (const_string "0"))
631
632 ;; Define attribute to indicate unaligned ssemov insns
633 (define_attr "movu" "0,1" (const_string "0"))
634
635 ;; Used to control the "enabled" attribute on a per-instruction basis.
636 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
637 (const_string "base"))
638
639 (define_attr "enabled" ""
640 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
641 (eq_attr "isa" "sse2_noavx")
642 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
643 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
644 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
645 (eq_attr "isa" "sse4_noavx")
646 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
647 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
648 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
649 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
650 ]
651 (const_int 1)))
652
653 ;; Describe a user's asm statement.
654 (define_asm_attributes
655 [(set_attr "length" "128")
656 (set_attr "type" "multi")])
657
658 (define_code_iterator plusminus [plus minus])
659
660 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
661
662 ;; Base name for define_insn
663 (define_code_attr plusminus_insn
664 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
665 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
666
667 ;; Base name for insn mnemonic.
668 (define_code_attr plusminus_mnemonic
669 [(plus "add") (ss_plus "adds") (us_plus "addus")
670 (minus "sub") (ss_minus "subs") (us_minus "subus")])
671 (define_code_attr plusminus_carry_mnemonic
672 [(plus "adc") (minus "sbb")])
673
674 ;; Mark commutative operators as such in constraints.
675 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
676 (minus "") (ss_minus "") (us_minus "")])
677
678 ;; Mapping of max and min
679 (define_code_iterator maxmin [smax smin umax umin])
680
681 ;; Mapping of signed max and min
682 (define_code_iterator smaxmin [smax smin])
683
684 ;; Mapping of unsigned max and min
685 (define_code_iterator umaxmin [umax umin])
686
687 ;; Base name for integer and FP insn mnemonic
688 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
689 (umax "maxu") (umin "minu")])
690 (define_code_attr maxmin_float [(smax "max") (smin "min")])
691
692 ;; Mapping of logic operators
693 (define_code_iterator any_logic [and ior xor])
694 (define_code_iterator any_or [ior xor])
695
696 ;; Base name for insn mnemonic.
697 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
698
699 ;; Mapping of logic-shift operators
700 (define_code_iterator any_lshift [ashift lshiftrt])
701
702 ;; Mapping of shift-right operators
703 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
704
705 ;; Base name for define_insn
706 (define_code_attr shift_insn
707 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
708
709 ;; Base name for insn mnemonic.
710 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
711 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
712
713 ;; Mapping of rotate operators
714 (define_code_iterator any_rotate [rotate rotatert])
715
716 ;; Base name for define_insn
717 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
718
719 ;; Base name for insn mnemonic.
720 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
721
722 ;; Mapping of abs neg operators
723 (define_code_iterator absneg [abs neg])
724
725 ;; Base name for x87 insn mnemonic.
726 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
727
728 ;; Used in signed and unsigned widening multiplications.
729 (define_code_iterator any_extend [sign_extend zero_extend])
730
731 ;; Prefix for insn menmonic.
732 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
733
734 ;; Prefix for define_insn
735 (define_code_attr u [(sign_extend "") (zero_extend "u")])
736 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
737
738 ;; All integer modes.
739 (define_mode_iterator SWI1248x [QI HI SI DI])
740
741 ;; All integer modes without QImode.
742 (define_mode_iterator SWI248x [HI SI DI])
743
744 ;; All integer modes without QImode and HImode.
745 (define_mode_iterator SWI48x [SI DI])
746
747 ;; All integer modes without SImode and DImode.
748 (define_mode_iterator SWI12 [QI HI])
749
750 ;; All integer modes without DImode.
751 (define_mode_iterator SWI124 [QI HI SI])
752
753 ;; All integer modes without QImode and DImode.
754 (define_mode_iterator SWI24 [HI SI])
755
756 ;; Single word integer modes.
757 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
758
759 ;; Single word integer modes without QImode.
760 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
761
762 ;; Single word integer modes without QImode and HImode.
763 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
764
765 ;; All math-dependant single and double word integer modes.
766 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
767 (HI "TARGET_HIMODE_MATH")
768 SI DI (TI "TARGET_64BIT")])
769
770 ;; Math-dependant single word integer modes.
771 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
772 (HI "TARGET_HIMODE_MATH")
773 SI (DI "TARGET_64BIT")])
774
775 ;; Math-dependant integer modes without DImode.
776 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
777 (HI "TARGET_HIMODE_MATH")
778 SI])
779
780 ;; Math-dependant single word integer modes without QImode.
781 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
782 SI (DI "TARGET_64BIT")])
783
784 ;; Double word integer modes.
785 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
786 (TI "TARGET_64BIT")])
787
788 ;; Double word integer modes as mode attribute.
789 (define_mode_attr DWI [(SI "DI") (DI "TI")])
790 (define_mode_attr dwi [(SI "di") (DI "ti")])
791
792 ;; Half mode for double word integer modes.
793 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
794 (DI "TARGET_64BIT")])
795
796 ;; Instruction suffix for integer modes.
797 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
798
799 ;; Pointer size prefix for integer modes (Intel asm dialect)
800 (define_mode_attr iptrsize [(QI "BYTE")
801 (HI "WORD")
802 (SI "DWORD")
803 (DI "QWORD")])
804
805 ;; Register class for integer modes.
806 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
807
808 ;; Immediate operand constraint for integer modes.
809 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
810
811 ;; General operand constraint for word modes.
812 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
813
814 ;; Immediate operand constraint for double integer modes.
815 (define_mode_attr di [(SI "nF") (DI "e")])
816
817 ;; Immediate operand constraint for shifts.
818 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
819
820 ;; General operand predicate for integer modes.
821 (define_mode_attr general_operand
822 [(QI "general_operand")
823 (HI "general_operand")
824 (SI "x86_64_general_operand")
825 (DI "x86_64_general_operand")
826 (TI "x86_64_general_operand")])
827
828 ;; General sign/zero extend operand predicate for integer modes.
829 (define_mode_attr general_szext_operand
830 [(QI "general_operand")
831 (HI "general_operand")
832 (SI "x86_64_szext_general_operand")
833 (DI "x86_64_szext_general_operand")])
834
835 ;; Immediate operand predicate for integer modes.
836 (define_mode_attr immediate_operand
837 [(QI "immediate_operand")
838 (HI "immediate_operand")
839 (SI "x86_64_immediate_operand")
840 (DI "x86_64_immediate_operand")])
841
842 ;; Nonmemory operand predicate for integer modes.
843 (define_mode_attr nonmemory_operand
844 [(QI "nonmemory_operand")
845 (HI "nonmemory_operand")
846 (SI "x86_64_nonmemory_operand")
847 (DI "x86_64_nonmemory_operand")])
848
849 ;; Operand predicate for shifts.
850 (define_mode_attr shift_operand
851 [(QI "nonimmediate_operand")
852 (HI "nonimmediate_operand")
853 (SI "nonimmediate_operand")
854 (DI "shiftdi_operand")
855 (TI "register_operand")])
856
857 ;; Operand predicate for shift argument.
858 (define_mode_attr shift_immediate_operand
859 [(QI "const_1_to_31_operand")
860 (HI "const_1_to_31_operand")
861 (SI "const_1_to_31_operand")
862 (DI "const_1_to_63_operand")])
863
864 ;; Input operand predicate for arithmetic left shifts.
865 (define_mode_attr ashl_input_operand
866 [(QI "nonimmediate_operand")
867 (HI "nonimmediate_operand")
868 (SI "nonimmediate_operand")
869 (DI "ashldi_input_operand")
870 (TI "reg_or_pm1_operand")])
871
872 ;; SSE and x87 SFmode and DFmode floating point modes
873 (define_mode_iterator MODEF [SF DF])
874
875 ;; All x87 floating point modes
876 (define_mode_iterator X87MODEF [SF DF XF])
877
878 ;; SSE instruction suffix for various modes
879 (define_mode_attr ssemodesuffix
880 [(SF "ss") (DF "sd")
881 (V8SF "ps") (V4DF "pd")
882 (V4SF "ps") (V2DF "pd")
883 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
884 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
885
886 ;; SSE vector suffix for floating point modes
887 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
888
889 ;; SSE vector mode corresponding to a scalar mode
890 (define_mode_attr ssevecmode
891 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
892
893 ;; Instruction suffix for REX 64bit operators.
894 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
895
896 ;; This mode iterator allows :P to be used for patterns that operate on
897 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
898 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
899
900 ;; This mode iterator allows :W to be used for patterns that operate on
901 ;; word_mode sized quantities.
902 (define_mode_iterator W
903 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
904
905 ;; This mode iterator allows :PTR to be used for patterns that operate on
906 ;; ptr_mode sized quantities.
907 (define_mode_iterator PTR
908 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
909 \f
910 ;; Scheduling descriptions
911
912 (include "pentium.md")
913 (include "ppro.md")
914 (include "k6.md")
915 (include "athlon.md")
916 (include "bdver1.md")
917 (include "geode.md")
918 (include "atom.md")
919 (include "core2.md")
920
921 \f
922 ;; Operand and operator predicates and constraints
923
924 (include "predicates.md")
925 (include "constraints.md")
926
927 \f
928 ;; Compare and branch/compare and store instructions.
929
930 (define_expand "cbranch<mode>4"
931 [(set (reg:CC FLAGS_REG)
932 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
933 (match_operand:SDWIM 2 "<general_operand>" "")))
934 (set (pc) (if_then_else
935 (match_operator 0 "ordered_comparison_operator"
936 [(reg:CC FLAGS_REG) (const_int 0)])
937 (label_ref (match_operand 3 "" ""))
938 (pc)))]
939 ""
940 {
941 if (MEM_P (operands[1]) && MEM_P (operands[2]))
942 operands[1] = force_reg (<MODE>mode, operands[1]);
943 ix86_expand_branch (GET_CODE (operands[0]),
944 operands[1], operands[2], operands[3]);
945 DONE;
946 })
947
948 (define_expand "cstore<mode>4"
949 [(set (reg:CC FLAGS_REG)
950 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
951 (match_operand:SWIM 3 "<general_operand>" "")))
952 (set (match_operand:QI 0 "register_operand" "")
953 (match_operator 1 "ordered_comparison_operator"
954 [(reg:CC FLAGS_REG) (const_int 0)]))]
955 ""
956 {
957 if (MEM_P (operands[2]) && MEM_P (operands[3]))
958 operands[2] = force_reg (<MODE>mode, operands[2]);
959 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
960 operands[2], operands[3]);
961 DONE;
962 })
963
964 (define_expand "cmp<mode>_1"
965 [(set (reg:CC FLAGS_REG)
966 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
967 (match_operand:SWI48 1 "<general_operand>" "")))])
968
969 (define_insn "*cmp<mode>_ccno_1"
970 [(set (reg FLAGS_REG)
971 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
972 (match_operand:SWI 1 "const0_operand" "")))]
973 "ix86_match_ccmode (insn, CCNOmode)"
974 "@
975 test{<imodesuffix>}\t%0, %0
976 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977 [(set_attr "type" "test,icmp")
978 (set_attr "length_immediate" "0,1")
979 (set_attr "mode" "<MODE>")])
980
981 (define_insn "*cmp<mode>_1"
982 [(set (reg FLAGS_REG)
983 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
985 "ix86_match_ccmode (insn, CCmode)"
986 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987 [(set_attr "type" "icmp")
988 (set_attr "mode" "<MODE>")])
989
990 (define_insn "*cmp<mode>_minus_1"
991 [(set (reg FLAGS_REG)
992 (compare
993 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
995 (const_int 0)))]
996 "ix86_match_ccmode (insn, CCGOCmode)"
997 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "<MODE>")])
1000
1001 (define_insn "*cmpqi_ext_1"
1002 [(set (reg FLAGS_REG)
1003 (compare
1004 (match_operand:QI 0 "general_operand" "Qm")
1005 (subreg:QI
1006 (zero_extract:SI
1007 (match_operand 1 "ext_register_operand" "Q")
1008 (const_int 8)
1009 (const_int 8)) 0)))]
1010 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011 "cmp{b}\t{%h1, %0|%0, %h1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "QI")])
1014
1015 (define_insn "*cmpqi_ext_1_rex64"
1016 [(set (reg FLAGS_REG)
1017 (compare
1018 (match_operand:QI 0 "register_operand" "Q")
1019 (subreg:QI
1020 (zero_extract:SI
1021 (match_operand 1 "ext_register_operand" "Q")
1022 (const_int 8)
1023 (const_int 8)) 0)))]
1024 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1025 "cmp{b}\t{%h1, %0|%0, %h1}"
1026 [(set_attr "type" "icmp")
1027 (set_attr "mode" "QI")])
1028
1029 (define_insn "*cmpqi_ext_2"
1030 [(set (reg FLAGS_REG)
1031 (compare
1032 (subreg:QI
1033 (zero_extract:SI
1034 (match_operand 0 "ext_register_operand" "Q")
1035 (const_int 8)
1036 (const_int 8)) 0)
1037 (match_operand:QI 1 "const0_operand" "")))]
1038 "ix86_match_ccmode (insn, CCNOmode)"
1039 "test{b}\t%h0, %h0"
1040 [(set_attr "type" "test")
1041 (set_attr "length_immediate" "0")
1042 (set_attr "mode" "QI")])
1043
1044 (define_expand "cmpqi_ext_3"
1045 [(set (reg:CC FLAGS_REG)
1046 (compare:CC
1047 (subreg:QI
1048 (zero_extract:SI
1049 (match_operand 0 "ext_register_operand" "")
1050 (const_int 8)
1051 (const_int 8)) 0)
1052 (match_operand:QI 1 "immediate_operand" "")))])
1053
1054 (define_insn "*cmpqi_ext_3_insn"
1055 [(set (reg FLAGS_REG)
1056 (compare
1057 (subreg:QI
1058 (zero_extract:SI
1059 (match_operand 0 "ext_register_operand" "Q")
1060 (const_int 8)
1061 (const_int 8)) 0)
1062 (match_operand:QI 1 "general_operand" "Qmn")))]
1063 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1064 "cmp{b}\t{%1, %h0|%h0, %1}"
1065 [(set_attr "type" "icmp")
1066 (set_attr "modrm" "1")
1067 (set_attr "mode" "QI")])
1068
1069 (define_insn "*cmpqi_ext_3_insn_rex64"
1070 [(set (reg FLAGS_REG)
1071 (compare
1072 (subreg:QI
1073 (zero_extract:SI
1074 (match_operand 0 "ext_register_operand" "Q")
1075 (const_int 8)
1076 (const_int 8)) 0)
1077 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1078 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1079 "cmp{b}\t{%1, %h0|%h0, %1}"
1080 [(set_attr "type" "icmp")
1081 (set_attr "modrm" "1")
1082 (set_attr "mode" "QI")])
1083
1084 (define_insn "*cmpqi_ext_4"
1085 [(set (reg FLAGS_REG)
1086 (compare
1087 (subreg:QI
1088 (zero_extract:SI
1089 (match_operand 0 "ext_register_operand" "Q")
1090 (const_int 8)
1091 (const_int 8)) 0)
1092 (subreg:QI
1093 (zero_extract:SI
1094 (match_operand 1 "ext_register_operand" "Q")
1095 (const_int 8)
1096 (const_int 8)) 0)))]
1097 "ix86_match_ccmode (insn, CCmode)"
1098 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1099 [(set_attr "type" "icmp")
1100 (set_attr "mode" "QI")])
1101
1102 ;; These implement float point compares.
1103 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1104 ;; which would allow mix and match FP modes on the compares. Which is what
1105 ;; the old patterns did, but with many more of them.
1106
1107 (define_expand "cbranchxf4"
1108 [(set (reg:CC FLAGS_REG)
1109 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1110 (match_operand:XF 2 "nonmemory_operand" "")))
1111 (set (pc) (if_then_else
1112 (match_operator 0 "ix86_fp_comparison_operator"
1113 [(reg:CC FLAGS_REG)
1114 (const_int 0)])
1115 (label_ref (match_operand 3 "" ""))
1116 (pc)))]
1117 "TARGET_80387"
1118 {
1119 ix86_expand_branch (GET_CODE (operands[0]),
1120 operands[1], operands[2], operands[3]);
1121 DONE;
1122 })
1123
1124 (define_expand "cstorexf4"
1125 [(set (reg:CC FLAGS_REG)
1126 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1127 (match_operand:XF 3 "nonmemory_operand" "")))
1128 (set (match_operand:QI 0 "register_operand" "")
1129 (match_operator 1 "ix86_fp_comparison_operator"
1130 [(reg:CC FLAGS_REG)
1131 (const_int 0)]))]
1132 "TARGET_80387"
1133 {
1134 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1135 operands[2], operands[3]);
1136 DONE;
1137 })
1138
1139 (define_expand "cbranch<mode>4"
1140 [(set (reg:CC FLAGS_REG)
1141 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1142 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1143 (set (pc) (if_then_else
1144 (match_operator 0 "ix86_fp_comparison_operator"
1145 [(reg:CC FLAGS_REG)
1146 (const_int 0)])
1147 (label_ref (match_operand 3 "" ""))
1148 (pc)))]
1149 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1150 {
1151 ix86_expand_branch (GET_CODE (operands[0]),
1152 operands[1], operands[2], operands[3]);
1153 DONE;
1154 })
1155
1156 (define_expand "cstore<mode>4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1159 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1160 (set (match_operand:QI 0 "register_operand" "")
1161 (match_operator 1 "ix86_fp_comparison_operator"
1162 [(reg:CC FLAGS_REG)
1163 (const_int 0)]))]
1164 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1165 {
1166 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1167 operands[2], operands[3]);
1168 DONE;
1169 })
1170
1171 (define_expand "cbranchcc4"
1172 [(set (pc) (if_then_else
1173 (match_operator 0 "comparison_operator"
1174 [(match_operand 1 "flags_reg_operand" "")
1175 (match_operand 2 "const0_operand" "")])
1176 (label_ref (match_operand 3 "" ""))
1177 (pc)))]
1178 ""
1179 {
1180 ix86_expand_branch (GET_CODE (operands[0]),
1181 operands[1], operands[2], operands[3]);
1182 DONE;
1183 })
1184
1185 (define_expand "cstorecc4"
1186 [(set (match_operand:QI 0 "register_operand" "")
1187 (match_operator 1 "comparison_operator"
1188 [(match_operand 2 "flags_reg_operand" "")
1189 (match_operand 3 "const0_operand" "")]))]
1190 ""
1191 {
1192 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1193 operands[2], operands[3]);
1194 DONE;
1195 })
1196
1197
1198 ;; FP compares, step 1:
1199 ;; Set the FP condition codes.
1200 ;;
1201 ;; CCFPmode compare with exceptions
1202 ;; CCFPUmode compare with no exceptions
1203
1204 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1205 ;; used to manage the reg stack popping would not be preserved.
1206
1207 (define_insn "*cmpfp_0"
1208 [(set (match_operand:HI 0 "register_operand" "=a")
1209 (unspec:HI
1210 [(compare:CCFP
1211 (match_operand 1 "register_operand" "f")
1212 (match_operand 2 "const0_operand" ""))]
1213 UNSPEC_FNSTSW))]
1214 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1215 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1216 "* return output_fp_compare (insn, operands, false, false);"
1217 [(set_attr "type" "multi")
1218 (set_attr "unit" "i387")
1219 (set (attr "mode")
1220 (cond [(match_operand:SF 1 "" "")
1221 (const_string "SF")
1222 (match_operand:DF 1 "" "")
1223 (const_string "DF")
1224 ]
1225 (const_string "XF")))])
1226
1227 (define_insn_and_split "*cmpfp_0_cc"
1228 [(set (reg:CCFP FLAGS_REG)
1229 (compare:CCFP
1230 (match_operand 1 "register_operand" "f")
1231 (match_operand 2 "const0_operand" "")))
1232 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1233 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1234 && TARGET_SAHF && !TARGET_CMOVE
1235 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1236 "#"
1237 "&& reload_completed"
1238 [(set (match_dup 0)
1239 (unspec:HI
1240 [(compare:CCFP (match_dup 1)(match_dup 2))]
1241 UNSPEC_FNSTSW))
1242 (set (reg:CC FLAGS_REG)
1243 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1244 ""
1245 [(set_attr "type" "multi")
1246 (set_attr "unit" "i387")
1247 (set (attr "mode")
1248 (cond [(match_operand:SF 1 "" "")
1249 (const_string "SF")
1250 (match_operand:DF 1 "" "")
1251 (const_string "DF")
1252 ]
1253 (const_string "XF")))])
1254
1255 (define_insn "*cmpfp_xf"
1256 [(set (match_operand:HI 0 "register_operand" "=a")
1257 (unspec:HI
1258 [(compare:CCFP
1259 (match_operand:XF 1 "register_operand" "f")
1260 (match_operand:XF 2 "register_operand" "f"))]
1261 UNSPEC_FNSTSW))]
1262 "TARGET_80387"
1263 "* return output_fp_compare (insn, operands, false, false);"
1264 [(set_attr "type" "multi")
1265 (set_attr "unit" "i387")
1266 (set_attr "mode" "XF")])
1267
1268 (define_insn_and_split "*cmpfp_xf_cc"
1269 [(set (reg:CCFP FLAGS_REG)
1270 (compare:CCFP
1271 (match_operand:XF 1 "register_operand" "f")
1272 (match_operand:XF 2 "register_operand" "f")))
1273 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1274 "TARGET_80387
1275 && TARGET_SAHF && !TARGET_CMOVE"
1276 "#"
1277 "&& reload_completed"
1278 [(set (match_dup 0)
1279 (unspec:HI
1280 [(compare:CCFP (match_dup 1)(match_dup 2))]
1281 UNSPEC_FNSTSW))
1282 (set (reg:CC FLAGS_REG)
1283 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1284 ""
1285 [(set_attr "type" "multi")
1286 (set_attr "unit" "i387")
1287 (set_attr "mode" "XF")])
1288
1289 (define_insn "*cmpfp_<mode>"
1290 [(set (match_operand:HI 0 "register_operand" "=a")
1291 (unspec:HI
1292 [(compare:CCFP
1293 (match_operand:MODEF 1 "register_operand" "f")
1294 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1295 UNSPEC_FNSTSW))]
1296 "TARGET_80387"
1297 "* return output_fp_compare (insn, operands, false, false);"
1298 [(set_attr "type" "multi")
1299 (set_attr "unit" "i387")
1300 (set_attr "mode" "<MODE>")])
1301
1302 (define_insn_and_split "*cmpfp_<mode>_cc"
1303 [(set (reg:CCFP FLAGS_REG)
1304 (compare:CCFP
1305 (match_operand:MODEF 1 "register_operand" "f")
1306 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1307 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1308 "TARGET_80387
1309 && TARGET_SAHF && !TARGET_CMOVE"
1310 "#"
1311 "&& reload_completed"
1312 [(set (match_dup 0)
1313 (unspec:HI
1314 [(compare:CCFP (match_dup 1)(match_dup 2))]
1315 UNSPEC_FNSTSW))
1316 (set (reg:CC FLAGS_REG)
1317 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1318 ""
1319 [(set_attr "type" "multi")
1320 (set_attr "unit" "i387")
1321 (set_attr "mode" "<MODE>")])
1322
1323 (define_insn "*cmpfp_u"
1324 [(set (match_operand:HI 0 "register_operand" "=a")
1325 (unspec:HI
1326 [(compare:CCFPU
1327 (match_operand 1 "register_operand" "f")
1328 (match_operand 2 "register_operand" "f"))]
1329 UNSPEC_FNSTSW))]
1330 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1331 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1332 "* return output_fp_compare (insn, operands, false, true);"
1333 [(set_attr "type" "multi")
1334 (set_attr "unit" "i387")
1335 (set (attr "mode")
1336 (cond [(match_operand:SF 1 "" "")
1337 (const_string "SF")
1338 (match_operand:DF 1 "" "")
1339 (const_string "DF")
1340 ]
1341 (const_string "XF")))])
1342
1343 (define_insn_and_split "*cmpfp_u_cc"
1344 [(set (reg:CCFPU FLAGS_REG)
1345 (compare:CCFPU
1346 (match_operand 1 "register_operand" "f")
1347 (match_operand 2 "register_operand" "f")))
1348 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1349 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1350 && TARGET_SAHF && !TARGET_CMOVE
1351 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1352 "#"
1353 "&& reload_completed"
1354 [(set (match_dup 0)
1355 (unspec:HI
1356 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1357 UNSPEC_FNSTSW))
1358 (set (reg:CC FLAGS_REG)
1359 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1360 ""
1361 [(set_attr "type" "multi")
1362 (set_attr "unit" "i387")
1363 (set (attr "mode")
1364 (cond [(match_operand:SF 1 "" "")
1365 (const_string "SF")
1366 (match_operand:DF 1 "" "")
1367 (const_string "DF")
1368 ]
1369 (const_string "XF")))])
1370
1371 (define_insn "*cmpfp_<mode>"
1372 [(set (match_operand:HI 0 "register_operand" "=a")
1373 (unspec:HI
1374 [(compare:CCFP
1375 (match_operand 1 "register_operand" "f")
1376 (match_operator 3 "float_operator"
1377 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1378 UNSPEC_FNSTSW))]
1379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1381 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1382 "* return output_fp_compare (insn, operands, false, false);"
1383 [(set_attr "type" "multi")
1384 (set_attr "unit" "i387")
1385 (set_attr "fp_int_src" "true")
1386 (set_attr "mode" "<MODE>")])
1387
1388 (define_insn_and_split "*cmpfp_<mode>_cc"
1389 [(set (reg:CCFP FLAGS_REG)
1390 (compare:CCFP
1391 (match_operand 1 "register_operand" "f")
1392 (match_operator 3 "float_operator"
1393 [(match_operand:SWI24 2 "memory_operand" "m")])))
1394 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1395 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1396 && TARGET_SAHF && !TARGET_CMOVE
1397 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1398 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1399 "#"
1400 "&& reload_completed"
1401 [(set (match_dup 0)
1402 (unspec:HI
1403 [(compare:CCFP
1404 (match_dup 1)
1405 (match_op_dup 3 [(match_dup 2)]))]
1406 UNSPEC_FNSTSW))
1407 (set (reg:CC FLAGS_REG)
1408 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1409 ""
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1412 (set_attr "fp_int_src" "true")
1413 (set_attr "mode" "<MODE>")])
1414
1415 ;; FP compares, step 2
1416 ;; Move the fpsw to ax.
1417
1418 (define_insn "x86_fnstsw_1"
1419 [(set (match_operand:HI 0 "register_operand" "=a")
1420 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1421 "TARGET_80387"
1422 "fnstsw\t%0"
1423 [(set (attr "length")
1424 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1425 (set_attr "mode" "SI")
1426 (set_attr "unit" "i387")])
1427
1428 ;; FP compares, step 3
1429 ;; Get ax into flags, general case.
1430
1431 (define_insn "x86_sahf_1"
1432 [(set (reg:CC FLAGS_REG)
1433 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1434 UNSPEC_SAHF))]
1435 "TARGET_SAHF"
1436 {
1437 #ifndef HAVE_AS_IX86_SAHF
1438 if (TARGET_64BIT)
1439 return ASM_BYTE "0x9e";
1440 else
1441 #endif
1442 return "sahf";
1443 }
1444 [(set_attr "length" "1")
1445 (set_attr "athlon_decode" "vector")
1446 (set_attr "amdfam10_decode" "direct")
1447 (set_attr "bdver1_decode" "direct")
1448 (set_attr "mode" "SI")])
1449
1450 ;; Pentium Pro can do steps 1 through 3 in one go.
1451 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1452 ;; (these i387 instructions set flags directly)
1453 (define_insn "*cmpfp_i_mixed"
1454 [(set (reg:CCFP FLAGS_REG)
1455 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1456 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1457 "TARGET_MIX_SSE_I387
1458 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1459 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1460 "* return output_fp_compare (insn, operands, true, false);"
1461 [(set_attr "type" "fcmp,ssecomi")
1462 (set_attr "prefix" "orig,maybe_vex")
1463 (set (attr "mode")
1464 (if_then_else (match_operand:SF 1 "" "")
1465 (const_string "SF")
1466 (const_string "DF")))
1467 (set (attr "prefix_rep")
1468 (if_then_else (eq_attr "type" "ssecomi")
1469 (const_string "0")
1470 (const_string "*")))
1471 (set (attr "prefix_data16")
1472 (cond [(eq_attr "type" "fcmp")
1473 (const_string "*")
1474 (eq_attr "mode" "DF")
1475 (const_string "1")
1476 ]
1477 (const_string "0")))
1478 (set_attr "athlon_decode" "vector")
1479 (set_attr "amdfam10_decode" "direct")
1480 (set_attr "bdver1_decode" "double")])
1481
1482 (define_insn "*cmpfp_i_sse"
1483 [(set (reg:CCFP FLAGS_REG)
1484 (compare:CCFP (match_operand 0 "register_operand" "x")
1485 (match_operand 1 "nonimmediate_operand" "xm")))]
1486 "TARGET_SSE_MATH
1487 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1488 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1489 "* return output_fp_compare (insn, operands, true, false);"
1490 [(set_attr "type" "ssecomi")
1491 (set_attr "prefix" "maybe_vex")
1492 (set (attr "mode")
1493 (if_then_else (match_operand:SF 1 "" "")
1494 (const_string "SF")
1495 (const_string "DF")))
1496 (set_attr "prefix_rep" "0")
1497 (set (attr "prefix_data16")
1498 (if_then_else (eq_attr "mode" "DF")
1499 (const_string "1")
1500 (const_string "0")))
1501 (set_attr "athlon_decode" "vector")
1502 (set_attr "amdfam10_decode" "direct")
1503 (set_attr "bdver1_decode" "double")])
1504
1505 (define_insn "*cmpfp_i_i387"
1506 [(set (reg:CCFP FLAGS_REG)
1507 (compare:CCFP (match_operand 0 "register_operand" "f")
1508 (match_operand 1 "register_operand" "f")))]
1509 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1510 && TARGET_CMOVE
1511 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1512 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1513 "* return output_fp_compare (insn, operands, true, false);"
1514 [(set_attr "type" "fcmp")
1515 (set (attr "mode")
1516 (cond [(match_operand:SF 1 "" "")
1517 (const_string "SF")
1518 (match_operand:DF 1 "" "")
1519 (const_string "DF")
1520 ]
1521 (const_string "XF")))
1522 (set_attr "athlon_decode" "vector")
1523 (set_attr "amdfam10_decode" "direct")
1524 (set_attr "bdver1_decode" "double")])
1525
1526 (define_insn "*cmpfp_iu_mixed"
1527 [(set (reg:CCFPU FLAGS_REG)
1528 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1529 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1530 "TARGET_MIX_SSE_I387
1531 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1532 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1533 "* return output_fp_compare (insn, operands, true, true);"
1534 [(set_attr "type" "fcmp,ssecomi")
1535 (set_attr "prefix" "orig,maybe_vex")
1536 (set (attr "mode")
1537 (if_then_else (match_operand:SF 1 "" "")
1538 (const_string "SF")
1539 (const_string "DF")))
1540 (set (attr "prefix_rep")
1541 (if_then_else (eq_attr "type" "ssecomi")
1542 (const_string "0")
1543 (const_string "*")))
1544 (set (attr "prefix_data16")
1545 (cond [(eq_attr "type" "fcmp")
1546 (const_string "*")
1547 (eq_attr "mode" "DF")
1548 (const_string "1")
1549 ]
1550 (const_string "0")))
1551 (set_attr "athlon_decode" "vector")
1552 (set_attr "amdfam10_decode" "direct")
1553 (set_attr "bdver1_decode" "double")])
1554
1555 (define_insn "*cmpfp_iu_sse"
1556 [(set (reg:CCFPU FLAGS_REG)
1557 (compare:CCFPU (match_operand 0 "register_operand" "x")
1558 (match_operand 1 "nonimmediate_operand" "xm")))]
1559 "TARGET_SSE_MATH
1560 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1561 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1562 "* return output_fp_compare (insn, operands, true, true);"
1563 [(set_attr "type" "ssecomi")
1564 (set_attr "prefix" "maybe_vex")
1565 (set (attr "mode")
1566 (if_then_else (match_operand:SF 1 "" "")
1567 (const_string "SF")
1568 (const_string "DF")))
1569 (set_attr "prefix_rep" "0")
1570 (set (attr "prefix_data16")
1571 (if_then_else (eq_attr "mode" "DF")
1572 (const_string "1")
1573 (const_string "0")))
1574 (set_attr "athlon_decode" "vector")
1575 (set_attr "amdfam10_decode" "direct")
1576 (set_attr "bdver1_decode" "double")])
1577
1578 (define_insn "*cmpfp_iu_387"
1579 [(set (reg:CCFPU FLAGS_REG)
1580 (compare:CCFPU (match_operand 0 "register_operand" "f")
1581 (match_operand 1 "register_operand" "f")))]
1582 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1583 && TARGET_CMOVE
1584 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1585 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1586 "* return output_fp_compare (insn, operands, true, true);"
1587 [(set_attr "type" "fcmp")
1588 (set (attr "mode")
1589 (cond [(match_operand:SF 1 "" "")
1590 (const_string "SF")
1591 (match_operand:DF 1 "" "")
1592 (const_string "DF")
1593 ]
1594 (const_string "XF")))
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "direct")
1597 (set_attr "bdver1_decode" "direct")])
1598 \f
1599 ;; Push/pop instructions.
1600
1601 (define_insn "*push<mode>2"
1602 [(set (match_operand:DWI 0 "push_operand" "=<")
1603 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1604 ""
1605 "#"
1606 [(set_attr "type" "multi")
1607 (set_attr "mode" "<MODE>")])
1608
1609 (define_split
1610 [(set (match_operand:TI 0 "push_operand" "")
1611 (match_operand:TI 1 "general_operand" ""))]
1612 "TARGET_64BIT && reload_completed
1613 && !SSE_REG_P (operands[1])"
1614 [(const_int 0)]
1615 "ix86_split_long_move (operands); DONE;")
1616
1617 (define_insn "*pushdi2_rex64"
1618 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1619 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1620 "TARGET_64BIT"
1621 "@
1622 push{q}\t%1
1623 #"
1624 [(set_attr "type" "push,multi")
1625 (set_attr "mode" "DI")])
1626
1627 ;; Convert impossible pushes of immediate to existing instructions.
1628 ;; First try to get scratch register and go through it. In case this
1629 ;; fails, push sign extended lower part first and then overwrite
1630 ;; upper part by 32bit move.
1631 (define_peephole2
1632 [(match_scratch:DI 2 "r")
1633 (set (match_operand:DI 0 "push_operand" "")
1634 (match_operand:DI 1 "immediate_operand" ""))]
1635 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1636 && !x86_64_immediate_operand (operands[1], DImode)"
1637 [(set (match_dup 2) (match_dup 1))
1638 (set (match_dup 0) (match_dup 2))])
1639
1640 ;; We need to define this as both peepholer and splitter for case
1641 ;; peephole2 pass is not run.
1642 ;; "&& 1" is needed to keep it from matching the previous pattern.
1643 (define_peephole2
1644 [(set (match_operand:DI 0 "push_operand" "")
1645 (match_operand:DI 1 "immediate_operand" ""))]
1646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1647 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1648 [(set (match_dup 0) (match_dup 1))
1649 (set (match_dup 2) (match_dup 3))]
1650 {
1651 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1652
1653 operands[1] = gen_lowpart (DImode, operands[2]);
1654 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1655 GEN_INT (4)));
1656 })
1657
1658 (define_split
1659 [(set (match_operand:DI 0 "push_operand" "")
1660 (match_operand:DI 1 "immediate_operand" ""))]
1661 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1662 ? epilogue_completed : reload_completed)
1663 && !symbolic_operand (operands[1], DImode)
1664 && !x86_64_immediate_operand (operands[1], DImode)"
1665 [(set (match_dup 0) (match_dup 1))
1666 (set (match_dup 2) (match_dup 3))]
1667 {
1668 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1669
1670 operands[1] = gen_lowpart (DImode, operands[2]);
1671 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1672 GEN_INT (4)));
1673 })
1674
1675 (define_split
1676 [(set (match_operand:DI 0 "push_operand" "")
1677 (match_operand:DI 1 "general_operand" ""))]
1678 "!TARGET_64BIT && reload_completed
1679 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1680 [(const_int 0)]
1681 "ix86_split_long_move (operands); DONE;")
1682
1683 (define_insn "*pushsi2"
1684 [(set (match_operand:SI 0 "push_operand" "=<")
1685 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1686 "!TARGET_64BIT"
1687 "push{l}\t%1"
1688 [(set_attr "type" "push")
1689 (set_attr "mode" "SI")])
1690
1691 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1692 ;; "push a byte/word". But actually we use pushl, which has the effect
1693 ;; of rounding the amount pushed up to a word.
1694
1695 ;; For TARGET_64BIT we always round up to 8 bytes.
1696 (define_insn "*push<mode>2_rex64"
1697 [(set (match_operand:SWI124 0 "push_operand" "=X")
1698 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1699 "TARGET_64BIT"
1700 "push{q}\t%q1"
1701 [(set_attr "type" "push")
1702 (set_attr "mode" "DI")])
1703
1704 (define_insn "*push<mode>2"
1705 [(set (match_operand:SWI12 0 "push_operand" "=X")
1706 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1707 "!TARGET_64BIT"
1708 "push{l}\t%k1"
1709 [(set_attr "type" "push")
1710 (set_attr "mode" "SI")])
1711
1712 (define_insn "*push<mode>2_prologue"
1713 [(set (match_operand:W 0 "push_operand" "=<")
1714 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1715 (clobber (mem:BLK (scratch)))]
1716 ""
1717 "push{<imodesuffix>}\t%1"
1718 [(set_attr "type" "push")
1719 (set_attr "mode" "<MODE>")])
1720
1721 (define_insn "*pop<mode>1"
1722 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1723 (match_operand:W 1 "pop_operand" ">"))]
1724 ""
1725 "pop{<imodesuffix>}\t%0"
1726 [(set_attr "type" "pop")
1727 (set_attr "mode" "<MODE>")])
1728
1729 (define_insn "*pop<mode>1_epilogue"
1730 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1731 (match_operand:W 1 "pop_operand" ">"))
1732 (clobber (mem:BLK (scratch)))]
1733 ""
1734 "pop{<imodesuffix>}\t%0"
1735 [(set_attr "type" "pop")
1736 (set_attr "mode" "<MODE>")])
1737 \f
1738 ;; Move instructions.
1739
1740 (define_expand "movoi"
1741 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1742 (match_operand:OI 1 "general_operand" ""))]
1743 "TARGET_AVX"
1744 "ix86_expand_move (OImode, operands); DONE;")
1745
1746 (define_expand "movti"
1747 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1748 (match_operand:TI 1 "nonimmediate_operand" ""))]
1749 "TARGET_64BIT || TARGET_SSE"
1750 {
1751 if (TARGET_64BIT)
1752 ix86_expand_move (TImode, operands);
1753 else if (push_operand (operands[0], TImode))
1754 ix86_expand_push (TImode, operands[1]);
1755 else
1756 ix86_expand_vector_move (TImode, operands);
1757 DONE;
1758 })
1759
1760 ;; This expands to what emit_move_complex would generate if we didn't
1761 ;; have a movti pattern. Having this avoids problems with reload on
1762 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1763 ;; to have around all the time.
1764 (define_expand "movcdi"
1765 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1766 (match_operand:CDI 1 "general_operand" ""))]
1767 ""
1768 {
1769 if (push_operand (operands[0], CDImode))
1770 emit_move_complex_push (CDImode, operands[0], operands[1]);
1771 else
1772 emit_move_complex_parts (operands[0], operands[1]);
1773 DONE;
1774 })
1775
1776 (define_expand "mov<mode>"
1777 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1778 (match_operand:SWI1248x 1 "general_operand" ""))]
1779 ""
1780 "ix86_expand_move (<MODE>mode, operands); DONE;")
1781
1782 (define_insn "*mov<mode>_xor"
1783 [(set (match_operand:SWI48 0 "register_operand" "=r")
1784 (match_operand:SWI48 1 "const0_operand" ""))
1785 (clobber (reg:CC FLAGS_REG))]
1786 "reload_completed"
1787 "xor{l}\t%k0, %k0"
1788 [(set_attr "type" "alu1")
1789 (set_attr "mode" "SI")
1790 (set_attr "length_immediate" "0")])
1791
1792 (define_insn "*mov<mode>_or"
1793 [(set (match_operand:SWI48 0 "register_operand" "=r")
1794 (match_operand:SWI48 1 "const_int_operand" ""))
1795 (clobber (reg:CC FLAGS_REG))]
1796 "reload_completed
1797 && operands[1] == constm1_rtx"
1798 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1799 [(set_attr "type" "alu1")
1800 (set_attr "mode" "<MODE>")
1801 (set_attr "length_immediate" "1")])
1802
1803 (define_insn "*movoi_internal_avx"
1804 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1805 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1806 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1807 {
1808 switch (which_alternative)
1809 {
1810 case 0:
1811 return standard_sse_constant_opcode (insn, operands[1]);
1812 case 1:
1813 case 2:
1814 if (misaligned_operand (operands[0], OImode)
1815 || misaligned_operand (operands[1], OImode))
1816 return "vmovdqu\t{%1, %0|%0, %1}";
1817 else
1818 return "vmovdqa\t{%1, %0|%0, %1}";
1819 default:
1820 gcc_unreachable ();
1821 }
1822 }
1823 [(set_attr "type" "sselog1,ssemov,ssemov")
1824 (set_attr "prefix" "vex")
1825 (set_attr "mode" "OI")])
1826
1827 (define_insn "*movti_internal_rex64"
1828 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1829 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1830 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1831 {
1832 switch (which_alternative)
1833 {
1834 case 0:
1835 case 1:
1836 return "#";
1837 case 2:
1838 return standard_sse_constant_opcode (insn, operands[1]);
1839 case 3:
1840 case 4:
1841 /* TDmode values are passed as TImode on the stack. Moving them
1842 to stack may result in unaligned memory access. */
1843 if (misaligned_operand (operands[0], TImode)
1844 || misaligned_operand (operands[1], TImode))
1845 {
1846 if (get_attr_mode (insn) == MODE_V4SF)
1847 return "%vmovups\t{%1, %0|%0, %1}";
1848 else
1849 return "%vmovdqu\t{%1, %0|%0, %1}";
1850 }
1851 else
1852 {
1853 if (get_attr_mode (insn) == MODE_V4SF)
1854 return "%vmovaps\t{%1, %0|%0, %1}";
1855 else
1856 return "%vmovdqa\t{%1, %0|%0, %1}";
1857 }
1858 default:
1859 gcc_unreachable ();
1860 }
1861 }
1862 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1863 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1864 (set (attr "mode")
1865 (cond [(eq_attr "alternative" "2,3")
1866 (if_then_else
1867 (match_test "optimize_function_for_size_p (cfun)")
1868 (const_string "V4SF")
1869 (const_string "TI"))
1870 (eq_attr "alternative" "4")
1871 (if_then_else
1872 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1873 (match_test "optimize_function_for_size_p (cfun)"))
1874 (const_string "V4SF")
1875 (const_string "TI"))]
1876 (const_string "DI")))])
1877
1878 (define_split
1879 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1880 (match_operand:TI 1 "general_operand" ""))]
1881 "reload_completed
1882 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1883 [(const_int 0)]
1884 "ix86_split_long_move (operands); DONE;")
1885
1886 (define_insn "*movti_internal_sse"
1887 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1888 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1889 "TARGET_SSE && !TARGET_64BIT
1890 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1891 {
1892 switch (which_alternative)
1893 {
1894 case 0:
1895 return standard_sse_constant_opcode (insn, operands[1]);
1896 case 1:
1897 case 2:
1898 /* TDmode values are passed as TImode on the stack. Moving them
1899 to stack may result in unaligned memory access. */
1900 if (misaligned_operand (operands[0], TImode)
1901 || misaligned_operand (operands[1], TImode))
1902 {
1903 if (get_attr_mode (insn) == MODE_V4SF)
1904 return "%vmovups\t{%1, %0|%0, %1}";
1905 else
1906 return "%vmovdqu\t{%1, %0|%0, %1}";
1907 }
1908 else
1909 {
1910 if (get_attr_mode (insn) == MODE_V4SF)
1911 return "%vmovaps\t{%1, %0|%0, %1}";
1912 else
1913 return "%vmovdqa\t{%1, %0|%0, %1}";
1914 }
1915 default:
1916 gcc_unreachable ();
1917 }
1918 }
1919 [(set_attr "type" "sselog1,ssemov,ssemov")
1920 (set_attr "prefix" "maybe_vex")
1921 (set (attr "mode")
1922 (cond [(ior (not (match_test "TARGET_SSE2"))
1923 (match_test "optimize_function_for_size_p (cfun)"))
1924 (const_string "V4SF")
1925 (and (eq_attr "alternative" "2")
1926 (match_test "TARGET_SSE_TYPELESS_STORES"))
1927 (const_string "V4SF")]
1928 (const_string "TI")))])
1929
1930 (define_insn "*movdi_internal_rex64"
1931 [(set (match_operand:DI 0 "nonimmediate_operand"
1932 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1933 (match_operand:DI 1 "general_operand"
1934 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1935 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936 {
1937 switch (get_attr_type (insn))
1938 {
1939 case TYPE_SSECVT:
1940 if (SSE_REG_P (operands[0]))
1941 return "movq2dq\t{%1, %0|%0, %1}";
1942 else
1943 return "movdq2q\t{%1, %0|%0, %1}";
1944
1945 case TYPE_SSEMOV:
1946 if (get_attr_mode (insn) == MODE_TI)
1947 return "%vmovdqa\t{%1, %0|%0, %1}";
1948 /* Handle broken assemblers that require movd instead of movq. */
1949 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1950 return "%vmovd\t{%1, %0|%0, %1}";
1951 else
1952 return "%vmovq\t{%1, %0|%0, %1}";
1953
1954 case TYPE_MMXMOV:
1955 /* Handle broken assemblers that require movd instead of movq. */
1956 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1957 return "movd\t{%1, %0|%0, %1}";
1958 else
1959 return "movq\t{%1, %0|%0, %1}";
1960
1961 case TYPE_SSELOG1:
1962 return standard_sse_constant_opcode (insn, operands[1]);
1963
1964 case TYPE_MMX:
1965 return "pxor\t%0, %0";
1966
1967 case TYPE_MULTI:
1968 return "#";
1969
1970 case TYPE_LEA:
1971 return "lea{q}\t{%E1, %0|%0, %E1}";
1972
1973 default:
1974 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1975 if (get_attr_mode (insn) == MODE_SI)
1976 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1977 else if (which_alternative == 2)
1978 return "movabs{q}\t{%1, %0|%0, %1}";
1979 else if (ix86_use_lea_for_mov (insn, operands))
1980 return "lea{q}\t{%E1, %0|%0, %E1}";
1981 else
1982 return "mov{q}\t{%1, %0|%0, %1}";
1983 }
1984 }
1985 [(set (attr "type")
1986 (cond [(eq_attr "alternative" "4")
1987 (const_string "multi")
1988 (eq_attr "alternative" "5")
1989 (const_string "mmx")
1990 (eq_attr "alternative" "6,7,8,9")
1991 (const_string "mmxmov")
1992 (eq_attr "alternative" "10")
1993 (const_string "sselog1")
1994 (eq_attr "alternative" "11,12,13,14,15")
1995 (const_string "ssemov")
1996 (eq_attr "alternative" "16,17")
1997 (const_string "ssecvt")
1998 (match_operand 1 "pic_32bit_operand" "")
1999 (const_string "lea")
2000 ]
2001 (const_string "imov")))
2002 (set (attr "modrm")
2003 (if_then_else
2004 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2005 (const_string "0")
2006 (const_string "*")))
2007 (set (attr "length_immediate")
2008 (if_then_else
2009 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2010 (const_string "8")
2011 (const_string "*")))
2012 (set (attr "prefix_rex")
2013 (if_then_else (eq_attr "alternative" "8,9")
2014 (const_string "1")
2015 (const_string "*")))
2016 (set (attr "prefix_data16")
2017 (if_then_else (eq_attr "alternative" "11")
2018 (const_string "1")
2019 (const_string "*")))
2020 (set (attr "prefix")
2021 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2022 (const_string "maybe_vex")
2023 (const_string "orig")))
2024 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2025
2026 ;; Reload patterns to support multi-word load/store
2027 ;; with non-offsetable address.
2028 (define_expand "reload_noff_store"
2029 [(parallel [(match_operand 0 "memory_operand" "=m")
2030 (match_operand 1 "register_operand" "r")
2031 (match_operand:DI 2 "register_operand" "=&r")])]
2032 "TARGET_64BIT"
2033 {
2034 rtx mem = operands[0];
2035 rtx addr = XEXP (mem, 0);
2036
2037 emit_move_insn (operands[2], addr);
2038 mem = replace_equiv_address_nv (mem, operands[2]);
2039
2040 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2041 DONE;
2042 })
2043
2044 (define_expand "reload_noff_load"
2045 [(parallel [(match_operand 0 "register_operand" "=r")
2046 (match_operand 1 "memory_operand" "m")
2047 (match_operand:DI 2 "register_operand" "=r")])]
2048 "TARGET_64BIT"
2049 {
2050 rtx mem = operands[1];
2051 rtx addr = XEXP (mem, 0);
2052
2053 emit_move_insn (operands[2], addr);
2054 mem = replace_equiv_address_nv (mem, operands[2]);
2055
2056 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2057 DONE;
2058 })
2059
2060 ;; Convert impossible stores of immediate to existing instructions.
2061 ;; First try to get scratch register and go through it. In case this
2062 ;; fails, move by 32bit parts.
2063 (define_peephole2
2064 [(match_scratch:DI 2 "r")
2065 (set (match_operand:DI 0 "memory_operand" "")
2066 (match_operand:DI 1 "immediate_operand" ""))]
2067 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2068 && !x86_64_immediate_operand (operands[1], DImode)"
2069 [(set (match_dup 2) (match_dup 1))
2070 (set (match_dup 0) (match_dup 2))])
2071
2072 ;; We need to define this as both peepholer and splitter for case
2073 ;; peephole2 pass is not run.
2074 ;; "&& 1" is needed to keep it from matching the previous pattern.
2075 (define_peephole2
2076 [(set (match_operand:DI 0 "memory_operand" "")
2077 (match_operand:DI 1 "immediate_operand" ""))]
2078 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2080 [(set (match_dup 2) (match_dup 3))
2081 (set (match_dup 4) (match_dup 5))]
2082 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2083
2084 (define_split
2085 [(set (match_operand:DI 0 "memory_operand" "")
2086 (match_operand:DI 1 "immediate_operand" ""))]
2087 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2088 ? epilogue_completed : reload_completed)
2089 && !symbolic_operand (operands[1], DImode)
2090 && !x86_64_immediate_operand (operands[1], DImode)"
2091 [(set (match_dup 2) (match_dup 3))
2092 (set (match_dup 4) (match_dup 5))]
2093 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2094
2095 (define_insn "*movdi_internal"
2096 [(set (match_operand:DI 0 "nonimmediate_operand"
2097 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2098 (match_operand:DI 1 "general_operand"
2099 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2100 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2101 {
2102 switch (get_attr_type (insn))
2103 {
2104 case TYPE_SSECVT:
2105 if (SSE_REG_P (operands[0]))
2106 return "movq2dq\t{%1, %0|%0, %1}";
2107 else
2108 return "movdq2q\t{%1, %0|%0, %1}";
2109
2110 case TYPE_SSEMOV:
2111 switch (get_attr_mode (insn))
2112 {
2113 case MODE_TI:
2114 return "%vmovdqa\t{%1, %0|%0, %1}";
2115 case MODE_DI:
2116 return "%vmovq\t{%1, %0|%0, %1}";
2117 case MODE_V4SF:
2118 return "movaps\t{%1, %0|%0, %1}";
2119 case MODE_V2SF:
2120 return "movlps\t{%1, %0|%0, %1}";
2121 default:
2122 gcc_unreachable ();
2123 }
2124
2125 case TYPE_MMXMOV:
2126 return "movq\t{%1, %0|%0, %1}";
2127
2128 case TYPE_SSELOG1:
2129 return standard_sse_constant_opcode (insn, operands[1]);
2130
2131 case TYPE_MMX:
2132 return "pxor\t%0, %0";
2133
2134 case TYPE_MULTI:
2135 return "#";
2136
2137 default:
2138 gcc_unreachable ();
2139 }
2140 }
2141 [(set (attr "isa")
2142 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2143 (const_string "sse2")
2144 (eq_attr "alternative" "9,10,11,12")
2145 (const_string "noavx")
2146 ]
2147 (const_string "*")))
2148 (set (attr "type")
2149 (cond [(eq_attr "alternative" "0,1")
2150 (const_string "multi")
2151 (eq_attr "alternative" "2")
2152 (const_string "mmx")
2153 (eq_attr "alternative" "3,4")
2154 (const_string "mmxmov")
2155 (eq_attr "alternative" "5,9")
2156 (const_string "sselog1")
2157 (eq_attr "alternative" "13,14")
2158 (const_string "ssecvt")
2159 ]
2160 (const_string "ssemov")))
2161 (set (attr "prefix")
2162 (if_then_else (eq_attr "alternative" "5,6,7,8")
2163 (const_string "maybe_vex")
2164 (const_string "orig")))
2165 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2166
2167 (define_split
2168 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2169 (match_operand:DI 1 "general_operand" ""))]
2170 "!TARGET_64BIT && reload_completed
2171 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2172 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2173 [(const_int 0)]
2174 "ix86_split_long_move (operands); DONE;")
2175
2176 (define_insn "*movsi_internal"
2177 [(set (match_operand:SI 0 "nonimmediate_operand"
2178 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2179 (match_operand:SI 1 "general_operand"
2180 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2181 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2182 {
2183 switch (get_attr_type (insn))
2184 {
2185 case TYPE_SSELOG1:
2186 return standard_sse_constant_opcode (insn, operands[1]);
2187
2188 case TYPE_SSEMOV:
2189 switch (get_attr_mode (insn))
2190 {
2191 case MODE_TI:
2192 return "%vmovdqa\t{%1, %0|%0, %1}";
2193 case MODE_V4SF:
2194 return "%vmovaps\t{%1, %0|%0, %1}";
2195 case MODE_SI:
2196 return "%vmovd\t{%1, %0|%0, %1}";
2197 case MODE_SF:
2198 return "%vmovss\t{%1, %0|%0, %1}";
2199 default:
2200 gcc_unreachable ();
2201 }
2202
2203 case TYPE_MMX:
2204 return "pxor\t%0, %0";
2205
2206 case TYPE_MMXMOV:
2207 if (get_attr_mode (insn) == MODE_DI)
2208 return "movq\t{%1, %0|%0, %1}";
2209 return "movd\t{%1, %0|%0, %1}";
2210
2211 case TYPE_LEA:
2212 return "lea{l}\t{%E1, %0|%0, %E1}";
2213
2214 default:
2215 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2216 if (ix86_use_lea_for_mov (insn, operands))
2217 return "lea{l}\t{%E1, %0|%0, %E1}";
2218 else
2219 return "mov{l}\t{%1, %0|%0, %1}";
2220 }
2221 }
2222 [(set (attr "type")
2223 (cond [(eq_attr "alternative" "2")
2224 (const_string "mmx")
2225 (eq_attr "alternative" "3,4,5")
2226 (const_string "mmxmov")
2227 (eq_attr "alternative" "6")
2228 (const_string "sselog1")
2229 (eq_attr "alternative" "7,8,9,10,11")
2230 (const_string "ssemov")
2231 (match_operand 1 "pic_32bit_operand" "")
2232 (const_string "lea")
2233 ]
2234 (const_string "imov")))
2235 (set (attr "prefix")
2236 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2237 (const_string "orig")
2238 (const_string "maybe_vex")))
2239 (set (attr "prefix_data16")
2240 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2241 (const_string "1")
2242 (const_string "*")))
2243 (set (attr "mode")
2244 (cond [(eq_attr "alternative" "2,3")
2245 (const_string "DI")
2246 (eq_attr "alternative" "6,7")
2247 (if_then_else
2248 (not (match_test "TARGET_SSE2"))
2249 (const_string "V4SF")
2250 (const_string "TI"))
2251 (and (eq_attr "alternative" "8,9,10,11")
2252 (not (match_test "TARGET_SSE2")))
2253 (const_string "SF")
2254 ]
2255 (const_string "SI")))])
2256
2257 (define_insn "*movhi_internal"
2258 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2259 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2260 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2261 {
2262 switch (get_attr_type (insn))
2263 {
2264 case TYPE_IMOVX:
2265 /* movzwl is faster than movw on p2 due to partial word stalls,
2266 though not as fast as an aligned movl. */
2267 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2268 default:
2269 if (get_attr_mode (insn) == MODE_SI)
2270 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2271 else
2272 return "mov{w}\t{%1, %0|%0, %1}";
2273 }
2274 }
2275 [(set (attr "type")
2276 (cond [(match_test "optimize_function_for_size_p (cfun)")
2277 (const_string "imov")
2278 (and (eq_attr "alternative" "0")
2279 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2280 (not (match_test "TARGET_HIMODE_MATH"))))
2281 (const_string "imov")
2282 (and (eq_attr "alternative" "1,2")
2283 (match_operand:HI 1 "aligned_operand" ""))
2284 (const_string "imov")
2285 (and (match_test "TARGET_MOVX")
2286 (eq_attr "alternative" "0,2"))
2287 (const_string "imovx")
2288 ]
2289 (const_string "imov")))
2290 (set (attr "mode")
2291 (cond [(eq_attr "type" "imovx")
2292 (const_string "SI")
2293 (and (eq_attr "alternative" "1,2")
2294 (match_operand:HI 1 "aligned_operand" ""))
2295 (const_string "SI")
2296 (and (eq_attr "alternative" "0")
2297 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2298 (not (match_test "TARGET_HIMODE_MATH"))))
2299 (const_string "SI")
2300 ]
2301 (const_string "HI")))])
2302
2303 ;; Situation is quite tricky about when to choose full sized (SImode) move
2304 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2305 ;; partial register dependency machines (such as AMD Athlon), where QImode
2306 ;; moves issue extra dependency and for partial register stalls machines
2307 ;; that don't use QImode patterns (and QImode move cause stall on the next
2308 ;; instruction).
2309 ;;
2310 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2311 ;; register stall machines with, where we use QImode instructions, since
2312 ;; partial register stall can be caused there. Then we use movzx.
2313 (define_insn "*movqi_internal"
2314 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2315 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2316 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2317 {
2318 switch (get_attr_type (insn))
2319 {
2320 case TYPE_IMOVX:
2321 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2322 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2323 default:
2324 if (get_attr_mode (insn) == MODE_SI)
2325 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2326 else
2327 return "mov{b}\t{%1, %0|%0, %1}";
2328 }
2329 }
2330 [(set (attr "type")
2331 (cond [(and (eq_attr "alternative" "5")
2332 (not (match_operand:QI 1 "aligned_operand" "")))
2333 (const_string "imovx")
2334 (match_test "optimize_function_for_size_p (cfun)")
2335 (const_string "imov")
2336 (and (eq_attr "alternative" "3")
2337 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2338 (not (match_test "TARGET_QIMODE_MATH"))))
2339 (const_string "imov")
2340 (eq_attr "alternative" "3,5")
2341 (const_string "imovx")
2342 (and (match_test "TARGET_MOVX")
2343 (eq_attr "alternative" "2"))
2344 (const_string "imovx")
2345 ]
2346 (const_string "imov")))
2347 (set (attr "mode")
2348 (cond [(eq_attr "alternative" "3,4,5")
2349 (const_string "SI")
2350 (eq_attr "alternative" "6")
2351 (const_string "QI")
2352 (eq_attr "type" "imovx")
2353 (const_string "SI")
2354 (and (eq_attr "type" "imov")
2355 (and (eq_attr "alternative" "0,1")
2356 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2357 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2358 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2359 (const_string "SI")
2360 ;; Avoid partial register stalls when not using QImode arithmetic
2361 (and (eq_attr "type" "imov")
2362 (and (eq_attr "alternative" "0,1")
2363 (and (match_test "TARGET_PARTIAL_REG_STALL")
2364 (not (match_test "TARGET_QIMODE_MATH")))))
2365 (const_string "SI")
2366 ]
2367 (const_string "QI")))])
2368
2369 ;; Stores and loads of ax to arbitrary constant address.
2370 ;; We fake an second form of instruction to force reload to load address
2371 ;; into register when rax is not available
2372 (define_insn "*movabs<mode>_1"
2373 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2374 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2375 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2376 "@
2377 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2378 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2379 [(set_attr "type" "imov")
2380 (set_attr "modrm" "0,*")
2381 (set_attr "length_address" "8,0")
2382 (set_attr "length_immediate" "0,*")
2383 (set_attr "memory" "store")
2384 (set_attr "mode" "<MODE>")])
2385
2386 (define_insn "*movabs<mode>_2"
2387 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2388 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2389 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2390 "@
2391 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2392 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2393 [(set_attr "type" "imov")
2394 (set_attr "modrm" "0,*")
2395 (set_attr "length_address" "8,0")
2396 (set_attr "length_immediate" "0")
2397 (set_attr "memory" "load")
2398 (set_attr "mode" "<MODE>")])
2399
2400 (define_insn "*swap<mode>"
2401 [(set (match_operand:SWI48 0 "register_operand" "+r")
2402 (match_operand:SWI48 1 "register_operand" "+r"))
2403 (set (match_dup 1)
2404 (match_dup 0))]
2405 ""
2406 "xchg{<imodesuffix>}\t%1, %0"
2407 [(set_attr "type" "imov")
2408 (set_attr "mode" "<MODE>")
2409 (set_attr "pent_pair" "np")
2410 (set_attr "athlon_decode" "vector")
2411 (set_attr "amdfam10_decode" "double")
2412 (set_attr "bdver1_decode" "double")])
2413
2414 (define_insn "*swap<mode>_1"
2415 [(set (match_operand:SWI12 0 "register_operand" "+r")
2416 (match_operand:SWI12 1 "register_operand" "+r"))
2417 (set (match_dup 1)
2418 (match_dup 0))]
2419 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2420 "xchg{l}\t%k1, %k0"
2421 [(set_attr "type" "imov")
2422 (set_attr "mode" "SI")
2423 (set_attr "pent_pair" "np")
2424 (set_attr "athlon_decode" "vector")
2425 (set_attr "amdfam10_decode" "double")
2426 (set_attr "bdver1_decode" "double")])
2427
2428 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2429 ;; is disabled for AMDFAM10
2430 (define_insn "*swap<mode>_2"
2431 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2432 (match_operand:SWI12 1 "register_operand" "+<r>"))
2433 (set (match_dup 1)
2434 (match_dup 0))]
2435 "TARGET_PARTIAL_REG_STALL"
2436 "xchg{<imodesuffix>}\t%1, %0"
2437 [(set_attr "type" "imov")
2438 (set_attr "mode" "<MODE>")
2439 (set_attr "pent_pair" "np")
2440 (set_attr "athlon_decode" "vector")])
2441
2442 (define_expand "movstrict<mode>"
2443 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2444 (match_operand:SWI12 1 "general_operand" ""))]
2445 ""
2446 {
2447 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2448 FAIL;
2449 if (GET_CODE (operands[0]) == SUBREG
2450 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2451 FAIL;
2452 /* Don't generate memory->memory moves, go through a register */
2453 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2454 operands[1] = force_reg (<MODE>mode, operands[1]);
2455 })
2456
2457 (define_insn "*movstrict<mode>_1"
2458 [(set (strict_low_part
2459 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2460 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2461 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2462 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2463 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2464 [(set_attr "type" "imov")
2465 (set_attr "mode" "<MODE>")])
2466
2467 (define_insn "*movstrict<mode>_xor"
2468 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2469 (match_operand:SWI12 1 "const0_operand" ""))
2470 (clobber (reg:CC FLAGS_REG))]
2471 "reload_completed"
2472 "xor{<imodesuffix>}\t%0, %0"
2473 [(set_attr "type" "alu1")
2474 (set_attr "mode" "<MODE>")
2475 (set_attr "length_immediate" "0")])
2476
2477 (define_insn "*mov<mode>_extv_1"
2478 [(set (match_operand:SWI24 0 "register_operand" "=R")
2479 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2480 (const_int 8)
2481 (const_int 8)))]
2482 ""
2483 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2484 [(set_attr "type" "imovx")
2485 (set_attr "mode" "SI")])
2486
2487 (define_insn "*movqi_extv_1_rex64"
2488 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2489 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2490 (const_int 8)
2491 (const_int 8)))]
2492 "TARGET_64BIT"
2493 {
2494 switch (get_attr_type (insn))
2495 {
2496 case TYPE_IMOVX:
2497 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2498 default:
2499 return "mov{b}\t{%h1, %0|%0, %h1}";
2500 }
2501 }
2502 [(set (attr "type")
2503 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2504 (match_test "TARGET_MOVX"))
2505 (const_string "imovx")
2506 (const_string "imov")))
2507 (set (attr "mode")
2508 (if_then_else (eq_attr "type" "imovx")
2509 (const_string "SI")
2510 (const_string "QI")))])
2511
2512 (define_insn "*movqi_extv_1"
2513 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2514 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2515 (const_int 8)
2516 (const_int 8)))]
2517 "!TARGET_64BIT"
2518 {
2519 switch (get_attr_type (insn))
2520 {
2521 case TYPE_IMOVX:
2522 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2523 default:
2524 return "mov{b}\t{%h1, %0|%0, %h1}";
2525 }
2526 }
2527 [(set (attr "type")
2528 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2529 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2530 (match_test "TARGET_MOVX")))
2531 (const_string "imovx")
2532 (const_string "imov")))
2533 (set (attr "mode")
2534 (if_then_else (eq_attr "type" "imovx")
2535 (const_string "SI")
2536 (const_string "QI")))])
2537
2538 (define_insn "*mov<mode>_extzv_1"
2539 [(set (match_operand:SWI48 0 "register_operand" "=R")
2540 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2541 (const_int 8)
2542 (const_int 8)))]
2543 ""
2544 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2545 [(set_attr "type" "imovx")
2546 (set_attr "mode" "SI")])
2547
2548 (define_insn "*movqi_extzv_2_rex64"
2549 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2550 (subreg:QI
2551 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2552 (const_int 8)
2553 (const_int 8)) 0))]
2554 "TARGET_64BIT"
2555 {
2556 switch (get_attr_type (insn))
2557 {
2558 case TYPE_IMOVX:
2559 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2560 default:
2561 return "mov{b}\t{%h1, %0|%0, %h1}";
2562 }
2563 }
2564 [(set (attr "type")
2565 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2566 (match_test "TARGET_MOVX"))
2567 (const_string "imovx")
2568 (const_string "imov")))
2569 (set (attr "mode")
2570 (if_then_else (eq_attr "type" "imovx")
2571 (const_string "SI")
2572 (const_string "QI")))])
2573
2574 (define_insn "*movqi_extzv_2"
2575 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2576 (subreg:QI
2577 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2578 (const_int 8)
2579 (const_int 8)) 0))]
2580 "!TARGET_64BIT"
2581 {
2582 switch (get_attr_type (insn))
2583 {
2584 case TYPE_IMOVX:
2585 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2586 default:
2587 return "mov{b}\t{%h1, %0|%0, %h1}";
2588 }
2589 }
2590 [(set (attr "type")
2591 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2592 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2593 (match_test "TARGET_MOVX")))
2594 (const_string "imovx")
2595 (const_string "imov")))
2596 (set (attr "mode")
2597 (if_then_else (eq_attr "type" "imovx")
2598 (const_string "SI")
2599 (const_string "QI")))])
2600
2601 (define_expand "mov<mode>_insv_1"
2602 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2603 (const_int 8)
2604 (const_int 8))
2605 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2606
2607 (define_insn "*mov<mode>_insv_1_rex64"
2608 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2609 (const_int 8)
2610 (const_int 8))
2611 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2612 "TARGET_64BIT"
2613 "mov{b}\t{%b1, %h0|%h0, %b1}"
2614 [(set_attr "type" "imov")
2615 (set_attr "mode" "QI")])
2616
2617 (define_insn "*movsi_insv_1"
2618 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2619 (const_int 8)
2620 (const_int 8))
2621 (match_operand:SI 1 "general_operand" "Qmn"))]
2622 "!TARGET_64BIT"
2623 "mov{b}\t{%b1, %h0|%h0, %b1}"
2624 [(set_attr "type" "imov")
2625 (set_attr "mode" "QI")])
2626
2627 (define_insn "*movqi_insv_2"
2628 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2629 (const_int 8)
2630 (const_int 8))
2631 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2632 (const_int 8)))]
2633 ""
2634 "mov{b}\t{%h1, %h0|%h0, %h1}"
2635 [(set_attr "type" "imov")
2636 (set_attr "mode" "QI")])
2637 \f
2638 ;; Floating point push instructions.
2639
2640 (define_insn "*pushtf"
2641 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2642 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2643 "TARGET_SSE2"
2644 {
2645 /* This insn should be already split before reg-stack. */
2646 gcc_unreachable ();
2647 }
2648 [(set_attr "type" "multi")
2649 (set_attr "unit" "sse,*,*")
2650 (set_attr "mode" "TF,SI,SI")])
2651
2652 ;; %%% Kill this when call knows how to work this out.
2653 (define_split
2654 [(set (match_operand:TF 0 "push_operand" "")
2655 (match_operand:TF 1 "sse_reg_operand" ""))]
2656 "TARGET_SSE2 && reload_completed"
2657 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2658 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2659
2660 (define_insn "*pushxf"
2661 [(set (match_operand:XF 0 "push_operand" "=<,<")
2662 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2663 "optimize_function_for_speed_p (cfun)"
2664 {
2665 /* This insn should be already split before reg-stack. */
2666 gcc_unreachable ();
2667 }
2668 [(set_attr "type" "multi")
2669 (set_attr "unit" "i387,*")
2670 (set_attr "mode" "XF,SI")])
2671
2672 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2673 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2674 ;; Pushing using integer instructions is longer except for constants
2675 ;; and direct memory references (assuming that any given constant is pushed
2676 ;; only once, but this ought to be handled elsewhere).
2677
2678 (define_insn "*pushxf_nointeger"
2679 [(set (match_operand:XF 0 "push_operand" "=<,<")
2680 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2681 "optimize_function_for_size_p (cfun)"
2682 {
2683 /* This insn should be already split before reg-stack. */
2684 gcc_unreachable ();
2685 }
2686 [(set_attr "type" "multi")
2687 (set_attr "unit" "i387,*")
2688 (set_attr "mode" "XF,SI")])
2689
2690 ;; %%% Kill this when call knows how to work this out.
2691 (define_split
2692 [(set (match_operand:XF 0 "push_operand" "")
2693 (match_operand:XF 1 "fp_register_operand" ""))]
2694 "reload_completed"
2695 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2696 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2697 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2698
2699 (define_insn "*pushdf_rex64"
2700 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2701 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2702 "TARGET_64BIT"
2703 {
2704 /* This insn should be already split before reg-stack. */
2705 gcc_unreachable ();
2706 }
2707 [(set_attr "type" "multi")
2708 (set_attr "unit" "i387,*,*")
2709 (set_attr "mode" "DF,DI,DF")])
2710
2711 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2712 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2713 ;; On the average, pushdf using integers can be still shorter.
2714
2715 (define_insn "*pushdf"
2716 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2717 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2718 "!TARGET_64BIT"
2719 {
2720 /* This insn should be already split before reg-stack. */
2721 gcc_unreachable ();
2722 }
2723 [(set_attr "isa" "*,*,sse2")
2724 (set_attr "type" "multi")
2725 (set_attr "unit" "i387,*,*")
2726 (set_attr "mode" "DF,DI,DF")])
2727
2728 ;; %%% Kill this when call knows how to work this out.
2729 (define_split
2730 [(set (match_operand:DF 0 "push_operand" "")
2731 (match_operand:DF 1 "any_fp_register_operand" ""))]
2732 "reload_completed"
2733 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2734 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2735
2736 (define_insn "*pushsf_rex64"
2737 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2738 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2739 "TARGET_64BIT"
2740 {
2741 /* Anything else should be already split before reg-stack. */
2742 gcc_assert (which_alternative == 1);
2743 return "push{q}\t%q1";
2744 }
2745 [(set_attr "type" "multi,push,multi")
2746 (set_attr "unit" "i387,*,*")
2747 (set_attr "mode" "SF,DI,SF")])
2748
2749 (define_insn "*pushsf"
2750 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2751 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2752 "!TARGET_64BIT"
2753 {
2754 /* Anything else should be already split before reg-stack. */
2755 gcc_assert (which_alternative == 1);
2756 return "push{l}\t%1";
2757 }
2758 [(set_attr "type" "multi,push,multi")
2759 (set_attr "unit" "i387,*,*")
2760 (set_attr "mode" "SF,SI,SF")])
2761
2762 ;; %%% Kill this when call knows how to work this out.
2763 (define_split
2764 [(set (match_operand:SF 0 "push_operand" "")
2765 (match_operand:SF 1 "any_fp_register_operand" ""))]
2766 "reload_completed"
2767 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2768 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2769 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2770
2771 (define_split
2772 [(set (match_operand:SF 0 "push_operand" "")
2773 (match_operand:SF 1 "memory_operand" ""))]
2774 "reload_completed
2775 && (operands[2] = find_constant_src (insn))"
2776 [(set (match_dup 0) (match_dup 2))])
2777
2778 (define_split
2779 [(set (match_operand 0 "push_operand" "")
2780 (match_operand 1 "general_operand" ""))]
2781 "reload_completed
2782 && (GET_MODE (operands[0]) == TFmode
2783 || GET_MODE (operands[0]) == XFmode
2784 || GET_MODE (operands[0]) == DFmode)
2785 && !ANY_FP_REG_P (operands[1])"
2786 [(const_int 0)]
2787 "ix86_split_long_move (operands); DONE;")
2788 \f
2789 ;; Floating point move instructions.
2790
2791 (define_expand "movtf"
2792 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2793 (match_operand:TF 1 "nonimmediate_operand" ""))]
2794 "TARGET_SSE2"
2795 {
2796 ix86_expand_move (TFmode, operands);
2797 DONE;
2798 })
2799
2800 (define_expand "mov<mode>"
2801 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2802 (match_operand:X87MODEF 1 "general_operand" ""))]
2803 ""
2804 "ix86_expand_move (<MODE>mode, operands); DONE;")
2805
2806 (define_insn "*movtf_internal"
2807 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2808 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2809 "TARGET_SSE2
2810 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2811 && (!can_create_pseudo_p ()
2812 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2813 || GET_CODE (operands[1]) != CONST_DOUBLE
2814 || (optimize_function_for_size_p (cfun)
2815 && standard_sse_constant_p (operands[1])
2816 && !memory_operand (operands[0], TFmode))
2817 || (!TARGET_MEMORY_MISMATCH_STALL
2818 && memory_operand (operands[0], TFmode)))"
2819 {
2820 switch (which_alternative)
2821 {
2822 case 0:
2823 case 1:
2824 /* Handle misaligned load/store since we
2825 don't have movmisaligntf pattern. */
2826 if (misaligned_operand (operands[0], TFmode)
2827 || misaligned_operand (operands[1], TFmode))
2828 {
2829 if (get_attr_mode (insn) == MODE_V4SF)
2830 return "%vmovups\t{%1, %0|%0, %1}";
2831 else
2832 return "%vmovdqu\t{%1, %0|%0, %1}";
2833 }
2834 else
2835 {
2836 if (get_attr_mode (insn) == MODE_V4SF)
2837 return "%vmovaps\t{%1, %0|%0, %1}";
2838 else
2839 return "%vmovdqa\t{%1, %0|%0, %1}";
2840 }
2841
2842 case 2:
2843 return standard_sse_constant_opcode (insn, operands[1]);
2844
2845 case 3:
2846 case 4:
2847 return "#";
2848
2849 default:
2850 gcc_unreachable ();
2851 }
2852 }
2853 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2854 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2855 (set (attr "mode")
2856 (cond [(eq_attr "alternative" "0,2")
2857 (if_then_else
2858 (match_test "optimize_function_for_size_p (cfun)")
2859 (const_string "V4SF")
2860 (const_string "TI"))
2861 (eq_attr "alternative" "1")
2862 (if_then_else
2863 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2864 (match_test "optimize_function_for_size_p (cfun)"))
2865 (const_string "V4SF")
2866 (const_string "TI"))]
2867 (const_string "DI")))])
2868
2869 ;; Possible store forwarding (partial memory) stall in alternative 4.
2870 (define_insn "*movxf_internal"
2871 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2872 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2873 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2874 && (!can_create_pseudo_p ()
2875 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2876 || GET_CODE (operands[1]) != CONST_DOUBLE
2877 || (optimize_function_for_size_p (cfun)
2878 && standard_80387_constant_p (operands[1]) > 0
2879 && !memory_operand (operands[0], XFmode))
2880 || (!TARGET_MEMORY_MISMATCH_STALL
2881 && memory_operand (operands[0], XFmode)))"
2882 {
2883 switch (which_alternative)
2884 {
2885 case 0:
2886 case 1:
2887 return output_387_reg_move (insn, operands);
2888
2889 case 2:
2890 return standard_80387_constant_opcode (operands[1]);
2891
2892 case 3:
2893 case 4:
2894 return "#";
2895
2896 default:
2897 gcc_unreachable ();
2898 }
2899 }
2900 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2901 (set_attr "mode" "XF,XF,XF,SI,SI")])
2902
2903 (define_insn "*movdf_internal_rex64"
2904 [(set (match_operand:DF 0 "nonimmediate_operand"
2905 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2906 (match_operand:DF 1 "general_operand"
2907 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2908 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2909 && (!can_create_pseudo_p ()
2910 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2911 || GET_CODE (operands[1]) != CONST_DOUBLE
2912 || (optimize_function_for_size_p (cfun)
2913 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2914 && standard_80387_constant_p (operands[1]) > 0)
2915 || (TARGET_SSE2 && TARGET_SSE_MATH
2916 && standard_sse_constant_p (operands[1]))))
2917 || memory_operand (operands[0], DFmode))"
2918 {
2919 switch (which_alternative)
2920 {
2921 case 0:
2922 case 1:
2923 return output_387_reg_move (insn, operands);
2924
2925 case 2:
2926 return standard_80387_constant_opcode (operands[1]);
2927
2928 case 3:
2929 case 4:
2930 return "mov{q}\t{%1, %0|%0, %1}";
2931
2932 case 5:
2933 return "movabs{q}\t{%1, %0|%0, %1}";
2934
2935 case 6:
2936 return "#";
2937
2938 case 7:
2939 return standard_sse_constant_opcode (insn, operands[1]);
2940
2941 case 8:
2942 case 9:
2943 case 10:
2944 switch (get_attr_mode (insn))
2945 {
2946 case MODE_V2DF:
2947 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2948 return "%vmovapd\t{%1, %0|%0, %1}";
2949 case MODE_V4SF:
2950 return "%vmovaps\t{%1, %0|%0, %1}";
2951
2952 case MODE_DI:
2953 return "%vmovq\t{%1, %0|%0, %1}";
2954 case MODE_DF:
2955 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2956 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2957 return "%vmovsd\t{%1, %0|%0, %1}";
2958 case MODE_V1DF:
2959 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2960 case MODE_V2SF:
2961 return "%vmovlps\t{%1, %d0|%d0, %1}";
2962 default:
2963 gcc_unreachable ();
2964 }
2965
2966 case 11:
2967 case 12:
2968 /* Handle broken assemblers that require movd instead of movq. */
2969 return "%vmovd\t{%1, %0|%0, %1}";
2970
2971 default:
2972 gcc_unreachable();
2973 }
2974 }
2975 [(set (attr "type")
2976 (cond [(eq_attr "alternative" "0,1,2")
2977 (const_string "fmov")
2978 (eq_attr "alternative" "3,4,5")
2979 (const_string "imov")
2980 (eq_attr "alternative" "6")
2981 (const_string "multi")
2982 (eq_attr "alternative" "7")
2983 (const_string "sselog1")
2984 ]
2985 (const_string "ssemov")))
2986 (set (attr "modrm")
2987 (if_then_else
2988 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2989 (const_string "0")
2990 (const_string "*")))
2991 (set (attr "length_immediate")
2992 (if_then_else
2993 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2994 (const_string "8")
2995 (const_string "*")))
2996 (set (attr "prefix")
2997 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2998 (const_string "orig")
2999 (const_string "maybe_vex")))
3000 (set (attr "prefix_data16")
3001 (if_then_else (eq_attr "mode" "V1DF")
3002 (const_string "1")
3003 (const_string "*")))
3004 (set (attr "mode")
3005 (cond [(eq_attr "alternative" "0,1,2")
3006 (const_string "DF")
3007 (eq_attr "alternative" "3,4,5,6,11,12")
3008 (const_string "DI")
3009
3010 /* xorps is one byte shorter. */
3011 (eq_attr "alternative" "7")
3012 (cond [(match_test "optimize_function_for_size_p (cfun)")
3013 (const_string "V4SF")
3014 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3015 (const_string "TI")
3016 ]
3017 (const_string "V2DF"))
3018
3019 /* For architectures resolving dependencies on
3020 whole SSE registers use APD move to break dependency
3021 chains, otherwise use short move to avoid extra work.
3022
3023 movaps encodes one byte shorter. */
3024 (eq_attr "alternative" "8")
3025 (cond
3026 [(match_test "optimize_function_for_size_p (cfun)")
3027 (const_string "V4SF")
3028 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3029 (const_string "V2DF")
3030 ]
3031 (const_string "DF"))
3032 /* For architectures resolving dependencies on register
3033 parts we may avoid extra work to zero out upper part
3034 of register. */
3035 (eq_attr "alternative" "9")
3036 (if_then_else
3037 (match_test "TARGET_SSE_SPLIT_REGS")
3038 (const_string "V1DF")
3039 (const_string "DF"))
3040 ]
3041 (const_string "DF")))])
3042
3043 ;; Possible store forwarding (partial memory) stall in alternative 4.
3044 (define_insn "*movdf_internal"
3045 [(set (match_operand:DF 0 "nonimmediate_operand"
3046 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3047 (match_operand:DF 1 "general_operand"
3048 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3049 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050 && (!can_create_pseudo_p ()
3051 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3052 || GET_CODE (operands[1]) != CONST_DOUBLE
3053 || (optimize_function_for_size_p (cfun)
3054 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3055 && standard_80387_constant_p (operands[1]) > 0)
3056 || (TARGET_SSE2 && TARGET_SSE_MATH
3057 && standard_sse_constant_p (operands[1])))
3058 && !memory_operand (operands[0], DFmode))
3059 || (!TARGET_MEMORY_MISMATCH_STALL
3060 && memory_operand (operands[0], DFmode)))"
3061 {
3062 switch (which_alternative)
3063 {
3064 case 0:
3065 case 1:
3066 return output_387_reg_move (insn, operands);
3067
3068 case 2:
3069 return standard_80387_constant_opcode (operands[1]);
3070
3071 case 3:
3072 case 4:
3073 return "#";
3074
3075 case 5:
3076 case 9:
3077 return standard_sse_constant_opcode (insn, operands[1]);
3078
3079 case 6:
3080 case 7:
3081 case 8:
3082 case 10:
3083 case 11:
3084 case 12:
3085 switch (get_attr_mode (insn))
3086 {
3087 case MODE_V2DF:
3088 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3089 return "%vmovapd\t{%1, %0|%0, %1}";
3090 case MODE_V4SF:
3091 return "%vmovaps\t{%1, %0|%0, %1}";
3092
3093 case MODE_DI:
3094 return "%vmovq\t{%1, %0|%0, %1}";
3095 case MODE_DF:
3096 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3097 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3098 return "%vmovsd\t{%1, %0|%0, %1}";
3099 case MODE_V1DF:
3100 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3101 case MODE_V2SF:
3102 return "%vmovlps\t{%1, %d0|%d0, %1}";
3103 default:
3104 gcc_unreachable ();
3105 }
3106
3107 default:
3108 gcc_unreachable ();
3109 }
3110 }
3111 [(set (attr "isa")
3112 (if_then_else (eq_attr "alternative" "5,6,7,8")
3113 (const_string "sse2")
3114 (const_string "*")))
3115 (set (attr "type")
3116 (cond [(eq_attr "alternative" "0,1,2")
3117 (const_string "fmov")
3118 (eq_attr "alternative" "3,4")
3119 (const_string "multi")
3120 (eq_attr "alternative" "5,9")
3121 (const_string "sselog1")
3122 ]
3123 (const_string "ssemov")))
3124 (set (attr "prefix")
3125 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3126 (const_string "orig")
3127 (const_string "maybe_vex")))
3128 (set (attr "prefix_data16")
3129 (if_then_else (eq_attr "mode" "V1DF")
3130 (const_string "1")
3131 (const_string "*")))
3132 (set (attr "mode")
3133 (cond [(eq_attr "alternative" "0,1,2")
3134 (const_string "DF")
3135 (eq_attr "alternative" "3,4")
3136 (const_string "SI")
3137
3138 /* For SSE1, we have many fewer alternatives. */
3139 (not (match_test "TARGET_SSE2"))
3140 (if_then_else
3141 (eq_attr "alternative" "5,6,9,10")
3142 (const_string "V4SF")
3143 (const_string "V2SF"))
3144
3145 /* xorps is one byte shorter. */
3146 (eq_attr "alternative" "5,9")
3147 (cond [(match_test "optimize_function_for_size_p (cfun)")
3148 (const_string "V4SF")
3149 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3150 (const_string "TI")
3151 ]
3152 (const_string "V2DF"))
3153
3154 /* For architectures resolving dependencies on
3155 whole SSE registers use APD move to break dependency
3156 chains, otherwise use short move to avoid extra work.
3157
3158 movaps encodes one byte shorter. */
3159 (eq_attr "alternative" "6,10")
3160 (cond
3161 [(match_test "optimize_function_for_size_p (cfun)")
3162 (const_string "V4SF")
3163 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3164 (const_string "V2DF")
3165 ]
3166 (const_string "DF"))
3167 /* For architectures resolving dependencies on register
3168 parts we may avoid extra work to zero out upper part
3169 of register. */
3170 (eq_attr "alternative" "7,11")
3171 (if_then_else
3172 (match_test "TARGET_SSE_SPLIT_REGS")
3173 (const_string "V1DF")
3174 (const_string "DF"))
3175 ]
3176 (const_string "DF")))])
3177
3178 (define_insn "*movsf_internal"
3179 [(set (match_operand:SF 0 "nonimmediate_operand"
3180 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3181 (match_operand:SF 1 "general_operand"
3182 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3183 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3184 && (!can_create_pseudo_p ()
3185 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3186 || GET_CODE (operands[1]) != CONST_DOUBLE
3187 || (optimize_function_for_size_p (cfun)
3188 && ((!TARGET_SSE_MATH
3189 && standard_80387_constant_p (operands[1]) > 0)
3190 || (TARGET_SSE_MATH
3191 && standard_sse_constant_p (operands[1]))))
3192 || memory_operand (operands[0], SFmode))"
3193 {
3194 switch (which_alternative)
3195 {
3196 case 0:
3197 case 1:
3198 return output_387_reg_move (insn, operands);
3199
3200 case 2:
3201 return standard_80387_constant_opcode (operands[1]);
3202
3203 case 3:
3204 case 4:
3205 return "mov{l}\t{%1, %0|%0, %1}";
3206
3207 case 5:
3208 return standard_sse_constant_opcode (insn, operands[1]);
3209
3210 case 6:
3211 if (get_attr_mode (insn) == MODE_V4SF)
3212 return "%vmovaps\t{%1, %0|%0, %1}";
3213 if (TARGET_AVX)
3214 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3215
3216 case 7:
3217 case 8:
3218 return "%vmovss\t{%1, %0|%0, %1}";
3219
3220 case 9:
3221 case 10:
3222 case 14:
3223 case 15:
3224 return "movd\t{%1, %0|%0, %1}";
3225
3226 case 11:
3227 return "movq\t{%1, %0|%0, %1}";
3228
3229 case 12:
3230 case 13:
3231 return "%vmovd\t{%1, %0|%0, %1}";
3232
3233 default:
3234 gcc_unreachable ();
3235 }
3236 }
3237 [(set (attr "type")
3238 (cond [(eq_attr "alternative" "0,1,2")
3239 (const_string "fmov")
3240 (eq_attr "alternative" "3,4")
3241 (const_string "multi")
3242 (eq_attr "alternative" "5")
3243 (const_string "sselog1")
3244 (eq_attr "alternative" "9,10,11,14,15")
3245 (const_string "mmxmov")
3246 ]
3247 (const_string "ssemov")))
3248 (set (attr "prefix")
3249 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3250 (const_string "maybe_vex")
3251 (const_string "orig")))
3252 (set (attr "mode")
3253 (cond [(eq_attr "alternative" "3,4,9,10")
3254 (const_string "SI")
3255 (eq_attr "alternative" "5")
3256 (if_then_else
3257 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3258 (match_test "TARGET_SSE2"))
3259 (not (match_test "optimize_function_for_size_p (cfun)")))
3260 (const_string "TI")
3261 (const_string "V4SF"))
3262 /* For architectures resolving dependencies on
3263 whole SSE registers use APS move to break dependency
3264 chains, otherwise use short move to avoid extra work.
3265
3266 Do the same for architectures resolving dependencies on
3267 the parts. While in DF mode it is better to always handle
3268 just register parts, the SF mode is different due to lack
3269 of instructions to load just part of the register. It is
3270 better to maintain the whole registers in single format
3271 to avoid problems on using packed logical operations. */
3272 (eq_attr "alternative" "6")
3273 (if_then_else
3274 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3275 (match_test "TARGET_SSE_SPLIT_REGS"))
3276 (const_string "V4SF")
3277 (const_string "SF"))
3278 (eq_attr "alternative" "11")
3279 (const_string "DI")]
3280 (const_string "SF")))])
3281
3282 (define_split
3283 [(set (match_operand 0 "any_fp_register_operand" "")
3284 (match_operand 1 "memory_operand" ""))]
3285 "reload_completed
3286 && (GET_MODE (operands[0]) == TFmode
3287 || GET_MODE (operands[0]) == XFmode
3288 || GET_MODE (operands[0]) == DFmode
3289 || GET_MODE (operands[0]) == SFmode)
3290 && (operands[2] = find_constant_src (insn))"
3291 [(set (match_dup 0) (match_dup 2))]
3292 {
3293 rtx c = operands[2];
3294 int r = REGNO (operands[0]);
3295
3296 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3297 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3298 FAIL;
3299 })
3300
3301 (define_split
3302 [(set (match_operand 0 "any_fp_register_operand" "")
3303 (float_extend (match_operand 1 "memory_operand" "")))]
3304 "reload_completed
3305 && (GET_MODE (operands[0]) == TFmode
3306 || GET_MODE (operands[0]) == XFmode
3307 || GET_MODE (operands[0]) == DFmode)
3308 && (operands[2] = find_constant_src (insn))"
3309 [(set (match_dup 0) (match_dup 2))]
3310 {
3311 rtx c = operands[2];
3312 int r = REGNO (operands[0]);
3313
3314 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3315 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3316 FAIL;
3317 })
3318
3319 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3320 (define_split
3321 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3322 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3323 "reload_completed
3324 && (standard_80387_constant_p (operands[1]) == 8
3325 || standard_80387_constant_p (operands[1]) == 9)"
3326 [(set (match_dup 0)(match_dup 1))
3327 (set (match_dup 0)
3328 (neg:X87MODEF (match_dup 0)))]
3329 {
3330 REAL_VALUE_TYPE r;
3331
3332 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3333 if (real_isnegzero (&r))
3334 operands[1] = CONST0_RTX (<MODE>mode);
3335 else
3336 operands[1] = CONST1_RTX (<MODE>mode);
3337 })
3338
3339 (define_split
3340 [(set (match_operand 0 "nonimmediate_operand" "")
3341 (match_operand 1 "general_operand" ""))]
3342 "reload_completed
3343 && (GET_MODE (operands[0]) == TFmode
3344 || GET_MODE (operands[0]) == XFmode
3345 || GET_MODE (operands[0]) == DFmode)
3346 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3347 [(const_int 0)]
3348 "ix86_split_long_move (operands); DONE;")
3349
3350 (define_insn "swapxf"
3351 [(set (match_operand:XF 0 "register_operand" "+f")
3352 (match_operand:XF 1 "register_operand" "+f"))
3353 (set (match_dup 1)
3354 (match_dup 0))]
3355 "TARGET_80387"
3356 {
3357 if (STACK_TOP_P (operands[0]))
3358 return "fxch\t%1";
3359 else
3360 return "fxch\t%0";
3361 }
3362 [(set_attr "type" "fxch")
3363 (set_attr "mode" "XF")])
3364
3365 (define_insn "*swap<mode>"
3366 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3367 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3368 (set (match_dup 1)
3369 (match_dup 0))]
3370 "TARGET_80387 || reload_completed"
3371 {
3372 if (STACK_TOP_P (operands[0]))
3373 return "fxch\t%1";
3374 else
3375 return "fxch\t%0";
3376 }
3377 [(set_attr "type" "fxch")
3378 (set_attr "mode" "<MODE>")])
3379 \f
3380 ;; Zero extension instructions
3381
3382 (define_expand "zero_extendsidi2"
3383 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3384 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))])
3385
3386 (define_insn "*zero_extendsidi2_rex64"
3387 [(set (match_operand:DI 0 "nonimmediate_operand"
3388 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3389 (zero_extend:DI
3390 (match_operand:SI 1 "x86_64_zext_general_operand"
3391 "rmZ,0,r ,m ,r ,m*x")))]
3392 "TARGET_64BIT"
3393 "@
3394 mov{l}\t{%1, %k0|%k0, %1}
3395 #
3396 movd\t{%1, %0|%0, %1}
3397 movd\t{%1, %0|%0, %1}
3398 %vmovd\t{%1, %0|%0, %1}
3399 %vmovd\t{%1, %0|%0, %1}"
3400 [(set_attr "isa" "*,*,*,*,*,sse2")
3401 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3402 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3403 (set_attr "prefix_0f" "0,*,*,*,*,*")
3404 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3405
3406 (define_insn "*zero_extendsidi2"
3407 [(set (match_operand:DI 0 "nonimmediate_operand"
3408 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3409 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3410 "0 ,rm,r ,r ,m ,r ,m*x")))]
3411 "!TARGET_64BIT"
3412 "@
3413 #
3414 #
3415 #
3416 movd\t{%1, %0|%0, %1}
3417 movd\t{%1, %0|%0, %1}
3418 %vmovd\t{%1, %0|%0, %1}
3419 %vmovd\t{%1, %0|%0, %1}"
3420 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3421 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3422 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3423 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3424
3425 (define_split
3426 [(set (match_operand:DI 0 "memory_operand" "")
3427 (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))]
3428 "reload_completed"
3429 [(set (match_dup 4) (const_int 0))]
3430 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3431
3432 (define_split
3433 [(set (match_operand:DI 0 "register_operand" "")
3434 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3435 "!TARGET_64BIT && reload_completed
3436 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3437 && true_regnum (operands[0]) == true_regnum (operands[1])"
3438 [(set (match_dup 4) (const_int 0))]
3439 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3440
3441 (define_split
3442 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3443 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3444 "!TARGET_64BIT && reload_completed
3445 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3446 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3447 [(set (match_dup 3) (match_dup 1))
3448 (set (match_dup 4) (const_int 0))]
3449 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3450
3451 (define_insn "zero_extend<mode>di2"
3452 [(set (match_operand:DI 0 "register_operand" "=r")
3453 (zero_extend:DI
3454 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3455 "TARGET_64BIT"
3456 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3457 [(set_attr "type" "imovx")
3458 (set_attr "mode" "SI")])
3459
3460 (define_expand "zero_extend<mode>si2"
3461 [(set (match_operand:SI 0 "register_operand" "")
3462 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand" "")))]
3463 ""
3464 {
3465 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3466 {
3467 operands[1] = force_reg (<MODE>mode, operands[1]);
3468 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3469 DONE;
3470 }
3471 })
3472
3473 (define_insn_and_split "zero_extend<mode>si2_and"
3474 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3475 (zero_extend:SI
3476 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3477 (clobber (reg:CC FLAGS_REG))]
3478 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3479 "#"
3480 "&& reload_completed"
3481 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3482 (clobber (reg:CC FLAGS_REG))])]
3483 {
3484 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3485 {
3486 ix86_expand_clear (operands[0]);
3487
3488 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3489 emit_insn (gen_movstrict<mode>
3490 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3491 DONE;
3492 }
3493
3494 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3495 }
3496 [(set_attr "type" "alu1")
3497 (set_attr "mode" "SI")])
3498
3499 (define_insn "*zero_extend<mode>si2"
3500 [(set (match_operand:SI 0 "register_operand" "=r")
3501 (zero_extend:SI
3502 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3503 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3504 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3505 [(set_attr "type" "imovx")
3506 (set_attr "mode" "SI")])
3507
3508 (define_expand "zero_extendqihi2"
3509 [(set (match_operand:HI 0 "register_operand" "")
3510 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3511 ""
3512 {
3513 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3514 {
3515 operands[1] = force_reg (QImode, operands[1]);
3516 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3517 DONE;
3518 }
3519 })
3520
3521 (define_insn_and_split "zero_extendqihi2_and"
3522 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3523 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3524 (clobber (reg:CC FLAGS_REG))]
3525 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3526 "#"
3527 "&& reload_completed"
3528 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3529 (clobber (reg:CC FLAGS_REG))])]
3530 {
3531 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3532 {
3533 ix86_expand_clear (operands[0]);
3534
3535 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3536 emit_insn (gen_movstrictqi
3537 (gen_lowpart (QImode, operands[0]), operands[1]));
3538 DONE;
3539 }
3540
3541 operands[0] = gen_lowpart (SImode, operands[0]);
3542 }
3543 [(set_attr "type" "alu1")
3544 (set_attr "mode" "SI")])
3545
3546 ; zero extend to SImode to avoid partial register stalls
3547 (define_insn "*zero_extendqihi2"
3548 [(set (match_operand:HI 0 "register_operand" "=r")
3549 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3550 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3551 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3552 [(set_attr "type" "imovx")
3553 (set_attr "mode" "SI")])
3554 \f
3555 ;; Sign extension instructions
3556
3557 (define_expand "extendsidi2"
3558 [(set (match_operand:DI 0 "register_operand" "")
3559 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3560 ""
3561 {
3562 if (!TARGET_64BIT)
3563 {
3564 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3565 DONE;
3566 }
3567 })
3568
3569 (define_insn "*extendsidi2_rex64"
3570 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3571 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3572 "TARGET_64BIT"
3573 "@
3574 {cltq|cdqe}
3575 movs{lq|x}\t{%1, %0|%0, %1}"
3576 [(set_attr "type" "imovx")
3577 (set_attr "mode" "DI")
3578 (set_attr "prefix_0f" "0")
3579 (set_attr "modrm" "0,1")])
3580
3581 (define_insn "extendsidi2_1"
3582 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3583 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3584 (clobber (reg:CC FLAGS_REG))
3585 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3586 "!TARGET_64BIT"
3587 "#")
3588
3589 ;; Extend to memory case when source register does die.
3590 (define_split
3591 [(set (match_operand:DI 0 "memory_operand" "")
3592 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3593 (clobber (reg:CC FLAGS_REG))
3594 (clobber (match_operand:SI 2 "register_operand" ""))]
3595 "(reload_completed
3596 && dead_or_set_p (insn, operands[1])
3597 && !reg_mentioned_p (operands[1], operands[0]))"
3598 [(set (match_dup 3) (match_dup 1))
3599 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3600 (clobber (reg:CC FLAGS_REG))])
3601 (set (match_dup 4) (match_dup 1))]
3602 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3603
3604 ;; Extend to memory case when source register does not die.
3605 (define_split
3606 [(set (match_operand:DI 0 "memory_operand" "")
3607 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3608 (clobber (reg:CC FLAGS_REG))
3609 (clobber (match_operand:SI 2 "register_operand" ""))]
3610 "reload_completed"
3611 [(const_int 0)]
3612 {
3613 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3614
3615 emit_move_insn (operands[3], operands[1]);
3616
3617 /* Generate a cltd if possible and doing so it profitable. */
3618 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3619 && true_regnum (operands[1]) == AX_REG
3620 && true_regnum (operands[2]) == DX_REG)
3621 {
3622 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3623 }
3624 else
3625 {
3626 emit_move_insn (operands[2], operands[1]);
3627 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3628 }
3629 emit_move_insn (operands[4], operands[2]);
3630 DONE;
3631 })
3632
3633 ;; Extend to register case. Optimize case where source and destination
3634 ;; registers match and cases where we can use cltd.
3635 (define_split
3636 [(set (match_operand:DI 0 "register_operand" "")
3637 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3638 (clobber (reg:CC FLAGS_REG))
3639 (clobber (match_scratch:SI 2 ""))]
3640 "reload_completed"
3641 [(const_int 0)]
3642 {
3643 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3644
3645 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3646 emit_move_insn (operands[3], operands[1]);
3647
3648 /* Generate a cltd if possible and doing so it profitable. */
3649 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3650 && true_regnum (operands[3]) == AX_REG
3651 && true_regnum (operands[4]) == DX_REG)
3652 {
3653 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3654 DONE;
3655 }
3656
3657 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3658 emit_move_insn (operands[4], operands[1]);
3659
3660 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3661 DONE;
3662 })
3663
3664 (define_insn "extend<mode>di2"
3665 [(set (match_operand:DI 0 "register_operand" "=r")
3666 (sign_extend:DI
3667 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3668 "TARGET_64BIT"
3669 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3670 [(set_attr "type" "imovx")
3671 (set_attr "mode" "DI")])
3672
3673 (define_insn "extendhisi2"
3674 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3675 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3676 ""
3677 {
3678 switch (get_attr_prefix_0f (insn))
3679 {
3680 case 0:
3681 return "{cwtl|cwde}";
3682 default:
3683 return "movs{wl|x}\t{%1, %0|%0, %1}";
3684 }
3685 }
3686 [(set_attr "type" "imovx")
3687 (set_attr "mode" "SI")
3688 (set (attr "prefix_0f")
3689 ;; movsx is short decodable while cwtl is vector decoded.
3690 (if_then_else (and (eq_attr "cpu" "!k6")
3691 (eq_attr "alternative" "0"))
3692 (const_string "0")
3693 (const_string "1")))
3694 (set (attr "modrm")
3695 (if_then_else (eq_attr "prefix_0f" "0")
3696 (const_string "0")
3697 (const_string "1")))])
3698
3699 (define_insn "*extendhisi2_zext"
3700 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3701 (zero_extend:DI
3702 (sign_extend:SI
3703 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3704 "TARGET_64BIT"
3705 {
3706 switch (get_attr_prefix_0f (insn))
3707 {
3708 case 0:
3709 return "{cwtl|cwde}";
3710 default:
3711 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3712 }
3713 }
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "SI")
3716 (set (attr "prefix_0f")
3717 ;; movsx is short decodable while cwtl is vector decoded.
3718 (if_then_else (and (eq_attr "cpu" "!k6")
3719 (eq_attr "alternative" "0"))
3720 (const_string "0")
3721 (const_string "1")))
3722 (set (attr "modrm")
3723 (if_then_else (eq_attr "prefix_0f" "0")
3724 (const_string "0")
3725 (const_string "1")))])
3726
3727 (define_insn "extendqisi2"
3728 [(set (match_operand:SI 0 "register_operand" "=r")
3729 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3730 ""
3731 "movs{bl|x}\t{%1, %0|%0, %1}"
3732 [(set_attr "type" "imovx")
3733 (set_attr "mode" "SI")])
3734
3735 (define_insn "*extendqisi2_zext"
3736 [(set (match_operand:DI 0 "register_operand" "=r")
3737 (zero_extend:DI
3738 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3739 "TARGET_64BIT"
3740 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3743
3744 (define_insn "extendqihi2"
3745 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3746 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3747 ""
3748 {
3749 switch (get_attr_prefix_0f (insn))
3750 {
3751 case 0:
3752 return "{cbtw|cbw}";
3753 default:
3754 return "movs{bw|x}\t{%1, %0|%0, %1}";
3755 }
3756 }
3757 [(set_attr "type" "imovx")
3758 (set_attr "mode" "HI")
3759 (set (attr "prefix_0f")
3760 ;; movsx is short decodable while cwtl is vector decoded.
3761 (if_then_else (and (eq_attr "cpu" "!k6")
3762 (eq_attr "alternative" "0"))
3763 (const_string "0")
3764 (const_string "1")))
3765 (set (attr "modrm")
3766 (if_then_else (eq_attr "prefix_0f" "0")
3767 (const_string "0")
3768 (const_string "1")))])
3769 \f
3770 ;; Conversions between float and double.
3771
3772 ;; These are all no-ops in the model used for the 80387.
3773 ;; So just emit moves.
3774
3775 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3776 (define_split
3777 [(set (match_operand:DF 0 "push_operand" "")
3778 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3779 "reload_completed"
3780 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3781 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3782
3783 (define_split
3784 [(set (match_operand:XF 0 "push_operand" "")
3785 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3786 "reload_completed"
3787 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3788 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3789 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3790
3791 (define_expand "extendsfdf2"
3792 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3793 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3794 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3795 {
3796 /* ??? Needed for compress_float_constant since all fp constants
3797 are TARGET_LEGITIMATE_CONSTANT_P. */
3798 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3799 {
3800 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3801 && standard_80387_constant_p (operands[1]) > 0)
3802 {
3803 operands[1] = simplify_const_unary_operation
3804 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3805 emit_move_insn_1 (operands[0], operands[1]);
3806 DONE;
3807 }
3808 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3809 }
3810 })
3811
3812 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3813 cvtss2sd:
3814 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3815 cvtps2pd xmm2,xmm1
3816 We do the conversion post reload to avoid producing of 128bit spills
3817 that might lead to ICE on 32bit target. The sequence unlikely combine
3818 anyway. */
3819 (define_split
3820 [(set (match_operand:DF 0 "register_operand" "")
3821 (float_extend:DF
3822 (match_operand:SF 1 "nonimmediate_operand" "")))]
3823 "TARGET_USE_VECTOR_FP_CONVERTS
3824 && optimize_insn_for_speed_p ()
3825 && reload_completed && SSE_REG_P (operands[0])"
3826 [(set (match_dup 2)
3827 (float_extend:V2DF
3828 (vec_select:V2SF
3829 (match_dup 3)
3830 (parallel [(const_int 0) (const_int 1)]))))]
3831 {
3832 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3833 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3834 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3835 Try to avoid move when unpacking can be done in source. */
3836 if (REG_P (operands[1]))
3837 {
3838 /* If it is unsafe to overwrite upper half of source, we need
3839 to move to destination and unpack there. */
3840 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3841 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3842 && true_regnum (operands[0]) != true_regnum (operands[1]))
3843 {
3844 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3845 emit_move_insn (tmp, operands[1]);
3846 }
3847 else
3848 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3849 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3850 operands[3]));
3851 }
3852 else
3853 emit_insn (gen_vec_setv4sf_0 (operands[3],
3854 CONST0_RTX (V4SFmode), operands[1]));
3855 })
3856
3857 (define_insn "*extendsfdf2_mixed"
3858 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3859 (float_extend:DF
3860 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3861 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3862 {
3863 switch (which_alternative)
3864 {
3865 case 0:
3866 case 1:
3867 return output_387_reg_move (insn, operands);
3868
3869 case 2:
3870 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3871
3872 default:
3873 gcc_unreachable ();
3874 }
3875 }
3876 [(set_attr "type" "fmov,fmov,ssecvt")
3877 (set_attr "prefix" "orig,orig,maybe_vex")
3878 (set_attr "mode" "SF,XF,DF")])
3879
3880 (define_insn "*extendsfdf2_sse"
3881 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3882 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3883 "TARGET_SSE2 && TARGET_SSE_MATH"
3884 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3885 [(set_attr "type" "ssecvt")
3886 (set_attr "prefix" "maybe_vex")
3887 (set_attr "mode" "DF")])
3888
3889 (define_insn "*extendsfdf2_i387"
3890 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3891 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3892 "TARGET_80387"
3893 "* return output_387_reg_move (insn, operands);"
3894 [(set_attr "type" "fmov")
3895 (set_attr "mode" "SF,XF")])
3896
3897 (define_expand "extend<mode>xf2"
3898 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3899 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3900 "TARGET_80387"
3901 {
3902 /* ??? Needed for compress_float_constant since all fp constants
3903 are TARGET_LEGITIMATE_CONSTANT_P. */
3904 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3905 {
3906 if (standard_80387_constant_p (operands[1]) > 0)
3907 {
3908 operands[1] = simplify_const_unary_operation
3909 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3910 emit_move_insn_1 (operands[0], operands[1]);
3911 DONE;
3912 }
3913 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3914 }
3915 })
3916
3917 (define_insn "*extend<mode>xf2_i387"
3918 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3919 (float_extend:XF
3920 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3921 "TARGET_80387"
3922 "* return output_387_reg_move (insn, operands);"
3923 [(set_attr "type" "fmov")
3924 (set_attr "mode" "<MODE>,XF")])
3925
3926 ;; %%% This seems bad bad news.
3927 ;; This cannot output into an f-reg because there is no way to be sure
3928 ;; of truncating in that case. Otherwise this is just like a simple move
3929 ;; insn. So we pretend we can output to a reg in order to get better
3930 ;; register preferencing, but we really use a stack slot.
3931
3932 ;; Conversion from DFmode to SFmode.
3933
3934 (define_expand "truncdfsf2"
3935 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3936 (float_truncate:SF
3937 (match_operand:DF 1 "nonimmediate_operand" "")))]
3938 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3939 {
3940 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3941 ;
3942 else if (flag_unsafe_math_optimizations)
3943 ;
3944 else
3945 {
3946 enum ix86_stack_slot slot = (virtuals_instantiated
3947 ? SLOT_TEMP
3948 : SLOT_VIRTUAL);
3949 rtx temp = assign_386_stack_local (SFmode, slot);
3950 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3951 DONE;
3952 }
3953 })
3954
3955 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3956 cvtsd2ss:
3957 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3958 cvtpd2ps xmm2,xmm1
3959 We do the conversion post reload to avoid producing of 128bit spills
3960 that might lead to ICE on 32bit target. The sequence unlikely combine
3961 anyway. */
3962 (define_split
3963 [(set (match_operand:SF 0 "register_operand" "")
3964 (float_truncate:SF
3965 (match_operand:DF 1 "nonimmediate_operand" "")))]
3966 "TARGET_USE_VECTOR_FP_CONVERTS
3967 && optimize_insn_for_speed_p ()
3968 && reload_completed && SSE_REG_P (operands[0])"
3969 [(set (match_dup 2)
3970 (vec_concat:V4SF
3971 (float_truncate:V2SF
3972 (match_dup 4))
3973 (match_dup 3)))]
3974 {
3975 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3976 operands[3] = CONST0_RTX (V2SFmode);
3977 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3978 /* Use movsd for loading from memory, unpcklpd for registers.
3979 Try to avoid move when unpacking can be done in source, or SSE3
3980 movddup is available. */
3981 if (REG_P (operands[1]))
3982 {
3983 if (!TARGET_SSE3
3984 && true_regnum (operands[0]) != true_regnum (operands[1])
3985 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3986 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3987 {
3988 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3989 emit_move_insn (tmp, operands[1]);
3990 operands[1] = tmp;
3991 }
3992 else if (!TARGET_SSE3)
3993 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3994 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3995 }
3996 else
3997 emit_insn (gen_sse2_loadlpd (operands[4],
3998 CONST0_RTX (V2DFmode), operands[1]));
3999 })
4000
4001 (define_expand "truncdfsf2_with_temp"
4002 [(parallel [(set (match_operand:SF 0 "" "")
4003 (float_truncate:SF (match_operand:DF 1 "" "")))
4004 (clobber (match_operand:SF 2 "" ""))])])
4005
4006 (define_insn "*truncdfsf_fast_mixed"
4007 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4008 (float_truncate:SF
4009 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4010 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4011 {
4012 switch (which_alternative)
4013 {
4014 case 0:
4015 return output_387_reg_move (insn, operands);
4016 case 1:
4017 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4018 default:
4019 gcc_unreachable ();
4020 }
4021 }
4022 [(set_attr "type" "fmov,ssecvt")
4023 (set_attr "prefix" "orig,maybe_vex")
4024 (set_attr "mode" "SF")])
4025
4026 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4027 ;; because nothing we do here is unsafe.
4028 (define_insn "*truncdfsf_fast_sse"
4029 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4030 (float_truncate:SF
4031 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4032 "TARGET_SSE2 && TARGET_SSE_MATH"
4033 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4034 [(set_attr "type" "ssecvt")
4035 (set_attr "prefix" "maybe_vex")
4036 (set_attr "mode" "SF")])
4037
4038 (define_insn "*truncdfsf_fast_i387"
4039 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4040 (float_truncate:SF
4041 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4042 "TARGET_80387 && flag_unsafe_math_optimizations"
4043 "* return output_387_reg_move (insn, operands);"
4044 [(set_attr "type" "fmov")
4045 (set_attr "mode" "SF")])
4046
4047 (define_insn "*truncdfsf_mixed"
4048 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4049 (float_truncate:SF
4050 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4051 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4052 "TARGET_MIX_SSE_I387"
4053 {
4054 switch (which_alternative)
4055 {
4056 case 0:
4057 return output_387_reg_move (insn, operands);
4058 case 1:
4059 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4060
4061 default:
4062 return "#";
4063 }
4064 }
4065 [(set_attr "isa" "*,sse2,*,*,*")
4066 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4067 (set_attr "unit" "*,*,i387,i387,i387")
4068 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4069 (set_attr "mode" "SF")])
4070
4071 (define_insn "*truncdfsf_i387"
4072 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4073 (float_truncate:SF
4074 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4075 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4076 "TARGET_80387"
4077 {
4078 switch (which_alternative)
4079 {
4080 case 0:
4081 return output_387_reg_move (insn, operands);
4082
4083 default:
4084 return "#";
4085 }
4086 }
4087 [(set_attr "type" "fmov,multi,multi,multi")
4088 (set_attr "unit" "*,i387,i387,i387")
4089 (set_attr "mode" "SF")])
4090
4091 (define_insn "*truncdfsf2_i387_1"
4092 [(set (match_operand:SF 0 "memory_operand" "=m")
4093 (float_truncate:SF
4094 (match_operand:DF 1 "register_operand" "f")))]
4095 "TARGET_80387
4096 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4097 && !TARGET_MIX_SSE_I387"
4098 "* return output_387_reg_move (insn, operands);"
4099 [(set_attr "type" "fmov")
4100 (set_attr "mode" "SF")])
4101
4102 (define_split
4103 [(set (match_operand:SF 0 "register_operand" "")
4104 (float_truncate:SF
4105 (match_operand:DF 1 "fp_register_operand" "")))
4106 (clobber (match_operand 2 "" ""))]
4107 "reload_completed"
4108 [(set (match_dup 2) (match_dup 1))
4109 (set (match_dup 0) (match_dup 2))]
4110 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4111
4112 ;; Conversion from XFmode to {SF,DF}mode
4113
4114 (define_expand "truncxf<mode>2"
4115 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4116 (float_truncate:MODEF
4117 (match_operand:XF 1 "register_operand" "")))
4118 (clobber (match_dup 2))])]
4119 "TARGET_80387"
4120 {
4121 if (flag_unsafe_math_optimizations)
4122 {
4123 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4124 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4125 if (reg != operands[0])
4126 emit_move_insn (operands[0], reg);
4127 DONE;
4128 }
4129 else
4130 {
4131 enum ix86_stack_slot slot = (virtuals_instantiated
4132 ? SLOT_TEMP
4133 : SLOT_VIRTUAL);
4134 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4135 }
4136 })
4137
4138 (define_insn "*truncxfsf2_mixed"
4139 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4140 (float_truncate:SF
4141 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4142 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4143 "TARGET_80387"
4144 {
4145 gcc_assert (!which_alternative);
4146 return output_387_reg_move (insn, operands);
4147 }
4148 [(set_attr "type" "fmov,multi,multi,multi")
4149 (set_attr "unit" "*,i387,i387,i387")
4150 (set_attr "mode" "SF")])
4151
4152 (define_insn "*truncxfdf2_mixed"
4153 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4154 (float_truncate:DF
4155 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4156 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4157 "TARGET_80387"
4158 {
4159 gcc_assert (!which_alternative);
4160 return output_387_reg_move (insn, operands);
4161 }
4162 [(set_attr "isa" "*,*,sse2,*")
4163 (set_attr "type" "fmov,multi,multi,multi")
4164 (set_attr "unit" "*,i387,i387,i387")
4165 (set_attr "mode" "DF")])
4166
4167 (define_insn "truncxf<mode>2_i387_noop"
4168 [(set (match_operand:MODEF 0 "register_operand" "=f")
4169 (float_truncate:MODEF
4170 (match_operand:XF 1 "register_operand" "f")))]
4171 "TARGET_80387 && flag_unsafe_math_optimizations"
4172 "* return output_387_reg_move (insn, operands);"
4173 [(set_attr "type" "fmov")
4174 (set_attr "mode" "<MODE>")])
4175
4176 (define_insn "*truncxf<mode>2_i387"
4177 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4178 (float_truncate:MODEF
4179 (match_operand:XF 1 "register_operand" "f")))]
4180 "TARGET_80387"
4181 "* return output_387_reg_move (insn, operands);"
4182 [(set_attr "type" "fmov")
4183 (set_attr "mode" "<MODE>")])
4184
4185 (define_split
4186 [(set (match_operand:MODEF 0 "register_operand" "")
4187 (float_truncate:MODEF
4188 (match_operand:XF 1 "register_operand" "")))
4189 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4190 "TARGET_80387 && reload_completed"
4191 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4192 (set (match_dup 0) (match_dup 2))])
4193
4194 (define_split
4195 [(set (match_operand:MODEF 0 "memory_operand" "")
4196 (float_truncate:MODEF
4197 (match_operand:XF 1 "register_operand" "")))
4198 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4199 "TARGET_80387"
4200 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4201 \f
4202 ;; Signed conversion to DImode.
4203
4204 (define_expand "fix_truncxfdi2"
4205 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4206 (fix:DI (match_operand:XF 1 "register_operand" "")))
4207 (clobber (reg:CC FLAGS_REG))])]
4208 "TARGET_80387"
4209 {
4210 if (TARGET_FISTTP)
4211 {
4212 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4213 DONE;
4214 }
4215 })
4216
4217 (define_expand "fix_trunc<mode>di2"
4218 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4219 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4220 (clobber (reg:CC FLAGS_REG))])]
4221 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4222 {
4223 if (TARGET_FISTTP
4224 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4225 {
4226 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4227 DONE;
4228 }
4229 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4230 {
4231 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4232 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4233 if (out != operands[0])
4234 emit_move_insn (operands[0], out);
4235 DONE;
4236 }
4237 })
4238
4239 ;; Signed conversion to SImode.
4240
4241 (define_expand "fix_truncxfsi2"
4242 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4243 (fix:SI (match_operand:XF 1 "register_operand" "")))
4244 (clobber (reg:CC FLAGS_REG))])]
4245 "TARGET_80387"
4246 {
4247 if (TARGET_FISTTP)
4248 {
4249 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4250 DONE;
4251 }
4252 })
4253
4254 (define_expand "fix_trunc<mode>si2"
4255 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4256 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4257 (clobber (reg:CC FLAGS_REG))])]
4258 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4259 {
4260 if (TARGET_FISTTP
4261 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4262 {
4263 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4264 DONE;
4265 }
4266 if (SSE_FLOAT_MODE_P (<MODE>mode))
4267 {
4268 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4269 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4270 if (out != operands[0])
4271 emit_move_insn (operands[0], out);
4272 DONE;
4273 }
4274 })
4275
4276 ;; Signed conversion to HImode.
4277
4278 (define_expand "fix_trunc<mode>hi2"
4279 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4280 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4281 (clobber (reg:CC FLAGS_REG))])]
4282 "TARGET_80387
4283 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4284 {
4285 if (TARGET_FISTTP)
4286 {
4287 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4288 DONE;
4289 }
4290 })
4291
4292 ;; Unsigned conversion to SImode.
4293
4294 (define_expand "fixuns_trunc<mode>si2"
4295 [(parallel
4296 [(set (match_operand:SI 0 "register_operand" "")
4297 (unsigned_fix:SI
4298 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4299 (use (match_dup 2))
4300 (clobber (match_scratch:<ssevecmode> 3 ""))
4301 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4302 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4303 {
4304 enum machine_mode mode = <MODE>mode;
4305 enum machine_mode vecmode = <ssevecmode>mode;
4306 REAL_VALUE_TYPE TWO31r;
4307 rtx two31;
4308
4309 if (optimize_insn_for_size_p ())
4310 FAIL;
4311
4312 real_ldexp (&TWO31r, &dconst1, 31);
4313 two31 = const_double_from_real_value (TWO31r, mode);
4314 two31 = ix86_build_const_vector (vecmode, true, two31);
4315 operands[2] = force_reg (vecmode, two31);
4316 })
4317
4318 (define_insn_and_split "*fixuns_trunc<mode>_1"
4319 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4320 (unsigned_fix:SI
4321 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4322 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4323 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4324 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4325 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4326 && optimize_function_for_speed_p (cfun)"
4327 "#"
4328 "&& reload_completed"
4329 [(const_int 0)]
4330 {
4331 ix86_split_convert_uns_si_sse (operands);
4332 DONE;
4333 })
4334
4335 ;; Unsigned conversion to HImode.
4336 ;; Without these patterns, we'll try the unsigned SI conversion which
4337 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4338
4339 (define_expand "fixuns_trunc<mode>hi2"
4340 [(set (match_dup 2)
4341 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4342 (set (match_operand:HI 0 "nonimmediate_operand" "")
4343 (subreg:HI (match_dup 2) 0))]
4344 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4345 "operands[2] = gen_reg_rtx (SImode);")
4346
4347 ;; When SSE is available, it is always faster to use it!
4348 (define_insn "fix_trunc<mode>di_sse"
4349 [(set (match_operand:DI 0 "register_operand" "=r,r")
4350 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4351 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4352 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4353 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4354 [(set_attr "type" "sseicvt")
4355 (set_attr "prefix" "maybe_vex")
4356 (set_attr "prefix_rex" "1")
4357 (set_attr "mode" "<MODE>")
4358 (set_attr "athlon_decode" "double,vector")
4359 (set_attr "amdfam10_decode" "double,double")
4360 (set_attr "bdver1_decode" "double,double")])
4361
4362 (define_insn "fix_trunc<mode>si_sse"
4363 [(set (match_operand:SI 0 "register_operand" "=r,r")
4364 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4365 "SSE_FLOAT_MODE_P (<MODE>mode)
4366 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4367 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4368 [(set_attr "type" "sseicvt")
4369 (set_attr "prefix" "maybe_vex")
4370 (set_attr "mode" "<MODE>")
4371 (set_attr "athlon_decode" "double,vector")
4372 (set_attr "amdfam10_decode" "double,double")
4373 (set_attr "bdver1_decode" "double,double")])
4374
4375 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4376 (define_peephole2
4377 [(set (match_operand:MODEF 0 "register_operand" "")
4378 (match_operand:MODEF 1 "memory_operand" ""))
4379 (set (match_operand:SWI48x 2 "register_operand" "")
4380 (fix:SWI48x (match_dup 0)))]
4381 "TARGET_SHORTEN_X87_SSE
4382 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4383 && peep2_reg_dead_p (2, operands[0])"
4384 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4385
4386 ;; Avoid vector decoded forms of the instruction.
4387 (define_peephole2
4388 [(match_scratch:DF 2 "x")
4389 (set (match_operand:SWI48x 0 "register_operand" "")
4390 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4391 "TARGET_SSE2 && 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_peephole2
4396 [(match_scratch:SF 2 "x")
4397 (set (match_operand:SWI48x 0 "register_operand" "")
4398 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4399 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4400 [(set (match_dup 2) (match_dup 1))
4401 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4402
4403 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4404 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4405 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4406 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4407 && TARGET_FISTTP
4408 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4409 && (TARGET_64BIT || <MODE>mode != DImode))
4410 && TARGET_SSE_MATH)
4411 && can_create_pseudo_p ()"
4412 "#"
4413 "&& 1"
4414 [(const_int 0)]
4415 {
4416 if (memory_operand (operands[0], VOIDmode))
4417 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4418 else
4419 {
4420 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4421 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4422 operands[1],
4423 operands[2]));
4424 }
4425 DONE;
4426 }
4427 [(set_attr "type" "fisttp")
4428 (set_attr "mode" "<MODE>")])
4429
4430 (define_insn "fix_trunc<mode>_i387_fisttp"
4431 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4432 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4433 (clobber (match_scratch:XF 2 "=&1f"))]
4434 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4435 && TARGET_FISTTP
4436 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4437 && (TARGET_64BIT || <MODE>mode != DImode))
4438 && TARGET_SSE_MATH)"
4439 "* return output_fix_trunc (insn, operands, true);"
4440 [(set_attr "type" "fisttp")
4441 (set_attr "mode" "<MODE>")])
4442
4443 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4444 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4445 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4446 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4447 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4448 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4449 && TARGET_FISTTP
4450 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4451 && (TARGET_64BIT || <MODE>mode != DImode))
4452 && TARGET_SSE_MATH)"
4453 "#"
4454 [(set_attr "type" "fisttp")
4455 (set_attr "mode" "<MODE>")])
4456
4457 (define_split
4458 [(set (match_operand:SWI248x 0 "register_operand" "")
4459 (fix:SWI248x (match_operand 1 "register_operand" "")))
4460 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4461 (clobber (match_scratch 3 ""))]
4462 "reload_completed"
4463 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4464 (clobber (match_dup 3))])
4465 (set (match_dup 0) (match_dup 2))])
4466
4467 (define_split
4468 [(set (match_operand:SWI248x 0 "memory_operand" "")
4469 (fix:SWI248x (match_operand 1 "register_operand" "")))
4470 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4471 (clobber (match_scratch 3 ""))]
4472 "reload_completed"
4473 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4474 (clobber (match_dup 3))])])
4475
4476 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4477 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4478 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4479 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4480 ;; function in i386.c.
4481 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4482 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4483 (fix:SWI248x (match_operand 1 "register_operand" "")))
4484 (clobber (reg:CC FLAGS_REG))]
4485 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4486 && !TARGET_FISTTP
4487 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && (TARGET_64BIT || <MODE>mode != DImode))
4489 && can_create_pseudo_p ()"
4490 "#"
4491 "&& 1"
4492 [(const_int 0)]
4493 {
4494 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4495
4496 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4497 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4498 if (memory_operand (operands[0], VOIDmode))
4499 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4500 operands[2], operands[3]));
4501 else
4502 {
4503 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4504 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4505 operands[2], operands[3],
4506 operands[4]));
4507 }
4508 DONE;
4509 }
4510 [(set_attr "type" "fistp")
4511 (set_attr "i387_cw" "trunc")
4512 (set_attr "mode" "<MODE>")])
4513
4514 (define_insn "fix_truncdi_i387"
4515 [(set (match_operand:DI 0 "memory_operand" "=m")
4516 (fix:DI (match_operand 1 "register_operand" "f")))
4517 (use (match_operand:HI 2 "memory_operand" "m"))
4518 (use (match_operand:HI 3 "memory_operand" "m"))
4519 (clobber (match_scratch:XF 4 "=&1f"))]
4520 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4521 && !TARGET_FISTTP
4522 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4523 "* return output_fix_trunc (insn, operands, false);"
4524 [(set_attr "type" "fistp")
4525 (set_attr "i387_cw" "trunc")
4526 (set_attr "mode" "DI")])
4527
4528 (define_insn "fix_truncdi_i387_with_temp"
4529 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4530 (fix:DI (match_operand 1 "register_operand" "f,f")))
4531 (use (match_operand:HI 2 "memory_operand" "m,m"))
4532 (use (match_operand:HI 3 "memory_operand" "m,m"))
4533 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4534 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4535 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && !TARGET_FISTTP
4537 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4538 "#"
4539 [(set_attr "type" "fistp")
4540 (set_attr "i387_cw" "trunc")
4541 (set_attr "mode" "DI")])
4542
4543 (define_split
4544 [(set (match_operand:DI 0 "register_operand" "")
4545 (fix:DI (match_operand 1 "register_operand" "")))
4546 (use (match_operand:HI 2 "memory_operand" ""))
4547 (use (match_operand:HI 3 "memory_operand" ""))
4548 (clobber (match_operand:DI 4 "memory_operand" ""))
4549 (clobber (match_scratch 5 ""))]
4550 "reload_completed"
4551 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4552 (use (match_dup 2))
4553 (use (match_dup 3))
4554 (clobber (match_dup 5))])
4555 (set (match_dup 0) (match_dup 4))])
4556
4557 (define_split
4558 [(set (match_operand:DI 0 "memory_operand" "")
4559 (fix:DI (match_operand 1 "register_operand" "")))
4560 (use (match_operand:HI 2 "memory_operand" ""))
4561 (use (match_operand:HI 3 "memory_operand" ""))
4562 (clobber (match_operand:DI 4 "memory_operand" ""))
4563 (clobber (match_scratch 5 ""))]
4564 "reload_completed"
4565 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4566 (use (match_dup 2))
4567 (use (match_dup 3))
4568 (clobber (match_dup 5))])])
4569
4570 (define_insn "fix_trunc<mode>_i387"
4571 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4572 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4573 (use (match_operand:HI 2 "memory_operand" "m"))
4574 (use (match_operand:HI 3 "memory_operand" "m"))]
4575 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4576 && !TARGET_FISTTP
4577 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4578 "* return output_fix_trunc (insn, operands, false);"
4579 [(set_attr "type" "fistp")
4580 (set_attr "i387_cw" "trunc")
4581 (set_attr "mode" "<MODE>")])
4582
4583 (define_insn "fix_trunc<mode>_i387_with_temp"
4584 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4585 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4586 (use (match_operand:HI 2 "memory_operand" "m,m"))
4587 (use (match_operand:HI 3 "memory_operand" "m,m"))
4588 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4589 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4590 && !TARGET_FISTTP
4591 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4592 "#"
4593 [(set_attr "type" "fistp")
4594 (set_attr "i387_cw" "trunc")
4595 (set_attr "mode" "<MODE>")])
4596
4597 (define_split
4598 [(set (match_operand:SWI24 0 "register_operand" "")
4599 (fix:SWI24 (match_operand 1 "register_operand" "")))
4600 (use (match_operand:HI 2 "memory_operand" ""))
4601 (use (match_operand:HI 3 "memory_operand" ""))
4602 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4603 "reload_completed"
4604 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4605 (use (match_dup 2))
4606 (use (match_dup 3))])
4607 (set (match_dup 0) (match_dup 4))])
4608
4609 (define_split
4610 [(set (match_operand:SWI24 0 "memory_operand" "")
4611 (fix:SWI24 (match_operand 1 "register_operand" "")))
4612 (use (match_operand:HI 2 "memory_operand" ""))
4613 (use (match_operand:HI 3 "memory_operand" ""))
4614 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4615 "reload_completed"
4616 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4617 (use (match_dup 2))
4618 (use (match_dup 3))])])
4619
4620 (define_insn "x86_fnstcw_1"
4621 [(set (match_operand:HI 0 "memory_operand" "=m")
4622 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4623 "TARGET_80387"
4624 "fnstcw\t%0"
4625 [(set (attr "length")
4626 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4627 (set_attr "mode" "HI")
4628 (set_attr "unit" "i387")
4629 (set_attr "bdver1_decode" "vector")])
4630
4631 (define_insn "x86_fldcw_1"
4632 [(set (reg:HI FPCR_REG)
4633 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4634 "TARGET_80387"
4635 "fldcw\t%0"
4636 [(set (attr "length")
4637 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4638 (set_attr "mode" "HI")
4639 (set_attr "unit" "i387")
4640 (set_attr "athlon_decode" "vector")
4641 (set_attr "amdfam10_decode" "vector")
4642 (set_attr "bdver1_decode" "vector")])
4643 \f
4644 ;; Conversion between fixed point and floating point.
4645
4646 ;; Even though we only accept memory inputs, the backend _really_
4647 ;; wants to be able to do this between registers.
4648
4649 (define_expand "floathi<mode>2"
4650 [(set (match_operand:X87MODEF 0 "register_operand" "")
4651 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4652 "TARGET_80387
4653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4654 || TARGET_MIX_SSE_I387)")
4655
4656 ;; Pre-reload splitter to add memory clobber to the pattern.
4657 (define_insn_and_split "*floathi<mode>2_1"
4658 [(set (match_operand:X87MODEF 0 "register_operand" "")
4659 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4660 "TARGET_80387
4661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4662 || TARGET_MIX_SSE_I387)
4663 && can_create_pseudo_p ()"
4664 "#"
4665 "&& 1"
4666 [(parallel [(set (match_dup 0)
4667 (float:X87MODEF (match_dup 1)))
4668 (clobber (match_dup 2))])]
4669 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4670
4671 (define_insn "*floathi<mode>2_i387_with_temp"
4672 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4673 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4674 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4675 "TARGET_80387
4676 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4677 || TARGET_MIX_SSE_I387)"
4678 "#"
4679 [(set_attr "type" "fmov,multi")
4680 (set_attr "mode" "<MODE>")
4681 (set_attr "unit" "*,i387")
4682 (set_attr "fp_int_src" "true")])
4683
4684 (define_insn "*floathi<mode>2_i387"
4685 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4686 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4687 "TARGET_80387
4688 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4689 || TARGET_MIX_SSE_I387)"
4690 "fild%Z1\t%1"
4691 [(set_attr "type" "fmov")
4692 (set_attr "mode" "<MODE>")
4693 (set_attr "fp_int_src" "true")])
4694
4695 (define_split
4696 [(set (match_operand:X87MODEF 0 "register_operand" "")
4697 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4698 (clobber (match_operand:HI 2 "memory_operand" ""))]
4699 "TARGET_80387
4700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4701 || TARGET_MIX_SSE_I387)
4702 && reload_completed"
4703 [(set (match_dup 2) (match_dup 1))
4704 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4705
4706 (define_split
4707 [(set (match_operand:X87MODEF 0 "register_operand" "")
4708 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4709 (clobber (match_operand:HI 2 "memory_operand" ""))]
4710 "TARGET_80387
4711 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4712 || TARGET_MIX_SSE_I387)
4713 && reload_completed"
4714 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4715
4716 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4717 [(set (match_operand:X87MODEF 0 "register_operand" "")
4718 (float:X87MODEF
4719 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4720 "TARGET_80387
4721 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4722 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4723 {
4724 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4725 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4726 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4727 {
4728 rtx reg = gen_reg_rtx (XFmode);
4729 rtx (*insn)(rtx, rtx);
4730
4731 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4732
4733 if (<X87MODEF:MODE>mode == SFmode)
4734 insn = gen_truncxfsf2;
4735 else if (<X87MODEF:MODE>mode == DFmode)
4736 insn = gen_truncxfdf2;
4737 else
4738 gcc_unreachable ();
4739
4740 emit_insn (insn (operands[0], reg));
4741 DONE;
4742 }
4743 })
4744
4745 ;; Pre-reload splitter to add memory clobber to the pattern.
4746 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4747 [(set (match_operand:X87MODEF 0 "register_operand" "")
4748 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4749 "((TARGET_80387
4750 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4751 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4752 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4753 || TARGET_MIX_SSE_I387))
4754 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4755 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4756 && ((<SWI48x:MODE>mode == SImode
4757 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4758 && optimize_function_for_speed_p (cfun)
4759 && flag_trapping_math)
4760 || !(TARGET_INTER_UNIT_CONVERSIONS
4761 || optimize_function_for_size_p (cfun)))))
4762 && can_create_pseudo_p ()"
4763 "#"
4764 "&& 1"
4765 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4766 (clobber (match_dup 2))])]
4767 {
4768 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4769
4770 /* Avoid store forwarding (partial memory) stall penalty
4771 by passing DImode value through XMM registers. */
4772 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4773 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4774 && optimize_function_for_speed_p (cfun))
4775 {
4776 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4777 operands[1],
4778 operands[2]));
4779 DONE;
4780 }
4781 })
4782
4783 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4784 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4785 (float:MODEF
4786 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4787 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4788 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4789 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4790 "#"
4791 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4792 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4793 (set_attr "unit" "*,i387,*,*,*")
4794 (set_attr "athlon_decode" "*,*,double,direct,double")
4795 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4796 (set_attr "bdver1_decode" "*,*,double,direct,double")
4797 (set_attr "fp_int_src" "true")])
4798
4799 (define_insn "*floatsi<mode>2_vector_mixed"
4800 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4801 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4802 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4803 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4804 "@
4805 fild%Z1\t%1
4806 #"
4807 [(set_attr "type" "fmov,sseicvt")
4808 (set_attr "mode" "<MODE>,<ssevecmode>")
4809 (set_attr "unit" "i387,*")
4810 (set_attr "athlon_decode" "*,direct")
4811 (set_attr "amdfam10_decode" "*,double")
4812 (set_attr "bdver1_decode" "*,direct")
4813 (set_attr "fp_int_src" "true")])
4814
4815 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4816 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4817 (float:MODEF
4818 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4819 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4820 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4821 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4822 "#"
4823 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4824 (set_attr "mode" "<MODEF:MODE>")
4825 (set_attr "unit" "*,i387,*,*")
4826 (set_attr "athlon_decode" "*,*,double,direct")
4827 (set_attr "amdfam10_decode" "*,*,vector,double")
4828 (set_attr "bdver1_decode" "*,*,double,direct")
4829 (set_attr "fp_int_src" "true")])
4830
4831 (define_split
4832 [(set (match_operand:MODEF 0 "register_operand" "")
4833 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4834 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4835 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4836 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4837 && TARGET_INTER_UNIT_CONVERSIONS
4838 && reload_completed
4839 && (SSE_REG_P (operands[0])
4840 || (GET_CODE (operands[0]) == SUBREG
4841 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4842 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4843
4844 (define_split
4845 [(set (match_operand:MODEF 0 "register_operand" "")
4846 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4847 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4848 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4849 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4850 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4851 && reload_completed
4852 && (SSE_REG_P (operands[0])
4853 || (GET_CODE (operands[0]) == SUBREG
4854 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4855 [(set (match_dup 2) (match_dup 1))
4856 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4857
4858 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4859 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4860 (float:MODEF
4861 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4862 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4863 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4864 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4865 "@
4866 fild%Z1\t%1
4867 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4868 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4869 [(set_attr "type" "fmov,sseicvt,sseicvt")
4870 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4871 (set_attr "mode" "<MODEF:MODE>")
4872 (set (attr "prefix_rex")
4873 (if_then_else
4874 (and (eq_attr "prefix" "maybe_vex")
4875 (match_test "<SWI48x:MODE>mode == DImode"))
4876 (const_string "1")
4877 (const_string "*")))
4878 (set_attr "unit" "i387,*,*")
4879 (set_attr "athlon_decode" "*,double,direct")
4880 (set_attr "amdfam10_decode" "*,vector,double")
4881 (set_attr "bdver1_decode" "*,double,direct")
4882 (set_attr "fp_int_src" "true")])
4883
4884 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4885 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4886 (float:MODEF
4887 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4888 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4889 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4890 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4891 "@
4892 fild%Z1\t%1
4893 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4894 [(set_attr "type" "fmov,sseicvt")
4895 (set_attr "prefix" "orig,maybe_vex")
4896 (set_attr "mode" "<MODEF:MODE>")
4897 (set (attr "prefix_rex")
4898 (if_then_else
4899 (and (eq_attr "prefix" "maybe_vex")
4900 (match_test "<SWI48x:MODE>mode == DImode"))
4901 (const_string "1")
4902 (const_string "*")))
4903 (set_attr "athlon_decode" "*,direct")
4904 (set_attr "amdfam10_decode" "*,double")
4905 (set_attr "bdver1_decode" "*,direct")
4906 (set_attr "fp_int_src" "true")])
4907
4908 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4909 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4910 (float:MODEF
4911 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4912 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4913 "TARGET_SSE2 && TARGET_SSE_MATH
4914 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4915 "#"
4916 [(set_attr "type" "sseicvt")
4917 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4918 (set_attr "athlon_decode" "double,direct,double")
4919 (set_attr "amdfam10_decode" "vector,double,double")
4920 (set_attr "bdver1_decode" "double,direct,double")
4921 (set_attr "fp_int_src" "true")])
4922
4923 (define_insn "*floatsi<mode>2_vector_sse"
4924 [(set (match_operand:MODEF 0 "register_operand" "=x")
4925 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4926 "TARGET_SSE2 && TARGET_SSE_MATH
4927 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4928 "#"
4929 [(set_attr "type" "sseicvt")
4930 (set_attr "mode" "<MODE>")
4931 (set_attr "athlon_decode" "direct")
4932 (set_attr "amdfam10_decode" "double")
4933 (set_attr "bdver1_decode" "direct")
4934 (set_attr "fp_int_src" "true")])
4935
4936 (define_split
4937 [(set (match_operand:MODEF 0 "register_operand" "")
4938 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4939 (clobber (match_operand:SI 2 "memory_operand" ""))]
4940 "TARGET_SSE2 && TARGET_SSE_MATH
4941 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4942 && reload_completed
4943 && (SSE_REG_P (operands[0])
4944 || (GET_CODE (operands[0]) == SUBREG
4945 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4946 [(const_int 0)]
4947 {
4948 rtx op1 = operands[1];
4949
4950 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4951 <MODE>mode, 0);
4952 if (GET_CODE (op1) == SUBREG)
4953 op1 = SUBREG_REG (op1);
4954
4955 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4956 {
4957 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4958 emit_insn (gen_sse2_loadld (operands[4],
4959 CONST0_RTX (V4SImode), operands[1]));
4960 }
4961 /* We can ignore possible trapping value in the
4962 high part of SSE register for non-trapping math. */
4963 else if (SSE_REG_P (op1) && !flag_trapping_math)
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4965 else
4966 {
4967 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4968 emit_move_insn (operands[2], operands[1]);
4969 emit_insn (gen_sse2_loadld (operands[4],
4970 CONST0_RTX (V4SImode), operands[2]));
4971 }
4972 if (<ssevecmode>mode == V4SFmode)
4973 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4974 else
4975 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4976 DONE;
4977 })
4978
4979 (define_split
4980 [(set (match_operand:MODEF 0 "register_operand" "")
4981 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4982 (clobber (match_operand:SI 2 "memory_operand" ""))]
4983 "TARGET_SSE2 && TARGET_SSE_MATH
4984 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4985 && reload_completed
4986 && (SSE_REG_P (operands[0])
4987 || (GET_CODE (operands[0]) == SUBREG
4988 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4989 [(const_int 0)]
4990 {
4991 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4992 <MODE>mode, 0);
4993 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4994
4995 emit_insn (gen_sse2_loadld (operands[4],
4996 CONST0_RTX (V4SImode), operands[1]));
4997 if (<ssevecmode>mode == V4SFmode)
4998 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4999 else
5000 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5001 DONE;
5002 })
5003
5004 (define_split
5005 [(set (match_operand:MODEF 0 "register_operand" "")
5006 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5007 "TARGET_SSE2 && TARGET_SSE_MATH
5008 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5009 && reload_completed
5010 && (SSE_REG_P (operands[0])
5011 || (GET_CODE (operands[0]) == SUBREG
5012 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5013 [(const_int 0)]
5014 {
5015 rtx op1 = operands[1];
5016
5017 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5018 <MODE>mode, 0);
5019 if (GET_CODE (op1) == SUBREG)
5020 op1 = SUBREG_REG (op1);
5021
5022 if (GENERAL_REG_P (op1))
5023 {
5024 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5025 if (TARGET_INTER_UNIT_MOVES)
5026 emit_insn (gen_sse2_loadld (operands[4],
5027 CONST0_RTX (V4SImode), operands[1]));
5028 else
5029 {
5030 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5031 operands[1]);
5032 emit_insn (gen_sse2_loadld (operands[4],
5033 CONST0_RTX (V4SImode), operands[5]));
5034 ix86_free_from_memory (GET_MODE (operands[1]));
5035 }
5036 }
5037 /* We can ignore possible trapping value in the
5038 high part of SSE register for non-trapping math. */
5039 else if (SSE_REG_P (op1) && !flag_trapping_math)
5040 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5041 else
5042 gcc_unreachable ();
5043 if (<ssevecmode>mode == V4SFmode)
5044 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5045 else
5046 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5047 DONE;
5048 })
5049
5050 (define_split
5051 [(set (match_operand:MODEF 0 "register_operand" "")
5052 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5053 "TARGET_SSE2 && TARGET_SSE_MATH
5054 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5055 && reload_completed
5056 && (SSE_REG_P (operands[0])
5057 || (GET_CODE (operands[0]) == SUBREG
5058 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5059 [(const_int 0)]
5060 {
5061 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5062 <MODE>mode, 0);
5063 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5064
5065 emit_insn (gen_sse2_loadld (operands[4],
5066 CONST0_RTX (V4SImode), operands[1]));
5067 if (<ssevecmode>mode == V4SFmode)
5068 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5069 else
5070 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5071 DONE;
5072 })
5073
5074 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5075 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5076 (float:MODEF
5077 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5078 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5079 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5080 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5081 "#"
5082 [(set_attr "type" "sseicvt")
5083 (set_attr "mode" "<MODEF:MODE>")
5084 (set_attr "athlon_decode" "double,direct")
5085 (set_attr "amdfam10_decode" "vector,double")
5086 (set_attr "bdver1_decode" "double,direct")
5087 (set_attr "fp_int_src" "true")])
5088
5089 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5090 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5091 (float:MODEF
5092 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5093 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5094 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5095 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5096 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5097 [(set_attr "type" "sseicvt")
5098 (set_attr "prefix" "maybe_vex")
5099 (set_attr "mode" "<MODEF:MODE>")
5100 (set (attr "prefix_rex")
5101 (if_then_else
5102 (and (eq_attr "prefix" "maybe_vex")
5103 (match_test "<SWI48x:MODE>mode == DImode"))
5104 (const_string "1")
5105 (const_string "*")))
5106 (set_attr "athlon_decode" "double,direct")
5107 (set_attr "amdfam10_decode" "vector,double")
5108 (set_attr "bdver1_decode" "double,direct")
5109 (set_attr "fp_int_src" "true")])
5110
5111 (define_split
5112 [(set (match_operand:MODEF 0 "register_operand" "")
5113 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5114 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5115 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5116 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5117 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5118 && reload_completed
5119 && (SSE_REG_P (operands[0])
5120 || (GET_CODE (operands[0]) == SUBREG
5121 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5122 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5123
5124 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5125 [(set (match_operand:MODEF 0 "register_operand" "=x")
5126 (float:MODEF
5127 (match_operand:SWI48x 1 "memory_operand" "m")))]
5128 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5129 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5130 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5131 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5132 [(set_attr "type" "sseicvt")
5133 (set_attr "prefix" "maybe_vex")
5134 (set_attr "mode" "<MODEF:MODE>")
5135 (set (attr "prefix_rex")
5136 (if_then_else
5137 (and (eq_attr "prefix" "maybe_vex")
5138 (match_test "<SWI48x:MODE>mode == DImode"))
5139 (const_string "1")
5140 (const_string "*")))
5141 (set_attr "athlon_decode" "direct")
5142 (set_attr "amdfam10_decode" "double")
5143 (set_attr "bdver1_decode" "direct")
5144 (set_attr "fp_int_src" "true")])
5145
5146 (define_split
5147 [(set (match_operand:MODEF 0 "register_operand" "")
5148 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5149 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5150 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5151 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5152 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5153 && reload_completed
5154 && (SSE_REG_P (operands[0])
5155 || (GET_CODE (operands[0]) == SUBREG
5156 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5157 [(set (match_dup 2) (match_dup 1))
5158 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5159
5160 (define_split
5161 [(set (match_operand:MODEF 0 "register_operand" "")
5162 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5163 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5164 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5165 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5166 && reload_completed
5167 && (SSE_REG_P (operands[0])
5168 || (GET_CODE (operands[0]) == SUBREG
5169 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5170 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5171
5172 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5173 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5174 (float:X87MODEF
5175 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5176 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5177 "TARGET_80387
5178 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5179 "@
5180 fild%Z1\t%1
5181 #"
5182 [(set_attr "type" "fmov,multi")
5183 (set_attr "mode" "<X87MODEF:MODE>")
5184 (set_attr "unit" "*,i387")
5185 (set_attr "fp_int_src" "true")])
5186
5187 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5188 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5189 (float:X87MODEF
5190 (match_operand:SWI48x 1 "memory_operand" "m")))]
5191 "TARGET_80387
5192 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5193 "fild%Z1\t%1"
5194 [(set_attr "type" "fmov")
5195 (set_attr "mode" "<X87MODEF:MODE>")
5196 (set_attr "fp_int_src" "true")])
5197
5198 (define_split
5199 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5200 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5201 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5202 "TARGET_80387
5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5204 && reload_completed"
5205 [(set (match_dup 2) (match_dup 1))
5206 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5207
5208 (define_split
5209 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5210 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5211 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5212 "TARGET_80387
5213 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5214 && reload_completed"
5215 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5216
5217 ;; Avoid store forwarding (partial memory) stall penalty
5218 ;; by passing DImode value through XMM registers. */
5219
5220 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5221 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5222 (float:X87MODEF
5223 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5224 (clobber (match_scratch:V4SI 3 "=X,x"))
5225 (clobber (match_scratch:V4SI 4 "=X,x"))
5226 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5227 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5228 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5229 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5230 "#"
5231 [(set_attr "type" "multi")
5232 (set_attr "mode" "<X87MODEF:MODE>")
5233 (set_attr "unit" "i387")
5234 (set_attr "fp_int_src" "true")])
5235
5236 (define_split
5237 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5238 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5239 (clobber (match_scratch:V4SI 3 ""))
5240 (clobber (match_scratch:V4SI 4 ""))
5241 (clobber (match_operand:DI 2 "memory_operand" ""))]
5242 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5243 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5244 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5245 && reload_completed"
5246 [(set (match_dup 2) (match_dup 3))
5247 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5248 {
5249 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5250 Assemble the 64-bit DImode value in an xmm register. */
5251 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5252 gen_rtx_SUBREG (SImode, operands[1], 0)));
5253 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5254 gen_rtx_SUBREG (SImode, operands[1], 4)));
5255 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5256 operands[4]));
5257
5258 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5259 })
5260
5261 (define_split
5262 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5263 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5264 (clobber (match_scratch:V4SI 3 ""))
5265 (clobber (match_scratch:V4SI 4 ""))
5266 (clobber (match_operand:DI 2 "memory_operand" ""))]
5267 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5268 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5269 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5270 && reload_completed"
5271 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5272
5273 ;; Avoid store forwarding (partial memory) stall penalty by extending
5274 ;; SImode value to DImode through XMM register instead of pushing two
5275 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5276 ;; targets benefit from this optimization. Also note that fild
5277 ;; loads from memory only.
5278
5279 (define_insn "*floatunssi<mode>2_1"
5280 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5281 (unsigned_float:X87MODEF
5282 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5283 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5284 (clobber (match_scratch:SI 3 "=X,x"))]
5285 "!TARGET_64BIT
5286 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5287 && TARGET_SSE"
5288 "#"
5289 [(set_attr "type" "multi")
5290 (set_attr "mode" "<MODE>")])
5291
5292 (define_split
5293 [(set (match_operand:X87MODEF 0 "register_operand" "")
5294 (unsigned_float:X87MODEF
5295 (match_operand:SI 1 "register_operand" "")))
5296 (clobber (match_operand:DI 2 "memory_operand" ""))
5297 (clobber (match_scratch:SI 3 ""))]
5298 "!TARGET_64BIT
5299 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5300 && TARGET_SSE
5301 && reload_completed"
5302 [(set (match_dup 2) (match_dup 1))
5303 (set (match_dup 0)
5304 (float:X87MODEF (match_dup 2)))]
5305 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5306
5307 (define_split
5308 [(set (match_operand:X87MODEF 0 "register_operand" "")
5309 (unsigned_float:X87MODEF
5310 (match_operand:SI 1 "memory_operand" "")))
5311 (clobber (match_operand:DI 2 "memory_operand" ""))
5312 (clobber (match_scratch:SI 3 ""))]
5313 "!TARGET_64BIT
5314 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5315 && TARGET_SSE
5316 && reload_completed"
5317 [(set (match_dup 2) (match_dup 3))
5318 (set (match_dup 0)
5319 (float:X87MODEF (match_dup 2)))]
5320 {
5321 emit_move_insn (operands[3], operands[1]);
5322 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5323 })
5324
5325 (define_expand "floatunssi<mode>2"
5326 [(parallel
5327 [(set (match_operand:X87MODEF 0 "register_operand" "")
5328 (unsigned_float:X87MODEF
5329 (match_operand:SI 1 "nonimmediate_operand" "")))
5330 (clobber (match_dup 2))
5331 (clobber (match_scratch:SI 3 ""))])]
5332 "!TARGET_64BIT
5333 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 && TARGET_SSE)
5335 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5336 {
5337 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5338 {
5339 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5340 DONE;
5341 }
5342 else
5343 {
5344 enum ix86_stack_slot slot = (virtuals_instantiated
5345 ? SLOT_TEMP
5346 : SLOT_VIRTUAL);
5347 operands[2] = assign_386_stack_local (DImode, slot);
5348 }
5349 })
5350
5351 (define_expand "floatunsdisf2"
5352 [(use (match_operand:SF 0 "register_operand" ""))
5353 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5354 "TARGET_64BIT && TARGET_SSE_MATH"
5355 "x86_emit_floatuns (operands); DONE;")
5356
5357 (define_expand "floatunsdidf2"
5358 [(use (match_operand:DF 0 "register_operand" ""))
5359 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5360 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5361 && TARGET_SSE2 && TARGET_SSE_MATH"
5362 {
5363 if (TARGET_64BIT)
5364 x86_emit_floatuns (operands);
5365 else
5366 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5367 DONE;
5368 })
5369 \f
5370 ;; Add instructions
5371
5372 (define_expand "add<mode>3"
5373 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5374 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5375 (match_operand:SDWIM 2 "<general_operand>" "")))]
5376 ""
5377 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5378
5379 (define_insn_and_split "*add<dwi>3_doubleword"
5380 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5381 (plus:<DWI>
5382 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5383 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5384 (clobber (reg:CC FLAGS_REG))]
5385 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5386 "#"
5387 "reload_completed"
5388 [(parallel [(set (reg:CC FLAGS_REG)
5389 (unspec:CC [(match_dup 1) (match_dup 2)]
5390 UNSPEC_ADD_CARRY))
5391 (set (match_dup 0)
5392 (plus:DWIH (match_dup 1) (match_dup 2)))])
5393 (parallel [(set (match_dup 3)
5394 (plus:DWIH
5395 (match_dup 4)
5396 (plus:DWIH
5397 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5398 (match_dup 5))))
5399 (clobber (reg:CC FLAGS_REG))])]
5400 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5401
5402 (define_insn "*add<mode>3_cc"
5403 [(set (reg:CC FLAGS_REG)
5404 (unspec:CC
5405 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5406 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5407 UNSPEC_ADD_CARRY))
5408 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5409 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5410 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5411 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5412 [(set_attr "type" "alu")
5413 (set_attr "mode" "<MODE>")])
5414
5415 (define_insn "addqi3_cc"
5416 [(set (reg:CC FLAGS_REG)
5417 (unspec:CC
5418 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5419 (match_operand:QI 2 "general_operand" "qn,qm")]
5420 UNSPEC_ADD_CARRY))
5421 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5422 (plus:QI (match_dup 1) (match_dup 2)))]
5423 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5424 "add{b}\t{%2, %0|%0, %2}"
5425 [(set_attr "type" "alu")
5426 (set_attr "mode" "QI")])
5427
5428 (define_insn_and_split "*lea_1"
5429 [(set (match_operand:SI 0 "register_operand" "=r")
5430 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5431 "TARGET_64BIT"
5432 "lea{l}\t{%E1, %0|%0, %E1}"
5433 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5434 [(const_int 0)]
5435 {
5436 ix86_split_lea_for_addr (operands, SImode);
5437 DONE;
5438 }
5439 [(set_attr "type" "lea")
5440 (set_attr "mode" "SI")])
5441
5442 (define_insn_and_split "*lea<mode>_2"
5443 [(set (match_operand:SWI48 0 "register_operand" "=r")
5444 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5445 ""
5446 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5447 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5448 [(const_int 0)]
5449 {
5450 ix86_split_lea_for_addr (operands, <MODE>mode);
5451 DONE;
5452 }
5453 [(set_attr "type" "lea")
5454 (set_attr "mode" "<MODE>")])
5455
5456 (define_insn "*lea_3_zext"
5457 [(set (match_operand:DI 0 "register_operand" "=r")
5458 (zero_extend:DI
5459 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5460 "TARGET_64BIT"
5461 "lea{l}\t{%E1, %k0|%k0, %E1}"
5462 [(set_attr "type" "lea")
5463 (set_attr "mode" "SI")])
5464
5465 (define_insn "*lea_4_zext"
5466 [(set (match_operand:DI 0 "register_operand" "=r")
5467 (zero_extend:DI
5468 (match_operand:SI 1 "lea_address_operand" "j")))]
5469 "TARGET_64BIT"
5470 "lea{l}\t{%E1, %k0|%k0, %E1}"
5471 [(set_attr "type" "lea")
5472 (set_attr "mode" "SI")])
5473
5474 (define_insn "*lea_5_zext"
5475 [(set (match_operand:DI 0 "register_operand" "=r")
5476 (and:DI
5477 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5478 (match_operand:DI 2 "const_32bit_mask" "n")))]
5479 "TARGET_64BIT"
5480 "lea{l}\t{%E1, %k0|%k0, %E1}"
5481 [(set_attr "type" "lea")
5482 (set_attr "mode" "SI")])
5483
5484 (define_insn "*lea_6_zext"
5485 [(set (match_operand:DI 0 "register_operand" "=r")
5486 (and:DI
5487 (match_operand:DI 1 "lea_address_operand" "p")
5488 (match_operand:DI 2 "const_32bit_mask" "n")))]
5489 "TARGET_64BIT"
5490 "lea{l}\t{%E1, %k0|%k0, %E1}"
5491 [(set_attr "type" "lea")
5492 (set_attr "mode" "SI")])
5493
5494 (define_insn "*add<mode>_1"
5495 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5496 (plus:SWI48
5497 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5498 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5499 (clobber (reg:CC FLAGS_REG))]
5500 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5501 {
5502 switch (get_attr_type (insn))
5503 {
5504 case TYPE_LEA:
5505 return "#";
5506
5507 case TYPE_INCDEC:
5508 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5509 if (operands[2] == const1_rtx)
5510 return "inc{<imodesuffix>}\t%0";
5511 else
5512 {
5513 gcc_assert (operands[2] == constm1_rtx);
5514 return "dec{<imodesuffix>}\t%0";
5515 }
5516
5517 default:
5518 /* For most processors, ADD is faster than LEA. This alternative
5519 was added to use ADD as much as possible. */
5520 if (which_alternative == 2)
5521 {
5522 rtx tmp;
5523 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5524 }
5525
5526 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5527 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5528 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5529
5530 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5531 }
5532 }
5533 [(set (attr "type")
5534 (cond [(eq_attr "alternative" "3")
5535 (const_string "lea")
5536 (match_operand:SWI48 2 "incdec_operand" "")
5537 (const_string "incdec")
5538 ]
5539 (const_string "alu")))
5540 (set (attr "length_immediate")
5541 (if_then_else
5542 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5543 (const_string "1")
5544 (const_string "*")))
5545 (set_attr "mode" "<MODE>")])
5546
5547 ;; It may seem that nonimmediate operand is proper one for operand 1.
5548 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5549 ;; we take care in ix86_binary_operator_ok to not allow two memory
5550 ;; operands so proper swapping will be done in reload. This allow
5551 ;; patterns constructed from addsi_1 to match.
5552
5553 (define_insn "addsi_1_zext"
5554 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5555 (zero_extend:DI
5556 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5557 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5558 (clobber (reg:CC FLAGS_REG))]
5559 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5560 {
5561 switch (get_attr_type (insn))
5562 {
5563 case TYPE_LEA:
5564 return "#";
5565
5566 case TYPE_INCDEC:
5567 if (operands[2] == const1_rtx)
5568 return "inc{l}\t%k0";
5569 else
5570 {
5571 gcc_assert (operands[2] == constm1_rtx);
5572 return "dec{l}\t%k0";
5573 }
5574
5575 default:
5576 /* For most processors, ADD is faster than LEA. This alternative
5577 was added to use ADD as much as possible. */
5578 if (which_alternative == 1)
5579 {
5580 rtx tmp;
5581 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5582 }
5583
5584 if (x86_maybe_negate_const_int (&operands[2], SImode))
5585 return "sub{l}\t{%2, %k0|%k0, %2}";
5586
5587 return "add{l}\t{%2, %k0|%k0, %2}";
5588 }
5589 }
5590 [(set (attr "type")
5591 (cond [(eq_attr "alternative" "2")
5592 (const_string "lea")
5593 (match_operand:SI 2 "incdec_operand" "")
5594 (const_string "incdec")
5595 ]
5596 (const_string "alu")))
5597 (set (attr "length_immediate")
5598 (if_then_else
5599 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5600 (const_string "1")
5601 (const_string "*")))
5602 (set_attr "mode" "SI")])
5603
5604 (define_insn "*addhi_1"
5605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5606 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5607 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5608 (clobber (reg:CC FLAGS_REG))]
5609 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5610 {
5611 switch (get_attr_type (insn))
5612 {
5613 case TYPE_LEA:
5614 return "#";
5615
5616 case TYPE_INCDEC:
5617 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5618 if (operands[2] == const1_rtx)
5619 return "inc{w}\t%0";
5620 else
5621 {
5622 gcc_assert (operands[2] == constm1_rtx);
5623 return "dec{w}\t%0";
5624 }
5625
5626 default:
5627 /* For most processors, ADD is faster than LEA. This alternative
5628 was added to use ADD as much as possible. */
5629 if (which_alternative == 2)
5630 {
5631 rtx tmp;
5632 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5633 }
5634
5635 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5636 if (x86_maybe_negate_const_int (&operands[2], HImode))
5637 return "sub{w}\t{%2, %0|%0, %2}";
5638
5639 return "add{w}\t{%2, %0|%0, %2}";
5640 }
5641 }
5642 [(set (attr "type")
5643 (cond [(eq_attr "alternative" "3")
5644 (const_string "lea")
5645 (match_operand:HI 2 "incdec_operand" "")
5646 (const_string "incdec")
5647 ]
5648 (const_string "alu")))
5649 (set (attr "length_immediate")
5650 (if_then_else
5651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5652 (const_string "1")
5653 (const_string "*")))
5654 (set_attr "mode" "HI,HI,HI,SI")])
5655
5656 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5657 (define_insn "*addqi_1"
5658 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5659 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5660 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5661 (clobber (reg:CC FLAGS_REG))]
5662 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5663 {
5664 bool widen = (which_alternative == 3 || which_alternative == 4);
5665
5666 switch (get_attr_type (insn))
5667 {
5668 case TYPE_LEA:
5669 return "#";
5670
5671 case TYPE_INCDEC:
5672 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5673 if (operands[2] == const1_rtx)
5674 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5675 else
5676 {
5677 gcc_assert (operands[2] == constm1_rtx);
5678 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5679 }
5680
5681 default:
5682 /* For most processors, ADD is faster than LEA. These alternatives
5683 were added to use ADD as much as possible. */
5684 if (which_alternative == 2 || which_alternative == 4)
5685 {
5686 rtx tmp;
5687 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5688 }
5689
5690 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5691 if (x86_maybe_negate_const_int (&operands[2], QImode))
5692 {
5693 if (widen)
5694 return "sub{l}\t{%2, %k0|%k0, %2}";
5695 else
5696 return "sub{b}\t{%2, %0|%0, %2}";
5697 }
5698 if (widen)
5699 return "add{l}\t{%k2, %k0|%k0, %k2}";
5700 else
5701 return "add{b}\t{%2, %0|%0, %2}";
5702 }
5703 }
5704 [(set (attr "type")
5705 (cond [(eq_attr "alternative" "5")
5706 (const_string "lea")
5707 (match_operand:QI 2 "incdec_operand" "")
5708 (const_string "incdec")
5709 ]
5710 (const_string "alu")))
5711 (set (attr "length_immediate")
5712 (if_then_else
5713 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5714 (const_string "1")
5715 (const_string "*")))
5716 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5717
5718 (define_insn "*addqi_1_slp"
5719 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5720 (plus:QI (match_dup 0)
5721 (match_operand:QI 1 "general_operand" "qn,qm")))
5722 (clobber (reg:CC FLAGS_REG))]
5723 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5724 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5725 {
5726 switch (get_attr_type (insn))
5727 {
5728 case TYPE_INCDEC:
5729 if (operands[1] == const1_rtx)
5730 return "inc{b}\t%0";
5731 else
5732 {
5733 gcc_assert (operands[1] == constm1_rtx);
5734 return "dec{b}\t%0";
5735 }
5736
5737 default:
5738 if (x86_maybe_negate_const_int (&operands[1], QImode))
5739 return "sub{b}\t{%1, %0|%0, %1}";
5740
5741 return "add{b}\t{%1, %0|%0, %1}";
5742 }
5743 }
5744 [(set (attr "type")
5745 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5746 (const_string "incdec")
5747 (const_string "alu1")))
5748 (set (attr "memory")
5749 (if_then_else (match_operand 1 "memory_operand" "")
5750 (const_string "load")
5751 (const_string "none")))
5752 (set_attr "mode" "QI")])
5753
5754 ;; Split non destructive adds if we cannot use lea.
5755 (define_split
5756 [(set (match_operand:SWI48 0 "register_operand" "")
5757 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5758 (match_operand:SWI48 2 "nonmemory_operand" "")))
5759 (clobber (reg:CC FLAGS_REG))]
5760 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5761 [(set (match_dup 0) (match_dup 1))
5762 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5763 (clobber (reg:CC FLAGS_REG))])])
5764
5765 ;; Convert add to the lea pattern to avoid flags dependency.
5766 (define_split
5767 [(set (match_operand:SWI 0 "register_operand" "")
5768 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5769 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5770 (clobber (reg:CC FLAGS_REG))]
5771 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5772 [(const_int 0)]
5773 {
5774 enum machine_mode mode = <MODE>mode;
5775 rtx pat;
5776
5777 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5778 {
5779 mode = SImode;
5780 operands[0] = gen_lowpart (mode, operands[0]);
5781 operands[1] = gen_lowpart (mode, operands[1]);
5782 operands[2] = gen_lowpart (mode, operands[2]);
5783 }
5784
5785 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5786
5787 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5788 DONE;
5789 })
5790
5791 ;; Convert add to the lea pattern to avoid flags dependency.
5792 (define_split
5793 [(set (match_operand:DI 0 "register_operand" "")
5794 (zero_extend:DI
5795 (plus:SI (match_operand:SI 1 "register_operand" "")
5796 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5797 (clobber (reg:CC FLAGS_REG))]
5798 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5799 [(set (match_dup 0)
5800 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5801
5802 (define_insn "*add<mode>_2"
5803 [(set (reg FLAGS_REG)
5804 (compare
5805 (plus:SWI
5806 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5807 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5808 (const_int 0)))
5809 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5810 (plus:SWI (match_dup 1) (match_dup 2)))]
5811 "ix86_match_ccmode (insn, CCGOCmode)
5812 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5813 {
5814 switch (get_attr_type (insn))
5815 {
5816 case TYPE_INCDEC:
5817 if (operands[2] == const1_rtx)
5818 return "inc{<imodesuffix>}\t%0";
5819 else
5820 {
5821 gcc_assert (operands[2] == constm1_rtx);
5822 return "dec{<imodesuffix>}\t%0";
5823 }
5824
5825 default:
5826 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5827 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5828
5829 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5830 }
5831 }
5832 [(set (attr "type")
5833 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5834 (const_string "incdec")
5835 (const_string "alu")))
5836 (set (attr "length_immediate")
5837 (if_then_else
5838 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5839 (const_string "1")
5840 (const_string "*")))
5841 (set_attr "mode" "<MODE>")])
5842
5843 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5844 (define_insn "*addsi_2_zext"
5845 [(set (reg FLAGS_REG)
5846 (compare
5847 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5848 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5849 (const_int 0)))
5850 (set (match_operand:DI 0 "register_operand" "=r")
5851 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5852 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5853 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5854 {
5855 switch (get_attr_type (insn))
5856 {
5857 case TYPE_INCDEC:
5858 if (operands[2] == const1_rtx)
5859 return "inc{l}\t%k0";
5860 else
5861 {
5862 gcc_assert (operands[2] == constm1_rtx);
5863 return "dec{l}\t%k0";
5864 }
5865
5866 default:
5867 if (x86_maybe_negate_const_int (&operands[2], SImode))
5868 return "sub{l}\t{%2, %k0|%k0, %2}";
5869
5870 return "add{l}\t{%2, %k0|%k0, %2}";
5871 }
5872 }
5873 [(set (attr "type")
5874 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5875 (const_string "incdec")
5876 (const_string "alu")))
5877 (set (attr "length_immediate")
5878 (if_then_else
5879 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5880 (const_string "1")
5881 (const_string "*")))
5882 (set_attr "mode" "SI")])
5883
5884 (define_insn "*add<mode>_3"
5885 [(set (reg FLAGS_REG)
5886 (compare
5887 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5888 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5889 (clobber (match_scratch:SWI 0 "=<r>"))]
5890 "ix86_match_ccmode (insn, CCZmode)
5891 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5892 {
5893 switch (get_attr_type (insn))
5894 {
5895 case TYPE_INCDEC:
5896 if (operands[2] == const1_rtx)
5897 return "inc{<imodesuffix>}\t%0";
5898 else
5899 {
5900 gcc_assert (operands[2] == constm1_rtx);
5901 return "dec{<imodesuffix>}\t%0";
5902 }
5903
5904 default:
5905 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5906 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5907
5908 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5909 }
5910 }
5911 [(set (attr "type")
5912 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5913 (const_string "incdec")
5914 (const_string "alu")))
5915 (set (attr "length_immediate")
5916 (if_then_else
5917 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5918 (const_string "1")
5919 (const_string "*")))
5920 (set_attr "mode" "<MODE>")])
5921
5922 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5923 (define_insn "*addsi_3_zext"
5924 [(set (reg FLAGS_REG)
5925 (compare
5926 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5927 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5928 (set (match_operand:DI 0 "register_operand" "=r")
5929 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5930 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5931 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5932 {
5933 switch (get_attr_type (insn))
5934 {
5935 case TYPE_INCDEC:
5936 if (operands[2] == const1_rtx)
5937 return "inc{l}\t%k0";
5938 else
5939 {
5940 gcc_assert (operands[2] == constm1_rtx);
5941 return "dec{l}\t%k0";
5942 }
5943
5944 default:
5945 if (x86_maybe_negate_const_int (&operands[2], SImode))
5946 return "sub{l}\t{%2, %k0|%k0, %2}";
5947
5948 return "add{l}\t{%2, %k0|%k0, %2}";
5949 }
5950 }
5951 [(set (attr "type")
5952 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5953 (const_string "incdec")
5954 (const_string "alu")))
5955 (set (attr "length_immediate")
5956 (if_then_else
5957 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5958 (const_string "1")
5959 (const_string "*")))
5960 (set_attr "mode" "SI")])
5961
5962 ; For comparisons against 1, -1 and 128, we may generate better code
5963 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5964 ; is matched then. We can't accept general immediate, because for
5965 ; case of overflows, the result is messed up.
5966 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5967 ; only for comparisons not depending on it.
5968
5969 (define_insn "*adddi_4"
5970 [(set (reg FLAGS_REG)
5971 (compare
5972 (match_operand:DI 1 "nonimmediate_operand" "0")
5973 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5974 (clobber (match_scratch:DI 0 "=rm"))]
5975 "TARGET_64BIT
5976 && ix86_match_ccmode (insn, CCGCmode)"
5977 {
5978 switch (get_attr_type (insn))
5979 {
5980 case TYPE_INCDEC:
5981 if (operands[2] == constm1_rtx)
5982 return "inc{q}\t%0";
5983 else
5984 {
5985 gcc_assert (operands[2] == const1_rtx);
5986 return "dec{q}\t%0";
5987 }
5988
5989 default:
5990 if (x86_maybe_negate_const_int (&operands[2], DImode))
5991 return "add{q}\t{%2, %0|%0, %2}";
5992
5993 return "sub{q}\t{%2, %0|%0, %2}";
5994 }
5995 }
5996 [(set (attr "type")
5997 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5998 (const_string "incdec")
5999 (const_string "alu")))
6000 (set (attr "length_immediate")
6001 (if_then_else
6002 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6003 (const_string "1")
6004 (const_string "*")))
6005 (set_attr "mode" "DI")])
6006
6007 ; For comparisons against 1, -1 and 128, we may generate better code
6008 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6009 ; is matched then. We can't accept general immediate, because for
6010 ; case of overflows, the result is messed up.
6011 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6012 ; only for comparisons not depending on it.
6013
6014 (define_insn "*add<mode>_4"
6015 [(set (reg FLAGS_REG)
6016 (compare
6017 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6018 (match_operand:SWI124 2 "const_int_operand" "n")))
6019 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6020 "ix86_match_ccmode (insn, CCGCmode)"
6021 {
6022 switch (get_attr_type (insn))
6023 {
6024 case TYPE_INCDEC:
6025 if (operands[2] == constm1_rtx)
6026 return "inc{<imodesuffix>}\t%0";
6027 else
6028 {
6029 gcc_assert (operands[2] == const1_rtx);
6030 return "dec{<imodesuffix>}\t%0";
6031 }
6032
6033 default:
6034 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6035 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6036
6037 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6038 }
6039 }
6040 [(set (attr "type")
6041 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6042 (const_string "incdec")
6043 (const_string "alu")))
6044 (set (attr "length_immediate")
6045 (if_then_else
6046 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6047 (const_string "1")
6048 (const_string "*")))
6049 (set_attr "mode" "<MODE>")])
6050
6051 (define_insn "*add<mode>_5"
6052 [(set (reg FLAGS_REG)
6053 (compare
6054 (plus:SWI
6055 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6056 (match_operand:SWI 2 "<general_operand>" "<g>"))
6057 (const_int 0)))
6058 (clobber (match_scratch:SWI 0 "=<r>"))]
6059 "ix86_match_ccmode (insn, CCGOCmode)
6060 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6061 {
6062 switch (get_attr_type (insn))
6063 {
6064 case TYPE_INCDEC:
6065 if (operands[2] == const1_rtx)
6066 return "inc{<imodesuffix>}\t%0";
6067 else
6068 {
6069 gcc_assert (operands[2] == constm1_rtx);
6070 return "dec{<imodesuffix>}\t%0";
6071 }
6072
6073 default:
6074 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6075 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6076
6077 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6078 }
6079 }
6080 [(set (attr "type")
6081 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6082 (const_string "incdec")
6083 (const_string "alu")))
6084 (set (attr "length_immediate")
6085 (if_then_else
6086 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6087 (const_string "1")
6088 (const_string "*")))
6089 (set_attr "mode" "<MODE>")])
6090
6091 (define_insn "*addqi_ext_1_rex64"
6092 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6093 (const_int 8)
6094 (const_int 8))
6095 (plus:SI
6096 (zero_extract:SI
6097 (match_operand 1 "ext_register_operand" "0")
6098 (const_int 8)
6099 (const_int 8))
6100 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6101 (clobber (reg:CC FLAGS_REG))]
6102 "TARGET_64BIT"
6103 {
6104 switch (get_attr_type (insn))
6105 {
6106 case TYPE_INCDEC:
6107 if (operands[2] == const1_rtx)
6108 return "inc{b}\t%h0";
6109 else
6110 {
6111 gcc_assert (operands[2] == constm1_rtx);
6112 return "dec{b}\t%h0";
6113 }
6114
6115 default:
6116 return "add{b}\t{%2, %h0|%h0, %2}";
6117 }
6118 }
6119 [(set (attr "type")
6120 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set_attr "modrm" "1")
6124 (set_attr "mode" "QI")])
6125
6126 (define_insn "addqi_ext_1"
6127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6128 (const_int 8)
6129 (const_int 8))
6130 (plus:SI
6131 (zero_extract:SI
6132 (match_operand 1 "ext_register_operand" "0")
6133 (const_int 8)
6134 (const_int 8))
6135 (match_operand:QI 2 "general_operand" "Qmn")))
6136 (clobber (reg:CC FLAGS_REG))]
6137 "!TARGET_64BIT"
6138 {
6139 switch (get_attr_type (insn))
6140 {
6141 case TYPE_INCDEC:
6142 if (operands[2] == const1_rtx)
6143 return "inc{b}\t%h0";
6144 else
6145 {
6146 gcc_assert (operands[2] == constm1_rtx);
6147 return "dec{b}\t%h0";
6148 }
6149
6150 default:
6151 return "add{b}\t{%2, %h0|%h0, %2}";
6152 }
6153 }
6154 [(set (attr "type")
6155 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6156 (const_string "incdec")
6157 (const_string "alu")))
6158 (set_attr "modrm" "1")
6159 (set_attr "mode" "QI")])
6160
6161 (define_insn "*addqi_ext_2"
6162 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6163 (const_int 8)
6164 (const_int 8))
6165 (plus:SI
6166 (zero_extract:SI
6167 (match_operand 1 "ext_register_operand" "%0")
6168 (const_int 8)
6169 (const_int 8))
6170 (zero_extract:SI
6171 (match_operand 2 "ext_register_operand" "Q")
6172 (const_int 8)
6173 (const_int 8))))
6174 (clobber (reg:CC FLAGS_REG))]
6175 ""
6176 "add{b}\t{%h2, %h0|%h0, %h2}"
6177 [(set_attr "type" "alu")
6178 (set_attr "mode" "QI")])
6179
6180 ;; The lea patterns for modes less than 32 bits need to be matched by
6181 ;; several insns converted to real lea by splitters.
6182
6183 (define_insn_and_split "*lea_general_1"
6184 [(set (match_operand 0 "register_operand" "=r")
6185 (plus (plus (match_operand 1 "index_register_operand" "l")
6186 (match_operand 2 "register_operand" "r"))
6187 (match_operand 3 "immediate_operand" "i")))]
6188 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6189 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6190 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6191 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6192 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6193 || GET_MODE (operands[3]) == VOIDmode)"
6194 "#"
6195 "&& reload_completed"
6196 [(const_int 0)]
6197 {
6198 enum machine_mode mode = SImode;
6199 rtx pat;
6200
6201 operands[0] = gen_lowpart (mode, operands[0]);
6202 operands[1] = gen_lowpart (mode, operands[1]);
6203 operands[2] = gen_lowpart (mode, operands[2]);
6204 operands[3] = gen_lowpart (mode, operands[3]);
6205
6206 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6207 operands[3]);
6208
6209 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6210 DONE;
6211 }
6212 [(set_attr "type" "lea")
6213 (set_attr "mode" "SI")])
6214
6215 (define_insn_and_split "*lea_general_2"
6216 [(set (match_operand 0 "register_operand" "=r")
6217 (plus (mult (match_operand 1 "index_register_operand" "l")
6218 (match_operand 2 "const248_operand" "n"))
6219 (match_operand 3 "nonmemory_operand" "ri")))]
6220 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6221 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6222 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6223 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6224 || GET_MODE (operands[3]) == VOIDmode)"
6225 "#"
6226 "&& reload_completed"
6227 [(const_int 0)]
6228 {
6229 enum machine_mode mode = SImode;
6230 rtx pat;
6231
6232 operands[0] = gen_lowpart (mode, operands[0]);
6233 operands[1] = gen_lowpart (mode, operands[1]);
6234 operands[3] = gen_lowpart (mode, operands[3]);
6235
6236 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6237 operands[3]);
6238
6239 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6240 DONE;
6241 }
6242 [(set_attr "type" "lea")
6243 (set_attr "mode" "SI")])
6244
6245 (define_insn_and_split "*lea_general_3"
6246 [(set (match_operand 0 "register_operand" "=r")
6247 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6248 (match_operand 2 "const248_operand" "n"))
6249 (match_operand 3 "register_operand" "r"))
6250 (match_operand 4 "immediate_operand" "i")))]
6251 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6252 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6253 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6254 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6255 "#"
6256 "&& reload_completed"
6257 [(const_int 0)]
6258 {
6259 enum machine_mode mode = SImode;
6260 rtx pat;
6261
6262 operands[0] = gen_lowpart (mode, operands[0]);
6263 operands[1] = gen_lowpart (mode, operands[1]);
6264 operands[3] = gen_lowpart (mode, operands[3]);
6265 operands[4] = gen_lowpart (mode, operands[4]);
6266
6267 pat = gen_rtx_PLUS (mode,
6268 gen_rtx_PLUS (mode,
6269 gen_rtx_MULT (mode, operands[1],
6270 operands[2]),
6271 operands[3]),
6272 operands[4]);
6273
6274 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6275 DONE;
6276 }
6277 [(set_attr "type" "lea")
6278 (set_attr "mode" "SI")])
6279
6280 (define_insn_and_split "*lea_general_4"
6281 [(set (match_operand 0 "register_operand" "=r")
6282 (any_or (ashift
6283 (match_operand 1 "index_register_operand" "l")
6284 (match_operand 2 "const_int_operand" "n"))
6285 (match_operand 3 "const_int_operand" "n")))]
6286 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6287 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6288 || GET_MODE (operands[0]) == SImode
6289 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6290 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6291 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6292 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6293 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6294 "#"
6295 "&& reload_completed"
6296 [(const_int 0)]
6297 {
6298 enum machine_mode mode = GET_MODE (operands[0]);
6299 rtx pat;
6300
6301 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6302 {
6303 mode = SImode;
6304 operands[0] = gen_lowpart (mode, operands[0]);
6305 operands[1] = gen_lowpart (mode, operands[1]);
6306 }
6307
6308 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6309
6310 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6311 INTVAL (operands[3]));
6312
6313 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6314 DONE;
6315 }
6316 [(set_attr "type" "lea")
6317 (set (attr "mode")
6318 (if_then_else (match_operand:DI 0 "" "")
6319 (const_string "DI")
6320 (const_string "SI")))])
6321 \f
6322 ;; Subtract instructions
6323
6324 (define_expand "sub<mode>3"
6325 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6326 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6327 (match_operand:SDWIM 2 "<general_operand>" "")))]
6328 ""
6329 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6330
6331 (define_insn_and_split "*sub<dwi>3_doubleword"
6332 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6333 (minus:<DWI>
6334 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6335 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6336 (clobber (reg:CC FLAGS_REG))]
6337 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6338 "#"
6339 "reload_completed"
6340 [(parallel [(set (reg:CC FLAGS_REG)
6341 (compare:CC (match_dup 1) (match_dup 2)))
6342 (set (match_dup 0)
6343 (minus:DWIH (match_dup 1) (match_dup 2)))])
6344 (parallel [(set (match_dup 3)
6345 (minus:DWIH
6346 (match_dup 4)
6347 (plus:DWIH
6348 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6349 (match_dup 5))))
6350 (clobber (reg:CC FLAGS_REG))])]
6351 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6352
6353 (define_insn "*sub<mode>_1"
6354 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6355 (minus:SWI
6356 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6357 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6358 (clobber (reg:CC FLAGS_REG))]
6359 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6360 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6361 [(set_attr "type" "alu")
6362 (set_attr "mode" "<MODE>")])
6363
6364 (define_insn "*subsi_1_zext"
6365 [(set (match_operand:DI 0 "register_operand" "=r")
6366 (zero_extend:DI
6367 (minus:SI (match_operand:SI 1 "register_operand" "0")
6368 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6369 (clobber (reg:CC FLAGS_REG))]
6370 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6371 "sub{l}\t{%2, %k0|%k0, %2}"
6372 [(set_attr "type" "alu")
6373 (set_attr "mode" "SI")])
6374
6375 (define_insn "*subqi_1_slp"
6376 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6377 (minus:QI (match_dup 0)
6378 (match_operand:QI 1 "general_operand" "qn,qm")))
6379 (clobber (reg:CC FLAGS_REG))]
6380 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6381 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6382 "sub{b}\t{%1, %0|%0, %1}"
6383 [(set_attr "type" "alu1")
6384 (set_attr "mode" "QI")])
6385
6386 (define_insn "*sub<mode>_2"
6387 [(set (reg FLAGS_REG)
6388 (compare
6389 (minus:SWI
6390 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6391 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6392 (const_int 0)))
6393 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6394 (minus:SWI (match_dup 1) (match_dup 2)))]
6395 "ix86_match_ccmode (insn, CCGOCmode)
6396 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6397 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6398 [(set_attr "type" "alu")
6399 (set_attr "mode" "<MODE>")])
6400
6401 (define_insn "*subsi_2_zext"
6402 [(set (reg FLAGS_REG)
6403 (compare
6404 (minus:SI (match_operand:SI 1 "register_operand" "0")
6405 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6406 (const_int 0)))
6407 (set (match_operand:DI 0 "register_operand" "=r")
6408 (zero_extend:DI
6409 (minus:SI (match_dup 1)
6410 (match_dup 2))))]
6411 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6412 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6413 "sub{l}\t{%2, %k0|%k0, %2}"
6414 [(set_attr "type" "alu")
6415 (set_attr "mode" "SI")])
6416
6417 (define_insn "*sub<mode>_3"
6418 [(set (reg FLAGS_REG)
6419 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6420 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6421 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6422 (minus:SWI (match_dup 1) (match_dup 2)))]
6423 "ix86_match_ccmode (insn, CCmode)
6424 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6425 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6426 [(set_attr "type" "alu")
6427 (set_attr "mode" "<MODE>")])
6428
6429 (define_insn "*subsi_3_zext"
6430 [(set (reg FLAGS_REG)
6431 (compare (match_operand:SI 1 "register_operand" "0")
6432 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6433 (set (match_operand:DI 0 "register_operand" "=r")
6434 (zero_extend:DI
6435 (minus:SI (match_dup 1)
6436 (match_dup 2))))]
6437 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6438 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6439 "sub{l}\t{%2, %1|%1, %2}"
6440 [(set_attr "type" "alu")
6441 (set_attr "mode" "SI")])
6442 \f
6443 ;; Add with carry and subtract with borrow
6444
6445 (define_expand "<plusminus_insn><mode>3_carry"
6446 [(parallel
6447 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6448 (plusminus:SWI
6449 (match_operand:SWI 1 "nonimmediate_operand" "")
6450 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6451 [(match_operand 3 "flags_reg_operand" "")
6452 (const_int 0)])
6453 (match_operand:SWI 2 "<general_operand>" ""))))
6454 (clobber (reg:CC FLAGS_REG))])]
6455 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6456
6457 (define_insn "*<plusminus_insn><mode>3_carry"
6458 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6459 (plusminus:SWI
6460 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6461 (plus:SWI
6462 (match_operator 3 "ix86_carry_flag_operator"
6463 [(reg FLAGS_REG) (const_int 0)])
6464 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6465 (clobber (reg:CC FLAGS_REG))]
6466 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6467 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6468 [(set_attr "type" "alu")
6469 (set_attr "use_carry" "1")
6470 (set_attr "pent_pair" "pu")
6471 (set_attr "mode" "<MODE>")])
6472
6473 (define_insn "*addsi3_carry_zext"
6474 [(set (match_operand:DI 0 "register_operand" "=r")
6475 (zero_extend:DI
6476 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6477 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6478 [(reg FLAGS_REG) (const_int 0)])
6479 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6480 (clobber (reg:CC FLAGS_REG))]
6481 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6482 "adc{l}\t{%2, %k0|%k0, %2}"
6483 [(set_attr "type" "alu")
6484 (set_attr "use_carry" "1")
6485 (set_attr "pent_pair" "pu")
6486 (set_attr "mode" "SI")])
6487
6488 (define_insn "*subsi3_carry_zext"
6489 [(set (match_operand:DI 0 "register_operand" "=r")
6490 (zero_extend:DI
6491 (minus:SI (match_operand:SI 1 "register_operand" "0")
6492 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6493 [(reg FLAGS_REG) (const_int 0)])
6494 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6497 "sbb{l}\t{%2, %k0|%k0, %2}"
6498 [(set_attr "type" "alu")
6499 (set_attr "pent_pair" "pu")
6500 (set_attr "mode" "SI")])
6501 \f
6502 ;; Overflow setting add and subtract instructions
6503
6504 (define_insn "*add<mode>3_cconly_overflow"
6505 [(set (reg:CCC FLAGS_REG)
6506 (compare:CCC
6507 (plus:SWI
6508 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6509 (match_operand:SWI 2 "<general_operand>" "<g>"))
6510 (match_dup 1)))
6511 (clobber (match_scratch:SWI 0 "=<r>"))]
6512 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6513 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6516
6517 (define_insn "*sub<mode>3_cconly_overflow"
6518 [(set (reg:CCC FLAGS_REG)
6519 (compare:CCC
6520 (minus:SWI
6521 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6522 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6523 (match_dup 0)))]
6524 ""
6525 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6526 [(set_attr "type" "icmp")
6527 (set_attr "mode" "<MODE>")])
6528
6529 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6530 [(set (reg:CCC FLAGS_REG)
6531 (compare:CCC
6532 (plusminus:SWI
6533 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6534 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6535 (match_dup 1)))
6536 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6537 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6538 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6539 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6540 [(set_attr "type" "alu")
6541 (set_attr "mode" "<MODE>")])
6542
6543 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6544 [(set (reg:CCC FLAGS_REG)
6545 (compare:CCC
6546 (plusminus:SI
6547 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6548 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6549 (match_dup 1)))
6550 (set (match_operand:DI 0 "register_operand" "=r")
6551 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6552 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6553 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6554 [(set_attr "type" "alu")
6555 (set_attr "mode" "SI")])
6556
6557 ;; The patterns that match these are at the end of this file.
6558
6559 (define_expand "<plusminus_insn>xf3"
6560 [(set (match_operand:XF 0 "register_operand" "")
6561 (plusminus:XF
6562 (match_operand:XF 1 "register_operand" "")
6563 (match_operand:XF 2 "register_operand" "")))]
6564 "TARGET_80387")
6565
6566 (define_expand "<plusminus_insn><mode>3"
6567 [(set (match_operand:MODEF 0 "register_operand" "")
6568 (plusminus:MODEF
6569 (match_operand:MODEF 1 "register_operand" "")
6570 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6571 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6572 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6573 \f
6574 ;; Multiply instructions
6575
6576 (define_expand "mul<mode>3"
6577 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6578 (mult:SWIM248
6579 (match_operand:SWIM248 1 "register_operand" "")
6580 (match_operand:SWIM248 2 "<general_operand>" "")))
6581 (clobber (reg:CC FLAGS_REG))])])
6582
6583 (define_expand "mulqi3"
6584 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6585 (mult:QI
6586 (match_operand:QI 1 "register_operand" "")
6587 (match_operand:QI 2 "nonimmediate_operand" "")))
6588 (clobber (reg:CC FLAGS_REG))])]
6589 "TARGET_QIMODE_MATH")
6590
6591 ;; On AMDFAM10
6592 ;; IMUL reg32/64, reg32/64, imm8 Direct
6593 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6594 ;; IMUL reg32/64, reg32/64, imm32 Direct
6595 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6596 ;; IMUL reg32/64, reg32/64 Direct
6597 ;; IMUL reg32/64, mem32/64 Direct
6598 ;;
6599 ;; On BDVER1, all above IMULs use DirectPath
6600
6601 (define_insn "*mul<mode>3_1"
6602 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6603 (mult:SWI48
6604 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6605 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6606 (clobber (reg:CC FLAGS_REG))]
6607 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6608 "@
6609 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6610 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6611 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6612 [(set_attr "type" "imul")
6613 (set_attr "prefix_0f" "0,0,1")
6614 (set (attr "athlon_decode")
6615 (cond [(eq_attr "cpu" "athlon")
6616 (const_string "vector")
6617 (eq_attr "alternative" "1")
6618 (const_string "vector")
6619 (and (eq_attr "alternative" "2")
6620 (match_operand 1 "memory_operand" ""))
6621 (const_string "vector")]
6622 (const_string "direct")))
6623 (set (attr "amdfam10_decode")
6624 (cond [(and (eq_attr "alternative" "0,1")
6625 (match_operand 1 "memory_operand" ""))
6626 (const_string "vector")]
6627 (const_string "direct")))
6628 (set_attr "bdver1_decode" "direct")
6629 (set_attr "mode" "<MODE>")])
6630
6631 (define_insn "*mulsi3_1_zext"
6632 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6633 (zero_extend:DI
6634 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6635 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "TARGET_64BIT
6638 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6639 "@
6640 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6641 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6642 imul{l}\t{%2, %k0|%k0, %2}"
6643 [(set_attr "type" "imul")
6644 (set_attr "prefix_0f" "0,0,1")
6645 (set (attr "athlon_decode")
6646 (cond [(eq_attr "cpu" "athlon")
6647 (const_string "vector")
6648 (eq_attr "alternative" "1")
6649 (const_string "vector")
6650 (and (eq_attr "alternative" "2")
6651 (match_operand 1 "memory_operand" ""))
6652 (const_string "vector")]
6653 (const_string "direct")))
6654 (set (attr "amdfam10_decode")
6655 (cond [(and (eq_attr "alternative" "0,1")
6656 (match_operand 1 "memory_operand" ""))
6657 (const_string "vector")]
6658 (const_string "direct")))
6659 (set_attr "bdver1_decode" "direct")
6660 (set_attr "mode" "SI")])
6661
6662 ;; On AMDFAM10
6663 ;; IMUL reg16, reg16, imm8 VectorPath
6664 ;; IMUL reg16, mem16, imm8 VectorPath
6665 ;; IMUL reg16, reg16, imm16 VectorPath
6666 ;; IMUL reg16, mem16, imm16 VectorPath
6667 ;; IMUL reg16, reg16 Direct
6668 ;; IMUL reg16, mem16 Direct
6669 ;;
6670 ;; On BDVER1, all HI MULs use DoublePath
6671
6672 (define_insn "*mulhi3_1"
6673 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6674 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6675 (match_operand:HI 2 "general_operand" "K,n,mr")))
6676 (clobber (reg:CC FLAGS_REG))]
6677 "TARGET_HIMODE_MATH
6678 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6679 "@
6680 imul{w}\t{%2, %1, %0|%0, %1, %2}
6681 imul{w}\t{%2, %1, %0|%0, %1, %2}
6682 imul{w}\t{%2, %0|%0, %2}"
6683 [(set_attr "type" "imul")
6684 (set_attr "prefix_0f" "0,0,1")
6685 (set (attr "athlon_decode")
6686 (cond [(eq_attr "cpu" "athlon")
6687 (const_string "vector")
6688 (eq_attr "alternative" "1,2")
6689 (const_string "vector")]
6690 (const_string "direct")))
6691 (set (attr "amdfam10_decode")
6692 (cond [(eq_attr "alternative" "0,1")
6693 (const_string "vector")]
6694 (const_string "direct")))
6695 (set_attr "bdver1_decode" "double")
6696 (set_attr "mode" "HI")])
6697
6698 ;;On AMDFAM10 and BDVER1
6699 ;; MUL reg8 Direct
6700 ;; MUL mem8 Direct
6701
6702 (define_insn "*mulqi3_1"
6703 [(set (match_operand:QI 0 "register_operand" "=a")
6704 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6705 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6706 (clobber (reg:CC FLAGS_REG))]
6707 "TARGET_QIMODE_MATH
6708 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6709 "mul{b}\t%2"
6710 [(set_attr "type" "imul")
6711 (set_attr "length_immediate" "0")
6712 (set (attr "athlon_decode")
6713 (if_then_else (eq_attr "cpu" "athlon")
6714 (const_string "vector")
6715 (const_string "direct")))
6716 (set_attr "amdfam10_decode" "direct")
6717 (set_attr "bdver1_decode" "direct")
6718 (set_attr "mode" "QI")])
6719
6720 (define_expand "<u>mul<mode><dwi>3"
6721 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6722 (mult:<DWI>
6723 (any_extend:<DWI>
6724 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6725 (any_extend:<DWI>
6726 (match_operand:DWIH 2 "register_operand" ""))))
6727 (clobber (reg:CC FLAGS_REG))])])
6728
6729 (define_expand "<u>mulqihi3"
6730 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6731 (mult:HI
6732 (any_extend:HI
6733 (match_operand:QI 1 "nonimmediate_operand" ""))
6734 (any_extend:HI
6735 (match_operand:QI 2 "register_operand" ""))))
6736 (clobber (reg:CC FLAGS_REG))])]
6737 "TARGET_QIMODE_MATH")
6738
6739 (define_insn "*bmi2_umulditi3_1"
6740 [(set (match_operand:DI 0 "register_operand" "=r")
6741 (mult:DI
6742 (match_operand:DI 2 "nonimmediate_operand" "%d")
6743 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6744 (set (match_operand:DI 1 "register_operand" "=r")
6745 (truncate:DI
6746 (lshiftrt:TI
6747 (mult:TI (zero_extend:TI (match_dup 2))
6748 (zero_extend:TI (match_dup 3)))
6749 (const_int 64))))]
6750 "TARGET_64BIT && TARGET_BMI2
6751 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6752 "mulx\t{%3, %0, %1|%1, %0, %3}"
6753 [(set_attr "type" "imulx")
6754 (set_attr "prefix" "vex")
6755 (set_attr "mode" "DI")])
6756
6757 (define_insn "*bmi2_umulsidi3_1"
6758 [(set (match_operand:SI 0 "register_operand" "=r")
6759 (mult:SI
6760 (match_operand:SI 2 "nonimmediate_operand" "%d")
6761 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6762 (set (match_operand:SI 1 "register_operand" "=r")
6763 (truncate:SI
6764 (lshiftrt:DI
6765 (mult:DI (zero_extend:DI (match_dup 2))
6766 (zero_extend:DI (match_dup 3)))
6767 (const_int 32))))]
6768 "!TARGET_64BIT && TARGET_BMI2
6769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6770 "mulx\t{%3, %0, %1|%1, %0, %3}"
6771 [(set_attr "type" "imulx")
6772 (set_attr "prefix" "vex")
6773 (set_attr "mode" "SI")])
6774
6775 (define_insn "*umul<mode><dwi>3_1"
6776 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6777 (mult:<DWI>
6778 (zero_extend:<DWI>
6779 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6780 (zero_extend:<DWI>
6781 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6782 (clobber (reg:CC FLAGS_REG))]
6783 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6784 "@
6785 mul{<imodesuffix>}\t%2
6786 #"
6787 [(set_attr "isa" "*,bmi2")
6788 (set_attr "type" "imul,imulx")
6789 (set_attr "length_immediate" "0,*")
6790 (set (attr "athlon_decode")
6791 (cond [(eq_attr "alternative" "0")
6792 (if_then_else (eq_attr "cpu" "athlon")
6793 (const_string "vector")
6794 (const_string "double"))]
6795 (const_string "*")))
6796 (set_attr "amdfam10_decode" "double,*")
6797 (set_attr "bdver1_decode" "direct,*")
6798 (set_attr "prefix" "orig,vex")
6799 (set_attr "mode" "<MODE>")])
6800
6801 ;; Convert mul to the mulx pattern to avoid flags dependency.
6802 (define_split
6803 [(set (match_operand:<DWI> 0 "register_operand" "")
6804 (mult:<DWI>
6805 (zero_extend:<DWI>
6806 (match_operand:DWIH 1 "register_operand" ""))
6807 (zero_extend:<DWI>
6808 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6809 (clobber (reg:CC FLAGS_REG))]
6810 "TARGET_BMI2 && reload_completed
6811 && true_regnum (operands[1]) == DX_REG"
6812 [(parallel [(set (match_dup 3)
6813 (mult:DWIH (match_dup 1) (match_dup 2)))
6814 (set (match_dup 4)
6815 (truncate:DWIH
6816 (lshiftrt:<DWI>
6817 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6818 (zero_extend:<DWI> (match_dup 2)))
6819 (match_dup 5))))])]
6820 {
6821 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6822
6823 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6824 })
6825
6826 (define_insn "*mul<mode><dwi>3_1"
6827 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6828 (mult:<DWI>
6829 (sign_extend:<DWI>
6830 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6831 (sign_extend:<DWI>
6832 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6833 (clobber (reg:CC FLAGS_REG))]
6834 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6835 "imul{<imodesuffix>}\t%2"
6836 [(set_attr "type" "imul")
6837 (set_attr "length_immediate" "0")
6838 (set (attr "athlon_decode")
6839 (if_then_else (eq_attr "cpu" "athlon")
6840 (const_string "vector")
6841 (const_string "double")))
6842 (set_attr "amdfam10_decode" "double")
6843 (set_attr "bdver1_decode" "direct")
6844 (set_attr "mode" "<MODE>")])
6845
6846 (define_insn "*<u>mulqihi3_1"
6847 [(set (match_operand:HI 0 "register_operand" "=a")
6848 (mult:HI
6849 (any_extend:HI
6850 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6851 (any_extend:HI
6852 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6853 (clobber (reg:CC FLAGS_REG))]
6854 "TARGET_QIMODE_MATH
6855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "<sgnprefix>mul{b}\t%2"
6857 [(set_attr "type" "imul")
6858 (set_attr "length_immediate" "0")
6859 (set (attr "athlon_decode")
6860 (if_then_else (eq_attr "cpu" "athlon")
6861 (const_string "vector")
6862 (const_string "direct")))
6863 (set_attr "amdfam10_decode" "direct")
6864 (set_attr "bdver1_decode" "direct")
6865 (set_attr "mode" "QI")])
6866
6867 (define_expand "<s>mul<mode>3_highpart"
6868 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6869 (truncate:SWI48
6870 (lshiftrt:<DWI>
6871 (mult:<DWI>
6872 (any_extend:<DWI>
6873 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6874 (any_extend:<DWI>
6875 (match_operand:SWI48 2 "register_operand" "")))
6876 (match_dup 4))))
6877 (clobber (match_scratch:SWI48 3 ""))
6878 (clobber (reg:CC FLAGS_REG))])]
6879 ""
6880 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6881
6882 (define_insn "*<s>muldi3_highpart_1"
6883 [(set (match_operand:DI 0 "register_operand" "=d")
6884 (truncate:DI
6885 (lshiftrt:TI
6886 (mult:TI
6887 (any_extend:TI
6888 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6889 (any_extend:TI
6890 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6891 (const_int 64))))
6892 (clobber (match_scratch:DI 3 "=1"))
6893 (clobber (reg:CC FLAGS_REG))]
6894 "TARGET_64BIT
6895 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6896 "<sgnprefix>mul{q}\t%2"
6897 [(set_attr "type" "imul")
6898 (set_attr "length_immediate" "0")
6899 (set (attr "athlon_decode")
6900 (if_then_else (eq_attr "cpu" "athlon")
6901 (const_string "vector")
6902 (const_string "double")))
6903 (set_attr "amdfam10_decode" "double")
6904 (set_attr "bdver1_decode" "direct")
6905 (set_attr "mode" "DI")])
6906
6907 (define_insn "*<s>mulsi3_highpart_1"
6908 [(set (match_operand:SI 0 "register_operand" "=d")
6909 (truncate:SI
6910 (lshiftrt:DI
6911 (mult:DI
6912 (any_extend:DI
6913 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6914 (any_extend:DI
6915 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6916 (const_int 32))))
6917 (clobber (match_scratch:SI 3 "=1"))
6918 (clobber (reg:CC FLAGS_REG))]
6919 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6920 "<sgnprefix>mul{l}\t%2"
6921 [(set_attr "type" "imul")
6922 (set_attr "length_immediate" "0")
6923 (set (attr "athlon_decode")
6924 (if_then_else (eq_attr "cpu" "athlon")
6925 (const_string "vector")
6926 (const_string "double")))
6927 (set_attr "amdfam10_decode" "double")
6928 (set_attr "bdver1_decode" "direct")
6929 (set_attr "mode" "SI")])
6930
6931 (define_insn "*<s>mulsi3_highpart_zext"
6932 [(set (match_operand:DI 0 "register_operand" "=d")
6933 (zero_extend:DI (truncate:SI
6934 (lshiftrt:DI
6935 (mult:DI (any_extend:DI
6936 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6937 (any_extend:DI
6938 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6939 (const_int 32)))))
6940 (clobber (match_scratch:SI 3 "=1"))
6941 (clobber (reg:CC FLAGS_REG))]
6942 "TARGET_64BIT
6943 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944 "<sgnprefix>mul{l}\t%2"
6945 [(set_attr "type" "imul")
6946 (set_attr "length_immediate" "0")
6947 (set (attr "athlon_decode")
6948 (if_then_else (eq_attr "cpu" "athlon")
6949 (const_string "vector")
6950 (const_string "double")))
6951 (set_attr "amdfam10_decode" "double")
6952 (set_attr "bdver1_decode" "direct")
6953 (set_attr "mode" "SI")])
6954
6955 ;; The patterns that match these are at the end of this file.
6956
6957 (define_expand "mulxf3"
6958 [(set (match_operand:XF 0 "register_operand" "")
6959 (mult:XF (match_operand:XF 1 "register_operand" "")
6960 (match_operand:XF 2 "register_operand" "")))]
6961 "TARGET_80387")
6962
6963 (define_expand "mul<mode>3"
6964 [(set (match_operand:MODEF 0 "register_operand" "")
6965 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6966 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6967 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6968 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6969 \f
6970 ;; Divide instructions
6971
6972 ;; The patterns that match these are at the end of this file.
6973
6974 (define_expand "divxf3"
6975 [(set (match_operand:XF 0 "register_operand" "")
6976 (div:XF (match_operand:XF 1 "register_operand" "")
6977 (match_operand:XF 2 "register_operand" "")))]
6978 "TARGET_80387")
6979
6980 (define_expand "divdf3"
6981 [(set (match_operand:DF 0 "register_operand" "")
6982 (div:DF (match_operand:DF 1 "register_operand" "")
6983 (match_operand:DF 2 "nonimmediate_operand" "")))]
6984 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6985 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6986
6987 (define_expand "divsf3"
6988 [(set (match_operand:SF 0 "register_operand" "")
6989 (div:SF (match_operand:SF 1 "register_operand" "")
6990 (match_operand:SF 2 "nonimmediate_operand" "")))]
6991 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6992 || TARGET_SSE_MATH"
6993 {
6994 if (TARGET_SSE_MATH
6995 && TARGET_RECIP_DIV
6996 && optimize_insn_for_speed_p ()
6997 && flag_finite_math_only && !flag_trapping_math
6998 && flag_unsafe_math_optimizations)
6999 {
7000 ix86_emit_swdivsf (operands[0], operands[1],
7001 operands[2], SFmode);
7002 DONE;
7003 }
7004 })
7005 \f
7006 ;; Divmod instructions.
7007
7008 (define_expand "divmod<mode>4"
7009 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7010 (div:SWIM248
7011 (match_operand:SWIM248 1 "register_operand" "")
7012 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7013 (set (match_operand:SWIM248 3 "register_operand" "")
7014 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7015 (clobber (reg:CC FLAGS_REG))])])
7016
7017 ;; Split with 8bit unsigned divide:
7018 ;; if (dividend an divisor are in [0-255])
7019 ;; use 8bit unsigned integer divide
7020 ;; else
7021 ;; use original integer divide
7022 (define_split
7023 [(set (match_operand:SWI48 0 "register_operand" "")
7024 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7025 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7026 (set (match_operand:SWI48 1 "register_operand" "")
7027 (mod:SWI48 (match_dup 2) (match_dup 3)))
7028 (clobber (reg:CC FLAGS_REG))]
7029 "TARGET_USE_8BIT_IDIV
7030 && TARGET_QIMODE_MATH
7031 && can_create_pseudo_p ()
7032 && !optimize_insn_for_size_p ()"
7033 [(const_int 0)]
7034 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7035
7036 (define_insn_and_split "divmod<mode>4_1"
7037 [(set (match_operand:SWI48 0 "register_operand" "=a")
7038 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7039 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7040 (set (match_operand:SWI48 1 "register_operand" "=&d")
7041 (mod:SWI48 (match_dup 2) (match_dup 3)))
7042 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7043 (clobber (reg:CC FLAGS_REG))]
7044 ""
7045 "#"
7046 "reload_completed"
7047 [(parallel [(set (match_dup 1)
7048 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7049 (clobber (reg:CC FLAGS_REG))])
7050 (parallel [(set (match_dup 0)
7051 (div:SWI48 (match_dup 2) (match_dup 3)))
7052 (set (match_dup 1)
7053 (mod:SWI48 (match_dup 2) (match_dup 3)))
7054 (use (match_dup 1))
7055 (clobber (reg:CC FLAGS_REG))])]
7056 {
7057 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7058
7059 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7060 operands[4] = operands[2];
7061 else
7062 {
7063 /* Avoid use of cltd in favor of a mov+shift. */
7064 emit_move_insn (operands[1], operands[2]);
7065 operands[4] = operands[1];
7066 }
7067 }
7068 [(set_attr "type" "multi")
7069 (set_attr "mode" "<MODE>")])
7070
7071 (define_insn_and_split "*divmod<mode>4"
7072 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7073 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7074 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7075 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7076 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7077 (clobber (reg:CC FLAGS_REG))]
7078 ""
7079 "#"
7080 "reload_completed"
7081 [(parallel [(set (match_dup 1)
7082 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7083 (clobber (reg:CC FLAGS_REG))])
7084 (parallel [(set (match_dup 0)
7085 (div:SWIM248 (match_dup 2) (match_dup 3)))
7086 (set (match_dup 1)
7087 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7088 (use (match_dup 1))
7089 (clobber (reg:CC FLAGS_REG))])]
7090 {
7091 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7092
7093 if (<MODE>mode != HImode
7094 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7095 operands[4] = operands[2];
7096 else
7097 {
7098 /* Avoid use of cltd in favor of a mov+shift. */
7099 emit_move_insn (operands[1], operands[2]);
7100 operands[4] = operands[1];
7101 }
7102 }
7103 [(set_attr "type" "multi")
7104 (set_attr "mode" "<MODE>")])
7105
7106 (define_insn "*divmod<mode>4_noext"
7107 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7108 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7109 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7110 (set (match_operand:SWIM248 1 "register_operand" "=d")
7111 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7112 (use (match_operand:SWIM248 4 "register_operand" "1"))
7113 (clobber (reg:CC FLAGS_REG))]
7114 ""
7115 "idiv{<imodesuffix>}\t%3"
7116 [(set_attr "type" "idiv")
7117 (set_attr "mode" "<MODE>")])
7118
7119 (define_expand "divmodqi4"
7120 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7121 (div:QI
7122 (match_operand:QI 1 "register_operand" "")
7123 (match_operand:QI 2 "nonimmediate_operand" "")))
7124 (set (match_operand:QI 3 "register_operand" "")
7125 (mod:QI (match_dup 1) (match_dup 2)))
7126 (clobber (reg:CC FLAGS_REG))])]
7127 "TARGET_QIMODE_MATH"
7128 {
7129 rtx div, mod, insn;
7130 rtx tmp0, tmp1;
7131
7132 tmp0 = gen_reg_rtx (HImode);
7133 tmp1 = gen_reg_rtx (HImode);
7134
7135 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7136 in AX. */
7137 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7138 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7139
7140 /* Extract remainder from AH. */
7141 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7142 insn = emit_move_insn (operands[3], tmp1);
7143
7144 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7145 set_unique_reg_note (insn, REG_EQUAL, mod);
7146
7147 /* Extract quotient from AL. */
7148 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7149
7150 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7151 set_unique_reg_note (insn, REG_EQUAL, div);
7152
7153 DONE;
7154 })
7155
7156 ;; Divide AX by r/m8, with result stored in
7157 ;; AL <- Quotient
7158 ;; AH <- Remainder
7159 ;; Change div/mod to HImode and extend the second argument to HImode
7160 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7161 ;; combine may fail.
7162 (define_insn "divmodhiqi3"
7163 [(set (match_operand:HI 0 "register_operand" "=a")
7164 (ior:HI
7165 (ashift:HI
7166 (zero_extend:HI
7167 (truncate:QI
7168 (mod:HI (match_operand:HI 1 "register_operand" "0")
7169 (sign_extend:HI
7170 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7171 (const_int 8))
7172 (zero_extend:HI
7173 (truncate:QI
7174 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7175 (clobber (reg:CC FLAGS_REG))]
7176 "TARGET_QIMODE_MATH"
7177 "idiv{b}\t%2"
7178 [(set_attr "type" "idiv")
7179 (set_attr "mode" "QI")])
7180
7181 (define_expand "udivmod<mode>4"
7182 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7183 (udiv:SWIM248
7184 (match_operand:SWIM248 1 "register_operand" "")
7185 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7186 (set (match_operand:SWIM248 3 "register_operand" "")
7187 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7188 (clobber (reg:CC FLAGS_REG))])])
7189
7190 ;; Split with 8bit unsigned divide:
7191 ;; if (dividend an divisor are in [0-255])
7192 ;; use 8bit unsigned integer divide
7193 ;; else
7194 ;; use original integer divide
7195 (define_split
7196 [(set (match_operand:SWI48 0 "register_operand" "")
7197 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7198 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7199 (set (match_operand:SWI48 1 "register_operand" "")
7200 (umod:SWI48 (match_dup 2) (match_dup 3)))
7201 (clobber (reg:CC FLAGS_REG))]
7202 "TARGET_USE_8BIT_IDIV
7203 && TARGET_QIMODE_MATH
7204 && can_create_pseudo_p ()
7205 && !optimize_insn_for_size_p ()"
7206 [(const_int 0)]
7207 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7208
7209 (define_insn_and_split "udivmod<mode>4_1"
7210 [(set (match_operand:SWI48 0 "register_operand" "=a")
7211 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7212 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7213 (set (match_operand:SWI48 1 "register_operand" "=&d")
7214 (umod:SWI48 (match_dup 2) (match_dup 3)))
7215 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7216 (clobber (reg:CC FLAGS_REG))]
7217 ""
7218 "#"
7219 "reload_completed"
7220 [(set (match_dup 1) (const_int 0))
7221 (parallel [(set (match_dup 0)
7222 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7223 (set (match_dup 1)
7224 (umod:SWI48 (match_dup 2) (match_dup 3)))
7225 (use (match_dup 1))
7226 (clobber (reg:CC FLAGS_REG))])]
7227 ""
7228 [(set_attr "type" "multi")
7229 (set_attr "mode" "<MODE>")])
7230
7231 (define_insn_and_split "*udivmod<mode>4"
7232 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7233 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7234 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7235 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7236 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7237 (clobber (reg:CC FLAGS_REG))]
7238 ""
7239 "#"
7240 "reload_completed"
7241 [(set (match_dup 1) (const_int 0))
7242 (parallel [(set (match_dup 0)
7243 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7244 (set (match_dup 1)
7245 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7246 (use (match_dup 1))
7247 (clobber (reg:CC FLAGS_REG))])]
7248 ""
7249 [(set_attr "type" "multi")
7250 (set_attr "mode" "<MODE>")])
7251
7252 (define_insn "*udivmod<mode>4_noext"
7253 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7254 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7255 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7256 (set (match_operand:SWIM248 1 "register_operand" "=d")
7257 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7258 (use (match_operand:SWIM248 4 "register_operand" "1"))
7259 (clobber (reg:CC FLAGS_REG))]
7260 ""
7261 "div{<imodesuffix>}\t%3"
7262 [(set_attr "type" "idiv")
7263 (set_attr "mode" "<MODE>")])
7264
7265 (define_expand "udivmodqi4"
7266 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7267 (udiv:QI
7268 (match_operand:QI 1 "register_operand" "")
7269 (match_operand:QI 2 "nonimmediate_operand" "")))
7270 (set (match_operand:QI 3 "register_operand" "")
7271 (umod:QI (match_dup 1) (match_dup 2)))
7272 (clobber (reg:CC FLAGS_REG))])]
7273 "TARGET_QIMODE_MATH"
7274 {
7275 rtx div, mod, insn;
7276 rtx tmp0, tmp1;
7277
7278 tmp0 = gen_reg_rtx (HImode);
7279 tmp1 = gen_reg_rtx (HImode);
7280
7281 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7282 in AX. */
7283 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7284 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7285
7286 /* Extract remainder from AH. */
7287 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7288 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7289 insn = emit_move_insn (operands[3], tmp1);
7290
7291 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7292 set_unique_reg_note (insn, REG_EQUAL, mod);
7293
7294 /* Extract quotient from AL. */
7295 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7296
7297 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7298 set_unique_reg_note (insn, REG_EQUAL, div);
7299
7300 DONE;
7301 })
7302
7303 (define_insn "udivmodhiqi3"
7304 [(set (match_operand:HI 0 "register_operand" "=a")
7305 (ior:HI
7306 (ashift:HI
7307 (zero_extend:HI
7308 (truncate:QI
7309 (mod:HI (match_operand:HI 1 "register_operand" "0")
7310 (zero_extend:HI
7311 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7312 (const_int 8))
7313 (zero_extend:HI
7314 (truncate:QI
7315 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7316 (clobber (reg:CC FLAGS_REG))]
7317 "TARGET_QIMODE_MATH"
7318 "div{b}\t%2"
7319 [(set_attr "type" "idiv")
7320 (set_attr "mode" "QI")])
7321
7322 ;; We cannot use div/idiv for double division, because it causes
7323 ;; "division by zero" on the overflow and that's not what we expect
7324 ;; from truncate. Because true (non truncating) double division is
7325 ;; never generated, we can't create this insn anyway.
7326 ;
7327 ;(define_insn ""
7328 ; [(set (match_operand:SI 0 "register_operand" "=a")
7329 ; (truncate:SI
7330 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7331 ; (zero_extend:DI
7332 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7333 ; (set (match_operand:SI 3 "register_operand" "=d")
7334 ; (truncate:SI
7335 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7336 ; (clobber (reg:CC FLAGS_REG))]
7337 ; ""
7338 ; "div{l}\t{%2, %0|%0, %2}"
7339 ; [(set_attr "type" "idiv")])
7340 \f
7341 ;;- Logical AND instructions
7342
7343 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7344 ;; Note that this excludes ah.
7345
7346 (define_expand "testsi_ccno_1"
7347 [(set (reg:CCNO FLAGS_REG)
7348 (compare:CCNO
7349 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7350 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7351 (const_int 0)))])
7352
7353 (define_expand "testqi_ccz_1"
7354 [(set (reg:CCZ FLAGS_REG)
7355 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7356 (match_operand:QI 1 "nonmemory_operand" ""))
7357 (const_int 0)))])
7358
7359 (define_expand "testdi_ccno_1"
7360 [(set (reg:CCNO FLAGS_REG)
7361 (compare:CCNO
7362 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7363 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7364 (const_int 0)))]
7365 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7366
7367 (define_insn "*testdi_1"
7368 [(set (reg FLAGS_REG)
7369 (compare
7370 (and:DI
7371 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7372 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7373 (const_int 0)))]
7374 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7375 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7376 "@
7377 test{l}\t{%k1, %k0|%k0, %k1}
7378 test{l}\t{%k1, %k0|%k0, %k1}
7379 test{q}\t{%1, %0|%0, %1}
7380 test{q}\t{%1, %0|%0, %1}
7381 test{q}\t{%1, %0|%0, %1}"
7382 [(set_attr "type" "test")
7383 (set_attr "modrm" "0,1,0,1,1")
7384 (set_attr "mode" "SI,SI,DI,DI,DI")])
7385
7386 (define_insn "*testqi_1_maybe_si"
7387 [(set (reg FLAGS_REG)
7388 (compare
7389 (and:QI
7390 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7391 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7392 (const_int 0)))]
7393 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7394 && ix86_match_ccmode (insn,
7395 CONST_INT_P (operands[1])
7396 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7397 {
7398 if (which_alternative == 3)
7399 {
7400 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7401 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7402 return "test{l}\t{%1, %k0|%k0, %1}";
7403 }
7404 return "test{b}\t{%1, %0|%0, %1}";
7405 }
7406 [(set_attr "type" "test")
7407 (set_attr "modrm" "0,1,1,1")
7408 (set_attr "mode" "QI,QI,QI,SI")
7409 (set_attr "pent_pair" "uv,np,uv,np")])
7410
7411 (define_insn "*test<mode>_1"
7412 [(set (reg FLAGS_REG)
7413 (compare
7414 (and:SWI124
7415 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7416 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7417 (const_int 0)))]
7418 "ix86_match_ccmode (insn, CCNOmode)
7419 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7420 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7421 [(set_attr "type" "test")
7422 (set_attr "modrm" "0,1,1")
7423 (set_attr "mode" "<MODE>")
7424 (set_attr "pent_pair" "uv,np,uv")])
7425
7426 (define_expand "testqi_ext_ccno_0"
7427 [(set (reg:CCNO FLAGS_REG)
7428 (compare:CCNO
7429 (and:SI
7430 (zero_extract:SI
7431 (match_operand 0 "ext_register_operand" "")
7432 (const_int 8)
7433 (const_int 8))
7434 (match_operand 1 "const_int_operand" ""))
7435 (const_int 0)))])
7436
7437 (define_insn "*testqi_ext_0"
7438 [(set (reg FLAGS_REG)
7439 (compare
7440 (and:SI
7441 (zero_extract:SI
7442 (match_operand 0 "ext_register_operand" "Q")
7443 (const_int 8)
7444 (const_int 8))
7445 (match_operand 1 "const_int_operand" "n"))
7446 (const_int 0)))]
7447 "ix86_match_ccmode (insn, CCNOmode)"
7448 "test{b}\t{%1, %h0|%h0, %1}"
7449 [(set_attr "type" "test")
7450 (set_attr "mode" "QI")
7451 (set_attr "length_immediate" "1")
7452 (set_attr "modrm" "1")
7453 (set_attr "pent_pair" "np")])
7454
7455 (define_insn "*testqi_ext_1_rex64"
7456 [(set (reg FLAGS_REG)
7457 (compare
7458 (and:SI
7459 (zero_extract:SI
7460 (match_operand 0 "ext_register_operand" "Q")
7461 (const_int 8)
7462 (const_int 8))
7463 (zero_extend:SI
7464 (match_operand:QI 1 "register_operand" "Q")))
7465 (const_int 0)))]
7466 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7467 "test{b}\t{%1, %h0|%h0, %1}"
7468 [(set_attr "type" "test")
7469 (set_attr "mode" "QI")])
7470
7471 (define_insn "*testqi_ext_1"
7472 [(set (reg FLAGS_REG)
7473 (compare
7474 (and:SI
7475 (zero_extract:SI
7476 (match_operand 0 "ext_register_operand" "Q")
7477 (const_int 8)
7478 (const_int 8))
7479 (zero_extend:SI
7480 (match_operand:QI 1 "general_operand" "Qm")))
7481 (const_int 0)))]
7482 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7483 "test{b}\t{%1, %h0|%h0, %1}"
7484 [(set_attr "type" "test")
7485 (set_attr "mode" "QI")])
7486
7487 (define_insn "*testqi_ext_2"
7488 [(set (reg FLAGS_REG)
7489 (compare
7490 (and:SI
7491 (zero_extract:SI
7492 (match_operand 0 "ext_register_operand" "Q")
7493 (const_int 8)
7494 (const_int 8))
7495 (zero_extract:SI
7496 (match_operand 1 "ext_register_operand" "Q")
7497 (const_int 8)
7498 (const_int 8)))
7499 (const_int 0)))]
7500 "ix86_match_ccmode (insn, CCNOmode)"
7501 "test{b}\t{%h1, %h0|%h0, %h1}"
7502 [(set_attr "type" "test")
7503 (set_attr "mode" "QI")])
7504
7505 (define_insn "*testqi_ext_3_rex64"
7506 [(set (reg FLAGS_REG)
7507 (compare (zero_extract:DI
7508 (match_operand 0 "nonimmediate_operand" "rm")
7509 (match_operand:DI 1 "const_int_operand" "")
7510 (match_operand:DI 2 "const_int_operand" ""))
7511 (const_int 0)))]
7512 "TARGET_64BIT
7513 && ix86_match_ccmode (insn, CCNOmode)
7514 && INTVAL (operands[1]) > 0
7515 && INTVAL (operands[2]) >= 0
7516 /* Ensure that resulting mask is zero or sign extended operand. */
7517 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7518 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7519 && INTVAL (operands[1]) > 32))
7520 && (GET_MODE (operands[0]) == SImode
7521 || GET_MODE (operands[0]) == DImode
7522 || GET_MODE (operands[0]) == HImode
7523 || GET_MODE (operands[0]) == QImode)"
7524 "#")
7525
7526 ;; Combine likes to form bit extractions for some tests. Humor it.
7527 (define_insn "*testqi_ext_3"
7528 [(set (reg FLAGS_REG)
7529 (compare (zero_extract:SI
7530 (match_operand 0 "nonimmediate_operand" "rm")
7531 (match_operand:SI 1 "const_int_operand" "")
7532 (match_operand:SI 2 "const_int_operand" ""))
7533 (const_int 0)))]
7534 "ix86_match_ccmode (insn, CCNOmode)
7535 && INTVAL (operands[1]) > 0
7536 && INTVAL (operands[2]) >= 0
7537 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7538 && (GET_MODE (operands[0]) == SImode
7539 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7540 || GET_MODE (operands[0]) == HImode
7541 || GET_MODE (operands[0]) == QImode)"
7542 "#")
7543
7544 (define_split
7545 [(set (match_operand 0 "flags_reg_operand" "")
7546 (match_operator 1 "compare_operator"
7547 [(zero_extract
7548 (match_operand 2 "nonimmediate_operand" "")
7549 (match_operand 3 "const_int_operand" "")
7550 (match_operand 4 "const_int_operand" ""))
7551 (const_int 0)]))]
7552 "ix86_match_ccmode (insn, CCNOmode)"
7553 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7554 {
7555 rtx val = operands[2];
7556 HOST_WIDE_INT len = INTVAL (operands[3]);
7557 HOST_WIDE_INT pos = INTVAL (operands[4]);
7558 HOST_WIDE_INT mask;
7559 enum machine_mode mode, submode;
7560
7561 mode = GET_MODE (val);
7562 if (MEM_P (val))
7563 {
7564 /* ??? Combine likes to put non-volatile mem extractions in QImode
7565 no matter the size of the test. So find a mode that works. */
7566 if (! MEM_VOLATILE_P (val))
7567 {
7568 mode = smallest_mode_for_size (pos + len, MODE_INT);
7569 val = adjust_address (val, mode, 0);
7570 }
7571 }
7572 else if (GET_CODE (val) == SUBREG
7573 && (submode = GET_MODE (SUBREG_REG (val)),
7574 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7575 && pos + len <= GET_MODE_BITSIZE (submode)
7576 && GET_MODE_CLASS (submode) == MODE_INT)
7577 {
7578 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7579 mode = submode;
7580 val = SUBREG_REG (val);
7581 }
7582 else if (mode == HImode && pos + len <= 8)
7583 {
7584 /* Small HImode tests can be converted to QImode. */
7585 mode = QImode;
7586 val = gen_lowpart (QImode, val);
7587 }
7588
7589 if (len == HOST_BITS_PER_WIDE_INT)
7590 mask = -1;
7591 else
7592 mask = ((HOST_WIDE_INT)1 << len) - 1;
7593 mask <<= pos;
7594
7595 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7596 })
7597
7598 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7599 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7600 ;; this is relatively important trick.
7601 ;; Do the conversion only post-reload to avoid limiting of the register class
7602 ;; to QI regs.
7603 (define_split
7604 [(set (match_operand 0 "flags_reg_operand" "")
7605 (match_operator 1 "compare_operator"
7606 [(and (match_operand 2 "register_operand" "")
7607 (match_operand 3 "const_int_operand" ""))
7608 (const_int 0)]))]
7609 "reload_completed
7610 && QI_REG_P (operands[2])
7611 && GET_MODE (operands[2]) != QImode
7612 && ((ix86_match_ccmode (insn, CCZmode)
7613 && !(INTVAL (operands[3]) & ~(255 << 8)))
7614 || (ix86_match_ccmode (insn, CCNOmode)
7615 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7616 [(set (match_dup 0)
7617 (match_op_dup 1
7618 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7619 (match_dup 3))
7620 (const_int 0)]))]
7621 {
7622 operands[2] = gen_lowpart (SImode, operands[2]);
7623 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7624 })
7625
7626 (define_split
7627 [(set (match_operand 0 "flags_reg_operand" "")
7628 (match_operator 1 "compare_operator"
7629 [(and (match_operand 2 "nonimmediate_operand" "")
7630 (match_operand 3 "const_int_operand" ""))
7631 (const_int 0)]))]
7632 "reload_completed
7633 && GET_MODE (operands[2]) != QImode
7634 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7635 && ((ix86_match_ccmode (insn, CCZmode)
7636 && !(INTVAL (operands[3]) & ~255))
7637 || (ix86_match_ccmode (insn, CCNOmode)
7638 && !(INTVAL (operands[3]) & ~127)))"
7639 [(set (match_dup 0)
7640 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7641 (const_int 0)]))]
7642 {
7643 operands[2] = gen_lowpart (QImode, operands[2]);
7644 operands[3] = gen_lowpart (QImode, operands[3]);
7645 })
7646
7647 ;; %%% This used to optimize known byte-wide and operations to memory,
7648 ;; and sometimes to QImode registers. If this is considered useful,
7649 ;; it should be done with splitters.
7650
7651 (define_expand "and<mode>3"
7652 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7653 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7654 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7655 ""
7656 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7657
7658 (define_insn "*anddi_1"
7659 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7660 (and:DI
7661 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7662 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7663 (clobber (reg:CC FLAGS_REG))]
7664 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7665 {
7666 switch (get_attr_type (insn))
7667 {
7668 case TYPE_IMOVX:
7669 return "#";
7670
7671 default:
7672 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7673 if (get_attr_mode (insn) == MODE_SI)
7674 return "and{l}\t{%k2, %k0|%k0, %k2}";
7675 else
7676 return "and{q}\t{%2, %0|%0, %2}";
7677 }
7678 }
7679 [(set_attr "type" "alu,alu,alu,imovx")
7680 (set_attr "length_immediate" "*,*,*,0")
7681 (set (attr "prefix_rex")
7682 (if_then_else
7683 (and (eq_attr "type" "imovx")
7684 (and (match_test "INTVAL (operands[2]) == 0xff")
7685 (match_operand 1 "ext_QIreg_operand" "")))
7686 (const_string "1")
7687 (const_string "*")))
7688 (set_attr "mode" "SI,DI,DI,SI")])
7689
7690 (define_insn "*andsi_1"
7691 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7692 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7693 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7694 (clobber (reg:CC FLAGS_REG))]
7695 "ix86_binary_operator_ok (AND, SImode, operands)"
7696 {
7697 switch (get_attr_type (insn))
7698 {
7699 case TYPE_IMOVX:
7700 return "#";
7701
7702 default:
7703 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7704 return "and{l}\t{%2, %0|%0, %2}";
7705 }
7706 }
7707 [(set_attr "type" "alu,alu,imovx")
7708 (set (attr "prefix_rex")
7709 (if_then_else
7710 (and (eq_attr "type" "imovx")
7711 (and (match_test "INTVAL (operands[2]) == 0xff")
7712 (match_operand 1 "ext_QIreg_operand" "")))
7713 (const_string "1")
7714 (const_string "*")))
7715 (set_attr "length_immediate" "*,*,0")
7716 (set_attr "mode" "SI")])
7717
7718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7719 (define_insn "*andsi_1_zext"
7720 [(set (match_operand:DI 0 "register_operand" "=r")
7721 (zero_extend:DI
7722 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7723 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7724 (clobber (reg:CC FLAGS_REG))]
7725 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7726 "and{l}\t{%2, %k0|%k0, %2}"
7727 [(set_attr "type" "alu")
7728 (set_attr "mode" "SI")])
7729
7730 (define_insn "*andhi_1"
7731 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7732 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7733 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7734 (clobber (reg:CC FLAGS_REG))]
7735 "ix86_binary_operator_ok (AND, HImode, operands)"
7736 {
7737 switch (get_attr_type (insn))
7738 {
7739 case TYPE_IMOVX:
7740 return "#";
7741
7742 default:
7743 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7744 return "and{w}\t{%2, %0|%0, %2}";
7745 }
7746 }
7747 [(set_attr "type" "alu,alu,imovx")
7748 (set_attr "length_immediate" "*,*,0")
7749 (set (attr "prefix_rex")
7750 (if_then_else
7751 (and (eq_attr "type" "imovx")
7752 (match_operand 1 "ext_QIreg_operand" ""))
7753 (const_string "1")
7754 (const_string "*")))
7755 (set_attr "mode" "HI,HI,SI")])
7756
7757 ;; %%% Potential partial reg stall on alternative 2. What to do?
7758 (define_insn "*andqi_1"
7759 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7760 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7761 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7762 (clobber (reg:CC FLAGS_REG))]
7763 "ix86_binary_operator_ok (AND, QImode, operands)"
7764 "@
7765 and{b}\t{%2, %0|%0, %2}
7766 and{b}\t{%2, %0|%0, %2}
7767 and{l}\t{%k2, %k0|%k0, %k2}"
7768 [(set_attr "type" "alu")
7769 (set_attr "mode" "QI,QI,SI")])
7770
7771 (define_insn "*andqi_1_slp"
7772 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7773 (and:QI (match_dup 0)
7774 (match_operand:QI 1 "general_operand" "qn,qmn")))
7775 (clobber (reg:CC FLAGS_REG))]
7776 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7777 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7778 "and{b}\t{%1, %0|%0, %1}"
7779 [(set_attr "type" "alu1")
7780 (set_attr "mode" "QI")])
7781
7782 (define_split
7783 [(set (match_operand:SWI248 0 "register_operand" "")
7784 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")
7785 (match_operand:SWI248 2 "const_int_operand" "")))
7786 (clobber (reg:CC FLAGS_REG))]
7787 "reload_completed
7788 && true_regnum (operands[0]) != true_regnum (operands[1])"
7789 [(const_int 0)]
7790 {
7791 enum machine_mode mode;
7792
7793 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7794 mode = SImode;
7795 else if (INTVAL (operands[2]) == 0xffff)
7796 mode = HImode;
7797 else
7798 {
7799 gcc_assert (INTVAL (operands[2]) == 0xff);
7800 mode = QImode;
7801 }
7802
7803 operands[1] = gen_lowpart (mode, operands[1]);
7804
7805 if (mode == SImode)
7806 emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
7807 else
7808 {
7809 rtx (*insn) (rtx, rtx);
7810
7811 /* Zero extend to SImode to avoid partial register stalls. */
7812 operands[0] = gen_lowpart (SImode, operands[0]);
7813
7814 insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2;
7815 emit_insn (insn (operands[0], operands[1]));
7816 }
7817 DONE;
7818 })
7819
7820 (define_split
7821 [(set (match_operand 0 "register_operand" "")
7822 (and (match_dup 0)
7823 (const_int -65536)))
7824 (clobber (reg:CC FLAGS_REG))]
7825 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7826 || optimize_function_for_size_p (cfun)"
7827 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7828 "operands[1] = gen_lowpart (HImode, operands[0]);")
7829
7830 (define_split
7831 [(set (match_operand 0 "ext_register_operand" "")
7832 (and (match_dup 0)
7833 (const_int -256)))
7834 (clobber (reg:CC FLAGS_REG))]
7835 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7836 && reload_completed"
7837 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7838 "operands[1] = gen_lowpart (QImode, operands[0]);")
7839
7840 (define_split
7841 [(set (match_operand 0 "ext_register_operand" "")
7842 (and (match_dup 0)
7843 (const_int -65281)))
7844 (clobber (reg:CC FLAGS_REG))]
7845 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7846 && reload_completed"
7847 [(parallel [(set (zero_extract:SI (match_dup 0)
7848 (const_int 8)
7849 (const_int 8))
7850 (xor:SI
7851 (zero_extract:SI (match_dup 0)
7852 (const_int 8)
7853 (const_int 8))
7854 (zero_extract:SI (match_dup 0)
7855 (const_int 8)
7856 (const_int 8))))
7857 (clobber (reg:CC FLAGS_REG))])]
7858 "operands[0] = gen_lowpart (SImode, operands[0]);")
7859
7860 (define_insn "*anddi_2"
7861 [(set (reg FLAGS_REG)
7862 (compare
7863 (and:DI
7864 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7865 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7866 (const_int 0)))
7867 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7868 (and:DI (match_dup 1) (match_dup 2)))]
7869 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870 && ix86_binary_operator_ok (AND, DImode, operands)"
7871 "@
7872 and{l}\t{%k2, %k0|%k0, %k2}
7873 and{q}\t{%2, %0|%0, %2}
7874 and{q}\t{%2, %0|%0, %2}"
7875 [(set_attr "type" "alu")
7876 (set_attr "mode" "SI,DI,DI")])
7877
7878 (define_insn "*andqi_2_maybe_si"
7879 [(set (reg FLAGS_REG)
7880 (compare (and:QI
7881 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7882 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7883 (const_int 0)))
7884 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7885 (and:QI (match_dup 1) (match_dup 2)))]
7886 "ix86_binary_operator_ok (AND, QImode, operands)
7887 && ix86_match_ccmode (insn,
7888 CONST_INT_P (operands[2])
7889 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7890 {
7891 if (which_alternative == 2)
7892 {
7893 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7894 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7895 return "and{l}\t{%2, %k0|%k0, %2}";
7896 }
7897 return "and{b}\t{%2, %0|%0, %2}";
7898 }
7899 [(set_attr "type" "alu")
7900 (set_attr "mode" "QI,QI,SI")])
7901
7902 (define_insn "*and<mode>_2"
7903 [(set (reg FLAGS_REG)
7904 (compare (and:SWI124
7905 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7906 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7907 (const_int 0)))
7908 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7909 (and:SWI124 (match_dup 1) (match_dup 2)))]
7910 "ix86_match_ccmode (insn, CCNOmode)
7911 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7912 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7913 [(set_attr "type" "alu")
7914 (set_attr "mode" "<MODE>")])
7915
7916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7917 (define_insn "*andsi_2_zext"
7918 [(set (reg FLAGS_REG)
7919 (compare (and:SI
7920 (match_operand:SI 1 "nonimmediate_operand" "%0")
7921 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7922 (const_int 0)))
7923 (set (match_operand:DI 0 "register_operand" "=r")
7924 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7925 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7926 && ix86_binary_operator_ok (AND, SImode, operands)"
7927 "and{l}\t{%2, %k0|%k0, %2}"
7928 [(set_attr "type" "alu")
7929 (set_attr "mode" "SI")])
7930
7931 (define_insn "*andqi_2_slp"
7932 [(set (reg FLAGS_REG)
7933 (compare (and:QI
7934 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7935 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7936 (const_int 0)))
7937 (set (strict_low_part (match_dup 0))
7938 (and:QI (match_dup 0) (match_dup 1)))]
7939 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7940 && ix86_match_ccmode (insn, CCNOmode)
7941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7942 "and{b}\t{%1, %0|%0, %1}"
7943 [(set_attr "type" "alu1")
7944 (set_attr "mode" "QI")])
7945
7946 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7947 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7948 ;; for a QImode operand, which of course failed.
7949 (define_insn "andqi_ext_0"
7950 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7951 (const_int 8)
7952 (const_int 8))
7953 (and:SI
7954 (zero_extract:SI
7955 (match_operand 1 "ext_register_operand" "0")
7956 (const_int 8)
7957 (const_int 8))
7958 (match_operand 2 "const_int_operand" "n")))
7959 (clobber (reg:CC FLAGS_REG))]
7960 ""
7961 "and{b}\t{%2, %h0|%h0, %2}"
7962 [(set_attr "type" "alu")
7963 (set_attr "length_immediate" "1")
7964 (set_attr "modrm" "1")
7965 (set_attr "mode" "QI")])
7966
7967 ;; Generated by peephole translating test to and. This shows up
7968 ;; often in fp comparisons.
7969 (define_insn "*andqi_ext_0_cc"
7970 [(set (reg FLAGS_REG)
7971 (compare
7972 (and:SI
7973 (zero_extract:SI
7974 (match_operand 1 "ext_register_operand" "0")
7975 (const_int 8)
7976 (const_int 8))
7977 (match_operand 2 "const_int_operand" "n"))
7978 (const_int 0)))
7979 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7980 (const_int 8)
7981 (const_int 8))
7982 (and:SI
7983 (zero_extract:SI
7984 (match_dup 1)
7985 (const_int 8)
7986 (const_int 8))
7987 (match_dup 2)))]
7988 "ix86_match_ccmode (insn, CCNOmode)"
7989 "and{b}\t{%2, %h0|%h0, %2}"
7990 [(set_attr "type" "alu")
7991 (set_attr "length_immediate" "1")
7992 (set_attr "modrm" "1")
7993 (set_attr "mode" "QI")])
7994
7995 (define_insn "*andqi_ext_1_rex64"
7996 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7997 (const_int 8)
7998 (const_int 8))
7999 (and:SI
8000 (zero_extract:SI
8001 (match_operand 1 "ext_register_operand" "0")
8002 (const_int 8)
8003 (const_int 8))
8004 (zero_extend:SI
8005 (match_operand 2 "ext_register_operand" "Q"))))
8006 (clobber (reg:CC FLAGS_REG))]
8007 "TARGET_64BIT"
8008 "and{b}\t{%2, %h0|%h0, %2}"
8009 [(set_attr "type" "alu")
8010 (set_attr "length_immediate" "0")
8011 (set_attr "mode" "QI")])
8012
8013 (define_insn "*andqi_ext_1"
8014 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8015 (const_int 8)
8016 (const_int 8))
8017 (and:SI
8018 (zero_extract:SI
8019 (match_operand 1 "ext_register_operand" "0")
8020 (const_int 8)
8021 (const_int 8))
8022 (zero_extend:SI
8023 (match_operand:QI 2 "general_operand" "Qm"))))
8024 (clobber (reg:CC FLAGS_REG))]
8025 "!TARGET_64BIT"
8026 "and{b}\t{%2, %h0|%h0, %2}"
8027 [(set_attr "type" "alu")
8028 (set_attr "length_immediate" "0")
8029 (set_attr "mode" "QI")])
8030
8031 (define_insn "*andqi_ext_2"
8032 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8033 (const_int 8)
8034 (const_int 8))
8035 (and:SI
8036 (zero_extract:SI
8037 (match_operand 1 "ext_register_operand" "%0")
8038 (const_int 8)
8039 (const_int 8))
8040 (zero_extract:SI
8041 (match_operand 2 "ext_register_operand" "Q")
8042 (const_int 8)
8043 (const_int 8))))
8044 (clobber (reg:CC FLAGS_REG))]
8045 ""
8046 "and{b}\t{%h2, %h0|%h0, %h2}"
8047 [(set_attr "type" "alu")
8048 (set_attr "length_immediate" "0")
8049 (set_attr "mode" "QI")])
8050
8051 ;; Convert wide AND instructions with immediate operand to shorter QImode
8052 ;; equivalents when possible.
8053 ;; Don't do the splitting with memory operands, since it introduces risk
8054 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8055 ;; for size, but that can (should?) be handled by generic code instead.
8056 (define_split
8057 [(set (match_operand 0 "register_operand" "")
8058 (and (match_operand 1 "register_operand" "")
8059 (match_operand 2 "const_int_operand" "")))
8060 (clobber (reg:CC FLAGS_REG))]
8061 "reload_completed
8062 && QI_REG_P (operands[0])
8063 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8064 && !(~INTVAL (operands[2]) & ~(255 << 8))
8065 && GET_MODE (operands[0]) != QImode"
8066 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8067 (and:SI (zero_extract:SI (match_dup 1)
8068 (const_int 8) (const_int 8))
8069 (match_dup 2)))
8070 (clobber (reg:CC FLAGS_REG))])]
8071 {
8072 operands[0] = gen_lowpart (SImode, operands[0]);
8073 operands[1] = gen_lowpart (SImode, operands[1]);
8074 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8075 })
8076
8077 ;; Since AND can be encoded with sign extended immediate, this is only
8078 ;; profitable when 7th bit is not set.
8079 (define_split
8080 [(set (match_operand 0 "register_operand" "")
8081 (and (match_operand 1 "general_operand" "")
8082 (match_operand 2 "const_int_operand" "")))
8083 (clobber (reg:CC FLAGS_REG))]
8084 "reload_completed
8085 && ANY_QI_REG_P (operands[0])
8086 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8087 && !(~INTVAL (operands[2]) & ~255)
8088 && !(INTVAL (operands[2]) & 128)
8089 && GET_MODE (operands[0]) != QImode"
8090 [(parallel [(set (strict_low_part (match_dup 0))
8091 (and:QI (match_dup 1)
8092 (match_dup 2)))
8093 (clobber (reg:CC FLAGS_REG))])]
8094 {
8095 operands[0] = gen_lowpart (QImode, operands[0]);
8096 operands[1] = gen_lowpart (QImode, operands[1]);
8097 operands[2] = gen_lowpart (QImode, operands[2]);
8098 })
8099 \f
8100 ;; Logical inclusive and exclusive OR instructions
8101
8102 ;; %%% This used to optimize known byte-wide and operations to memory.
8103 ;; If this is considered useful, it should be done with splitters.
8104
8105 (define_expand "<code><mode>3"
8106 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8107 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8108 (match_operand:SWIM 2 "<general_operand>" "")))]
8109 ""
8110 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8111
8112 (define_insn "*<code><mode>_1"
8113 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8114 (any_or:SWI248
8115 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8116 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8117 (clobber (reg:CC FLAGS_REG))]
8118 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8119 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8120 [(set_attr "type" "alu")
8121 (set_attr "mode" "<MODE>")])
8122
8123 ;; %%% Potential partial reg stall on alternative 2. What to do?
8124 (define_insn "*<code>qi_1"
8125 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8126 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8127 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8130 "@
8131 <logic>{b}\t{%2, %0|%0, %2}
8132 <logic>{b}\t{%2, %0|%0, %2}
8133 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8134 [(set_attr "type" "alu")
8135 (set_attr "mode" "QI,QI,SI")])
8136
8137 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8138 (define_insn "*<code>si_1_zext"
8139 [(set (match_operand:DI 0 "register_operand" "=r")
8140 (zero_extend:DI
8141 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8142 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8143 (clobber (reg:CC FLAGS_REG))]
8144 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8145 "<logic>{l}\t{%2, %k0|%k0, %2}"
8146 [(set_attr "type" "alu")
8147 (set_attr "mode" "SI")])
8148
8149 (define_insn "*<code>si_1_zext_imm"
8150 [(set (match_operand:DI 0 "register_operand" "=r")
8151 (any_or:DI
8152 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8153 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8154 (clobber (reg:CC FLAGS_REG))]
8155 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8156 "<logic>{l}\t{%2, %k0|%k0, %2}"
8157 [(set_attr "type" "alu")
8158 (set_attr "mode" "SI")])
8159
8160 (define_insn "*<code>qi_1_slp"
8161 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8162 (any_or:QI (match_dup 0)
8163 (match_operand:QI 1 "general_operand" "qmn,qn")))
8164 (clobber (reg:CC FLAGS_REG))]
8165 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8166 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8167 "<logic>{b}\t{%1, %0|%0, %1}"
8168 [(set_attr "type" "alu1")
8169 (set_attr "mode" "QI")])
8170
8171 (define_insn "*<code><mode>_2"
8172 [(set (reg FLAGS_REG)
8173 (compare (any_or:SWI
8174 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8175 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8176 (const_int 0)))
8177 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8178 (any_or:SWI (match_dup 1) (match_dup 2)))]
8179 "ix86_match_ccmode (insn, CCNOmode)
8180 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8181 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "mode" "<MODE>")])
8184
8185 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8186 ;; ??? Special case for immediate operand is missing - it is tricky.
8187 (define_insn "*<code>si_2_zext"
8188 [(set (reg FLAGS_REG)
8189 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8190 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8191 (const_int 0)))
8192 (set (match_operand:DI 0 "register_operand" "=r")
8193 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8194 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8195 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8196 "<logic>{l}\t{%2, %k0|%k0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "mode" "SI")])
8199
8200 (define_insn "*<code>si_2_zext_imm"
8201 [(set (reg FLAGS_REG)
8202 (compare (any_or:SI
8203 (match_operand:SI 1 "nonimmediate_operand" "%0")
8204 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8205 (const_int 0)))
8206 (set (match_operand:DI 0 "register_operand" "=r")
8207 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8208 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8209 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8210 "<logic>{l}\t{%2, %k0|%k0, %2}"
8211 [(set_attr "type" "alu")
8212 (set_attr "mode" "SI")])
8213
8214 (define_insn "*<code>qi_2_slp"
8215 [(set (reg FLAGS_REG)
8216 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8217 (match_operand:QI 1 "general_operand" "qmn,qn"))
8218 (const_int 0)))
8219 (set (strict_low_part (match_dup 0))
8220 (any_or:QI (match_dup 0) (match_dup 1)))]
8221 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8222 && ix86_match_ccmode (insn, CCNOmode)
8223 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8224 "<logic>{b}\t{%1, %0|%0, %1}"
8225 [(set_attr "type" "alu1")
8226 (set_attr "mode" "QI")])
8227
8228 (define_insn "*<code><mode>_3"
8229 [(set (reg FLAGS_REG)
8230 (compare (any_or:SWI
8231 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8232 (match_operand:SWI 2 "<general_operand>" "<g>"))
8233 (const_int 0)))
8234 (clobber (match_scratch:SWI 0 "=<r>"))]
8235 "ix86_match_ccmode (insn, CCNOmode)
8236 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8237 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8238 [(set_attr "type" "alu")
8239 (set_attr "mode" "<MODE>")])
8240
8241 (define_insn "*<code>qi_ext_0"
8242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8243 (const_int 8)
8244 (const_int 8))
8245 (any_or:SI
8246 (zero_extract:SI
8247 (match_operand 1 "ext_register_operand" "0")
8248 (const_int 8)
8249 (const_int 8))
8250 (match_operand 2 "const_int_operand" "n")))
8251 (clobber (reg:CC FLAGS_REG))]
8252 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8253 "<logic>{b}\t{%2, %h0|%h0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "length_immediate" "1")
8256 (set_attr "modrm" "1")
8257 (set_attr "mode" "QI")])
8258
8259 (define_insn "*<code>qi_ext_1_rex64"
8260 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8261 (const_int 8)
8262 (const_int 8))
8263 (any_or:SI
8264 (zero_extract:SI
8265 (match_operand 1 "ext_register_operand" "0")
8266 (const_int 8)
8267 (const_int 8))
8268 (zero_extend:SI
8269 (match_operand 2 "ext_register_operand" "Q"))))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "TARGET_64BIT
8272 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8273 "<logic>{b}\t{%2, %h0|%h0, %2}"
8274 [(set_attr "type" "alu")
8275 (set_attr "length_immediate" "0")
8276 (set_attr "mode" "QI")])
8277
8278 (define_insn "*<code>qi_ext_1"
8279 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8280 (const_int 8)
8281 (const_int 8))
8282 (any_or:SI
8283 (zero_extract:SI
8284 (match_operand 1 "ext_register_operand" "0")
8285 (const_int 8)
8286 (const_int 8))
8287 (zero_extend:SI
8288 (match_operand:QI 2 "general_operand" "Qm"))))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "!TARGET_64BIT
8291 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8292 "<logic>{b}\t{%2, %h0|%h0, %2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "length_immediate" "0")
8295 (set_attr "mode" "QI")])
8296
8297 (define_insn "*<code>qi_ext_2"
8298 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8299 (const_int 8)
8300 (const_int 8))
8301 (any_or:SI
8302 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8303 (const_int 8)
8304 (const_int 8))
8305 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8306 (const_int 8)
8307 (const_int 8))))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8310 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "length_immediate" "0")
8313 (set_attr "mode" "QI")])
8314
8315 (define_split
8316 [(set (match_operand 0 "register_operand" "")
8317 (any_or (match_operand 1 "register_operand" "")
8318 (match_operand 2 "const_int_operand" "")))
8319 (clobber (reg:CC FLAGS_REG))]
8320 "reload_completed
8321 && QI_REG_P (operands[0])
8322 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8323 && !(INTVAL (operands[2]) & ~(255 << 8))
8324 && GET_MODE (operands[0]) != QImode"
8325 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8326 (any_or:SI (zero_extract:SI (match_dup 1)
8327 (const_int 8) (const_int 8))
8328 (match_dup 2)))
8329 (clobber (reg:CC FLAGS_REG))])]
8330 {
8331 operands[0] = gen_lowpart (SImode, operands[0]);
8332 operands[1] = gen_lowpart (SImode, operands[1]);
8333 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8334 })
8335
8336 ;; Since OR can be encoded with sign extended immediate, this is only
8337 ;; profitable when 7th bit is set.
8338 (define_split
8339 [(set (match_operand 0 "register_operand" "")
8340 (any_or (match_operand 1 "general_operand" "")
8341 (match_operand 2 "const_int_operand" "")))
8342 (clobber (reg:CC FLAGS_REG))]
8343 "reload_completed
8344 && ANY_QI_REG_P (operands[0])
8345 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8346 && !(INTVAL (operands[2]) & ~255)
8347 && (INTVAL (operands[2]) & 128)
8348 && GET_MODE (operands[0]) != QImode"
8349 [(parallel [(set (strict_low_part (match_dup 0))
8350 (any_or:QI (match_dup 1)
8351 (match_dup 2)))
8352 (clobber (reg:CC FLAGS_REG))])]
8353 {
8354 operands[0] = gen_lowpart (QImode, operands[0]);
8355 operands[1] = gen_lowpart (QImode, operands[1]);
8356 operands[2] = gen_lowpart (QImode, operands[2]);
8357 })
8358
8359 (define_expand "xorqi_cc_ext_1"
8360 [(parallel [
8361 (set (reg:CCNO FLAGS_REG)
8362 (compare:CCNO
8363 (xor:SI
8364 (zero_extract:SI
8365 (match_operand 1 "ext_register_operand" "")
8366 (const_int 8)
8367 (const_int 8))
8368 (match_operand:QI 2 "general_operand" ""))
8369 (const_int 0)))
8370 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8371 (const_int 8)
8372 (const_int 8))
8373 (xor:SI
8374 (zero_extract:SI
8375 (match_dup 1)
8376 (const_int 8)
8377 (const_int 8))
8378 (match_dup 2)))])])
8379
8380 (define_insn "*xorqi_cc_ext_1_rex64"
8381 [(set (reg FLAGS_REG)
8382 (compare
8383 (xor:SI
8384 (zero_extract:SI
8385 (match_operand 1 "ext_register_operand" "0")
8386 (const_int 8)
8387 (const_int 8))
8388 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8389 (const_int 0)))
8390 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8391 (const_int 8)
8392 (const_int 8))
8393 (xor:SI
8394 (zero_extract:SI
8395 (match_dup 1)
8396 (const_int 8)
8397 (const_int 8))
8398 (match_dup 2)))]
8399 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8400 "xor{b}\t{%2, %h0|%h0, %2}"
8401 [(set_attr "type" "alu")
8402 (set_attr "modrm" "1")
8403 (set_attr "mode" "QI")])
8404
8405 (define_insn "*xorqi_cc_ext_1"
8406 [(set (reg FLAGS_REG)
8407 (compare
8408 (xor:SI
8409 (zero_extract:SI
8410 (match_operand 1 "ext_register_operand" "0")
8411 (const_int 8)
8412 (const_int 8))
8413 (match_operand:QI 2 "general_operand" "qmn"))
8414 (const_int 0)))
8415 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8416 (const_int 8)
8417 (const_int 8))
8418 (xor:SI
8419 (zero_extract:SI
8420 (match_dup 1)
8421 (const_int 8)
8422 (const_int 8))
8423 (match_dup 2)))]
8424 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8425 "xor{b}\t{%2, %h0|%h0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "modrm" "1")
8428 (set_attr "mode" "QI")])
8429 \f
8430 ;; Negation instructions
8431
8432 (define_expand "neg<mode>2"
8433 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8434 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8435 ""
8436 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8437
8438 (define_insn_and_split "*neg<dwi>2_doubleword"
8439 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8440 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8441 (clobber (reg:CC FLAGS_REG))]
8442 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8443 "#"
8444 "reload_completed"
8445 [(parallel
8446 [(set (reg:CCZ FLAGS_REG)
8447 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8448 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8449 (parallel
8450 [(set (match_dup 2)
8451 (plus:DWIH (match_dup 3)
8452 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8453 (const_int 0))))
8454 (clobber (reg:CC FLAGS_REG))])
8455 (parallel
8456 [(set (match_dup 2)
8457 (neg:DWIH (match_dup 2)))
8458 (clobber (reg:CC FLAGS_REG))])]
8459 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8460
8461 (define_insn "*neg<mode>2_1"
8462 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8463 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8464 (clobber (reg:CC FLAGS_REG))]
8465 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8466 "neg{<imodesuffix>}\t%0"
8467 [(set_attr "type" "negnot")
8468 (set_attr "mode" "<MODE>")])
8469
8470 ;; Combine is quite creative about this pattern.
8471 (define_insn "*negsi2_1_zext"
8472 [(set (match_operand:DI 0 "register_operand" "=r")
8473 (lshiftrt:DI
8474 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8475 (const_int 32)))
8476 (const_int 32)))
8477 (clobber (reg:CC FLAGS_REG))]
8478 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8479 "neg{l}\t%k0"
8480 [(set_attr "type" "negnot")
8481 (set_attr "mode" "SI")])
8482
8483 ;; The problem with neg is that it does not perform (compare x 0),
8484 ;; it really performs (compare 0 x), which leaves us with the zero
8485 ;; flag being the only useful item.
8486
8487 (define_insn "*neg<mode>2_cmpz"
8488 [(set (reg:CCZ FLAGS_REG)
8489 (compare:CCZ
8490 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8491 (const_int 0)))
8492 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8493 (neg:SWI (match_dup 1)))]
8494 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8495 "neg{<imodesuffix>}\t%0"
8496 [(set_attr "type" "negnot")
8497 (set_attr "mode" "<MODE>")])
8498
8499 (define_insn "*negsi2_cmpz_zext"
8500 [(set (reg:CCZ FLAGS_REG)
8501 (compare:CCZ
8502 (lshiftrt:DI
8503 (neg:DI (ashift:DI
8504 (match_operand:DI 1 "register_operand" "0")
8505 (const_int 32)))
8506 (const_int 32))
8507 (const_int 0)))
8508 (set (match_operand:DI 0 "register_operand" "=r")
8509 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8510 (const_int 32)))
8511 (const_int 32)))]
8512 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8513 "neg{l}\t%k0"
8514 [(set_attr "type" "negnot")
8515 (set_attr "mode" "SI")])
8516
8517 ;; Changing of sign for FP values is doable using integer unit too.
8518
8519 (define_expand "<code><mode>2"
8520 [(set (match_operand:X87MODEF 0 "register_operand" "")
8521 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8522 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8523 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8524
8525 (define_insn "*absneg<mode>2_mixed"
8526 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8527 (match_operator:MODEF 3 "absneg_operator"
8528 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8529 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8530 (clobber (reg:CC FLAGS_REG))]
8531 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8532 "#")
8533
8534 (define_insn "*absneg<mode>2_sse"
8535 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8536 (match_operator:MODEF 3 "absneg_operator"
8537 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8538 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8541 "#")
8542
8543 (define_insn "*absneg<mode>2_i387"
8544 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8545 (match_operator:X87MODEF 3 "absneg_operator"
8546 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8547 (use (match_operand 2 "" ""))
8548 (clobber (reg:CC FLAGS_REG))]
8549 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8550 "#")
8551
8552 (define_expand "<code>tf2"
8553 [(set (match_operand:TF 0 "register_operand" "")
8554 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8555 "TARGET_SSE2"
8556 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8557
8558 (define_insn "*absnegtf2_sse"
8559 [(set (match_operand:TF 0 "register_operand" "=x,x")
8560 (match_operator:TF 3 "absneg_operator"
8561 [(match_operand:TF 1 "register_operand" "0,x")]))
8562 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8563 (clobber (reg:CC FLAGS_REG))]
8564 "TARGET_SSE2"
8565 "#")
8566
8567 ;; Splitters for fp abs and neg.
8568
8569 (define_split
8570 [(set (match_operand 0 "fp_register_operand" "")
8571 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8572 (use (match_operand 2 "" ""))
8573 (clobber (reg:CC FLAGS_REG))]
8574 "reload_completed"
8575 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8576
8577 (define_split
8578 [(set (match_operand 0 "register_operand" "")
8579 (match_operator 3 "absneg_operator"
8580 [(match_operand 1 "register_operand" "")]))
8581 (use (match_operand 2 "nonimmediate_operand" ""))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "reload_completed && SSE_REG_P (operands[0])"
8584 [(set (match_dup 0) (match_dup 3))]
8585 {
8586 enum machine_mode mode = GET_MODE (operands[0]);
8587 enum machine_mode vmode = GET_MODE (operands[2]);
8588 rtx tmp;
8589
8590 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8591 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8592 if (operands_match_p (operands[0], operands[2]))
8593 {
8594 tmp = operands[1];
8595 operands[1] = operands[2];
8596 operands[2] = tmp;
8597 }
8598 if (GET_CODE (operands[3]) == ABS)
8599 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8600 else
8601 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8602 operands[3] = tmp;
8603 })
8604
8605 (define_split
8606 [(set (match_operand:SF 0 "register_operand" "")
8607 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8608 (use (match_operand:V4SF 2 "" ""))
8609 (clobber (reg:CC FLAGS_REG))]
8610 "reload_completed"
8611 [(parallel [(set (match_dup 0) (match_dup 1))
8612 (clobber (reg:CC FLAGS_REG))])]
8613 {
8614 rtx tmp;
8615 operands[0] = gen_lowpart (SImode, operands[0]);
8616 if (GET_CODE (operands[1]) == ABS)
8617 {
8618 tmp = gen_int_mode (0x7fffffff, SImode);
8619 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8620 }
8621 else
8622 {
8623 tmp = gen_int_mode (0x80000000, SImode);
8624 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8625 }
8626 operands[1] = tmp;
8627 })
8628
8629 (define_split
8630 [(set (match_operand:DF 0 "register_operand" "")
8631 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8632 (use (match_operand 2 "" ""))
8633 (clobber (reg:CC FLAGS_REG))]
8634 "reload_completed"
8635 [(parallel [(set (match_dup 0) (match_dup 1))
8636 (clobber (reg:CC FLAGS_REG))])]
8637 {
8638 rtx tmp;
8639 if (TARGET_64BIT)
8640 {
8641 tmp = gen_lowpart (DImode, operands[0]);
8642 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8643 operands[0] = tmp;
8644
8645 if (GET_CODE (operands[1]) == ABS)
8646 tmp = const0_rtx;
8647 else
8648 tmp = gen_rtx_NOT (DImode, tmp);
8649 }
8650 else
8651 {
8652 operands[0] = gen_highpart (SImode, operands[0]);
8653 if (GET_CODE (operands[1]) == ABS)
8654 {
8655 tmp = gen_int_mode (0x7fffffff, SImode);
8656 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8657 }
8658 else
8659 {
8660 tmp = gen_int_mode (0x80000000, SImode);
8661 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8662 }
8663 }
8664 operands[1] = tmp;
8665 })
8666
8667 (define_split
8668 [(set (match_operand:XF 0 "register_operand" "")
8669 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8670 (use (match_operand 2 "" ""))
8671 (clobber (reg:CC FLAGS_REG))]
8672 "reload_completed"
8673 [(parallel [(set (match_dup 0) (match_dup 1))
8674 (clobber (reg:CC FLAGS_REG))])]
8675 {
8676 rtx tmp;
8677 operands[0] = gen_rtx_REG (SImode,
8678 true_regnum (operands[0])
8679 + (TARGET_64BIT ? 1 : 2));
8680 if (GET_CODE (operands[1]) == ABS)
8681 {
8682 tmp = GEN_INT (0x7fff);
8683 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8684 }
8685 else
8686 {
8687 tmp = GEN_INT (0x8000);
8688 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8689 }
8690 operands[1] = tmp;
8691 })
8692
8693 ;; Conditionalize these after reload. If they match before reload, we
8694 ;; lose the clobber and ability to use integer instructions.
8695
8696 (define_insn "*<code><mode>2_1"
8697 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8698 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8699 "TARGET_80387
8700 && (reload_completed
8701 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8702 "f<absneg_mnemonic>"
8703 [(set_attr "type" "fsgn")
8704 (set_attr "mode" "<MODE>")])
8705
8706 (define_insn "*<code>extendsfdf2"
8707 [(set (match_operand:DF 0 "register_operand" "=f")
8708 (absneg:DF (float_extend:DF
8709 (match_operand:SF 1 "register_operand" "0"))))]
8710 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8711 "f<absneg_mnemonic>"
8712 [(set_attr "type" "fsgn")
8713 (set_attr "mode" "DF")])
8714
8715 (define_insn "*<code>extendsfxf2"
8716 [(set (match_operand:XF 0 "register_operand" "=f")
8717 (absneg:XF (float_extend:XF
8718 (match_operand:SF 1 "register_operand" "0"))))]
8719 "TARGET_80387"
8720 "f<absneg_mnemonic>"
8721 [(set_attr "type" "fsgn")
8722 (set_attr "mode" "XF")])
8723
8724 (define_insn "*<code>extenddfxf2"
8725 [(set (match_operand:XF 0 "register_operand" "=f")
8726 (absneg:XF (float_extend:XF
8727 (match_operand:DF 1 "register_operand" "0"))))]
8728 "TARGET_80387"
8729 "f<absneg_mnemonic>"
8730 [(set_attr "type" "fsgn")
8731 (set_attr "mode" "XF")])
8732
8733 ;; Copysign instructions
8734
8735 (define_mode_iterator CSGNMODE [SF DF TF])
8736 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8737
8738 (define_expand "copysign<mode>3"
8739 [(match_operand:CSGNMODE 0 "register_operand" "")
8740 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8741 (match_operand:CSGNMODE 2 "register_operand" "")]
8742 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8743 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8744 "ix86_expand_copysign (operands); DONE;")
8745
8746 (define_insn_and_split "copysign<mode>3_const"
8747 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8748 (unspec:CSGNMODE
8749 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8750 (match_operand:CSGNMODE 2 "register_operand" "0")
8751 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8752 UNSPEC_COPYSIGN))]
8753 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8754 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8755 "#"
8756 "&& reload_completed"
8757 [(const_int 0)]
8758 "ix86_split_copysign_const (operands); DONE;")
8759
8760 (define_insn "copysign<mode>3_var"
8761 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8762 (unspec:CSGNMODE
8763 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8764 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8765 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8766 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8767 UNSPEC_COPYSIGN))
8768 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8769 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8770 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8771 "#")
8772
8773 (define_split
8774 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8775 (unspec:CSGNMODE
8776 [(match_operand:CSGNMODE 2 "register_operand" "")
8777 (match_operand:CSGNMODE 3 "register_operand" "")
8778 (match_operand:<CSGNVMODE> 4 "" "")
8779 (match_operand:<CSGNVMODE> 5 "" "")]
8780 UNSPEC_COPYSIGN))
8781 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8782 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8783 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8784 && reload_completed"
8785 [(const_int 0)]
8786 "ix86_split_copysign_var (operands); DONE;")
8787 \f
8788 ;; One complement instructions
8789
8790 (define_expand "one_cmpl<mode>2"
8791 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8792 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8793 ""
8794 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8795
8796 (define_insn "*one_cmpl<mode>2_1"
8797 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8798 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8799 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8800 "not{<imodesuffix>}\t%0"
8801 [(set_attr "type" "negnot")
8802 (set_attr "mode" "<MODE>")])
8803
8804 ;; %%% Potential partial reg stall on alternative 1. What to do?
8805 (define_insn "*one_cmplqi2_1"
8806 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8807 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8808 "ix86_unary_operator_ok (NOT, QImode, operands)"
8809 "@
8810 not{b}\t%0
8811 not{l}\t%k0"
8812 [(set_attr "type" "negnot")
8813 (set_attr "mode" "QI,SI")])
8814
8815 ;; ??? Currently never generated - xor is used instead.
8816 (define_insn "*one_cmplsi2_1_zext"
8817 [(set (match_operand:DI 0 "register_operand" "=r")
8818 (zero_extend:DI
8819 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8820 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8821 "not{l}\t%k0"
8822 [(set_attr "type" "negnot")
8823 (set_attr "mode" "SI")])
8824
8825 (define_insn "*one_cmpl<mode>2_2"
8826 [(set (reg FLAGS_REG)
8827 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8828 (const_int 0)))
8829 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8830 (not:SWI (match_dup 1)))]
8831 "ix86_match_ccmode (insn, CCNOmode)
8832 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8833 "#"
8834 [(set_attr "type" "alu1")
8835 (set_attr "mode" "<MODE>")])
8836
8837 (define_split
8838 [(set (match_operand 0 "flags_reg_operand" "")
8839 (match_operator 2 "compare_operator"
8840 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8841 (const_int 0)]))
8842 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8843 (not:SWI (match_dup 3)))]
8844 "ix86_match_ccmode (insn, CCNOmode)"
8845 [(parallel [(set (match_dup 0)
8846 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8847 (const_int 0)]))
8848 (set (match_dup 1)
8849 (xor:SWI (match_dup 3) (const_int -1)))])])
8850
8851 ;; ??? Currently never generated - xor is used instead.
8852 (define_insn "*one_cmplsi2_2_zext"
8853 [(set (reg FLAGS_REG)
8854 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8855 (const_int 0)))
8856 (set (match_operand:DI 0 "register_operand" "=r")
8857 (zero_extend:DI (not:SI (match_dup 1))))]
8858 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8859 && ix86_unary_operator_ok (NOT, SImode, operands)"
8860 "#"
8861 [(set_attr "type" "alu1")
8862 (set_attr "mode" "SI")])
8863
8864 (define_split
8865 [(set (match_operand 0 "flags_reg_operand" "")
8866 (match_operator 2 "compare_operator"
8867 [(not:SI (match_operand:SI 3 "register_operand" ""))
8868 (const_int 0)]))
8869 (set (match_operand:DI 1 "register_operand" "")
8870 (zero_extend:DI (not:SI (match_dup 3))))]
8871 "ix86_match_ccmode (insn, CCNOmode)"
8872 [(parallel [(set (match_dup 0)
8873 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8874 (const_int 0)]))
8875 (set (match_dup 1)
8876 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8877 \f
8878 ;; Shift instructions
8879
8880 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8881 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8882 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8883 ;; from the assembler input.
8884 ;;
8885 ;; This instruction shifts the target reg/mem as usual, but instead of
8886 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8887 ;; is a left shift double, bits are taken from the high order bits of
8888 ;; reg, else if the insn is a shift right double, bits are taken from the
8889 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8890 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8891 ;;
8892 ;; Since sh[lr]d does not change the `reg' operand, that is done
8893 ;; separately, making all shifts emit pairs of shift double and normal
8894 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8895 ;; support a 63 bit shift, each shift where the count is in a reg expands
8896 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8897 ;;
8898 ;; If the shift count is a constant, we need never emit more than one
8899 ;; shift pair, instead using moves and sign extension for counts greater
8900 ;; than 31.
8901
8902 (define_expand "ashl<mode>3"
8903 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8904 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8905 (match_operand:QI 2 "nonmemory_operand" "")))]
8906 ""
8907 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8908
8909 (define_insn "*ashl<mode>3_doubleword"
8910 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8911 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8912 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8913 (clobber (reg:CC FLAGS_REG))]
8914 ""
8915 "#"
8916 [(set_attr "type" "multi")])
8917
8918 (define_split
8919 [(set (match_operand:DWI 0 "register_operand" "")
8920 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8921 (match_operand:QI 2 "nonmemory_operand" "")))
8922 (clobber (reg:CC FLAGS_REG))]
8923 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8924 [(const_int 0)]
8925 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8926
8927 ;; By default we don't ask for a scratch register, because when DWImode
8928 ;; values are manipulated, registers are already at a premium. But if
8929 ;; we have one handy, we won't turn it away.
8930
8931 (define_peephole2
8932 [(match_scratch:DWIH 3 "r")
8933 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8934 (ashift:<DWI>
8935 (match_operand:<DWI> 1 "nonmemory_operand" "")
8936 (match_operand:QI 2 "nonmemory_operand" "")))
8937 (clobber (reg:CC FLAGS_REG))])
8938 (match_dup 3)]
8939 "TARGET_CMOVE"
8940 [(const_int 0)]
8941 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8942
8943 (define_insn "x86_64_shld"
8944 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8945 (ior:DI (ashift:DI (match_dup 0)
8946 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8947 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8948 (minus:QI (const_int 64) (match_dup 2)))))
8949 (clobber (reg:CC FLAGS_REG))]
8950 "TARGET_64BIT"
8951 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8952 [(set_attr "type" "ishift")
8953 (set_attr "prefix_0f" "1")
8954 (set_attr "mode" "DI")
8955 (set_attr "athlon_decode" "vector")
8956 (set_attr "amdfam10_decode" "vector")
8957 (set_attr "bdver1_decode" "vector")])
8958
8959 (define_insn "x86_shld"
8960 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8961 (ior:SI (ashift:SI (match_dup 0)
8962 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8963 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8964 (minus:QI (const_int 32) (match_dup 2)))))
8965 (clobber (reg:CC FLAGS_REG))]
8966 ""
8967 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8968 [(set_attr "type" "ishift")
8969 (set_attr "prefix_0f" "1")
8970 (set_attr "mode" "SI")
8971 (set_attr "pent_pair" "np")
8972 (set_attr "athlon_decode" "vector")
8973 (set_attr "amdfam10_decode" "vector")
8974 (set_attr "bdver1_decode" "vector")])
8975
8976 (define_expand "x86_shift<mode>_adj_1"
8977 [(set (reg:CCZ FLAGS_REG)
8978 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8979 (match_dup 4))
8980 (const_int 0)))
8981 (set (match_operand:SWI48 0 "register_operand" "")
8982 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8983 (match_operand:SWI48 1 "register_operand" "")
8984 (match_dup 0)))
8985 (set (match_dup 1)
8986 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8987 (match_operand:SWI48 3 "register_operand" "")
8988 (match_dup 1)))]
8989 "TARGET_CMOVE"
8990 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8991
8992 (define_expand "x86_shift<mode>_adj_2"
8993 [(use (match_operand:SWI48 0 "register_operand" ""))
8994 (use (match_operand:SWI48 1 "register_operand" ""))
8995 (use (match_operand:QI 2 "register_operand" ""))]
8996 ""
8997 {
8998 rtx label = gen_label_rtx ();
8999 rtx tmp;
9000
9001 emit_insn (gen_testqi_ccz_1 (operands[2],
9002 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9003
9004 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9005 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9006 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9007 gen_rtx_LABEL_REF (VOIDmode, label),
9008 pc_rtx);
9009 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9010 JUMP_LABEL (tmp) = label;
9011
9012 emit_move_insn (operands[0], operands[1]);
9013 ix86_expand_clear (operands[1]);
9014
9015 emit_label (label);
9016 LABEL_NUSES (label) = 1;
9017
9018 DONE;
9019 })
9020
9021 ;; Avoid useless masking of count operand.
9022 (define_insn_and_split "*ashl<mode>3_mask"
9023 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9024 (ashift:SWI48
9025 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9026 (subreg:QI
9027 (and:SI
9028 (match_operand:SI 2 "nonimmediate_operand" "c")
9029 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9030 (clobber (reg:CC FLAGS_REG))]
9031 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9032 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9033 == GET_MODE_BITSIZE (<MODE>mode)-1"
9034 "#"
9035 "&& 1"
9036 [(parallel [(set (match_dup 0)
9037 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9038 (clobber (reg:CC FLAGS_REG))])]
9039 {
9040 if (can_create_pseudo_p ())
9041 operands [2] = force_reg (SImode, operands[2]);
9042
9043 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9044 }
9045 [(set_attr "type" "ishift")
9046 (set_attr "mode" "<MODE>")])
9047
9048 (define_insn "*bmi2_ashl<mode>3_1"
9049 [(set (match_operand:SWI48 0 "register_operand" "=r")
9050 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9051 (match_operand:SWI48 2 "register_operand" "r")))]
9052 "TARGET_BMI2"
9053 "shlx\t{%2, %1, %0|%0, %1, %2}"
9054 [(set_attr "type" "ishiftx")
9055 (set_attr "mode" "<MODE>")])
9056
9057 (define_insn "*ashl<mode>3_1"
9058 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9059 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9060 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9063 {
9064 switch (get_attr_type (insn))
9065 {
9066 case TYPE_LEA:
9067 case TYPE_ISHIFTX:
9068 return "#";
9069
9070 case TYPE_ALU:
9071 gcc_assert (operands[2] == const1_rtx);
9072 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9073 return "add{<imodesuffix>}\t%0, %0";
9074
9075 default:
9076 if (operands[2] == const1_rtx
9077 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9078 return "sal{<imodesuffix>}\t%0";
9079 else
9080 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9081 }
9082 }
9083 [(set_attr "isa" "*,*,bmi2")
9084 (set (attr "type")
9085 (cond [(eq_attr "alternative" "1")
9086 (const_string "lea")
9087 (eq_attr "alternative" "2")
9088 (const_string "ishiftx")
9089 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9090 (match_operand 0 "register_operand" ""))
9091 (match_operand 2 "const1_operand" ""))
9092 (const_string "alu")
9093 ]
9094 (const_string "ishift")))
9095 (set (attr "length_immediate")
9096 (if_then_else
9097 (ior (eq_attr "type" "alu")
9098 (and (eq_attr "type" "ishift")
9099 (and (match_operand 2 "const1_operand" "")
9100 (ior (match_test "TARGET_SHIFT1")
9101 (match_test "optimize_function_for_size_p (cfun)")))))
9102 (const_string "0")
9103 (const_string "*")))
9104 (set_attr "mode" "<MODE>")])
9105
9106 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9107 (define_split
9108 [(set (match_operand:SWI48 0 "register_operand" "")
9109 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9110 (match_operand:QI 2 "register_operand" "")))
9111 (clobber (reg:CC FLAGS_REG))]
9112 "TARGET_BMI2 && reload_completed"
9113 [(set (match_dup 0)
9114 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9115 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9116
9117 (define_insn "*bmi2_ashlsi3_1_zext"
9118 [(set (match_operand:DI 0 "register_operand" "=r")
9119 (zero_extend:DI
9120 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9121 (match_operand:SI 2 "register_operand" "r"))))]
9122 "TARGET_64BIT && TARGET_BMI2"
9123 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9124 [(set_attr "type" "ishiftx")
9125 (set_attr "mode" "SI")])
9126
9127 (define_insn "*ashlsi3_1_zext"
9128 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9129 (zero_extend:DI
9130 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9131 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9132 (clobber (reg:CC FLAGS_REG))]
9133 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9134 {
9135 switch (get_attr_type (insn))
9136 {
9137 case TYPE_LEA:
9138 case TYPE_ISHIFTX:
9139 return "#";
9140
9141 case TYPE_ALU:
9142 gcc_assert (operands[2] == const1_rtx);
9143 return "add{l}\t%k0, %k0";
9144
9145 default:
9146 if (operands[2] == const1_rtx
9147 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9148 return "sal{l}\t%k0";
9149 else
9150 return "sal{l}\t{%2, %k0|%k0, %2}";
9151 }
9152 }
9153 [(set_attr "isa" "*,*,bmi2")
9154 (set (attr "type")
9155 (cond [(eq_attr "alternative" "1")
9156 (const_string "lea")
9157 (eq_attr "alternative" "2")
9158 (const_string "ishiftx")
9159 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9160 (match_operand 2 "const1_operand" ""))
9161 (const_string "alu")
9162 ]
9163 (const_string "ishift")))
9164 (set (attr "length_immediate")
9165 (if_then_else
9166 (ior (eq_attr "type" "alu")
9167 (and (eq_attr "type" "ishift")
9168 (and (match_operand 2 "const1_operand" "")
9169 (ior (match_test "TARGET_SHIFT1")
9170 (match_test "optimize_function_for_size_p (cfun)")))))
9171 (const_string "0")
9172 (const_string "*")))
9173 (set_attr "mode" "SI")])
9174
9175 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9176 (define_split
9177 [(set (match_operand:DI 0 "register_operand" "")
9178 (zero_extend:DI
9179 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9180 (match_operand:QI 2 "register_operand" ""))))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9183 [(set (match_dup 0)
9184 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9185 "operands[2] = gen_lowpart (SImode, operands[2]);")
9186
9187 (define_insn "*ashlhi3_1"
9188 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9189 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9190 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9191 (clobber (reg:CC FLAGS_REG))]
9192 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9193 {
9194 switch (get_attr_type (insn))
9195 {
9196 case TYPE_LEA:
9197 return "#";
9198
9199 case TYPE_ALU:
9200 gcc_assert (operands[2] == const1_rtx);
9201 return "add{w}\t%0, %0";
9202
9203 default:
9204 if (operands[2] == const1_rtx
9205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206 return "sal{w}\t%0";
9207 else
9208 return "sal{w}\t{%2, %0|%0, %2}";
9209 }
9210 }
9211 [(set (attr "type")
9212 (cond [(eq_attr "alternative" "1")
9213 (const_string "lea")
9214 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9215 (match_operand 0 "register_operand" ""))
9216 (match_operand 2 "const1_operand" ""))
9217 (const_string "alu")
9218 ]
9219 (const_string "ishift")))
9220 (set (attr "length_immediate")
9221 (if_then_else
9222 (ior (eq_attr "type" "alu")
9223 (and (eq_attr "type" "ishift")
9224 (and (match_operand 2 "const1_operand" "")
9225 (ior (match_test "TARGET_SHIFT1")
9226 (match_test "optimize_function_for_size_p (cfun)")))))
9227 (const_string "0")
9228 (const_string "*")))
9229 (set_attr "mode" "HI,SI")])
9230
9231 ;; %%% Potential partial reg stall on alternative 1. What to do?
9232 (define_insn "*ashlqi3_1"
9233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9234 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9235 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9236 (clobber (reg:CC FLAGS_REG))]
9237 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9238 {
9239 switch (get_attr_type (insn))
9240 {
9241 case TYPE_LEA:
9242 return "#";
9243
9244 case TYPE_ALU:
9245 gcc_assert (operands[2] == const1_rtx);
9246 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9247 return "add{l}\t%k0, %k0";
9248 else
9249 return "add{b}\t%0, %0";
9250
9251 default:
9252 if (operands[2] == const1_rtx
9253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9254 {
9255 if (get_attr_mode (insn) == MODE_SI)
9256 return "sal{l}\t%k0";
9257 else
9258 return "sal{b}\t%0";
9259 }
9260 else
9261 {
9262 if (get_attr_mode (insn) == MODE_SI)
9263 return "sal{l}\t{%2, %k0|%k0, %2}";
9264 else
9265 return "sal{b}\t{%2, %0|%0, %2}";
9266 }
9267 }
9268 }
9269 [(set (attr "type")
9270 (cond [(eq_attr "alternative" "2")
9271 (const_string "lea")
9272 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9273 (match_operand 0 "register_operand" ""))
9274 (match_operand 2 "const1_operand" ""))
9275 (const_string "alu")
9276 ]
9277 (const_string "ishift")))
9278 (set (attr "length_immediate")
9279 (if_then_else
9280 (ior (eq_attr "type" "alu")
9281 (and (eq_attr "type" "ishift")
9282 (and (match_operand 2 "const1_operand" "")
9283 (ior (match_test "TARGET_SHIFT1")
9284 (match_test "optimize_function_for_size_p (cfun)")))))
9285 (const_string "0")
9286 (const_string "*")))
9287 (set_attr "mode" "QI,SI,SI")])
9288
9289 (define_insn "*ashlqi3_1_slp"
9290 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9291 (ashift:QI (match_dup 0)
9292 (match_operand:QI 1 "nonmemory_operand" "cI")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "(optimize_function_for_size_p (cfun)
9295 || !TARGET_PARTIAL_FLAG_REG_STALL
9296 || (operands[1] == const1_rtx
9297 && (TARGET_SHIFT1
9298 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9299 {
9300 switch (get_attr_type (insn))
9301 {
9302 case TYPE_ALU:
9303 gcc_assert (operands[1] == const1_rtx);
9304 return "add{b}\t%0, %0";
9305
9306 default:
9307 if (operands[1] == const1_rtx
9308 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9309 return "sal{b}\t%0";
9310 else
9311 return "sal{b}\t{%1, %0|%0, %1}";
9312 }
9313 }
9314 [(set (attr "type")
9315 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9316 (match_operand 0 "register_operand" ""))
9317 (match_operand 1 "const1_operand" ""))
9318 (const_string "alu")
9319 ]
9320 (const_string "ishift1")))
9321 (set (attr "length_immediate")
9322 (if_then_else
9323 (ior (eq_attr "type" "alu")
9324 (and (eq_attr "type" "ishift1")
9325 (and (match_operand 1 "const1_operand" "")
9326 (ior (match_test "TARGET_SHIFT1")
9327 (match_test "optimize_function_for_size_p (cfun)")))))
9328 (const_string "0")
9329 (const_string "*")))
9330 (set_attr "mode" "QI")])
9331
9332 ;; Convert ashift to the lea pattern to avoid flags dependency.
9333 (define_split
9334 [(set (match_operand 0 "register_operand" "")
9335 (ashift (match_operand 1 "index_register_operand" "")
9336 (match_operand:QI 2 "const_int_operand" "")))
9337 (clobber (reg:CC FLAGS_REG))]
9338 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9339 && reload_completed
9340 && true_regnum (operands[0]) != true_regnum (operands[1])"
9341 [(const_int 0)]
9342 {
9343 enum machine_mode mode = GET_MODE (operands[0]);
9344 rtx pat;
9345
9346 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9347 {
9348 mode = SImode;
9349 operands[0] = gen_lowpart (mode, operands[0]);
9350 operands[1] = gen_lowpart (mode, operands[1]);
9351 }
9352
9353 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9354
9355 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9356
9357 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9358 DONE;
9359 })
9360
9361 ;; Convert ashift to the lea pattern to avoid flags dependency.
9362 (define_split
9363 [(set (match_operand:DI 0 "register_operand" "")
9364 (zero_extend:DI
9365 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9366 (match_operand:QI 2 "const_int_operand" ""))))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "TARGET_64BIT && reload_completed
9369 && true_regnum (operands[0]) != true_regnum (operands[1])"
9370 [(set (match_dup 0)
9371 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9372 {
9373 operands[1] = gen_lowpart (DImode, operands[1]);
9374 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9375 })
9376
9377 ;; This pattern can't accept a variable shift count, since shifts by
9378 ;; zero don't affect the flags. We assume that shifts by constant
9379 ;; zero are optimized away.
9380 (define_insn "*ashl<mode>3_cmp"
9381 [(set (reg FLAGS_REG)
9382 (compare
9383 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9384 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9385 (const_int 0)))
9386 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9387 (ashift:SWI (match_dup 1) (match_dup 2)))]
9388 "(optimize_function_for_size_p (cfun)
9389 || !TARGET_PARTIAL_FLAG_REG_STALL
9390 || (operands[2] == const1_rtx
9391 && (TARGET_SHIFT1
9392 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9393 && ix86_match_ccmode (insn, CCGOCmode)
9394 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9395 {
9396 switch (get_attr_type (insn))
9397 {
9398 case TYPE_ALU:
9399 gcc_assert (operands[2] == const1_rtx);
9400 return "add{<imodesuffix>}\t%0, %0";
9401
9402 default:
9403 if (operands[2] == const1_rtx
9404 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9405 return "sal{<imodesuffix>}\t%0";
9406 else
9407 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9408 }
9409 }
9410 [(set (attr "type")
9411 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9412 (match_operand 0 "register_operand" ""))
9413 (match_operand 2 "const1_operand" ""))
9414 (const_string "alu")
9415 ]
9416 (const_string "ishift")))
9417 (set (attr "length_immediate")
9418 (if_then_else
9419 (ior (eq_attr "type" "alu")
9420 (and (eq_attr "type" "ishift")
9421 (and (match_operand 2 "const1_operand" "")
9422 (ior (match_test "TARGET_SHIFT1")
9423 (match_test "optimize_function_for_size_p (cfun)")))))
9424 (const_string "0")
9425 (const_string "*")))
9426 (set_attr "mode" "<MODE>")])
9427
9428 (define_insn "*ashlsi3_cmp_zext"
9429 [(set (reg FLAGS_REG)
9430 (compare
9431 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9432 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9433 (const_int 0)))
9434 (set (match_operand:DI 0 "register_operand" "=r")
9435 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9436 "TARGET_64BIT
9437 && (optimize_function_for_size_p (cfun)
9438 || !TARGET_PARTIAL_FLAG_REG_STALL
9439 || (operands[2] == const1_rtx
9440 && (TARGET_SHIFT1
9441 || TARGET_DOUBLE_WITH_ADD)))
9442 && ix86_match_ccmode (insn, CCGOCmode)
9443 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9444 {
9445 switch (get_attr_type (insn))
9446 {
9447 case TYPE_ALU:
9448 gcc_assert (operands[2] == const1_rtx);
9449 return "add{l}\t%k0, %k0";
9450
9451 default:
9452 if (operands[2] == const1_rtx
9453 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9454 return "sal{l}\t%k0";
9455 else
9456 return "sal{l}\t{%2, %k0|%k0, %2}";
9457 }
9458 }
9459 [(set (attr "type")
9460 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9461 (match_operand 2 "const1_operand" ""))
9462 (const_string "alu")
9463 ]
9464 (const_string "ishift")))
9465 (set (attr "length_immediate")
9466 (if_then_else
9467 (ior (eq_attr "type" "alu")
9468 (and (eq_attr "type" "ishift")
9469 (and (match_operand 2 "const1_operand" "")
9470 (ior (match_test "TARGET_SHIFT1")
9471 (match_test "optimize_function_for_size_p (cfun)")))))
9472 (const_string "0")
9473 (const_string "*")))
9474 (set_attr "mode" "SI")])
9475
9476 (define_insn "*ashl<mode>3_cconly"
9477 [(set (reg FLAGS_REG)
9478 (compare
9479 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9480 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9481 (const_int 0)))
9482 (clobber (match_scratch:SWI 0 "=<r>"))]
9483 "(optimize_function_for_size_p (cfun)
9484 || !TARGET_PARTIAL_FLAG_REG_STALL
9485 || (operands[2] == const1_rtx
9486 && (TARGET_SHIFT1
9487 || TARGET_DOUBLE_WITH_ADD)))
9488 && ix86_match_ccmode (insn, CCGOCmode)"
9489 {
9490 switch (get_attr_type (insn))
9491 {
9492 case TYPE_ALU:
9493 gcc_assert (operands[2] == const1_rtx);
9494 return "add{<imodesuffix>}\t%0, %0";
9495
9496 default:
9497 if (operands[2] == const1_rtx
9498 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9499 return "sal{<imodesuffix>}\t%0";
9500 else
9501 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9502 }
9503 }
9504 [(set (attr "type")
9505 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9506 (match_operand 0 "register_operand" ""))
9507 (match_operand 2 "const1_operand" ""))
9508 (const_string "alu")
9509 ]
9510 (const_string "ishift")))
9511 (set (attr "length_immediate")
9512 (if_then_else
9513 (ior (eq_attr "type" "alu")
9514 (and (eq_attr "type" "ishift")
9515 (and (match_operand 2 "const1_operand" "")
9516 (ior (match_test "TARGET_SHIFT1")
9517 (match_test "optimize_function_for_size_p (cfun)")))))
9518 (const_string "0")
9519 (const_string "*")))
9520 (set_attr "mode" "<MODE>")])
9521
9522 ;; See comment above `ashl<mode>3' about how this works.
9523
9524 (define_expand "<shift_insn><mode>3"
9525 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9526 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9527 (match_operand:QI 2 "nonmemory_operand" "")))]
9528 ""
9529 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9530
9531 ;; Avoid useless masking of count operand.
9532 (define_insn_and_split "*<shift_insn><mode>3_mask"
9533 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9534 (any_shiftrt:SWI48
9535 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9536 (subreg:QI
9537 (and:SI
9538 (match_operand:SI 2 "nonimmediate_operand" "c")
9539 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9540 (clobber (reg:CC FLAGS_REG))]
9541 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9542 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9543 == GET_MODE_BITSIZE (<MODE>mode)-1"
9544 "#"
9545 "&& 1"
9546 [(parallel [(set (match_dup 0)
9547 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9548 (clobber (reg:CC FLAGS_REG))])]
9549 {
9550 if (can_create_pseudo_p ())
9551 operands [2] = force_reg (SImode, operands[2]);
9552
9553 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9554 }
9555 [(set_attr "type" "ishift")
9556 (set_attr "mode" "<MODE>")])
9557
9558 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9559 [(set (match_operand:DWI 0 "register_operand" "=r")
9560 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9561 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9562 (clobber (reg:CC FLAGS_REG))]
9563 ""
9564 "#"
9565 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9566 [(const_int 0)]
9567 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9568 [(set_attr "type" "multi")])
9569
9570 ;; By default we don't ask for a scratch register, because when DWImode
9571 ;; values are manipulated, registers are already at a premium. But if
9572 ;; we have one handy, we won't turn it away.
9573
9574 (define_peephole2
9575 [(match_scratch:DWIH 3 "r")
9576 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9577 (any_shiftrt:<DWI>
9578 (match_operand:<DWI> 1 "register_operand" "")
9579 (match_operand:QI 2 "nonmemory_operand" "")))
9580 (clobber (reg:CC FLAGS_REG))])
9581 (match_dup 3)]
9582 "TARGET_CMOVE"
9583 [(const_int 0)]
9584 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9585
9586 (define_insn "x86_64_shrd"
9587 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9588 (ior:DI (ashiftrt:DI (match_dup 0)
9589 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9590 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9591 (minus:QI (const_int 64) (match_dup 2)))))
9592 (clobber (reg:CC FLAGS_REG))]
9593 "TARGET_64BIT"
9594 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9595 [(set_attr "type" "ishift")
9596 (set_attr "prefix_0f" "1")
9597 (set_attr "mode" "DI")
9598 (set_attr "athlon_decode" "vector")
9599 (set_attr "amdfam10_decode" "vector")
9600 (set_attr "bdver1_decode" "vector")])
9601
9602 (define_insn "x86_shrd"
9603 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9604 (ior:SI (ashiftrt:SI (match_dup 0)
9605 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9606 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9607 (minus:QI (const_int 32) (match_dup 2)))))
9608 (clobber (reg:CC FLAGS_REG))]
9609 ""
9610 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9611 [(set_attr "type" "ishift")
9612 (set_attr "prefix_0f" "1")
9613 (set_attr "mode" "SI")
9614 (set_attr "pent_pair" "np")
9615 (set_attr "athlon_decode" "vector")
9616 (set_attr "amdfam10_decode" "vector")
9617 (set_attr "bdver1_decode" "vector")])
9618
9619 (define_insn "ashrdi3_cvt"
9620 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9621 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9622 (match_operand:QI 2 "const_int_operand" "")))
9623 (clobber (reg:CC FLAGS_REG))]
9624 "TARGET_64BIT && INTVAL (operands[2]) == 63
9625 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9626 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9627 "@
9628 {cqto|cqo}
9629 sar{q}\t{%2, %0|%0, %2}"
9630 [(set_attr "type" "imovx,ishift")
9631 (set_attr "prefix_0f" "0,*")
9632 (set_attr "length_immediate" "0,*")
9633 (set_attr "modrm" "0,1")
9634 (set_attr "mode" "DI")])
9635
9636 (define_insn "ashrsi3_cvt"
9637 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9638 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9639 (match_operand:QI 2 "const_int_operand" "")))
9640 (clobber (reg:CC FLAGS_REG))]
9641 "INTVAL (operands[2]) == 31
9642 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9643 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9644 "@
9645 {cltd|cdq}
9646 sar{l}\t{%2, %0|%0, %2}"
9647 [(set_attr "type" "imovx,ishift")
9648 (set_attr "prefix_0f" "0,*")
9649 (set_attr "length_immediate" "0,*")
9650 (set_attr "modrm" "0,1")
9651 (set_attr "mode" "SI")])
9652
9653 (define_insn "*ashrsi3_cvt_zext"
9654 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9655 (zero_extend:DI
9656 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9657 (match_operand:QI 2 "const_int_operand" ""))))
9658 (clobber (reg:CC FLAGS_REG))]
9659 "TARGET_64BIT && INTVAL (operands[2]) == 31
9660 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9661 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9662 "@
9663 {cltd|cdq}
9664 sar{l}\t{%2, %k0|%k0, %2}"
9665 [(set_attr "type" "imovx,ishift")
9666 (set_attr "prefix_0f" "0,*")
9667 (set_attr "length_immediate" "0,*")
9668 (set_attr "modrm" "0,1")
9669 (set_attr "mode" "SI")])
9670
9671 (define_expand "x86_shift<mode>_adj_3"
9672 [(use (match_operand:SWI48 0 "register_operand" ""))
9673 (use (match_operand:SWI48 1 "register_operand" ""))
9674 (use (match_operand:QI 2 "register_operand" ""))]
9675 ""
9676 {
9677 rtx label = gen_label_rtx ();
9678 rtx tmp;
9679
9680 emit_insn (gen_testqi_ccz_1 (operands[2],
9681 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9682
9683 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9684 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9685 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9686 gen_rtx_LABEL_REF (VOIDmode, label),
9687 pc_rtx);
9688 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9689 JUMP_LABEL (tmp) = label;
9690
9691 emit_move_insn (operands[0], operands[1]);
9692 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9693 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9694 emit_label (label);
9695 LABEL_NUSES (label) = 1;
9696
9697 DONE;
9698 })
9699
9700 (define_insn "*bmi2_<shift_insn><mode>3_1"
9701 [(set (match_operand:SWI48 0 "register_operand" "=r")
9702 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9703 (match_operand:SWI48 2 "register_operand" "r")))]
9704 "TARGET_BMI2"
9705 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9706 [(set_attr "type" "ishiftx")
9707 (set_attr "mode" "<MODE>")])
9708
9709 (define_insn "*<shift_insn><mode>3_1"
9710 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9711 (any_shiftrt:SWI48
9712 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9713 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9716 {
9717 switch (get_attr_type (insn))
9718 {
9719 case TYPE_ISHIFTX:
9720 return "#";
9721
9722 default:
9723 if (operands[2] == const1_rtx
9724 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9725 return "<shift>{<imodesuffix>}\t%0";
9726 else
9727 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9728 }
9729 }
9730 [(set_attr "isa" "*,bmi2")
9731 (set_attr "type" "ishift,ishiftx")
9732 (set (attr "length_immediate")
9733 (if_then_else
9734 (and (match_operand 2 "const1_operand" "")
9735 (ior (match_test "TARGET_SHIFT1")
9736 (match_test "optimize_function_for_size_p (cfun)")))
9737 (const_string "0")
9738 (const_string "*")))
9739 (set_attr "mode" "<MODE>")])
9740
9741 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9742 (define_split
9743 [(set (match_operand:SWI48 0 "register_operand" "")
9744 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9745 (match_operand:QI 2 "register_operand" "")))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "TARGET_BMI2 && reload_completed"
9748 [(set (match_dup 0)
9749 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9750 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9751
9752 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9753 [(set (match_operand:DI 0 "register_operand" "=r")
9754 (zero_extend:DI
9755 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9756 (match_operand:SI 2 "register_operand" "r"))))]
9757 "TARGET_64BIT && TARGET_BMI2"
9758 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9759 [(set_attr "type" "ishiftx")
9760 (set_attr "mode" "SI")])
9761
9762 (define_insn "*<shift_insn>si3_1_zext"
9763 [(set (match_operand:DI 0 "register_operand" "=r,r")
9764 (zero_extend:DI
9765 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9766 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9769 {
9770 switch (get_attr_type (insn))
9771 {
9772 case TYPE_ISHIFTX:
9773 return "#";
9774
9775 default:
9776 if (operands[2] == const1_rtx
9777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9778 return "<shift>{l}\t%k0";
9779 else
9780 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9781 }
9782 }
9783 [(set_attr "isa" "*,bmi2")
9784 (set_attr "type" "ishift,ishiftx")
9785 (set (attr "length_immediate")
9786 (if_then_else
9787 (and (match_operand 2 "const1_operand" "")
9788 (ior (match_test "TARGET_SHIFT1")
9789 (match_test "optimize_function_for_size_p (cfun)")))
9790 (const_string "0")
9791 (const_string "*")))
9792 (set_attr "mode" "SI")])
9793
9794 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9795 (define_split
9796 [(set (match_operand:DI 0 "register_operand" "")
9797 (zero_extend:DI
9798 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9799 (match_operand:QI 2 "register_operand" ""))))
9800 (clobber (reg:CC FLAGS_REG))]
9801 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9802 [(set (match_dup 0)
9803 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9804 "operands[2] = gen_lowpart (SImode, operands[2]);")
9805
9806 (define_insn "*<shift_insn><mode>3_1"
9807 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9808 (any_shiftrt:SWI12
9809 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9810 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9811 (clobber (reg:CC FLAGS_REG))]
9812 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9813 {
9814 if (operands[2] == const1_rtx
9815 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9816 return "<shift>{<imodesuffix>}\t%0";
9817 else
9818 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9819 }
9820 [(set_attr "type" "ishift")
9821 (set (attr "length_immediate")
9822 (if_then_else
9823 (and (match_operand 2 "const1_operand" "")
9824 (ior (match_test "TARGET_SHIFT1")
9825 (match_test "optimize_function_for_size_p (cfun)")))
9826 (const_string "0")
9827 (const_string "*")))
9828 (set_attr "mode" "<MODE>")])
9829
9830 (define_insn "*<shift_insn>qi3_1_slp"
9831 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9832 (any_shiftrt:QI (match_dup 0)
9833 (match_operand:QI 1 "nonmemory_operand" "cI")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "(optimize_function_for_size_p (cfun)
9836 || !TARGET_PARTIAL_REG_STALL
9837 || (operands[1] == const1_rtx
9838 && TARGET_SHIFT1))"
9839 {
9840 if (operands[1] == const1_rtx
9841 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9842 return "<shift>{b}\t%0";
9843 else
9844 return "<shift>{b}\t{%1, %0|%0, %1}";
9845 }
9846 [(set_attr "type" "ishift1")
9847 (set (attr "length_immediate")
9848 (if_then_else
9849 (and (match_operand 1 "const1_operand" "")
9850 (ior (match_test "TARGET_SHIFT1")
9851 (match_test "optimize_function_for_size_p (cfun)")))
9852 (const_string "0")
9853 (const_string "*")))
9854 (set_attr "mode" "QI")])
9855
9856 ;; This pattern can't accept a variable shift count, since shifts by
9857 ;; zero don't affect the flags. We assume that shifts by constant
9858 ;; zero are optimized away.
9859 (define_insn "*<shift_insn><mode>3_cmp"
9860 [(set (reg FLAGS_REG)
9861 (compare
9862 (any_shiftrt:SWI
9863 (match_operand:SWI 1 "nonimmediate_operand" "0")
9864 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9865 (const_int 0)))
9866 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9867 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9868 "(optimize_function_for_size_p (cfun)
9869 || !TARGET_PARTIAL_FLAG_REG_STALL
9870 || (operands[2] == const1_rtx
9871 && TARGET_SHIFT1))
9872 && ix86_match_ccmode (insn, CCGOCmode)
9873 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9874 {
9875 if (operands[2] == const1_rtx
9876 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9877 return "<shift>{<imodesuffix>}\t%0";
9878 else
9879 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9880 }
9881 [(set_attr "type" "ishift")
9882 (set (attr "length_immediate")
9883 (if_then_else
9884 (and (match_operand 2 "const1_operand" "")
9885 (ior (match_test "TARGET_SHIFT1")
9886 (match_test "optimize_function_for_size_p (cfun)")))
9887 (const_string "0")
9888 (const_string "*")))
9889 (set_attr "mode" "<MODE>")])
9890
9891 (define_insn "*<shift_insn>si3_cmp_zext"
9892 [(set (reg FLAGS_REG)
9893 (compare
9894 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9895 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9896 (const_int 0)))
9897 (set (match_operand:DI 0 "register_operand" "=r")
9898 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9899 "TARGET_64BIT
9900 && (optimize_function_for_size_p (cfun)
9901 || !TARGET_PARTIAL_FLAG_REG_STALL
9902 || (operands[2] == const1_rtx
9903 && TARGET_SHIFT1))
9904 && ix86_match_ccmode (insn, CCGOCmode)
9905 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9906 {
9907 if (operands[2] == const1_rtx
9908 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9909 return "<shift>{l}\t%k0";
9910 else
9911 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9912 }
9913 [(set_attr "type" "ishift")
9914 (set (attr "length_immediate")
9915 (if_then_else
9916 (and (match_operand 2 "const1_operand" "")
9917 (ior (match_test "TARGET_SHIFT1")
9918 (match_test "optimize_function_for_size_p (cfun)")))
9919 (const_string "0")
9920 (const_string "*")))
9921 (set_attr "mode" "SI")])
9922
9923 (define_insn "*<shift_insn><mode>3_cconly"
9924 [(set (reg FLAGS_REG)
9925 (compare
9926 (any_shiftrt:SWI
9927 (match_operand:SWI 1 "register_operand" "0")
9928 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9929 (const_int 0)))
9930 (clobber (match_scratch:SWI 0 "=<r>"))]
9931 "(optimize_function_for_size_p (cfun)
9932 || !TARGET_PARTIAL_FLAG_REG_STALL
9933 || (operands[2] == const1_rtx
9934 && TARGET_SHIFT1))
9935 && ix86_match_ccmode (insn, CCGOCmode)"
9936 {
9937 if (operands[2] == const1_rtx
9938 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9939 return "<shift>{<imodesuffix>}\t%0";
9940 else
9941 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9942 }
9943 [(set_attr "type" "ishift")
9944 (set (attr "length_immediate")
9945 (if_then_else
9946 (and (match_operand 2 "const1_operand" "")
9947 (ior (match_test "TARGET_SHIFT1")
9948 (match_test "optimize_function_for_size_p (cfun)")))
9949 (const_string "0")
9950 (const_string "*")))
9951 (set_attr "mode" "<MODE>")])
9952 \f
9953 ;; Rotate instructions
9954
9955 (define_expand "<rotate_insn>ti3"
9956 [(set (match_operand:TI 0 "register_operand" "")
9957 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9958 (match_operand:QI 2 "nonmemory_operand" "")))]
9959 "TARGET_64BIT"
9960 {
9961 if (const_1_to_63_operand (operands[2], VOIDmode))
9962 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9963 (operands[0], operands[1], operands[2]));
9964 else
9965 FAIL;
9966
9967 DONE;
9968 })
9969
9970 (define_expand "<rotate_insn>di3"
9971 [(set (match_operand:DI 0 "shiftdi_operand" "")
9972 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9973 (match_operand:QI 2 "nonmemory_operand" "")))]
9974 ""
9975 {
9976 if (TARGET_64BIT)
9977 ix86_expand_binary_operator (<CODE>, DImode, operands);
9978 else if (const_1_to_31_operand (operands[2], VOIDmode))
9979 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9980 (operands[0], operands[1], operands[2]));
9981 else
9982 FAIL;
9983
9984 DONE;
9985 })
9986
9987 (define_expand "<rotate_insn><mode>3"
9988 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9989 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9990 (match_operand:QI 2 "nonmemory_operand" "")))]
9991 ""
9992 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9993
9994 ;; Avoid useless masking of count operand.
9995 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9996 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9997 (any_rotate:SWI48
9998 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9999 (subreg:QI
10000 (and:SI
10001 (match_operand:SI 2 "nonimmediate_operand" "c")
10002 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10003 (clobber (reg:CC FLAGS_REG))]
10004 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10005 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10006 == GET_MODE_BITSIZE (<MODE>mode)-1"
10007 "#"
10008 "&& 1"
10009 [(parallel [(set (match_dup 0)
10010 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10011 (clobber (reg:CC FLAGS_REG))])]
10012 {
10013 if (can_create_pseudo_p ())
10014 operands [2] = force_reg (SImode, operands[2]);
10015
10016 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10017 }
10018 [(set_attr "type" "rotate")
10019 (set_attr "mode" "<MODE>")])
10020
10021 ;; Implement rotation using two double-precision
10022 ;; shift instructions and a scratch register.
10023
10024 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10025 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10026 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10027 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10028 (clobber (reg:CC FLAGS_REG))
10029 (clobber (match_scratch:DWIH 3 "=&r"))]
10030 ""
10031 "#"
10032 "reload_completed"
10033 [(set (match_dup 3) (match_dup 4))
10034 (parallel
10035 [(set (match_dup 4)
10036 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10037 (lshiftrt:DWIH (match_dup 5)
10038 (minus:QI (match_dup 6) (match_dup 2)))))
10039 (clobber (reg:CC FLAGS_REG))])
10040 (parallel
10041 [(set (match_dup 5)
10042 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10043 (lshiftrt:DWIH (match_dup 3)
10044 (minus:QI (match_dup 6) (match_dup 2)))))
10045 (clobber (reg:CC FLAGS_REG))])]
10046 {
10047 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10048
10049 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10050 })
10051
10052 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10053 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10054 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10055 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10056 (clobber (reg:CC FLAGS_REG))
10057 (clobber (match_scratch:DWIH 3 "=&r"))]
10058 ""
10059 "#"
10060 "reload_completed"
10061 [(set (match_dup 3) (match_dup 4))
10062 (parallel
10063 [(set (match_dup 4)
10064 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10065 (ashift:DWIH (match_dup 5)
10066 (minus:QI (match_dup 6) (match_dup 2)))))
10067 (clobber (reg:CC FLAGS_REG))])
10068 (parallel
10069 [(set (match_dup 5)
10070 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10071 (ashift:DWIH (match_dup 3)
10072 (minus:QI (match_dup 6) (match_dup 2)))))
10073 (clobber (reg:CC FLAGS_REG))])]
10074 {
10075 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10076
10077 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10078 })
10079
10080 (define_insn "*bmi2_rorx<mode>3_1"
10081 [(set (match_operand:SWI48 0 "register_operand" "=r")
10082 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10083 (match_operand:QI 2 "immediate_operand" "<S>")))]
10084 "TARGET_BMI2"
10085 "rorx\t{%2, %1, %0|%0, %1, %2}"
10086 [(set_attr "type" "rotatex")
10087 (set_attr "mode" "<MODE>")])
10088
10089 (define_insn "*<rotate_insn><mode>3_1"
10090 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10091 (any_rotate:SWI48
10092 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10093 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10096 {
10097 switch (get_attr_type (insn))
10098 {
10099 case TYPE_ROTATEX:
10100 return "#";
10101
10102 default:
10103 if (operands[2] == const1_rtx
10104 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10105 return "<rotate>{<imodesuffix>}\t%0";
10106 else
10107 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10108 }
10109 }
10110 [(set_attr "isa" "*,bmi2")
10111 (set_attr "type" "rotate,rotatex")
10112 (set (attr "length_immediate")
10113 (if_then_else
10114 (and (eq_attr "type" "rotate")
10115 (and (match_operand 2 "const1_operand" "")
10116 (ior (match_test "TARGET_SHIFT1")
10117 (match_test "optimize_function_for_size_p (cfun)"))))
10118 (const_string "0")
10119 (const_string "*")))
10120 (set_attr "mode" "<MODE>")])
10121
10122 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10123 (define_split
10124 [(set (match_operand:SWI48 0 "register_operand" "")
10125 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10126 (match_operand:QI 2 "immediate_operand" "")))
10127 (clobber (reg:CC FLAGS_REG))]
10128 "TARGET_BMI2 && reload_completed"
10129 [(set (match_dup 0)
10130 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10131 {
10132 operands[2]
10133 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10134 })
10135
10136 (define_split
10137 [(set (match_operand:SWI48 0 "register_operand" "")
10138 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10139 (match_operand:QI 2 "immediate_operand" "")))
10140 (clobber (reg:CC FLAGS_REG))]
10141 "TARGET_BMI2 && reload_completed"
10142 [(set (match_dup 0)
10143 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10144
10145 (define_insn "*bmi2_rorxsi3_1_zext"
10146 [(set (match_operand:DI 0 "register_operand" "=r")
10147 (zero_extend:DI
10148 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10149 (match_operand:QI 2 "immediate_operand" "I"))))]
10150 "TARGET_64BIT && TARGET_BMI2"
10151 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10152 [(set_attr "type" "rotatex")
10153 (set_attr "mode" "SI")])
10154
10155 (define_insn "*<rotate_insn>si3_1_zext"
10156 [(set (match_operand:DI 0 "register_operand" "=r,r")
10157 (zero_extend:DI
10158 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10159 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10160 (clobber (reg:CC FLAGS_REG))]
10161 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10162 {
10163 switch (get_attr_type (insn))
10164 {
10165 case TYPE_ROTATEX:
10166 return "#";
10167
10168 default:
10169 if (operands[2] == const1_rtx
10170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10171 return "<rotate>{l}\t%k0";
10172 else
10173 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10174 }
10175 }
10176 [(set_attr "isa" "*,bmi2")
10177 (set_attr "type" "rotate,rotatex")
10178 (set (attr "length_immediate")
10179 (if_then_else
10180 (and (eq_attr "type" "rotate")
10181 (and (match_operand 2 "const1_operand" "")
10182 (ior (match_test "TARGET_SHIFT1")
10183 (match_test "optimize_function_for_size_p (cfun)"))))
10184 (const_string "0")
10185 (const_string "*")))
10186 (set_attr "mode" "SI")])
10187
10188 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10189 (define_split
10190 [(set (match_operand:DI 0 "register_operand" "")
10191 (zero_extend:DI
10192 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10193 (match_operand:QI 2 "immediate_operand" ""))))
10194 (clobber (reg:CC FLAGS_REG))]
10195 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10196 [(set (match_dup 0)
10197 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10198 {
10199 operands[2]
10200 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10201 })
10202
10203 (define_split
10204 [(set (match_operand:DI 0 "register_operand" "")
10205 (zero_extend:DI
10206 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10207 (match_operand:QI 2 "immediate_operand" ""))))
10208 (clobber (reg:CC FLAGS_REG))]
10209 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10210 [(set (match_dup 0)
10211 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10212
10213 (define_insn "*<rotate_insn><mode>3_1"
10214 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10215 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10216 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10219 {
10220 if (operands[2] == const1_rtx
10221 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10222 return "<rotate>{<imodesuffix>}\t%0";
10223 else
10224 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10225 }
10226 [(set_attr "type" "rotate")
10227 (set (attr "length_immediate")
10228 (if_then_else
10229 (and (match_operand 2 "const1_operand" "")
10230 (ior (match_test "TARGET_SHIFT1")
10231 (match_test "optimize_function_for_size_p (cfun)")))
10232 (const_string "0")
10233 (const_string "*")))
10234 (set_attr "mode" "<MODE>")])
10235
10236 (define_insn "*<rotate_insn>qi3_1_slp"
10237 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10238 (any_rotate:QI (match_dup 0)
10239 (match_operand:QI 1 "nonmemory_operand" "cI")))
10240 (clobber (reg:CC FLAGS_REG))]
10241 "(optimize_function_for_size_p (cfun)
10242 || !TARGET_PARTIAL_REG_STALL
10243 || (operands[1] == const1_rtx
10244 && TARGET_SHIFT1))"
10245 {
10246 if (operands[1] == const1_rtx
10247 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10248 return "<rotate>{b}\t%0";
10249 else
10250 return "<rotate>{b}\t{%1, %0|%0, %1}";
10251 }
10252 [(set_attr "type" "rotate1")
10253 (set (attr "length_immediate")
10254 (if_then_else
10255 (and (match_operand 1 "const1_operand" "")
10256 (ior (match_test "TARGET_SHIFT1")
10257 (match_test "optimize_function_for_size_p (cfun)")))
10258 (const_string "0")
10259 (const_string "*")))
10260 (set_attr "mode" "QI")])
10261
10262 (define_split
10263 [(set (match_operand:HI 0 "register_operand" "")
10264 (any_rotate:HI (match_dup 0) (const_int 8)))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "reload_completed
10267 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10268 [(parallel [(set (strict_low_part (match_dup 0))
10269 (bswap:HI (match_dup 0)))
10270 (clobber (reg:CC FLAGS_REG))])])
10271 \f
10272 ;; Bit set / bit test instructions
10273
10274 (define_expand "extv"
10275 [(set (match_operand:SI 0 "register_operand" "")
10276 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10277 (match_operand:SI 2 "const8_operand" "")
10278 (match_operand:SI 3 "const8_operand" "")))]
10279 ""
10280 {
10281 /* Handle extractions from %ah et al. */
10282 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10283 FAIL;
10284
10285 /* From mips.md: extract_bit_field doesn't verify that our source
10286 matches the predicate, so check it again here. */
10287 if (! ext_register_operand (operands[1], VOIDmode))
10288 FAIL;
10289 })
10290
10291 (define_expand "extzv"
10292 [(set (match_operand:SI 0 "register_operand" "")
10293 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10294 (match_operand:SI 2 "const8_operand" "")
10295 (match_operand:SI 3 "const8_operand" "")))]
10296 ""
10297 {
10298 /* Handle extractions from %ah et al. */
10299 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10300 FAIL;
10301
10302 /* From mips.md: extract_bit_field doesn't verify that our source
10303 matches the predicate, so check it again here. */
10304 if (! ext_register_operand (operands[1], VOIDmode))
10305 FAIL;
10306 })
10307
10308 (define_expand "insv"
10309 [(set (zero_extract (match_operand 0 "register_operand" "")
10310 (match_operand 1 "const_int_operand" "")
10311 (match_operand 2 "const_int_operand" ""))
10312 (match_operand 3 "register_operand" ""))]
10313 ""
10314 {
10315 rtx (*gen_mov_insv_1) (rtx, rtx);
10316
10317 if (ix86_expand_pinsr (operands))
10318 DONE;
10319
10320 /* Handle insertions to %ah et al. */
10321 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10322 FAIL;
10323
10324 /* From mips.md: insert_bit_field doesn't verify that our source
10325 matches the predicate, so check it again here. */
10326 if (! ext_register_operand (operands[0], VOIDmode))
10327 FAIL;
10328
10329 gen_mov_insv_1 = (TARGET_64BIT
10330 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10331
10332 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10333 DONE;
10334 })
10335
10336 ;; %%% bts, btr, btc, bt.
10337 ;; In general these instructions are *slow* when applied to memory,
10338 ;; since they enforce atomic operation. When applied to registers,
10339 ;; it depends on the cpu implementation. They're never faster than
10340 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10341 ;; no point. But in 64-bit, we can't hold the relevant immediates
10342 ;; within the instruction itself, so operating on bits in the high
10343 ;; 32-bits of a register becomes easier.
10344 ;;
10345 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10346 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10347 ;; negdf respectively, so they can never be disabled entirely.
10348
10349 (define_insn "*btsq"
10350 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10351 (const_int 1)
10352 (match_operand:DI 1 "const_0_to_63_operand" ""))
10353 (const_int 1))
10354 (clobber (reg:CC FLAGS_REG))]
10355 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10356 "bts{q}\t{%1, %0|%0, %1}"
10357 [(set_attr "type" "alu1")
10358 (set_attr "prefix_0f" "1")
10359 (set_attr "mode" "DI")])
10360
10361 (define_insn "*btrq"
10362 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10363 (const_int 1)
10364 (match_operand:DI 1 "const_0_to_63_operand" ""))
10365 (const_int 0))
10366 (clobber (reg:CC FLAGS_REG))]
10367 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10368 "btr{q}\t{%1, %0|%0, %1}"
10369 [(set_attr "type" "alu1")
10370 (set_attr "prefix_0f" "1")
10371 (set_attr "mode" "DI")])
10372
10373 (define_insn "*btcq"
10374 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10375 (const_int 1)
10376 (match_operand:DI 1 "const_0_to_63_operand" ""))
10377 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10378 (clobber (reg:CC FLAGS_REG))]
10379 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10380 "btc{q}\t{%1, %0|%0, %1}"
10381 [(set_attr "type" "alu1")
10382 (set_attr "prefix_0f" "1")
10383 (set_attr "mode" "DI")])
10384
10385 ;; Allow Nocona to avoid these instructions if a register is available.
10386
10387 (define_peephole2
10388 [(match_scratch:DI 2 "r")
10389 (parallel [(set (zero_extract:DI
10390 (match_operand:DI 0 "register_operand" "")
10391 (const_int 1)
10392 (match_operand:DI 1 "const_0_to_63_operand" ""))
10393 (const_int 1))
10394 (clobber (reg:CC FLAGS_REG))])]
10395 "TARGET_64BIT && !TARGET_USE_BT"
10396 [(const_int 0)]
10397 {
10398 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10399 rtx op1;
10400
10401 if (HOST_BITS_PER_WIDE_INT >= 64)
10402 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10403 else if (i < HOST_BITS_PER_WIDE_INT)
10404 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10405 else
10406 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10407
10408 op1 = immed_double_const (lo, hi, DImode);
10409 if (i >= 31)
10410 {
10411 emit_move_insn (operands[2], op1);
10412 op1 = operands[2];
10413 }
10414
10415 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10416 DONE;
10417 })
10418
10419 (define_peephole2
10420 [(match_scratch:DI 2 "r")
10421 (parallel [(set (zero_extract:DI
10422 (match_operand:DI 0 "register_operand" "")
10423 (const_int 1)
10424 (match_operand:DI 1 "const_0_to_63_operand" ""))
10425 (const_int 0))
10426 (clobber (reg:CC FLAGS_REG))])]
10427 "TARGET_64BIT && !TARGET_USE_BT"
10428 [(const_int 0)]
10429 {
10430 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10431 rtx op1;
10432
10433 if (HOST_BITS_PER_WIDE_INT >= 64)
10434 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10435 else if (i < HOST_BITS_PER_WIDE_INT)
10436 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10437 else
10438 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10439
10440 op1 = immed_double_const (~lo, ~hi, DImode);
10441 if (i >= 32)
10442 {
10443 emit_move_insn (operands[2], op1);
10444 op1 = operands[2];
10445 }
10446
10447 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10448 DONE;
10449 })
10450
10451 (define_peephole2
10452 [(match_scratch:DI 2 "r")
10453 (parallel [(set (zero_extract:DI
10454 (match_operand:DI 0 "register_operand" "")
10455 (const_int 1)
10456 (match_operand:DI 1 "const_0_to_63_operand" ""))
10457 (not:DI (zero_extract:DI
10458 (match_dup 0) (const_int 1) (match_dup 1))))
10459 (clobber (reg:CC FLAGS_REG))])]
10460 "TARGET_64BIT && !TARGET_USE_BT"
10461 [(const_int 0)]
10462 {
10463 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10464 rtx op1;
10465
10466 if (HOST_BITS_PER_WIDE_INT >= 64)
10467 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10468 else if (i < HOST_BITS_PER_WIDE_INT)
10469 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10470 else
10471 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10472
10473 op1 = immed_double_const (lo, hi, DImode);
10474 if (i >= 31)
10475 {
10476 emit_move_insn (operands[2], op1);
10477 op1 = operands[2];
10478 }
10479
10480 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10481 DONE;
10482 })
10483
10484 (define_insn "*bt<mode>"
10485 [(set (reg:CCC FLAGS_REG)
10486 (compare:CCC
10487 (zero_extract:SWI48
10488 (match_operand:SWI48 0 "register_operand" "r")
10489 (const_int 1)
10490 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10491 (const_int 0)))]
10492 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10493 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10494 [(set_attr "type" "alu1")
10495 (set_attr "prefix_0f" "1")
10496 (set_attr "mode" "<MODE>")])
10497 \f
10498 ;; Store-flag instructions.
10499
10500 ;; For all sCOND expanders, also expand the compare or test insn that
10501 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10502
10503 (define_insn_and_split "*setcc_di_1"
10504 [(set (match_operand:DI 0 "register_operand" "=q")
10505 (match_operator:DI 1 "ix86_comparison_operator"
10506 [(reg FLAGS_REG) (const_int 0)]))]
10507 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10508 "#"
10509 "&& reload_completed"
10510 [(set (match_dup 2) (match_dup 1))
10511 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10512 {
10513 PUT_MODE (operands[1], QImode);
10514 operands[2] = gen_lowpart (QImode, operands[0]);
10515 })
10516
10517 (define_insn_and_split "*setcc_si_1_and"
10518 [(set (match_operand:SI 0 "register_operand" "=q")
10519 (match_operator:SI 1 "ix86_comparison_operator"
10520 [(reg FLAGS_REG) (const_int 0)]))
10521 (clobber (reg:CC FLAGS_REG))]
10522 "!TARGET_PARTIAL_REG_STALL
10523 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10524 "#"
10525 "&& reload_completed"
10526 [(set (match_dup 2) (match_dup 1))
10527 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10528 (clobber (reg:CC FLAGS_REG))])]
10529 {
10530 PUT_MODE (operands[1], QImode);
10531 operands[2] = gen_lowpart (QImode, operands[0]);
10532 })
10533
10534 (define_insn_and_split "*setcc_si_1_movzbl"
10535 [(set (match_operand:SI 0 "register_operand" "=q")
10536 (match_operator:SI 1 "ix86_comparison_operator"
10537 [(reg FLAGS_REG) (const_int 0)]))]
10538 "!TARGET_PARTIAL_REG_STALL
10539 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10540 "#"
10541 "&& reload_completed"
10542 [(set (match_dup 2) (match_dup 1))
10543 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10544 {
10545 PUT_MODE (operands[1], QImode);
10546 operands[2] = gen_lowpart (QImode, operands[0]);
10547 })
10548
10549 (define_insn "*setcc_qi"
10550 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10551 (match_operator:QI 1 "ix86_comparison_operator"
10552 [(reg FLAGS_REG) (const_int 0)]))]
10553 ""
10554 "set%C1\t%0"
10555 [(set_attr "type" "setcc")
10556 (set_attr "mode" "QI")])
10557
10558 (define_insn "*setcc_qi_slp"
10559 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10560 (match_operator:QI 1 "ix86_comparison_operator"
10561 [(reg FLAGS_REG) (const_int 0)]))]
10562 ""
10563 "set%C1\t%0"
10564 [(set_attr "type" "setcc")
10565 (set_attr "mode" "QI")])
10566
10567 ;; In general it is not safe to assume too much about CCmode registers,
10568 ;; so simplify-rtx stops when it sees a second one. Under certain
10569 ;; conditions this is safe on x86, so help combine not create
10570 ;;
10571 ;; seta %al
10572 ;; testb %al, %al
10573 ;; sete %al
10574
10575 (define_split
10576 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10577 (ne:QI (match_operator 1 "ix86_comparison_operator"
10578 [(reg FLAGS_REG) (const_int 0)])
10579 (const_int 0)))]
10580 ""
10581 [(set (match_dup 0) (match_dup 1))]
10582 "PUT_MODE (operands[1], QImode);")
10583
10584 (define_split
10585 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10586 (ne:QI (match_operator 1 "ix86_comparison_operator"
10587 [(reg FLAGS_REG) (const_int 0)])
10588 (const_int 0)))]
10589 ""
10590 [(set (match_dup 0) (match_dup 1))]
10591 "PUT_MODE (operands[1], QImode);")
10592
10593 (define_split
10594 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10595 (eq:QI (match_operator 1 "ix86_comparison_operator"
10596 [(reg FLAGS_REG) (const_int 0)])
10597 (const_int 0)))]
10598 ""
10599 [(set (match_dup 0) (match_dup 1))]
10600 {
10601 rtx new_op1 = copy_rtx (operands[1]);
10602 operands[1] = new_op1;
10603 PUT_MODE (new_op1, QImode);
10604 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10605 GET_MODE (XEXP (new_op1, 0))));
10606
10607 /* Make sure that (a) the CCmode we have for the flags is strong
10608 enough for the reversed compare or (b) we have a valid FP compare. */
10609 if (! ix86_comparison_operator (new_op1, VOIDmode))
10610 FAIL;
10611 })
10612
10613 (define_split
10614 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10615 (eq:QI (match_operator 1 "ix86_comparison_operator"
10616 [(reg FLAGS_REG) (const_int 0)])
10617 (const_int 0)))]
10618 ""
10619 [(set (match_dup 0) (match_dup 1))]
10620 {
10621 rtx new_op1 = copy_rtx (operands[1]);
10622 operands[1] = new_op1;
10623 PUT_MODE (new_op1, QImode);
10624 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10625 GET_MODE (XEXP (new_op1, 0))));
10626
10627 /* Make sure that (a) the CCmode we have for the flags is strong
10628 enough for the reversed compare or (b) we have a valid FP compare. */
10629 if (! ix86_comparison_operator (new_op1, VOIDmode))
10630 FAIL;
10631 })
10632
10633 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10634 ;; subsequent logical operations are used to imitate conditional moves.
10635 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10636 ;; it directly.
10637
10638 (define_insn "setcc_<mode>_sse"
10639 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10640 (match_operator:MODEF 3 "sse_comparison_operator"
10641 [(match_operand:MODEF 1 "register_operand" "0,x")
10642 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10643 "SSE_FLOAT_MODE_P (<MODE>mode)"
10644 "@
10645 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10646 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10647 [(set_attr "isa" "noavx,avx")
10648 (set_attr "type" "ssecmp")
10649 (set_attr "length_immediate" "1")
10650 (set_attr "prefix" "orig,vex")
10651 (set_attr "mode" "<MODE>")])
10652 \f
10653 ;; Basic conditional jump instructions.
10654 ;; We ignore the overflow flag for signed branch instructions.
10655
10656 (define_insn "*jcc_1"
10657 [(set (pc)
10658 (if_then_else (match_operator 1 "ix86_comparison_operator"
10659 [(reg FLAGS_REG) (const_int 0)])
10660 (label_ref (match_operand 0 "" ""))
10661 (pc)))]
10662 ""
10663 "%+j%C1\t%l0"
10664 [(set_attr "type" "ibr")
10665 (set_attr "modrm" "0")
10666 (set (attr "length")
10667 (if_then_else (and (ge (minus (match_dup 0) (pc))
10668 (const_int -126))
10669 (lt (minus (match_dup 0) (pc))
10670 (const_int 128)))
10671 (const_int 2)
10672 (const_int 6)))])
10673
10674 (define_insn "*jcc_2"
10675 [(set (pc)
10676 (if_then_else (match_operator 1 "ix86_comparison_operator"
10677 [(reg FLAGS_REG) (const_int 0)])
10678 (pc)
10679 (label_ref (match_operand 0 "" ""))))]
10680 ""
10681 "%+j%c1\t%l0"
10682 [(set_attr "type" "ibr")
10683 (set_attr "modrm" "0")
10684 (set (attr "length")
10685 (if_then_else (and (ge (minus (match_dup 0) (pc))
10686 (const_int -126))
10687 (lt (minus (match_dup 0) (pc))
10688 (const_int 128)))
10689 (const_int 2)
10690 (const_int 6)))])
10691
10692 ;; In general it is not safe to assume too much about CCmode registers,
10693 ;; so simplify-rtx stops when it sees a second one. Under certain
10694 ;; conditions this is safe on x86, so help combine not create
10695 ;;
10696 ;; seta %al
10697 ;; testb %al, %al
10698 ;; je Lfoo
10699
10700 (define_split
10701 [(set (pc)
10702 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10703 [(reg FLAGS_REG) (const_int 0)])
10704 (const_int 0))
10705 (label_ref (match_operand 1 "" ""))
10706 (pc)))]
10707 ""
10708 [(set (pc)
10709 (if_then_else (match_dup 0)
10710 (label_ref (match_dup 1))
10711 (pc)))]
10712 "PUT_MODE (operands[0], VOIDmode);")
10713
10714 (define_split
10715 [(set (pc)
10716 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10717 [(reg FLAGS_REG) (const_int 0)])
10718 (const_int 0))
10719 (label_ref (match_operand 1 "" ""))
10720 (pc)))]
10721 ""
10722 [(set (pc)
10723 (if_then_else (match_dup 0)
10724 (label_ref (match_dup 1))
10725 (pc)))]
10726 {
10727 rtx new_op0 = copy_rtx (operands[0]);
10728 operands[0] = new_op0;
10729 PUT_MODE (new_op0, VOIDmode);
10730 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10731 GET_MODE (XEXP (new_op0, 0))));
10732
10733 /* Make sure that (a) the CCmode we have for the flags is strong
10734 enough for the reversed compare or (b) we have a valid FP compare. */
10735 if (! ix86_comparison_operator (new_op0, VOIDmode))
10736 FAIL;
10737 })
10738
10739 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10740 ;; pass generates from shift insn with QImode operand. Actually, the mode
10741 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10742 ;; appropriate modulo of the bit offset value.
10743
10744 (define_insn_and_split "*jcc_bt<mode>"
10745 [(set (pc)
10746 (if_then_else (match_operator 0 "bt_comparison_operator"
10747 [(zero_extract:SWI48
10748 (match_operand:SWI48 1 "register_operand" "r")
10749 (const_int 1)
10750 (zero_extend:SI
10751 (match_operand:QI 2 "register_operand" "r")))
10752 (const_int 0)])
10753 (label_ref (match_operand 3 "" ""))
10754 (pc)))
10755 (clobber (reg:CC FLAGS_REG))]
10756 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10757 "#"
10758 "&& 1"
10759 [(set (reg:CCC FLAGS_REG)
10760 (compare:CCC
10761 (zero_extract:SWI48
10762 (match_dup 1)
10763 (const_int 1)
10764 (match_dup 2))
10765 (const_int 0)))
10766 (set (pc)
10767 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10768 (label_ref (match_dup 3))
10769 (pc)))]
10770 {
10771 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10772
10773 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10774 })
10775
10776 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10777 ;; also for DImode, this is what combine produces.
10778 (define_insn_and_split "*jcc_bt<mode>_mask"
10779 [(set (pc)
10780 (if_then_else (match_operator 0 "bt_comparison_operator"
10781 [(zero_extract:SWI48
10782 (match_operand:SWI48 1 "register_operand" "r")
10783 (const_int 1)
10784 (and:SI
10785 (match_operand:SI 2 "register_operand" "r")
10786 (match_operand:SI 3 "const_int_operand" "n")))])
10787 (label_ref (match_operand 4 "" ""))
10788 (pc)))
10789 (clobber (reg:CC FLAGS_REG))]
10790 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10791 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10792 == GET_MODE_BITSIZE (<MODE>mode)-1"
10793 "#"
10794 "&& 1"
10795 [(set (reg:CCC FLAGS_REG)
10796 (compare:CCC
10797 (zero_extract:SWI48
10798 (match_dup 1)
10799 (const_int 1)
10800 (match_dup 2))
10801 (const_int 0)))
10802 (set (pc)
10803 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10804 (label_ref (match_dup 4))
10805 (pc)))]
10806 {
10807 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10808
10809 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10810 })
10811
10812 (define_insn_and_split "*jcc_btsi_1"
10813 [(set (pc)
10814 (if_then_else (match_operator 0 "bt_comparison_operator"
10815 [(and:SI
10816 (lshiftrt:SI
10817 (match_operand:SI 1 "register_operand" "r")
10818 (match_operand:QI 2 "register_operand" "r"))
10819 (const_int 1))
10820 (const_int 0)])
10821 (label_ref (match_operand 3 "" ""))
10822 (pc)))
10823 (clobber (reg:CC FLAGS_REG))]
10824 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10825 "#"
10826 "&& 1"
10827 [(set (reg:CCC FLAGS_REG)
10828 (compare:CCC
10829 (zero_extract:SI
10830 (match_dup 1)
10831 (const_int 1)
10832 (match_dup 2))
10833 (const_int 0)))
10834 (set (pc)
10835 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10836 (label_ref (match_dup 3))
10837 (pc)))]
10838 {
10839 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10840
10841 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10842 })
10843
10844 ;; avoid useless masking of bit offset operand
10845 (define_insn_and_split "*jcc_btsi_mask_1"
10846 [(set (pc)
10847 (if_then_else
10848 (match_operator 0 "bt_comparison_operator"
10849 [(and:SI
10850 (lshiftrt:SI
10851 (match_operand:SI 1 "register_operand" "r")
10852 (subreg:QI
10853 (and:SI
10854 (match_operand:SI 2 "register_operand" "r")
10855 (match_operand:SI 3 "const_int_operand" "n")) 0))
10856 (const_int 1))
10857 (const_int 0)])
10858 (label_ref (match_operand 4 "" ""))
10859 (pc)))
10860 (clobber (reg:CC FLAGS_REG))]
10861 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10862 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10863 "#"
10864 "&& 1"
10865 [(set (reg:CCC FLAGS_REG)
10866 (compare:CCC
10867 (zero_extract:SI
10868 (match_dup 1)
10869 (const_int 1)
10870 (match_dup 2))
10871 (const_int 0)))
10872 (set (pc)
10873 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10874 (label_ref (match_dup 4))
10875 (pc)))]
10876 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10877
10878 ;; Define combination compare-and-branch fp compare instructions to help
10879 ;; combine.
10880
10881 (define_insn "*fp_jcc_1_387"
10882 [(set (pc)
10883 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10884 [(match_operand 1 "register_operand" "f")
10885 (match_operand 2 "nonimmediate_operand" "fm")])
10886 (label_ref (match_operand 3 "" ""))
10887 (pc)))
10888 (clobber (reg:CCFP FPSR_REG))
10889 (clobber (reg:CCFP FLAGS_REG))
10890 (clobber (match_scratch:HI 4 "=a"))]
10891 "TARGET_80387
10892 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10893 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10894 && SELECT_CC_MODE (GET_CODE (operands[0]),
10895 operands[1], operands[2]) == CCFPmode
10896 && !TARGET_CMOVE"
10897 "#")
10898
10899 (define_insn "*fp_jcc_1r_387"
10900 [(set (pc)
10901 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10902 [(match_operand 1 "register_operand" "f")
10903 (match_operand 2 "nonimmediate_operand" "fm")])
10904 (pc)
10905 (label_ref (match_operand 3 "" ""))))
10906 (clobber (reg:CCFP FPSR_REG))
10907 (clobber (reg:CCFP FLAGS_REG))
10908 (clobber (match_scratch:HI 4 "=a"))]
10909 "TARGET_80387
10910 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10911 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10912 && SELECT_CC_MODE (GET_CODE (operands[0]),
10913 operands[1], operands[2]) == CCFPmode
10914 && !TARGET_CMOVE"
10915 "#")
10916
10917 (define_insn "*fp_jcc_2_387"
10918 [(set (pc)
10919 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10920 [(match_operand 1 "register_operand" "f")
10921 (match_operand 2 "register_operand" "f")])
10922 (label_ref (match_operand 3 "" ""))
10923 (pc)))
10924 (clobber (reg:CCFP FPSR_REG))
10925 (clobber (reg:CCFP FLAGS_REG))
10926 (clobber (match_scratch:HI 4 "=a"))]
10927 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10928 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10929 && !TARGET_CMOVE"
10930 "#")
10931
10932 (define_insn "*fp_jcc_2r_387"
10933 [(set (pc)
10934 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10935 [(match_operand 1 "register_operand" "f")
10936 (match_operand 2 "register_operand" "f")])
10937 (pc)
10938 (label_ref (match_operand 3 "" ""))))
10939 (clobber (reg:CCFP FPSR_REG))
10940 (clobber (reg:CCFP FLAGS_REG))
10941 (clobber (match_scratch:HI 4 "=a"))]
10942 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10943 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10944 && !TARGET_CMOVE"
10945 "#")
10946
10947 (define_insn "*fp_jcc_3_387"
10948 [(set (pc)
10949 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10950 [(match_operand 1 "register_operand" "f")
10951 (match_operand 2 "const0_operand" "")])
10952 (label_ref (match_operand 3 "" ""))
10953 (pc)))
10954 (clobber (reg:CCFP FPSR_REG))
10955 (clobber (reg:CCFP FLAGS_REG))
10956 (clobber (match_scratch:HI 4 "=a"))]
10957 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10958 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10959 && SELECT_CC_MODE (GET_CODE (operands[0]),
10960 operands[1], operands[2]) == CCFPmode
10961 && !TARGET_CMOVE"
10962 "#")
10963
10964 (define_split
10965 [(set (pc)
10966 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10967 [(match_operand 1 "register_operand" "")
10968 (match_operand 2 "nonimmediate_operand" "")])
10969 (match_operand 3 "" "")
10970 (match_operand 4 "" "")))
10971 (clobber (reg:CCFP FPSR_REG))
10972 (clobber (reg:CCFP FLAGS_REG))]
10973 "reload_completed"
10974 [(const_int 0)]
10975 {
10976 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10977 operands[3], operands[4], NULL_RTX, NULL_RTX);
10978 DONE;
10979 })
10980
10981 (define_split
10982 [(set (pc)
10983 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10984 [(match_operand 1 "register_operand" "")
10985 (match_operand 2 "general_operand" "")])
10986 (match_operand 3 "" "")
10987 (match_operand 4 "" "")))
10988 (clobber (reg:CCFP FPSR_REG))
10989 (clobber (reg:CCFP FLAGS_REG))
10990 (clobber (match_scratch:HI 5 "=a"))]
10991 "reload_completed"
10992 [(const_int 0)]
10993 {
10994 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10995 operands[3], operands[4], operands[5], NULL_RTX);
10996 DONE;
10997 })
10998
10999 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11000 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11001 ;; with a precedence over other operators and is always put in the first
11002 ;; place. Swap condition and operands to match ficom instruction.
11003
11004 (define_insn "*fp_jcc_4_<mode>_387"
11005 [(set (pc)
11006 (if_then_else
11007 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11008 [(match_operator 1 "float_operator"
11009 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11010 (match_operand 3 "register_operand" "f,f")])
11011 (label_ref (match_operand 4 "" ""))
11012 (pc)))
11013 (clobber (reg:CCFP FPSR_REG))
11014 (clobber (reg:CCFP FLAGS_REG))
11015 (clobber (match_scratch:HI 5 "=a,a"))]
11016 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11017 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11018 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11019 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11020 && !TARGET_CMOVE"
11021 "#")
11022
11023 (define_split
11024 [(set (pc)
11025 (if_then_else
11026 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11027 [(match_operator 1 "float_operator"
11028 [(match_operand:SWI24 2 "memory_operand" "")])
11029 (match_operand 3 "register_operand" "")])
11030 (match_operand 4 "" "")
11031 (match_operand 5 "" "")))
11032 (clobber (reg:CCFP FPSR_REG))
11033 (clobber (reg:CCFP FLAGS_REG))
11034 (clobber (match_scratch:HI 6 "=a"))]
11035 "reload_completed"
11036 [(const_int 0)]
11037 {
11038 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11039
11040 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11041 operands[3], operands[7],
11042 operands[4], operands[5], operands[6], NULL_RTX);
11043 DONE;
11044 })
11045
11046 ;; %%% Kill this when reload knows how to do it.
11047 (define_split
11048 [(set (pc)
11049 (if_then_else
11050 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11051 [(match_operator 1 "float_operator"
11052 [(match_operand:SWI24 2 "register_operand" "")])
11053 (match_operand 3 "register_operand" "")])
11054 (match_operand 4 "" "")
11055 (match_operand 5 "" "")))
11056 (clobber (reg:CCFP FPSR_REG))
11057 (clobber (reg:CCFP FLAGS_REG))
11058 (clobber (match_scratch:HI 6 "=a"))]
11059 "reload_completed"
11060 [(const_int 0)]
11061 {
11062 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11063 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11064
11065 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11066 operands[3], operands[7],
11067 operands[4], operands[5], operands[6], operands[2]);
11068 DONE;
11069 })
11070 \f
11071 ;; Unconditional and other jump instructions
11072
11073 (define_insn "jump"
11074 [(set (pc)
11075 (label_ref (match_operand 0 "" "")))]
11076 ""
11077 "jmp\t%l0"
11078 [(set_attr "type" "ibr")
11079 (set (attr "length")
11080 (if_then_else (and (ge (minus (match_dup 0) (pc))
11081 (const_int -126))
11082 (lt (minus (match_dup 0) (pc))
11083 (const_int 128)))
11084 (const_int 2)
11085 (const_int 5)))
11086 (set_attr "modrm" "0")])
11087
11088 (define_expand "indirect_jump"
11089 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))]
11090 ""
11091 {
11092 if (TARGET_X32)
11093 operands[0] = convert_memory_address (word_mode, operands[0]);
11094 })
11095
11096 (define_insn "*indirect_jump"
11097 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11098 ""
11099 "jmp\t%A0"
11100 [(set_attr "type" "ibr")
11101 (set_attr "length_immediate" "0")])
11102
11103 (define_expand "tablejump"
11104 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11105 (use (label_ref (match_operand 1 "" "")))])]
11106 ""
11107 {
11108 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11109 relative. Convert the relative address to an absolute address. */
11110 if (flag_pic)
11111 {
11112 rtx op0, op1;
11113 enum rtx_code code;
11114
11115 /* We can't use @GOTOFF for text labels on VxWorks;
11116 see gotoff_operand. */
11117 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11118 {
11119 code = PLUS;
11120 op0 = operands[0];
11121 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11122 }
11123 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11124 {
11125 code = PLUS;
11126 op0 = operands[0];
11127 op1 = pic_offset_table_rtx;
11128 }
11129 else
11130 {
11131 code = MINUS;
11132 op0 = pic_offset_table_rtx;
11133 op1 = operands[0];
11134 }
11135
11136 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11137 OPTAB_DIRECT);
11138 }
11139
11140 if (TARGET_X32)
11141 operands[0] = convert_memory_address (word_mode, operands[0]);
11142 })
11143
11144 (define_insn "*tablejump_1"
11145 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11146 (use (label_ref (match_operand 1 "" "")))]
11147 ""
11148 "jmp\t%A0"
11149 [(set_attr "type" "ibr")
11150 (set_attr "length_immediate" "0")])
11151 \f
11152 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11153
11154 (define_peephole2
11155 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11156 (set (match_operand:QI 1 "register_operand" "")
11157 (match_operator:QI 2 "ix86_comparison_operator"
11158 [(reg FLAGS_REG) (const_int 0)]))
11159 (set (match_operand 3 "q_regs_operand" "")
11160 (zero_extend (match_dup 1)))]
11161 "(peep2_reg_dead_p (3, operands[1])
11162 || operands_match_p (operands[1], operands[3]))
11163 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11164 [(set (match_dup 4) (match_dup 0))
11165 (set (strict_low_part (match_dup 5))
11166 (match_dup 2))]
11167 {
11168 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11169 operands[5] = gen_lowpart (QImode, operands[3]);
11170 ix86_expand_clear (operands[3]);
11171 })
11172
11173 ;; Similar, but match zero extend with andsi3.
11174
11175 (define_peephole2
11176 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11177 (set (match_operand:QI 1 "register_operand" "")
11178 (match_operator:QI 2 "ix86_comparison_operator"
11179 [(reg FLAGS_REG) (const_int 0)]))
11180 (parallel [(set (match_operand:SI 3 "q_regs_operand" "")
11181 (and:SI (match_dup 3) (const_int 255)))
11182 (clobber (reg:CC FLAGS_REG))])]
11183 "REGNO (operands[1]) == REGNO (operands[3])
11184 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11185 [(set (match_dup 4) (match_dup 0))
11186 (set (strict_low_part (match_dup 5))
11187 (match_dup 2))]
11188 {
11189 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11190 operands[5] = gen_lowpart (QImode, operands[3]);
11191 ix86_expand_clear (operands[3]);
11192 })
11193 \f
11194 ;; Call instructions.
11195
11196 ;; The predicates normally associated with named expanders are not properly
11197 ;; checked for calls. This is a bug in the generic code, but it isn't that
11198 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11199
11200 ;; P6 processors will jump to the address after the decrement when %esp
11201 ;; is used as a call operand, so they will execute return address as a code.
11202 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11203
11204 ;; Register constraint for call instruction.
11205 (define_mode_attr c [(SI "l") (DI "r")])
11206
11207 ;; Call subroutine returning no value.
11208
11209 (define_expand "call"
11210 [(call (match_operand:QI 0 "" "")
11211 (match_operand 1 "" ""))
11212 (use (match_operand 2 "" ""))]
11213 ""
11214 {
11215 ix86_expand_call (NULL, operands[0], operands[1],
11216 operands[2], NULL, false);
11217 DONE;
11218 })
11219
11220 (define_expand "sibcall"
11221 [(call (match_operand:QI 0 "" "")
11222 (match_operand 1 "" ""))
11223 (use (match_operand 2 "" ""))]
11224 ""
11225 {
11226 ix86_expand_call (NULL, operands[0], operands[1],
11227 operands[2], NULL, true);
11228 DONE;
11229 })
11230
11231 (define_insn_and_split "*call_vzeroupper"
11232 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11233 (match_operand 1 "" ""))
11234 (unspec [(match_operand 2 "const_int_operand" "")]
11235 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11236 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11237 "#"
11238 "&& reload_completed"
11239 [(const_int 0)]
11240 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11241 [(set_attr "type" "call")])
11242
11243 (define_insn "*call"
11244 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11245 (match_operand 1 "" ""))]
11246 "!SIBLING_CALL_P (insn)"
11247 "* return ix86_output_call_insn (insn, operands[0]);"
11248 [(set_attr "type" "call")])
11249
11250 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11251 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11252 (match_operand 1 "" ""))
11253 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11254 (clobber (reg:TI XMM6_REG))
11255 (clobber (reg:TI XMM7_REG))
11256 (clobber (reg:TI XMM8_REG))
11257 (clobber (reg:TI XMM9_REG))
11258 (clobber (reg:TI XMM10_REG))
11259 (clobber (reg:TI XMM11_REG))
11260 (clobber (reg:TI XMM12_REG))
11261 (clobber (reg:TI XMM13_REG))
11262 (clobber (reg:TI XMM14_REG))
11263 (clobber (reg:TI XMM15_REG))
11264 (clobber (reg:DI SI_REG))
11265 (clobber (reg:DI DI_REG))
11266 (unspec [(match_operand 2 "const_int_operand" "")]
11267 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11268 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11269 "#"
11270 "&& reload_completed"
11271 [(const_int 0)]
11272 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11273 [(set_attr "type" "call")])
11274
11275 (define_insn "*call_rex64_ms_sysv"
11276 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11277 (match_operand 1 "" ""))
11278 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11279 (clobber (reg:TI XMM6_REG))
11280 (clobber (reg:TI XMM7_REG))
11281 (clobber (reg:TI XMM8_REG))
11282 (clobber (reg:TI XMM9_REG))
11283 (clobber (reg:TI XMM10_REG))
11284 (clobber (reg:TI XMM11_REG))
11285 (clobber (reg:TI XMM12_REG))
11286 (clobber (reg:TI XMM13_REG))
11287 (clobber (reg:TI XMM14_REG))
11288 (clobber (reg:TI XMM15_REG))
11289 (clobber (reg:DI SI_REG))
11290 (clobber (reg:DI DI_REG))]
11291 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11292 "* return ix86_output_call_insn (insn, operands[0]);"
11293 [(set_attr "type" "call")])
11294
11295 (define_insn_and_split "*sibcall_vzeroupper"
11296 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11297 (match_operand 1 "" ""))
11298 (unspec [(match_operand 2 "const_int_operand" "")]
11299 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11300 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11301 "#"
11302 "&& reload_completed"
11303 [(const_int 0)]
11304 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11305 [(set_attr "type" "call")])
11306
11307 (define_insn "*sibcall"
11308 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11309 (match_operand 1 "" ""))]
11310 "SIBLING_CALL_P (insn)"
11311 "* return ix86_output_call_insn (insn, operands[0]);"
11312 [(set_attr "type" "call")])
11313
11314 (define_expand "call_pop"
11315 [(parallel [(call (match_operand:QI 0 "" "")
11316 (match_operand:SI 1 "" ""))
11317 (set (reg:SI SP_REG)
11318 (plus:SI (reg:SI SP_REG)
11319 (match_operand:SI 3 "" "")))])]
11320 "!TARGET_64BIT"
11321 {
11322 ix86_expand_call (NULL, operands[0], operands[1],
11323 operands[2], operands[3], false);
11324 DONE;
11325 })
11326
11327 (define_insn_and_split "*call_pop_vzeroupper"
11328 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11329 (match_operand:SI 1 "" ""))
11330 (set (reg:SI SP_REG)
11331 (plus:SI (reg:SI SP_REG)
11332 (match_operand:SI 2 "immediate_operand" "i")))
11333 (unspec [(match_operand 3 "const_int_operand" "")]
11334 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11335 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11336 "#"
11337 "&& reload_completed"
11338 [(const_int 0)]
11339 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11340 [(set_attr "type" "call")])
11341
11342 (define_insn "*call_pop"
11343 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11344 (match_operand 1 "" ""))
11345 (set (reg:SI SP_REG)
11346 (plus:SI (reg:SI SP_REG)
11347 (match_operand:SI 2 "immediate_operand" "i")))]
11348 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11349 "* return ix86_output_call_insn (insn, operands[0]);"
11350 [(set_attr "type" "call")])
11351
11352 (define_insn_and_split "*sibcall_pop_vzeroupper"
11353 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11354 (match_operand 1 "" ""))
11355 (set (reg:SI SP_REG)
11356 (plus:SI (reg:SI SP_REG)
11357 (match_operand:SI 2 "immediate_operand" "i")))
11358 (unspec [(match_operand 3 "const_int_operand" "")]
11359 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11360 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11361 "#"
11362 "&& reload_completed"
11363 [(const_int 0)]
11364 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11365 [(set_attr "type" "call")])
11366
11367 (define_insn "*sibcall_pop"
11368 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11369 (match_operand 1 "" ""))
11370 (set (reg:SI SP_REG)
11371 (plus:SI (reg:SI SP_REG)
11372 (match_operand:SI 2 "immediate_operand" "i")))]
11373 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11374 "* return ix86_output_call_insn (insn, operands[0]);"
11375 [(set_attr "type" "call")])
11376
11377 ;; Call subroutine, returning value in operand 0
11378
11379 (define_expand "call_value"
11380 [(set (match_operand 0 "" "")
11381 (call (match_operand:QI 1 "" "")
11382 (match_operand 2 "" "")))
11383 (use (match_operand 3 "" ""))]
11384 ""
11385 {
11386 ix86_expand_call (operands[0], operands[1], operands[2],
11387 operands[3], NULL, false);
11388 DONE;
11389 })
11390
11391 (define_expand "sibcall_value"
11392 [(set (match_operand 0 "" "")
11393 (call (match_operand:QI 1 "" "")
11394 (match_operand 2 "" "")))
11395 (use (match_operand 3 "" ""))]
11396 ""
11397 {
11398 ix86_expand_call (operands[0], operands[1], operands[2],
11399 operands[3], NULL, true);
11400 DONE;
11401 })
11402
11403 (define_insn_and_split "*call_value_vzeroupper"
11404 [(set (match_operand 0 "" "")
11405 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11406 (match_operand 2 "" "")))
11407 (unspec [(match_operand 3 "const_int_operand" "")]
11408 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11409 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11410 "#"
11411 "&& reload_completed"
11412 [(const_int 0)]
11413 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11414 [(set_attr "type" "callv")])
11415
11416 (define_insn "*call_value"
11417 [(set (match_operand 0 "" "")
11418 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11419 (match_operand 2 "" "")))]
11420 "!SIBLING_CALL_P (insn)"
11421 "* return ix86_output_call_insn (insn, operands[1]);"
11422 [(set_attr "type" "callv")])
11423
11424 (define_insn_and_split "*sibcall_value_vzeroupper"
11425 [(set (match_operand 0 "" "")
11426 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11427 (match_operand 2 "" "")))
11428 (unspec [(match_operand 3 "const_int_operand" "")]
11429 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11430 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11431 "#"
11432 "&& reload_completed"
11433 [(const_int 0)]
11434 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11435 [(set_attr "type" "callv")])
11436
11437 (define_insn "*sibcall_value"
11438 [(set (match_operand 0 "" "")
11439 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11440 (match_operand 2 "" "")))]
11441 "SIBLING_CALL_P (insn)"
11442 "* return ix86_output_call_insn (insn, operands[1]);"
11443 [(set_attr "type" "callv")])
11444
11445 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11446 [(set (match_operand 0 "" "")
11447 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11448 (match_operand 2 "" "")))
11449 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11450 (clobber (reg:TI XMM6_REG))
11451 (clobber (reg:TI XMM7_REG))
11452 (clobber (reg:TI XMM8_REG))
11453 (clobber (reg:TI XMM9_REG))
11454 (clobber (reg:TI XMM10_REG))
11455 (clobber (reg:TI XMM11_REG))
11456 (clobber (reg:TI XMM12_REG))
11457 (clobber (reg:TI XMM13_REG))
11458 (clobber (reg:TI XMM14_REG))
11459 (clobber (reg:TI XMM15_REG))
11460 (clobber (reg:DI SI_REG))
11461 (clobber (reg:DI DI_REG))
11462 (unspec [(match_operand 3 "const_int_operand" "")]
11463 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11464 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11465 "#"
11466 "&& reload_completed"
11467 [(const_int 0)]
11468 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11469 [(set_attr "type" "callv")])
11470
11471 (define_insn "*call_value_rex64_ms_sysv"
11472 [(set (match_operand 0 "" "")
11473 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11474 (match_operand 2 "" "")))
11475 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11476 (clobber (reg:TI XMM6_REG))
11477 (clobber (reg:TI XMM7_REG))
11478 (clobber (reg:TI XMM8_REG))
11479 (clobber (reg:TI XMM9_REG))
11480 (clobber (reg:TI XMM10_REG))
11481 (clobber (reg:TI XMM11_REG))
11482 (clobber (reg:TI XMM12_REG))
11483 (clobber (reg:TI XMM13_REG))
11484 (clobber (reg:TI XMM14_REG))
11485 (clobber (reg:TI XMM15_REG))
11486 (clobber (reg:DI SI_REG))
11487 (clobber (reg:DI DI_REG))]
11488 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11489 "* return ix86_output_call_insn (insn, operands[1]);"
11490 [(set_attr "type" "callv")])
11491
11492 (define_expand "call_value_pop"
11493 [(parallel [(set (match_operand 0 "" "")
11494 (call (match_operand:QI 1 "" "")
11495 (match_operand:SI 2 "" "")))
11496 (set (reg:SI SP_REG)
11497 (plus:SI (reg:SI SP_REG)
11498 (match_operand:SI 4 "" "")))])]
11499 "!TARGET_64BIT"
11500 {
11501 ix86_expand_call (operands[0], operands[1], operands[2],
11502 operands[3], operands[4], false);
11503 DONE;
11504 })
11505
11506 (define_insn_and_split "*call_value_pop_vzeroupper"
11507 [(set (match_operand 0 "" "")
11508 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11509 (match_operand 2 "" "")))
11510 (set (reg:SI SP_REG)
11511 (plus:SI (reg:SI SP_REG)
11512 (match_operand:SI 3 "immediate_operand" "i")))
11513 (unspec [(match_operand 4 "const_int_operand" "")]
11514 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11515 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11516 "#"
11517 "&& reload_completed"
11518 [(const_int 0)]
11519 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11520 [(set_attr "type" "callv")])
11521
11522 (define_insn "*call_value_pop"
11523 [(set (match_operand 0 "" "")
11524 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11525 (match_operand 2 "" "")))
11526 (set (reg:SI SP_REG)
11527 (plus:SI (reg:SI SP_REG)
11528 (match_operand:SI 3 "immediate_operand" "i")))]
11529 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11530 "* return ix86_output_call_insn (insn, operands[1]);"
11531 [(set_attr "type" "callv")])
11532
11533 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11534 [(set (match_operand 0 "" "")
11535 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11536 (match_operand 2 "" "")))
11537 (set (reg:SI SP_REG)
11538 (plus:SI (reg:SI SP_REG)
11539 (match_operand:SI 3 "immediate_operand" "i")))
11540 (unspec [(match_operand 4 "const_int_operand" "")]
11541 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11542 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11543 "#"
11544 "&& reload_completed"
11545 [(const_int 0)]
11546 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11547 [(set_attr "type" "callv")])
11548
11549 (define_insn "*sibcall_value_pop"
11550 [(set (match_operand 0 "" "")
11551 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11552 (match_operand 2 "" "")))
11553 (set (reg:SI SP_REG)
11554 (plus:SI (reg:SI SP_REG)
11555 (match_operand:SI 3 "immediate_operand" "i")))]
11556 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11557 "* return ix86_output_call_insn (insn, operands[1]);"
11558 [(set_attr "type" "callv")])
11559
11560 ;; Call subroutine returning any type.
11561
11562 (define_expand "untyped_call"
11563 [(parallel [(call (match_operand 0 "" "")
11564 (const_int 0))
11565 (match_operand 1 "" "")
11566 (match_operand 2 "" "")])]
11567 ""
11568 {
11569 int i;
11570
11571 /* In order to give reg-stack an easier job in validating two
11572 coprocessor registers as containing a possible return value,
11573 simply pretend the untyped call returns a complex long double
11574 value.
11575
11576 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11577 and should have the default ABI. */
11578
11579 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11580 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11581 operands[0], const0_rtx,
11582 GEN_INT ((TARGET_64BIT
11583 ? (ix86_abi == SYSV_ABI
11584 ? X86_64_SSE_REGPARM_MAX
11585 : X86_64_MS_SSE_REGPARM_MAX)
11586 : X86_32_SSE_REGPARM_MAX)
11587 - 1),
11588 NULL, false);
11589
11590 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11591 {
11592 rtx set = XVECEXP (operands[2], 0, i);
11593 emit_move_insn (SET_DEST (set), SET_SRC (set));
11594 }
11595
11596 /* The optimizer does not know that the call sets the function value
11597 registers we stored in the result block. We avoid problems by
11598 claiming that all hard registers are used and clobbered at this
11599 point. */
11600 emit_insn (gen_blockage ());
11601
11602 DONE;
11603 })
11604 \f
11605 ;; Prologue and epilogue instructions
11606
11607 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11608 ;; all of memory. This blocks insns from being moved across this point.
11609
11610 (define_insn "blockage"
11611 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11612 ""
11613 ""
11614 [(set_attr "length" "0")])
11615
11616 ;; Do not schedule instructions accessing memory across this point.
11617
11618 (define_expand "memory_blockage"
11619 [(set (match_dup 0)
11620 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11621 ""
11622 {
11623 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11624 MEM_VOLATILE_P (operands[0]) = 1;
11625 })
11626
11627 (define_insn "*memory_blockage"
11628 [(set (match_operand:BLK 0 "" "")
11629 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11630 ""
11631 ""
11632 [(set_attr "length" "0")])
11633
11634 ;; As USE insns aren't meaningful after reload, this is used instead
11635 ;; to prevent deleting instructions setting registers for PIC code
11636 (define_insn "prologue_use"
11637 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11638 ""
11639 ""
11640 [(set_attr "length" "0")])
11641
11642 ;; Insn emitted into the body of a function to return from a function.
11643 ;; This is only done if the function's epilogue is known to be simple.
11644 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11645
11646 (define_expand "return"
11647 [(simple_return)]
11648 "ix86_can_use_return_insn_p ()"
11649 {
11650 ix86_maybe_emit_epilogue_vzeroupper ();
11651 if (crtl->args.pops_args)
11652 {
11653 rtx popc = GEN_INT (crtl->args.pops_args);
11654 emit_jump_insn (gen_simple_return_pop_internal (popc));
11655 DONE;
11656 }
11657 })
11658
11659 ;; We need to disable this for TARGET_SEH, as otherwise
11660 ;; shrink-wrapped prologue gets enabled too. This might exceed
11661 ;; the maximum size of prologue in unwind information.
11662
11663 (define_expand "simple_return"
11664 [(simple_return)]
11665 "!TARGET_SEH"
11666 {
11667 ix86_maybe_emit_epilogue_vzeroupper ();
11668 if (crtl->args.pops_args)
11669 {
11670 rtx popc = GEN_INT (crtl->args.pops_args);
11671 emit_jump_insn (gen_simple_return_pop_internal (popc));
11672 DONE;
11673 }
11674 })
11675
11676 (define_insn "simple_return_internal"
11677 [(simple_return)]
11678 "reload_completed"
11679 "ret"
11680 [(set_attr "length" "1")
11681 (set_attr "atom_unit" "jeu")
11682 (set_attr "length_immediate" "0")
11683 (set_attr "modrm" "0")])
11684
11685 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11686 ;; instruction Athlon and K8 have.
11687
11688 (define_insn "simple_return_internal_long"
11689 [(simple_return)
11690 (unspec [(const_int 0)] UNSPEC_REP)]
11691 "reload_completed"
11692 "rep\;ret"
11693 [(set_attr "length" "2")
11694 (set_attr "atom_unit" "jeu")
11695 (set_attr "length_immediate" "0")
11696 (set_attr "prefix_rep" "1")
11697 (set_attr "modrm" "0")])
11698
11699 (define_insn "simple_return_pop_internal"
11700 [(simple_return)
11701 (use (match_operand:SI 0 "const_int_operand" ""))]
11702 "reload_completed"
11703 "ret\t%0"
11704 [(set_attr "length" "3")
11705 (set_attr "atom_unit" "jeu")
11706 (set_attr "length_immediate" "2")
11707 (set_attr "modrm" "0")])
11708
11709 (define_insn "simple_return_indirect_internal"
11710 [(simple_return)
11711 (use (match_operand:SI 0 "register_operand" "r"))]
11712 "reload_completed"
11713 "jmp\t%A0"
11714 [(set_attr "type" "ibr")
11715 (set_attr "length_immediate" "0")])
11716
11717 (define_insn "nop"
11718 [(const_int 0)]
11719 ""
11720 "nop"
11721 [(set_attr "length" "1")
11722 (set_attr "length_immediate" "0")
11723 (set_attr "modrm" "0")])
11724
11725 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11726 (define_insn "nops"
11727 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11728 UNSPECV_NOPS)]
11729 "reload_completed"
11730 {
11731 int num = INTVAL (operands[0]);
11732
11733 gcc_assert (num >= 1 && num <= 8);
11734
11735 while (num--)
11736 fputs ("\tnop\n", asm_out_file);
11737
11738 return "";
11739 }
11740 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11741 (set_attr "length_immediate" "0")
11742 (set_attr "modrm" "0")])
11743
11744 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11745 ;; branch prediction penalty for the third jump in a 16-byte
11746 ;; block on K8.
11747
11748 (define_insn "pad"
11749 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11750 ""
11751 {
11752 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11753 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11754 #else
11755 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11756 The align insn is used to avoid 3 jump instructions in the row to improve
11757 branch prediction and the benefits hardly outweigh the cost of extra 8
11758 nops on the average inserted by full alignment pseudo operation. */
11759 #endif
11760 return "";
11761 }
11762 [(set_attr "length" "16")])
11763
11764 (define_expand "prologue"
11765 [(const_int 0)]
11766 ""
11767 "ix86_expand_prologue (); DONE;")
11768
11769 (define_insn "set_got"
11770 [(set (match_operand:SI 0 "register_operand" "=r")
11771 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11772 (clobber (reg:CC FLAGS_REG))]
11773 "!TARGET_64BIT"
11774 "* return output_set_got (operands[0], NULL_RTX);"
11775 [(set_attr "type" "multi")
11776 (set_attr "length" "12")])
11777
11778 (define_insn "set_got_labelled"
11779 [(set (match_operand:SI 0 "register_operand" "=r")
11780 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11781 UNSPEC_SET_GOT))
11782 (clobber (reg:CC FLAGS_REG))]
11783 "!TARGET_64BIT"
11784 "* return output_set_got (operands[0], operands[1]);"
11785 [(set_attr "type" "multi")
11786 (set_attr "length" "12")])
11787
11788 (define_insn "set_got_rex64"
11789 [(set (match_operand:DI 0 "register_operand" "=r")
11790 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11791 "TARGET_64BIT"
11792 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11793 [(set_attr "type" "lea")
11794 (set_attr "length_address" "4")
11795 (set_attr "mode" "DI")])
11796
11797 (define_insn "set_rip_rex64"
11798 [(set (match_operand:DI 0 "register_operand" "=r")
11799 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11800 "TARGET_64BIT"
11801 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11802 [(set_attr "type" "lea")
11803 (set_attr "length_address" "4")
11804 (set_attr "mode" "DI")])
11805
11806 (define_insn "set_got_offset_rex64"
11807 [(set (match_operand:DI 0 "register_operand" "=r")
11808 (unspec:DI
11809 [(label_ref (match_operand 1 "" ""))]
11810 UNSPEC_SET_GOT_OFFSET))]
11811 "TARGET_LP64"
11812 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11813 [(set_attr "type" "imov")
11814 (set_attr "length_immediate" "0")
11815 (set_attr "length_address" "8")
11816 (set_attr "mode" "DI")])
11817
11818 (define_expand "epilogue"
11819 [(const_int 0)]
11820 ""
11821 "ix86_expand_epilogue (1); DONE;")
11822
11823 (define_expand "sibcall_epilogue"
11824 [(const_int 0)]
11825 ""
11826 "ix86_expand_epilogue (0); DONE;")
11827
11828 (define_expand "eh_return"
11829 [(use (match_operand 0 "register_operand" ""))]
11830 ""
11831 {
11832 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11833
11834 /* Tricky bit: we write the address of the handler to which we will
11835 be returning into someone else's stack frame, one word below the
11836 stack address we wish to restore. */
11837 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11838 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11839 tmp = gen_rtx_MEM (Pmode, tmp);
11840 emit_move_insn (tmp, ra);
11841
11842 emit_jump_insn (gen_eh_return_internal ());
11843 emit_barrier ();
11844 DONE;
11845 })
11846
11847 (define_insn_and_split "eh_return_internal"
11848 [(eh_return)]
11849 ""
11850 "#"
11851 "epilogue_completed"
11852 [(const_int 0)]
11853 "ix86_expand_epilogue (2); DONE;")
11854
11855 (define_insn "leave"
11856 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11857 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11858 (clobber (mem:BLK (scratch)))]
11859 "!TARGET_64BIT"
11860 "leave"
11861 [(set_attr "type" "leave")])
11862
11863 (define_insn "leave_rex64"
11864 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11865 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11866 (clobber (mem:BLK (scratch)))]
11867 "TARGET_64BIT"
11868 "leave"
11869 [(set_attr "type" "leave")])
11870 \f
11871 ;; Handle -fsplit-stack.
11872
11873 (define_expand "split_stack_prologue"
11874 [(const_int 0)]
11875 ""
11876 {
11877 ix86_expand_split_stack_prologue ();
11878 DONE;
11879 })
11880
11881 ;; In order to support the call/return predictor, we use a return
11882 ;; instruction which the middle-end doesn't see.
11883 (define_insn "split_stack_return"
11884 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11885 UNSPECV_SPLIT_STACK_RETURN)]
11886 ""
11887 {
11888 if (operands[0] == const0_rtx)
11889 return "ret";
11890 else
11891 return "ret\t%0";
11892 }
11893 [(set_attr "atom_unit" "jeu")
11894 (set_attr "modrm" "0")
11895 (set (attr "length")
11896 (if_then_else (match_operand:SI 0 "const0_operand" "")
11897 (const_int 1)
11898 (const_int 3)))
11899 (set (attr "length_immediate")
11900 (if_then_else (match_operand:SI 0 "const0_operand" "")
11901 (const_int 0)
11902 (const_int 2)))])
11903
11904 ;; If there are operand 0 bytes available on the stack, jump to
11905 ;; operand 1.
11906
11907 (define_expand "split_stack_space_check"
11908 [(set (pc) (if_then_else
11909 (ltu (minus (reg SP_REG)
11910 (match_operand 0 "register_operand" ""))
11911 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11912 (label_ref (match_operand 1 "" ""))
11913 (pc)))]
11914 ""
11915 {
11916 rtx reg, size, limit;
11917
11918 reg = gen_reg_rtx (Pmode);
11919 size = force_reg (Pmode, operands[0]);
11920 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11921 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11922 UNSPEC_STACK_CHECK);
11923 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11924 ix86_expand_branch (GEU, reg, limit, operands[1]);
11925
11926 DONE;
11927 })
11928 \f
11929 ;; Bit manipulation instructions.
11930
11931 (define_expand "ffs<mode>2"
11932 [(set (match_dup 2) (const_int -1))
11933 (parallel [(set (reg:CCZ FLAGS_REG)
11934 (compare:CCZ
11935 (match_operand:SWI48 1 "nonimmediate_operand" "")
11936 (const_int 0)))
11937 (set (match_operand:SWI48 0 "register_operand" "")
11938 (ctz:SWI48 (match_dup 1)))])
11939 (set (match_dup 0) (if_then_else:SWI48
11940 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11941 (match_dup 2)
11942 (match_dup 0)))
11943 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11944 (clobber (reg:CC FLAGS_REG))])]
11945 ""
11946 {
11947 if (<MODE>mode == SImode && !TARGET_CMOVE)
11948 {
11949 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11950 DONE;
11951 }
11952 operands[2] = gen_reg_rtx (<MODE>mode);
11953 })
11954
11955 (define_insn_and_split "ffssi2_no_cmove"
11956 [(set (match_operand:SI 0 "register_operand" "=r")
11957 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11958 (clobber (match_scratch:SI 2 "=&q"))
11959 (clobber (reg:CC FLAGS_REG))]
11960 "!TARGET_CMOVE"
11961 "#"
11962 "&& reload_completed"
11963 [(parallel [(set (reg:CCZ FLAGS_REG)
11964 (compare:CCZ (match_dup 1) (const_int 0)))
11965 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11966 (set (strict_low_part (match_dup 3))
11967 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11968 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11969 (clobber (reg:CC FLAGS_REG))])
11970 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11971 (clobber (reg:CC FLAGS_REG))])
11972 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11973 (clobber (reg:CC FLAGS_REG))])]
11974 {
11975 operands[3] = gen_lowpart (QImode, operands[2]);
11976 ix86_expand_clear (operands[2]);
11977 })
11978
11979 (define_insn "*ffs<mode>_1"
11980 [(set (reg:CCZ FLAGS_REG)
11981 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11982 (const_int 0)))
11983 (set (match_operand:SWI48 0 "register_operand" "=r")
11984 (ctz:SWI48 (match_dup 1)))]
11985 ""
11986 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11987 [(set_attr "type" "alu1")
11988 (set_attr "prefix_0f" "1")
11989 (set_attr "mode" "<MODE>")])
11990
11991 (define_insn "ctz<mode>2"
11992 [(set (match_operand:SWI248 0 "register_operand" "=r")
11993 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11994 (clobber (reg:CC FLAGS_REG))]
11995 ""
11996 {
11997 if (TARGET_BMI)
11998 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11999 else
12000 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12001 }
12002 [(set_attr "type" "alu1")
12003 (set_attr "prefix_0f" "1")
12004 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12005 (set_attr "mode" "<MODE>")])
12006
12007 (define_expand "clz<mode>2"
12008 [(parallel
12009 [(set (match_operand:SWI248 0 "register_operand" "")
12010 (minus:SWI248
12011 (match_dup 2)
12012 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12013 (clobber (reg:CC FLAGS_REG))])
12014 (parallel
12015 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12016 (clobber (reg:CC FLAGS_REG))])]
12017 ""
12018 {
12019 if (TARGET_LZCNT)
12020 {
12021 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12022 DONE;
12023 }
12024 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12025 })
12026
12027 (define_insn "clz<mode>2_lzcnt"
12028 [(set (match_operand:SWI248 0 "register_operand" "=r")
12029 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12030 (clobber (reg:CC FLAGS_REG))]
12031 "TARGET_LZCNT"
12032 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12033 [(set_attr "prefix_rep" "1")
12034 (set_attr "type" "bitmanip")
12035 (set_attr "mode" "<MODE>")])
12036
12037 ;; BMI instructions.
12038 (define_insn "*bmi_andn_<mode>"
12039 [(set (match_operand:SWI48 0 "register_operand" "=r")
12040 (and:SWI48
12041 (not:SWI48
12042 (match_operand:SWI48 1 "register_operand" "r"))
12043 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12044 (clobber (reg:CC FLAGS_REG))]
12045 "TARGET_BMI"
12046 "andn\t{%2, %1, %0|%0, %1, %2}"
12047 [(set_attr "type" "bitmanip")
12048 (set_attr "mode" "<MODE>")])
12049
12050 (define_insn "bmi_bextr_<mode>"
12051 [(set (match_operand:SWI48 0 "register_operand" "=r")
12052 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12053 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12054 UNSPEC_BEXTR))
12055 (clobber (reg:CC FLAGS_REG))]
12056 "TARGET_BMI"
12057 "bextr\t{%2, %1, %0|%0, %1, %2}"
12058 [(set_attr "type" "bitmanip")
12059 (set_attr "mode" "<MODE>")])
12060
12061 (define_insn "*bmi_blsi_<mode>"
12062 [(set (match_operand:SWI48 0 "register_operand" "=r")
12063 (and:SWI48
12064 (neg:SWI48
12065 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12066 (match_dup 1)))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "TARGET_BMI"
12069 "blsi\t{%1, %0|%0, %1}"
12070 [(set_attr "type" "bitmanip")
12071 (set_attr "mode" "<MODE>")])
12072
12073 (define_insn "*bmi_blsmsk_<mode>"
12074 [(set (match_operand:SWI48 0 "register_operand" "=r")
12075 (xor:SWI48
12076 (plus:SWI48
12077 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12078 (const_int -1))
12079 (match_dup 1)))
12080 (clobber (reg:CC FLAGS_REG))]
12081 "TARGET_BMI"
12082 "blsmsk\t{%1, %0|%0, %1}"
12083 [(set_attr "type" "bitmanip")
12084 (set_attr "mode" "<MODE>")])
12085
12086 (define_insn "*bmi_blsr_<mode>"
12087 [(set (match_operand:SWI48 0 "register_operand" "=r")
12088 (and:SWI48
12089 (plus:SWI48
12090 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12091 (const_int -1))
12092 (match_dup 1)))
12093 (clobber (reg:CC FLAGS_REG))]
12094 "TARGET_BMI"
12095 "blsr\t{%1, %0|%0, %1}"
12096 [(set_attr "type" "bitmanip")
12097 (set_attr "mode" "<MODE>")])
12098
12099 ;; BMI2 instructions.
12100 (define_insn "bmi2_bzhi_<mode>3"
12101 [(set (match_operand:SWI48 0 "register_operand" "=r")
12102 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12103 (lshiftrt:SWI48 (const_int -1)
12104 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "TARGET_BMI2"
12107 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12108 [(set_attr "type" "bitmanip")
12109 (set_attr "prefix" "vex")
12110 (set_attr "mode" "<MODE>")])
12111
12112 (define_insn "bmi2_pdep_<mode>3"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12115 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12116 UNSPEC_PDEP))]
12117 "TARGET_BMI2"
12118 "pdep\t{%2, %1, %0|%0, %1, %2}"
12119 [(set_attr "type" "bitmanip")
12120 (set_attr "prefix" "vex")
12121 (set_attr "mode" "<MODE>")])
12122
12123 (define_insn "bmi2_pext_<mode>3"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r")
12125 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12126 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12127 UNSPEC_PEXT))]
12128 "TARGET_BMI2"
12129 "pext\t{%2, %1, %0|%0, %1, %2}"
12130 [(set_attr "type" "bitmanip")
12131 (set_attr "prefix" "vex")
12132 (set_attr "mode" "<MODE>")])
12133
12134 ;; TBM instructions.
12135 (define_insn "tbm_bextri_<mode>"
12136 [(set (match_operand:SWI48 0 "register_operand" "=r")
12137 (zero_extract:SWI48
12138 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12139 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12140 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12141 (clobber (reg:CC FLAGS_REG))]
12142 "TARGET_TBM"
12143 {
12144 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12145 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12146 }
12147 [(set_attr "type" "bitmanip")
12148 (set_attr "mode" "<MODE>")])
12149
12150 (define_insn "*tbm_blcfill_<mode>"
12151 [(set (match_operand:SWI48 0 "register_operand" "=r")
12152 (and: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 "blcfill\t{%1, %0|%0, %1}"
12160 [(set_attr "type" "bitmanip")
12161 (set_attr "mode" "<MODE>")])
12162
12163 (define_insn "*tbm_blci_<mode>"
12164 [(set (match_operand:SWI48 0 "register_operand" "=r")
12165 (ior:SWI48
12166 (not:SWI48
12167 (plus:SWI48
12168 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12169 (const_int 1)))
12170 (match_dup 1)))
12171 (clobber (reg:CC FLAGS_REG))]
12172 "TARGET_TBM"
12173 "blci\t{%1, %0|%0, %1}"
12174 [(set_attr "type" "bitmanip")
12175 (set_attr "mode" "<MODE>")])
12176
12177 (define_insn "*tbm_blcic_<mode>"
12178 [(set (match_operand:SWI48 0 "register_operand" "=r")
12179 (and:SWI48
12180 (plus:SWI48
12181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12182 (const_int 1))
12183 (not:SWI48
12184 (match_dup 1))))
12185 (clobber (reg:CC FLAGS_REG))]
12186 "TARGET_TBM"
12187 "blcic\t{%1, %0|%0, %1}"
12188 [(set_attr "type" "bitmanip")
12189 (set_attr "mode" "<MODE>")])
12190
12191 (define_insn "*tbm_blcmsk_<mode>"
12192 [(set (match_operand:SWI48 0 "register_operand" "=r")
12193 (xor:SWI48
12194 (plus:SWI48
12195 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12196 (const_int 1))
12197 (match_dup 1)))
12198 (clobber (reg:CC FLAGS_REG))]
12199 "TARGET_TBM"
12200 "blcmsk\t{%1, %0|%0, %1}"
12201 [(set_attr "type" "bitmanip")
12202 (set_attr "mode" "<MODE>")])
12203
12204 (define_insn "*tbm_blcs_<mode>"
12205 [(set (match_operand:SWI48 0 "register_operand" "=r")
12206 (ior:SWI48
12207 (plus:SWI48
12208 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12209 (const_int 1))
12210 (match_dup 1)))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "TARGET_TBM"
12213 "blcs\t{%1, %0|%0, %1}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "mode" "<MODE>")])
12216
12217 (define_insn "*tbm_blsfill_<mode>"
12218 [(set (match_operand:SWI48 0 "register_operand" "=r")
12219 (ior:SWI48
12220 (plus:SWI48
12221 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12222 (const_int -1))
12223 (match_dup 1)))
12224 (clobber (reg:CC FLAGS_REG))]
12225 "TARGET_TBM"
12226 "blsfill\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12229
12230 (define_insn "*tbm_blsic_<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 "blsic\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip")
12242 (set_attr "mode" "<MODE>")])
12243
12244 (define_insn "*tbm_t1mskc_<mode>"
12245 [(set (match_operand:SWI48 0 "register_operand" "=r")
12246 (ior: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 "t1mskc\t{%1, %0|%0, %1}"
12255 [(set_attr "type" "bitmanip")
12256 (set_attr "mode" "<MODE>")])
12257
12258 (define_insn "*tbm_tzmsk_<mode>"
12259 [(set (match_operand:SWI48 0 "register_operand" "=r")
12260 (and:SWI48
12261 (plus:SWI48
12262 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12263 (const_int -1))
12264 (not:SWI48
12265 (match_dup 1))))
12266 (clobber (reg:CC FLAGS_REG))]
12267 "TARGET_TBM"
12268 "tzmsk\t{%1, %0|%0, %1}"
12269 [(set_attr "type" "bitmanip")
12270 (set_attr "mode" "<MODE>")])
12271
12272 (define_insn "bsr_rex64"
12273 [(set (match_operand:DI 0 "register_operand" "=r")
12274 (minus:DI (const_int 63)
12275 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12276 (clobber (reg:CC FLAGS_REG))]
12277 "TARGET_64BIT"
12278 "bsr{q}\t{%1, %0|%0, %1}"
12279 [(set_attr "type" "alu1")
12280 (set_attr "prefix_0f" "1")
12281 (set_attr "mode" "DI")])
12282
12283 (define_insn "bsr"
12284 [(set (match_operand:SI 0 "register_operand" "=r")
12285 (minus:SI (const_int 31)
12286 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12287 (clobber (reg:CC FLAGS_REG))]
12288 ""
12289 "bsr{l}\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "alu1")
12291 (set_attr "prefix_0f" "1")
12292 (set_attr "mode" "SI")])
12293
12294 (define_insn "*bsrhi"
12295 [(set (match_operand:HI 0 "register_operand" "=r")
12296 (minus:HI (const_int 15)
12297 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12298 (clobber (reg:CC FLAGS_REG))]
12299 ""
12300 "bsr{w}\t{%1, %0|%0, %1}"
12301 [(set_attr "type" "alu1")
12302 (set_attr "prefix_0f" "1")
12303 (set_attr "mode" "HI")])
12304
12305 (define_insn "popcount<mode>2"
12306 [(set (match_operand:SWI248 0 "register_operand" "=r")
12307 (popcount:SWI248
12308 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12309 (clobber (reg:CC FLAGS_REG))]
12310 "TARGET_POPCNT"
12311 {
12312 #if TARGET_MACHO
12313 return "popcnt\t{%1, %0|%0, %1}";
12314 #else
12315 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12316 #endif
12317 }
12318 [(set_attr "prefix_rep" "1")
12319 (set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12321
12322 (define_insn "*popcount<mode>2_cmp"
12323 [(set (reg FLAGS_REG)
12324 (compare
12325 (popcount:SWI248
12326 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12327 (const_int 0)))
12328 (set (match_operand:SWI248 0 "register_operand" "=r")
12329 (popcount:SWI248 (match_dup 1)))]
12330 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12331 {
12332 #if TARGET_MACHO
12333 return "popcnt\t{%1, %0|%0, %1}";
12334 #else
12335 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12336 #endif
12337 }
12338 [(set_attr "prefix_rep" "1")
12339 (set_attr "type" "bitmanip")
12340 (set_attr "mode" "<MODE>")])
12341
12342 (define_insn "*popcountsi2_cmp_zext"
12343 [(set (reg FLAGS_REG)
12344 (compare
12345 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12346 (const_int 0)))
12347 (set (match_operand:DI 0 "register_operand" "=r")
12348 (zero_extend:DI(popcount:SI (match_dup 1))))]
12349 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12350 {
12351 #if TARGET_MACHO
12352 return "popcnt\t{%1, %0|%0, %1}";
12353 #else
12354 return "popcnt{l}\t{%1, %0|%0, %1}";
12355 #endif
12356 }
12357 [(set_attr "prefix_rep" "1")
12358 (set_attr "type" "bitmanip")
12359 (set_attr "mode" "SI")])
12360
12361 (define_expand "bswap<mode>2"
12362 [(set (match_operand:SWI48 0 "register_operand" "")
12363 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12364 ""
12365 {
12366 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12367 {
12368 rtx x = operands[0];
12369
12370 emit_move_insn (x, operands[1]);
12371 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12372 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12373 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12374 DONE;
12375 }
12376 })
12377
12378 (define_insn "*bswap<mode>2_movbe"
12379 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12380 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12381 "TARGET_MOVBE
12382 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12383 "@
12384 bswap\t%0
12385 movbe\t{%1, %0|%0, %1}
12386 movbe\t{%1, %0|%0, %1}"
12387 [(set_attr "type" "bitmanip,imov,imov")
12388 (set_attr "modrm" "0,1,1")
12389 (set_attr "prefix_0f" "*,1,1")
12390 (set_attr "prefix_extra" "*,1,1")
12391 (set_attr "mode" "<MODE>")])
12392
12393 (define_insn "*bswap<mode>2_1"
12394 [(set (match_operand:SWI48 0 "register_operand" "=r")
12395 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12396 "TARGET_BSWAP"
12397 "bswap\t%0"
12398 [(set_attr "type" "bitmanip")
12399 (set_attr "modrm" "0")
12400 (set_attr "mode" "<MODE>")])
12401
12402 (define_insn "*bswaphi_lowpart_1"
12403 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12404 (bswap:HI (match_dup 0)))
12405 (clobber (reg:CC FLAGS_REG))]
12406 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12407 "@
12408 xchg{b}\t{%h0, %b0|%b0, %h0}
12409 rol{w}\t{$8, %0|%0, 8}"
12410 [(set_attr "length" "2,4")
12411 (set_attr "mode" "QI,HI")])
12412
12413 (define_insn "bswaphi_lowpart"
12414 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12415 (bswap:HI (match_dup 0)))
12416 (clobber (reg:CC FLAGS_REG))]
12417 ""
12418 "rol{w}\t{$8, %0|%0, 8}"
12419 [(set_attr "length" "4")
12420 (set_attr "mode" "HI")])
12421
12422 (define_expand "paritydi2"
12423 [(set (match_operand:DI 0 "register_operand" "")
12424 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12425 "! TARGET_POPCNT"
12426 {
12427 rtx scratch = gen_reg_rtx (QImode);
12428 rtx cond;
12429
12430 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12431 NULL_RTX, operands[1]));
12432
12433 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12434 gen_rtx_REG (CCmode, FLAGS_REG),
12435 const0_rtx);
12436 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12437
12438 if (TARGET_64BIT)
12439 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12440 else
12441 {
12442 rtx tmp = gen_reg_rtx (SImode);
12443
12444 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12445 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12446 }
12447 DONE;
12448 })
12449
12450 (define_expand "paritysi2"
12451 [(set (match_operand:SI 0 "register_operand" "")
12452 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12453 "! TARGET_POPCNT"
12454 {
12455 rtx scratch = gen_reg_rtx (QImode);
12456 rtx cond;
12457
12458 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12459
12460 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12461 gen_rtx_REG (CCmode, FLAGS_REG),
12462 const0_rtx);
12463 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12464
12465 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12466 DONE;
12467 })
12468
12469 (define_insn_and_split "paritydi2_cmp"
12470 [(set (reg:CC FLAGS_REG)
12471 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12472 UNSPEC_PARITY))
12473 (clobber (match_scratch:DI 0 "=r"))
12474 (clobber (match_scratch:SI 1 "=&r"))
12475 (clobber (match_scratch:HI 2 "=Q"))]
12476 "! TARGET_POPCNT"
12477 "#"
12478 "&& reload_completed"
12479 [(parallel
12480 [(set (match_dup 1)
12481 (xor:SI (match_dup 1) (match_dup 4)))
12482 (clobber (reg:CC FLAGS_REG))])
12483 (parallel
12484 [(set (reg:CC FLAGS_REG)
12485 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12486 (clobber (match_dup 1))
12487 (clobber (match_dup 2))])]
12488 {
12489 operands[4] = gen_lowpart (SImode, operands[3]);
12490
12491 if (TARGET_64BIT)
12492 {
12493 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12494 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12495 }
12496 else
12497 operands[1] = gen_highpart (SImode, operands[3]);
12498 })
12499
12500 (define_insn_and_split "paritysi2_cmp"
12501 [(set (reg:CC FLAGS_REG)
12502 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12503 UNSPEC_PARITY))
12504 (clobber (match_scratch:SI 0 "=r"))
12505 (clobber (match_scratch:HI 1 "=&Q"))]
12506 "! TARGET_POPCNT"
12507 "#"
12508 "&& reload_completed"
12509 [(parallel
12510 [(set (match_dup 1)
12511 (xor:HI (match_dup 1) (match_dup 3)))
12512 (clobber (reg:CC FLAGS_REG))])
12513 (parallel
12514 [(set (reg:CC FLAGS_REG)
12515 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12516 (clobber (match_dup 1))])]
12517 {
12518 operands[3] = gen_lowpart (HImode, operands[2]);
12519
12520 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12521 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12522 })
12523
12524 (define_insn "*parityhi2_cmp"
12525 [(set (reg:CC FLAGS_REG)
12526 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12527 UNSPEC_PARITY))
12528 (clobber (match_scratch:HI 0 "=Q"))]
12529 "! TARGET_POPCNT"
12530 "xor{b}\t{%h0, %b0|%b0, %h0}"
12531 [(set_attr "length" "2")
12532 (set_attr "mode" "HI")])
12533
12534 \f
12535 ;; Thread-local storage patterns for ELF.
12536 ;;
12537 ;; Note that these code sequences must appear exactly as shown
12538 ;; in order to allow linker relaxation.
12539
12540 (define_insn "*tls_global_dynamic_32_gnu"
12541 [(set (match_operand:SI 0 "register_operand" "=a")
12542 (unspec:SI
12543 [(match_operand:SI 1 "register_operand" "b")
12544 (match_operand:SI 2 "tls_symbolic_operand" "")
12545 (match_operand:SI 3 "constant_call_address_operand" "z")]
12546 UNSPEC_TLS_GD))
12547 (clobber (match_scratch:SI 4 "=d"))
12548 (clobber (match_scratch:SI 5 "=c"))
12549 (clobber (reg:CC FLAGS_REG))]
12550 "!TARGET_64BIT && TARGET_GNU_TLS"
12551 {
12552 output_asm_insn
12553 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12554 if (TARGET_SUN_TLS)
12555 #ifdef HAVE_AS_IX86_TLSGDPLT
12556 return "call\t%a2@tlsgdplt";
12557 #else
12558 return "call\t%p3@plt";
12559 #endif
12560 return "call\t%P3";
12561 }
12562 [(set_attr "type" "multi")
12563 (set_attr "length" "12")])
12564
12565 (define_expand "tls_global_dynamic_32"
12566 [(parallel
12567 [(set (match_operand:SI 0 "register_operand" "")
12568 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12569 (match_operand:SI 1 "tls_symbolic_operand" "")
12570 (match_operand:SI 3 "constant_call_address_operand" "")]
12571 UNSPEC_TLS_GD))
12572 (clobber (match_scratch:SI 4 ""))
12573 (clobber (match_scratch:SI 5 ""))
12574 (clobber (reg:CC FLAGS_REG))])])
12575
12576 (define_insn "*tls_global_dynamic_64"
12577 [(set (match_operand:DI 0 "register_operand" "=a")
12578 (call:DI
12579 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12580 (match_operand:DI 3 "" "")))
12581 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12582 UNSPEC_TLS_GD)]
12583 "TARGET_64BIT"
12584 {
12585 if (!TARGET_X32)
12586 fputs (ASM_BYTE "0x66\n", asm_out_file);
12587 output_asm_insn
12588 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12589 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12590 fputs ("\trex64\n", asm_out_file);
12591 if (TARGET_SUN_TLS)
12592 return "call\t%p2@plt";
12593 return "call\t%P2";
12594 }
12595 [(set_attr "type" "multi")
12596 (set (attr "length")
12597 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12598
12599 (define_expand "tls_global_dynamic_64"
12600 [(parallel
12601 [(set (match_operand:DI 0 "register_operand" "")
12602 (call:DI
12603 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12604 (const_int 0)))
12605 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12606 UNSPEC_TLS_GD)])])
12607
12608 (define_insn "*tls_local_dynamic_base_32_gnu"
12609 [(set (match_operand:SI 0 "register_operand" "=a")
12610 (unspec:SI
12611 [(match_operand:SI 1 "register_operand" "b")
12612 (match_operand:SI 2 "constant_call_address_operand" "z")]
12613 UNSPEC_TLS_LD_BASE))
12614 (clobber (match_scratch:SI 3 "=d"))
12615 (clobber (match_scratch:SI 4 "=c"))
12616 (clobber (reg:CC FLAGS_REG))]
12617 "!TARGET_64BIT && TARGET_GNU_TLS"
12618 {
12619 output_asm_insn
12620 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12621 if (TARGET_SUN_TLS)
12622 #ifdef HAVE_AS_IX86_TLSLDMPLT
12623 return "call\t%&@tlsldmplt";
12624 #else
12625 return "call\t%p2@plt";
12626 #endif
12627 return "call\t%P2";
12628 }
12629 [(set_attr "type" "multi")
12630 (set_attr "length" "11")])
12631
12632 (define_expand "tls_local_dynamic_base_32"
12633 [(parallel
12634 [(set (match_operand:SI 0 "register_operand" "")
12635 (unspec:SI
12636 [(match_operand:SI 1 "register_operand" "")
12637 (match_operand:SI 2 "constant_call_address_operand" "")]
12638 UNSPEC_TLS_LD_BASE))
12639 (clobber (match_scratch:SI 3 ""))
12640 (clobber (match_scratch:SI 4 ""))
12641 (clobber (reg:CC FLAGS_REG))])])
12642
12643 (define_insn "*tls_local_dynamic_base_64"
12644 [(set (match_operand:DI 0 "register_operand" "=a")
12645 (call:DI
12646 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12647 (match_operand:DI 2 "" "")))
12648 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12649 "TARGET_64BIT"
12650 {
12651 output_asm_insn
12652 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12653 if (TARGET_SUN_TLS)
12654 return "call\t%p1@plt";
12655 return "call\t%P1";
12656 }
12657 [(set_attr "type" "multi")
12658 (set_attr "length" "12")])
12659
12660 (define_expand "tls_local_dynamic_base_64"
12661 [(parallel
12662 [(set (match_operand:DI 0 "register_operand" "")
12663 (call:DI
12664 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12665 (const_int 0)))
12666 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12667
12668 ;; Local dynamic of a single variable is a lose. Show combine how
12669 ;; to convert that back to global dynamic.
12670
12671 (define_insn_and_split "*tls_local_dynamic_32_once"
12672 [(set (match_operand:SI 0 "register_operand" "=a")
12673 (plus:SI
12674 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12675 (match_operand:SI 2 "constant_call_address_operand" "z")]
12676 UNSPEC_TLS_LD_BASE)
12677 (const:SI (unspec:SI
12678 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12679 UNSPEC_DTPOFF))))
12680 (clobber (match_scratch:SI 4 "=d"))
12681 (clobber (match_scratch:SI 5 "=c"))
12682 (clobber (reg:CC FLAGS_REG))]
12683 ""
12684 "#"
12685 ""
12686 [(parallel
12687 [(set (match_dup 0)
12688 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12689 UNSPEC_TLS_GD))
12690 (clobber (match_dup 4))
12691 (clobber (match_dup 5))
12692 (clobber (reg:CC FLAGS_REG))])])
12693
12694 ;; Segment register for the thread base ptr load
12695 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12696
12697 ;; Load and add the thread base pointer from %<tp_seg>:0.
12698 (define_insn "*load_tp_x32"
12699 [(set (match_operand:SI 0 "register_operand" "=r")
12700 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12701 "TARGET_X32"
12702 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12703 [(set_attr "type" "imov")
12704 (set_attr "modrm" "0")
12705 (set_attr "length" "7")
12706 (set_attr "memory" "load")
12707 (set_attr "imm_disp" "false")])
12708
12709 (define_insn "*load_tp_x32_zext"
12710 [(set (match_operand:DI 0 "register_operand" "=r")
12711 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12712 "TARGET_X32"
12713 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12714 [(set_attr "type" "imov")
12715 (set_attr "modrm" "0")
12716 (set_attr "length" "7")
12717 (set_attr "memory" "load")
12718 (set_attr "imm_disp" "false")])
12719
12720 (define_insn "*load_tp_<mode>"
12721 [(set (match_operand:P 0 "register_operand" "=r")
12722 (unspec:P [(const_int 0)] UNSPEC_TP))]
12723 "!TARGET_X32"
12724 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12725 [(set_attr "type" "imov")
12726 (set_attr "modrm" "0")
12727 (set_attr "length" "7")
12728 (set_attr "memory" "load")
12729 (set_attr "imm_disp" "false")])
12730
12731 (define_insn "*add_tp_x32"
12732 [(set (match_operand:SI 0 "register_operand" "=r")
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, %0|%0, 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_x32_zext"
12745 [(set (match_operand:DI 0 "register_operand" "=r")
12746 (zero_extend:DI
12747 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12748 (match_operand:SI 1 "register_operand" "0"))))
12749 (clobber (reg:CC FLAGS_REG))]
12750 "TARGET_X32"
12751 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12752 [(set_attr "type" "alu")
12753 (set_attr "modrm" "0")
12754 (set_attr "length" "7")
12755 (set_attr "memory" "load")
12756 (set_attr "imm_disp" "false")])
12757
12758 (define_insn "*add_tp_<mode>"
12759 [(set (match_operand:P 0 "register_operand" "=r")
12760 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12761 (match_operand:P 1 "register_operand" "0")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "!TARGET_X32"
12764 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12765 [(set_attr "type" "alu")
12766 (set_attr "modrm" "0")
12767 (set_attr "length" "7")
12768 (set_attr "memory" "load")
12769 (set_attr "imm_disp" "false")])
12770
12771 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12772 ;; %rax as destination of the initial executable code sequence.
12773 (define_insn "tls_initial_exec_64_sun"
12774 [(set (match_operand:DI 0 "register_operand" "=a")
12775 (unspec:DI
12776 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12777 UNSPEC_TLS_IE_SUN))
12778 (clobber (reg:CC FLAGS_REG))]
12779 "TARGET_64BIT && TARGET_SUN_TLS"
12780 {
12781 output_asm_insn
12782 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12783 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12784 }
12785 [(set_attr "type" "multi")])
12786
12787 ;; When Pmode == SImode, there may be no REX prefix for ADD. Avoid
12788 ;; any instructions between MOV and ADD, which may interfere linker
12789 ;; IE->LE optimization, since the last byte of the previous instruction
12790 ;; before ADD may look like a REX prefix. This also avoids
12791 ;; movl x@gottpoff(%rip), %reg32
12792 ;; movl $fs:(%reg32), %reg32
12793 ;; Since address override works only on the (reg32) part in fs:(reg32),
12794 ;; we can't use it as memory operand.
12795 (define_insn "tls_initial_exec_x32"
12796 [(set (match_operand:SI 0 "register_operand" "=r")
12797 (unspec:SI
12798 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12799 UNSPEC_TLS_IE_X32))
12800 (clobber (reg:CC FLAGS_REG))]
12801 "TARGET_X32"
12802 {
12803 output_asm_insn
12804 ("mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}", operands);
12805 return "add{l}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12806 }
12807 [(set_attr "type" "multi")])
12808
12809 ;; GNU2 TLS patterns can be split.
12810
12811 (define_expand "tls_dynamic_gnu2_32"
12812 [(set (match_dup 3)
12813 (plus:SI (match_operand:SI 2 "register_operand" "")
12814 (const:SI
12815 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12816 UNSPEC_TLSDESC))))
12817 (parallel
12818 [(set (match_operand:SI 0 "register_operand" "")
12819 (unspec:SI [(match_dup 1) (match_dup 3)
12820 (match_dup 2) (reg:SI SP_REG)]
12821 UNSPEC_TLSDESC))
12822 (clobber (reg:CC FLAGS_REG))])]
12823 "!TARGET_64BIT && TARGET_GNU2_TLS"
12824 {
12825 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12826 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12827 })
12828
12829 (define_insn "*tls_dynamic_gnu2_lea_32"
12830 [(set (match_operand:SI 0 "register_operand" "=r")
12831 (plus:SI (match_operand:SI 1 "register_operand" "b")
12832 (const:SI
12833 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12834 UNSPEC_TLSDESC))))]
12835 "!TARGET_64BIT && TARGET_GNU2_TLS"
12836 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12837 [(set_attr "type" "lea")
12838 (set_attr "mode" "SI")
12839 (set_attr "length" "6")
12840 (set_attr "length_address" "4")])
12841
12842 (define_insn "*tls_dynamic_gnu2_call_32"
12843 [(set (match_operand:SI 0 "register_operand" "=a")
12844 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12845 (match_operand:SI 2 "register_operand" "0")
12846 ;; we have to make sure %ebx still points to the GOT
12847 (match_operand:SI 3 "register_operand" "b")
12848 (reg:SI SP_REG)]
12849 UNSPEC_TLSDESC))
12850 (clobber (reg:CC FLAGS_REG))]
12851 "!TARGET_64BIT && TARGET_GNU2_TLS"
12852 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12853 [(set_attr "type" "call")
12854 (set_attr "length" "2")
12855 (set_attr "length_address" "0")])
12856
12857 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12858 [(set (match_operand:SI 0 "register_operand" "=&a")
12859 (plus:SI
12860 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12861 (match_operand:SI 4 "" "")
12862 (match_operand:SI 2 "register_operand" "b")
12863 (reg:SI SP_REG)]
12864 UNSPEC_TLSDESC)
12865 (const:SI (unspec:SI
12866 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12867 UNSPEC_DTPOFF))))
12868 (clobber (reg:CC FLAGS_REG))]
12869 "!TARGET_64BIT && TARGET_GNU2_TLS"
12870 "#"
12871 ""
12872 [(set (match_dup 0) (match_dup 5))]
12873 {
12874 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12875 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12876 })
12877
12878 (define_expand "tls_dynamic_gnu2_64"
12879 [(set (match_dup 2)
12880 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12881 UNSPEC_TLSDESC))
12882 (parallel
12883 [(set (match_operand:DI 0 "register_operand" "")
12884 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12885 UNSPEC_TLSDESC))
12886 (clobber (reg:CC FLAGS_REG))])]
12887 "TARGET_64BIT && TARGET_GNU2_TLS"
12888 {
12889 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12890 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12891 })
12892
12893 (define_insn "*tls_dynamic_gnu2_lea_64"
12894 [(set (match_operand:DI 0 "register_operand" "=r")
12895 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12896 UNSPEC_TLSDESC))]
12897 "TARGET_64BIT && TARGET_GNU2_TLS"
12898 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12899 [(set_attr "type" "lea")
12900 (set_attr "mode" "DI")
12901 (set_attr "length" "7")
12902 (set_attr "length_address" "4")])
12903
12904 (define_insn "*tls_dynamic_gnu2_call_64"
12905 [(set (match_operand:DI 0 "register_operand" "=a")
12906 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12907 (match_operand:DI 2 "register_operand" "0")
12908 (reg:DI SP_REG)]
12909 UNSPEC_TLSDESC))
12910 (clobber (reg:CC FLAGS_REG))]
12911 "TARGET_64BIT && TARGET_GNU2_TLS"
12912 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12913 [(set_attr "type" "call")
12914 (set_attr "length" "2")
12915 (set_attr "length_address" "0")])
12916
12917 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12918 [(set (match_operand:DI 0 "register_operand" "=&a")
12919 (plus:DI
12920 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12921 (match_operand:DI 3 "" "")
12922 (reg:DI SP_REG)]
12923 UNSPEC_TLSDESC)
12924 (const:DI (unspec:DI
12925 [(match_operand 1 "tls_symbolic_operand" "")]
12926 UNSPEC_DTPOFF))))
12927 (clobber (reg:CC FLAGS_REG))]
12928 "TARGET_64BIT && TARGET_GNU2_TLS"
12929 "#"
12930 ""
12931 [(set (match_dup 0) (match_dup 4))]
12932 {
12933 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12934 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12935 })
12936 \f
12937 ;; These patterns match the binary 387 instructions for addM3, subM3,
12938 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12939 ;; SFmode. The first is the normal insn, the second the same insn but
12940 ;; with one operand a conversion, and the third the same insn but with
12941 ;; the other operand a conversion. The conversion may be SFmode or
12942 ;; SImode if the target mode DFmode, but only SImode if the target mode
12943 ;; is SFmode.
12944
12945 ;; Gcc is slightly more smart about handling normal two address instructions
12946 ;; so use special patterns for add and mull.
12947
12948 (define_insn "*fop_<mode>_comm_mixed"
12949 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12950 (match_operator:MODEF 3 "binary_fp_operator"
12951 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12952 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12953 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12954 && COMMUTATIVE_ARITH_P (operands[3])
12955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12956 "* return output_387_binary_op (insn, operands);"
12957 [(set (attr "type")
12958 (if_then_else (eq_attr "alternative" "1,2")
12959 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12960 (const_string "ssemul")
12961 (const_string "sseadd"))
12962 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12963 (const_string "fmul")
12964 (const_string "fop"))))
12965 (set_attr "isa" "*,noavx,avx")
12966 (set_attr "prefix" "orig,orig,vex")
12967 (set_attr "mode" "<MODE>")])
12968
12969 (define_insn "*fop_<mode>_comm_sse"
12970 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12971 (match_operator:MODEF 3 "binary_fp_operator"
12972 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12973 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12974 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12975 && COMMUTATIVE_ARITH_P (operands[3])
12976 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12977 "* return output_387_binary_op (insn, operands);"
12978 [(set (attr "type")
12979 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12980 (const_string "ssemul")
12981 (const_string "sseadd")))
12982 (set_attr "isa" "noavx,avx")
12983 (set_attr "prefix" "orig,vex")
12984 (set_attr "mode" "<MODE>")])
12985
12986 (define_insn "*fop_<mode>_comm_i387"
12987 [(set (match_operand:MODEF 0 "register_operand" "=f")
12988 (match_operator:MODEF 3 "binary_fp_operator"
12989 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12990 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12991 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12992 && COMMUTATIVE_ARITH_P (operands[3])
12993 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12994 "* return output_387_binary_op (insn, operands);"
12995 [(set (attr "type")
12996 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12997 (const_string "fmul")
12998 (const_string "fop")))
12999 (set_attr "mode" "<MODE>")])
13000
13001 (define_insn "*fop_<mode>_1_mixed"
13002 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13003 (match_operator:MODEF 3 "binary_fp_operator"
13004 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13005 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13006 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13007 && !COMMUTATIVE_ARITH_P (operands[3])
13008 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13009 "* return output_387_binary_op (insn, operands);"
13010 [(set (attr "type")
13011 (cond [(and (eq_attr "alternative" "2,3")
13012 (match_operand:MODEF 3 "mult_operator" ""))
13013 (const_string "ssemul")
13014 (and (eq_attr "alternative" "2,3")
13015 (match_operand:MODEF 3 "div_operator" ""))
13016 (const_string "ssediv")
13017 (eq_attr "alternative" "2,3")
13018 (const_string "sseadd")
13019 (match_operand:MODEF 3 "mult_operator" "")
13020 (const_string "fmul")
13021 (match_operand:MODEF 3 "div_operator" "")
13022 (const_string "fdiv")
13023 ]
13024 (const_string "fop")))
13025 (set_attr "isa" "*,*,noavx,avx")
13026 (set_attr "prefix" "orig,orig,orig,vex")
13027 (set_attr "mode" "<MODE>")])
13028
13029 (define_insn "*rcpsf2_sse"
13030 [(set (match_operand:SF 0 "register_operand" "=x")
13031 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13032 UNSPEC_RCP))]
13033 "TARGET_SSE_MATH"
13034 "%vrcpss\t{%1, %d0|%d0, %1}"
13035 [(set_attr "type" "sse")
13036 (set_attr "atom_sse_attr" "rcp")
13037 (set_attr "prefix" "maybe_vex")
13038 (set_attr "mode" "SF")])
13039
13040 (define_insn "*fop_<mode>_1_sse"
13041 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13042 (match_operator:MODEF 3 "binary_fp_operator"
13043 [(match_operand:MODEF 1 "register_operand" "0,x")
13044 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13045 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13046 && !COMMUTATIVE_ARITH_P (operands[3])"
13047 "* return output_387_binary_op (insn, operands);"
13048 [(set (attr "type")
13049 (cond [(match_operand:MODEF 3 "mult_operator" "")
13050 (const_string "ssemul")
13051 (match_operand:MODEF 3 "div_operator" "")
13052 (const_string "ssediv")
13053 ]
13054 (const_string "sseadd")))
13055 (set_attr "isa" "noavx,avx")
13056 (set_attr "prefix" "orig,vex")
13057 (set_attr "mode" "<MODE>")])
13058
13059 ;; This pattern is not fully shadowed by the pattern above.
13060 (define_insn "*fop_<mode>_1_i387"
13061 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13062 (match_operator:MODEF 3 "binary_fp_operator"
13063 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13064 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13065 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13066 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13067 && !COMMUTATIVE_ARITH_P (operands[3])
13068 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13069 "* return output_387_binary_op (insn, operands);"
13070 [(set (attr "type")
13071 (cond [(match_operand:MODEF 3 "mult_operator" "")
13072 (const_string "fmul")
13073 (match_operand:MODEF 3 "div_operator" "")
13074 (const_string "fdiv")
13075 ]
13076 (const_string "fop")))
13077 (set_attr "mode" "<MODE>")])
13078
13079 ;; ??? Add SSE splitters for these!
13080 (define_insn "*fop_<MODEF:mode>_2_i387"
13081 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13082 (match_operator:MODEF 3 "binary_fp_operator"
13083 [(float:MODEF
13084 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13085 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13086 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13087 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13088 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13089 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13090 [(set (attr "type")
13091 (cond [(match_operand:MODEF 3 "mult_operator" "")
13092 (const_string "fmul")
13093 (match_operand:MODEF 3 "div_operator" "")
13094 (const_string "fdiv")
13095 ]
13096 (const_string "fop")))
13097 (set_attr "fp_int_src" "true")
13098 (set_attr "mode" "<SWI24:MODE>")])
13099
13100 (define_insn "*fop_<MODEF:mode>_3_i387"
13101 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13102 (match_operator:MODEF 3 "binary_fp_operator"
13103 [(match_operand:MODEF 1 "register_operand" "0,0")
13104 (float:MODEF
13105 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13106 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13107 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13108 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13109 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13110 [(set (attr "type")
13111 (cond [(match_operand:MODEF 3 "mult_operator" "")
13112 (const_string "fmul")
13113 (match_operand:MODEF 3 "div_operator" "")
13114 (const_string "fdiv")
13115 ]
13116 (const_string "fop")))
13117 (set_attr "fp_int_src" "true")
13118 (set_attr "mode" "<MODE>")])
13119
13120 (define_insn "*fop_df_4_i387"
13121 [(set (match_operand:DF 0 "register_operand" "=f,f")
13122 (match_operator:DF 3 "binary_fp_operator"
13123 [(float_extend:DF
13124 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13125 (match_operand:DF 2 "register_operand" "0,f")]))]
13126 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13127 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13128 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13129 "* return output_387_binary_op (insn, operands);"
13130 [(set (attr "type")
13131 (cond [(match_operand:DF 3 "mult_operator" "")
13132 (const_string "fmul")
13133 (match_operand:DF 3 "div_operator" "")
13134 (const_string "fdiv")
13135 ]
13136 (const_string "fop")))
13137 (set_attr "mode" "SF")])
13138
13139 (define_insn "*fop_df_5_i387"
13140 [(set (match_operand:DF 0 "register_operand" "=f,f")
13141 (match_operator:DF 3 "binary_fp_operator"
13142 [(match_operand:DF 1 "register_operand" "0,f")
13143 (float_extend:DF
13144 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13145 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13146 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13147 "* return output_387_binary_op (insn, operands);"
13148 [(set (attr "type")
13149 (cond [(match_operand:DF 3 "mult_operator" "")
13150 (const_string "fmul")
13151 (match_operand:DF 3 "div_operator" "")
13152 (const_string "fdiv")
13153 ]
13154 (const_string "fop")))
13155 (set_attr "mode" "SF")])
13156
13157 (define_insn "*fop_df_6_i387"
13158 [(set (match_operand:DF 0 "register_operand" "=f,f")
13159 (match_operator:DF 3 "binary_fp_operator"
13160 [(float_extend:DF
13161 (match_operand:SF 1 "register_operand" "0,f"))
13162 (float_extend:DF
13163 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13164 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13165 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13166 "* return output_387_binary_op (insn, operands);"
13167 [(set (attr "type")
13168 (cond [(match_operand:DF 3 "mult_operator" "")
13169 (const_string "fmul")
13170 (match_operand:DF 3 "div_operator" "")
13171 (const_string "fdiv")
13172 ]
13173 (const_string "fop")))
13174 (set_attr "mode" "SF")])
13175
13176 (define_insn "*fop_xf_comm_i387"
13177 [(set (match_operand:XF 0 "register_operand" "=f")
13178 (match_operator:XF 3 "binary_fp_operator"
13179 [(match_operand:XF 1 "register_operand" "%0")
13180 (match_operand:XF 2 "register_operand" "f")]))]
13181 "TARGET_80387
13182 && COMMUTATIVE_ARITH_P (operands[3])"
13183 "* return output_387_binary_op (insn, operands);"
13184 [(set (attr "type")
13185 (if_then_else (match_operand:XF 3 "mult_operator" "")
13186 (const_string "fmul")
13187 (const_string "fop")))
13188 (set_attr "mode" "XF")])
13189
13190 (define_insn "*fop_xf_1_i387"
13191 [(set (match_operand:XF 0 "register_operand" "=f,f")
13192 (match_operator:XF 3 "binary_fp_operator"
13193 [(match_operand:XF 1 "register_operand" "0,f")
13194 (match_operand:XF 2 "register_operand" "f,0")]))]
13195 "TARGET_80387
13196 && !COMMUTATIVE_ARITH_P (operands[3])"
13197 "* return output_387_binary_op (insn, operands);"
13198 [(set (attr "type")
13199 (cond [(match_operand:XF 3 "mult_operator" "")
13200 (const_string "fmul")
13201 (match_operand:XF 3 "div_operator" "")
13202 (const_string "fdiv")
13203 ]
13204 (const_string "fop")))
13205 (set_attr "mode" "XF")])
13206
13207 (define_insn "*fop_xf_2_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f,f")
13209 (match_operator:XF 3 "binary_fp_operator"
13210 [(float:XF
13211 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13212 (match_operand:XF 2 "register_operand" "0,0")]))]
13213 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13214 "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
13223 (set_attr "mode" "<MODE>")])
13224
13225 (define_insn "*fop_xf_3_i387"
13226 [(set (match_operand:XF 0 "register_operand" "=f,f")
13227 (match_operator:XF 3 "binary_fp_operator"
13228 [(match_operand:XF 1 "register_operand" "0,0")
13229 (float:XF
13230 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13231 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13232 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13233 [(set (attr "type")
13234 (cond [(match_operand:XF 3 "mult_operator" "")
13235 (const_string "fmul")
13236 (match_operand:XF 3 "div_operator" "")
13237 (const_string "fdiv")
13238 ]
13239 (const_string "fop")))
13240 (set_attr "fp_int_src" "true")
13241 (set_attr "mode" "<MODE>")])
13242
13243 (define_insn "*fop_xf_4_i387"
13244 [(set (match_operand:XF 0 "register_operand" "=f,f")
13245 (match_operator:XF 3 "binary_fp_operator"
13246 [(float_extend:XF
13247 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13248 (match_operand:XF 2 "register_operand" "0,f")]))]
13249 "TARGET_80387"
13250 "* return output_387_binary_op (insn, operands);"
13251 [(set (attr "type")
13252 (cond [(match_operand:XF 3 "mult_operator" "")
13253 (const_string "fmul")
13254 (match_operand:XF 3 "div_operator" "")
13255 (const_string "fdiv")
13256 ]
13257 (const_string "fop")))
13258 (set_attr "mode" "<MODE>")])
13259
13260 (define_insn "*fop_xf_5_i387"
13261 [(set (match_operand:XF 0 "register_operand" "=f,f")
13262 (match_operator:XF 3 "binary_fp_operator"
13263 [(match_operand:XF 1 "register_operand" "0,f")
13264 (float_extend:XF
13265 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13266 "TARGET_80387"
13267 "* return output_387_binary_op (insn, operands);"
13268 [(set (attr "type")
13269 (cond [(match_operand:XF 3 "mult_operator" "")
13270 (const_string "fmul")
13271 (match_operand:XF 3 "div_operator" "")
13272 (const_string "fdiv")
13273 ]
13274 (const_string "fop")))
13275 (set_attr "mode" "<MODE>")])
13276
13277 (define_insn "*fop_xf_6_i387"
13278 [(set (match_operand:XF 0 "register_operand" "=f,f")
13279 (match_operator:XF 3 "binary_fp_operator"
13280 [(float_extend:XF
13281 (match_operand:MODEF 1 "register_operand" "0,f"))
13282 (float_extend:XF
13283 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13284 "TARGET_80387"
13285 "* return output_387_binary_op (insn, operands);"
13286 [(set (attr "type")
13287 (cond [(match_operand:XF 3 "mult_operator" "")
13288 (const_string "fmul")
13289 (match_operand:XF 3 "div_operator" "")
13290 (const_string "fdiv")
13291 ]
13292 (const_string "fop")))
13293 (set_attr "mode" "<MODE>")])
13294
13295 (define_split
13296 [(set (match_operand 0 "register_operand" "")
13297 (match_operator 3 "binary_fp_operator"
13298 [(float (match_operand:SWI24 1 "register_operand" ""))
13299 (match_operand 2 "register_operand" "")]))]
13300 "reload_completed
13301 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13302 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13303 [(const_int 0)]
13304 {
13305 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13306 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13307 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13308 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13309 GET_MODE (operands[3]),
13310 operands[4],
13311 operands[2])));
13312 ix86_free_from_memory (GET_MODE (operands[1]));
13313 DONE;
13314 })
13315
13316 (define_split
13317 [(set (match_operand 0 "register_operand" "")
13318 (match_operator 3 "binary_fp_operator"
13319 [(match_operand 1 "register_operand" "")
13320 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13321 "reload_completed
13322 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13323 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13324 [(const_int 0)]
13325 {
13326 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13327 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13328 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13329 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13330 GET_MODE (operands[3]),
13331 operands[1],
13332 operands[4])));
13333 ix86_free_from_memory (GET_MODE (operands[2]));
13334 DONE;
13335 })
13336 \f
13337 ;; FPU special functions.
13338
13339 ;; This pattern implements a no-op XFmode truncation for
13340 ;; all fancy i386 XFmode math functions.
13341
13342 (define_insn "truncxf<mode>2_i387_noop_unspec"
13343 [(set (match_operand:MODEF 0 "register_operand" "=f")
13344 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13345 UNSPEC_TRUNC_NOOP))]
13346 "TARGET_USE_FANCY_MATH_387"
13347 "* return output_387_reg_move (insn, operands);"
13348 [(set_attr "type" "fmov")
13349 (set_attr "mode" "<MODE>")])
13350
13351 (define_insn "sqrtxf2"
13352 [(set (match_operand:XF 0 "register_operand" "=f")
13353 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13354 "TARGET_USE_FANCY_MATH_387"
13355 "fsqrt"
13356 [(set_attr "type" "fpspc")
13357 (set_attr "mode" "XF")
13358 (set_attr "athlon_decode" "direct")
13359 (set_attr "amdfam10_decode" "direct")
13360 (set_attr "bdver1_decode" "direct")])
13361
13362 (define_insn "sqrt_extend<mode>xf2_i387"
13363 [(set (match_operand:XF 0 "register_operand" "=f")
13364 (sqrt:XF
13365 (float_extend:XF
13366 (match_operand:MODEF 1 "register_operand" "0"))))]
13367 "TARGET_USE_FANCY_MATH_387"
13368 "fsqrt"
13369 [(set_attr "type" "fpspc")
13370 (set_attr "mode" "XF")
13371 (set_attr "athlon_decode" "direct")
13372 (set_attr "amdfam10_decode" "direct")
13373 (set_attr "bdver1_decode" "direct")])
13374
13375 (define_insn "*rsqrtsf2_sse"
13376 [(set (match_operand:SF 0 "register_operand" "=x")
13377 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13378 UNSPEC_RSQRT))]
13379 "TARGET_SSE_MATH"
13380 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13381 [(set_attr "type" "sse")
13382 (set_attr "atom_sse_attr" "rcp")
13383 (set_attr "prefix" "maybe_vex")
13384 (set_attr "mode" "SF")])
13385
13386 (define_expand "rsqrtsf2"
13387 [(set (match_operand:SF 0 "register_operand" "")
13388 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13389 UNSPEC_RSQRT))]
13390 "TARGET_SSE_MATH"
13391 {
13392 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13393 DONE;
13394 })
13395
13396 (define_insn "*sqrt<mode>2_sse"
13397 [(set (match_operand:MODEF 0 "register_operand" "=x")
13398 (sqrt:MODEF
13399 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13400 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13401 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13402 [(set_attr "type" "sse")
13403 (set_attr "atom_sse_attr" "sqrt")
13404 (set_attr "prefix" "maybe_vex")
13405 (set_attr "mode" "<MODE>")
13406 (set_attr "athlon_decode" "*")
13407 (set_attr "amdfam10_decode" "*")
13408 (set_attr "bdver1_decode" "*")])
13409
13410 (define_expand "sqrt<mode>2"
13411 [(set (match_operand:MODEF 0 "register_operand" "")
13412 (sqrt:MODEF
13413 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13414 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13415 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13416 {
13417 if (<MODE>mode == SFmode
13418 && TARGET_SSE_MATH
13419 && TARGET_RECIP_SQRT
13420 && !optimize_function_for_size_p (cfun)
13421 && flag_finite_math_only && !flag_trapping_math
13422 && flag_unsafe_math_optimizations)
13423 {
13424 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13425 DONE;
13426 }
13427
13428 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13429 {
13430 rtx op0 = gen_reg_rtx (XFmode);
13431 rtx op1 = force_reg (<MODE>mode, operands[1]);
13432
13433 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13434 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13435 DONE;
13436 }
13437 })
13438
13439 (define_insn "fpremxf4_i387"
13440 [(set (match_operand:XF 0 "register_operand" "=f")
13441 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13442 (match_operand:XF 3 "register_operand" "1")]
13443 UNSPEC_FPREM_F))
13444 (set (match_operand:XF 1 "register_operand" "=u")
13445 (unspec:XF [(match_dup 2) (match_dup 3)]
13446 UNSPEC_FPREM_U))
13447 (set (reg:CCFP FPSR_REG)
13448 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13449 UNSPEC_C2_FLAG))]
13450 "TARGET_USE_FANCY_MATH_387"
13451 "fprem"
13452 [(set_attr "type" "fpspc")
13453 (set_attr "mode" "XF")])
13454
13455 (define_expand "fmodxf3"
13456 [(use (match_operand:XF 0 "register_operand" ""))
13457 (use (match_operand:XF 1 "general_operand" ""))
13458 (use (match_operand:XF 2 "general_operand" ""))]
13459 "TARGET_USE_FANCY_MATH_387"
13460 {
13461 rtx label = gen_label_rtx ();
13462
13463 rtx op1 = gen_reg_rtx (XFmode);
13464 rtx op2 = gen_reg_rtx (XFmode);
13465
13466 emit_move_insn (op2, operands[2]);
13467 emit_move_insn (op1, operands[1]);
13468
13469 emit_label (label);
13470 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13471 ix86_emit_fp_unordered_jump (label);
13472 LABEL_NUSES (label) = 1;
13473
13474 emit_move_insn (operands[0], op1);
13475 DONE;
13476 })
13477
13478 (define_expand "fmod<mode>3"
13479 [(use (match_operand:MODEF 0 "register_operand" ""))
13480 (use (match_operand:MODEF 1 "general_operand" ""))
13481 (use (match_operand:MODEF 2 "general_operand" ""))]
13482 "TARGET_USE_FANCY_MATH_387"
13483 {
13484 rtx (*gen_truncxf) (rtx, rtx);
13485
13486 rtx label = gen_label_rtx ();
13487
13488 rtx op1 = gen_reg_rtx (XFmode);
13489 rtx op2 = gen_reg_rtx (XFmode);
13490
13491 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13492 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13493
13494 emit_label (label);
13495 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13496 ix86_emit_fp_unordered_jump (label);
13497 LABEL_NUSES (label) = 1;
13498
13499 /* Truncate the result properly for strict SSE math. */
13500 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13501 && !TARGET_MIX_SSE_I387)
13502 gen_truncxf = gen_truncxf<mode>2;
13503 else
13504 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13505
13506 emit_insn (gen_truncxf (operands[0], op1));
13507 DONE;
13508 })
13509
13510 (define_insn "fprem1xf4_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f")
13512 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13513 (match_operand:XF 3 "register_operand" "1")]
13514 UNSPEC_FPREM1_F))
13515 (set (match_operand:XF 1 "register_operand" "=u")
13516 (unspec:XF [(match_dup 2) (match_dup 3)]
13517 UNSPEC_FPREM1_U))
13518 (set (reg:CCFP FPSR_REG)
13519 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13520 UNSPEC_C2_FLAG))]
13521 "TARGET_USE_FANCY_MATH_387"
13522 "fprem1"
13523 [(set_attr "type" "fpspc")
13524 (set_attr "mode" "XF")])
13525
13526 (define_expand "remainderxf3"
13527 [(use (match_operand:XF 0 "register_operand" ""))
13528 (use (match_operand:XF 1 "general_operand" ""))
13529 (use (match_operand:XF 2 "general_operand" ""))]
13530 "TARGET_USE_FANCY_MATH_387"
13531 {
13532 rtx label = gen_label_rtx ();
13533
13534 rtx op1 = gen_reg_rtx (XFmode);
13535 rtx op2 = gen_reg_rtx (XFmode);
13536
13537 emit_move_insn (op2, operands[2]);
13538 emit_move_insn (op1, operands[1]);
13539
13540 emit_label (label);
13541 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13542 ix86_emit_fp_unordered_jump (label);
13543 LABEL_NUSES (label) = 1;
13544
13545 emit_move_insn (operands[0], op1);
13546 DONE;
13547 })
13548
13549 (define_expand "remainder<mode>3"
13550 [(use (match_operand:MODEF 0 "register_operand" ""))
13551 (use (match_operand:MODEF 1 "general_operand" ""))
13552 (use (match_operand:MODEF 2 "general_operand" ""))]
13553 "TARGET_USE_FANCY_MATH_387"
13554 {
13555 rtx (*gen_truncxf) (rtx, rtx);
13556
13557 rtx label = gen_label_rtx ();
13558
13559 rtx op1 = gen_reg_rtx (XFmode);
13560 rtx op2 = gen_reg_rtx (XFmode);
13561
13562 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13563 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13564
13565 emit_label (label);
13566
13567 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13568 ix86_emit_fp_unordered_jump (label);
13569 LABEL_NUSES (label) = 1;
13570
13571 /* Truncate the result properly for strict SSE math. */
13572 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13573 && !TARGET_MIX_SSE_I387)
13574 gen_truncxf = gen_truncxf<mode>2;
13575 else
13576 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13577
13578 emit_insn (gen_truncxf (operands[0], op1));
13579 DONE;
13580 })
13581
13582 (define_insn "*sinxf2_i387"
13583 [(set (match_operand:XF 0 "register_operand" "=f")
13584 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13585 "TARGET_USE_FANCY_MATH_387
13586 && flag_unsafe_math_optimizations"
13587 "fsin"
13588 [(set_attr "type" "fpspc")
13589 (set_attr "mode" "XF")])
13590
13591 (define_insn "*sin_extend<mode>xf2_i387"
13592 [(set (match_operand:XF 0 "register_operand" "=f")
13593 (unspec:XF [(float_extend:XF
13594 (match_operand:MODEF 1 "register_operand" "0"))]
13595 UNSPEC_SIN))]
13596 "TARGET_USE_FANCY_MATH_387
13597 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13598 || TARGET_MIX_SSE_I387)
13599 && flag_unsafe_math_optimizations"
13600 "fsin"
13601 [(set_attr "type" "fpspc")
13602 (set_attr "mode" "XF")])
13603
13604 (define_insn "*cosxf2_i387"
13605 [(set (match_operand:XF 0 "register_operand" "=f")
13606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13607 "TARGET_USE_FANCY_MATH_387
13608 && flag_unsafe_math_optimizations"
13609 "fcos"
13610 [(set_attr "type" "fpspc")
13611 (set_attr "mode" "XF")])
13612
13613 (define_insn "*cos_extend<mode>xf2_i387"
13614 [(set (match_operand:XF 0 "register_operand" "=f")
13615 (unspec:XF [(float_extend:XF
13616 (match_operand:MODEF 1 "register_operand" "0"))]
13617 UNSPEC_COS))]
13618 "TARGET_USE_FANCY_MATH_387
13619 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620 || TARGET_MIX_SSE_I387)
13621 && flag_unsafe_math_optimizations"
13622 "fcos"
13623 [(set_attr "type" "fpspc")
13624 (set_attr "mode" "XF")])
13625
13626 ;; When sincos pattern is defined, sin and cos builtin functions will be
13627 ;; expanded to sincos pattern with one of its outputs left unused.
13628 ;; CSE pass will figure out if two sincos patterns can be combined,
13629 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13630 ;; depending on the unused output.
13631
13632 (define_insn "sincosxf3"
13633 [(set (match_operand:XF 0 "register_operand" "=f")
13634 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13635 UNSPEC_SINCOS_COS))
13636 (set (match_operand:XF 1 "register_operand" "=u")
13637 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13638 "TARGET_USE_FANCY_MATH_387
13639 && flag_unsafe_math_optimizations"
13640 "fsincos"
13641 [(set_attr "type" "fpspc")
13642 (set_attr "mode" "XF")])
13643
13644 (define_split
13645 [(set (match_operand:XF 0 "register_operand" "")
13646 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13647 UNSPEC_SINCOS_COS))
13648 (set (match_operand:XF 1 "register_operand" "")
13649 (unspec: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) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13653
13654 (define_split
13655 [(set (match_operand:XF 0 "register_operand" "")
13656 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13657 UNSPEC_SINCOS_COS))
13658 (set (match_operand:XF 1 "register_operand" "")
13659 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13660 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13661 && can_create_pseudo_p ()"
13662 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13663
13664 (define_insn "sincos_extend<mode>xf3_i387"
13665 [(set (match_operand:XF 0 "register_operand" "=f")
13666 (unspec:XF [(float_extend:XF
13667 (match_operand:MODEF 2 "register_operand" "0"))]
13668 UNSPEC_SINCOS_COS))
13669 (set (match_operand:XF 1 "register_operand" "=u")
13670 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
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 "fsincos"
13676 [(set_attr "type" "fpspc")
13677 (set_attr "mode" "XF")])
13678
13679 (define_split
13680 [(set (match_operand:XF 0 "register_operand" "")
13681 (unspec:XF [(float_extend:XF
13682 (match_operand:MODEF 2 "register_operand" ""))]
13683 UNSPEC_SINCOS_COS))
13684 (set (match_operand:XF 1 "register_operand" "")
13685 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13686 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13687 && can_create_pseudo_p ()"
13688 [(set (match_dup 1)
13689 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13690
13691 (define_split
13692 [(set (match_operand:XF 0 "register_operand" "")
13693 (unspec:XF [(float_extend:XF
13694 (match_operand:MODEF 2 "register_operand" ""))]
13695 UNSPEC_SINCOS_COS))
13696 (set (match_operand:XF 1 "register_operand" "")
13697 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13698 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13699 && can_create_pseudo_p ()"
13700 [(set (match_dup 0)
13701 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13702
13703 (define_expand "sincos<mode>3"
13704 [(use (match_operand:MODEF 0 "register_operand" ""))
13705 (use (match_operand:MODEF 1 "register_operand" ""))
13706 (use (match_operand:MODEF 2 "register_operand" ""))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13709 || TARGET_MIX_SSE_I387)
13710 && flag_unsafe_math_optimizations"
13711 {
13712 rtx op0 = gen_reg_rtx (XFmode);
13713 rtx op1 = gen_reg_rtx (XFmode);
13714
13715 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13716 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13717 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13718 DONE;
13719 })
13720
13721 (define_insn "fptanxf4_i387"
13722 [(set (match_operand:XF 0 "register_operand" "=f")
13723 (match_operand:XF 3 "const_double_operand" "F"))
13724 (set (match_operand:XF 1 "register_operand" "=u")
13725 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13726 UNSPEC_TAN))]
13727 "TARGET_USE_FANCY_MATH_387
13728 && flag_unsafe_math_optimizations
13729 && standard_80387_constant_p (operands[3]) == 2"
13730 "fptan"
13731 [(set_attr "type" "fpspc")
13732 (set_attr "mode" "XF")])
13733
13734 (define_insn "fptan_extend<mode>xf4_i387"
13735 [(set (match_operand:MODEF 0 "register_operand" "=f")
13736 (match_operand:MODEF 3 "const_double_operand" "F"))
13737 (set (match_operand:XF 1 "register_operand" "=u")
13738 (unspec:XF [(float_extend:XF
13739 (match_operand:MODEF 2 "register_operand" "0"))]
13740 UNSPEC_TAN))]
13741 "TARGET_USE_FANCY_MATH_387
13742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13743 || TARGET_MIX_SSE_I387)
13744 && flag_unsafe_math_optimizations
13745 && standard_80387_constant_p (operands[3]) == 2"
13746 "fptan"
13747 [(set_attr "type" "fpspc")
13748 (set_attr "mode" "XF")])
13749
13750 (define_expand "tanxf2"
13751 [(use (match_operand:XF 0 "register_operand" ""))
13752 (use (match_operand:XF 1 "register_operand" ""))]
13753 "TARGET_USE_FANCY_MATH_387
13754 && flag_unsafe_math_optimizations"
13755 {
13756 rtx one = gen_reg_rtx (XFmode);
13757 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13758
13759 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13760 DONE;
13761 })
13762
13763 (define_expand "tan<mode>2"
13764 [(use (match_operand:MODEF 0 "register_operand" ""))
13765 (use (match_operand:MODEF 1 "register_operand" ""))]
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 {
13771 rtx op0 = gen_reg_rtx (XFmode);
13772
13773 rtx one = gen_reg_rtx (<MODE>mode);
13774 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13775
13776 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13777 operands[1], op2));
13778 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13779 DONE;
13780 })
13781
13782 (define_insn "*fpatanxf3_i387"
13783 [(set (match_operand:XF 0 "register_operand" "=f")
13784 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13785 (match_operand:XF 2 "register_operand" "u")]
13786 UNSPEC_FPATAN))
13787 (clobber (match_scratch:XF 3 "=2"))]
13788 "TARGET_USE_FANCY_MATH_387
13789 && flag_unsafe_math_optimizations"
13790 "fpatan"
13791 [(set_attr "type" "fpspc")
13792 (set_attr "mode" "XF")])
13793
13794 (define_insn "fpatan_extend<mode>xf3_i387"
13795 [(set (match_operand:XF 0 "register_operand" "=f")
13796 (unspec:XF [(float_extend:XF
13797 (match_operand:MODEF 1 "register_operand" "0"))
13798 (float_extend:XF
13799 (match_operand:MODEF 2 "register_operand" "u"))]
13800 UNSPEC_FPATAN))
13801 (clobber (match_scratch:XF 3 "=2"))]
13802 "TARGET_USE_FANCY_MATH_387
13803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13804 || TARGET_MIX_SSE_I387)
13805 && flag_unsafe_math_optimizations"
13806 "fpatan"
13807 [(set_attr "type" "fpspc")
13808 (set_attr "mode" "XF")])
13809
13810 (define_expand "atan2xf3"
13811 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13812 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13813 (match_operand:XF 1 "register_operand" "")]
13814 UNSPEC_FPATAN))
13815 (clobber (match_scratch:XF 3 ""))])]
13816 "TARGET_USE_FANCY_MATH_387
13817 && flag_unsafe_math_optimizations")
13818
13819 (define_expand "atan2<mode>3"
13820 [(use (match_operand:MODEF 0 "register_operand" ""))
13821 (use (match_operand:MODEF 1 "register_operand" ""))
13822 (use (match_operand:MODEF 2 "register_operand" ""))]
13823 "TARGET_USE_FANCY_MATH_387
13824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13825 || TARGET_MIX_SSE_I387)
13826 && flag_unsafe_math_optimizations"
13827 {
13828 rtx op0 = gen_reg_rtx (XFmode);
13829
13830 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13832 DONE;
13833 })
13834
13835 (define_expand "atanxf2"
13836 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13837 (unspec:XF [(match_dup 2)
13838 (match_operand:XF 1 "register_operand" "")]
13839 UNSPEC_FPATAN))
13840 (clobber (match_scratch:XF 3 ""))])]
13841 "TARGET_USE_FANCY_MATH_387
13842 && flag_unsafe_math_optimizations"
13843 {
13844 operands[2] = gen_reg_rtx (XFmode);
13845 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13846 })
13847
13848 (define_expand "atan<mode>2"
13849 [(use (match_operand:MODEF 0 "register_operand" ""))
13850 (use (match_operand:MODEF 1 "register_operand" ""))]
13851 "TARGET_USE_FANCY_MATH_387
13852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13853 || TARGET_MIX_SSE_I387)
13854 && flag_unsafe_math_optimizations"
13855 {
13856 rtx op0 = gen_reg_rtx (XFmode);
13857
13858 rtx op2 = gen_reg_rtx (<MODE>mode);
13859 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13860
13861 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13862 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13863 DONE;
13864 })
13865
13866 (define_expand "asinxf2"
13867 [(set (match_dup 2)
13868 (mult:XF (match_operand:XF 1 "register_operand" "")
13869 (match_dup 1)))
13870 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13871 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13872 (parallel [(set (match_operand:XF 0 "register_operand" "")
13873 (unspec:XF [(match_dup 5) (match_dup 1)]
13874 UNSPEC_FPATAN))
13875 (clobber (match_scratch:XF 6 ""))])]
13876 "TARGET_USE_FANCY_MATH_387
13877 && flag_unsafe_math_optimizations"
13878 {
13879 int i;
13880
13881 if (optimize_insn_for_size_p ())
13882 FAIL;
13883
13884 for (i = 2; i < 6; i++)
13885 operands[i] = gen_reg_rtx (XFmode);
13886
13887 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13888 })
13889
13890 (define_expand "asin<mode>2"
13891 [(use (match_operand:MODEF 0 "register_operand" ""))
13892 (use (match_operand:MODEF 1 "general_operand" ""))]
13893 "TARGET_USE_FANCY_MATH_387
13894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13895 || TARGET_MIX_SSE_I387)
13896 && flag_unsafe_math_optimizations"
13897 {
13898 rtx op0 = gen_reg_rtx (XFmode);
13899 rtx op1 = gen_reg_rtx (XFmode);
13900
13901 if (optimize_insn_for_size_p ())
13902 FAIL;
13903
13904 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13905 emit_insn (gen_asinxf2 (op0, op1));
13906 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13907 DONE;
13908 })
13909
13910 (define_expand "acosxf2"
13911 [(set (match_dup 2)
13912 (mult:XF (match_operand:XF 1 "register_operand" "")
13913 (match_dup 1)))
13914 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13915 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13916 (parallel [(set (match_operand:XF 0 "register_operand" "")
13917 (unspec:XF [(match_dup 1) (match_dup 5)]
13918 UNSPEC_FPATAN))
13919 (clobber (match_scratch:XF 6 ""))])]
13920 "TARGET_USE_FANCY_MATH_387
13921 && flag_unsafe_math_optimizations"
13922 {
13923 int i;
13924
13925 if (optimize_insn_for_size_p ())
13926 FAIL;
13927
13928 for (i = 2; i < 6; i++)
13929 operands[i] = gen_reg_rtx (XFmode);
13930
13931 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13932 })
13933
13934 (define_expand "acos<mode>2"
13935 [(use (match_operand:MODEF 0 "register_operand" ""))
13936 (use (match_operand:MODEF 1 "general_operand" ""))]
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 {
13942 rtx op0 = gen_reg_rtx (XFmode);
13943 rtx op1 = gen_reg_rtx (XFmode);
13944
13945 if (optimize_insn_for_size_p ())
13946 FAIL;
13947
13948 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13949 emit_insn (gen_acosxf2 (op0, op1));
13950 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13951 DONE;
13952 })
13953
13954 (define_insn "fyl2xxf3_i387"
13955 [(set (match_operand:XF 0 "register_operand" "=f")
13956 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13957 (match_operand:XF 2 "register_operand" "u")]
13958 UNSPEC_FYL2X))
13959 (clobber (match_scratch:XF 3 "=2"))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && flag_unsafe_math_optimizations"
13962 "fyl2x"
13963 [(set_attr "type" "fpspc")
13964 (set_attr "mode" "XF")])
13965
13966 (define_insn "fyl2x_extend<mode>xf3_i387"
13967 [(set (match_operand:XF 0 "register_operand" "=f")
13968 (unspec:XF [(float_extend:XF
13969 (match_operand:MODEF 1 "register_operand" "0"))
13970 (match_operand:XF 2 "register_operand" "u")]
13971 UNSPEC_FYL2X))
13972 (clobber (match_scratch:XF 3 "=2"))]
13973 "TARGET_USE_FANCY_MATH_387
13974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13975 || TARGET_MIX_SSE_I387)
13976 && flag_unsafe_math_optimizations"
13977 "fyl2x"
13978 [(set_attr "type" "fpspc")
13979 (set_attr "mode" "XF")])
13980
13981 (define_expand "logxf2"
13982 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13983 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13984 (match_dup 2)] UNSPEC_FYL2X))
13985 (clobber (match_scratch:XF 3 ""))])]
13986 "TARGET_USE_FANCY_MATH_387
13987 && flag_unsafe_math_optimizations"
13988 {
13989 operands[2] = gen_reg_rtx (XFmode);
13990 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13991 })
13992
13993 (define_expand "log<mode>2"
13994 [(use (match_operand:MODEF 0 "register_operand" ""))
13995 (use (match_operand:MODEF 1 "register_operand" ""))]
13996 "TARGET_USE_FANCY_MATH_387
13997 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13998 || TARGET_MIX_SSE_I387)
13999 && flag_unsafe_math_optimizations"
14000 {
14001 rtx op0 = gen_reg_rtx (XFmode);
14002
14003 rtx op2 = gen_reg_rtx (XFmode);
14004 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14005
14006 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14007 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14008 DONE;
14009 })
14010
14011 (define_expand "log10xf2"
14012 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14013 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14014 (match_dup 2)] UNSPEC_FYL2X))
14015 (clobber (match_scratch:XF 3 ""))])]
14016 "TARGET_USE_FANCY_MATH_387
14017 && flag_unsafe_math_optimizations"
14018 {
14019 operands[2] = gen_reg_rtx (XFmode);
14020 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14021 })
14022
14023 (define_expand "log10<mode>2"
14024 [(use (match_operand:MODEF 0 "register_operand" ""))
14025 (use (match_operand:MODEF 1 "register_operand" ""))]
14026 "TARGET_USE_FANCY_MATH_387
14027 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14028 || TARGET_MIX_SSE_I387)
14029 && flag_unsafe_math_optimizations"
14030 {
14031 rtx op0 = gen_reg_rtx (XFmode);
14032
14033 rtx op2 = gen_reg_rtx (XFmode);
14034 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14035
14036 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14037 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14038 DONE;
14039 })
14040
14041 (define_expand "log2xf2"
14042 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14043 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14044 (match_dup 2)] UNSPEC_FYL2X))
14045 (clobber (match_scratch:XF 3 ""))])]
14046 "TARGET_USE_FANCY_MATH_387
14047 && flag_unsafe_math_optimizations"
14048 {
14049 operands[2] = gen_reg_rtx (XFmode);
14050 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14051 })
14052
14053 (define_expand "log2<mode>2"
14054 [(use (match_operand:MODEF 0 "register_operand" ""))
14055 (use (match_operand:MODEF 1 "register_operand" ""))]
14056 "TARGET_USE_FANCY_MATH_387
14057 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14058 || TARGET_MIX_SSE_I387)
14059 && flag_unsafe_math_optimizations"
14060 {
14061 rtx op0 = gen_reg_rtx (XFmode);
14062
14063 rtx op2 = gen_reg_rtx (XFmode);
14064 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14065
14066 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14067 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14068 DONE;
14069 })
14070
14071 (define_insn "fyl2xp1xf3_i387"
14072 [(set (match_operand:XF 0 "register_operand" "=f")
14073 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14074 (match_operand:XF 2 "register_operand" "u")]
14075 UNSPEC_FYL2XP1))
14076 (clobber (match_scratch:XF 3 "=2"))]
14077 "TARGET_USE_FANCY_MATH_387
14078 && flag_unsafe_math_optimizations"
14079 "fyl2xp1"
14080 [(set_attr "type" "fpspc")
14081 (set_attr "mode" "XF")])
14082
14083 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14084 [(set (match_operand:XF 0 "register_operand" "=f")
14085 (unspec:XF [(float_extend:XF
14086 (match_operand:MODEF 1 "register_operand" "0"))
14087 (match_operand:XF 2 "register_operand" "u")]
14088 UNSPEC_FYL2XP1))
14089 (clobber (match_scratch:XF 3 "=2"))]
14090 "TARGET_USE_FANCY_MATH_387
14091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14092 || TARGET_MIX_SSE_I387)
14093 && flag_unsafe_math_optimizations"
14094 "fyl2xp1"
14095 [(set_attr "type" "fpspc")
14096 (set_attr "mode" "XF")])
14097
14098 (define_expand "log1pxf2"
14099 [(use (match_operand:XF 0 "register_operand" ""))
14100 (use (match_operand:XF 1 "register_operand" ""))]
14101 "TARGET_USE_FANCY_MATH_387
14102 && flag_unsafe_math_optimizations"
14103 {
14104 if (optimize_insn_for_size_p ())
14105 FAIL;
14106
14107 ix86_emit_i387_log1p (operands[0], operands[1]);
14108 DONE;
14109 })
14110
14111 (define_expand "log1p<mode>2"
14112 [(use (match_operand:MODEF 0 "register_operand" ""))
14113 (use (match_operand:MODEF 1 "register_operand" ""))]
14114 "TARGET_USE_FANCY_MATH_387
14115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14116 || TARGET_MIX_SSE_I387)
14117 && flag_unsafe_math_optimizations"
14118 {
14119 rtx op0;
14120
14121 if (optimize_insn_for_size_p ())
14122 FAIL;
14123
14124 op0 = gen_reg_rtx (XFmode);
14125
14126 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14127
14128 ix86_emit_i387_log1p (op0, operands[1]);
14129 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14130 DONE;
14131 })
14132
14133 (define_insn "fxtractxf3_i387"
14134 [(set (match_operand:XF 0 "register_operand" "=f")
14135 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14136 UNSPEC_XTRACT_FRACT))
14137 (set (match_operand:XF 1 "register_operand" "=u")
14138 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && flag_unsafe_math_optimizations"
14141 "fxtract"
14142 [(set_attr "type" "fpspc")
14143 (set_attr "mode" "XF")])
14144
14145 (define_insn "fxtract_extend<mode>xf3_i387"
14146 [(set (match_operand:XF 0 "register_operand" "=f")
14147 (unspec:XF [(float_extend:XF
14148 (match_operand:MODEF 2 "register_operand" "0"))]
14149 UNSPEC_XTRACT_FRACT))
14150 (set (match_operand:XF 1 "register_operand" "=u")
14151 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14152 "TARGET_USE_FANCY_MATH_387
14153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14154 || TARGET_MIX_SSE_I387)
14155 && flag_unsafe_math_optimizations"
14156 "fxtract"
14157 [(set_attr "type" "fpspc")
14158 (set_attr "mode" "XF")])
14159
14160 (define_expand "logbxf2"
14161 [(parallel [(set (match_dup 2)
14162 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14163 UNSPEC_XTRACT_FRACT))
14164 (set (match_operand:XF 0 "register_operand" "")
14165 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14166 "TARGET_USE_FANCY_MATH_387
14167 && flag_unsafe_math_optimizations"
14168 "operands[2] = gen_reg_rtx (XFmode);")
14169
14170 (define_expand "logb<mode>2"
14171 [(use (match_operand:MODEF 0 "register_operand" ""))
14172 (use (match_operand:MODEF 1 "register_operand" ""))]
14173 "TARGET_USE_FANCY_MATH_387
14174 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14175 || TARGET_MIX_SSE_I387)
14176 && flag_unsafe_math_optimizations"
14177 {
14178 rtx op0 = gen_reg_rtx (XFmode);
14179 rtx op1 = gen_reg_rtx (XFmode);
14180
14181 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14182 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14183 DONE;
14184 })
14185
14186 (define_expand "ilogbxf2"
14187 [(use (match_operand:SI 0 "register_operand" ""))
14188 (use (match_operand:XF 1 "register_operand" ""))]
14189 "TARGET_USE_FANCY_MATH_387
14190 && flag_unsafe_math_optimizations"
14191 {
14192 rtx op0, op1;
14193
14194 if (optimize_insn_for_size_p ())
14195 FAIL;
14196
14197 op0 = gen_reg_rtx (XFmode);
14198 op1 = gen_reg_rtx (XFmode);
14199
14200 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14201 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14202 DONE;
14203 })
14204
14205 (define_expand "ilogb<mode>2"
14206 [(use (match_operand:SI 0 "register_operand" ""))
14207 (use (match_operand:MODEF 1 "register_operand" ""))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14210 || TARGET_MIX_SSE_I387)
14211 && flag_unsafe_math_optimizations"
14212 {
14213 rtx op0, op1;
14214
14215 if (optimize_insn_for_size_p ())
14216 FAIL;
14217
14218 op0 = gen_reg_rtx (XFmode);
14219 op1 = gen_reg_rtx (XFmode);
14220
14221 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14222 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14223 DONE;
14224 })
14225
14226 (define_insn "*f2xm1xf2_i387"
14227 [(set (match_operand:XF 0 "register_operand" "=f")
14228 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14229 UNSPEC_F2XM1))]
14230 "TARGET_USE_FANCY_MATH_387
14231 && flag_unsafe_math_optimizations"
14232 "f2xm1"
14233 [(set_attr "type" "fpspc")
14234 (set_attr "mode" "XF")])
14235
14236 (define_insn "*fscalexf4_i387"
14237 [(set (match_operand:XF 0 "register_operand" "=f")
14238 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14239 (match_operand:XF 3 "register_operand" "1")]
14240 UNSPEC_FSCALE_FRACT))
14241 (set (match_operand:XF 1 "register_operand" "=u")
14242 (unspec:XF [(match_dup 2) (match_dup 3)]
14243 UNSPEC_FSCALE_EXP))]
14244 "TARGET_USE_FANCY_MATH_387
14245 && flag_unsafe_math_optimizations"
14246 "fscale"
14247 [(set_attr "type" "fpspc")
14248 (set_attr "mode" "XF")])
14249
14250 (define_expand "expNcorexf3"
14251 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14252 (match_operand:XF 2 "register_operand" "")))
14253 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14254 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14255 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14256 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14257 (parallel [(set (match_operand:XF 0 "register_operand" "")
14258 (unspec:XF [(match_dup 8) (match_dup 4)]
14259 UNSPEC_FSCALE_FRACT))
14260 (set (match_dup 9)
14261 (unspec:XF [(match_dup 8) (match_dup 4)]
14262 UNSPEC_FSCALE_EXP))])]
14263 "TARGET_USE_FANCY_MATH_387
14264 && flag_unsafe_math_optimizations"
14265 {
14266 int i;
14267
14268 if (optimize_insn_for_size_p ())
14269 FAIL;
14270
14271 for (i = 3; i < 10; i++)
14272 operands[i] = gen_reg_rtx (XFmode);
14273
14274 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14275 })
14276
14277 (define_expand "expxf2"
14278 [(use (match_operand:XF 0 "register_operand" ""))
14279 (use (match_operand:XF 1 "register_operand" ""))]
14280 "TARGET_USE_FANCY_MATH_387
14281 && flag_unsafe_math_optimizations"
14282 {
14283 rtx op2;
14284
14285 if (optimize_insn_for_size_p ())
14286 FAIL;
14287
14288 op2 = gen_reg_rtx (XFmode);
14289 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14290
14291 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14292 DONE;
14293 })
14294
14295 (define_expand "exp<mode>2"
14296 [(use (match_operand:MODEF 0 "register_operand" ""))
14297 (use (match_operand:MODEF 1 "general_operand" ""))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14302 {
14303 rtx op0, op1;
14304
14305 if (optimize_insn_for_size_p ())
14306 FAIL;
14307
14308 op0 = gen_reg_rtx (XFmode);
14309 op1 = gen_reg_rtx (XFmode);
14310
14311 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14312 emit_insn (gen_expxf2 (op0, op1));
14313 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14314 DONE;
14315 })
14316
14317 (define_expand "exp10xf2"
14318 [(use (match_operand:XF 0 "register_operand" ""))
14319 (use (match_operand:XF 1 "register_operand" ""))]
14320 "TARGET_USE_FANCY_MATH_387
14321 && flag_unsafe_math_optimizations"
14322 {
14323 rtx op2;
14324
14325 if (optimize_insn_for_size_p ())
14326 FAIL;
14327
14328 op2 = gen_reg_rtx (XFmode);
14329 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14330
14331 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14332 DONE;
14333 })
14334
14335 (define_expand "exp10<mode>2"
14336 [(use (match_operand:MODEF 0 "register_operand" ""))
14337 (use (match_operand:MODEF 1 "general_operand" ""))]
14338 "TARGET_USE_FANCY_MATH_387
14339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14340 || TARGET_MIX_SSE_I387)
14341 && flag_unsafe_math_optimizations"
14342 {
14343 rtx op0, op1;
14344
14345 if (optimize_insn_for_size_p ())
14346 FAIL;
14347
14348 op0 = gen_reg_rtx (XFmode);
14349 op1 = gen_reg_rtx (XFmode);
14350
14351 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14352 emit_insn (gen_exp10xf2 (op0, op1));
14353 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14354 DONE;
14355 })
14356
14357 (define_expand "exp2xf2"
14358 [(use (match_operand:XF 0 "register_operand" ""))
14359 (use (match_operand:XF 1 "register_operand" ""))]
14360 "TARGET_USE_FANCY_MATH_387
14361 && flag_unsafe_math_optimizations"
14362 {
14363 rtx op2;
14364
14365 if (optimize_insn_for_size_p ())
14366 FAIL;
14367
14368 op2 = gen_reg_rtx (XFmode);
14369 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14370
14371 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14372 DONE;
14373 })
14374
14375 (define_expand "exp2<mode>2"
14376 [(use (match_operand:MODEF 0 "register_operand" ""))
14377 (use (match_operand:MODEF 1 "general_operand" ""))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14382 {
14383 rtx op0, op1;
14384
14385 if (optimize_insn_for_size_p ())
14386 FAIL;
14387
14388 op0 = gen_reg_rtx (XFmode);
14389 op1 = gen_reg_rtx (XFmode);
14390
14391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14392 emit_insn (gen_exp2xf2 (op0, op1));
14393 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14394 DONE;
14395 })
14396
14397 (define_expand "expm1xf2"
14398 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14399 (match_dup 2)))
14400 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14401 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14402 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14403 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14404 (parallel [(set (match_dup 7)
14405 (unspec:XF [(match_dup 6) (match_dup 4)]
14406 UNSPEC_FSCALE_FRACT))
14407 (set (match_dup 8)
14408 (unspec:XF [(match_dup 6) (match_dup 4)]
14409 UNSPEC_FSCALE_EXP))])
14410 (parallel [(set (match_dup 10)
14411 (unspec:XF [(match_dup 9) (match_dup 8)]
14412 UNSPEC_FSCALE_FRACT))
14413 (set (match_dup 11)
14414 (unspec:XF [(match_dup 9) (match_dup 8)]
14415 UNSPEC_FSCALE_EXP))])
14416 (set (match_dup 12) (minus:XF (match_dup 10)
14417 (float_extend:XF (match_dup 13))))
14418 (set (match_operand:XF 0 "register_operand" "")
14419 (plus:XF (match_dup 12) (match_dup 7)))]
14420 "TARGET_USE_FANCY_MATH_387
14421 && flag_unsafe_math_optimizations"
14422 {
14423 int i;
14424
14425 if (optimize_insn_for_size_p ())
14426 FAIL;
14427
14428 for (i = 2; i < 13; i++)
14429 operands[i] = gen_reg_rtx (XFmode);
14430
14431 operands[13]
14432 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14433
14434 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14435 })
14436
14437 (define_expand "expm1<mode>2"
14438 [(use (match_operand:MODEF 0 "register_operand" ""))
14439 (use (match_operand:MODEF 1 "general_operand" ""))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14442 || TARGET_MIX_SSE_I387)
14443 && flag_unsafe_math_optimizations"
14444 {
14445 rtx op0, op1;
14446
14447 if (optimize_insn_for_size_p ())
14448 FAIL;
14449
14450 op0 = gen_reg_rtx (XFmode);
14451 op1 = gen_reg_rtx (XFmode);
14452
14453 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14454 emit_insn (gen_expm1xf2 (op0, op1));
14455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14456 DONE;
14457 })
14458
14459 (define_expand "ldexpxf3"
14460 [(set (match_dup 3)
14461 (float:XF (match_operand:SI 2 "register_operand" "")))
14462 (parallel [(set (match_operand:XF 0 " register_operand" "")
14463 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14464 (match_dup 3)]
14465 UNSPEC_FSCALE_FRACT))
14466 (set (match_dup 4)
14467 (unspec:XF [(match_dup 1) (match_dup 3)]
14468 UNSPEC_FSCALE_EXP))])]
14469 "TARGET_USE_FANCY_MATH_387
14470 && flag_unsafe_math_optimizations"
14471 {
14472 if (optimize_insn_for_size_p ())
14473 FAIL;
14474
14475 operands[3] = gen_reg_rtx (XFmode);
14476 operands[4] = gen_reg_rtx (XFmode);
14477 })
14478
14479 (define_expand "ldexp<mode>3"
14480 [(use (match_operand:MODEF 0 "register_operand" ""))
14481 (use (match_operand:MODEF 1 "general_operand" ""))
14482 (use (match_operand:SI 2 "register_operand" ""))]
14483 "TARGET_USE_FANCY_MATH_387
14484 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14485 || TARGET_MIX_SSE_I387)
14486 && flag_unsafe_math_optimizations"
14487 {
14488 rtx op0, op1;
14489
14490 if (optimize_insn_for_size_p ())
14491 FAIL;
14492
14493 op0 = gen_reg_rtx (XFmode);
14494 op1 = gen_reg_rtx (XFmode);
14495
14496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14497 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14498 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14499 DONE;
14500 })
14501
14502 (define_expand "scalbxf3"
14503 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14504 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14505 (match_operand:XF 2 "register_operand" "")]
14506 UNSPEC_FSCALE_FRACT))
14507 (set (match_dup 3)
14508 (unspec:XF [(match_dup 1) (match_dup 2)]
14509 UNSPEC_FSCALE_EXP))])]
14510 "TARGET_USE_FANCY_MATH_387
14511 && flag_unsafe_math_optimizations"
14512 {
14513 if (optimize_insn_for_size_p ())
14514 FAIL;
14515
14516 operands[3] = gen_reg_rtx (XFmode);
14517 })
14518
14519 (define_expand "scalb<mode>3"
14520 [(use (match_operand:MODEF 0 "register_operand" ""))
14521 (use (match_operand:MODEF 1 "general_operand" ""))
14522 (use (match_operand:MODEF 2 "general_operand" ""))]
14523 "TARGET_USE_FANCY_MATH_387
14524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14525 || TARGET_MIX_SSE_I387)
14526 && flag_unsafe_math_optimizations"
14527 {
14528 rtx op0, op1, op2;
14529
14530 if (optimize_insn_for_size_p ())
14531 FAIL;
14532
14533 op0 = gen_reg_rtx (XFmode);
14534 op1 = gen_reg_rtx (XFmode);
14535 op2 = gen_reg_rtx (XFmode);
14536
14537 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14538 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14539 emit_insn (gen_scalbxf3 (op0, op1, op2));
14540 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14541 DONE;
14542 })
14543
14544 (define_expand "significandxf2"
14545 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14546 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14547 UNSPEC_XTRACT_FRACT))
14548 (set (match_dup 2)
14549 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14550 "TARGET_USE_FANCY_MATH_387
14551 && flag_unsafe_math_optimizations"
14552 "operands[2] = gen_reg_rtx (XFmode);")
14553
14554 (define_expand "significand<mode>2"
14555 [(use (match_operand:MODEF 0 "register_operand" ""))
14556 (use (match_operand:MODEF 1 "register_operand" ""))]
14557 "TARGET_USE_FANCY_MATH_387
14558 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14559 || TARGET_MIX_SSE_I387)
14560 && flag_unsafe_math_optimizations"
14561 {
14562 rtx op0 = gen_reg_rtx (XFmode);
14563 rtx op1 = gen_reg_rtx (XFmode);
14564
14565 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14566 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14567 DONE;
14568 })
14569 \f
14570
14571 (define_insn "sse4_1_round<mode>2"
14572 [(set (match_operand:MODEF 0 "register_operand" "=x")
14573 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14574 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14575 UNSPEC_ROUND))]
14576 "TARGET_ROUND"
14577 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14578 [(set_attr "type" "ssecvt")
14579 (set_attr "prefix_extra" "1")
14580 (set_attr "prefix" "maybe_vex")
14581 (set_attr "mode" "<MODE>")])
14582
14583 (define_insn "rintxf2"
14584 [(set (match_operand:XF 0 "register_operand" "=f")
14585 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14586 UNSPEC_FRNDINT))]
14587 "TARGET_USE_FANCY_MATH_387
14588 && flag_unsafe_math_optimizations"
14589 "frndint"
14590 [(set_attr "type" "fpspc")
14591 (set_attr "mode" "XF")])
14592
14593 (define_expand "rint<mode>2"
14594 [(use (match_operand:MODEF 0 "register_operand" ""))
14595 (use (match_operand:MODEF 1 "register_operand" ""))]
14596 "(TARGET_USE_FANCY_MATH_387
14597 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14598 || TARGET_MIX_SSE_I387)
14599 && flag_unsafe_math_optimizations)
14600 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14601 && !flag_trapping_math)"
14602 {
14603 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14604 && !flag_trapping_math)
14605 {
14606 if (TARGET_ROUND)
14607 emit_insn (gen_sse4_1_round<mode>2
14608 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14609 else if (optimize_insn_for_size_p ())
14610 FAIL;
14611 else
14612 ix86_expand_rint (operands[0], operands[1]);
14613 }
14614 else
14615 {
14616 rtx op0 = gen_reg_rtx (XFmode);
14617 rtx op1 = gen_reg_rtx (XFmode);
14618
14619 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14620 emit_insn (gen_rintxf2 (op0, op1));
14621
14622 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14623 }
14624 DONE;
14625 })
14626
14627 (define_expand "round<mode>2"
14628 [(match_operand:X87MODEF 0 "register_operand" "")
14629 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14630 "(TARGET_USE_FANCY_MATH_387
14631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14632 || TARGET_MIX_SSE_I387)
14633 && flag_unsafe_math_optimizations)
14634 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14635 && !flag_trapping_math && !flag_rounding_math)"
14636 {
14637 if (optimize_insn_for_size_p ())
14638 FAIL;
14639
14640 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14641 && !flag_trapping_math && !flag_rounding_math)
14642 {
14643 if (TARGET_ROUND)
14644 {
14645 operands[1] = force_reg (<MODE>mode, operands[1]);
14646 ix86_expand_round_sse4 (operands[0], operands[1]);
14647 }
14648 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14649 ix86_expand_round (operands[0], operands[1]);
14650 else
14651 ix86_expand_rounddf_32 (operands[0], operands[1]);
14652 }
14653 else
14654 {
14655 operands[1] = force_reg (<MODE>mode, operands[1]);
14656 ix86_emit_i387_round (operands[0], operands[1]);
14657 }
14658 DONE;
14659 })
14660
14661 (define_insn_and_split "*fistdi2_1"
14662 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14663 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14664 UNSPEC_FIST))]
14665 "TARGET_USE_FANCY_MATH_387
14666 && can_create_pseudo_p ()"
14667 "#"
14668 "&& 1"
14669 [(const_int 0)]
14670 {
14671 if (memory_operand (operands[0], VOIDmode))
14672 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14673 else
14674 {
14675 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14676 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14677 operands[2]));
14678 }
14679 DONE;
14680 }
14681 [(set_attr "type" "fpspc")
14682 (set_attr "mode" "DI")])
14683
14684 (define_insn "fistdi2"
14685 [(set (match_operand:DI 0 "memory_operand" "=m")
14686 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14687 UNSPEC_FIST))
14688 (clobber (match_scratch:XF 2 "=&1f"))]
14689 "TARGET_USE_FANCY_MATH_387"
14690 "* return output_fix_trunc (insn, operands, false);"
14691 [(set_attr "type" "fpspc")
14692 (set_attr "mode" "DI")])
14693
14694 (define_insn "fistdi2_with_temp"
14695 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14696 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14697 UNSPEC_FIST))
14698 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14699 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14700 "TARGET_USE_FANCY_MATH_387"
14701 "#"
14702 [(set_attr "type" "fpspc")
14703 (set_attr "mode" "DI")])
14704
14705 (define_split
14706 [(set (match_operand:DI 0 "register_operand" "")
14707 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14708 UNSPEC_FIST))
14709 (clobber (match_operand:DI 2 "memory_operand" ""))
14710 (clobber (match_scratch 3 ""))]
14711 "reload_completed"
14712 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14713 (clobber (match_dup 3))])
14714 (set (match_dup 0) (match_dup 2))])
14715
14716 (define_split
14717 [(set (match_operand:DI 0 "memory_operand" "")
14718 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14719 UNSPEC_FIST))
14720 (clobber (match_operand:DI 2 "memory_operand" ""))
14721 (clobber (match_scratch 3 ""))]
14722 "reload_completed"
14723 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14724 (clobber (match_dup 3))])])
14725
14726 (define_insn_and_split "*fist<mode>2_1"
14727 [(set (match_operand:SWI24 0 "register_operand" "")
14728 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14729 UNSPEC_FIST))]
14730 "TARGET_USE_FANCY_MATH_387
14731 && can_create_pseudo_p ()"
14732 "#"
14733 "&& 1"
14734 [(const_int 0)]
14735 {
14736 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14737 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14738 operands[2]));
14739 DONE;
14740 }
14741 [(set_attr "type" "fpspc")
14742 (set_attr "mode" "<MODE>")])
14743
14744 (define_insn "fist<mode>2"
14745 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14746 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14747 UNSPEC_FIST))]
14748 "TARGET_USE_FANCY_MATH_387"
14749 "* return output_fix_trunc (insn, operands, false);"
14750 [(set_attr "type" "fpspc")
14751 (set_attr "mode" "<MODE>")])
14752
14753 (define_insn "fist<mode>2_with_temp"
14754 [(set (match_operand:SWI24 0 "register_operand" "=r")
14755 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14756 UNSPEC_FIST))
14757 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14758 "TARGET_USE_FANCY_MATH_387"
14759 "#"
14760 [(set_attr "type" "fpspc")
14761 (set_attr "mode" "<MODE>")])
14762
14763 (define_split
14764 [(set (match_operand:SWI24 0 "register_operand" "")
14765 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14766 UNSPEC_FIST))
14767 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14768 "reload_completed"
14769 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14770 (set (match_dup 0) (match_dup 2))])
14771
14772 (define_split
14773 [(set (match_operand:SWI24 0 "memory_operand" "")
14774 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14775 UNSPEC_FIST))
14776 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14777 "reload_completed"
14778 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14779
14780 (define_expand "lrintxf<mode>2"
14781 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14782 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14783 UNSPEC_FIST))]
14784 "TARGET_USE_FANCY_MATH_387")
14785
14786 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14787 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14788 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14789 UNSPEC_FIX_NOTRUNC))]
14790 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14791 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14792
14793 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14794 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14795 (match_operand:X87MODEF 1 "register_operand" "")]
14796 "(TARGET_USE_FANCY_MATH_387
14797 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14798 || TARGET_MIX_SSE_I387)
14799 && flag_unsafe_math_optimizations)
14800 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14801 && <SWI248x:MODE>mode != HImode
14802 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14803 && !flag_trapping_math && !flag_rounding_math)"
14804 {
14805 if (optimize_insn_for_size_p ())
14806 FAIL;
14807
14808 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14809 && <SWI248x:MODE>mode != HImode
14810 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14811 && !flag_trapping_math && !flag_rounding_math)
14812 ix86_expand_lround (operands[0], operands[1]);
14813 else
14814 ix86_emit_i387_round (operands[0], operands[1]);
14815 DONE;
14816 })
14817
14818 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14819 (define_insn_and_split "frndintxf2_floor"
14820 [(set (match_operand:XF 0 "register_operand" "")
14821 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14822 UNSPEC_FRNDINT_FLOOR))
14823 (clobber (reg:CC FLAGS_REG))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations
14826 && can_create_pseudo_p ()"
14827 "#"
14828 "&& 1"
14829 [(const_int 0)]
14830 {
14831 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14832
14833 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14834 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14835
14836 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14837 operands[2], operands[3]));
14838 DONE;
14839 }
14840 [(set_attr "type" "frndint")
14841 (set_attr "i387_cw" "floor")
14842 (set_attr "mode" "XF")])
14843
14844 (define_insn "frndintxf2_floor_i387"
14845 [(set (match_operand:XF 0 "register_operand" "=f")
14846 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14847 UNSPEC_FRNDINT_FLOOR))
14848 (use (match_operand:HI 2 "memory_operand" "m"))
14849 (use (match_operand:HI 3 "memory_operand" "m"))]
14850 "TARGET_USE_FANCY_MATH_387
14851 && flag_unsafe_math_optimizations"
14852 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14853 [(set_attr "type" "frndint")
14854 (set_attr "i387_cw" "floor")
14855 (set_attr "mode" "XF")])
14856
14857 (define_expand "floorxf2"
14858 [(use (match_operand:XF 0 "register_operand" ""))
14859 (use (match_operand:XF 1 "register_operand" ""))]
14860 "TARGET_USE_FANCY_MATH_387
14861 && flag_unsafe_math_optimizations"
14862 {
14863 if (optimize_insn_for_size_p ())
14864 FAIL;
14865 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14866 DONE;
14867 })
14868
14869 (define_expand "floor<mode>2"
14870 [(use (match_operand:MODEF 0 "register_operand" ""))
14871 (use (match_operand:MODEF 1 "register_operand" ""))]
14872 "(TARGET_USE_FANCY_MATH_387
14873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14874 || TARGET_MIX_SSE_I387)
14875 && flag_unsafe_math_optimizations)
14876 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14877 && !flag_trapping_math)"
14878 {
14879 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14880 && !flag_trapping_math)
14881 {
14882 if (TARGET_ROUND)
14883 emit_insn (gen_sse4_1_round<mode>2
14884 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14885 else if (optimize_insn_for_size_p ())
14886 FAIL;
14887 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14888 ix86_expand_floorceil (operands[0], operands[1], true);
14889 else
14890 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14891 }
14892 else
14893 {
14894 rtx op0, op1;
14895
14896 if (optimize_insn_for_size_p ())
14897 FAIL;
14898
14899 op0 = gen_reg_rtx (XFmode);
14900 op1 = gen_reg_rtx (XFmode);
14901 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14902 emit_insn (gen_frndintxf2_floor (op0, op1));
14903
14904 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14905 }
14906 DONE;
14907 })
14908
14909 (define_insn_and_split "*fist<mode>2_floor_1"
14910 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14911 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14912 UNSPEC_FIST_FLOOR))
14913 (clobber (reg:CC FLAGS_REG))]
14914 "TARGET_USE_FANCY_MATH_387
14915 && flag_unsafe_math_optimizations
14916 && can_create_pseudo_p ()"
14917 "#"
14918 "&& 1"
14919 [(const_int 0)]
14920 {
14921 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14922
14923 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14924 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14925 if (memory_operand (operands[0], VOIDmode))
14926 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14927 operands[2], operands[3]));
14928 else
14929 {
14930 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14931 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14932 operands[2], operands[3],
14933 operands[4]));
14934 }
14935 DONE;
14936 }
14937 [(set_attr "type" "fistp")
14938 (set_attr "i387_cw" "floor")
14939 (set_attr "mode" "<MODE>")])
14940
14941 (define_insn "fistdi2_floor"
14942 [(set (match_operand:DI 0 "memory_operand" "=m")
14943 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14944 UNSPEC_FIST_FLOOR))
14945 (use (match_operand:HI 2 "memory_operand" "m"))
14946 (use (match_operand:HI 3 "memory_operand" "m"))
14947 (clobber (match_scratch:XF 4 "=&1f"))]
14948 "TARGET_USE_FANCY_MATH_387
14949 && flag_unsafe_math_optimizations"
14950 "* return output_fix_trunc (insn, operands, false);"
14951 [(set_attr "type" "fistp")
14952 (set_attr "i387_cw" "floor")
14953 (set_attr "mode" "DI")])
14954
14955 (define_insn "fistdi2_floor_with_temp"
14956 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14957 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14958 UNSPEC_FIST_FLOOR))
14959 (use (match_operand:HI 2 "memory_operand" "m,m"))
14960 (use (match_operand:HI 3 "memory_operand" "m,m"))
14961 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14962 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14963 "TARGET_USE_FANCY_MATH_387
14964 && flag_unsafe_math_optimizations"
14965 "#"
14966 [(set_attr "type" "fistp")
14967 (set_attr "i387_cw" "floor")
14968 (set_attr "mode" "DI")])
14969
14970 (define_split
14971 [(set (match_operand:DI 0 "register_operand" "")
14972 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14973 UNSPEC_FIST_FLOOR))
14974 (use (match_operand:HI 2 "memory_operand" ""))
14975 (use (match_operand:HI 3 "memory_operand" ""))
14976 (clobber (match_operand:DI 4 "memory_operand" ""))
14977 (clobber (match_scratch 5 ""))]
14978 "reload_completed"
14979 [(parallel [(set (match_dup 4)
14980 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14981 (use (match_dup 2))
14982 (use (match_dup 3))
14983 (clobber (match_dup 5))])
14984 (set (match_dup 0) (match_dup 4))])
14985
14986 (define_split
14987 [(set (match_operand:DI 0 "memory_operand" "")
14988 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14989 UNSPEC_FIST_FLOOR))
14990 (use (match_operand:HI 2 "memory_operand" ""))
14991 (use (match_operand:HI 3 "memory_operand" ""))
14992 (clobber (match_operand:DI 4 "memory_operand" ""))
14993 (clobber (match_scratch 5 ""))]
14994 "reload_completed"
14995 [(parallel [(set (match_dup 0)
14996 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14997 (use (match_dup 2))
14998 (use (match_dup 3))
14999 (clobber (match_dup 5))])])
15000
15001 (define_insn "fist<mode>2_floor"
15002 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15003 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15004 UNSPEC_FIST_FLOOR))
15005 (use (match_operand:HI 2 "memory_operand" "m"))
15006 (use (match_operand:HI 3 "memory_operand" "m"))]
15007 "TARGET_USE_FANCY_MATH_387
15008 && flag_unsafe_math_optimizations"
15009 "* return output_fix_trunc (insn, operands, false);"
15010 [(set_attr "type" "fistp")
15011 (set_attr "i387_cw" "floor")
15012 (set_attr "mode" "<MODE>")])
15013
15014 (define_insn "fist<mode>2_floor_with_temp"
15015 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15016 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15017 UNSPEC_FIST_FLOOR))
15018 (use (match_operand:HI 2 "memory_operand" "m,m"))
15019 (use (match_operand:HI 3 "memory_operand" "m,m"))
15020 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15021 "TARGET_USE_FANCY_MATH_387
15022 && flag_unsafe_math_optimizations"
15023 "#"
15024 [(set_attr "type" "fistp")
15025 (set_attr "i387_cw" "floor")
15026 (set_attr "mode" "<MODE>")])
15027
15028 (define_split
15029 [(set (match_operand:SWI24 0 "register_operand" "")
15030 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15031 UNSPEC_FIST_FLOOR))
15032 (use (match_operand:HI 2 "memory_operand" ""))
15033 (use (match_operand:HI 3 "memory_operand" ""))
15034 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15035 "reload_completed"
15036 [(parallel [(set (match_dup 4)
15037 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15038 (use (match_dup 2))
15039 (use (match_dup 3))])
15040 (set (match_dup 0) (match_dup 4))])
15041
15042 (define_split
15043 [(set (match_operand:SWI24 0 "memory_operand" "")
15044 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15045 UNSPEC_FIST_FLOOR))
15046 (use (match_operand:HI 2 "memory_operand" ""))
15047 (use (match_operand:HI 3 "memory_operand" ""))
15048 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15049 "reload_completed"
15050 [(parallel [(set (match_dup 0)
15051 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15052 (use (match_dup 2))
15053 (use (match_dup 3))])])
15054
15055 (define_expand "lfloorxf<mode>2"
15056 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15057 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15058 UNSPEC_FIST_FLOOR))
15059 (clobber (reg:CC FLAGS_REG))])]
15060 "TARGET_USE_FANCY_MATH_387
15061 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15062 && flag_unsafe_math_optimizations")
15063
15064 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15065 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15066 (match_operand:MODEF 1 "register_operand" "")]
15067 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15068 && !flag_trapping_math"
15069 {
15070 if (TARGET_64BIT && optimize_insn_for_size_p ())
15071 FAIL;
15072 ix86_expand_lfloorceil (operands[0], operands[1], true);
15073 DONE;
15074 })
15075
15076 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15077 (define_insn_and_split "frndintxf2_ceil"
15078 [(set (match_operand:XF 0 "register_operand" "")
15079 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15080 UNSPEC_FRNDINT_CEIL))
15081 (clobber (reg:CC FLAGS_REG))]
15082 "TARGET_USE_FANCY_MATH_387
15083 && flag_unsafe_math_optimizations
15084 && can_create_pseudo_p ()"
15085 "#"
15086 "&& 1"
15087 [(const_int 0)]
15088 {
15089 ix86_optimize_mode_switching[I387_CEIL] = 1;
15090
15091 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15092 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15093
15094 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15095 operands[2], operands[3]));
15096 DONE;
15097 }
15098 [(set_attr "type" "frndint")
15099 (set_attr "i387_cw" "ceil")
15100 (set_attr "mode" "XF")])
15101
15102 (define_insn "frndintxf2_ceil_i387"
15103 [(set (match_operand:XF 0 "register_operand" "=f")
15104 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15105 UNSPEC_FRNDINT_CEIL))
15106 (use (match_operand:HI 2 "memory_operand" "m"))
15107 (use (match_operand:HI 3 "memory_operand" "m"))]
15108 "TARGET_USE_FANCY_MATH_387
15109 && flag_unsafe_math_optimizations"
15110 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15111 [(set_attr "type" "frndint")
15112 (set_attr "i387_cw" "ceil")
15113 (set_attr "mode" "XF")])
15114
15115 (define_expand "ceilxf2"
15116 [(use (match_operand:XF 0 "register_operand" ""))
15117 (use (match_operand:XF 1 "register_operand" ""))]
15118 "TARGET_USE_FANCY_MATH_387
15119 && flag_unsafe_math_optimizations"
15120 {
15121 if (optimize_insn_for_size_p ())
15122 FAIL;
15123 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15124 DONE;
15125 })
15126
15127 (define_expand "ceil<mode>2"
15128 [(use (match_operand:MODEF 0 "register_operand" ""))
15129 (use (match_operand:MODEF 1 "register_operand" ""))]
15130 "(TARGET_USE_FANCY_MATH_387
15131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15132 || TARGET_MIX_SSE_I387)
15133 && flag_unsafe_math_optimizations)
15134 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15135 && !flag_trapping_math)"
15136 {
15137 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15138 && !flag_trapping_math)
15139 {
15140 if (TARGET_ROUND)
15141 emit_insn (gen_sse4_1_round<mode>2
15142 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15143 else if (optimize_insn_for_size_p ())
15144 FAIL;
15145 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15146 ix86_expand_floorceil (operands[0], operands[1], false);
15147 else
15148 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15149 }
15150 else
15151 {
15152 rtx op0, op1;
15153
15154 if (optimize_insn_for_size_p ())
15155 FAIL;
15156
15157 op0 = gen_reg_rtx (XFmode);
15158 op1 = gen_reg_rtx (XFmode);
15159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15160 emit_insn (gen_frndintxf2_ceil (op0, op1));
15161
15162 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15163 }
15164 DONE;
15165 })
15166
15167 (define_insn_and_split "*fist<mode>2_ceil_1"
15168 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15169 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15170 UNSPEC_FIST_CEIL))
15171 (clobber (reg:CC FLAGS_REG))]
15172 "TARGET_USE_FANCY_MATH_387
15173 && flag_unsafe_math_optimizations
15174 && can_create_pseudo_p ()"
15175 "#"
15176 "&& 1"
15177 [(const_int 0)]
15178 {
15179 ix86_optimize_mode_switching[I387_CEIL] = 1;
15180
15181 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15182 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15183 if (memory_operand (operands[0], VOIDmode))
15184 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15185 operands[2], operands[3]));
15186 else
15187 {
15188 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15189 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15190 operands[2], operands[3],
15191 operands[4]));
15192 }
15193 DONE;
15194 }
15195 [(set_attr "type" "fistp")
15196 (set_attr "i387_cw" "ceil")
15197 (set_attr "mode" "<MODE>")])
15198
15199 (define_insn "fistdi2_ceil"
15200 [(set (match_operand:DI 0 "memory_operand" "=m")
15201 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15202 UNSPEC_FIST_CEIL))
15203 (use (match_operand:HI 2 "memory_operand" "m"))
15204 (use (match_operand:HI 3 "memory_operand" "m"))
15205 (clobber (match_scratch:XF 4 "=&1f"))]
15206 "TARGET_USE_FANCY_MATH_387
15207 && flag_unsafe_math_optimizations"
15208 "* return output_fix_trunc (insn, operands, false);"
15209 [(set_attr "type" "fistp")
15210 (set_attr "i387_cw" "ceil")
15211 (set_attr "mode" "DI")])
15212
15213 (define_insn "fistdi2_ceil_with_temp"
15214 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15215 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15216 UNSPEC_FIST_CEIL))
15217 (use (match_operand:HI 2 "memory_operand" "m,m"))
15218 (use (match_operand:HI 3 "memory_operand" "m,m"))
15219 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15220 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15221 "TARGET_USE_FANCY_MATH_387
15222 && flag_unsafe_math_optimizations"
15223 "#"
15224 [(set_attr "type" "fistp")
15225 (set_attr "i387_cw" "ceil")
15226 (set_attr "mode" "DI")])
15227
15228 (define_split
15229 [(set (match_operand:DI 0 "register_operand" "")
15230 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15231 UNSPEC_FIST_CEIL))
15232 (use (match_operand:HI 2 "memory_operand" ""))
15233 (use (match_operand:HI 3 "memory_operand" ""))
15234 (clobber (match_operand:DI 4 "memory_operand" ""))
15235 (clobber (match_scratch 5 ""))]
15236 "reload_completed"
15237 [(parallel [(set (match_dup 4)
15238 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15239 (use (match_dup 2))
15240 (use (match_dup 3))
15241 (clobber (match_dup 5))])
15242 (set (match_dup 0) (match_dup 4))])
15243
15244 (define_split
15245 [(set (match_operand:DI 0 "memory_operand" "")
15246 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15247 UNSPEC_FIST_CEIL))
15248 (use (match_operand:HI 2 "memory_operand" ""))
15249 (use (match_operand:HI 3 "memory_operand" ""))
15250 (clobber (match_operand:DI 4 "memory_operand" ""))
15251 (clobber (match_scratch 5 ""))]
15252 "reload_completed"
15253 [(parallel [(set (match_dup 0)
15254 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15255 (use (match_dup 2))
15256 (use (match_dup 3))
15257 (clobber (match_dup 5))])])
15258
15259 (define_insn "fist<mode>2_ceil"
15260 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15261 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15262 UNSPEC_FIST_CEIL))
15263 (use (match_operand:HI 2 "memory_operand" "m"))
15264 (use (match_operand:HI 3 "memory_operand" "m"))]
15265 "TARGET_USE_FANCY_MATH_387
15266 && flag_unsafe_math_optimizations"
15267 "* return output_fix_trunc (insn, operands, false);"
15268 [(set_attr "type" "fistp")
15269 (set_attr "i387_cw" "ceil")
15270 (set_attr "mode" "<MODE>")])
15271
15272 (define_insn "fist<mode>2_ceil_with_temp"
15273 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15274 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15275 UNSPEC_FIST_CEIL))
15276 (use (match_operand:HI 2 "memory_operand" "m,m"))
15277 (use (match_operand:HI 3 "memory_operand" "m,m"))
15278 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15279 "TARGET_USE_FANCY_MATH_387
15280 && flag_unsafe_math_optimizations"
15281 "#"
15282 [(set_attr "type" "fistp")
15283 (set_attr "i387_cw" "ceil")
15284 (set_attr "mode" "<MODE>")])
15285
15286 (define_split
15287 [(set (match_operand:SWI24 0 "register_operand" "")
15288 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15289 UNSPEC_FIST_CEIL))
15290 (use (match_operand:HI 2 "memory_operand" ""))
15291 (use (match_operand:HI 3 "memory_operand" ""))
15292 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15293 "reload_completed"
15294 [(parallel [(set (match_dup 4)
15295 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15296 (use (match_dup 2))
15297 (use (match_dup 3))])
15298 (set (match_dup 0) (match_dup 4))])
15299
15300 (define_split
15301 [(set (match_operand:SWI24 0 "memory_operand" "")
15302 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15303 UNSPEC_FIST_CEIL))
15304 (use (match_operand:HI 2 "memory_operand" ""))
15305 (use (match_operand:HI 3 "memory_operand" ""))
15306 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15307 "reload_completed"
15308 [(parallel [(set (match_dup 0)
15309 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15310 (use (match_dup 2))
15311 (use (match_dup 3))])])
15312
15313 (define_expand "lceilxf<mode>2"
15314 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15315 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15316 UNSPEC_FIST_CEIL))
15317 (clobber (reg:CC FLAGS_REG))])]
15318 "TARGET_USE_FANCY_MATH_387
15319 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15320 && flag_unsafe_math_optimizations")
15321
15322 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15323 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15324 (match_operand:MODEF 1 "register_operand" "")]
15325 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15326 && !flag_trapping_math"
15327 {
15328 ix86_expand_lfloorceil (operands[0], operands[1], false);
15329 DONE;
15330 })
15331
15332 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15333 (define_insn_and_split "frndintxf2_trunc"
15334 [(set (match_operand:XF 0 "register_operand" "")
15335 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15336 UNSPEC_FRNDINT_TRUNC))
15337 (clobber (reg:CC FLAGS_REG))]
15338 "TARGET_USE_FANCY_MATH_387
15339 && flag_unsafe_math_optimizations
15340 && can_create_pseudo_p ()"
15341 "#"
15342 "&& 1"
15343 [(const_int 0)]
15344 {
15345 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15346
15347 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15348 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15349
15350 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15351 operands[2], operands[3]));
15352 DONE;
15353 }
15354 [(set_attr "type" "frndint")
15355 (set_attr "i387_cw" "trunc")
15356 (set_attr "mode" "XF")])
15357
15358 (define_insn "frndintxf2_trunc_i387"
15359 [(set (match_operand:XF 0 "register_operand" "=f")
15360 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15361 UNSPEC_FRNDINT_TRUNC))
15362 (use (match_operand:HI 2 "memory_operand" "m"))
15363 (use (match_operand:HI 3 "memory_operand" "m"))]
15364 "TARGET_USE_FANCY_MATH_387
15365 && flag_unsafe_math_optimizations"
15366 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15367 [(set_attr "type" "frndint")
15368 (set_attr "i387_cw" "trunc")
15369 (set_attr "mode" "XF")])
15370
15371 (define_expand "btruncxf2"
15372 [(use (match_operand:XF 0 "register_operand" ""))
15373 (use (match_operand:XF 1 "register_operand" ""))]
15374 "TARGET_USE_FANCY_MATH_387
15375 && flag_unsafe_math_optimizations"
15376 {
15377 if (optimize_insn_for_size_p ())
15378 FAIL;
15379 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15380 DONE;
15381 })
15382
15383 (define_expand "btrunc<mode>2"
15384 [(use (match_operand:MODEF 0 "register_operand" ""))
15385 (use (match_operand:MODEF 1 "register_operand" ""))]
15386 "(TARGET_USE_FANCY_MATH_387
15387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15388 || TARGET_MIX_SSE_I387)
15389 && flag_unsafe_math_optimizations)
15390 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15391 && !flag_trapping_math)"
15392 {
15393 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15394 && !flag_trapping_math)
15395 {
15396 if (TARGET_ROUND)
15397 emit_insn (gen_sse4_1_round<mode>2
15398 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15399 else if (optimize_insn_for_size_p ())
15400 FAIL;
15401 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15402 ix86_expand_trunc (operands[0], operands[1]);
15403 else
15404 ix86_expand_truncdf_32 (operands[0], operands[1]);
15405 }
15406 else
15407 {
15408 rtx op0, op1;
15409
15410 if (optimize_insn_for_size_p ())
15411 FAIL;
15412
15413 op0 = gen_reg_rtx (XFmode);
15414 op1 = gen_reg_rtx (XFmode);
15415 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15416 emit_insn (gen_frndintxf2_trunc (op0, op1));
15417
15418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15419 }
15420 DONE;
15421 })
15422
15423 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15424 (define_insn_and_split "frndintxf2_mask_pm"
15425 [(set (match_operand:XF 0 "register_operand" "")
15426 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15427 UNSPEC_FRNDINT_MASK_PM))
15428 (clobber (reg:CC FLAGS_REG))]
15429 "TARGET_USE_FANCY_MATH_387
15430 && flag_unsafe_math_optimizations
15431 && can_create_pseudo_p ()"
15432 "#"
15433 "&& 1"
15434 [(const_int 0)]
15435 {
15436 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15437
15438 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15439 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15440
15441 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15442 operands[2], operands[3]));
15443 DONE;
15444 }
15445 [(set_attr "type" "frndint")
15446 (set_attr "i387_cw" "mask_pm")
15447 (set_attr "mode" "XF")])
15448
15449 (define_insn "frndintxf2_mask_pm_i387"
15450 [(set (match_operand:XF 0 "register_operand" "=f")
15451 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15452 UNSPEC_FRNDINT_MASK_PM))
15453 (use (match_operand:HI 2 "memory_operand" "m"))
15454 (use (match_operand:HI 3 "memory_operand" "m"))]
15455 "TARGET_USE_FANCY_MATH_387
15456 && flag_unsafe_math_optimizations"
15457 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15458 [(set_attr "type" "frndint")
15459 (set_attr "i387_cw" "mask_pm")
15460 (set_attr "mode" "XF")])
15461
15462 (define_expand "nearbyintxf2"
15463 [(use (match_operand:XF 0 "register_operand" ""))
15464 (use (match_operand:XF 1 "register_operand" ""))]
15465 "TARGET_USE_FANCY_MATH_387
15466 && flag_unsafe_math_optimizations"
15467 {
15468 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15469 DONE;
15470 })
15471
15472 (define_expand "nearbyint<mode>2"
15473 [(use (match_operand:MODEF 0 "register_operand" ""))
15474 (use (match_operand:MODEF 1 "register_operand" ""))]
15475 "TARGET_USE_FANCY_MATH_387
15476 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15477 || TARGET_MIX_SSE_I387)
15478 && flag_unsafe_math_optimizations"
15479 {
15480 rtx op0 = gen_reg_rtx (XFmode);
15481 rtx op1 = gen_reg_rtx (XFmode);
15482
15483 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15484 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15485
15486 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15487 DONE;
15488 })
15489
15490 (define_insn "fxam<mode>2_i387"
15491 [(set (match_operand:HI 0 "register_operand" "=a")
15492 (unspec:HI
15493 [(match_operand:X87MODEF 1 "register_operand" "f")]
15494 UNSPEC_FXAM))]
15495 "TARGET_USE_FANCY_MATH_387"
15496 "fxam\n\tfnstsw\t%0"
15497 [(set_attr "type" "multi")
15498 (set_attr "length" "4")
15499 (set_attr "unit" "i387")
15500 (set_attr "mode" "<MODE>")])
15501
15502 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15503 [(set (match_operand:HI 0 "register_operand" "")
15504 (unspec:HI
15505 [(match_operand:MODEF 1 "memory_operand" "")]
15506 UNSPEC_FXAM_MEM))]
15507 "TARGET_USE_FANCY_MATH_387
15508 && can_create_pseudo_p ()"
15509 "#"
15510 "&& 1"
15511 [(set (match_dup 2)(match_dup 1))
15512 (set (match_dup 0)
15513 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15514 {
15515 operands[2] = gen_reg_rtx (<MODE>mode);
15516
15517 MEM_VOLATILE_P (operands[1]) = 1;
15518 }
15519 [(set_attr "type" "multi")
15520 (set_attr "unit" "i387")
15521 (set_attr "mode" "<MODE>")])
15522
15523 (define_expand "isinfxf2"
15524 [(use (match_operand:SI 0 "register_operand" ""))
15525 (use (match_operand:XF 1 "register_operand" ""))]
15526 "TARGET_USE_FANCY_MATH_387
15527 && TARGET_C99_FUNCTIONS"
15528 {
15529 rtx mask = GEN_INT (0x45);
15530 rtx val = GEN_INT (0x05);
15531
15532 rtx cond;
15533
15534 rtx scratch = gen_reg_rtx (HImode);
15535 rtx res = gen_reg_rtx (QImode);
15536
15537 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15538
15539 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15540 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15541 cond = gen_rtx_fmt_ee (EQ, QImode,
15542 gen_rtx_REG (CCmode, FLAGS_REG),
15543 const0_rtx);
15544 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15545 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15546 DONE;
15547 })
15548
15549 (define_expand "isinf<mode>2"
15550 [(use (match_operand:SI 0 "register_operand" ""))
15551 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15552 "TARGET_USE_FANCY_MATH_387
15553 && TARGET_C99_FUNCTIONS
15554 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15555 {
15556 rtx mask = GEN_INT (0x45);
15557 rtx val = GEN_INT (0x05);
15558
15559 rtx cond;
15560
15561 rtx scratch = gen_reg_rtx (HImode);
15562 rtx res = gen_reg_rtx (QImode);
15563
15564 /* Remove excess precision by forcing value through memory. */
15565 if (memory_operand (operands[1], VOIDmode))
15566 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15567 else
15568 {
15569 enum ix86_stack_slot slot = (virtuals_instantiated
15570 ? SLOT_TEMP
15571 : SLOT_VIRTUAL);
15572 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15573
15574 emit_move_insn (temp, operands[1]);
15575 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15576 }
15577
15578 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15579 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15580 cond = gen_rtx_fmt_ee (EQ, QImode,
15581 gen_rtx_REG (CCmode, FLAGS_REG),
15582 const0_rtx);
15583 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15584 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15585 DONE;
15586 })
15587
15588 (define_expand "signbitxf2"
15589 [(use (match_operand:SI 0 "register_operand" ""))
15590 (use (match_operand:XF 1 "register_operand" ""))]
15591 "TARGET_USE_FANCY_MATH_387"
15592 {
15593 rtx scratch = gen_reg_rtx (HImode);
15594
15595 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15596 emit_insn (gen_andsi3 (operands[0],
15597 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15598 DONE;
15599 })
15600
15601 (define_insn "movmsk_df"
15602 [(set (match_operand:SI 0 "register_operand" "=r")
15603 (unspec:SI
15604 [(match_operand:DF 1 "register_operand" "x")]
15605 UNSPEC_MOVMSK))]
15606 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15607 "%vmovmskpd\t{%1, %0|%0, %1}"
15608 [(set_attr "type" "ssemov")
15609 (set_attr "prefix" "maybe_vex")
15610 (set_attr "mode" "DF")])
15611
15612 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15613 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15614 (define_expand "signbitdf2"
15615 [(use (match_operand:SI 0 "register_operand" ""))
15616 (use (match_operand:DF 1 "register_operand" ""))]
15617 "TARGET_USE_FANCY_MATH_387
15618 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15619 {
15620 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15621 {
15622 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15623 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15624 }
15625 else
15626 {
15627 rtx scratch = gen_reg_rtx (HImode);
15628
15629 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15630 emit_insn (gen_andsi3 (operands[0],
15631 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15632 }
15633 DONE;
15634 })
15635
15636 (define_expand "signbitsf2"
15637 [(use (match_operand:SI 0 "register_operand" ""))
15638 (use (match_operand:SF 1 "register_operand" ""))]
15639 "TARGET_USE_FANCY_MATH_387
15640 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15641 {
15642 rtx scratch = gen_reg_rtx (HImode);
15643
15644 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15645 emit_insn (gen_andsi3 (operands[0],
15646 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15647 DONE;
15648 })
15649 \f
15650 ;; Block operation instructions
15651
15652 (define_insn "cld"
15653 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15654 ""
15655 "cld"
15656 [(set_attr "length" "1")
15657 (set_attr "length_immediate" "0")
15658 (set_attr "modrm" "0")])
15659
15660 (define_expand "movmem<mode>"
15661 [(use (match_operand:BLK 0 "memory_operand" ""))
15662 (use (match_operand:BLK 1 "memory_operand" ""))
15663 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15664 (use (match_operand:SWI48 3 "const_int_operand" ""))
15665 (use (match_operand:SI 4 "const_int_operand" ""))
15666 (use (match_operand:SI 5 "const_int_operand" ""))]
15667 ""
15668 {
15669 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15670 operands[4], operands[5]))
15671 DONE;
15672 else
15673 FAIL;
15674 })
15675
15676 ;; Most CPUs don't like single string operations
15677 ;; Handle this case here to simplify previous expander.
15678
15679 (define_expand "strmov"
15680 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15681 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15682 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15683 (clobber (reg:CC FLAGS_REG))])
15684 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15685 (clobber (reg:CC FLAGS_REG))])]
15686 ""
15687 {
15688 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15689
15690 /* If .md ever supports :P for Pmode, these can be directly
15691 in the pattern above. */
15692 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15693 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15694
15695 /* Can't use this if the user has appropriated esi or edi. */
15696 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15697 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15698 {
15699 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15700 operands[2], operands[3],
15701 operands[5], operands[6]));
15702 DONE;
15703 }
15704
15705 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15706 })
15707
15708 (define_expand "strmov_singleop"
15709 [(parallel [(set (match_operand 1 "memory_operand" "")
15710 (match_operand 3 "memory_operand" ""))
15711 (set (match_operand 0 "register_operand" "")
15712 (match_operand 4 "" ""))
15713 (set (match_operand 2 "register_operand" "")
15714 (match_operand 5 "" ""))])]
15715 ""
15716 "ix86_current_function_needs_cld = 1;")
15717
15718 (define_insn "*strmovdi_rex_1"
15719 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15720 (mem:DI (match_operand:P 3 "register_operand" "1")))
15721 (set (match_operand:P 0 "register_operand" "=D")
15722 (plus:P (match_dup 2)
15723 (const_int 8)))
15724 (set (match_operand:P 1 "register_operand" "=S")
15725 (plus:P (match_dup 3)
15726 (const_int 8)))]
15727 "TARGET_64BIT
15728 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15729 "%^movsq"
15730 [(set_attr "type" "str")
15731 (set_attr "memory" "both")
15732 (set_attr "mode" "DI")])
15733
15734 (define_insn "*strmovsi_1"
15735 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15736 (mem:SI (match_operand:P 3 "register_operand" "1")))
15737 (set (match_operand:P 0 "register_operand" "=D")
15738 (plus:P (match_dup 2)
15739 (const_int 4)))
15740 (set (match_operand:P 1 "register_operand" "=S")
15741 (plus:P (match_dup 3)
15742 (const_int 4)))]
15743 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15744 "%^movs{l|d}"
15745 [(set_attr "type" "str")
15746 (set_attr "memory" "both")
15747 (set_attr "mode" "SI")])
15748
15749 (define_insn "*strmovhi_1"
15750 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15751 (mem:HI (match_operand:P 3 "register_operand" "1")))
15752 (set (match_operand:P 0 "register_operand" "=D")
15753 (plus:P (match_dup 2)
15754 (const_int 2)))
15755 (set (match_operand:P 1 "register_operand" "=S")
15756 (plus:P (match_dup 3)
15757 (const_int 2)))]
15758 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15759 "%^movsw"
15760 [(set_attr "type" "str")
15761 (set_attr "memory" "both")
15762 (set_attr "mode" "HI")])
15763
15764 (define_insn "*strmovqi_1"
15765 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15766 (mem:QI (match_operand:P 3 "register_operand" "1")))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (match_dup 2)
15769 (const_int 1)))
15770 (set (match_operand:P 1 "register_operand" "=S")
15771 (plus:P (match_dup 3)
15772 (const_int 1)))]
15773 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774 "%^movsb"
15775 [(set_attr "type" "str")
15776 (set_attr "memory" "both")
15777 (set (attr "prefix_rex")
15778 (if_then_else
15779 (match_test "<P:MODE>mode == DImode")
15780 (const_string "0")
15781 (const_string "*")))
15782 (set_attr "mode" "QI")])
15783
15784 (define_expand "rep_mov"
15785 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15786 (set (match_operand 0 "register_operand" "")
15787 (match_operand 5 "" ""))
15788 (set (match_operand 2 "register_operand" "")
15789 (match_operand 6 "" ""))
15790 (set (match_operand 1 "memory_operand" "")
15791 (match_operand 3 "memory_operand" ""))
15792 (use (match_dup 4))])]
15793 ""
15794 "ix86_current_function_needs_cld = 1;")
15795
15796 (define_insn "*rep_movdi_rex64"
15797 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15798 (set (match_operand:P 0 "register_operand" "=D")
15799 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15800 (const_int 3))
15801 (match_operand:P 3 "register_operand" "0")))
15802 (set (match_operand:P 1 "register_operand" "=S")
15803 (plus:P (ashift:P (match_dup 5) (const_int 3))
15804 (match_operand:P 4 "register_operand" "1")))
15805 (set (mem:BLK (match_dup 3))
15806 (mem:BLK (match_dup 4)))
15807 (use (match_dup 5))]
15808 "TARGET_64BIT
15809 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15810 "%^rep{%;} movsq"
15811 [(set_attr "type" "str")
15812 (set_attr "prefix_rep" "1")
15813 (set_attr "memory" "both")
15814 (set_attr "mode" "DI")])
15815
15816 (define_insn "*rep_movsi"
15817 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15818 (set (match_operand:P 0 "register_operand" "=D")
15819 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15820 (const_int 2))
15821 (match_operand:P 3 "register_operand" "0")))
15822 (set (match_operand:P 1 "register_operand" "=S")
15823 (plus:P (ashift:P (match_dup 5) (const_int 2))
15824 (match_operand:P 4 "register_operand" "1")))
15825 (set (mem:BLK (match_dup 3))
15826 (mem:BLK (match_dup 4)))
15827 (use (match_dup 5))]
15828 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15829 "%^rep{%;} movs{l|d}"
15830 [(set_attr "type" "str")
15831 (set_attr "prefix_rep" "1")
15832 (set_attr "memory" "both")
15833 (set_attr "mode" "SI")])
15834
15835 (define_insn "*rep_movqi"
15836 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15837 (set (match_operand:P 0 "register_operand" "=D")
15838 (plus:P (match_operand:P 3 "register_operand" "0")
15839 (match_operand:P 5 "register_operand" "2")))
15840 (set (match_operand:P 1 "register_operand" "=S")
15841 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15842 (set (mem:BLK (match_dup 3))
15843 (mem:BLK (match_dup 4)))
15844 (use (match_dup 5))]
15845 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15846 "%^rep{%;} movsb"
15847 [(set_attr "type" "str")
15848 (set_attr "prefix_rep" "1")
15849 (set_attr "memory" "both")
15850 (set_attr "mode" "QI")])
15851
15852 (define_expand "setmem<mode>"
15853 [(use (match_operand:BLK 0 "memory_operand" ""))
15854 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15855 (use (match_operand:QI 2 "nonmemory_operand" ""))
15856 (use (match_operand 3 "const_int_operand" ""))
15857 (use (match_operand:SI 4 "const_int_operand" ""))
15858 (use (match_operand:SI 5 "const_int_operand" ""))]
15859 ""
15860 {
15861 if (ix86_expand_setmem (operands[0], operands[1],
15862 operands[2], operands[3],
15863 operands[4], operands[5]))
15864 DONE;
15865 else
15866 FAIL;
15867 })
15868
15869 ;; Most CPUs don't like single string operations
15870 ;; Handle this case here to simplify previous expander.
15871
15872 (define_expand "strset"
15873 [(set (match_operand 1 "memory_operand" "")
15874 (match_operand 2 "register_operand" ""))
15875 (parallel [(set (match_operand 0 "register_operand" "")
15876 (match_dup 3))
15877 (clobber (reg:CC FLAGS_REG))])]
15878 ""
15879 {
15880 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15881 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15882
15883 /* If .md ever supports :P for Pmode, this can be directly
15884 in the pattern above. */
15885 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15886 GEN_INT (GET_MODE_SIZE (GET_MODE
15887 (operands[2]))));
15888 /* Can't use this if the user has appropriated eax or edi. */
15889 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15890 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15891 {
15892 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15893 operands[3]));
15894 DONE;
15895 }
15896 })
15897
15898 (define_expand "strset_singleop"
15899 [(parallel [(set (match_operand 1 "memory_operand" "")
15900 (match_operand 2 "register_operand" ""))
15901 (set (match_operand 0 "register_operand" "")
15902 (match_operand 3 "" ""))])]
15903 ""
15904 "ix86_current_function_needs_cld = 1;")
15905
15906 (define_insn "*strsetdi_rex_1"
15907 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15908 (match_operand:DI 2 "register_operand" "a"))
15909 (set (match_operand:P 0 "register_operand" "=D")
15910 (plus:P (match_dup 1)
15911 (const_int 8)))]
15912 "TARGET_64BIT
15913 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15914 "%^stosq"
15915 [(set_attr "type" "str")
15916 (set_attr "memory" "store")
15917 (set_attr "mode" "DI")])
15918
15919 (define_insn "*strsetsi_1"
15920 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15921 (match_operand:SI 2 "register_operand" "a"))
15922 (set (match_operand:P 0 "register_operand" "=D")
15923 (plus:P (match_dup 1)
15924 (const_int 4)))]
15925 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15926 "%^stos{l|d}"
15927 [(set_attr "type" "str")
15928 (set_attr "memory" "store")
15929 (set_attr "mode" "SI")])
15930
15931 (define_insn "*strsethi_1"
15932 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15933 (match_operand:HI 2 "register_operand" "a"))
15934 (set (match_operand:P 0 "register_operand" "=D")
15935 (plus:P (match_dup 1)
15936 (const_int 2)))]
15937 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15938 "%^stosw"
15939 [(set_attr "type" "str")
15940 (set_attr "memory" "store")
15941 (set_attr "mode" "HI")])
15942
15943 (define_insn "*strsetqi_1"
15944 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15945 (match_operand:QI 2 "register_operand" "a"))
15946 (set (match_operand:P 0 "register_operand" "=D")
15947 (plus:P (match_dup 1)
15948 (const_int 1)))]
15949 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15950 "%^stosb"
15951 [(set_attr "type" "str")
15952 (set_attr "memory" "store")
15953 (set (attr "prefix_rex")
15954 (if_then_else
15955 (match_test "<P:MODE>mode == DImode")
15956 (const_string "0")
15957 (const_string "*")))
15958 (set_attr "mode" "QI")])
15959
15960 (define_expand "rep_stos"
15961 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15962 (set (match_operand 0 "register_operand" "")
15963 (match_operand 4 "" ""))
15964 (set (match_operand 2 "memory_operand" "") (const_int 0))
15965 (use (match_operand 3 "register_operand" ""))
15966 (use (match_dup 1))])]
15967 ""
15968 "ix86_current_function_needs_cld = 1;")
15969
15970 (define_insn "*rep_stosdi_rex64"
15971 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15972 (set (match_operand:P 0 "register_operand" "=D")
15973 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15974 (const_int 3))
15975 (match_operand:P 3 "register_operand" "0")))
15976 (set (mem:BLK (match_dup 3))
15977 (const_int 0))
15978 (use (match_operand:DI 2 "register_operand" "a"))
15979 (use (match_dup 4))]
15980 "TARGET_64BIT
15981 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15982 "%^rep{%;} stosq"
15983 [(set_attr "type" "str")
15984 (set_attr "prefix_rep" "1")
15985 (set_attr "memory" "store")
15986 (set_attr "mode" "DI")])
15987
15988 (define_insn "*rep_stossi"
15989 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15990 (set (match_operand:P 0 "register_operand" "=D")
15991 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15992 (const_int 2))
15993 (match_operand:P 3 "register_operand" "0")))
15994 (set (mem:BLK (match_dup 3))
15995 (const_int 0))
15996 (use (match_operand:SI 2 "register_operand" "a"))
15997 (use (match_dup 4))]
15998 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15999 "%^rep{%;} stos{l|d}"
16000 [(set_attr "type" "str")
16001 (set_attr "prefix_rep" "1")
16002 (set_attr "memory" "store")
16003 (set_attr "mode" "SI")])
16004
16005 (define_insn "*rep_stosqi"
16006 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16007 (set (match_operand:P 0 "register_operand" "=D")
16008 (plus:P (match_operand:P 3 "register_operand" "0")
16009 (match_operand:P 4 "register_operand" "1")))
16010 (set (mem:BLK (match_dup 3))
16011 (const_int 0))
16012 (use (match_operand:QI 2 "register_operand" "a"))
16013 (use (match_dup 4))]
16014 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16015 "%^rep{%;} stosb"
16016 [(set_attr "type" "str")
16017 (set_attr "prefix_rep" "1")
16018 (set_attr "memory" "store")
16019 (set (attr "prefix_rex")
16020 (if_then_else
16021 (match_test "<P:MODE>mode == DImode")
16022 (const_string "0")
16023 (const_string "*")))
16024 (set_attr "mode" "QI")])
16025
16026 (define_expand "cmpstrnsi"
16027 [(set (match_operand:SI 0 "register_operand" "")
16028 (compare:SI (match_operand:BLK 1 "general_operand" "")
16029 (match_operand:BLK 2 "general_operand" "")))
16030 (use (match_operand 3 "general_operand" ""))
16031 (use (match_operand 4 "immediate_operand" ""))]
16032 ""
16033 {
16034 rtx addr1, addr2, out, outlow, count, countreg, align;
16035
16036 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16037 FAIL;
16038
16039 /* Can't use this if the user has appropriated ecx, esi or edi. */
16040 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16041 FAIL;
16042
16043 out = operands[0];
16044 if (!REG_P (out))
16045 out = gen_reg_rtx (SImode);
16046
16047 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16048 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16049 if (addr1 != XEXP (operands[1], 0))
16050 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16051 if (addr2 != XEXP (operands[2], 0))
16052 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16053
16054 count = operands[3];
16055 countreg = ix86_zero_extend_to_Pmode (count);
16056
16057 /* %%% Iff we are testing strict equality, we can use known alignment
16058 to good advantage. This may be possible with combine, particularly
16059 once cc0 is dead. */
16060 align = operands[4];
16061
16062 if (CONST_INT_P (count))
16063 {
16064 if (INTVAL (count) == 0)
16065 {
16066 emit_move_insn (operands[0], const0_rtx);
16067 DONE;
16068 }
16069 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16070 operands[1], operands[2]));
16071 }
16072 else
16073 {
16074 rtx (*gen_cmp) (rtx, rtx);
16075
16076 gen_cmp = (TARGET_64BIT
16077 ? gen_cmpdi_1 : gen_cmpsi_1);
16078
16079 emit_insn (gen_cmp (countreg, countreg));
16080 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16081 operands[1], operands[2]));
16082 }
16083
16084 outlow = gen_lowpart (QImode, out);
16085 emit_insn (gen_cmpintqi (outlow));
16086 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16087
16088 if (operands[0] != out)
16089 emit_move_insn (operands[0], out);
16090
16091 DONE;
16092 })
16093
16094 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16095
16096 (define_expand "cmpintqi"
16097 [(set (match_dup 1)
16098 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16099 (set (match_dup 2)
16100 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16101 (parallel [(set (match_operand:QI 0 "register_operand" "")
16102 (minus:QI (match_dup 1)
16103 (match_dup 2)))
16104 (clobber (reg:CC FLAGS_REG))])]
16105 ""
16106 {
16107 operands[1] = gen_reg_rtx (QImode);
16108 operands[2] = gen_reg_rtx (QImode);
16109 })
16110
16111 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16112 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16113
16114 (define_expand "cmpstrnqi_nz_1"
16115 [(parallel [(set (reg:CC FLAGS_REG)
16116 (compare:CC (match_operand 4 "memory_operand" "")
16117 (match_operand 5 "memory_operand" "")))
16118 (use (match_operand 2 "register_operand" ""))
16119 (use (match_operand:SI 3 "immediate_operand" ""))
16120 (clobber (match_operand 0 "register_operand" ""))
16121 (clobber (match_operand 1 "register_operand" ""))
16122 (clobber (match_dup 2))])]
16123 ""
16124 "ix86_current_function_needs_cld = 1;")
16125
16126 (define_insn "*cmpstrnqi_nz_1"
16127 [(set (reg:CC FLAGS_REG)
16128 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16129 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16130 (use (match_operand:P 6 "register_operand" "2"))
16131 (use (match_operand:SI 3 "immediate_operand" "i"))
16132 (clobber (match_operand:P 0 "register_operand" "=S"))
16133 (clobber (match_operand:P 1 "register_operand" "=D"))
16134 (clobber (match_operand:P 2 "register_operand" "=c"))]
16135 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16136 "%^repz{%;} cmpsb"
16137 [(set_attr "type" "str")
16138 (set_attr "mode" "QI")
16139 (set (attr "prefix_rex")
16140 (if_then_else
16141 (match_test "<P:MODE>mode == DImode")
16142 (const_string "0")
16143 (const_string "*")))
16144 (set_attr "prefix_rep" "1")])
16145
16146 ;; The same, but the count is not known to not be zero.
16147
16148 (define_expand "cmpstrnqi_1"
16149 [(parallel [(set (reg:CC FLAGS_REG)
16150 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16151 (const_int 0))
16152 (compare:CC (match_operand 4 "memory_operand" "")
16153 (match_operand 5 "memory_operand" ""))
16154 (const_int 0)))
16155 (use (match_operand:SI 3 "immediate_operand" ""))
16156 (use (reg:CC FLAGS_REG))
16157 (clobber (match_operand 0 "register_operand" ""))
16158 (clobber (match_operand 1 "register_operand" ""))
16159 (clobber (match_dup 2))])]
16160 ""
16161 "ix86_current_function_needs_cld = 1;")
16162
16163 (define_insn "*cmpstrnqi_1"
16164 [(set (reg:CC FLAGS_REG)
16165 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16166 (const_int 0))
16167 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16168 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16169 (const_int 0)))
16170 (use (match_operand:SI 3 "immediate_operand" "i"))
16171 (use (reg:CC FLAGS_REG))
16172 (clobber (match_operand:P 0 "register_operand" "=S"))
16173 (clobber (match_operand:P 1 "register_operand" "=D"))
16174 (clobber (match_operand:P 2 "register_operand" "=c"))]
16175 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16176 "%^repz{%;} cmpsb"
16177 [(set_attr "type" "str")
16178 (set_attr "mode" "QI")
16179 (set (attr "prefix_rex")
16180 (if_then_else
16181 (match_test "<P:MODE>mode == DImode")
16182 (const_string "0")
16183 (const_string "*")))
16184 (set_attr "prefix_rep" "1")])
16185
16186 (define_expand "strlen<mode>"
16187 [(set (match_operand:P 0 "register_operand" "")
16188 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16189 (match_operand:QI 2 "immediate_operand" "")
16190 (match_operand 3 "immediate_operand" "")]
16191 UNSPEC_SCAS))]
16192 ""
16193 {
16194 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16195 DONE;
16196 else
16197 FAIL;
16198 })
16199
16200 (define_expand "strlenqi_1"
16201 [(parallel [(set (match_operand 0 "register_operand" "")
16202 (match_operand 2 "" ""))
16203 (clobber (match_operand 1 "register_operand" ""))
16204 (clobber (reg:CC FLAGS_REG))])]
16205 ""
16206 "ix86_current_function_needs_cld = 1;")
16207
16208 (define_insn "*strlenqi_1"
16209 [(set (match_operand:P 0 "register_operand" "=&c")
16210 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16211 (match_operand:QI 2 "register_operand" "a")
16212 (match_operand:P 3 "immediate_operand" "i")
16213 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16214 (clobber (match_operand:P 1 "register_operand" "=D"))
16215 (clobber (reg:CC FLAGS_REG))]
16216 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16217 "%^repnz{%;} scasb"
16218 [(set_attr "type" "str")
16219 (set_attr "mode" "QI")
16220 (set (attr "prefix_rex")
16221 (if_then_else
16222 (match_test "<P:MODE>mode == DImode")
16223 (const_string "0")
16224 (const_string "*")))
16225 (set_attr "prefix_rep" "1")])
16226
16227 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16228 ;; handled in combine, but it is not currently up to the task.
16229 ;; When used for their truth value, the cmpstrn* expanders generate
16230 ;; code like this:
16231 ;;
16232 ;; repz cmpsb
16233 ;; seta %al
16234 ;; setb %dl
16235 ;; cmpb %al, %dl
16236 ;; jcc label
16237 ;;
16238 ;; The intermediate three instructions are unnecessary.
16239
16240 ;; This one handles cmpstrn*_nz_1...
16241 (define_peephole2
16242 [(parallel[
16243 (set (reg:CC FLAGS_REG)
16244 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16245 (mem:BLK (match_operand 5 "register_operand" ""))))
16246 (use (match_operand 6 "register_operand" ""))
16247 (use (match_operand:SI 3 "immediate_operand" ""))
16248 (clobber (match_operand 0 "register_operand" ""))
16249 (clobber (match_operand 1 "register_operand" ""))
16250 (clobber (match_operand 2 "register_operand" ""))])
16251 (set (match_operand:QI 7 "register_operand" "")
16252 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16253 (set (match_operand:QI 8 "register_operand" "")
16254 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16255 (set (reg FLAGS_REG)
16256 (compare (match_dup 7) (match_dup 8)))
16257 ]
16258 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16259 [(parallel[
16260 (set (reg:CC FLAGS_REG)
16261 (compare:CC (mem:BLK (match_dup 4))
16262 (mem:BLK (match_dup 5))))
16263 (use (match_dup 6))
16264 (use (match_dup 3))
16265 (clobber (match_dup 0))
16266 (clobber (match_dup 1))
16267 (clobber (match_dup 2))])])
16268
16269 ;; ...and this one handles cmpstrn*_1.
16270 (define_peephole2
16271 [(parallel[
16272 (set (reg:CC FLAGS_REG)
16273 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16274 (const_int 0))
16275 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16276 (mem:BLK (match_operand 5 "register_operand" "")))
16277 (const_int 0)))
16278 (use (match_operand:SI 3 "immediate_operand" ""))
16279 (use (reg:CC FLAGS_REG))
16280 (clobber (match_operand 0 "register_operand" ""))
16281 (clobber (match_operand 1 "register_operand" ""))
16282 (clobber (match_operand 2 "register_operand" ""))])
16283 (set (match_operand:QI 7 "register_operand" "")
16284 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16285 (set (match_operand:QI 8 "register_operand" "")
16286 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16287 (set (reg FLAGS_REG)
16288 (compare (match_dup 7) (match_dup 8)))
16289 ]
16290 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16291 [(parallel[
16292 (set (reg:CC FLAGS_REG)
16293 (if_then_else:CC (ne (match_dup 6)
16294 (const_int 0))
16295 (compare:CC (mem:BLK (match_dup 4))
16296 (mem:BLK (match_dup 5)))
16297 (const_int 0)))
16298 (use (match_dup 3))
16299 (use (reg:CC FLAGS_REG))
16300 (clobber (match_dup 0))
16301 (clobber (match_dup 1))
16302 (clobber (match_dup 2))])])
16303 \f
16304 ;; Conditional move instructions.
16305
16306 (define_expand "mov<mode>cc"
16307 [(set (match_operand:SWIM 0 "register_operand" "")
16308 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16309 (match_operand:SWIM 2 "<general_operand>" "")
16310 (match_operand:SWIM 3 "<general_operand>" "")))]
16311 ""
16312 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16313
16314 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16315 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16316 ;; So just document what we're doing explicitly.
16317
16318 (define_expand "x86_mov<mode>cc_0_m1"
16319 [(parallel
16320 [(set (match_operand:SWI48 0 "register_operand" "")
16321 (if_then_else:SWI48
16322 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16323 [(match_operand 1 "flags_reg_operand" "")
16324 (const_int 0)])
16325 (const_int -1)
16326 (const_int 0)))
16327 (clobber (reg:CC FLAGS_REG))])])
16328
16329 (define_insn "*x86_mov<mode>cc_0_m1"
16330 [(set (match_operand:SWI48 0 "register_operand" "=r")
16331 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16332 [(reg FLAGS_REG) (const_int 0)])
16333 (const_int -1)
16334 (const_int 0)))
16335 (clobber (reg:CC FLAGS_REG))]
16336 ""
16337 "sbb{<imodesuffix>}\t%0, %0"
16338 ; Since we don't have the proper number of operands for an alu insn,
16339 ; fill in all the blanks.
16340 [(set_attr "type" "alu")
16341 (set_attr "use_carry" "1")
16342 (set_attr "pent_pair" "pu")
16343 (set_attr "memory" "none")
16344 (set_attr "imm_disp" "false")
16345 (set_attr "mode" "<MODE>")
16346 (set_attr "length_immediate" "0")])
16347
16348 (define_insn "*x86_mov<mode>cc_0_m1_se"
16349 [(set (match_operand:SWI48 0 "register_operand" "=r")
16350 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16351 [(reg FLAGS_REG) (const_int 0)])
16352 (const_int 1)
16353 (const_int 0)))
16354 (clobber (reg:CC FLAGS_REG))]
16355 ""
16356 "sbb{<imodesuffix>}\t%0, %0"
16357 [(set_attr "type" "alu")
16358 (set_attr "use_carry" "1")
16359 (set_attr "pent_pair" "pu")
16360 (set_attr "memory" "none")
16361 (set_attr "imm_disp" "false")
16362 (set_attr "mode" "<MODE>")
16363 (set_attr "length_immediate" "0")])
16364
16365 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16366 [(set (match_operand:SWI48 0 "register_operand" "=r")
16367 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16368 [(reg FLAGS_REG) (const_int 0)])))]
16369 ""
16370 "sbb{<imodesuffix>}\t%0, %0"
16371 [(set_attr "type" "alu")
16372 (set_attr "use_carry" "1")
16373 (set_attr "pent_pair" "pu")
16374 (set_attr "memory" "none")
16375 (set_attr "imm_disp" "false")
16376 (set_attr "mode" "<MODE>")
16377 (set_attr "length_immediate" "0")])
16378
16379 (define_insn "*mov<mode>cc_noc"
16380 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16381 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16382 [(reg FLAGS_REG) (const_int 0)])
16383 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16384 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16385 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16386 "@
16387 cmov%O2%C1\t{%2, %0|%0, %2}
16388 cmov%O2%c1\t{%3, %0|%0, %3}"
16389 [(set_attr "type" "icmov")
16390 (set_attr "mode" "<MODE>")])
16391
16392 (define_insn_and_split "*movqicc_noc"
16393 [(set (match_operand:QI 0 "register_operand" "=r,r")
16394 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16395 [(match_operand 4 "flags_reg_operand" "")
16396 (const_int 0)])
16397 (match_operand:QI 2 "register_operand" "r,0")
16398 (match_operand:QI 3 "register_operand" "0,r")))]
16399 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16400 "#"
16401 "&& reload_completed"
16402 [(set (match_dup 0)
16403 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16404 (match_dup 2)
16405 (match_dup 3)))]
16406 "operands[0] = gen_lowpart (SImode, operands[0]);
16407 operands[2] = gen_lowpart (SImode, operands[2]);
16408 operands[3] = gen_lowpart (SImode, operands[3]);"
16409 [(set_attr "type" "icmov")
16410 (set_attr "mode" "SI")])
16411
16412 (define_expand "mov<mode>cc"
16413 [(set (match_operand:X87MODEF 0 "register_operand" "")
16414 (if_then_else:X87MODEF
16415 (match_operand 1 "ix86_fp_comparison_operator" "")
16416 (match_operand:X87MODEF 2 "register_operand" "")
16417 (match_operand:X87MODEF 3 "register_operand" "")))]
16418 "(TARGET_80387 && TARGET_CMOVE)
16419 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16420 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16421
16422 (define_insn "*movxfcc_1"
16423 [(set (match_operand:XF 0 "register_operand" "=f,f")
16424 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16425 [(reg FLAGS_REG) (const_int 0)])
16426 (match_operand:XF 2 "register_operand" "f,0")
16427 (match_operand:XF 3 "register_operand" "0,f")))]
16428 "TARGET_80387 && TARGET_CMOVE"
16429 "@
16430 fcmov%F1\t{%2, %0|%0, %2}
16431 fcmov%f1\t{%3, %0|%0, %3}"
16432 [(set_attr "type" "fcmov")
16433 (set_attr "mode" "XF")])
16434
16435 (define_insn "*movdfcc_1_rex64"
16436 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16437 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16440 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16441 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16442 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16443 "@
16444 fcmov%F1\t{%2, %0|%0, %2}
16445 fcmov%f1\t{%3, %0|%0, %3}
16446 cmov%O2%C1\t{%2, %0|%0, %2}
16447 cmov%O2%c1\t{%3, %0|%0, %3}"
16448 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16449 (set_attr "mode" "DF,DF,DI,DI")])
16450
16451 (define_insn "*movdfcc_1"
16452 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16453 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16454 [(reg FLAGS_REG) (const_int 0)])
16455 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16456 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16457 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16458 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16459 "@
16460 fcmov%F1\t{%2, %0|%0, %2}
16461 fcmov%f1\t{%3, %0|%0, %3}
16462 #
16463 #"
16464 [(set_attr "type" "fcmov,fcmov,multi,multi")
16465 (set_attr "mode" "DF,DF,DI,DI")])
16466
16467 (define_split
16468 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16469 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16470 [(match_operand 4 "flags_reg_operand" "")
16471 (const_int 0)])
16472 (match_operand:DF 2 "nonimmediate_operand" "")
16473 (match_operand:DF 3 "nonimmediate_operand" "")))]
16474 "!TARGET_64BIT && reload_completed"
16475 [(set (match_dup 2)
16476 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16477 (match_dup 5)
16478 (match_dup 6)))
16479 (set (match_dup 3)
16480 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16481 (match_dup 7)
16482 (match_dup 8)))]
16483 {
16484 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16485 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16486 })
16487
16488 (define_insn "*movsfcc_1_387"
16489 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16490 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16491 [(reg FLAGS_REG) (const_int 0)])
16492 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16493 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16494 "TARGET_80387 && TARGET_CMOVE
16495 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16496 "@
16497 fcmov%F1\t{%2, %0|%0, %2}
16498 fcmov%f1\t{%3, %0|%0, %3}
16499 cmov%O2%C1\t{%2, %0|%0, %2}
16500 cmov%O2%c1\t{%3, %0|%0, %3}"
16501 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16502 (set_attr "mode" "SF,SF,SI,SI")])
16503
16504 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16505 ;; the scalar versions to have only XMM registers as operands.
16506
16507 ;; XOP conditional move
16508 (define_insn "*xop_pcmov_<mode>"
16509 [(set (match_operand:MODEF 0 "register_operand" "=x")
16510 (if_then_else:MODEF
16511 (match_operand:MODEF 1 "register_operand" "x")
16512 (match_operand:MODEF 2 "register_operand" "x")
16513 (match_operand:MODEF 3 "register_operand" "x")))]
16514 "TARGET_XOP"
16515 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16516 [(set_attr "type" "sse4arg")])
16517
16518 ;; These versions of the min/max patterns are intentionally ignorant of
16519 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16520 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16521 ;; are undefined in this condition, we're certain this is correct.
16522
16523 (define_insn "<code><mode>3"
16524 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16525 (smaxmin:MODEF
16526 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16527 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16528 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16529 "@
16530 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16531 v<maxmin_float><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 ;; These versions of the min/max patterns implement exactly the operations
16538 ;; min = (op1 < op2 ? op1 : op2)
16539 ;; max = (!(op1 < op2) ? op1 : op2)
16540 ;; Their operands are not commutative, and thus they may be used in the
16541 ;; presence of -0.0 and NaN.
16542
16543 (define_insn "*ieee_smin<mode>3"
16544 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16545 (unspec:MODEF
16546 [(match_operand:MODEF 1 "register_operand" "0,x")
16547 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16548 UNSPEC_IEEE_MIN))]
16549 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16550 "@
16551 min<ssemodesuffix>\t{%2, %0|%0, %2}
16552 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16553 [(set_attr "isa" "noavx,avx")
16554 (set_attr "prefix" "orig,vex")
16555 (set_attr "type" "sseadd")
16556 (set_attr "mode" "<MODE>")])
16557
16558 (define_insn "*ieee_smax<mode>3"
16559 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16560 (unspec:MODEF
16561 [(match_operand:MODEF 1 "register_operand" "0,x")
16562 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16563 UNSPEC_IEEE_MAX))]
16564 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16565 "@
16566 max<ssemodesuffix>\t{%2, %0|%0, %2}
16567 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16568 [(set_attr "isa" "noavx,avx")
16569 (set_attr "prefix" "orig,vex")
16570 (set_attr "type" "sseadd")
16571 (set_attr "mode" "<MODE>")])
16572
16573 ;; Make two stack loads independent:
16574 ;; fld aa fld aa
16575 ;; fld %st(0) -> fld bb
16576 ;; fmul bb fmul %st(1), %st
16577 ;;
16578 ;; Actually we only match the last two instructions for simplicity.
16579 (define_peephole2
16580 [(set (match_operand 0 "fp_register_operand" "")
16581 (match_operand 1 "fp_register_operand" ""))
16582 (set (match_dup 0)
16583 (match_operator 2 "binary_fp_operator"
16584 [(match_dup 0)
16585 (match_operand 3 "memory_operand" "")]))]
16586 "REGNO (operands[0]) != REGNO (operands[1])"
16587 [(set (match_dup 0) (match_dup 3))
16588 (set (match_dup 0) (match_dup 4))]
16589
16590 ;; The % modifier is not operational anymore in peephole2's, so we have to
16591 ;; swap the operands manually in the case of addition and multiplication.
16592 {
16593 rtx op0, op1;
16594
16595 if (COMMUTATIVE_ARITH_P (operands[2]))
16596 op0 = operands[0], op1 = operands[1];
16597 else
16598 op0 = operands[1], op1 = operands[0];
16599
16600 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16601 GET_MODE (operands[2]),
16602 op0, op1);
16603 })
16604
16605 ;; Conditional addition patterns
16606 (define_expand "add<mode>cc"
16607 [(match_operand:SWI 0 "register_operand" "")
16608 (match_operand 1 "ordered_comparison_operator" "")
16609 (match_operand:SWI 2 "register_operand" "")
16610 (match_operand:SWI 3 "const_int_operand" "")]
16611 ""
16612 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16613 \f
16614 ;; Misc patterns (?)
16615
16616 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16617 ;; Otherwise there will be nothing to keep
16618 ;;
16619 ;; [(set (reg ebp) (reg esp))]
16620 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16621 ;; (clobber (eflags)]
16622 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16623 ;;
16624 ;; in proper program order.
16625
16626 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16627 [(set (match_operand:P 0 "register_operand" "=r,r")
16628 (plus:P (match_operand:P 1 "register_operand" "0,r")
16629 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16630 (clobber (reg:CC FLAGS_REG))
16631 (clobber (mem:BLK (scratch)))]
16632 ""
16633 {
16634 switch (get_attr_type (insn))
16635 {
16636 case TYPE_IMOV:
16637 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16638
16639 case TYPE_ALU:
16640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16641 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16642 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16643
16644 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16645
16646 default:
16647 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16648 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16649 }
16650 }
16651 [(set (attr "type")
16652 (cond [(and (eq_attr "alternative" "0")
16653 (not (match_test "TARGET_OPT_AGU")))
16654 (const_string "alu")
16655 (match_operand:<MODE> 2 "const0_operand" "")
16656 (const_string "imov")
16657 ]
16658 (const_string "lea")))
16659 (set (attr "length_immediate")
16660 (cond [(eq_attr "type" "imov")
16661 (const_string "0")
16662 (and (eq_attr "type" "alu")
16663 (match_operand 2 "const128_operand" ""))
16664 (const_string "1")
16665 ]
16666 (const_string "*")))
16667 (set_attr "mode" "<MODE>")])
16668
16669 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16670 [(set (match_operand:P 0 "register_operand" "=r")
16671 (minus:P (match_operand:P 1 "register_operand" "0")
16672 (match_operand:P 2 "register_operand" "r")))
16673 (clobber (reg:CC FLAGS_REG))
16674 (clobber (mem:BLK (scratch)))]
16675 ""
16676 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16677 [(set_attr "type" "alu")
16678 (set_attr "mode" "<MODE>")])
16679
16680 (define_insn "allocate_stack_worker_probe_<mode>"
16681 [(set (match_operand:P 0 "register_operand" "=a")
16682 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16683 UNSPECV_STACK_PROBE))
16684 (clobber (reg:CC FLAGS_REG))]
16685 "ix86_target_stack_probe ()"
16686 "call\t___chkstk_ms"
16687 [(set_attr "type" "multi")
16688 (set_attr "length" "5")])
16689
16690 (define_expand "allocate_stack"
16691 [(match_operand 0 "register_operand" "")
16692 (match_operand 1 "general_operand" "")]
16693 "ix86_target_stack_probe ()"
16694 {
16695 rtx x;
16696
16697 #ifndef CHECK_STACK_LIMIT
16698 #define CHECK_STACK_LIMIT 0
16699 #endif
16700
16701 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16702 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16703 {
16704 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16705 stack_pointer_rtx, 0, OPTAB_DIRECT);
16706 if (x != stack_pointer_rtx)
16707 emit_move_insn (stack_pointer_rtx, x);
16708 }
16709 else
16710 {
16711 x = copy_to_mode_reg (Pmode, operands[1]);
16712 if (TARGET_64BIT)
16713 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16714 else
16715 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16716 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16717 stack_pointer_rtx, 0, OPTAB_DIRECT);
16718 if (x != stack_pointer_rtx)
16719 emit_move_insn (stack_pointer_rtx, x);
16720 }
16721
16722 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16723 DONE;
16724 })
16725
16726 ;; Use IOR for stack probes, this is shorter.
16727 (define_expand "probe_stack"
16728 [(match_operand 0 "memory_operand" "")]
16729 ""
16730 {
16731 rtx (*gen_ior3) (rtx, rtx, rtx);
16732
16733 gen_ior3 = (GET_MODE (operands[0]) == DImode
16734 ? gen_iordi3 : gen_iorsi3);
16735
16736 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16737 DONE;
16738 })
16739
16740 (define_insn "adjust_stack_and_probe<mode>"
16741 [(set (match_operand:P 0 "register_operand" "=r")
16742 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16743 UNSPECV_PROBE_STACK_RANGE))
16744 (set (reg:P SP_REG)
16745 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16746 (clobber (reg:CC FLAGS_REG))
16747 (clobber (mem:BLK (scratch)))]
16748 ""
16749 "* return output_adjust_stack_and_probe (operands[0]);"
16750 [(set_attr "type" "multi")])
16751
16752 (define_insn "probe_stack_range<mode>"
16753 [(set (match_operand:P 0 "register_operand" "=r")
16754 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16755 (match_operand:P 2 "const_int_operand" "n")]
16756 UNSPECV_PROBE_STACK_RANGE))
16757 (clobber (reg:CC FLAGS_REG))]
16758 ""
16759 "* return output_probe_stack_range (operands[0], operands[2]);"
16760 [(set_attr "type" "multi")])
16761
16762 (define_expand "builtin_setjmp_receiver"
16763 [(label_ref (match_operand 0 "" ""))]
16764 "!TARGET_64BIT && flag_pic"
16765 {
16766 #if TARGET_MACHO
16767 if (TARGET_MACHO)
16768 {
16769 rtx xops[3];
16770 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16771 rtx label_rtx = gen_label_rtx ();
16772 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16773 xops[0] = xops[1] = picreg;
16774 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16775 ix86_expand_binary_operator (MINUS, SImode, xops);
16776 }
16777 else
16778 #endif
16779 emit_insn (gen_set_got (pic_offset_table_rtx));
16780 DONE;
16781 })
16782 \f
16783 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16784
16785 (define_split
16786 [(set (match_operand 0 "register_operand" "")
16787 (match_operator 3 "promotable_binary_operator"
16788 [(match_operand 1 "register_operand" "")
16789 (match_operand 2 "aligned_operand" "")]))
16790 (clobber (reg:CC FLAGS_REG))]
16791 "! TARGET_PARTIAL_REG_STALL && reload_completed
16792 && ((GET_MODE (operands[0]) == HImode
16793 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16794 /* ??? next two lines just !satisfies_constraint_K (...) */
16795 || !CONST_INT_P (operands[2])
16796 || satisfies_constraint_K (operands[2])))
16797 || (GET_MODE (operands[0]) == QImode
16798 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16799 [(parallel [(set (match_dup 0)
16800 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16801 (clobber (reg:CC FLAGS_REG))])]
16802 {
16803 operands[0] = gen_lowpart (SImode, operands[0]);
16804 operands[1] = gen_lowpart (SImode, operands[1]);
16805 if (GET_CODE (operands[3]) != ASHIFT)
16806 operands[2] = gen_lowpart (SImode, operands[2]);
16807 PUT_MODE (operands[3], SImode);
16808 })
16809
16810 ; Promote the QImode tests, as i386 has encoding of the AND
16811 ; instruction with 32-bit sign-extended immediate and thus the
16812 ; instruction size is unchanged, except in the %eax case for
16813 ; which it is increased by one byte, hence the ! optimize_size.
16814 (define_split
16815 [(set (match_operand 0 "flags_reg_operand" "")
16816 (match_operator 2 "compare_operator"
16817 [(and (match_operand 3 "aligned_operand" "")
16818 (match_operand 4 "const_int_operand" ""))
16819 (const_int 0)]))
16820 (set (match_operand 1 "register_operand" "")
16821 (and (match_dup 3) (match_dup 4)))]
16822 "! TARGET_PARTIAL_REG_STALL && reload_completed
16823 && optimize_insn_for_speed_p ()
16824 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16825 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16826 /* Ensure that the operand will remain sign-extended immediate. */
16827 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16828 [(parallel [(set (match_dup 0)
16829 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16830 (const_int 0)]))
16831 (set (match_dup 1)
16832 (and:SI (match_dup 3) (match_dup 4)))])]
16833 {
16834 operands[4]
16835 = gen_int_mode (INTVAL (operands[4])
16836 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16837 operands[1] = gen_lowpart (SImode, operands[1]);
16838 operands[3] = gen_lowpart (SImode, operands[3]);
16839 })
16840
16841 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16842 ; the TEST instruction with 32-bit sign-extended immediate and thus
16843 ; the instruction size would at least double, which is not what we
16844 ; want even with ! optimize_size.
16845 (define_split
16846 [(set (match_operand 0 "flags_reg_operand" "")
16847 (match_operator 1 "compare_operator"
16848 [(and (match_operand:HI 2 "aligned_operand" "")
16849 (match_operand:HI 3 "const_int_operand" ""))
16850 (const_int 0)]))]
16851 "! TARGET_PARTIAL_REG_STALL && reload_completed
16852 && ! TARGET_FAST_PREFIX
16853 && optimize_insn_for_speed_p ()
16854 /* Ensure that the operand will remain sign-extended immediate. */
16855 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16856 [(set (match_dup 0)
16857 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16858 (const_int 0)]))]
16859 {
16860 operands[3]
16861 = gen_int_mode (INTVAL (operands[3])
16862 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16863 operands[2] = gen_lowpart (SImode, operands[2]);
16864 })
16865
16866 (define_split
16867 [(set (match_operand 0 "register_operand" "")
16868 (neg (match_operand 1 "register_operand" "")))
16869 (clobber (reg:CC FLAGS_REG))]
16870 "! TARGET_PARTIAL_REG_STALL && reload_completed
16871 && (GET_MODE (operands[0]) == HImode
16872 || (GET_MODE (operands[0]) == QImode
16873 && (TARGET_PROMOTE_QImode
16874 || optimize_insn_for_size_p ())))"
16875 [(parallel [(set (match_dup 0)
16876 (neg:SI (match_dup 1)))
16877 (clobber (reg:CC FLAGS_REG))])]
16878 {
16879 operands[0] = gen_lowpart (SImode, operands[0]);
16880 operands[1] = gen_lowpart (SImode, operands[1]);
16881 })
16882
16883 (define_split
16884 [(set (match_operand 0 "register_operand" "")
16885 (not (match_operand 1 "register_operand" "")))]
16886 "! TARGET_PARTIAL_REG_STALL && reload_completed
16887 && (GET_MODE (operands[0]) == HImode
16888 || (GET_MODE (operands[0]) == QImode
16889 && (TARGET_PROMOTE_QImode
16890 || optimize_insn_for_size_p ())))"
16891 [(set (match_dup 0)
16892 (not:SI (match_dup 1)))]
16893 {
16894 operands[0] = gen_lowpart (SImode, operands[0]);
16895 operands[1] = gen_lowpart (SImode, operands[1]);
16896 })
16897
16898 (define_split
16899 [(set (match_operand 0 "register_operand" "")
16900 (if_then_else (match_operator 1 "ordered_comparison_operator"
16901 [(reg FLAGS_REG) (const_int 0)])
16902 (match_operand 2 "register_operand" "")
16903 (match_operand 3 "register_operand" "")))]
16904 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16905 && (GET_MODE (operands[0]) == HImode
16906 || (GET_MODE (operands[0]) == QImode
16907 && (TARGET_PROMOTE_QImode
16908 || optimize_insn_for_size_p ())))"
16909 [(set (match_dup 0)
16910 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16911 {
16912 operands[0] = gen_lowpart (SImode, operands[0]);
16913 operands[2] = gen_lowpart (SImode, operands[2]);
16914 operands[3] = gen_lowpart (SImode, operands[3]);
16915 })
16916 \f
16917 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16918 ;; transform a complex memory operation into two memory to register operations.
16919
16920 ;; Don't push memory operands
16921 (define_peephole2
16922 [(set (match_operand:SWI 0 "push_operand" "")
16923 (match_operand:SWI 1 "memory_operand" ""))
16924 (match_scratch:SWI 2 "<r>")]
16925 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16926 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16927 [(set (match_dup 2) (match_dup 1))
16928 (set (match_dup 0) (match_dup 2))])
16929
16930 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16931 ;; SImode pushes.
16932 (define_peephole2
16933 [(set (match_operand:SF 0 "push_operand" "")
16934 (match_operand:SF 1 "memory_operand" ""))
16935 (match_scratch:SF 2 "r")]
16936 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16937 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16938 [(set (match_dup 2) (match_dup 1))
16939 (set (match_dup 0) (match_dup 2))])
16940
16941 ;; Don't move an immediate directly to memory when the instruction
16942 ;; gets too big.
16943 (define_peephole2
16944 [(match_scratch:SWI124 1 "<r>")
16945 (set (match_operand:SWI124 0 "memory_operand" "")
16946 (const_int 0))]
16947 "optimize_insn_for_speed_p ()
16948 && !TARGET_USE_MOV0
16949 && TARGET_SPLIT_LONG_MOVES
16950 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16951 && peep2_regno_dead_p (0, FLAGS_REG)"
16952 [(parallel [(set (match_dup 2) (const_int 0))
16953 (clobber (reg:CC FLAGS_REG))])
16954 (set (match_dup 0) (match_dup 1))]
16955 "operands[2] = gen_lowpart (SImode, operands[1]);")
16956
16957 (define_peephole2
16958 [(match_scratch:SWI124 2 "<r>")
16959 (set (match_operand:SWI124 0 "memory_operand" "")
16960 (match_operand:SWI124 1 "immediate_operand" ""))]
16961 "optimize_insn_for_speed_p ()
16962 && TARGET_SPLIT_LONG_MOVES
16963 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16964 [(set (match_dup 2) (match_dup 1))
16965 (set (match_dup 0) (match_dup 2))])
16966
16967 ;; Don't compare memory with zero, load and use a test instead.
16968 (define_peephole2
16969 [(set (match_operand 0 "flags_reg_operand" "")
16970 (match_operator 1 "compare_operator"
16971 [(match_operand:SI 2 "memory_operand" "")
16972 (const_int 0)]))
16973 (match_scratch:SI 3 "r")]
16974 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16975 [(set (match_dup 3) (match_dup 2))
16976 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16977
16978 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16979 ;; Don't split NOTs with a displacement operand, because resulting XOR
16980 ;; will not be pairable anyway.
16981 ;;
16982 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16983 ;; represented using a modRM byte. The XOR replacement is long decoded,
16984 ;; so this split helps here as well.
16985 ;;
16986 ;; Note: Can't do this as a regular split because we can't get proper
16987 ;; lifetime information then.
16988
16989 (define_peephole2
16990 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16991 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16992 "optimize_insn_for_speed_p ()
16993 && ((TARGET_NOT_UNPAIRABLE
16994 && (!MEM_P (operands[0])
16995 || !memory_displacement_operand (operands[0], <MODE>mode)))
16996 || (TARGET_NOT_VECTORMODE
16997 && long_memory_operand (operands[0], <MODE>mode)))
16998 && peep2_regno_dead_p (0, FLAGS_REG)"
16999 [(parallel [(set (match_dup 0)
17000 (xor:SWI124 (match_dup 1) (const_int -1)))
17001 (clobber (reg:CC FLAGS_REG))])])
17002
17003 ;; Non pairable "test imm, reg" instructions can be translated to
17004 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17005 ;; byte opcode instead of two, have a short form for byte operands),
17006 ;; so do it for other CPUs as well. Given that the value was dead,
17007 ;; this should not create any new dependencies. Pass on the sub-word
17008 ;; versions if we're concerned about partial register stalls.
17009
17010 (define_peephole2
17011 [(set (match_operand 0 "flags_reg_operand" "")
17012 (match_operator 1 "compare_operator"
17013 [(and:SI (match_operand:SI 2 "register_operand" "")
17014 (match_operand:SI 3 "immediate_operand" ""))
17015 (const_int 0)]))]
17016 "ix86_match_ccmode (insn, CCNOmode)
17017 && (true_regnum (operands[2]) != AX_REG
17018 || satisfies_constraint_K (operands[3]))
17019 && peep2_reg_dead_p (1, operands[2])"
17020 [(parallel
17021 [(set (match_dup 0)
17022 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17023 (const_int 0)]))
17024 (set (match_dup 2)
17025 (and:SI (match_dup 2) (match_dup 3)))])])
17026
17027 ;; We don't need to handle HImode case, because it will be promoted to SImode
17028 ;; on ! TARGET_PARTIAL_REG_STALL
17029
17030 (define_peephole2
17031 [(set (match_operand 0 "flags_reg_operand" "")
17032 (match_operator 1 "compare_operator"
17033 [(and:QI (match_operand:QI 2 "register_operand" "")
17034 (match_operand:QI 3 "immediate_operand" ""))
17035 (const_int 0)]))]
17036 "! TARGET_PARTIAL_REG_STALL
17037 && ix86_match_ccmode (insn, CCNOmode)
17038 && true_regnum (operands[2]) != AX_REG
17039 && peep2_reg_dead_p (1, operands[2])"
17040 [(parallel
17041 [(set (match_dup 0)
17042 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17043 (const_int 0)]))
17044 (set (match_dup 2)
17045 (and:QI (match_dup 2) (match_dup 3)))])])
17046
17047 (define_peephole2
17048 [(set (match_operand 0 "flags_reg_operand" "")
17049 (match_operator 1 "compare_operator"
17050 [(and:SI
17051 (zero_extract:SI
17052 (match_operand 2 "ext_register_operand" "")
17053 (const_int 8)
17054 (const_int 8))
17055 (match_operand 3 "const_int_operand" ""))
17056 (const_int 0)]))]
17057 "! TARGET_PARTIAL_REG_STALL
17058 && ix86_match_ccmode (insn, CCNOmode)
17059 && true_regnum (operands[2]) != AX_REG
17060 && peep2_reg_dead_p (1, operands[2])"
17061 [(parallel [(set (match_dup 0)
17062 (match_op_dup 1
17063 [(and:SI
17064 (zero_extract:SI
17065 (match_dup 2)
17066 (const_int 8)
17067 (const_int 8))
17068 (match_dup 3))
17069 (const_int 0)]))
17070 (set (zero_extract:SI (match_dup 2)
17071 (const_int 8)
17072 (const_int 8))
17073 (and:SI
17074 (zero_extract:SI
17075 (match_dup 2)
17076 (const_int 8)
17077 (const_int 8))
17078 (match_dup 3)))])])
17079
17080 ;; Don't do logical operations with memory inputs.
17081 (define_peephole2
17082 [(match_scratch:SI 2 "r")
17083 (parallel [(set (match_operand:SI 0 "register_operand" "")
17084 (match_operator:SI 3 "arith_or_logical_operator"
17085 [(match_dup 0)
17086 (match_operand:SI 1 "memory_operand" "")]))
17087 (clobber (reg:CC FLAGS_REG))])]
17088 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17089 [(set (match_dup 2) (match_dup 1))
17090 (parallel [(set (match_dup 0)
17091 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17092 (clobber (reg:CC FLAGS_REG))])])
17093
17094 (define_peephole2
17095 [(match_scratch:SI 2 "r")
17096 (parallel [(set (match_operand:SI 0 "register_operand" "")
17097 (match_operator:SI 3 "arith_or_logical_operator"
17098 [(match_operand:SI 1 "memory_operand" "")
17099 (match_dup 0)]))
17100 (clobber (reg:CC FLAGS_REG))])]
17101 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17102 [(set (match_dup 2) (match_dup 1))
17103 (parallel [(set (match_dup 0)
17104 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17105 (clobber (reg:CC FLAGS_REG))])])
17106
17107 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17108 ;; refers to the destination of the load!
17109
17110 (define_peephole2
17111 [(set (match_operand:SI 0 "register_operand" "")
17112 (match_operand:SI 1 "register_operand" ""))
17113 (parallel [(set (match_dup 0)
17114 (match_operator:SI 3 "commutative_operator"
17115 [(match_dup 0)
17116 (match_operand:SI 2 "memory_operand" "")]))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "REGNO (operands[0]) != REGNO (operands[1])
17119 && GENERAL_REGNO_P (REGNO (operands[0]))
17120 && GENERAL_REGNO_P (REGNO (operands[1]))"
17121 [(set (match_dup 0) (match_dup 4))
17122 (parallel [(set (match_dup 0)
17123 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17124 (clobber (reg:CC FLAGS_REG))])]
17125 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17126
17127 (define_peephole2
17128 [(set (match_operand 0 "register_operand" "")
17129 (match_operand 1 "register_operand" ""))
17130 (set (match_dup 0)
17131 (match_operator 3 "commutative_operator"
17132 [(match_dup 0)
17133 (match_operand 2 "memory_operand" "")]))]
17134 "REGNO (operands[0]) != REGNO (operands[1])
17135 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17136 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17137 [(set (match_dup 0) (match_dup 2))
17138 (set (match_dup 0)
17139 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17140
17141 ; Don't do logical operations with memory outputs
17142 ;
17143 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17144 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17145 ; the same decoder scheduling characteristics as the original.
17146
17147 (define_peephole2
17148 [(match_scratch:SI 2 "r")
17149 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17150 (match_operator:SI 3 "arith_or_logical_operator"
17151 [(match_dup 0)
17152 (match_operand:SI 1 "nonmemory_operand" "")]))
17153 (clobber (reg:CC FLAGS_REG))])]
17154 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17155 /* Do not split stack checking probes. */
17156 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17157 [(set (match_dup 2) (match_dup 0))
17158 (parallel [(set (match_dup 2)
17159 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17160 (clobber (reg:CC FLAGS_REG))])
17161 (set (match_dup 0) (match_dup 2))])
17162
17163 (define_peephole2
17164 [(match_scratch:SI 2 "r")
17165 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17166 (match_operator:SI 3 "arith_or_logical_operator"
17167 [(match_operand:SI 1 "nonmemory_operand" "")
17168 (match_dup 0)]))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17171 /* Do not split stack checking probes. */
17172 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17173 [(set (match_dup 2) (match_dup 0))
17174 (parallel [(set (match_dup 2)
17175 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17176 (clobber (reg:CC FLAGS_REG))])
17177 (set (match_dup 0) (match_dup 2))])
17178
17179 ;; Attempt to use arith or logical operations with memory outputs with
17180 ;; setting of flags.
17181 (define_peephole2
17182 [(set (match_operand:SWI 0 "register_operand" "")
17183 (match_operand:SWI 1 "memory_operand" ""))
17184 (parallel [(set (match_dup 0)
17185 (match_operator:SWI 3 "plusminuslogic_operator"
17186 [(match_dup 0)
17187 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17188 (clobber (reg:CC FLAGS_REG))])
17189 (set (match_dup 1) (match_dup 0))
17190 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17191 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17192 && peep2_reg_dead_p (4, operands[0])
17193 && !reg_overlap_mentioned_p (operands[0], operands[1])
17194 && ix86_match_ccmode (peep2_next_insn (3),
17195 (GET_CODE (operands[3]) == PLUS
17196 || GET_CODE (operands[3]) == MINUS)
17197 ? CCGOCmode : CCNOmode)"
17198 [(parallel [(set (match_dup 4) (match_dup 5))
17199 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17200 (match_dup 2)]))])]
17201 {
17202 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17203 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17204 copy_rtx (operands[1]),
17205 copy_rtx (operands[2]));
17206 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17207 operands[5], const0_rtx);
17208 })
17209
17210 (define_peephole2
17211 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17212 (match_operator:SWI 2 "plusminuslogic_operator"
17213 [(match_dup 0)
17214 (match_operand:SWI 1 "memory_operand" "")]))
17215 (clobber (reg:CC FLAGS_REG))])
17216 (set (match_dup 1) (match_dup 0))
17217 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17218 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17219 && GET_CODE (operands[2]) != MINUS
17220 && peep2_reg_dead_p (3, operands[0])
17221 && !reg_overlap_mentioned_p (operands[0], operands[1])
17222 && ix86_match_ccmode (peep2_next_insn (2),
17223 GET_CODE (operands[2]) == PLUS
17224 ? CCGOCmode : CCNOmode)"
17225 [(parallel [(set (match_dup 3) (match_dup 4))
17226 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17227 (match_dup 0)]))])]
17228 {
17229 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17230 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17231 copy_rtx (operands[1]),
17232 copy_rtx (operands[0]));
17233 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17234 operands[4], const0_rtx);
17235 })
17236
17237 (define_peephole2
17238 [(set (match_operand:SWI12 0 "register_operand" "")
17239 (match_operand:SWI12 1 "memory_operand" ""))
17240 (parallel [(set (match_operand:SI 4 "register_operand" "")
17241 (match_operator:SI 3 "plusminuslogic_operator"
17242 [(match_dup 4)
17243 (match_operand:SI 2 "nonmemory_operand" "")]))
17244 (clobber (reg:CC FLAGS_REG))])
17245 (set (match_dup 1) (match_dup 0))
17246 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17247 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17248 && REG_P (operands[0]) && REG_P (operands[4])
17249 && REGNO (operands[0]) == REGNO (operands[4])
17250 && peep2_reg_dead_p (4, operands[0])
17251 && (<MODE>mode != QImode
17252 || immediate_operand (operands[2], SImode)
17253 || q_regs_operand (operands[2], SImode))
17254 && !reg_overlap_mentioned_p (operands[0], operands[1])
17255 && ix86_match_ccmode (peep2_next_insn (3),
17256 (GET_CODE (operands[3]) == PLUS
17257 || GET_CODE (operands[3]) == MINUS)
17258 ? CCGOCmode : CCNOmode)"
17259 [(parallel [(set (match_dup 4) (match_dup 5))
17260 (set (match_dup 1) (match_dup 6))])]
17261 {
17262 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17263 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17264 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17265 copy_rtx (operands[1]), operands[2]);
17266 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17267 operands[5], const0_rtx);
17268 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17269 copy_rtx (operands[1]),
17270 copy_rtx (operands[2]));
17271 })
17272
17273 ;; Attempt to always use XOR for zeroing registers.
17274 (define_peephole2
17275 [(set (match_operand 0 "register_operand" "")
17276 (match_operand 1 "const0_operand" ""))]
17277 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17278 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17279 && GENERAL_REG_P (operands[0])
17280 && peep2_regno_dead_p (0, FLAGS_REG)"
17281 [(parallel [(set (match_dup 0) (const_int 0))
17282 (clobber (reg:CC FLAGS_REG))])]
17283 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17284
17285 (define_peephole2
17286 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17287 (const_int 0))]
17288 "(GET_MODE (operands[0]) == QImode
17289 || GET_MODE (operands[0]) == HImode)
17290 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17291 && peep2_regno_dead_p (0, FLAGS_REG)"
17292 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17293 (clobber (reg:CC FLAGS_REG))])])
17294
17295 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17296 (define_peephole2
17297 [(set (match_operand:SWI248 0 "register_operand" "")
17298 (const_int -1))]
17299 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17300 && peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (match_dup 0) (const_int -1))
17302 (clobber (reg:CC FLAGS_REG))])]
17303 {
17304 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17305 operands[0] = gen_lowpart (SImode, operands[0]);
17306 })
17307
17308 ;; Attempt to convert simple lea to add/shift.
17309 ;; These can be created by move expanders.
17310
17311 (define_peephole2
17312 [(set (match_operand:SWI48 0 "register_operand" "")
17313 (plus:SWI48 (match_dup 0)
17314 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17315 "peep2_regno_dead_p (0, FLAGS_REG)"
17316 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17317 (clobber (reg:CC FLAGS_REG))])])
17318
17319 (define_peephole2
17320 [(set (match_operand:SI 0 "register_operand" "")
17321 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17322 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17323 "TARGET_64BIT
17324 && peep2_regno_dead_p (0, FLAGS_REG)
17325 && REGNO (operands[0]) == REGNO (operands[1])"
17326 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17327 (clobber (reg:CC FLAGS_REG))])]
17328 "operands[2] = gen_lowpart (SImode, operands[2]);")
17329
17330 (define_peephole2
17331 [(set (match_operand:SWI48 0 "register_operand" "")
17332 (mult:SWI48 (match_dup 0)
17333 (match_operand:SWI48 1 "const_int_operand" "")))]
17334 "exact_log2 (INTVAL (operands[1])) >= 0
17335 && peep2_regno_dead_p (0, FLAGS_REG)"
17336 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17337 (clobber (reg:CC FLAGS_REG))])]
17338 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17339
17340 (define_peephole2
17341 [(set (match_operand:SI 0 "register_operand" "")
17342 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17343 (match_operand:DI 2 "const_int_operand" "")) 0))]
17344 "TARGET_64BIT
17345 && exact_log2 (INTVAL (operands[2])) >= 0
17346 && REGNO (operands[0]) == REGNO (operands[1])
17347 && peep2_regno_dead_p (0, FLAGS_REG)"
17348 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17349 (clobber (reg:CC FLAGS_REG))])]
17350 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17351
17352 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17353 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17354 ;; On many CPUs it is also faster, since special hardware to avoid esp
17355 ;; dependencies is present.
17356
17357 ;; While some of these conversions may be done using splitters, we use
17358 ;; peepholes in order to allow combine_stack_adjustments pass to see
17359 ;; nonobfuscated RTL.
17360
17361 ;; Convert prologue esp subtractions to push.
17362 ;; We need register to push. In order to keep verify_flow_info happy we have
17363 ;; two choices
17364 ;; - use scratch and clobber it in order to avoid dependencies
17365 ;; - use already live register
17366 ;; We can't use the second way right now, since there is no reliable way how to
17367 ;; verify that given register is live. First choice will also most likely in
17368 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17369 ;; call clobbered registers are dead. We may want to use base pointer as an
17370 ;; alternative when no register is available later.
17371
17372 (define_peephole2
17373 [(match_scratch:W 1 "r")
17374 (parallel [(set (reg:P SP_REG)
17375 (plus:P (reg:P SP_REG)
17376 (match_operand:P 0 "const_int_operand" "")))
17377 (clobber (reg:CC FLAGS_REG))
17378 (clobber (mem:BLK (scratch)))])]
17379 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17380 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17381 [(clobber (match_dup 1))
17382 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17383 (clobber (mem:BLK (scratch)))])])
17384
17385 (define_peephole2
17386 [(match_scratch:W 1 "r")
17387 (parallel [(set (reg:P SP_REG)
17388 (plus:P (reg:P SP_REG)
17389 (match_operand:P 0 "const_int_operand" "")))
17390 (clobber (reg:CC FLAGS_REG))
17391 (clobber (mem:BLK (scratch)))])]
17392 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17393 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17394 [(clobber (match_dup 1))
17395 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17396 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17397 (clobber (mem:BLK (scratch)))])])
17398
17399 ;; Convert esp subtractions to push.
17400 (define_peephole2
17401 [(match_scratch:W 1 "r")
17402 (parallel [(set (reg:P SP_REG)
17403 (plus:P (reg:P SP_REG)
17404 (match_operand:P 0 "const_int_operand" "")))
17405 (clobber (reg:CC FLAGS_REG))])]
17406 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17407 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17408 [(clobber (match_dup 1))
17409 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17410
17411 (define_peephole2
17412 [(match_scratch:W 1 "r")
17413 (parallel [(set (reg:P SP_REG)
17414 (plus:P (reg:P SP_REG)
17415 (match_operand:P 0 "const_int_operand" "")))
17416 (clobber (reg:CC FLAGS_REG))])]
17417 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17418 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17419 [(clobber (match_dup 1))
17420 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17421 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17422
17423 ;; Convert epilogue deallocator to pop.
17424 (define_peephole2
17425 [(match_scratch:W 1 "r")
17426 (parallel [(set (reg:P SP_REG)
17427 (plus:P (reg:P SP_REG)
17428 (match_operand:P 0 "const_int_operand" "")))
17429 (clobber (reg:CC FLAGS_REG))
17430 (clobber (mem:BLK (scratch)))])]
17431 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17432 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17433 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17434 (clobber (mem:BLK (scratch)))])])
17435
17436 ;; Two pops case is tricky, since pop causes dependency
17437 ;; on destination register. We use two registers if available.
17438 (define_peephole2
17439 [(match_scratch:W 1 "r")
17440 (match_scratch:W 2 "r")
17441 (parallel [(set (reg:P SP_REG)
17442 (plus:P (reg:P SP_REG)
17443 (match_operand:P 0 "const_int_operand" "")))
17444 (clobber (reg:CC FLAGS_REG))
17445 (clobber (mem:BLK (scratch)))])]
17446 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17447 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17448 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17449 (clobber (mem:BLK (scratch)))])
17450 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17451
17452 (define_peephole2
17453 [(match_scratch:W 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 (clobber (mem:BLK (scratch)))])]
17459 "optimize_insn_for_size_p ()
17460 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17461 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17462 (clobber (mem:BLK (scratch)))])
17463 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17464
17465 ;; Convert esp additions to pop.
17466 (define_peephole2
17467 [(match_scratch:W 1 "r")
17468 (parallel [(set (reg:P SP_REG)
17469 (plus:P (reg:P SP_REG)
17470 (match_operand:P 0 "const_int_operand" "")))
17471 (clobber (reg:CC FLAGS_REG))])]
17472 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17473 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17474
17475 ;; Two pops case is tricky, since pop causes dependency
17476 ;; on destination register. We use two registers if available.
17477 (define_peephole2
17478 [(match_scratch:W 1 "r")
17479 (match_scratch:W 2 "r")
17480 (parallel [(set (reg:P SP_REG)
17481 (plus:P (reg:P SP_REG)
17482 (match_operand:P 0 "const_int_operand" "")))
17483 (clobber (reg:CC FLAGS_REG))])]
17484 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17485 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17486 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17487
17488 (define_peephole2
17489 [(match_scratch:W 1 "r")
17490 (parallel [(set (reg:P SP_REG)
17491 (plus:P (reg:P SP_REG)
17492 (match_operand:P 0 "const_int_operand" "")))
17493 (clobber (reg:CC FLAGS_REG))])]
17494 "optimize_insn_for_size_p ()
17495 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17496 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17497 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17498 \f
17499 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17500 ;; required and register dies. Similarly for 128 to -128.
17501 (define_peephole2
17502 [(set (match_operand 0 "flags_reg_operand" "")
17503 (match_operator 1 "compare_operator"
17504 [(match_operand 2 "register_operand" "")
17505 (match_operand 3 "const_int_operand" "")]))]
17506 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17507 && incdec_operand (operands[3], GET_MODE (operands[3])))
17508 || (!TARGET_FUSE_CMP_AND_BRANCH
17509 && INTVAL (operands[3]) == 128))
17510 && ix86_match_ccmode (insn, CCGCmode)
17511 && peep2_reg_dead_p (1, operands[2])"
17512 [(parallel [(set (match_dup 0)
17513 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17514 (clobber (match_dup 2))])])
17515 \f
17516 ;; Convert imul by three, five and nine into lea
17517 (define_peephole2
17518 [(parallel
17519 [(set (match_operand:SWI48 0 "register_operand" "")
17520 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17521 (match_operand:SWI48 2 "const359_operand" "")))
17522 (clobber (reg:CC FLAGS_REG))])]
17523 "!TARGET_PARTIAL_REG_STALL
17524 || <MODE>mode == SImode
17525 || optimize_function_for_size_p (cfun)"
17526 [(set (match_dup 0)
17527 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17528 (match_dup 1)))]
17529 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17530
17531 (define_peephole2
17532 [(parallel
17533 [(set (match_operand:SWI48 0 "register_operand" "")
17534 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17535 (match_operand:SWI48 2 "const359_operand" "")))
17536 (clobber (reg:CC FLAGS_REG))])]
17537 "optimize_insn_for_speed_p ()
17538 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17539 [(set (match_dup 0) (match_dup 1))
17540 (set (match_dup 0)
17541 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17542 (match_dup 0)))]
17543 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17544
17545 ;; imul $32bit_imm, mem, reg is vector decoded, while
17546 ;; imul $32bit_imm, reg, reg is direct decoded.
17547 (define_peephole2
17548 [(match_scratch:SWI48 3 "r")
17549 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17550 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17551 (match_operand:SWI48 2 "immediate_operand" "")))
17552 (clobber (reg:CC FLAGS_REG))])]
17553 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17554 && !satisfies_constraint_K (operands[2])"
17555 [(set (match_dup 3) (match_dup 1))
17556 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17557 (clobber (reg:CC FLAGS_REG))])])
17558
17559 (define_peephole2
17560 [(match_scratch:SI 3 "r")
17561 (parallel [(set (match_operand:DI 0 "register_operand" "")
17562 (zero_extend:DI
17563 (mult:SI (match_operand:SI 1 "memory_operand" "")
17564 (match_operand:SI 2 "immediate_operand" ""))))
17565 (clobber (reg:CC FLAGS_REG))])]
17566 "TARGET_64BIT
17567 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17568 && !satisfies_constraint_K (operands[2])"
17569 [(set (match_dup 3) (match_dup 1))
17570 (parallel [(set (match_dup 0)
17571 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17572 (clobber (reg:CC FLAGS_REG))])])
17573
17574 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17575 ;; Convert it into imul reg, reg
17576 ;; It would be better to force assembler to encode instruction using long
17577 ;; immediate, but there is apparently no way to do so.
17578 (define_peephole2
17579 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17580 (mult:SWI248
17581 (match_operand:SWI248 1 "nonimmediate_operand" "")
17582 (match_operand:SWI248 2 "const_int_operand" "")))
17583 (clobber (reg:CC FLAGS_REG))])
17584 (match_scratch:SWI248 3 "r")]
17585 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17586 && satisfies_constraint_K (operands[2])"
17587 [(set (match_dup 3) (match_dup 2))
17588 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17589 (clobber (reg:CC FLAGS_REG))])]
17590 {
17591 if (!rtx_equal_p (operands[0], operands[1]))
17592 emit_move_insn (operands[0], operands[1]);
17593 })
17594
17595 ;; After splitting up read-modify operations, array accesses with memory
17596 ;; operands might end up in form:
17597 ;; sall $2, %eax
17598 ;; movl 4(%esp), %edx
17599 ;; addl %edx, %eax
17600 ;; instead of pre-splitting:
17601 ;; sall $2, %eax
17602 ;; addl 4(%esp), %eax
17603 ;; Turn it into:
17604 ;; movl 4(%esp), %edx
17605 ;; leal (%edx,%eax,4), %eax
17606
17607 (define_peephole2
17608 [(match_scratch:W 5 "r")
17609 (parallel [(set (match_operand 0 "register_operand" "")
17610 (ashift (match_operand 1 "register_operand" "")
17611 (match_operand 2 "const_int_operand" "")))
17612 (clobber (reg:CC FLAGS_REG))])
17613 (parallel [(set (match_operand 3 "register_operand" "")
17614 (plus (match_dup 0)
17615 (match_operand 4 "x86_64_general_operand" "")))
17616 (clobber (reg:CC FLAGS_REG))])]
17617 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17618 /* Validate MODE for lea. */
17619 && ((!TARGET_PARTIAL_REG_STALL
17620 && (GET_MODE (operands[0]) == QImode
17621 || GET_MODE (operands[0]) == HImode))
17622 || GET_MODE (operands[0]) == SImode
17623 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17624 && (rtx_equal_p (operands[0], operands[3])
17625 || peep2_reg_dead_p (2, operands[0]))
17626 /* We reorder load and the shift. */
17627 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17628 [(set (match_dup 5) (match_dup 4))
17629 (set (match_dup 0) (match_dup 1))]
17630 {
17631 enum machine_mode op1mode = GET_MODE (operands[1]);
17632 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17633 int scale = 1 << INTVAL (operands[2]);
17634 rtx index = gen_lowpart (word_mode, operands[1]);
17635 rtx base = gen_lowpart (word_mode, operands[5]);
17636 rtx dest = gen_lowpart (mode, operands[3]);
17637
17638 operands[1] = gen_rtx_PLUS (word_mode, base,
17639 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17640 operands[5] = base;
17641 if (mode != word_mode)
17642 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17643 if (op1mode != word_mode)
17644 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17645 operands[0] = dest;
17646 })
17647 \f
17648 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17649 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17650 ;; caught for use by garbage collectors and the like. Using an insn that
17651 ;; maps to SIGILL makes it more likely the program will rightfully die.
17652 ;; Keeping with tradition, "6" is in honor of #UD.
17653 (define_insn "trap"
17654 [(trap_if (const_int 1) (const_int 6))]
17655 ""
17656 { return ASM_SHORT "0x0b0f"; }
17657 [(set_attr "length" "2")])
17658
17659 (define_expand "prefetch"
17660 [(prefetch (match_operand 0 "address_operand" "")
17661 (match_operand:SI 1 "const_int_operand" "")
17662 (match_operand:SI 2 "const_int_operand" ""))]
17663 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17664 {
17665 int rw = INTVAL (operands[1]);
17666 int locality = INTVAL (operands[2]);
17667
17668 gcc_assert (rw == 0 || rw == 1);
17669 gcc_assert (locality >= 0 && locality <= 3);
17670 gcc_assert (GET_MODE (operands[0]) == Pmode
17671 || GET_MODE (operands[0]) == VOIDmode);
17672
17673 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17674 supported by SSE counterpart or the SSE prefetch is not available
17675 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17676 of locality. */
17677 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17678 operands[2] = GEN_INT (3);
17679 else
17680 operands[1] = const0_rtx;
17681 })
17682
17683 (define_insn "*prefetch_sse_<mode>"
17684 [(prefetch (match_operand:P 0 "address_operand" "p")
17685 (const_int 0)
17686 (match_operand:SI 1 "const_int_operand" ""))]
17687 "TARGET_PREFETCH_SSE"
17688 {
17689 static const char * const patterns[4] = {
17690 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17691 };
17692
17693 int locality = INTVAL (operands[1]);
17694 gcc_assert (locality >= 0 && locality <= 3);
17695
17696 return patterns[locality];
17697 }
17698 [(set_attr "type" "sse")
17699 (set_attr "atom_sse_attr" "prefetch")
17700 (set (attr "length_address")
17701 (symbol_ref "memory_address_length (operands[0])"))
17702 (set_attr "memory" "none")])
17703
17704 (define_insn "*prefetch_3dnow_<mode>"
17705 [(prefetch (match_operand:P 0 "address_operand" "p")
17706 (match_operand:SI 1 "const_int_operand" "n")
17707 (const_int 3))]
17708 "TARGET_3DNOW"
17709 {
17710 if (INTVAL (operands[1]) == 0)
17711 return "prefetch\t%a0";
17712 else
17713 return "prefetchw\t%a0";
17714 }
17715 [(set_attr "type" "mmx")
17716 (set (attr "length_address")
17717 (symbol_ref "memory_address_length (operands[0])"))
17718 (set_attr "memory" "none")])
17719
17720 (define_expand "stack_protect_set"
17721 [(match_operand 0 "memory_operand" "")
17722 (match_operand 1 "memory_operand" "")]
17723 ""
17724 {
17725 rtx (*insn)(rtx, rtx);
17726
17727 #ifdef TARGET_THREAD_SSP_OFFSET
17728 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17729 insn = (TARGET_LP64
17730 ? gen_stack_tls_protect_set_di
17731 : gen_stack_tls_protect_set_si);
17732 #else
17733 insn = (TARGET_LP64
17734 ? gen_stack_protect_set_di
17735 : gen_stack_protect_set_si);
17736 #endif
17737
17738 emit_insn (insn (operands[0], operands[1]));
17739 DONE;
17740 })
17741
17742 (define_insn "stack_protect_set_<mode>"
17743 [(set (match_operand:PTR 0 "memory_operand" "=m")
17744 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17745 UNSPEC_SP_SET))
17746 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17747 (clobber (reg:CC FLAGS_REG))]
17748 ""
17749 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17750 [(set_attr "type" "multi")])
17751
17752 (define_insn "stack_tls_protect_set_<mode>"
17753 [(set (match_operand:PTR 0 "memory_operand" "=m")
17754 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17755 UNSPEC_SP_TLS_SET))
17756 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17757 (clobber (reg:CC FLAGS_REG))]
17758 ""
17759 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17760 [(set_attr "type" "multi")])
17761
17762 (define_expand "stack_protect_test"
17763 [(match_operand 0 "memory_operand" "")
17764 (match_operand 1 "memory_operand" "")
17765 (match_operand 2 "" "")]
17766 ""
17767 {
17768 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17769
17770 rtx (*insn)(rtx, rtx, rtx);
17771
17772 #ifdef TARGET_THREAD_SSP_OFFSET
17773 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17774 insn = (TARGET_LP64
17775 ? gen_stack_tls_protect_test_di
17776 : gen_stack_tls_protect_test_si);
17777 #else
17778 insn = (TARGET_LP64
17779 ? gen_stack_protect_test_di
17780 : gen_stack_protect_test_si);
17781 #endif
17782
17783 emit_insn (insn (flags, operands[0], operands[1]));
17784
17785 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17786 flags, const0_rtx, operands[2]));
17787 DONE;
17788 })
17789
17790 (define_insn "stack_protect_test_<mode>"
17791 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17792 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17793 (match_operand:PTR 2 "memory_operand" "m")]
17794 UNSPEC_SP_TEST))
17795 (clobber (match_scratch:PTR 3 "=&r"))]
17796 ""
17797 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17798 [(set_attr "type" "multi")])
17799
17800 (define_insn "stack_tls_protect_test_<mode>"
17801 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17802 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17803 (match_operand:PTR 2 "const_int_operand" "i")]
17804 UNSPEC_SP_TLS_TEST))
17805 (clobber (match_scratch:PTR 3 "=r"))]
17806 ""
17807 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17808 [(set_attr "type" "multi")])
17809
17810 (define_insn "sse4_2_crc32<mode>"
17811 [(set (match_operand:SI 0 "register_operand" "=r")
17812 (unspec:SI
17813 [(match_operand:SI 1 "register_operand" "0")
17814 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17815 UNSPEC_CRC32))]
17816 "TARGET_SSE4_2 || TARGET_CRC32"
17817 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17818 [(set_attr "type" "sselog1")
17819 (set_attr "prefix_rep" "1")
17820 (set_attr "prefix_extra" "1")
17821 (set (attr "prefix_data16")
17822 (if_then_else (match_operand:HI 2 "" "")
17823 (const_string "1")
17824 (const_string "*")))
17825 (set (attr "prefix_rex")
17826 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17827 (const_string "1")
17828 (const_string "*")))
17829 (set_attr "mode" "SI")])
17830
17831 (define_insn "sse4_2_crc32di"
17832 [(set (match_operand:DI 0 "register_operand" "=r")
17833 (unspec:DI
17834 [(match_operand:DI 1 "register_operand" "0")
17835 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17836 UNSPEC_CRC32))]
17837 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17838 "crc32{q}\t{%2, %0|%0, %2}"
17839 [(set_attr "type" "sselog1")
17840 (set_attr "prefix_rep" "1")
17841 (set_attr "prefix_extra" "1")
17842 (set_attr "mode" "DI")])
17843
17844 (define_expand "rdpmc"
17845 [(match_operand:DI 0 "register_operand" "")
17846 (match_operand:SI 1 "register_operand" "")]
17847 ""
17848 {
17849 rtx reg = gen_reg_rtx (DImode);
17850 rtx si;
17851
17852 /* Force operand 1 into ECX. */
17853 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17854 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17855 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17856 UNSPECV_RDPMC);
17857
17858 if (TARGET_64BIT)
17859 {
17860 rtvec vec = rtvec_alloc (2);
17861 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17862 rtx upper = gen_reg_rtx (DImode);
17863 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17864 gen_rtvec (1, const0_rtx),
17865 UNSPECV_RDPMC);
17866 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17867 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17868 emit_insn (load);
17869 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17870 NULL, 1, OPTAB_DIRECT);
17871 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17872 OPTAB_DIRECT);
17873 }
17874 else
17875 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17876 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17877 DONE;
17878 })
17879
17880 (define_insn "*rdpmc"
17881 [(set (match_operand:DI 0 "register_operand" "=A")
17882 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17883 UNSPECV_RDPMC))]
17884 "!TARGET_64BIT"
17885 "rdpmc"
17886 [(set_attr "type" "other")
17887 (set_attr "length" "2")])
17888
17889 (define_insn "*rdpmc_rex64"
17890 [(set (match_operand:DI 0 "register_operand" "=a")
17891 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17892 UNSPECV_RDPMC))
17893 (set (match_operand:DI 1 "register_operand" "=d")
17894 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17895 "TARGET_64BIT"
17896 "rdpmc"
17897 [(set_attr "type" "other")
17898 (set_attr "length" "2")])
17899
17900 (define_expand "rdtsc"
17901 [(set (match_operand:DI 0 "register_operand" "")
17902 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17903 ""
17904 {
17905 if (TARGET_64BIT)
17906 {
17907 rtvec vec = rtvec_alloc (2);
17908 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17909 rtx upper = gen_reg_rtx (DImode);
17910 rtx lower = gen_reg_rtx (DImode);
17911 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17912 gen_rtvec (1, const0_rtx),
17913 UNSPECV_RDTSC);
17914 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17915 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17916 emit_insn (load);
17917 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17918 NULL, 1, OPTAB_DIRECT);
17919 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17920 OPTAB_DIRECT);
17921 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17922 DONE;
17923 }
17924 })
17925
17926 (define_insn "*rdtsc"
17927 [(set (match_operand:DI 0 "register_operand" "=A")
17928 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17929 "!TARGET_64BIT"
17930 "rdtsc"
17931 [(set_attr "type" "other")
17932 (set_attr "length" "2")])
17933
17934 (define_insn "*rdtsc_rex64"
17935 [(set (match_operand:DI 0 "register_operand" "=a")
17936 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17937 (set (match_operand:DI 1 "register_operand" "=d")
17938 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17939 "TARGET_64BIT"
17940 "rdtsc"
17941 [(set_attr "type" "other")
17942 (set_attr "length" "2")])
17943
17944 (define_expand "rdtscp"
17945 [(match_operand:DI 0 "register_operand" "")
17946 (match_operand:SI 1 "memory_operand" "")]
17947 ""
17948 {
17949 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17950 gen_rtvec (1, const0_rtx),
17951 UNSPECV_RDTSCP);
17952 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17953 gen_rtvec (1, const0_rtx),
17954 UNSPECV_RDTSCP);
17955 rtx reg = gen_reg_rtx (DImode);
17956 rtx tmp = gen_reg_rtx (SImode);
17957
17958 if (TARGET_64BIT)
17959 {
17960 rtvec vec = rtvec_alloc (3);
17961 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17962 rtx upper = gen_reg_rtx (DImode);
17963 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17964 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17965 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17966 emit_insn (load);
17967 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17968 NULL, 1, OPTAB_DIRECT);
17969 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17970 OPTAB_DIRECT);
17971 }
17972 else
17973 {
17974 rtvec vec = rtvec_alloc (2);
17975 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17976 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17977 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17978 emit_insn (load);
17979 }
17980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17981 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17982 DONE;
17983 })
17984
17985 (define_insn "*rdtscp"
17986 [(set (match_operand:DI 0 "register_operand" "=A")
17987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17988 (set (match_operand:SI 1 "register_operand" "=c")
17989 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17990 "!TARGET_64BIT"
17991 "rdtscp"
17992 [(set_attr "type" "other")
17993 (set_attr "length" "3")])
17994
17995 (define_insn "*rdtscp_rex64"
17996 [(set (match_operand:DI 0 "register_operand" "=a")
17997 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17998 (set (match_operand:DI 1 "register_operand" "=d")
17999 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18000 (set (match_operand:SI 2 "register_operand" "=c")
18001 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18002 "TARGET_64BIT"
18003 "rdtscp"
18004 [(set_attr "type" "other")
18005 (set_attr "length" "3")])
18006
18007 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18008 ;;
18009 ;; LWP instructions
18010 ;;
18011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18012
18013 (define_expand "lwp_llwpcb"
18014 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18015 UNSPECV_LLWP_INTRINSIC)]
18016 "TARGET_LWP")
18017
18018 (define_insn "*lwp_llwpcb<mode>1"
18019 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18020 UNSPECV_LLWP_INTRINSIC)]
18021 "TARGET_LWP"
18022 "llwpcb\t%0"
18023 [(set_attr "type" "lwp")
18024 (set_attr "mode" "<MODE>")
18025 (set_attr "length" "5")])
18026
18027 (define_expand "lwp_slwpcb"
18028 [(set (match_operand 0 "register_operand" "=r")
18029 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18030 "TARGET_LWP"
18031 {
18032 rtx (*insn)(rtx);
18033
18034 insn = (TARGET_64BIT
18035 ? gen_lwp_slwpcbdi
18036 : gen_lwp_slwpcbsi);
18037
18038 emit_insn (insn (operands[0]));
18039 DONE;
18040 })
18041
18042 (define_insn "lwp_slwpcb<mode>"
18043 [(set (match_operand:P 0 "register_operand" "=r")
18044 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18045 "TARGET_LWP"
18046 "slwpcb\t%0"
18047 [(set_attr "type" "lwp")
18048 (set_attr "mode" "<MODE>")
18049 (set_attr "length" "5")])
18050
18051 (define_expand "lwp_lwpval<mode>3"
18052 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18053 (match_operand:SI 2 "nonimmediate_operand" "rm")
18054 (match_operand:SI 3 "const_int_operand" "i")]
18055 UNSPECV_LWPVAL_INTRINSIC)]
18056 "TARGET_LWP"
18057 ;; Avoid unused variable warning.
18058 "(void) operands[0];")
18059
18060 (define_insn "*lwp_lwpval<mode>3_1"
18061 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18062 (match_operand:SI 1 "nonimmediate_operand" "rm")
18063 (match_operand:SI 2 "const_int_operand" "i")]
18064 UNSPECV_LWPVAL_INTRINSIC)]
18065 "TARGET_LWP"
18066 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18067 [(set_attr "type" "lwp")
18068 (set_attr "mode" "<MODE>")
18069 (set (attr "length")
18070 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18071
18072 (define_expand "lwp_lwpins<mode>3"
18073 [(set (reg:CCC FLAGS_REG)
18074 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18075 (match_operand:SI 2 "nonimmediate_operand" "rm")
18076 (match_operand:SI 3 "const_int_operand" "i")]
18077 UNSPECV_LWPINS_INTRINSIC))
18078 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18079 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18080 "TARGET_LWP")
18081
18082 (define_insn "*lwp_lwpins<mode>3_1"
18083 [(set (reg:CCC FLAGS_REG)
18084 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18085 (match_operand:SI 1 "nonimmediate_operand" "rm")
18086 (match_operand:SI 2 "const_int_operand" "i")]
18087 UNSPECV_LWPINS_INTRINSIC))]
18088 "TARGET_LWP"
18089 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18090 [(set_attr "type" "lwp")
18091 (set_attr "mode" "<MODE>")
18092 (set (attr "length")
18093 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18094
18095 (define_insn "rdfsbase<mode>"
18096 [(set (match_operand:SWI48 0 "register_operand" "=r")
18097 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18098 "TARGET_64BIT && TARGET_FSGSBASE"
18099 "rdfsbase %0"
18100 [(set_attr "type" "other")
18101 (set_attr "prefix_extra" "2")])
18102
18103 (define_insn "rdgsbase<mode>"
18104 [(set (match_operand:SWI48 0 "register_operand" "=r")
18105 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18106 "TARGET_64BIT && TARGET_FSGSBASE"
18107 "rdgsbase %0"
18108 [(set_attr "type" "other")
18109 (set_attr "prefix_extra" "2")])
18110
18111 (define_insn "wrfsbase<mode>"
18112 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18113 UNSPECV_WRFSBASE)]
18114 "TARGET_64BIT && TARGET_FSGSBASE"
18115 "wrfsbase %0"
18116 [(set_attr "type" "other")
18117 (set_attr "prefix_extra" "2")])
18118
18119 (define_insn "wrgsbase<mode>"
18120 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18121 UNSPECV_WRGSBASE)]
18122 "TARGET_64BIT && TARGET_FSGSBASE"
18123 "wrgsbase %0"
18124 [(set_attr "type" "other")
18125 (set_attr "prefix_extra" "2")])
18126
18127 (define_insn "rdrand<mode>_1"
18128 [(set (match_operand:SWI248 0 "register_operand" "=r")
18129 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18130 (set (reg:CCC FLAGS_REG)
18131 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18132 "TARGET_RDRND"
18133 "rdrand\t%0"
18134 [(set_attr "type" "other")
18135 (set_attr "prefix_extra" "1")])
18136
18137 (define_expand "pause"
18138 [(set (match_dup 0)
18139 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18140 ""
18141 {
18142 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18143 MEM_VOLATILE_P (operands[0]) = 1;
18144 })
18145
18146 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18147 ;; They have the same encoding.
18148 (define_insn "*pause"
18149 [(set (match_operand:BLK 0 "" "")
18150 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18151 ""
18152 "rep; nop"
18153 [(set_attr "length" "2")
18154 (set_attr "memory" "unknown")])
18155
18156 (include "mmx.md")
18157 (include "sse.md")
18158 (include "sync.md")