beaf5327dfaa442349698b2e25dea9cb92923b6c
[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
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
67 UNSPEC_GOT
68 UNSPEC_GOTOFF
69 UNSPEC_GOTPCREL
70 UNSPEC_GOTTPOFF
71 UNSPEC_TPOFF
72 UNSPEC_NTPOFF
73 UNSPEC_DTPOFF
74 UNSPEC_GOTNTPOFF
75 UNSPEC_INDNTPOFF
76 UNSPEC_PLTOFF
77 UNSPEC_MACHOPIC_OFFSET
78 UNSPEC_PCREL
79
80 ;; Prologue support
81 UNSPEC_STACK_ALLOC
82 UNSPEC_SET_GOT
83 UNSPEC_REG_SAVE
84 UNSPEC_DEF_CFA
85 UNSPEC_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_STACK_CHECK
89
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
95 UNSPEC_TLS_IE_SUN
96
97 ;; Other random patterns
98 UNSPEC_SCAS
99 UNSPEC_FNSTSW
100 UNSPEC_SAHF
101 UNSPEC_PARITY
102 UNSPEC_FSTCW
103 UNSPEC_ADD_CARRY
104 UNSPEC_FLDCW
105 UNSPEC_REP
106 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_TRUNC_NOOP
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
110 UNSPEC_CALL_NEEDS_VZEROUPPER
111 UNSPEC_PAUSE
112
113 ;; For SSE/MMX support:
114 UNSPEC_FIX_NOTRUNC
115 UNSPEC_MASKMOV
116 UNSPEC_MOVMSK
117 UNSPEC_RCP
118 UNSPEC_RSQRT
119 UNSPEC_PSADBW
120
121 ;; Generic math support
122 UNSPEC_COPYSIGN
123 UNSPEC_IEEE_MIN ; not commutative
124 UNSPEC_IEEE_MAX ; not commutative
125
126 ;; x87 Floating point
127 UNSPEC_SIN
128 UNSPEC_COS
129 UNSPEC_FPATAN
130 UNSPEC_FYL2X
131 UNSPEC_FYL2XP1
132 UNSPEC_FRNDINT
133 UNSPEC_FIST
134 UNSPEC_F2XM1
135 UNSPEC_TAN
136 UNSPEC_FXAM
137
138 ;; x87 Rounding
139 UNSPEC_FRNDINT_FLOOR
140 UNSPEC_FRNDINT_CEIL
141 UNSPEC_FRNDINT_TRUNC
142 UNSPEC_FRNDINT_MASK_PM
143 UNSPEC_FIST_FLOOR
144 UNSPEC_FIST_CEIL
145
146 ;; x87 Double output FP
147 UNSPEC_SINCOS_COS
148 UNSPEC_SINCOS_SIN
149 UNSPEC_XTRACT_FRACT
150 UNSPEC_XTRACT_EXP
151 UNSPEC_FSCALE_FRACT
152 UNSPEC_FSCALE_EXP
153 UNSPEC_FPREM_F
154 UNSPEC_FPREM_U
155 UNSPEC_FPREM1_F
156 UNSPEC_FPREM1_U
157
158 UNSPEC_C2_FLAG
159 UNSPEC_FXAM_MEM
160
161 ;; SSP patterns
162 UNSPEC_SP_SET
163 UNSPEC_SP_TEST
164 UNSPEC_SP_TLS_SET
165 UNSPEC_SP_TLS_TEST
166
167 ;; For ROUND support
168 UNSPEC_ROUND
169
170 ;; For CRC32 support
171 UNSPEC_CRC32
172
173 ;; For RDRAND support
174 UNSPEC_RDRAND
175
176 ;; For BMI support
177 UNSPEC_BEXTR
178
179 ;; For BMI2 support
180 UNSPEC_PDEP
181 UNSPEC_PEXT
182 ])
183
184 (define_c_enum "unspecv" [
185 UNSPECV_BLOCKAGE
186 UNSPECV_STACK_PROBE
187 UNSPECV_PROBE_STACK_RANGE
188 UNSPECV_ALIGN
189 UNSPECV_PROLOGUE_USE
190 UNSPECV_SPLIT_STACK_RETURN
191 UNSPECV_CLD
192 UNSPECV_NOPS
193 UNSPECV_RDTSC
194 UNSPECV_RDTSCP
195 UNSPECV_RDPMC
196 UNSPECV_LLWP_INTRINSIC
197 UNSPECV_SLWP_INTRINSIC
198 UNSPECV_LWPVAL_INTRINSIC
199 UNSPECV_LWPINS_INTRINSIC
200 UNSPECV_RDFSBASE
201 UNSPECV_RDGSBASE
202 UNSPECV_WRFSBASE
203 UNSPECV_WRGSBASE
204 ])
205
206 ;; Constants to represent rounding modes in the ROUND instruction
207 (define_constants
208 [(ROUND_FLOOR 0x1)
209 (ROUND_CEIL 0x2)
210 (ROUND_TRUNC 0x3)
211 (ROUND_MXCSR 0x4)
212 (ROUND_NO_EXC 0x8)
213 ])
214
215 ;; Constants to represent pcomtrue/pcomfalse variants
216 (define_constants
217 [(PCOM_FALSE 0)
218 (PCOM_TRUE 1)
219 (COM_FALSE_S 2)
220 (COM_FALSE_P 3)
221 (COM_TRUE_S 4)
222 (COM_TRUE_P 5)
223 ])
224
225 ;; Constants used in the XOP pperm instruction
226 (define_constants
227 [(PPERM_SRC 0x00) /* copy source */
228 (PPERM_INVERT 0x20) /* invert source */
229 (PPERM_REVERSE 0x40) /* bit reverse source */
230 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
231 (PPERM_ZERO 0x80) /* all 0's */
232 (PPERM_ONES 0xa0) /* all 1's */
233 (PPERM_SIGN 0xc0) /* propagate sign bit */
234 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
235 (PPERM_SRC1 0x00) /* use first source byte */
236 (PPERM_SRC2 0x10) /* use second source byte */
237 ])
238
239 ;; Registers by name.
240 (define_constants
241 [(AX_REG 0)
242 (DX_REG 1)
243 (CX_REG 2)
244 (BX_REG 3)
245 (SI_REG 4)
246 (DI_REG 5)
247 (BP_REG 6)
248 (SP_REG 7)
249 (ST0_REG 8)
250 (ST1_REG 9)
251 (ST2_REG 10)
252 (ST3_REG 11)
253 (ST4_REG 12)
254 (ST5_REG 13)
255 (ST6_REG 14)
256 (ST7_REG 15)
257 (FLAGS_REG 17)
258 (FPSR_REG 18)
259 (FPCR_REG 19)
260 (XMM0_REG 21)
261 (XMM1_REG 22)
262 (XMM2_REG 23)
263 (XMM3_REG 24)
264 (XMM4_REG 25)
265 (XMM5_REG 26)
266 (XMM6_REG 27)
267 (XMM7_REG 28)
268 (MM0_REG 29)
269 (MM1_REG 30)
270 (MM2_REG 31)
271 (MM3_REG 32)
272 (MM4_REG 33)
273 (MM5_REG 34)
274 (MM6_REG 35)
275 (MM7_REG 36)
276 (R8_REG 37)
277 (R9_REG 38)
278 (R10_REG 39)
279 (R11_REG 40)
280 (R12_REG 41)
281 (R13_REG 42)
282 (XMM8_REG 45)
283 (XMM9_REG 46)
284 (XMM10_REG 47)
285 (XMM11_REG 48)
286 (XMM12_REG 49)
287 (XMM13_REG 50)
288 (XMM14_REG 51)
289 (XMM15_REG 52)
290 ])
291
292 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
293 ;; from i386.c.
294
295 ;; In C guard expressions, put expressions which may be compile-time
296 ;; constants first. This allows for better optimization. For
297 ;; example, write "TARGET_64BIT && reload_completed", not
298 ;; "reload_completed && TARGET_64BIT".
299
300 \f
301 ;; Processor type.
302 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
303 atom,generic64,amdfam10,bdver1,bdver2,btver1"
304 (const (symbol_ref "ix86_schedule")))
305
306 ;; A basic instruction type. Refinements due to arguments to be
307 ;; provided in other attributes.
308 (define_attr "type"
309 "other,multi,
310 alu,alu1,negnot,imov,imovx,lea,
311 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
312 icmp,test,ibr,setcc,icmov,
313 push,pop,call,callv,leave,
314 str,bitmanip,
315 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
316 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
317 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
318 ssemuladd,sse4arg,lwp,
319 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
320 (const_string "other"))
321
322 ;; Main data type used by the insn
323 (define_attr "mode"
324 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
325 (const_string "unknown"))
326
327 ;; The CPU unit operations uses.
328 (define_attr "unit" "integer,i387,sse,mmx,unknown"
329 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
330 (const_string "i387")
331 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
332 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
333 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
334 (const_string "sse")
335 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
336 (const_string "mmx")
337 (eq_attr "type" "other")
338 (const_string "unknown")]
339 (const_string "integer")))
340
341 ;; The (bounding maximum) length of an instruction immediate.
342 (define_attr "length_immediate" ""
343 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
344 bitmanip,imulx")
345 (const_int 0)
346 (eq_attr "unit" "i387,sse,mmx")
347 (const_int 0)
348 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
349 rotate,rotatex,rotate1,imul,icmp,push,pop")
350 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
351 (eq_attr "type" "imov,test")
352 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
353 (eq_attr "type" "call")
354 (if_then_else (match_operand 0 "constant_call_address_operand" "")
355 (const_int 4)
356 (const_int 0))
357 (eq_attr "type" "callv")
358 (if_then_else (match_operand 1 "constant_call_address_operand" "")
359 (const_int 4)
360 (const_int 0))
361 ;; We don't know the size before shorten_branches. Expect
362 ;; the instruction to fit for better scheduling.
363 (eq_attr "type" "ibr")
364 (const_int 1)
365 ]
366 (symbol_ref "/* Update immediate_length and other attributes! */
367 gcc_unreachable (),1")))
368
369 ;; The (bounding maximum) length of an instruction address.
370 (define_attr "length_address" ""
371 (cond [(eq_attr "type" "str,other,multi,fxch")
372 (const_int 0)
373 (and (eq_attr "type" "call")
374 (match_operand 0 "constant_call_address_operand" ""))
375 (const_int 0)
376 (and (eq_attr "type" "callv")
377 (match_operand 1 "constant_call_address_operand" ""))
378 (const_int 0)
379 ]
380 (symbol_ref "ix86_attr_length_address_default (insn)")))
381
382 ;; Set when length prefix is used.
383 (define_attr "prefix_data16" ""
384 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
385 (const_int 0)
386 (eq_attr "mode" "HI")
387 (const_int 1)
388 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
389 (const_int 1)
390 ]
391 (const_int 0)))
392
393 ;; Set when string REP prefix is used.
394 (define_attr "prefix_rep" ""
395 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
396 (const_int 0)
397 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
398 (const_int 1)
399 ]
400 (const_int 0)))
401
402 ;; Set when 0f opcode prefix is used.
403 (define_attr "prefix_0f" ""
404 (if_then_else
405 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
406 (eq_attr "unit" "sse,mmx"))
407 (const_int 1)
408 (const_int 0)))
409
410 ;; Set when REX opcode prefix is used.
411 (define_attr "prefix_rex" ""
412 (cond [(not (match_test "TARGET_64BIT"))
413 (const_int 0)
414 (and (eq_attr "mode" "DI")
415 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
416 (eq_attr "unit" "!mmx")))
417 (const_int 1)
418 (and (eq_attr "mode" "QI")
419 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
420 (const_int 1)
421 (match_test "x86_extended_reg_mentioned_p (insn)")
422 (const_int 1)
423 (and (eq_attr "type" "imovx")
424 (match_operand:QI 1 "ext_QIreg_operand" ""))
425 (const_int 1)
426 ]
427 (const_int 0)))
428
429 ;; There are also additional prefixes in 3DNOW, SSSE3.
430 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
431 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
432 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
433 (define_attr "prefix_extra" ""
434 (cond [(eq_attr "type" "ssemuladd,sse4arg")
435 (const_int 2)
436 (eq_attr "type" "sseiadd1,ssecvt1")
437 (const_int 1)
438 ]
439 (const_int 0)))
440
441 ;; Prefix used: original, VEX or maybe VEX.
442 (define_attr "prefix" "orig,vex,maybe_vex"
443 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
444 (const_string "vex")
445 (const_string "orig")))
446
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
449
450 ;; The length of VEX prefix
451 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
452 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
453 ;; still prefix_0f 1, with prefix_extra 1.
454 (define_attr "length_vex" ""
455 (if_then_else (and (eq_attr "prefix_0f" "1")
456 (eq_attr "prefix_extra" "0"))
457 (if_then_else (eq_attr "prefix_vex_w" "1")
458 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
459 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
460 (if_then_else (eq_attr "prefix_vex_w" "1")
461 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
462 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
463
464 ;; Set when modrm byte is used.
465 (define_attr "modrm" ""
466 (cond [(eq_attr "type" "str,leave")
467 (const_int 0)
468 (eq_attr "unit" "i387")
469 (const_int 0)
470 (and (eq_attr "type" "incdec")
471 (and (not (match_test "TARGET_64BIT"))
472 (ior (match_operand:SI 1 "register_operand" "")
473 (match_operand:HI 1 "register_operand" ""))))
474 (const_int 0)
475 (and (eq_attr "type" "push")
476 (not (match_operand 1 "memory_operand" "")))
477 (const_int 0)
478 (and (eq_attr "type" "pop")
479 (not (match_operand 0 "memory_operand" "")))
480 (const_int 0)
481 (and (eq_attr "type" "imov")
482 (and (not (eq_attr "mode" "DI"))
483 (ior (and (match_operand 0 "register_operand" "")
484 (match_operand 1 "immediate_operand" ""))
485 (ior (and (match_operand 0 "ax_reg_operand" "")
486 (match_operand 1 "memory_displacement_only_operand" ""))
487 (and (match_operand 0 "memory_displacement_only_operand" "")
488 (match_operand 1 "ax_reg_operand" ""))))))
489 (const_int 0)
490 (and (eq_attr "type" "call")
491 (match_operand 0 "constant_call_address_operand" ""))
492 (const_int 0)
493 (and (eq_attr "type" "callv")
494 (match_operand 1 "constant_call_address_operand" ""))
495 (const_int 0)
496 (and (eq_attr "type" "alu,alu1,icmp,test")
497 (match_operand 0 "ax_reg_operand" ""))
498 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
499 ]
500 (const_int 1)))
501
502 ;; The (bounding maximum) length of an instruction in bytes.
503 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
504 ;; Later we may want to split them and compute proper length as for
505 ;; other insns.
506 (define_attr "length" ""
507 (cond [(eq_attr "type" "other,multi,fistp,frndint")
508 (const_int 16)
509 (eq_attr "type" "fcmp")
510 (const_int 4)
511 (eq_attr "unit" "i387")
512 (plus (const_int 2)
513 (plus (attr "prefix_data16")
514 (attr "length_address")))
515 (ior (eq_attr "prefix" "vex")
516 (and (eq_attr "prefix" "maybe_vex")
517 (match_test "TARGET_AVX")))
518 (plus (attr "length_vex")
519 (plus (attr "length_immediate")
520 (plus (attr "modrm")
521 (attr "length_address"))))]
522 (plus (plus (attr "modrm")
523 (plus (attr "prefix_0f")
524 (plus (attr "prefix_rex")
525 (plus (attr "prefix_extra")
526 (const_int 1)))))
527 (plus (attr "prefix_rep")
528 (plus (attr "prefix_data16")
529 (plus (attr "length_immediate")
530 (attr "length_address")))))))
531
532 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
533 ;; `store' if there is a simple memory reference therein, or `unknown'
534 ;; if the instruction is complex.
535
536 (define_attr "memory" "none,load,store,both,unknown"
537 (cond [(eq_attr "type" "other,multi,str,lwp")
538 (const_string "unknown")
539 (eq_attr "type" "lea,fcmov,fpspc")
540 (const_string "none")
541 (eq_attr "type" "fistp,leave")
542 (const_string "both")
543 (eq_attr "type" "frndint")
544 (const_string "load")
545 (eq_attr "type" "push")
546 (if_then_else (match_operand 1 "memory_operand" "")
547 (const_string "both")
548 (const_string "store"))
549 (eq_attr "type" "pop")
550 (if_then_else (match_operand 0 "memory_operand" "")
551 (const_string "both")
552 (const_string "load"))
553 (eq_attr "type" "setcc")
554 (if_then_else (match_operand 0 "memory_operand" "")
555 (const_string "store")
556 (const_string "none"))
557 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
558 (if_then_else (ior (match_operand 0 "memory_operand" "")
559 (match_operand 1 "memory_operand" ""))
560 (const_string "load")
561 (const_string "none"))
562 (eq_attr "type" "ibr")
563 (if_then_else (match_operand 0 "memory_operand" "")
564 (const_string "load")
565 (const_string "none"))
566 (eq_attr "type" "call")
567 (if_then_else (match_operand 0 "constant_call_address_operand" "")
568 (const_string "none")
569 (const_string "load"))
570 (eq_attr "type" "callv")
571 (if_then_else (match_operand 1 "constant_call_address_operand" "")
572 (const_string "none")
573 (const_string "load"))
574 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
575 (match_operand 1 "memory_operand" ""))
576 (const_string "both")
577 (and (match_operand 0 "memory_operand" "")
578 (match_operand 1 "memory_operand" ""))
579 (const_string "both")
580 (match_operand 0 "memory_operand" "")
581 (const_string "store")
582 (match_operand 1 "memory_operand" "")
583 (const_string "load")
584 (and (eq_attr "type"
585 "!alu1,negnot,ishift1,
586 imov,imovx,icmp,test,bitmanip,
587 fmov,fcmp,fsgn,
588 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
589 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
590 (match_operand 2 "memory_operand" ""))
591 (const_string "load")
592 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
593 (match_operand 3 "memory_operand" ""))
594 (const_string "load")
595 ]
596 (const_string "none")))
597
598 ;; Indicates if an instruction has both an immediate and a displacement.
599
600 (define_attr "imm_disp" "false,true,unknown"
601 (cond [(eq_attr "type" "other,multi")
602 (const_string "unknown")
603 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
604 (and (match_operand 0 "memory_displacement_operand" "")
605 (match_operand 1 "immediate_operand" "")))
606 (const_string "true")
607 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
608 (and (match_operand 0 "memory_displacement_operand" "")
609 (match_operand 2 "immediate_operand" "")))
610 (const_string "true")
611 ]
612 (const_string "false")))
613
614 ;; Indicates if an FP operation has an integer source.
615
616 (define_attr "fp_int_src" "false,true"
617 (const_string "false"))
618
619 ;; Defines rounding mode of an FP operation.
620
621 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
622 (const_string "any"))
623
624 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
625 (define_attr "use_carry" "0,1" (const_string "0"))
626
627 ;; Define attribute to indicate unaligned ssemov insns
628 (define_attr "movu" "0,1" (const_string "0"))
629
630 ;; Used to control the "enabled" attribute on a per-instruction basis.
631 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
632 (const_string "base"))
633
634 (define_attr "enabled" ""
635 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
636 (eq_attr "isa" "sse2_noavx")
637 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
638 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
639 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
640 (eq_attr "isa" "sse4_noavx")
641 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
642 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
643 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
644 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
645 ]
646 (const_int 1)))
647
648 ;; Describe a user's asm statement.
649 (define_asm_attributes
650 [(set_attr "length" "128")
651 (set_attr "type" "multi")])
652
653 (define_code_iterator plusminus [plus minus])
654
655 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
656
657 ;; Base name for define_insn
658 (define_code_attr plusminus_insn
659 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
660 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
661
662 ;; Base name for insn mnemonic.
663 (define_code_attr plusminus_mnemonic
664 [(plus "add") (ss_plus "adds") (us_plus "addus")
665 (minus "sub") (ss_minus "subs") (us_minus "subus")])
666 (define_code_attr plusminus_carry_mnemonic
667 [(plus "adc") (minus "sbb")])
668
669 ;; Mark commutative operators as such in constraints.
670 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
671 (minus "") (ss_minus "") (us_minus "")])
672
673 ;; Mapping of max and min
674 (define_code_iterator maxmin [smax smin umax umin])
675
676 ;; Mapping of signed max and min
677 (define_code_iterator smaxmin [smax smin])
678
679 ;; Mapping of unsigned max and min
680 (define_code_iterator umaxmin [umax umin])
681
682 ;; Base name for integer and FP insn mnemonic
683 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
684 (umax "maxu") (umin "minu")])
685 (define_code_attr maxmin_float [(smax "max") (smin "min")])
686
687 ;; Mapping of logic operators
688 (define_code_iterator any_logic [and ior xor])
689 (define_code_iterator any_or [ior xor])
690
691 ;; Base name for insn mnemonic.
692 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
693
694 ;; Mapping of logic-shift operators
695 (define_code_iterator any_lshift [ashift lshiftrt])
696
697 ;; Mapping of shift-right operators
698 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
699
700 ;; Base name for define_insn
701 (define_code_attr shift_insn
702 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
703
704 ;; Base name for insn mnemonic.
705 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
706 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
707
708 ;; Mapping of rotate operators
709 (define_code_iterator any_rotate [rotate rotatert])
710
711 ;; Base name for define_insn
712 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
713
714 ;; Base name for insn mnemonic.
715 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
716
717 ;; Mapping of abs neg operators
718 (define_code_iterator absneg [abs neg])
719
720 ;; Base name for x87 insn mnemonic.
721 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
722
723 ;; Used in signed and unsigned widening multiplications.
724 (define_code_iterator any_extend [sign_extend zero_extend])
725
726 ;; Prefix for insn menmonic.
727 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
728
729 ;; Prefix for define_insn
730 (define_code_attr u [(sign_extend "") (zero_extend "u")])
731 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
732
733 ;; All integer modes.
734 (define_mode_iterator SWI1248x [QI HI SI DI])
735
736 ;; All integer modes without QImode.
737 (define_mode_iterator SWI248x [HI SI DI])
738
739 ;; All integer modes without QImode and HImode.
740 (define_mode_iterator SWI48x [SI DI])
741
742 ;; All integer modes without SImode and DImode.
743 (define_mode_iterator SWI12 [QI HI])
744
745 ;; All integer modes without DImode.
746 (define_mode_iterator SWI124 [QI HI SI])
747
748 ;; All integer modes without QImode and DImode.
749 (define_mode_iterator SWI24 [HI SI])
750
751 ;; Single word integer modes.
752 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
753
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
756
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
759
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762 (HI "TARGET_HIMODE_MATH")
763 SI DI (TI "TARGET_64BIT")])
764
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767 (HI "TARGET_HIMODE_MATH")
768 SI (DI "TARGET_64BIT")])
769
770 ;; Math-dependant integer modes without DImode.
771 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
772 (HI "TARGET_HIMODE_MATH")
773 SI])
774
775 ;; Math-dependant single word integer modes without QImode.
776 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
777 SI (DI "TARGET_64BIT")])
778
779 ;; Double word integer modes.
780 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
781 (TI "TARGET_64BIT")])
782
783 ;; Double word integer modes as mode attribute.
784 (define_mode_attr DWI [(SI "DI") (DI "TI")])
785 (define_mode_attr dwi [(SI "di") (DI "ti")])
786
787 ;; Half mode for double word integer modes.
788 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
789 (DI "TARGET_64BIT")])
790
791 ;; Instruction suffix for integer modes.
792 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
793
794 ;; Pointer size prefix for integer modes (Intel asm dialect)
795 (define_mode_attr iptrsize [(QI "BYTE")
796 (HI "WORD")
797 (SI "DWORD")
798 (DI "QWORD")])
799
800 ;; Register class for integer modes.
801 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
802
803 ;; Immediate operand constraint for integer modes.
804 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
805
806 ;; General operand constraint for word modes.
807 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
808
809 ;; Immediate operand constraint for double integer modes.
810 (define_mode_attr di [(SI "nF") (DI "e")])
811
812 ;; Immediate operand constraint for shifts.
813 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
814
815 ;; General operand predicate for integer modes.
816 (define_mode_attr general_operand
817 [(QI "general_operand")
818 (HI "general_operand")
819 (SI "x86_64_general_operand")
820 (DI "x86_64_general_operand")
821 (TI "x86_64_general_operand")])
822
823 ;; General sign/zero extend operand predicate for integer modes.
824 (define_mode_attr general_szext_operand
825 [(QI "general_operand")
826 (HI "general_operand")
827 (SI "x86_64_szext_general_operand")
828 (DI "x86_64_szext_general_operand")])
829
830 ;; Immediate operand predicate for integer modes.
831 (define_mode_attr immediate_operand
832 [(QI "immediate_operand")
833 (HI "immediate_operand")
834 (SI "x86_64_immediate_operand")
835 (DI "x86_64_immediate_operand")])
836
837 ;; Nonmemory operand predicate for integer modes.
838 (define_mode_attr nonmemory_operand
839 [(QI "nonmemory_operand")
840 (HI "nonmemory_operand")
841 (SI "x86_64_nonmemory_operand")
842 (DI "x86_64_nonmemory_operand")])
843
844 ;; Operand predicate for shifts.
845 (define_mode_attr shift_operand
846 [(QI "nonimmediate_operand")
847 (HI "nonimmediate_operand")
848 (SI "nonimmediate_operand")
849 (DI "shiftdi_operand")
850 (TI "register_operand")])
851
852 ;; Operand predicate for shift argument.
853 (define_mode_attr shift_immediate_operand
854 [(QI "const_1_to_31_operand")
855 (HI "const_1_to_31_operand")
856 (SI "const_1_to_31_operand")
857 (DI "const_1_to_63_operand")])
858
859 ;; Input operand predicate for arithmetic left shifts.
860 (define_mode_attr ashl_input_operand
861 [(QI "nonimmediate_operand")
862 (HI "nonimmediate_operand")
863 (SI "nonimmediate_operand")
864 (DI "ashldi_input_operand")
865 (TI "reg_or_pm1_operand")])
866
867 ;; SSE and x87 SFmode and DFmode floating point modes
868 (define_mode_iterator MODEF [SF DF])
869
870 ;; All x87 floating point modes
871 (define_mode_iterator X87MODEF [SF DF XF])
872
873 ;; SSE instruction suffix for various modes
874 (define_mode_attr ssemodesuffix
875 [(SF "ss") (DF "sd")
876 (V8SF "ps") (V4DF "pd")
877 (V4SF "ps") (V2DF "pd")
878 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
879 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
880
881 ;; SSE vector suffix for floating point modes
882 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
883
884 ;; SSE vector mode corresponding to a scalar mode
885 (define_mode_attr ssevecmode
886 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
887
888 ;; Instruction suffix for REX 64bit operators.
889 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
890
891 ;; This mode iterator allows :P to be used for patterns that operate on
892 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
893 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
894
895 ;; This mode iterator allows :PTR to be used for patterns that operate on
896 ;; ptr_mode sized quantities.
897 (define_mode_iterator PTR
898 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
899 \f
900 ;; Scheduling descriptions
901
902 (include "pentium.md")
903 (include "ppro.md")
904 (include "k6.md")
905 (include "athlon.md")
906 (include "bdver1.md")
907 (include "geode.md")
908 (include "atom.md")
909 (include "core2.md")
910
911 \f
912 ;; Operand and operator predicates and constraints
913
914 (include "predicates.md")
915 (include "constraints.md")
916
917 \f
918 ;; Compare and branch/compare and store instructions.
919
920 (define_expand "cbranch<mode>4"
921 [(set (reg:CC FLAGS_REG)
922 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
923 (match_operand:SDWIM 2 "<general_operand>" "")))
924 (set (pc) (if_then_else
925 (match_operator 0 "ordered_comparison_operator"
926 [(reg:CC FLAGS_REG) (const_int 0)])
927 (label_ref (match_operand 3 "" ""))
928 (pc)))]
929 ""
930 {
931 if (MEM_P (operands[1]) && MEM_P (operands[2]))
932 operands[1] = force_reg (<MODE>mode, operands[1]);
933 ix86_expand_branch (GET_CODE (operands[0]),
934 operands[1], operands[2], operands[3]);
935 DONE;
936 })
937
938 (define_expand "cstore<mode>4"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
941 (match_operand:SWIM 3 "<general_operand>" "")))
942 (set (match_operand:QI 0 "register_operand" "")
943 (match_operator 1 "ordered_comparison_operator"
944 [(reg:CC FLAGS_REG) (const_int 0)]))]
945 ""
946 {
947 if (MEM_P (operands[2]) && MEM_P (operands[3]))
948 operands[2] = force_reg (<MODE>mode, operands[2]);
949 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
950 operands[2], operands[3]);
951 DONE;
952 })
953
954 (define_expand "cmp<mode>_1"
955 [(set (reg:CC FLAGS_REG)
956 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
957 (match_operand:SWI48 1 "<general_operand>" "")))])
958
959 (define_insn "*cmp<mode>_ccno_1"
960 [(set (reg FLAGS_REG)
961 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
962 (match_operand:SWI 1 "const0_operand" "")))]
963 "ix86_match_ccmode (insn, CCNOmode)"
964 "@
965 test{<imodesuffix>}\t%0, %0
966 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
967 [(set_attr "type" "test,icmp")
968 (set_attr "length_immediate" "0,1")
969 (set_attr "mode" "<MODE>")])
970
971 (define_insn "*cmp<mode>_1"
972 [(set (reg FLAGS_REG)
973 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
974 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
975 "ix86_match_ccmode (insn, CCmode)"
976 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977 [(set_attr "type" "icmp")
978 (set_attr "mode" "<MODE>")])
979
980 (define_insn "*cmp<mode>_minus_1"
981 [(set (reg FLAGS_REG)
982 (compare
983 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
985 (const_int 0)))]
986 "ix86_match_ccmode (insn, CCGOCmode)"
987 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988 [(set_attr "type" "icmp")
989 (set_attr "mode" "<MODE>")])
990
991 (define_insn "*cmpqi_ext_1"
992 [(set (reg FLAGS_REG)
993 (compare
994 (match_operand:QI 0 "general_operand" "Qm")
995 (subreg:QI
996 (zero_extract:SI
997 (match_operand 1 "ext_register_operand" "Q")
998 (const_int 8)
999 (const_int 8)) 0)))]
1000 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001 "cmp{b}\t{%h1, %0|%0, %h1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "QI")])
1004
1005 (define_insn "*cmpqi_ext_1_rex64"
1006 [(set (reg FLAGS_REG)
1007 (compare
1008 (match_operand:QI 0 "register_operand" "Q")
1009 (subreg:QI
1010 (zero_extract:SI
1011 (match_operand 1 "ext_register_operand" "Q")
1012 (const_int 8)
1013 (const_int 8)) 0)))]
1014 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015 "cmp{b}\t{%h1, %0|%0, %h1}"
1016 [(set_attr "type" "icmp")
1017 (set_attr "mode" "QI")])
1018
1019 (define_insn "*cmpqi_ext_2"
1020 [(set (reg FLAGS_REG)
1021 (compare
1022 (subreg:QI
1023 (zero_extract:SI
1024 (match_operand 0 "ext_register_operand" "Q")
1025 (const_int 8)
1026 (const_int 8)) 0)
1027 (match_operand:QI 1 "const0_operand" "")))]
1028 "ix86_match_ccmode (insn, CCNOmode)"
1029 "test{b}\t%h0, %h0"
1030 [(set_attr "type" "test")
1031 (set_attr "length_immediate" "0")
1032 (set_attr "mode" "QI")])
1033
1034 (define_expand "cmpqi_ext_3"
1035 [(set (reg:CC FLAGS_REG)
1036 (compare:CC
1037 (subreg:QI
1038 (zero_extract:SI
1039 (match_operand 0 "ext_register_operand" "")
1040 (const_int 8)
1041 (const_int 8)) 0)
1042 (match_operand:QI 1 "immediate_operand" "")))])
1043
1044 (define_insn "*cmpqi_ext_3_insn"
1045 [(set (reg FLAGS_REG)
1046 (compare
1047 (subreg:QI
1048 (zero_extract:SI
1049 (match_operand 0 "ext_register_operand" "Q")
1050 (const_int 8)
1051 (const_int 8)) 0)
1052 (match_operand:QI 1 "general_operand" "Qmn")))]
1053 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054 "cmp{b}\t{%1, %h0|%h0, %1}"
1055 [(set_attr "type" "icmp")
1056 (set_attr "modrm" "1")
1057 (set_attr "mode" "QI")])
1058
1059 (define_insn "*cmpqi_ext_3_insn_rex64"
1060 [(set (reg FLAGS_REG)
1061 (compare
1062 (subreg:QI
1063 (zero_extract:SI
1064 (match_operand 0 "ext_register_operand" "Q")
1065 (const_int 8)
1066 (const_int 8)) 0)
1067 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1068 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069 "cmp{b}\t{%1, %h0|%h0, %1}"
1070 [(set_attr "type" "icmp")
1071 (set_attr "modrm" "1")
1072 (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_4"
1075 [(set (reg FLAGS_REG)
1076 (compare
1077 (subreg:QI
1078 (zero_extract:SI
1079 (match_operand 0 "ext_register_operand" "Q")
1080 (const_int 8)
1081 (const_int 8)) 0)
1082 (subreg:QI
1083 (zero_extract:SI
1084 (match_operand 1 "ext_register_operand" "Q")
1085 (const_int 8)
1086 (const_int 8)) 0)))]
1087 "ix86_match_ccmode (insn, CCmode)"
1088 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1089 [(set_attr "type" "icmp")
1090 (set_attr "mode" "QI")])
1091
1092 ;; These implement float point compares.
1093 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1094 ;; which would allow mix and match FP modes on the compares. Which is what
1095 ;; the old patterns did, but with many more of them.
1096
1097 (define_expand "cbranchxf4"
1098 [(set (reg:CC FLAGS_REG)
1099 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1100 (match_operand:XF 2 "nonmemory_operand" "")))
1101 (set (pc) (if_then_else
1102 (match_operator 0 "ix86_fp_comparison_operator"
1103 [(reg:CC FLAGS_REG)
1104 (const_int 0)])
1105 (label_ref (match_operand 3 "" ""))
1106 (pc)))]
1107 "TARGET_80387"
1108 {
1109 ix86_expand_branch (GET_CODE (operands[0]),
1110 operands[1], operands[2], operands[3]);
1111 DONE;
1112 })
1113
1114 (define_expand "cstorexf4"
1115 [(set (reg:CC FLAGS_REG)
1116 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117 (match_operand:XF 3 "nonmemory_operand" "")))
1118 (set (match_operand:QI 0 "register_operand" "")
1119 (match_operator 1 "ix86_fp_comparison_operator"
1120 [(reg:CC FLAGS_REG)
1121 (const_int 0)]))]
1122 "TARGET_80387"
1123 {
1124 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1125 operands[2], operands[3]);
1126 DONE;
1127 })
1128
1129 (define_expand "cbranch<mode>4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133 (set (pc) (if_then_else
1134 (match_operator 0 "ix86_fp_comparison_operator"
1135 [(reg:CC FLAGS_REG)
1136 (const_int 0)])
1137 (label_ref (match_operand 3 "" ""))
1138 (pc)))]
1139 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1140 {
1141 ix86_expand_branch (GET_CODE (operands[0]),
1142 operands[1], operands[2], operands[3]);
1143 DONE;
1144 })
1145
1146 (define_expand "cstore<mode>4"
1147 [(set (reg:CC FLAGS_REG)
1148 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1149 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1150 (set (match_operand:QI 0 "register_operand" "")
1151 (match_operator 1 "ix86_fp_comparison_operator"
1152 [(reg:CC FLAGS_REG)
1153 (const_int 0)]))]
1154 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1155 {
1156 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1157 operands[2], operands[3]);
1158 DONE;
1159 })
1160
1161 (define_expand "cbranchcc4"
1162 [(set (pc) (if_then_else
1163 (match_operator 0 "comparison_operator"
1164 [(match_operand 1 "flags_reg_operand" "")
1165 (match_operand 2 "const0_operand" "")])
1166 (label_ref (match_operand 3 "" ""))
1167 (pc)))]
1168 ""
1169 {
1170 ix86_expand_branch (GET_CODE (operands[0]),
1171 operands[1], operands[2], operands[3]);
1172 DONE;
1173 })
1174
1175 (define_expand "cstorecc4"
1176 [(set (match_operand:QI 0 "register_operand" "")
1177 (match_operator 1 "comparison_operator"
1178 [(match_operand 2 "flags_reg_operand" "")
1179 (match_operand 3 "const0_operand" "")]))]
1180 ""
1181 {
1182 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1183 operands[2], operands[3]);
1184 DONE;
1185 })
1186
1187
1188 ;; FP compares, step 1:
1189 ;; Set the FP condition codes.
1190 ;;
1191 ;; CCFPmode compare with exceptions
1192 ;; CCFPUmode compare with no exceptions
1193
1194 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1195 ;; used to manage the reg stack popping would not be preserved.
1196
1197 (define_insn "*cmpfp_0"
1198 [(set (match_operand:HI 0 "register_operand" "=a")
1199 (unspec:HI
1200 [(compare:CCFP
1201 (match_operand 1 "register_operand" "f")
1202 (match_operand 2 "const0_operand" ""))]
1203 UNSPEC_FNSTSW))]
1204 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1205 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1206 "* return output_fp_compare (insn, operands, false, false);"
1207 [(set_attr "type" "multi")
1208 (set_attr "unit" "i387")
1209 (set (attr "mode")
1210 (cond [(match_operand:SF 1 "" "")
1211 (const_string "SF")
1212 (match_operand:DF 1 "" "")
1213 (const_string "DF")
1214 ]
1215 (const_string "XF")))])
1216
1217 (define_insn_and_split "*cmpfp_0_cc"
1218 [(set (reg:CCFP FLAGS_REG)
1219 (compare:CCFP
1220 (match_operand 1 "register_operand" "f")
1221 (match_operand 2 "const0_operand" "")))
1222 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1223 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1224 && TARGET_SAHF && !TARGET_CMOVE
1225 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1226 "#"
1227 "&& reload_completed"
1228 [(set (match_dup 0)
1229 (unspec:HI
1230 [(compare:CCFP (match_dup 1)(match_dup 2))]
1231 UNSPEC_FNSTSW))
1232 (set (reg:CC FLAGS_REG)
1233 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1234 ""
1235 [(set_attr "type" "multi")
1236 (set_attr "unit" "i387")
1237 (set (attr "mode")
1238 (cond [(match_operand:SF 1 "" "")
1239 (const_string "SF")
1240 (match_operand:DF 1 "" "")
1241 (const_string "DF")
1242 ]
1243 (const_string "XF")))])
1244
1245 (define_insn "*cmpfp_xf"
1246 [(set (match_operand:HI 0 "register_operand" "=a")
1247 (unspec:HI
1248 [(compare:CCFP
1249 (match_operand:XF 1 "register_operand" "f")
1250 (match_operand:XF 2 "register_operand" "f"))]
1251 UNSPEC_FNSTSW))]
1252 "TARGET_80387"
1253 "* return output_fp_compare (insn, operands, false, false);"
1254 [(set_attr "type" "multi")
1255 (set_attr "unit" "i387")
1256 (set_attr "mode" "XF")])
1257
1258 (define_insn_and_split "*cmpfp_xf_cc"
1259 [(set (reg:CCFP FLAGS_REG)
1260 (compare:CCFP
1261 (match_operand:XF 1 "register_operand" "f")
1262 (match_operand:XF 2 "register_operand" "f")))
1263 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1264 "TARGET_80387
1265 && TARGET_SAHF && !TARGET_CMOVE"
1266 "#"
1267 "&& reload_completed"
1268 [(set (match_dup 0)
1269 (unspec:HI
1270 [(compare:CCFP (match_dup 1)(match_dup 2))]
1271 UNSPEC_FNSTSW))
1272 (set (reg:CC FLAGS_REG)
1273 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1274 ""
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1277 (set_attr "mode" "XF")])
1278
1279 (define_insn "*cmpfp_<mode>"
1280 [(set (match_operand:HI 0 "register_operand" "=a")
1281 (unspec:HI
1282 [(compare:CCFP
1283 (match_operand:MODEF 1 "register_operand" "f")
1284 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1285 UNSPEC_FNSTSW))]
1286 "TARGET_80387"
1287 "* return output_fp_compare (insn, operands, false, false);"
1288 [(set_attr "type" "multi")
1289 (set_attr "unit" "i387")
1290 (set_attr "mode" "<MODE>")])
1291
1292 (define_insn_and_split "*cmpfp_<mode>_cc"
1293 [(set (reg:CCFP FLAGS_REG)
1294 (compare:CCFP
1295 (match_operand:MODEF 1 "register_operand" "f")
1296 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1297 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1298 "TARGET_80387
1299 && TARGET_SAHF && !TARGET_CMOVE"
1300 "#"
1301 "&& reload_completed"
1302 [(set (match_dup 0)
1303 (unspec:HI
1304 [(compare:CCFP (match_dup 1)(match_dup 2))]
1305 UNSPEC_FNSTSW))
1306 (set (reg:CC FLAGS_REG)
1307 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1308 ""
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "<MODE>")])
1312
1313 (define_insn "*cmpfp_u"
1314 [(set (match_operand:HI 0 "register_operand" "=a")
1315 (unspec:HI
1316 [(compare:CCFPU
1317 (match_operand 1 "register_operand" "f")
1318 (match_operand 2 "register_operand" "f"))]
1319 UNSPEC_FNSTSW))]
1320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1322 "* return output_fp_compare (insn, operands, false, true);"
1323 [(set_attr "type" "multi")
1324 (set_attr "unit" "i387")
1325 (set (attr "mode")
1326 (cond [(match_operand:SF 1 "" "")
1327 (const_string "SF")
1328 (match_operand:DF 1 "" "")
1329 (const_string "DF")
1330 ]
1331 (const_string "XF")))])
1332
1333 (define_insn_and_split "*cmpfp_u_cc"
1334 [(set (reg:CCFPU FLAGS_REG)
1335 (compare:CCFPU
1336 (match_operand 1 "register_operand" "f")
1337 (match_operand 2 "register_operand" "f")))
1338 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1339 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1340 && TARGET_SAHF && !TARGET_CMOVE
1341 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1342 "#"
1343 "&& reload_completed"
1344 [(set (match_dup 0)
1345 (unspec:HI
1346 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1347 UNSPEC_FNSTSW))
1348 (set (reg:CC FLAGS_REG)
1349 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1350 ""
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1353 (set (attr "mode")
1354 (cond [(match_operand:SF 1 "" "")
1355 (const_string "SF")
1356 (match_operand:DF 1 "" "")
1357 (const_string "DF")
1358 ]
1359 (const_string "XF")))])
1360
1361 (define_insn "*cmpfp_<mode>"
1362 [(set (match_operand:HI 0 "register_operand" "=a")
1363 (unspec:HI
1364 [(compare:CCFP
1365 (match_operand 1 "register_operand" "f")
1366 (match_operator 3 "float_operator"
1367 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1368 UNSPEC_FNSTSW))]
1369 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1370 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1371 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1372 "* return output_fp_compare (insn, operands, false, false);"
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1375 (set_attr "fp_int_src" "true")
1376 (set_attr "mode" "<MODE>")])
1377
1378 (define_insn_and_split "*cmpfp_<mode>_cc"
1379 [(set (reg:CCFP FLAGS_REG)
1380 (compare:CCFP
1381 (match_operand 1 "register_operand" "f")
1382 (match_operator 3 "float_operator"
1383 [(match_operand:SWI24 2 "memory_operand" "m")])))
1384 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1386 && TARGET_SAHF && !TARGET_CMOVE
1387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1388 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1389 "#"
1390 "&& reload_completed"
1391 [(set (match_dup 0)
1392 (unspec:HI
1393 [(compare:CCFP
1394 (match_dup 1)
1395 (match_op_dup 3 [(match_dup 2)]))]
1396 UNSPEC_FNSTSW))
1397 (set (reg:CC FLAGS_REG)
1398 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1399 ""
1400 [(set_attr "type" "multi")
1401 (set_attr "unit" "i387")
1402 (set_attr "fp_int_src" "true")
1403 (set_attr "mode" "<MODE>")])
1404
1405 ;; FP compares, step 2
1406 ;; Move the fpsw to ax.
1407
1408 (define_insn "x86_fnstsw_1"
1409 [(set (match_operand:HI 0 "register_operand" "=a")
1410 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1411 "TARGET_80387"
1412 "fnstsw\t%0"
1413 [(set (attr "length")
1414 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1415 (set_attr "mode" "SI")
1416 (set_attr "unit" "i387")])
1417
1418 ;; FP compares, step 3
1419 ;; Get ax into flags, general case.
1420
1421 (define_insn "x86_sahf_1"
1422 [(set (reg:CC FLAGS_REG)
1423 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1424 UNSPEC_SAHF))]
1425 "TARGET_SAHF"
1426 {
1427 #ifndef HAVE_AS_IX86_SAHF
1428 if (TARGET_64BIT)
1429 return ASM_BYTE "0x9e";
1430 else
1431 #endif
1432 return "sahf";
1433 }
1434 [(set_attr "length" "1")
1435 (set_attr "athlon_decode" "vector")
1436 (set_attr "amdfam10_decode" "direct")
1437 (set_attr "bdver1_decode" "direct")
1438 (set_attr "mode" "SI")])
1439
1440 ;; Pentium Pro can do steps 1 through 3 in one go.
1441 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1442 ;; (these i387 instructions set flags directly)
1443 (define_insn "*cmpfp_i_mixed"
1444 [(set (reg:CCFP FLAGS_REG)
1445 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447 "TARGET_MIX_SSE_I387
1448 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450 "* return output_fp_compare (insn, operands, true, false);"
1451 [(set_attr "type" "fcmp,ssecomi")
1452 (set_attr "prefix" "orig,maybe_vex")
1453 (set (attr "mode")
1454 (if_then_else (match_operand:SF 1 "" "")
1455 (const_string "SF")
1456 (const_string "DF")))
1457 (set (attr "prefix_rep")
1458 (if_then_else (eq_attr "type" "ssecomi")
1459 (const_string "0")
1460 (const_string "*")))
1461 (set (attr "prefix_data16")
1462 (cond [(eq_attr "type" "fcmp")
1463 (const_string "*")
1464 (eq_attr "mode" "DF")
1465 (const_string "1")
1466 ]
1467 (const_string "0")))
1468 (set_attr "athlon_decode" "vector")
1469 (set_attr "amdfam10_decode" "direct")
1470 (set_attr "bdver1_decode" "double")])
1471
1472 (define_insn "*cmpfp_i_sse"
1473 [(set (reg:CCFP FLAGS_REG)
1474 (compare:CCFP (match_operand 0 "register_operand" "x")
1475 (match_operand 1 "nonimmediate_operand" "xm")))]
1476 "TARGET_SSE_MATH
1477 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1478 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1479 "* return output_fp_compare (insn, operands, true, false);"
1480 [(set_attr "type" "ssecomi")
1481 (set_attr "prefix" "maybe_vex")
1482 (set (attr "mode")
1483 (if_then_else (match_operand:SF 1 "" "")
1484 (const_string "SF")
1485 (const_string "DF")))
1486 (set_attr "prefix_rep" "0")
1487 (set (attr "prefix_data16")
1488 (if_then_else (eq_attr "mode" "DF")
1489 (const_string "1")
1490 (const_string "0")))
1491 (set_attr "athlon_decode" "vector")
1492 (set_attr "amdfam10_decode" "direct")
1493 (set_attr "bdver1_decode" "double")])
1494
1495 (define_insn "*cmpfp_i_i387"
1496 [(set (reg:CCFP FLAGS_REG)
1497 (compare:CCFP (match_operand 0 "register_operand" "f")
1498 (match_operand 1 "register_operand" "f")))]
1499 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1500 && TARGET_CMOVE
1501 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp")
1505 (set (attr "mode")
1506 (cond [(match_operand:SF 1 "" "")
1507 (const_string "SF")
1508 (match_operand:DF 1 "" "")
1509 (const_string "DF")
1510 ]
1511 (const_string "XF")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "double")])
1515
1516 (define_insn "*cmpfp_iu_mixed"
1517 [(set (reg:CCFPU FLAGS_REG)
1518 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1519 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1520 "TARGET_MIX_SSE_I387
1521 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, true, true);"
1524 [(set_attr "type" "fcmp,ssecomi")
1525 (set_attr "prefix" "orig,maybe_vex")
1526 (set (attr "mode")
1527 (if_then_else (match_operand:SF 1 "" "")
1528 (const_string "SF")
1529 (const_string "DF")))
1530 (set (attr "prefix_rep")
1531 (if_then_else (eq_attr "type" "ssecomi")
1532 (const_string "0")
1533 (const_string "*")))
1534 (set (attr "prefix_data16")
1535 (cond [(eq_attr "type" "fcmp")
1536 (const_string "*")
1537 (eq_attr "mode" "DF")
1538 (const_string "1")
1539 ]
1540 (const_string "0")))
1541 (set_attr "athlon_decode" "vector")
1542 (set_attr "amdfam10_decode" "direct")
1543 (set_attr "bdver1_decode" "double")])
1544
1545 (define_insn "*cmpfp_iu_sse"
1546 [(set (reg:CCFPU FLAGS_REG)
1547 (compare:CCFPU (match_operand 0 "register_operand" "x")
1548 (match_operand 1 "nonimmediate_operand" "xm")))]
1549 "TARGET_SSE_MATH
1550 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1551 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1552 "* return output_fp_compare (insn, operands, true, true);"
1553 [(set_attr "type" "ssecomi")
1554 (set_attr "prefix" "maybe_vex")
1555 (set (attr "mode")
1556 (if_then_else (match_operand:SF 1 "" "")
1557 (const_string "SF")
1558 (const_string "DF")))
1559 (set_attr "prefix_rep" "0")
1560 (set (attr "prefix_data16")
1561 (if_then_else (eq_attr "mode" "DF")
1562 (const_string "1")
1563 (const_string "0")))
1564 (set_attr "athlon_decode" "vector")
1565 (set_attr "amdfam10_decode" "direct")
1566 (set_attr "bdver1_decode" "double")])
1567
1568 (define_insn "*cmpfp_iu_387"
1569 [(set (reg:CCFPU FLAGS_REG)
1570 (compare:CCFPU (match_operand 0 "register_operand" "f")
1571 (match_operand 1 "register_operand" "f")))]
1572 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1573 && TARGET_CMOVE
1574 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp")
1578 (set (attr "mode")
1579 (cond [(match_operand:SF 1 "" "")
1580 (const_string "SF")
1581 (match_operand:DF 1 "" "")
1582 (const_string "DF")
1583 ]
1584 (const_string "XF")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")
1587 (set_attr "bdver1_decode" "direct")])
1588 \f
1589 ;; Push/pop instructions.
1590
1591 (define_insn "*push<mode>2"
1592 [(set (match_operand:DWI 0 "push_operand" "=<")
1593 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1594 ""
1595 "#"
1596 [(set_attr "type" "multi")
1597 (set_attr "mode" "<MODE>")])
1598
1599 (define_split
1600 [(set (match_operand:TI 0 "push_operand" "")
1601 (match_operand:TI 1 "general_operand" ""))]
1602 "TARGET_64BIT && reload_completed
1603 && !SSE_REG_P (operands[1])"
1604 [(const_int 0)]
1605 "ix86_split_long_move (operands); DONE;")
1606
1607 (define_insn "*pushdi2_rex64"
1608 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1609 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1610 "TARGET_64BIT"
1611 "@
1612 push{q}\t%1
1613 #"
1614 [(set_attr "type" "push,multi")
1615 (set_attr "mode" "DI")])
1616
1617 ;; Convert impossible pushes of immediate to existing instructions.
1618 ;; First try to get scratch register and go through it. In case this
1619 ;; fails, push sign extended lower part first and then overwrite
1620 ;; upper part by 32bit move.
1621 (define_peephole2
1622 [(match_scratch:DI 2 "r")
1623 (set (match_operand:DI 0 "push_operand" "")
1624 (match_operand:DI 1 "immediate_operand" ""))]
1625 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1626 && !x86_64_immediate_operand (operands[1], DImode)"
1627 [(set (match_dup 2) (match_dup 1))
1628 (set (match_dup 0) (match_dup 2))])
1629
1630 ;; We need to define this as both peepholer and splitter for case
1631 ;; peephole2 pass is not run.
1632 ;; "&& 1" is needed to keep it from matching the previous pattern.
1633 (define_peephole2
1634 [(set (match_operand:DI 0 "push_operand" "")
1635 (match_operand:DI 1 "immediate_operand" ""))]
1636 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1637 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1638 [(set (match_dup 0) (match_dup 1))
1639 (set (match_dup 2) (match_dup 3))]
1640 {
1641 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1642
1643 operands[1] = gen_lowpart (DImode, operands[2]);
1644 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1645 GEN_INT (4)));
1646 })
1647
1648 (define_split
1649 [(set (match_operand:DI 0 "push_operand" "")
1650 (match_operand:DI 1 "immediate_operand" ""))]
1651 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1652 ? epilogue_completed : reload_completed)
1653 && !symbolic_operand (operands[1], DImode)
1654 && !x86_64_immediate_operand (operands[1], DImode)"
1655 [(set (match_dup 0) (match_dup 1))
1656 (set (match_dup 2) (match_dup 3))]
1657 {
1658 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1659
1660 operands[1] = gen_lowpart (DImode, operands[2]);
1661 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1662 GEN_INT (4)));
1663 })
1664
1665 (define_split
1666 [(set (match_operand:DI 0 "push_operand" "")
1667 (match_operand:DI 1 "general_operand" ""))]
1668 "!TARGET_64BIT && reload_completed
1669 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1670 [(const_int 0)]
1671 "ix86_split_long_move (operands); DONE;")
1672
1673 (define_insn "*pushsi2"
1674 [(set (match_operand:SI 0 "push_operand" "=<")
1675 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1676 "!TARGET_64BIT"
1677 "push{l}\t%1"
1678 [(set_attr "type" "push")
1679 (set_attr "mode" "SI")])
1680
1681 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1682 ;; "push a byte/word". But actually we use pushl, which has the effect
1683 ;; of rounding the amount pushed up to a word.
1684
1685 ;; For TARGET_64BIT we always round up to 8 bytes.
1686 (define_insn "*push<mode>2_rex64"
1687 [(set (match_operand:SWI124 0 "push_operand" "=X")
1688 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1689 "TARGET_64BIT"
1690 "push{q}\t%q1"
1691 [(set_attr "type" "push")
1692 (set_attr "mode" "DI")])
1693
1694 (define_insn "*push<mode>2"
1695 [(set (match_operand:SWI12 0 "push_operand" "=X")
1696 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1697 "!TARGET_64BIT"
1698 "push{l}\t%k1"
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1701
1702 (define_insn "*push<mode>2_prologue"
1703 [(set (match_operand:P 0 "push_operand" "=<")
1704 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1705 (clobber (mem:BLK (scratch)))]
1706 ""
1707 "push{<imodesuffix>}\t%1"
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "<MODE>")])
1710
1711 (define_insn "*pop<mode>1"
1712 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1713 (match_operand:P 1 "pop_operand" ">"))]
1714 ""
1715 "pop{<imodesuffix>}\t%0"
1716 [(set_attr "type" "pop")
1717 (set_attr "mode" "<MODE>")])
1718
1719 (define_insn "*pop<mode>1_epilogue"
1720 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1721 (match_operand:P 1 "pop_operand" ">"))
1722 (clobber (mem:BLK (scratch)))]
1723 ""
1724 "pop{<imodesuffix>}\t%0"
1725 [(set_attr "type" "pop")
1726 (set_attr "mode" "<MODE>")])
1727 \f
1728 ;; Move instructions.
1729
1730 (define_expand "movoi"
1731 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1732 (match_operand:OI 1 "general_operand" ""))]
1733 "TARGET_AVX"
1734 "ix86_expand_move (OImode, operands); DONE;")
1735
1736 (define_expand "movti"
1737 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1738 (match_operand:TI 1 "nonimmediate_operand" ""))]
1739 "TARGET_64BIT || TARGET_SSE"
1740 {
1741 if (TARGET_64BIT)
1742 ix86_expand_move (TImode, operands);
1743 else if (push_operand (operands[0], TImode))
1744 ix86_expand_push (TImode, operands[1]);
1745 else
1746 ix86_expand_vector_move (TImode, operands);
1747 DONE;
1748 })
1749
1750 ;; This expands to what emit_move_complex would generate if we didn't
1751 ;; have a movti pattern. Having this avoids problems with reload on
1752 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1753 ;; to have around all the time.
1754 (define_expand "movcdi"
1755 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1756 (match_operand:CDI 1 "general_operand" ""))]
1757 ""
1758 {
1759 if (push_operand (operands[0], CDImode))
1760 emit_move_complex_push (CDImode, operands[0], operands[1]);
1761 else
1762 emit_move_complex_parts (operands[0], operands[1]);
1763 DONE;
1764 })
1765
1766 (define_expand "mov<mode>"
1767 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1768 (match_operand:SWI1248x 1 "general_operand" ""))]
1769 ""
1770 "ix86_expand_move (<MODE>mode, operands); DONE;")
1771
1772 (define_insn "*mov<mode>_xor"
1773 [(set (match_operand:SWI48 0 "register_operand" "=r")
1774 (match_operand:SWI48 1 "const0_operand" ""))
1775 (clobber (reg:CC FLAGS_REG))]
1776 "reload_completed"
1777 "xor{l}\t%k0, %k0"
1778 [(set_attr "type" "alu1")
1779 (set_attr "mode" "SI")
1780 (set_attr "length_immediate" "0")])
1781
1782 (define_insn "*mov<mode>_or"
1783 [(set (match_operand:SWI48 0 "register_operand" "=r")
1784 (match_operand:SWI48 1 "const_int_operand" ""))
1785 (clobber (reg:CC FLAGS_REG))]
1786 "reload_completed
1787 && operands[1] == constm1_rtx"
1788 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1789 [(set_attr "type" "alu1")
1790 (set_attr "mode" "<MODE>")
1791 (set_attr "length_immediate" "1")])
1792
1793 (define_insn "*movoi_internal_avx"
1794 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1795 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1796 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1797 {
1798 switch (which_alternative)
1799 {
1800 case 0:
1801 return standard_sse_constant_opcode (insn, operands[1]);
1802 case 1:
1803 case 2:
1804 if (misaligned_operand (operands[0], OImode)
1805 || misaligned_operand (operands[1], OImode))
1806 return "vmovdqu\t{%1, %0|%0, %1}";
1807 else
1808 return "vmovdqa\t{%1, %0|%0, %1}";
1809 default:
1810 gcc_unreachable ();
1811 }
1812 }
1813 [(set_attr "type" "sselog1,ssemov,ssemov")
1814 (set_attr "prefix" "vex")
1815 (set_attr "mode" "OI")])
1816
1817 (define_insn "*movti_internal_rex64"
1818 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1819 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1820 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1821 {
1822 switch (which_alternative)
1823 {
1824 case 0:
1825 case 1:
1826 return "#";
1827 case 2:
1828 return standard_sse_constant_opcode (insn, operands[1]);
1829 case 3:
1830 case 4:
1831 /* TDmode values are passed as TImode on the stack. Moving them
1832 to stack may result in unaligned memory access. */
1833 if (misaligned_operand (operands[0], TImode)
1834 || misaligned_operand (operands[1], TImode))
1835 {
1836 if (get_attr_mode (insn) == MODE_V4SF)
1837 return "%vmovups\t{%1, %0|%0, %1}";
1838 else
1839 return "%vmovdqu\t{%1, %0|%0, %1}";
1840 }
1841 else
1842 {
1843 if (get_attr_mode (insn) == MODE_V4SF)
1844 return "%vmovaps\t{%1, %0|%0, %1}";
1845 else
1846 return "%vmovdqa\t{%1, %0|%0, %1}";
1847 }
1848 default:
1849 gcc_unreachable ();
1850 }
1851 }
1852 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1853 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1854 (set (attr "mode")
1855 (cond [(eq_attr "alternative" "2,3")
1856 (if_then_else
1857 (match_test "optimize_function_for_size_p (cfun)")
1858 (const_string "V4SF")
1859 (const_string "TI"))
1860 (eq_attr "alternative" "4")
1861 (if_then_else
1862 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1863 (match_test "optimize_function_for_size_p (cfun)"))
1864 (const_string "V4SF")
1865 (const_string "TI"))]
1866 (const_string "DI")))])
1867
1868 (define_split
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1870 (match_operand:TI 1 "general_operand" ""))]
1871 "reload_completed
1872 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1873 [(const_int 0)]
1874 "ix86_split_long_move (operands); DONE;")
1875
1876 (define_insn "*movti_internal_sse"
1877 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1878 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1879 "TARGET_SSE && !TARGET_64BIT
1880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1881 {
1882 switch (which_alternative)
1883 {
1884 case 0:
1885 return standard_sse_constant_opcode (insn, operands[1]);
1886 case 1:
1887 case 2:
1888 /* TDmode values are passed as TImode on the stack. Moving them
1889 to stack may result in unaligned memory access. */
1890 if (misaligned_operand (operands[0], TImode)
1891 || misaligned_operand (operands[1], TImode))
1892 {
1893 if (get_attr_mode (insn) == MODE_V4SF)
1894 return "%vmovups\t{%1, %0|%0, %1}";
1895 else
1896 return "%vmovdqu\t{%1, %0|%0, %1}";
1897 }
1898 else
1899 {
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vmovaps\t{%1, %0|%0, %1}";
1902 else
1903 return "%vmovdqa\t{%1, %0|%0, %1}";
1904 }
1905 default:
1906 gcc_unreachable ();
1907 }
1908 }
1909 [(set_attr "type" "sselog1,ssemov,ssemov")
1910 (set_attr "prefix" "maybe_vex")
1911 (set (attr "mode")
1912 (cond [(ior (not (match_test "TARGET_SSE2"))
1913 (match_test "optimize_function_for_size_p (cfun)"))
1914 (const_string "V4SF")
1915 (and (eq_attr "alternative" "2")
1916 (match_test "TARGET_SSE_TYPELESS_STORES"))
1917 (const_string "V4SF")]
1918 (const_string "TI")))])
1919
1920 (define_insn "*movdi_internal_rex64"
1921 [(set (match_operand:DI 0 "nonimmediate_operand"
1922 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1923 (match_operand:DI 1 "general_operand"
1924 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1925 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1926 {
1927 switch (get_attr_type (insn))
1928 {
1929 case TYPE_SSECVT:
1930 if (SSE_REG_P (operands[0]))
1931 return "movq2dq\t{%1, %0|%0, %1}";
1932 else
1933 return "movdq2q\t{%1, %0|%0, %1}";
1934
1935 case TYPE_SSEMOV:
1936 if (get_attr_mode (insn) == MODE_TI)
1937 return "%vmovdqa\t{%1, %0|%0, %1}";
1938 /* Handle broken assemblers that require movd instead of movq. */
1939 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1940 return "%vmovd\t{%1, %0|%0, %1}";
1941 else
1942 return "%vmovq\t{%1, %0|%0, %1}";
1943
1944 case TYPE_MMXMOV:
1945 /* Handle broken assemblers that require movd instead of movq. */
1946 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1947 return "movd\t{%1, %0|%0, %1}";
1948 else
1949 return "movq\t{%1, %0|%0, %1}";
1950
1951 case TYPE_SSELOG1:
1952 return standard_sse_constant_opcode (insn, operands[1]);
1953
1954 case TYPE_MMX:
1955 return "pxor\t%0, %0";
1956
1957 case TYPE_MULTI:
1958 return "#";
1959
1960 case TYPE_LEA:
1961 return "lea{q}\t{%a1, %0|%0, %a1}";
1962
1963 default:
1964 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1965 if (get_attr_mode (insn) == MODE_SI)
1966 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1967 else if (which_alternative == 2)
1968 return "movabs{q}\t{%1, %0|%0, %1}";
1969 else if (ix86_use_lea_for_mov (insn, operands))
1970 return "lea{q}\t{%a1, %0|%0, %a1}";
1971 else
1972 return "mov{q}\t{%1, %0|%0, %1}";
1973 }
1974 }
1975 [(set (attr "type")
1976 (cond [(eq_attr "alternative" "4")
1977 (const_string "multi")
1978 (eq_attr "alternative" "5")
1979 (const_string "mmx")
1980 (eq_attr "alternative" "6,7,8,9")
1981 (const_string "mmxmov")
1982 (eq_attr "alternative" "10")
1983 (const_string "sselog1")
1984 (eq_attr "alternative" "11,12,13,14,15")
1985 (const_string "ssemov")
1986 (eq_attr "alternative" "16,17")
1987 (const_string "ssecvt")
1988 (match_operand 1 "pic_32bit_operand" "")
1989 (const_string "lea")
1990 ]
1991 (const_string "imov")))
1992 (set (attr "modrm")
1993 (if_then_else
1994 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1995 (const_string "0")
1996 (const_string "*")))
1997 (set (attr "length_immediate")
1998 (if_then_else
1999 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2000 (const_string "8")
2001 (const_string "*")))
2002 (set (attr "prefix_rex")
2003 (if_then_else (eq_attr "alternative" "8,9")
2004 (const_string "1")
2005 (const_string "*")))
2006 (set (attr "prefix_data16")
2007 (if_then_else (eq_attr "alternative" "11")
2008 (const_string "1")
2009 (const_string "*")))
2010 (set (attr "prefix")
2011 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2012 (const_string "maybe_vex")
2013 (const_string "orig")))
2014 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2015
2016 ;; Reload patterns to support multi-word load/store
2017 ;; with non-offsetable address.
2018 (define_expand "reload_noff_store"
2019 [(parallel [(match_operand 0 "memory_operand" "=m")
2020 (match_operand 1 "register_operand" "r")
2021 (match_operand:DI 2 "register_operand" "=&r")])]
2022 "TARGET_64BIT"
2023 {
2024 rtx mem = operands[0];
2025 rtx addr = XEXP (mem, 0);
2026
2027 emit_move_insn (operands[2], addr);
2028 mem = replace_equiv_address_nv (mem, operands[2]);
2029
2030 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2031 DONE;
2032 })
2033
2034 (define_expand "reload_noff_load"
2035 [(parallel [(match_operand 0 "register_operand" "=r")
2036 (match_operand 1 "memory_operand" "m")
2037 (match_operand:DI 2 "register_operand" "=r")])]
2038 "TARGET_64BIT"
2039 {
2040 rtx mem = operands[1];
2041 rtx addr = XEXP (mem, 0);
2042
2043 emit_move_insn (operands[2], addr);
2044 mem = replace_equiv_address_nv (mem, operands[2]);
2045
2046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2047 DONE;
2048 })
2049
2050 ;; Convert impossible stores of immediate to existing instructions.
2051 ;; First try to get scratch register and go through it. In case this
2052 ;; fails, move by 32bit parts.
2053 (define_peephole2
2054 [(match_scratch:DI 2 "r")
2055 (set (match_operand:DI 0 "memory_operand" "")
2056 (match_operand:DI 1 "immediate_operand" ""))]
2057 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2058 && !x86_64_immediate_operand (operands[1], DImode)"
2059 [(set (match_dup 2) (match_dup 1))
2060 (set (match_dup 0) (match_dup 2))])
2061
2062 ;; We need to define this as both peepholer and splitter for case
2063 ;; peephole2 pass is not run.
2064 ;; "&& 1" is needed to keep it from matching the previous pattern.
2065 (define_peephole2
2066 [(set (match_operand:DI 0 "memory_operand" "")
2067 (match_operand:DI 1 "immediate_operand" ""))]
2068 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2069 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2070 [(set (match_dup 2) (match_dup 3))
2071 (set (match_dup 4) (match_dup 5))]
2072 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2073
2074 (define_split
2075 [(set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2078 ? epilogue_completed : reload_completed)
2079 && !symbolic_operand (operands[1], DImode)
2080 && !x86_64_immediate_operand (operands[1], DImode)"
2081 [(set (match_dup 2) (match_dup 3))
2082 (set (match_dup 4) (match_dup 5))]
2083 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2084
2085 (define_insn "*movdi_internal"
2086 [(set (match_operand:DI 0 "nonimmediate_operand"
2087 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2088 (match_operand:DI 1 "general_operand"
2089 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2090 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2091 {
2092 switch (get_attr_type (insn))
2093 {
2094 case TYPE_SSECVT:
2095 if (SSE_REG_P (operands[0]))
2096 return "movq2dq\t{%1, %0|%0, %1}";
2097 else
2098 return "movdq2q\t{%1, %0|%0, %1}";
2099
2100 case TYPE_SSEMOV:
2101 switch (get_attr_mode (insn))
2102 {
2103 case MODE_TI:
2104 return "%vmovdqa\t{%1, %0|%0, %1}";
2105 case MODE_DI:
2106 return "%vmovq\t{%1, %0|%0, %1}";
2107 case MODE_V4SF:
2108 return "movaps\t{%1, %0|%0, %1}";
2109 case MODE_V2SF:
2110 return "movlps\t{%1, %0|%0, %1}";
2111 default:
2112 gcc_unreachable ();
2113 }
2114
2115 case TYPE_MMXMOV:
2116 return "movq\t{%1, %0|%0, %1}";
2117
2118 case TYPE_SSELOG1:
2119 return standard_sse_constant_opcode (insn, operands[1]);
2120
2121 case TYPE_MMX:
2122 return "pxor\t%0, %0";
2123
2124 case TYPE_MULTI:
2125 return "#";
2126
2127 default:
2128 gcc_unreachable ();
2129 }
2130 }
2131 [(set (attr "isa")
2132 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2133 (const_string "sse2")
2134 (eq_attr "alternative" "9,10,11,12")
2135 (const_string "noavx")
2136 ]
2137 (const_string "*")))
2138 (set (attr "type")
2139 (cond [(eq_attr "alternative" "0,1")
2140 (const_string "multi")
2141 (eq_attr "alternative" "2")
2142 (const_string "mmx")
2143 (eq_attr "alternative" "3,4")
2144 (const_string "mmxmov")
2145 (eq_attr "alternative" "5,9")
2146 (const_string "sselog1")
2147 (eq_attr "alternative" "13,14")
2148 (const_string "ssecvt")
2149 ]
2150 (const_string "ssemov")))
2151 (set (attr "prefix")
2152 (if_then_else (eq_attr "alternative" "5,6,7,8")
2153 (const_string "maybe_vex")
2154 (const_string "orig")))
2155 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2156
2157 (define_split
2158 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2159 (match_operand:DI 1 "general_operand" ""))]
2160 "!TARGET_64BIT && reload_completed
2161 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2162 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2163 [(const_int 0)]
2164 "ix86_split_long_move (operands); DONE;")
2165
2166 (define_insn "*movsi_internal"
2167 [(set (match_operand:SI 0 "nonimmediate_operand"
2168 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2169 (match_operand:SI 1 "general_operand"
2170 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2171 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2172 {
2173 switch (get_attr_type (insn))
2174 {
2175 case TYPE_SSELOG1:
2176 return standard_sse_constant_opcode (insn, operands[1]);
2177
2178 case TYPE_SSEMOV:
2179 switch (get_attr_mode (insn))
2180 {
2181 case MODE_TI:
2182 return "%vmovdqa\t{%1, %0|%0, %1}";
2183 case MODE_V4SF:
2184 return "%vmovaps\t{%1, %0|%0, %1}";
2185 case MODE_SI:
2186 return "%vmovd\t{%1, %0|%0, %1}";
2187 case MODE_SF:
2188 return "%vmovss\t{%1, %0|%0, %1}";
2189 default:
2190 gcc_unreachable ();
2191 }
2192
2193 case TYPE_MMX:
2194 return "pxor\t%0, %0";
2195
2196 case TYPE_MMXMOV:
2197 if (get_attr_mode (insn) == MODE_DI)
2198 return "movq\t{%1, %0|%0, %1}";
2199 return "movd\t{%1, %0|%0, %1}";
2200
2201 case TYPE_LEA:
2202 return "lea{l}\t{%a1, %0|%0, %a1}";
2203
2204 default:
2205 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2206 if (ix86_use_lea_for_mov (insn, operands))
2207 return "lea{l}\t{%a1, %0|%0, %a1}";
2208 else
2209 return "mov{l}\t{%1, %0|%0, %1}";
2210 }
2211 }
2212 [(set (attr "type")
2213 (cond [(eq_attr "alternative" "2")
2214 (const_string "mmx")
2215 (eq_attr "alternative" "3,4,5")
2216 (const_string "mmxmov")
2217 (eq_attr "alternative" "6")
2218 (const_string "sselog1")
2219 (eq_attr "alternative" "7,8,9,10,11")
2220 (const_string "ssemov")
2221 (match_operand 1 "pic_32bit_operand" "")
2222 (const_string "lea")
2223 ]
2224 (const_string "imov")))
2225 (set (attr "prefix")
2226 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2227 (const_string "orig")
2228 (const_string "maybe_vex")))
2229 (set (attr "prefix_data16")
2230 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2231 (const_string "1")
2232 (const_string "*")))
2233 (set (attr "mode")
2234 (cond [(eq_attr "alternative" "2,3")
2235 (const_string "DI")
2236 (eq_attr "alternative" "6,7")
2237 (if_then_else
2238 (not (match_test "TARGET_SSE2"))
2239 (const_string "V4SF")
2240 (const_string "TI"))
2241 (and (eq_attr "alternative" "8,9,10,11")
2242 (not (match_test "TARGET_SSE2")))
2243 (const_string "SF")
2244 ]
2245 (const_string "SI")))])
2246
2247 (define_insn "*movhi_internal"
2248 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2249 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2250 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2251 {
2252 switch (get_attr_type (insn))
2253 {
2254 case TYPE_IMOVX:
2255 /* movzwl is faster than movw on p2 due to partial word stalls,
2256 though not as fast as an aligned movl. */
2257 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2258 default:
2259 if (get_attr_mode (insn) == MODE_SI)
2260 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2261 else
2262 return "mov{w}\t{%1, %0|%0, %1}";
2263 }
2264 }
2265 [(set (attr "type")
2266 (cond [(match_test "optimize_function_for_size_p (cfun)")
2267 (const_string "imov")
2268 (and (eq_attr "alternative" "0")
2269 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2270 (not (match_test "TARGET_HIMODE_MATH"))))
2271 (const_string "imov")
2272 (and (eq_attr "alternative" "1,2")
2273 (match_operand:HI 1 "aligned_operand" ""))
2274 (const_string "imov")
2275 (and (match_test "TARGET_MOVX")
2276 (eq_attr "alternative" "0,2"))
2277 (const_string "imovx")
2278 ]
2279 (const_string "imov")))
2280 (set (attr "mode")
2281 (cond [(eq_attr "type" "imovx")
2282 (const_string "SI")
2283 (and (eq_attr "alternative" "1,2")
2284 (match_operand:HI 1 "aligned_operand" ""))
2285 (const_string "SI")
2286 (and (eq_attr "alternative" "0")
2287 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2288 (not (match_test "TARGET_HIMODE_MATH"))))
2289 (const_string "SI")
2290 ]
2291 (const_string "HI")))])
2292
2293 ;; Situation is quite tricky about when to choose full sized (SImode) move
2294 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2295 ;; partial register dependency machines (such as AMD Athlon), where QImode
2296 ;; moves issue extra dependency and for partial register stalls machines
2297 ;; that don't use QImode patterns (and QImode move cause stall on the next
2298 ;; instruction).
2299 ;;
2300 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2301 ;; register stall machines with, where we use QImode instructions, since
2302 ;; partial register stall can be caused there. Then we use movzx.
2303 (define_insn "*movqi_internal"
2304 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2305 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2306 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2307 {
2308 switch (get_attr_type (insn))
2309 {
2310 case TYPE_IMOVX:
2311 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2312 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2313 default:
2314 if (get_attr_mode (insn) == MODE_SI)
2315 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2316 else
2317 return "mov{b}\t{%1, %0|%0, %1}";
2318 }
2319 }
2320 [(set (attr "type")
2321 (cond [(and (eq_attr "alternative" "5")
2322 (not (match_operand:QI 1 "aligned_operand" "")))
2323 (const_string "imovx")
2324 (match_test "optimize_function_for_size_p (cfun)")
2325 (const_string "imov")
2326 (and (eq_attr "alternative" "3")
2327 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2328 (not (match_test "TARGET_QIMODE_MATH"))))
2329 (const_string "imov")
2330 (eq_attr "alternative" "3,5")
2331 (const_string "imovx")
2332 (and (match_test "TARGET_MOVX")
2333 (eq_attr "alternative" "2"))
2334 (const_string "imovx")
2335 ]
2336 (const_string "imov")))
2337 (set (attr "mode")
2338 (cond [(eq_attr "alternative" "3,4,5")
2339 (const_string "SI")
2340 (eq_attr "alternative" "6")
2341 (const_string "QI")
2342 (eq_attr "type" "imovx")
2343 (const_string "SI")
2344 (and (eq_attr "type" "imov")
2345 (and (eq_attr "alternative" "0,1")
2346 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2347 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2348 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2349 (const_string "SI")
2350 ;; Avoid partial register stalls when not using QImode arithmetic
2351 (and (eq_attr "type" "imov")
2352 (and (eq_attr "alternative" "0,1")
2353 (and (match_test "TARGET_PARTIAL_REG_STALL")
2354 (not (match_test "TARGET_QIMODE_MATH")))))
2355 (const_string "SI")
2356 ]
2357 (const_string "QI")))])
2358
2359 ;; Stores and loads of ax to arbitrary constant address.
2360 ;; We fake an second form of instruction to force reload to load address
2361 ;; into register when rax is not available
2362 (define_insn "*movabs<mode>_1"
2363 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2364 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2365 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2366 "@
2367 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2368 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2369 [(set_attr "type" "imov")
2370 (set_attr "modrm" "0,*")
2371 (set_attr "length_address" "8,0")
2372 (set_attr "length_immediate" "0,*")
2373 (set_attr "memory" "store")
2374 (set_attr "mode" "<MODE>")])
2375
2376 (define_insn "*movabs<mode>_2"
2377 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2378 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2379 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2380 "@
2381 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2382 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2383 [(set_attr "type" "imov")
2384 (set_attr "modrm" "0,*")
2385 (set_attr "length_address" "8,0")
2386 (set_attr "length_immediate" "0")
2387 (set_attr "memory" "load")
2388 (set_attr "mode" "<MODE>")])
2389
2390 (define_insn "*swap<mode>"
2391 [(set (match_operand:SWI48 0 "register_operand" "+r")
2392 (match_operand:SWI48 1 "register_operand" "+r"))
2393 (set (match_dup 1)
2394 (match_dup 0))]
2395 ""
2396 "xchg{<imodesuffix>}\t%1, %0"
2397 [(set_attr "type" "imov")
2398 (set_attr "mode" "<MODE>")
2399 (set_attr "pent_pair" "np")
2400 (set_attr "athlon_decode" "vector")
2401 (set_attr "amdfam10_decode" "double")
2402 (set_attr "bdver1_decode" "double")])
2403
2404 (define_insn "*swap<mode>_1"
2405 [(set (match_operand:SWI12 0 "register_operand" "+r")
2406 (match_operand:SWI12 1 "register_operand" "+r"))
2407 (set (match_dup 1)
2408 (match_dup 0))]
2409 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2410 "xchg{l}\t%k1, %k0"
2411 [(set_attr "type" "imov")
2412 (set_attr "mode" "SI")
2413 (set_attr "pent_pair" "np")
2414 (set_attr "athlon_decode" "vector")
2415 (set_attr "amdfam10_decode" "double")
2416 (set_attr "bdver1_decode" "double")])
2417
2418 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2419 ;; is disabled for AMDFAM10
2420 (define_insn "*swap<mode>_2"
2421 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2422 (match_operand:SWI12 1 "register_operand" "+<r>"))
2423 (set (match_dup 1)
2424 (match_dup 0))]
2425 "TARGET_PARTIAL_REG_STALL"
2426 "xchg{<imodesuffix>}\t%1, %0"
2427 [(set_attr "type" "imov")
2428 (set_attr "mode" "<MODE>")
2429 (set_attr "pent_pair" "np")
2430 (set_attr "athlon_decode" "vector")])
2431
2432 (define_expand "movstrict<mode>"
2433 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2434 (match_operand:SWI12 1 "general_operand" ""))]
2435 ""
2436 {
2437 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2438 FAIL;
2439 if (GET_CODE (operands[0]) == SUBREG
2440 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2441 FAIL;
2442 /* Don't generate memory->memory moves, go through a register */
2443 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2444 operands[1] = force_reg (<MODE>mode, operands[1]);
2445 })
2446
2447 (define_insn "*movstrict<mode>_1"
2448 [(set (strict_low_part
2449 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2450 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2451 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2452 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2453 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2454 [(set_attr "type" "imov")
2455 (set_attr "mode" "<MODE>")])
2456
2457 (define_insn "*movstrict<mode>_xor"
2458 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2459 (match_operand:SWI12 1 "const0_operand" ""))
2460 (clobber (reg:CC FLAGS_REG))]
2461 "reload_completed"
2462 "xor{<imodesuffix>}\t%0, %0"
2463 [(set_attr "type" "alu1")
2464 (set_attr "mode" "<MODE>")
2465 (set_attr "length_immediate" "0")])
2466
2467 (define_insn "*mov<mode>_extv_1"
2468 [(set (match_operand:SWI24 0 "register_operand" "=R")
2469 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2470 (const_int 8)
2471 (const_int 8)))]
2472 ""
2473 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2474 [(set_attr "type" "imovx")
2475 (set_attr "mode" "SI")])
2476
2477 (define_insn "*movqi_extv_1_rex64"
2478 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2479 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2480 (const_int 8)
2481 (const_int 8)))]
2482 "TARGET_64BIT"
2483 {
2484 switch (get_attr_type (insn))
2485 {
2486 case TYPE_IMOVX:
2487 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2488 default:
2489 return "mov{b}\t{%h1, %0|%0, %h1}";
2490 }
2491 }
2492 [(set (attr "type")
2493 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2494 (match_test "TARGET_MOVX"))
2495 (const_string "imovx")
2496 (const_string "imov")))
2497 (set (attr "mode")
2498 (if_then_else (eq_attr "type" "imovx")
2499 (const_string "SI")
2500 (const_string "QI")))])
2501
2502 (define_insn "*movqi_extv_1"
2503 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2504 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2505 (const_int 8)
2506 (const_int 8)))]
2507 "!TARGET_64BIT"
2508 {
2509 switch (get_attr_type (insn))
2510 {
2511 case TYPE_IMOVX:
2512 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2513 default:
2514 return "mov{b}\t{%h1, %0|%0, %h1}";
2515 }
2516 }
2517 [(set (attr "type")
2518 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2519 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2520 (match_test "TARGET_MOVX")))
2521 (const_string "imovx")
2522 (const_string "imov")))
2523 (set (attr "mode")
2524 (if_then_else (eq_attr "type" "imovx")
2525 (const_string "SI")
2526 (const_string "QI")))])
2527
2528 (define_insn "*mov<mode>_extzv_1"
2529 [(set (match_operand:SWI48 0 "register_operand" "=R")
2530 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2531 (const_int 8)
2532 (const_int 8)))]
2533 ""
2534 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535 [(set_attr "type" "imovx")
2536 (set_attr "mode" "SI")])
2537
2538 (define_insn "*movqi_extzv_2_rex64"
2539 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2540 (subreg:QI
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2542 (const_int 8)
2543 (const_int 8)) 0))]
2544 "TARGET_64BIT"
2545 {
2546 switch (get_attr_type (insn))
2547 {
2548 case TYPE_IMOVX:
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2550 default:
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2552 }
2553 }
2554 [(set (attr "type")
2555 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2556 (match_test "TARGET_MOVX"))
2557 (const_string "imovx")
2558 (const_string "imov")))
2559 (set (attr "mode")
2560 (if_then_else (eq_attr "type" "imovx")
2561 (const_string "SI")
2562 (const_string "QI")))])
2563
2564 (define_insn "*movqi_extzv_2"
2565 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2566 (subreg:QI
2567 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2568 (const_int 8)
2569 (const_int 8)) 0))]
2570 "!TARGET_64BIT"
2571 {
2572 switch (get_attr_type (insn))
2573 {
2574 case TYPE_IMOVX:
2575 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2576 default:
2577 return "mov{b}\t{%h1, %0|%0, %h1}";
2578 }
2579 }
2580 [(set (attr "type")
2581 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2582 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2583 (match_test "TARGET_MOVX")))
2584 (const_string "imovx")
2585 (const_string "imov")))
2586 (set (attr "mode")
2587 (if_then_else (eq_attr "type" "imovx")
2588 (const_string "SI")
2589 (const_string "QI")))])
2590
2591 (define_expand "mov<mode>_insv_1"
2592 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2593 (const_int 8)
2594 (const_int 8))
2595 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2596
2597 (define_insn "*mov<mode>_insv_1_rex64"
2598 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2599 (const_int 8)
2600 (const_int 8))
2601 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2602 "TARGET_64BIT"
2603 "mov{b}\t{%b1, %h0|%h0, %b1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "QI")])
2606
2607 (define_insn "*movsi_insv_1"
2608 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2609 (const_int 8)
2610 (const_int 8))
2611 (match_operand:SI 1 "general_operand" "Qmn"))]
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 "*movqi_insv_2"
2618 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2619 (const_int 8)
2620 (const_int 8))
2621 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2622 (const_int 8)))]
2623 ""
2624 "mov{b}\t{%h1, %h0|%h0, %h1}"
2625 [(set_attr "type" "imov")
2626 (set_attr "mode" "QI")])
2627 \f
2628 ;; Floating point push instructions.
2629
2630 (define_insn "*pushtf"
2631 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2632 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2633 "TARGET_SSE2"
2634 {
2635 /* This insn should be already split before reg-stack. */
2636 gcc_unreachable ();
2637 }
2638 [(set_attr "type" "multi")
2639 (set_attr "unit" "sse,*,*")
2640 (set_attr "mode" "TF,SI,SI")])
2641
2642 ;; %%% Kill this when call knows how to work this out.
2643 (define_split
2644 [(set (match_operand:TF 0 "push_operand" "")
2645 (match_operand:TF 1 "sse_reg_operand" ""))]
2646 "TARGET_SSE2 && reload_completed"
2647 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2648 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2649
2650 (define_insn "*pushxf"
2651 [(set (match_operand:XF 0 "push_operand" "=<,<")
2652 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2653 "optimize_function_for_speed_p (cfun)"
2654 {
2655 /* This insn should be already split before reg-stack. */
2656 gcc_unreachable ();
2657 }
2658 [(set_attr "type" "multi")
2659 (set_attr "unit" "i387,*")
2660 (set_attr "mode" "XF,SI")])
2661
2662 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references (assuming that any given constant is pushed
2666 ;; only once, but this ought to be handled elsewhere).
2667
2668 (define_insn "*pushxf_nointeger"
2669 [(set (match_operand:XF 0 "push_operand" "=<,<")
2670 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2671 "optimize_function_for_size_p (cfun)"
2672 {
2673 /* This insn should be already split before reg-stack. */
2674 gcc_unreachable ();
2675 }
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*")
2678 (set_attr "mode" "XF,SI")])
2679
2680 ;; %%% Kill this when call knows how to work this out.
2681 (define_split
2682 [(set (match_operand:XF 0 "push_operand" "")
2683 (match_operand:XF 1 "fp_register_operand" ""))]
2684 "reload_completed"
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2688
2689 (define_insn "*pushdf_rex64"
2690 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2691 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2692 "TARGET_64BIT"
2693 {
2694 /* This insn should be already split before reg-stack. */
2695 gcc_unreachable ();
2696 }
2697 [(set_attr "type" "multi")
2698 (set_attr "unit" "i387,*,*")
2699 (set_attr "mode" "DF,DI,DF")])
2700
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter.
2704
2705 (define_insn "*pushdf"
2706 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2708 "!TARGET_64BIT"
2709 {
2710 /* This insn should be already split before reg-stack. */
2711 gcc_unreachable ();
2712 }
2713 [(set_attr "isa" "*,*,sse2")
2714 (set_attr "type" "multi")
2715 (set_attr "unit" "i387,*,*")
2716 (set_attr "mode" "DF,DI,DF")])
2717
2718 ;; %%% Kill this when call knows how to work this out.
2719 (define_split
2720 [(set (match_operand:DF 0 "push_operand" "")
2721 (match_operand:DF 1 "any_fp_register_operand" ""))]
2722 "reload_completed"
2723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2724 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2725
2726 (define_insn "*pushsf_rex64"
2727 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2728 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2729 "TARGET_64BIT"
2730 {
2731 /* Anything else should be already split before reg-stack. */
2732 gcc_assert (which_alternative == 1);
2733 return "push{q}\t%q1";
2734 }
2735 [(set_attr "type" "multi,push,multi")
2736 (set_attr "unit" "i387,*,*")
2737 (set_attr "mode" "SF,DI,SF")])
2738
2739 (define_insn "*pushsf"
2740 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2741 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2742 "!TARGET_64BIT"
2743 {
2744 /* Anything else should be already split before reg-stack. */
2745 gcc_assert (which_alternative == 1);
2746 return "push{l}\t%1";
2747 }
2748 [(set_attr "type" "multi,push,multi")
2749 (set_attr "unit" "i387,*,*")
2750 (set_attr "mode" "SF,SI,SF")])
2751
2752 ;; %%% Kill this when call knows how to work this out.
2753 (define_split
2754 [(set (match_operand:SF 0 "push_operand" "")
2755 (match_operand:SF 1 "any_fp_register_operand" ""))]
2756 "reload_completed"
2757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2758 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2759 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2760
2761 (define_split
2762 [(set (match_operand:SF 0 "push_operand" "")
2763 (match_operand:SF 1 "memory_operand" ""))]
2764 "reload_completed
2765 && (operands[2] = find_constant_src (insn))"
2766 [(set (match_dup 0) (match_dup 2))])
2767
2768 (define_split
2769 [(set (match_operand 0 "push_operand" "")
2770 (match_operand 1 "general_operand" ""))]
2771 "reload_completed
2772 && (GET_MODE (operands[0]) == TFmode
2773 || GET_MODE (operands[0]) == XFmode
2774 || GET_MODE (operands[0]) == DFmode)
2775 && !ANY_FP_REG_P (operands[1])"
2776 [(const_int 0)]
2777 "ix86_split_long_move (operands); DONE;")
2778 \f
2779 ;; Floating point move instructions.
2780
2781 (define_expand "movtf"
2782 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2783 (match_operand:TF 1 "nonimmediate_operand" ""))]
2784 "TARGET_SSE2"
2785 {
2786 ix86_expand_move (TFmode, operands);
2787 DONE;
2788 })
2789
2790 (define_expand "mov<mode>"
2791 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2792 (match_operand:X87MODEF 1 "general_operand" ""))]
2793 ""
2794 "ix86_expand_move (<MODE>mode, operands); DONE;")
2795
2796 (define_insn "*movtf_internal"
2797 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2798 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2799 "TARGET_SSE2
2800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2801 && (!can_create_pseudo_p ()
2802 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2803 || GET_CODE (operands[1]) != CONST_DOUBLE
2804 || (optimize_function_for_size_p (cfun)
2805 && standard_sse_constant_p (operands[1])
2806 && !memory_operand (operands[0], TFmode))
2807 || (!TARGET_MEMORY_MISMATCH_STALL
2808 && memory_operand (operands[0], TFmode)))"
2809 {
2810 switch (which_alternative)
2811 {
2812 case 0:
2813 case 1:
2814 /* Handle misaligned load/store since we
2815 don't have movmisaligntf pattern. */
2816 if (misaligned_operand (operands[0], TFmode)
2817 || misaligned_operand (operands[1], TFmode))
2818 {
2819 if (get_attr_mode (insn) == MODE_V4SF)
2820 return "%vmovups\t{%1, %0|%0, %1}";
2821 else
2822 return "%vmovdqu\t{%1, %0|%0, %1}";
2823 }
2824 else
2825 {
2826 if (get_attr_mode (insn) == MODE_V4SF)
2827 return "%vmovaps\t{%1, %0|%0, %1}";
2828 else
2829 return "%vmovdqa\t{%1, %0|%0, %1}";
2830 }
2831
2832 case 2:
2833 return standard_sse_constant_opcode (insn, operands[1]);
2834
2835 case 3:
2836 case 4:
2837 return "#";
2838
2839 default:
2840 gcc_unreachable ();
2841 }
2842 }
2843 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2844 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2845 (set (attr "mode")
2846 (cond [(eq_attr "alternative" "0,2")
2847 (if_then_else
2848 (match_test "optimize_function_for_size_p (cfun)")
2849 (const_string "V4SF")
2850 (const_string "TI"))
2851 (eq_attr "alternative" "1")
2852 (if_then_else
2853 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2854 (match_test "optimize_function_for_size_p (cfun)"))
2855 (const_string "V4SF")
2856 (const_string "TI"))]
2857 (const_string "DI")))])
2858
2859 ;; Possible store forwarding (partial memory) stall in alternative 4.
2860 (define_insn "*movxf_internal"
2861 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2862 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864 && (!can_create_pseudo_p ()
2865 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2866 || GET_CODE (operands[1]) != CONST_DOUBLE
2867 || (optimize_function_for_size_p (cfun)
2868 && standard_80387_constant_p (operands[1]) > 0
2869 && !memory_operand (operands[0], XFmode))
2870 || (!TARGET_MEMORY_MISMATCH_STALL
2871 && memory_operand (operands[0], XFmode)))"
2872 {
2873 switch (which_alternative)
2874 {
2875 case 0:
2876 case 1:
2877 return output_387_reg_move (insn, operands);
2878
2879 case 2:
2880 return standard_80387_constant_opcode (operands[1]);
2881
2882 case 3:
2883 case 4:
2884 return "#";
2885
2886 default:
2887 gcc_unreachable ();
2888 }
2889 }
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2892
2893 (define_insn "*movdf_internal_rex64"
2894 [(set (match_operand:DF 0 "nonimmediate_operand"
2895 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2896 (match_operand:DF 1 "general_operand"
2897 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2898 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2899 && (!can_create_pseudo_p ()
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || GET_CODE (operands[1]) != CONST_DOUBLE
2902 || (optimize_function_for_size_p (cfun)
2903 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2904 && standard_80387_constant_p (operands[1]) > 0)
2905 || (TARGET_SSE2 && TARGET_SSE_MATH
2906 && standard_sse_constant_p (operands[1]))))
2907 || memory_operand (operands[0], DFmode))"
2908 {
2909 switch (which_alternative)
2910 {
2911 case 0:
2912 case 1:
2913 return output_387_reg_move (insn, operands);
2914
2915 case 2:
2916 return standard_80387_constant_opcode (operands[1]);
2917
2918 case 3:
2919 case 4:
2920 return "mov{q}\t{%1, %0|%0, %1}";
2921
2922 case 5:
2923 return "movabs{q}\t{%1, %0|%0, %1}";
2924
2925 case 6:
2926 return "#";
2927
2928 case 7:
2929 return standard_sse_constant_opcode (insn, operands[1]);
2930
2931 case 8:
2932 case 9:
2933 case 10:
2934 switch (get_attr_mode (insn))
2935 {
2936 case MODE_V2DF:
2937 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938 return "%vmovapd\t{%1, %0|%0, %1}";
2939 case MODE_V4SF:
2940 return "%vmovaps\t{%1, %0|%0, %1}";
2941
2942 case MODE_DI:
2943 return "%vmovq\t{%1, %0|%0, %1}";
2944 case MODE_DF:
2945 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2946 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2947 return "%vmovsd\t{%1, %0|%0, %1}";
2948 case MODE_V1DF:
2949 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2950 case MODE_V2SF:
2951 return "%vmovlps\t{%1, %d0|%d0, %1}";
2952 default:
2953 gcc_unreachable ();
2954 }
2955
2956 case 11:
2957 case 12:
2958 /* Handle broken assemblers that require movd instead of movq. */
2959 return "%vmovd\t{%1, %0|%0, %1}";
2960
2961 default:
2962 gcc_unreachable();
2963 }
2964 }
2965 [(set (attr "type")
2966 (cond [(eq_attr "alternative" "0,1,2")
2967 (const_string "fmov")
2968 (eq_attr "alternative" "3,4,5")
2969 (const_string "imov")
2970 (eq_attr "alternative" "6")
2971 (const_string "multi")
2972 (eq_attr "alternative" "7")
2973 (const_string "sselog1")
2974 ]
2975 (const_string "ssemov")))
2976 (set (attr "modrm")
2977 (if_then_else
2978 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2979 (const_string "0")
2980 (const_string "*")))
2981 (set (attr "length_immediate")
2982 (if_then_else
2983 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2984 (const_string "8")
2985 (const_string "*")))
2986 (set (attr "prefix")
2987 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2988 (const_string "orig")
2989 (const_string "maybe_vex")))
2990 (set (attr "prefix_data16")
2991 (if_then_else (eq_attr "mode" "V1DF")
2992 (const_string "1")
2993 (const_string "*")))
2994 (set (attr "mode")
2995 (cond [(eq_attr "alternative" "0,1,2")
2996 (const_string "DF")
2997 (eq_attr "alternative" "3,4,5,6,11,12")
2998 (const_string "DI")
2999
3000 /* xorps is one byte shorter. */
3001 (eq_attr "alternative" "7")
3002 (cond [(match_test "optimize_function_for_size_p (cfun)")
3003 (const_string "V4SF")
3004 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3005 (const_string "TI")
3006 ]
3007 (const_string "V2DF"))
3008
3009 /* For architectures resolving dependencies on
3010 whole SSE registers use APD move to break dependency
3011 chains, otherwise use short move to avoid extra work.
3012
3013 movaps encodes one byte shorter. */
3014 (eq_attr "alternative" "8")
3015 (cond
3016 [(match_test "optimize_function_for_size_p (cfun)")
3017 (const_string "V4SF")
3018 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3019 (const_string "V2DF")
3020 ]
3021 (const_string "DF"))
3022 /* For architectures resolving dependencies on register
3023 parts we may avoid extra work to zero out upper part
3024 of register. */
3025 (eq_attr "alternative" "9")
3026 (if_then_else
3027 (match_test "TARGET_SSE_SPLIT_REGS")
3028 (const_string "V1DF")
3029 (const_string "DF"))
3030 ]
3031 (const_string "DF")))])
3032
3033 ;; Possible store forwarding (partial memory) stall in alternative 4.
3034 (define_insn "*movdf_internal"
3035 [(set (match_operand:DF 0 "nonimmediate_operand"
3036 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3037 (match_operand:DF 1 "general_operand"
3038 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3039 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3040 && (!can_create_pseudo_p ()
3041 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3042 || GET_CODE (operands[1]) != CONST_DOUBLE
3043 || (optimize_function_for_size_p (cfun)
3044 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3045 && standard_80387_constant_p (operands[1]) > 0)
3046 || (TARGET_SSE2 && TARGET_SSE_MATH
3047 && standard_sse_constant_p (operands[1])))
3048 && !memory_operand (operands[0], DFmode))
3049 || (!TARGET_MEMORY_MISMATCH_STALL
3050 && memory_operand (operands[0], DFmode)))"
3051 {
3052 switch (which_alternative)
3053 {
3054 case 0:
3055 case 1:
3056 return output_387_reg_move (insn, operands);
3057
3058 case 2:
3059 return standard_80387_constant_opcode (operands[1]);
3060
3061 case 3:
3062 case 4:
3063 return "#";
3064
3065 case 5:
3066 case 9:
3067 return standard_sse_constant_opcode (insn, operands[1]);
3068
3069 case 6:
3070 case 7:
3071 case 8:
3072 case 10:
3073 case 11:
3074 case 12:
3075 switch (get_attr_mode (insn))
3076 {
3077 case MODE_V2DF:
3078 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3079 return "%vmovapd\t{%1, %0|%0, %1}";
3080 case MODE_V4SF:
3081 return "%vmovaps\t{%1, %0|%0, %1}";
3082
3083 case MODE_DI:
3084 return "%vmovq\t{%1, %0|%0, %1}";
3085 case MODE_DF:
3086 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3087 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3088 return "%vmovsd\t{%1, %0|%0, %1}";
3089 case MODE_V1DF:
3090 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3091 case MODE_V2SF:
3092 return "%vmovlps\t{%1, %d0|%d0, %1}";
3093 default:
3094 gcc_unreachable ();
3095 }
3096
3097 default:
3098 gcc_unreachable ();
3099 }
3100 }
3101 [(set (attr "isa")
3102 (if_then_else (eq_attr "alternative" "5,6,7,8")
3103 (const_string "sse2")
3104 (const_string "*")))
3105 (set (attr "type")
3106 (cond [(eq_attr "alternative" "0,1,2")
3107 (const_string "fmov")
3108 (eq_attr "alternative" "3,4")
3109 (const_string "multi")
3110 (eq_attr "alternative" "5,9")
3111 (const_string "sselog1")
3112 ]
3113 (const_string "ssemov")))
3114 (set (attr "prefix")
3115 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3116 (const_string "orig")
3117 (const_string "maybe_vex")))
3118 (set (attr "prefix_data16")
3119 (if_then_else (eq_attr "mode" "V1DF")
3120 (const_string "1")
3121 (const_string "*")))
3122 (set (attr "mode")
3123 (cond [(eq_attr "alternative" "0,1,2")
3124 (const_string "DF")
3125 (eq_attr "alternative" "3,4")
3126 (const_string "SI")
3127
3128 /* For SSE1, we have many fewer alternatives. */
3129 (not (match_test "TARGET_SSE2"))
3130 (if_then_else
3131 (eq_attr "alternative" "5,6,9,10")
3132 (const_string "V4SF")
3133 (const_string "V2SF"))
3134
3135 /* xorps is one byte shorter. */
3136 (eq_attr "alternative" "5,9")
3137 (cond [(match_test "optimize_function_for_size_p (cfun)")
3138 (const_string "V4SF")
3139 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3140 (const_string "TI")
3141 ]
3142 (const_string "V2DF"))
3143
3144 /* For architectures resolving dependencies on
3145 whole SSE registers use APD move to break dependency
3146 chains, otherwise use short move to avoid extra work.
3147
3148 movaps encodes one byte shorter. */
3149 (eq_attr "alternative" "6,10")
3150 (cond
3151 [(match_test "optimize_function_for_size_p (cfun)")
3152 (const_string "V4SF")
3153 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154 (const_string "V2DF")
3155 ]
3156 (const_string "DF"))
3157 /* For architectures resolving dependencies on register
3158 parts we may avoid extra work to zero out upper part
3159 of register. */
3160 (eq_attr "alternative" "7,11")
3161 (if_then_else
3162 (match_test "TARGET_SSE_SPLIT_REGS")
3163 (const_string "V1DF")
3164 (const_string "DF"))
3165 ]
3166 (const_string "DF")))])
3167
3168 (define_insn "*movsf_internal"
3169 [(set (match_operand:SF 0 "nonimmediate_operand"
3170 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3171 (match_operand:SF 1 "general_operand"
3172 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3173 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3174 && (!can_create_pseudo_p ()
3175 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3176 || GET_CODE (operands[1]) != CONST_DOUBLE
3177 || (optimize_function_for_size_p (cfun)
3178 && ((!TARGET_SSE_MATH
3179 && standard_80387_constant_p (operands[1]) > 0)
3180 || (TARGET_SSE_MATH
3181 && standard_sse_constant_p (operands[1]))))
3182 || memory_operand (operands[0], SFmode))"
3183 {
3184 switch (which_alternative)
3185 {
3186 case 0:
3187 case 1:
3188 return output_387_reg_move (insn, operands);
3189
3190 case 2:
3191 return standard_80387_constant_opcode (operands[1]);
3192
3193 case 3:
3194 case 4:
3195 return "mov{l}\t{%1, %0|%0, %1}";
3196
3197 case 5:
3198 return standard_sse_constant_opcode (insn, operands[1]);
3199
3200 case 6:
3201 if (get_attr_mode (insn) == MODE_V4SF)
3202 return "%vmovaps\t{%1, %0|%0, %1}";
3203 if (TARGET_AVX)
3204 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3205
3206 case 7:
3207 case 8:
3208 return "%vmovss\t{%1, %0|%0, %1}";
3209
3210 case 9:
3211 case 10:
3212 case 14:
3213 case 15:
3214 return "movd\t{%1, %0|%0, %1}";
3215
3216 case 11:
3217 return "movq\t{%1, %0|%0, %1}";
3218
3219 case 12:
3220 case 13:
3221 return "%vmovd\t{%1, %0|%0, %1}";
3222
3223 default:
3224 gcc_unreachable ();
3225 }
3226 }
3227 [(set (attr "type")
3228 (cond [(eq_attr "alternative" "0,1,2")
3229 (const_string "fmov")
3230 (eq_attr "alternative" "3,4")
3231 (const_string "multi")
3232 (eq_attr "alternative" "5")
3233 (const_string "sselog1")
3234 (eq_attr "alternative" "9,10,11,14,15")
3235 (const_string "mmxmov")
3236 ]
3237 (const_string "ssemov")))
3238 (set (attr "prefix")
3239 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3240 (const_string "maybe_vex")
3241 (const_string "orig")))
3242 (set (attr "mode")
3243 (cond [(eq_attr "alternative" "3,4,9,10")
3244 (const_string "SI")
3245 (eq_attr "alternative" "5")
3246 (if_then_else
3247 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3248 (match_test "TARGET_SSE2"))
3249 (not (match_test "optimize_function_for_size_p (cfun)")))
3250 (const_string "TI")
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3255
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3263 (if_then_else
3264 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265 (match_test "TARGET_SSE_SPLIT_REGS"))
3266 (const_string "V4SF")
3267 (const_string "SF"))
3268 (eq_attr "alternative" "11")
3269 (const_string "DI")]
3270 (const_string "SF")))])
3271
3272 (define_split
3273 [(set (match_operand 0 "any_fp_register_operand" "")
3274 (match_operand 1 "memory_operand" ""))]
3275 "reload_completed
3276 && (GET_MODE (operands[0]) == TFmode
3277 || GET_MODE (operands[0]) == XFmode
3278 || GET_MODE (operands[0]) == DFmode
3279 || GET_MODE (operands[0]) == SFmode)
3280 && (operands[2] = find_constant_src (insn))"
3281 [(set (match_dup 0) (match_dup 2))]
3282 {
3283 rtx c = operands[2];
3284 int r = REGNO (operands[0]);
3285
3286 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3287 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3288 FAIL;
3289 })
3290
3291 (define_split
3292 [(set (match_operand 0 "any_fp_register_operand" "")
3293 (float_extend (match_operand 1 "memory_operand" "")))]
3294 "reload_completed
3295 && (GET_MODE (operands[0]) == TFmode
3296 || GET_MODE (operands[0]) == XFmode
3297 || GET_MODE (operands[0]) == DFmode)
3298 && (operands[2] = find_constant_src (insn))"
3299 [(set (match_dup 0) (match_dup 2))]
3300 {
3301 rtx c = operands[2];
3302 int r = REGNO (operands[0]);
3303
3304 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3305 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3306 FAIL;
3307 })
3308
3309 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3310 (define_split
3311 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3312 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3313 "reload_completed
3314 && (standard_80387_constant_p (operands[1]) == 8
3315 || standard_80387_constant_p (operands[1]) == 9)"
3316 [(set (match_dup 0)(match_dup 1))
3317 (set (match_dup 0)
3318 (neg:X87MODEF (match_dup 0)))]
3319 {
3320 REAL_VALUE_TYPE r;
3321
3322 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3323 if (real_isnegzero (&r))
3324 operands[1] = CONST0_RTX (<MODE>mode);
3325 else
3326 operands[1] = CONST1_RTX (<MODE>mode);
3327 })
3328
3329 (define_split
3330 [(set (match_operand 0 "nonimmediate_operand" "")
3331 (match_operand 1 "general_operand" ""))]
3332 "reload_completed
3333 && (GET_MODE (operands[0]) == TFmode
3334 || GET_MODE (operands[0]) == XFmode
3335 || GET_MODE (operands[0]) == DFmode)
3336 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3337 [(const_int 0)]
3338 "ix86_split_long_move (operands); DONE;")
3339
3340 (define_insn "swapxf"
3341 [(set (match_operand:XF 0 "register_operand" "+f")
3342 (match_operand:XF 1 "register_operand" "+f"))
3343 (set (match_dup 1)
3344 (match_dup 0))]
3345 "TARGET_80387"
3346 {
3347 if (STACK_TOP_P (operands[0]))
3348 return "fxch\t%1";
3349 else
3350 return "fxch\t%0";
3351 }
3352 [(set_attr "type" "fxch")
3353 (set_attr "mode" "XF")])
3354
3355 (define_insn "*swap<mode>"
3356 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3357 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3358 (set (match_dup 1)
3359 (match_dup 0))]
3360 "TARGET_80387 || reload_completed"
3361 {
3362 if (STACK_TOP_P (operands[0]))
3363 return "fxch\t%1";
3364 else
3365 return "fxch\t%0";
3366 }
3367 [(set_attr "type" "fxch")
3368 (set_attr "mode" "<MODE>")])
3369 \f
3370 ;; Zero extension instructions
3371
3372 (define_expand "zero_extendsidi2"
3373 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3374 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3375 ""
3376 {
3377 if (!TARGET_64BIT)
3378 {
3379 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3380 DONE;
3381 }
3382 })
3383
3384 (define_insn "*zero_extendsidi2_rex64"
3385 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3386 (zero_extend:DI
3387 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3388 "TARGET_64BIT"
3389 "@
3390 mov\t{%k1, %k0|%k0, %k1}
3391 #
3392 movd\t{%1, %0|%0, %1}
3393 movd\t{%1, %0|%0, %1}
3394 %vmovd\t{%1, %0|%0, %1}
3395 %vmovd\t{%1, %0|%0, %1}"
3396 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3397 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3398 (set_attr "prefix_0f" "0,*,*,*,*,*")
3399 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3400
3401 (define_split
3402 [(set (match_operand:DI 0 "memory_operand" "")
3403 (zero_extend:DI (match_dup 0)))]
3404 "TARGET_64BIT"
3405 [(set (match_dup 4) (const_int 0))]
3406 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3407
3408 ;; %%% Kill me once multi-word ops are sane.
3409 (define_insn "zero_extendsidi2_1"
3410 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3411 (zero_extend:DI
3412 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3413 (clobber (reg:CC FLAGS_REG))]
3414 "!TARGET_64BIT"
3415 "@
3416 #
3417 #
3418 #
3419 movd\t{%1, %0|%0, %1}
3420 movd\t{%1, %0|%0, %1}
3421 %vmovd\t{%1, %0|%0, %1}
3422 %vmovd\t{%1, %0|%0, %1}"
3423 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3424 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3425 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3426 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3427
3428 (define_split
3429 [(set (match_operand:DI 0 "register_operand" "")
3430 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3431 (clobber (reg:CC FLAGS_REG))]
3432 "!TARGET_64BIT && reload_completed
3433 && true_regnum (operands[0]) == true_regnum (operands[1])"
3434 [(set (match_dup 4) (const_int 0))]
3435 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3436
3437 (define_split
3438 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3439 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3440 (clobber (reg:CC FLAGS_REG))]
3441 "!TARGET_64BIT && reload_completed
3442 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3443 [(set (match_dup 3) (match_dup 1))
3444 (set (match_dup 4) (const_int 0))]
3445 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3446
3447 (define_insn "zero_extend<mode>di2"
3448 [(set (match_operand:DI 0 "register_operand" "=r")
3449 (zero_extend:DI
3450 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3451 "TARGET_64BIT"
3452 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "SI")])
3455
3456 (define_expand "zero_extendhisi2"
3457 [(set (match_operand:SI 0 "register_operand" "")
3458 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3459 ""
3460 {
3461 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3462 {
3463 operands[1] = force_reg (HImode, operands[1]);
3464 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3465 DONE;
3466 }
3467 })
3468
3469 (define_insn_and_split "zero_extendhisi2_and"
3470 [(set (match_operand:SI 0 "register_operand" "=r")
3471 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3472 (clobber (reg:CC FLAGS_REG))]
3473 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3474 "#"
3475 "&& reload_completed"
3476 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3477 (clobber (reg:CC FLAGS_REG))])]
3478 ""
3479 [(set_attr "type" "alu1")
3480 (set_attr "mode" "SI")])
3481
3482 (define_insn "*zero_extendhisi2_movzwl"
3483 [(set (match_operand:SI 0 "register_operand" "=r")
3484 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3485 "!TARGET_ZERO_EXTEND_WITH_AND
3486 || optimize_function_for_size_p (cfun)"
3487 "movz{wl|x}\t{%1, %0|%0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "SI")])
3490
3491 (define_expand "zero_extendqi<mode>2"
3492 [(parallel
3493 [(set (match_operand:SWI24 0 "register_operand" "")
3494 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3495 (clobber (reg:CC FLAGS_REG))])])
3496
3497 (define_insn "*zero_extendqi<mode>2_and"
3498 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3499 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3500 (clobber (reg:CC FLAGS_REG))]
3501 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3502 "#"
3503 [(set_attr "type" "alu1")
3504 (set_attr "mode" "<MODE>")])
3505
3506 ;; When source and destination does not overlap, clear destination
3507 ;; first and then do the movb
3508 (define_split
3509 [(set (match_operand:SWI24 0 "register_operand" "")
3510 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3511 (clobber (reg:CC FLAGS_REG))]
3512 "reload_completed
3513 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3514 && ANY_QI_REG_P (operands[0])
3515 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3516 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3517 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3518 {
3519 operands[2] = gen_lowpart (QImode, operands[0]);
3520 ix86_expand_clear (operands[0]);
3521 })
3522
3523 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3524 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3525 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3526 (clobber (reg:CC FLAGS_REG))]
3527 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3528 "#"
3529 [(set_attr "type" "imovx,alu1")
3530 (set_attr "mode" "<MODE>")])
3531
3532 ;; For the movzbl case strip only the clobber
3533 (define_split
3534 [(set (match_operand:SWI24 0 "register_operand" "")
3535 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3536 (clobber (reg:CC FLAGS_REG))]
3537 "reload_completed
3538 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3539 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3540 [(set (match_dup 0)
3541 (zero_extend:SWI24 (match_dup 1)))])
3542
3543 ; zero extend to SImode to avoid partial register stalls
3544 (define_insn "*zero_extendqi<mode>2_movzbl"
3545 [(set (match_operand:SWI24 0 "register_operand" "=r")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547 "reload_completed
3548 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3549 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3550 [(set_attr "type" "imovx")
3551 (set_attr "mode" "SI")])
3552
3553 ;; Rest is handled by single and.
3554 (define_split
3555 [(set (match_operand:SWI24 0 "register_operand" "")
3556 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3557 (clobber (reg:CC FLAGS_REG))]
3558 "reload_completed
3559 && true_regnum (operands[0]) == true_regnum (operands[1])"
3560 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3561 (clobber (reg:CC FLAGS_REG))])])
3562 \f
3563 ;; Sign extension instructions
3564
3565 (define_expand "extendsidi2"
3566 [(set (match_operand:DI 0 "register_operand" "")
3567 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3568 ""
3569 {
3570 if (!TARGET_64BIT)
3571 {
3572 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3573 DONE;
3574 }
3575 })
3576
3577 (define_insn "*extendsidi2_rex64"
3578 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3579 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3580 "TARGET_64BIT"
3581 "@
3582 {cltq|cdqe}
3583 movs{lq|x}\t{%1, %0|%0, %1}"
3584 [(set_attr "type" "imovx")
3585 (set_attr "mode" "DI")
3586 (set_attr "prefix_0f" "0")
3587 (set_attr "modrm" "0,1")])
3588
3589 (define_insn "extendsidi2_1"
3590 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3591 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3592 (clobber (reg:CC FLAGS_REG))
3593 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3594 "!TARGET_64BIT"
3595 "#")
3596
3597 ;; Extend to memory case when source register does die.
3598 (define_split
3599 [(set (match_operand:DI 0 "memory_operand" "")
3600 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3601 (clobber (reg:CC FLAGS_REG))
3602 (clobber (match_operand:SI 2 "register_operand" ""))]
3603 "(reload_completed
3604 && dead_or_set_p (insn, operands[1])
3605 && !reg_mentioned_p (operands[1], operands[0]))"
3606 [(set (match_dup 3) (match_dup 1))
3607 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3608 (clobber (reg:CC FLAGS_REG))])
3609 (set (match_dup 4) (match_dup 1))]
3610 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3611
3612 ;; Extend to memory case when source register does not die.
3613 (define_split
3614 [(set (match_operand:DI 0 "memory_operand" "")
3615 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3616 (clobber (reg:CC FLAGS_REG))
3617 (clobber (match_operand:SI 2 "register_operand" ""))]
3618 "reload_completed"
3619 [(const_int 0)]
3620 {
3621 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3622
3623 emit_move_insn (operands[3], operands[1]);
3624
3625 /* Generate a cltd if possible and doing so it profitable. */
3626 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3627 && true_regnum (operands[1]) == AX_REG
3628 && true_regnum (operands[2]) == DX_REG)
3629 {
3630 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3631 }
3632 else
3633 {
3634 emit_move_insn (operands[2], operands[1]);
3635 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3636 }
3637 emit_move_insn (operands[4], operands[2]);
3638 DONE;
3639 })
3640
3641 ;; Extend to register case. Optimize case where source and destination
3642 ;; registers match and cases where we can use cltd.
3643 (define_split
3644 [(set (match_operand:DI 0 "register_operand" "")
3645 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3646 (clobber (reg:CC FLAGS_REG))
3647 (clobber (match_scratch:SI 2 ""))]
3648 "reload_completed"
3649 [(const_int 0)]
3650 {
3651 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3652
3653 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3654 emit_move_insn (operands[3], operands[1]);
3655
3656 /* Generate a cltd if possible and doing so it profitable. */
3657 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3658 && true_regnum (operands[3]) == AX_REG
3659 && true_regnum (operands[4]) == DX_REG)
3660 {
3661 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3662 DONE;
3663 }
3664
3665 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3666 emit_move_insn (operands[4], operands[1]);
3667
3668 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3669 DONE;
3670 })
3671
3672 (define_insn "extend<mode>di2"
3673 [(set (match_operand:DI 0 "register_operand" "=r")
3674 (sign_extend:DI
3675 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3676 "TARGET_64BIT"
3677 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3678 [(set_attr "type" "imovx")
3679 (set_attr "mode" "DI")])
3680
3681 (define_insn "extendhisi2"
3682 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3683 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3684 ""
3685 {
3686 switch (get_attr_prefix_0f (insn))
3687 {
3688 case 0:
3689 return "{cwtl|cwde}";
3690 default:
3691 return "movs{wl|x}\t{%1, %0|%0, %1}";
3692 }
3693 }
3694 [(set_attr "type" "imovx")
3695 (set_attr "mode" "SI")
3696 (set (attr "prefix_0f")
3697 ;; movsx is short decodable while cwtl is vector decoded.
3698 (if_then_else (and (eq_attr "cpu" "!k6")
3699 (eq_attr "alternative" "0"))
3700 (const_string "0")
3701 (const_string "1")))
3702 (set (attr "modrm")
3703 (if_then_else (eq_attr "prefix_0f" "0")
3704 (const_string "0")
3705 (const_string "1")))])
3706
3707 (define_insn "*extendhisi2_zext"
3708 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3709 (zero_extend:DI
3710 (sign_extend:SI
3711 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3712 "TARGET_64BIT"
3713 {
3714 switch (get_attr_prefix_0f (insn))
3715 {
3716 case 0:
3717 return "{cwtl|cwde}";
3718 default:
3719 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3720 }
3721 }
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "SI")
3724 (set (attr "prefix_0f")
3725 ;; movsx is short decodable while cwtl is vector decoded.
3726 (if_then_else (and (eq_attr "cpu" "!k6")
3727 (eq_attr "alternative" "0"))
3728 (const_string "0")
3729 (const_string "1")))
3730 (set (attr "modrm")
3731 (if_then_else (eq_attr "prefix_0f" "0")
3732 (const_string "0")
3733 (const_string "1")))])
3734
3735 (define_insn "extendqisi2"
3736 [(set (match_operand:SI 0 "register_operand" "=r")
3737 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3738 ""
3739 "movs{bl|x}\t{%1, %0|%0, %1}"
3740 [(set_attr "type" "imovx")
3741 (set_attr "mode" "SI")])
3742
3743 (define_insn "*extendqisi2_zext"
3744 [(set (match_operand:DI 0 "register_operand" "=r")
3745 (zero_extend:DI
3746 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3747 "TARGET_64BIT"
3748 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "SI")])
3751
3752 (define_insn "extendqihi2"
3753 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3754 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3755 ""
3756 {
3757 switch (get_attr_prefix_0f (insn))
3758 {
3759 case 0:
3760 return "{cbtw|cbw}";
3761 default:
3762 return "movs{bw|x}\t{%1, %0|%0, %1}";
3763 }
3764 }
3765 [(set_attr "type" "imovx")
3766 (set_attr "mode" "HI")
3767 (set (attr "prefix_0f")
3768 ;; movsx is short decodable while cwtl is vector decoded.
3769 (if_then_else (and (eq_attr "cpu" "!k6")
3770 (eq_attr "alternative" "0"))
3771 (const_string "0")
3772 (const_string "1")))
3773 (set (attr "modrm")
3774 (if_then_else (eq_attr "prefix_0f" "0")
3775 (const_string "0")
3776 (const_string "1")))])
3777 \f
3778 ;; Conversions between float and double.
3779
3780 ;; These are all no-ops in the model used for the 80387.
3781 ;; So just emit moves.
3782
3783 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3784 (define_split
3785 [(set (match_operand:DF 0 "push_operand" "")
3786 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3787 "reload_completed"
3788 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3789 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3790
3791 (define_split
3792 [(set (match_operand:XF 0 "push_operand" "")
3793 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3794 "reload_completed"
3795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3796 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3797 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3798
3799 (define_expand "extendsfdf2"
3800 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3801 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3802 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3803 {
3804 /* ??? Needed for compress_float_constant since all fp constants
3805 are TARGET_LEGITIMATE_CONSTANT_P. */
3806 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3807 {
3808 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3809 && standard_80387_constant_p (operands[1]) > 0)
3810 {
3811 operands[1] = simplify_const_unary_operation
3812 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3813 emit_move_insn_1 (operands[0], operands[1]);
3814 DONE;
3815 }
3816 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3817 }
3818 })
3819
3820 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3821 cvtss2sd:
3822 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3823 cvtps2pd xmm2,xmm1
3824 We do the conversion post reload to avoid producing of 128bit spills
3825 that might lead to ICE on 32bit target. The sequence unlikely combine
3826 anyway. */
3827 (define_split
3828 [(set (match_operand:DF 0 "register_operand" "")
3829 (float_extend:DF
3830 (match_operand:SF 1 "nonimmediate_operand" "")))]
3831 "TARGET_USE_VECTOR_FP_CONVERTS
3832 && optimize_insn_for_speed_p ()
3833 && reload_completed && SSE_REG_P (operands[0])"
3834 [(set (match_dup 2)
3835 (float_extend:V2DF
3836 (vec_select:V2SF
3837 (match_dup 3)
3838 (parallel [(const_int 0) (const_int 1)]))))]
3839 {
3840 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3841 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3842 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3843 Try to avoid move when unpacking can be done in source. */
3844 if (REG_P (operands[1]))
3845 {
3846 /* If it is unsafe to overwrite upper half of source, we need
3847 to move to destination and unpack there. */
3848 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3849 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3850 && true_regnum (operands[0]) != true_regnum (operands[1]))
3851 {
3852 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3853 emit_move_insn (tmp, operands[1]);
3854 }
3855 else
3856 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3857 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3858 operands[3]));
3859 }
3860 else
3861 emit_insn (gen_vec_setv4sf_0 (operands[3],
3862 CONST0_RTX (V4SFmode), operands[1]));
3863 })
3864
3865 (define_insn "*extendsfdf2_mixed"
3866 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3867 (float_extend:DF
3868 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3869 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3870 {
3871 switch (which_alternative)
3872 {
3873 case 0:
3874 case 1:
3875 return output_387_reg_move (insn, operands);
3876
3877 case 2:
3878 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3879
3880 default:
3881 gcc_unreachable ();
3882 }
3883 }
3884 [(set_attr "type" "fmov,fmov,ssecvt")
3885 (set_attr "prefix" "orig,orig,maybe_vex")
3886 (set_attr "mode" "SF,XF,DF")])
3887
3888 (define_insn "*extendsfdf2_sse"
3889 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3890 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3891 "TARGET_SSE2 && TARGET_SSE_MATH"
3892 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3893 [(set_attr "type" "ssecvt")
3894 (set_attr "prefix" "maybe_vex")
3895 (set_attr "mode" "DF")])
3896
3897 (define_insn "*extendsfdf2_i387"
3898 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3899 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3900 "TARGET_80387"
3901 "* return output_387_reg_move (insn, operands);"
3902 [(set_attr "type" "fmov")
3903 (set_attr "mode" "SF,XF")])
3904
3905 (define_expand "extend<mode>xf2"
3906 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3907 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3908 "TARGET_80387"
3909 {
3910 /* ??? Needed for compress_float_constant since all fp constants
3911 are TARGET_LEGITIMATE_CONSTANT_P. */
3912 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3913 {
3914 if (standard_80387_constant_p (operands[1]) > 0)
3915 {
3916 operands[1] = simplify_const_unary_operation
3917 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3918 emit_move_insn_1 (operands[0], operands[1]);
3919 DONE;
3920 }
3921 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3922 }
3923 })
3924
3925 (define_insn "*extend<mode>xf2_i387"
3926 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3927 (float_extend:XF
3928 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3929 "TARGET_80387"
3930 "* return output_387_reg_move (insn, operands);"
3931 [(set_attr "type" "fmov")
3932 (set_attr "mode" "<MODE>,XF")])
3933
3934 ;; %%% This seems bad bad news.
3935 ;; This cannot output into an f-reg because there is no way to be sure
3936 ;; of truncating in that case. Otherwise this is just like a simple move
3937 ;; insn. So we pretend we can output to a reg in order to get better
3938 ;; register preferencing, but we really use a stack slot.
3939
3940 ;; Conversion from DFmode to SFmode.
3941
3942 (define_expand "truncdfsf2"
3943 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3944 (float_truncate:SF
3945 (match_operand:DF 1 "nonimmediate_operand" "")))]
3946 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3947 {
3948 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3949 ;
3950 else if (flag_unsafe_math_optimizations)
3951 ;
3952 else
3953 {
3954 enum ix86_stack_slot slot = (virtuals_instantiated
3955 ? SLOT_TEMP
3956 : SLOT_VIRTUAL);
3957 rtx temp = assign_386_stack_local (SFmode, slot);
3958 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3959 DONE;
3960 }
3961 })
3962
3963 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3964 cvtsd2ss:
3965 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3966 cvtpd2ps xmm2,xmm1
3967 We do the conversion post reload to avoid producing of 128bit spills
3968 that might lead to ICE on 32bit target. The sequence unlikely combine
3969 anyway. */
3970 (define_split
3971 [(set (match_operand:SF 0 "register_operand" "")
3972 (float_truncate:SF
3973 (match_operand:DF 1 "nonimmediate_operand" "")))]
3974 "TARGET_USE_VECTOR_FP_CONVERTS
3975 && optimize_insn_for_speed_p ()
3976 && reload_completed && SSE_REG_P (operands[0])"
3977 [(set (match_dup 2)
3978 (vec_concat:V4SF
3979 (float_truncate:V2SF
3980 (match_dup 4))
3981 (match_dup 3)))]
3982 {
3983 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3984 operands[3] = CONST0_RTX (V2SFmode);
3985 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3986 /* Use movsd for loading from memory, unpcklpd for registers.
3987 Try to avoid move when unpacking can be done in source, or SSE3
3988 movddup is available. */
3989 if (REG_P (operands[1]))
3990 {
3991 if (!TARGET_SSE3
3992 && true_regnum (operands[0]) != true_regnum (operands[1])
3993 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3994 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3995 {
3996 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3997 emit_move_insn (tmp, operands[1]);
3998 operands[1] = tmp;
3999 }
4000 else if (!TARGET_SSE3)
4001 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4002 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4003 }
4004 else
4005 emit_insn (gen_sse2_loadlpd (operands[4],
4006 CONST0_RTX (V2DFmode), operands[1]));
4007 })
4008
4009 (define_expand "truncdfsf2_with_temp"
4010 [(parallel [(set (match_operand:SF 0 "" "")
4011 (float_truncate:SF (match_operand:DF 1 "" "")))
4012 (clobber (match_operand:SF 2 "" ""))])])
4013
4014 (define_insn "*truncdfsf_fast_mixed"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4016 (float_truncate:SF
4017 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4018 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4019 {
4020 switch (which_alternative)
4021 {
4022 case 0:
4023 return output_387_reg_move (insn, operands);
4024 case 1:
4025 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4026 default:
4027 gcc_unreachable ();
4028 }
4029 }
4030 [(set_attr "type" "fmov,ssecvt")
4031 (set_attr "prefix" "orig,maybe_vex")
4032 (set_attr "mode" "SF")])
4033
4034 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4035 ;; because nothing we do here is unsafe.
4036 (define_insn "*truncdfsf_fast_sse"
4037 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4038 (float_truncate:SF
4039 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4040 "TARGET_SSE2 && TARGET_SSE_MATH"
4041 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4042 [(set_attr "type" "ssecvt")
4043 (set_attr "prefix" "maybe_vex")
4044 (set_attr "mode" "SF")])
4045
4046 (define_insn "*truncdfsf_fast_i387"
4047 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4048 (float_truncate:SF
4049 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4050 "TARGET_80387 && flag_unsafe_math_optimizations"
4051 "* return output_387_reg_move (insn, operands);"
4052 [(set_attr "type" "fmov")
4053 (set_attr "mode" "SF")])
4054
4055 (define_insn "*truncdfsf_mixed"
4056 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4057 (float_truncate:SF
4058 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4059 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4060 "TARGET_MIX_SSE_I387"
4061 {
4062 switch (which_alternative)
4063 {
4064 case 0:
4065 return output_387_reg_move (insn, operands);
4066 case 1:
4067 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4068
4069 default:
4070 return "#";
4071 }
4072 }
4073 [(set_attr "isa" "*,sse2,*,*,*")
4074 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4078
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4081 (float_truncate:SF
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4084 "TARGET_80387"
4085 {
4086 switch (which_alternative)
4087 {
4088 case 0:
4089 return output_387_reg_move (insn, operands);
4090
4091 default:
4092 return "#";
4093 }
4094 }
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4098
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4101 (float_truncate:SF
4102 (match_operand:DF 1 "register_operand" "f")))]
4103 "TARGET_80387
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4109
4110 (define_split
4111 [(set (match_operand:SF 0 "register_operand" "")
4112 (float_truncate:SF
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4115 "reload_completed"
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4119
4120 ;; Conversion from XFmode to {SF,DF}mode
4121
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4127 "TARGET_80387"
4128 {
4129 if (flag_unsafe_math_optimizations)
4130 {
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4135 DONE;
4136 }
4137 else
4138 {
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4140 ? SLOT_TEMP
4141 : SLOT_VIRTUAL);
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4143 }
4144 })
4145
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4148 (float_truncate:SF
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4151 "TARGET_80387"
4152 {
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4155 }
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4162 (float_truncate:DF
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4165 "TARGET_80387"
4166 {
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4169 }
4170 [(set_attr "isa" "*,*,sse2,*")
4171 (set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "DF")])
4174
4175 (define_insn "truncxf<mode>2_i387_noop"
4176 [(set (match_operand:MODEF 0 "register_operand" "=f")
4177 (float_truncate:MODEF
4178 (match_operand:XF 1 "register_operand" "f")))]
4179 "TARGET_80387 && flag_unsafe_math_optimizations"
4180 "* return output_387_reg_move (insn, operands);"
4181 [(set_attr "type" "fmov")
4182 (set_attr "mode" "<MODE>")])
4183
4184 (define_insn "*truncxf<mode>2_i387"
4185 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4186 (float_truncate:MODEF
4187 (match_operand:XF 1 "register_operand" "f")))]
4188 "TARGET_80387"
4189 "* return output_387_reg_move (insn, operands);"
4190 [(set_attr "type" "fmov")
4191 (set_attr "mode" "<MODE>")])
4192
4193 (define_split
4194 [(set (match_operand:MODEF 0 "register_operand" "")
4195 (float_truncate:MODEF
4196 (match_operand:XF 1 "register_operand" "")))
4197 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4198 "TARGET_80387 && reload_completed"
4199 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4200 (set (match_dup 0) (match_dup 2))])
4201
4202 (define_split
4203 [(set (match_operand:MODEF 0 "memory_operand" "")
4204 (float_truncate:MODEF
4205 (match_operand:XF 1 "register_operand" "")))
4206 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4207 "TARGET_80387"
4208 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4209 \f
4210 ;; Signed conversion to DImode.
4211
4212 (define_expand "fix_truncxfdi2"
4213 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4214 (fix:DI (match_operand:XF 1 "register_operand" "")))
4215 (clobber (reg:CC FLAGS_REG))])]
4216 "TARGET_80387"
4217 {
4218 if (TARGET_FISTTP)
4219 {
4220 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4221 DONE;
4222 }
4223 })
4224
4225 (define_expand "fix_trunc<mode>di2"
4226 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4227 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4228 (clobber (reg:CC FLAGS_REG))])]
4229 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4230 {
4231 if (TARGET_FISTTP
4232 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4233 {
4234 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4235 DONE;
4236 }
4237 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4238 {
4239 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4240 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4241 if (out != operands[0])
4242 emit_move_insn (operands[0], out);
4243 DONE;
4244 }
4245 })
4246
4247 ;; Signed conversion to SImode.
4248
4249 (define_expand "fix_truncxfsi2"
4250 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4251 (fix:SI (match_operand:XF 1 "register_operand" "")))
4252 (clobber (reg:CC FLAGS_REG))])]
4253 "TARGET_80387"
4254 {
4255 if (TARGET_FISTTP)
4256 {
4257 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4258 DONE;
4259 }
4260 })
4261
4262 (define_expand "fix_trunc<mode>si2"
4263 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4265 (clobber (reg:CC FLAGS_REG))])]
4266 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4267 {
4268 if (TARGET_FISTTP
4269 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4270 {
4271 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4272 DONE;
4273 }
4274 if (SSE_FLOAT_MODE_P (<MODE>mode))
4275 {
4276 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4277 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4278 if (out != operands[0])
4279 emit_move_insn (operands[0], out);
4280 DONE;
4281 }
4282 })
4283
4284 ;; Signed conversion to HImode.
4285
4286 (define_expand "fix_trunc<mode>hi2"
4287 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4288 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4289 (clobber (reg:CC FLAGS_REG))])]
4290 "TARGET_80387
4291 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4292 {
4293 if (TARGET_FISTTP)
4294 {
4295 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4296 DONE;
4297 }
4298 })
4299
4300 ;; Unsigned conversion to SImode.
4301
4302 (define_expand "fixuns_trunc<mode>si2"
4303 [(parallel
4304 [(set (match_operand:SI 0 "register_operand" "")
4305 (unsigned_fix:SI
4306 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4307 (use (match_dup 2))
4308 (clobber (match_scratch:<ssevecmode> 3 ""))
4309 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4310 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4311 {
4312 enum machine_mode mode = <MODE>mode;
4313 enum machine_mode vecmode = <ssevecmode>mode;
4314 REAL_VALUE_TYPE TWO31r;
4315 rtx two31;
4316
4317 if (optimize_insn_for_size_p ())
4318 FAIL;
4319
4320 real_ldexp (&TWO31r, &dconst1, 31);
4321 two31 = const_double_from_real_value (TWO31r, mode);
4322 two31 = ix86_build_const_vector (vecmode, true, two31);
4323 operands[2] = force_reg (vecmode, two31);
4324 })
4325
4326 (define_insn_and_split "*fixuns_trunc<mode>_1"
4327 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4328 (unsigned_fix:SI
4329 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4330 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4331 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4332 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4333 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4334 && optimize_function_for_speed_p (cfun)"
4335 "#"
4336 "&& reload_completed"
4337 [(const_int 0)]
4338 {
4339 ix86_split_convert_uns_si_sse (operands);
4340 DONE;
4341 })
4342
4343 ;; Unsigned conversion to HImode.
4344 ;; Without these patterns, we'll try the unsigned SI conversion which
4345 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4346
4347 (define_expand "fixuns_trunc<mode>hi2"
4348 [(set (match_dup 2)
4349 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4350 (set (match_operand:HI 0 "nonimmediate_operand" "")
4351 (subreg:HI (match_dup 2) 0))]
4352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4353 "operands[2] = gen_reg_rtx (SImode);")
4354
4355 ;; When SSE is available, it is always faster to use it!
4356 (define_insn "fix_trunc<mode>di_sse"
4357 [(set (match_operand:DI 0 "register_operand" "=r,r")
4358 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4359 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4360 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4361 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4362 [(set_attr "type" "sseicvt")
4363 (set_attr "prefix" "maybe_vex")
4364 (set_attr "prefix_rex" "1")
4365 (set_attr "mode" "<MODE>")
4366 (set_attr "athlon_decode" "double,vector")
4367 (set_attr "amdfam10_decode" "double,double")
4368 (set_attr "bdver1_decode" "double,double")])
4369
4370 (define_insn "fix_trunc<mode>si_sse"
4371 [(set (match_operand:SI 0 "register_operand" "=r,r")
4372 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4373 "SSE_FLOAT_MODE_P (<MODE>mode)
4374 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4375 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4376 [(set_attr "type" "sseicvt")
4377 (set_attr "prefix" "maybe_vex")
4378 (set_attr "mode" "<MODE>")
4379 (set_attr "athlon_decode" "double,vector")
4380 (set_attr "amdfam10_decode" "double,double")
4381 (set_attr "bdver1_decode" "double,double")])
4382
4383 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4384 (define_peephole2
4385 [(set (match_operand:MODEF 0 "register_operand" "")
4386 (match_operand:MODEF 1 "memory_operand" ""))
4387 (set (match_operand:SWI48x 2 "register_operand" "")
4388 (fix:SWI48x (match_dup 0)))]
4389 "TARGET_SHORTEN_X87_SSE
4390 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4391 && peep2_reg_dead_p (2, operands[0])"
4392 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4393
4394 ;; Avoid vector decoded forms of the instruction.
4395 (define_peephole2
4396 [(match_scratch:DF 2 "x")
4397 (set (match_operand:SWI48x 0 "register_operand" "")
4398 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4399 "TARGET_SSE2 && 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_peephole2
4404 [(match_scratch:SF 2 "x")
4405 (set (match_operand:SWI48x 0 "register_operand" "")
4406 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4407 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4408 [(set (match_dup 2) (match_dup 1))
4409 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4410
4411 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4412 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4413 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4414 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4415 && TARGET_FISTTP
4416 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4417 && (TARGET_64BIT || <MODE>mode != DImode))
4418 && TARGET_SSE_MATH)
4419 && can_create_pseudo_p ()"
4420 "#"
4421 "&& 1"
4422 [(const_int 0)]
4423 {
4424 if (memory_operand (operands[0], VOIDmode))
4425 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4426 else
4427 {
4428 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4429 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4430 operands[1],
4431 operands[2]));
4432 }
4433 DONE;
4434 }
4435 [(set_attr "type" "fisttp")
4436 (set_attr "mode" "<MODE>")])
4437
4438 (define_insn "fix_trunc<mode>_i387_fisttp"
4439 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4440 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4441 (clobber (match_scratch:XF 2 "=&1f"))]
4442 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && TARGET_FISTTP
4444 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4445 && (TARGET_64BIT || <MODE>mode != DImode))
4446 && TARGET_SSE_MATH)"
4447 "* return output_fix_trunc (insn, operands, true);"
4448 [(set_attr "type" "fisttp")
4449 (set_attr "mode" "<MODE>")])
4450
4451 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4452 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4453 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4454 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4455 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4456 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4457 && TARGET_FISTTP
4458 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459 && (TARGET_64BIT || <MODE>mode != DImode))
4460 && TARGET_SSE_MATH)"
4461 "#"
4462 [(set_attr "type" "fisttp")
4463 (set_attr "mode" "<MODE>")])
4464
4465 (define_split
4466 [(set (match_operand:SWI248x 0 "register_operand" "")
4467 (fix:SWI248x (match_operand 1 "register_operand" "")))
4468 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4469 (clobber (match_scratch 3 ""))]
4470 "reload_completed"
4471 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4472 (clobber (match_dup 3))])
4473 (set (match_dup 0) (match_dup 2))])
4474
4475 (define_split
4476 [(set (match_operand:SWI248x 0 "memory_operand" "")
4477 (fix:SWI248x (match_operand 1 "register_operand" "")))
4478 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4479 (clobber (match_scratch 3 ""))]
4480 "reload_completed"
4481 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4482 (clobber (match_dup 3))])])
4483
4484 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4485 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4486 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4487 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4488 ;; function in i386.c.
4489 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4490 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4491 (fix:SWI248x (match_operand 1 "register_operand" "")))
4492 (clobber (reg:CC FLAGS_REG))]
4493 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && !TARGET_FISTTP
4495 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && (TARGET_64BIT || <MODE>mode != DImode))
4497 && can_create_pseudo_p ()"
4498 "#"
4499 "&& 1"
4500 [(const_int 0)]
4501 {
4502 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4503
4504 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4505 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4506 if (memory_operand (operands[0], VOIDmode))
4507 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4508 operands[2], operands[3]));
4509 else
4510 {
4511 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4512 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4513 operands[2], operands[3],
4514 operands[4]));
4515 }
4516 DONE;
4517 }
4518 [(set_attr "type" "fistp")
4519 (set_attr "i387_cw" "trunc")
4520 (set_attr "mode" "<MODE>")])
4521
4522 (define_insn "fix_truncdi_i387"
4523 [(set (match_operand:DI 0 "memory_operand" "=m")
4524 (fix:DI (match_operand 1 "register_operand" "f")))
4525 (use (match_operand:HI 2 "memory_operand" "m"))
4526 (use (match_operand:HI 3 "memory_operand" "m"))
4527 (clobber (match_scratch:XF 4 "=&1f"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !TARGET_FISTTP
4530 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4531 "* return output_fix_trunc (insn, operands, false);"
4532 [(set_attr "type" "fistp")
4533 (set_attr "i387_cw" "trunc")
4534 (set_attr "mode" "DI")])
4535
4536 (define_insn "fix_truncdi_i387_with_temp"
4537 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4538 (fix:DI (match_operand 1 "register_operand" "f,f")))
4539 (use (match_operand:HI 2 "memory_operand" "m,m"))
4540 (use (match_operand:HI 3 "memory_operand" "m,m"))
4541 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4542 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4543 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544 && !TARGET_FISTTP
4545 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4546 "#"
4547 [(set_attr "type" "fistp")
4548 (set_attr "i387_cw" "trunc")
4549 (set_attr "mode" "DI")])
4550
4551 (define_split
4552 [(set (match_operand:DI 0 "register_operand" "")
4553 (fix:DI (match_operand 1 "register_operand" "")))
4554 (use (match_operand:HI 2 "memory_operand" ""))
4555 (use (match_operand:HI 3 "memory_operand" ""))
4556 (clobber (match_operand:DI 4 "memory_operand" ""))
4557 (clobber (match_scratch 5 ""))]
4558 "reload_completed"
4559 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4560 (use (match_dup 2))
4561 (use (match_dup 3))
4562 (clobber (match_dup 5))])
4563 (set (match_dup 0) (match_dup 4))])
4564
4565 (define_split
4566 [(set (match_operand:DI 0 "memory_operand" "")
4567 (fix:DI (match_operand 1 "register_operand" "")))
4568 (use (match_operand:HI 2 "memory_operand" ""))
4569 (use (match_operand:HI 3 "memory_operand" ""))
4570 (clobber (match_operand:DI 4 "memory_operand" ""))
4571 (clobber (match_scratch 5 ""))]
4572 "reload_completed"
4573 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4574 (use (match_dup 2))
4575 (use (match_dup 3))
4576 (clobber (match_dup 5))])])
4577
4578 (define_insn "fix_trunc<mode>_i387"
4579 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4580 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4581 (use (match_operand:HI 2 "memory_operand" "m"))
4582 (use (match_operand:HI 3 "memory_operand" "m"))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !TARGET_FISTTP
4585 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4586 "* return output_fix_trunc (insn, operands, false);"
4587 [(set_attr "type" "fistp")
4588 (set_attr "i387_cw" "trunc")
4589 (set_attr "mode" "<MODE>")])
4590
4591 (define_insn "fix_trunc<mode>_i387_with_temp"
4592 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4593 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4594 (use (match_operand:HI 2 "memory_operand" "m,m"))
4595 (use (match_operand:HI 3 "memory_operand" "m,m"))
4596 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4597 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598 && !TARGET_FISTTP
4599 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4600 "#"
4601 [(set_attr "type" "fistp")
4602 (set_attr "i387_cw" "trunc")
4603 (set_attr "mode" "<MODE>")])
4604
4605 (define_split
4606 [(set (match_operand:SWI24 0 "register_operand" "")
4607 (fix:SWI24 (match_operand 1 "register_operand" "")))
4608 (use (match_operand:HI 2 "memory_operand" ""))
4609 (use (match_operand:HI 3 "memory_operand" ""))
4610 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4611 "reload_completed"
4612 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4613 (use (match_dup 2))
4614 (use (match_dup 3))])
4615 (set (match_dup 0) (match_dup 4))])
4616
4617 (define_split
4618 [(set (match_operand:SWI24 0 "memory_operand" "")
4619 (fix:SWI24 (match_operand 1 "register_operand" "")))
4620 (use (match_operand:HI 2 "memory_operand" ""))
4621 (use (match_operand:HI 3 "memory_operand" ""))
4622 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4623 "reload_completed"
4624 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4625 (use (match_dup 2))
4626 (use (match_dup 3))])])
4627
4628 (define_insn "x86_fnstcw_1"
4629 [(set (match_operand:HI 0 "memory_operand" "=m")
4630 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4631 "TARGET_80387"
4632 "fnstcw\t%0"
4633 [(set (attr "length")
4634 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635 (set_attr "mode" "HI")
4636 (set_attr "unit" "i387")
4637 (set_attr "bdver1_decode" "vector")])
4638
4639 (define_insn "x86_fldcw_1"
4640 [(set (reg:HI FPCR_REG)
4641 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4642 "TARGET_80387"
4643 "fldcw\t%0"
4644 [(set (attr "length")
4645 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4646 (set_attr "mode" "HI")
4647 (set_attr "unit" "i387")
4648 (set_attr "athlon_decode" "vector")
4649 (set_attr "amdfam10_decode" "vector")
4650 (set_attr "bdver1_decode" "vector")])
4651 \f
4652 ;; Conversion between fixed point and floating point.
4653
4654 ;; Even though we only accept memory inputs, the backend _really_
4655 ;; wants to be able to do this between registers.
4656
4657 (define_expand "floathi<mode>2"
4658 [(set (match_operand:X87MODEF 0 "register_operand" "")
4659 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4660 "TARGET_80387
4661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4662 || TARGET_MIX_SSE_I387)")
4663
4664 ;; Pre-reload splitter to add memory clobber to the pattern.
4665 (define_insn_and_split "*floathi<mode>2_1"
4666 [(set (match_operand:X87MODEF 0 "register_operand" "")
4667 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4668 "TARGET_80387
4669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4670 || TARGET_MIX_SSE_I387)
4671 && can_create_pseudo_p ()"
4672 "#"
4673 "&& 1"
4674 [(parallel [(set (match_dup 0)
4675 (float:X87MODEF (match_dup 1)))
4676 (clobber (match_dup 2))])]
4677 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4678
4679 (define_insn "*floathi<mode>2_i387_with_temp"
4680 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4681 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4682 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4683 "TARGET_80387
4684 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4685 || TARGET_MIX_SSE_I387)"
4686 "#"
4687 [(set_attr "type" "fmov,multi")
4688 (set_attr "mode" "<MODE>")
4689 (set_attr "unit" "*,i387")
4690 (set_attr "fp_int_src" "true")])
4691
4692 (define_insn "*floathi<mode>2_i387"
4693 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4694 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4695 "TARGET_80387
4696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4697 || TARGET_MIX_SSE_I387)"
4698 "fild%Z1\t%1"
4699 [(set_attr "type" "fmov")
4700 (set_attr "mode" "<MODE>")
4701 (set_attr "fp_int_src" "true")])
4702
4703 (define_split
4704 [(set (match_operand:X87MODEF 0 "register_operand" "")
4705 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4706 (clobber (match_operand:HI 2 "memory_operand" ""))]
4707 "TARGET_80387
4708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4709 || TARGET_MIX_SSE_I387)
4710 && reload_completed"
4711 [(set (match_dup 2) (match_dup 1))
4712 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4713
4714 (define_split
4715 [(set (match_operand:X87MODEF 0 "register_operand" "")
4716 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4717 (clobber (match_operand:HI 2 "memory_operand" ""))]
4718 "TARGET_80387
4719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4720 || TARGET_MIX_SSE_I387)
4721 && reload_completed"
4722 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4723
4724 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4725 [(set (match_operand:X87MODEF 0 "register_operand" "")
4726 (float:X87MODEF
4727 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4728 "TARGET_80387
4729 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4730 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4731 {
4732 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4733 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4734 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4735 {
4736 rtx reg = gen_reg_rtx (XFmode);
4737 rtx (*insn)(rtx, rtx);
4738
4739 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4740
4741 if (<X87MODEF:MODE>mode == SFmode)
4742 insn = gen_truncxfsf2;
4743 else if (<X87MODEF:MODE>mode == DFmode)
4744 insn = gen_truncxfdf2;
4745 else
4746 gcc_unreachable ();
4747
4748 emit_insn (insn (operands[0], reg));
4749 DONE;
4750 }
4751 })
4752
4753 ;; Pre-reload splitter to add memory clobber to the pattern.
4754 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4755 [(set (match_operand:X87MODEF 0 "register_operand" "")
4756 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4757 "((TARGET_80387
4758 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4759 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4760 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387))
4762 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4763 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4764 && ((<SWI48x:MODE>mode == SImode
4765 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4766 && optimize_function_for_speed_p (cfun)
4767 && flag_trapping_math)
4768 || !(TARGET_INTER_UNIT_CONVERSIONS
4769 || optimize_function_for_size_p (cfun)))))
4770 && can_create_pseudo_p ()"
4771 "#"
4772 "&& 1"
4773 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4774 (clobber (match_dup 2))])]
4775 {
4776 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4777
4778 /* Avoid store forwarding (partial memory) stall penalty
4779 by passing DImode value through XMM registers. */
4780 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4781 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4782 && optimize_function_for_speed_p (cfun))
4783 {
4784 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4785 operands[1],
4786 operands[2]));
4787 DONE;
4788 }
4789 })
4790
4791 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4792 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4793 (float:MODEF
4794 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4795 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4796 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4797 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4798 "#"
4799 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4800 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4801 (set_attr "unit" "*,i387,*,*,*")
4802 (set_attr "athlon_decode" "*,*,double,direct,double")
4803 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4804 (set_attr "bdver1_decode" "*,*,double,direct,double")
4805 (set_attr "fp_int_src" "true")])
4806
4807 (define_insn "*floatsi<mode>2_vector_mixed"
4808 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4809 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4810 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4811 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4812 "@
4813 fild%Z1\t%1
4814 #"
4815 [(set_attr "type" "fmov,sseicvt")
4816 (set_attr "mode" "<MODE>,<ssevecmode>")
4817 (set_attr "unit" "i387,*")
4818 (set_attr "athlon_decode" "*,direct")
4819 (set_attr "amdfam10_decode" "*,double")
4820 (set_attr "bdver1_decode" "*,direct")
4821 (set_attr "fp_int_src" "true")])
4822
4823 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4824 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4825 (float:MODEF
4826 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4827 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4828 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4829 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4830 "#"
4831 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832 (set_attr "mode" "<MODEF:MODE>")
4833 (set_attr "unit" "*,i387,*,*")
4834 (set_attr "athlon_decode" "*,*,double,direct")
4835 (set_attr "amdfam10_decode" "*,*,vector,double")
4836 (set_attr "bdver1_decode" "*,*,double,direct")
4837 (set_attr "fp_int_src" "true")])
4838
4839 (define_split
4840 [(set (match_operand:MODEF 0 "register_operand" "")
4841 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4842 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4843 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4844 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4845 && TARGET_INTER_UNIT_CONVERSIONS
4846 && reload_completed
4847 && (SSE_REG_P (operands[0])
4848 || (GET_CODE (operands[0]) == SUBREG
4849 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4850 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4851
4852 (define_split
4853 [(set (match_operand:MODEF 0 "register_operand" "")
4854 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4855 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4856 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4857 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4858 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4859 && reload_completed
4860 && (SSE_REG_P (operands[0])
4861 || (GET_CODE (operands[0]) == SUBREG
4862 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4863 [(set (match_dup 2) (match_dup 1))
4864 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4865
4866 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4867 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4868 (float:MODEF
4869 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4870 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4871 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4872 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4873 "@
4874 fild%Z1\t%1
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4876 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4877 [(set_attr "type" "fmov,sseicvt,sseicvt")
4878 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4879 (set_attr "mode" "<MODEF:MODE>")
4880 (set (attr "prefix_rex")
4881 (if_then_else
4882 (and (eq_attr "prefix" "maybe_vex")
4883 (match_test "<SWI48x:MODE>mode == DImode"))
4884 (const_string "1")
4885 (const_string "*")))
4886 (set_attr "unit" "i387,*,*")
4887 (set_attr "athlon_decode" "*,double,direct")
4888 (set_attr "amdfam10_decode" "*,vector,double")
4889 (set_attr "bdver1_decode" "*,double,direct")
4890 (set_attr "fp_int_src" "true")])
4891
4892 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4893 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4894 (float:MODEF
4895 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4896 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4897 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4898 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4899 "@
4900 fild%Z1\t%1
4901 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4902 [(set_attr "type" "fmov,sseicvt")
4903 (set_attr "prefix" "orig,maybe_vex")
4904 (set_attr "mode" "<MODEF:MODE>")
4905 (set (attr "prefix_rex")
4906 (if_then_else
4907 (and (eq_attr "prefix" "maybe_vex")
4908 (match_test "<SWI48x:MODE>mode == DImode"))
4909 (const_string "1")
4910 (const_string "*")))
4911 (set_attr "athlon_decode" "*,direct")
4912 (set_attr "amdfam10_decode" "*,double")
4913 (set_attr "bdver1_decode" "*,direct")
4914 (set_attr "fp_int_src" "true")])
4915
4916 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4917 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4918 (float:MODEF
4919 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4920 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4921 "TARGET_SSE2 && TARGET_SSE_MATH
4922 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4923 "#"
4924 [(set_attr "type" "sseicvt")
4925 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4926 (set_attr "athlon_decode" "double,direct,double")
4927 (set_attr "amdfam10_decode" "vector,double,double")
4928 (set_attr "bdver1_decode" "double,direct,double")
4929 (set_attr "fp_int_src" "true")])
4930
4931 (define_insn "*floatsi<mode>2_vector_sse"
4932 [(set (match_operand:MODEF 0 "register_operand" "=x")
4933 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4934 "TARGET_SSE2 && TARGET_SSE_MATH
4935 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4936 "#"
4937 [(set_attr "type" "sseicvt")
4938 (set_attr "mode" "<MODE>")
4939 (set_attr "athlon_decode" "direct")
4940 (set_attr "amdfam10_decode" "double")
4941 (set_attr "bdver1_decode" "direct")
4942 (set_attr "fp_int_src" "true")])
4943
4944 (define_split
4945 [(set (match_operand:MODEF 0 "register_operand" "")
4946 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4947 (clobber (match_operand:SI 2 "memory_operand" ""))]
4948 "TARGET_SSE2 && TARGET_SSE_MATH
4949 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4950 && reload_completed
4951 && (SSE_REG_P (operands[0])
4952 || (GET_CODE (operands[0]) == SUBREG
4953 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4954 [(const_int 0)]
4955 {
4956 rtx op1 = operands[1];
4957
4958 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4959 <MODE>mode, 0);
4960 if (GET_CODE (op1) == SUBREG)
4961 op1 = SUBREG_REG (op1);
4962
4963 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4964 {
4965 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[1]));
4968 }
4969 /* We can ignore possible trapping value in the
4970 high part of SSE register for non-trapping math. */
4971 else if (SSE_REG_P (op1) && !flag_trapping_math)
4972 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4973 else
4974 {
4975 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4976 emit_move_insn (operands[2], operands[1]);
4977 emit_insn (gen_sse2_loadld (operands[4],
4978 CONST0_RTX (V4SImode), operands[2]));
4979 }
4980 if (<ssevecmode>mode == V4SFmode)
4981 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4982 else
4983 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4984 DONE;
4985 })
4986
4987 (define_split
4988 [(set (match_operand:MODEF 0 "register_operand" "")
4989 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4990 (clobber (match_operand:SI 2 "memory_operand" ""))]
4991 "TARGET_SSE2 && TARGET_SSE_MATH
4992 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4993 && reload_completed
4994 && (SSE_REG_P (operands[0])
4995 || (GET_CODE (operands[0]) == SUBREG
4996 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4997 [(const_int 0)]
4998 {
4999 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5000 <MODE>mode, 0);
5001 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5002
5003 emit_insn (gen_sse2_loadld (operands[4],
5004 CONST0_RTX (V4SImode), operands[1]));
5005 if (<ssevecmode>mode == V4SFmode)
5006 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5007 else
5008 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5009 DONE;
5010 })
5011
5012 (define_split
5013 [(set (match_operand:MODEF 0 "register_operand" "")
5014 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5015 "TARGET_SSE2 && TARGET_SSE_MATH
5016 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5017 && reload_completed
5018 && (SSE_REG_P (operands[0])
5019 || (GET_CODE (operands[0]) == SUBREG
5020 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5021 [(const_int 0)]
5022 {
5023 rtx op1 = operands[1];
5024
5025 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5026 <MODE>mode, 0);
5027 if (GET_CODE (op1) == SUBREG)
5028 op1 = SUBREG_REG (op1);
5029
5030 if (GENERAL_REG_P (op1))
5031 {
5032 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5033 if (TARGET_INTER_UNIT_MOVES)
5034 emit_insn (gen_sse2_loadld (operands[4],
5035 CONST0_RTX (V4SImode), operands[1]));
5036 else
5037 {
5038 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5039 operands[1]);
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[5]));
5042 ix86_free_from_memory (GET_MODE (operands[1]));
5043 }
5044 }
5045 /* We can ignore possible trapping value in the
5046 high part of SSE register for non-trapping math. */
5047 else if (SSE_REG_P (op1) && !flag_trapping_math)
5048 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049 else
5050 gcc_unreachable ();
5051 if (<ssevecmode>mode == V4SFmode)
5052 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5053 else
5054 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5055 DONE;
5056 })
5057
5058 (define_split
5059 [(set (match_operand:MODEF 0 "register_operand" "")
5060 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5061 "TARGET_SSE2 && TARGET_SSE_MATH
5062 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5063 && reload_completed
5064 && (SSE_REG_P (operands[0])
5065 || (GET_CODE (operands[0]) == SUBREG
5066 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5067 [(const_int 0)]
5068 {
5069 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5070 <MODE>mode, 0);
5071 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5072
5073 emit_insn (gen_sse2_loadld (operands[4],
5074 CONST0_RTX (V4SImode), operands[1]));
5075 if (<ssevecmode>mode == V4SFmode)
5076 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5077 else
5078 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5079 DONE;
5080 })
5081
5082 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5083 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5084 (float:MODEF
5085 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5086 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5087 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5088 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5089 "#"
5090 [(set_attr "type" "sseicvt")
5091 (set_attr "mode" "<MODEF:MODE>")
5092 (set_attr "athlon_decode" "double,direct")
5093 (set_attr "amdfam10_decode" "vector,double")
5094 (set_attr "bdver1_decode" "double,direct")
5095 (set_attr "fp_int_src" "true")])
5096
5097 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5098 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5099 (float:MODEF
5100 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5101 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5102 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5103 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5104 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "prefix" "maybe_vex")
5107 (set_attr "mode" "<MODEF:MODE>")
5108 (set (attr "prefix_rex")
5109 (if_then_else
5110 (and (eq_attr "prefix" "maybe_vex")
5111 (match_test "<SWI48x:MODE>mode == DImode"))
5112 (const_string "1")
5113 (const_string "*")))
5114 (set_attr "athlon_decode" "double,direct")
5115 (set_attr "amdfam10_decode" "vector,double")
5116 (set_attr "bdver1_decode" "double,direct")
5117 (set_attr "fp_int_src" "true")])
5118
5119 (define_split
5120 [(set (match_operand:MODEF 0 "register_operand" "")
5121 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5122 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5123 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5125 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5126 && reload_completed
5127 && (SSE_REG_P (operands[0])
5128 || (GET_CODE (operands[0]) == SUBREG
5129 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5130 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5131
5132 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5133 [(set (match_operand:MODEF 0 "register_operand" "=x")
5134 (float:MODEF
5135 (match_operand:SWI48x 1 "memory_operand" "m")))]
5136 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5137 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5138 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5139 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5140 [(set_attr "type" "sseicvt")
5141 (set_attr "prefix" "maybe_vex")
5142 (set_attr "mode" "<MODEF:MODE>")
5143 (set (attr "prefix_rex")
5144 (if_then_else
5145 (and (eq_attr "prefix" "maybe_vex")
5146 (match_test "<SWI48x:MODE>mode == DImode"))
5147 (const_string "1")
5148 (const_string "*")))
5149 (set_attr "athlon_decode" "direct")
5150 (set_attr "amdfam10_decode" "double")
5151 (set_attr "bdver1_decode" "direct")
5152 (set_attr "fp_int_src" "true")])
5153
5154 (define_split
5155 [(set (match_operand:MODEF 0 "register_operand" "")
5156 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5157 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5158 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5159 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5160 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5161 && reload_completed
5162 && (SSE_REG_P (operands[0])
5163 || (GET_CODE (operands[0]) == SUBREG
5164 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5165 [(set (match_dup 2) (match_dup 1))
5166 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5167
5168 (define_split
5169 [(set (match_operand:MODEF 0 "register_operand" "")
5170 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5171 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5172 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5173 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5174 && reload_completed
5175 && (SSE_REG_P (operands[0])
5176 || (GET_CODE (operands[0]) == SUBREG
5177 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5178 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5179
5180 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5181 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5182 (float:X87MODEF
5183 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5184 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5185 "TARGET_80387
5186 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5187 "@
5188 fild%Z1\t%1
5189 #"
5190 [(set_attr "type" "fmov,multi")
5191 (set_attr "mode" "<X87MODEF:MODE>")
5192 (set_attr "unit" "*,i387")
5193 (set_attr "fp_int_src" "true")])
5194
5195 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5196 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5197 (float:X87MODEF
5198 (match_operand:SWI48x 1 "memory_operand" "m")))]
5199 "TARGET_80387
5200 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5201 "fild%Z1\t%1"
5202 [(set_attr "type" "fmov")
5203 (set_attr "mode" "<X87MODEF:MODE>")
5204 (set_attr "fp_int_src" "true")])
5205
5206 (define_split
5207 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5208 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5209 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5210 "TARGET_80387
5211 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5212 && reload_completed"
5213 [(set (match_dup 2) (match_dup 1))
5214 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5215
5216 (define_split
5217 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5218 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5220 "TARGET_80387
5221 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5222 && reload_completed"
5223 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5224
5225 ;; Avoid store forwarding (partial memory) stall penalty
5226 ;; by passing DImode value through XMM registers. */
5227
5228 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5229 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5230 (float:X87MODEF
5231 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5232 (clobber (match_scratch:V4SI 3 "=X,x"))
5233 (clobber (match_scratch:V4SI 4 "=X,x"))
5234 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5235 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5236 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5237 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5238 "#"
5239 [(set_attr "type" "multi")
5240 (set_attr "mode" "<X87MODEF:MODE>")
5241 (set_attr "unit" "i387")
5242 (set_attr "fp_int_src" "true")])
5243
5244 (define_split
5245 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5246 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5247 (clobber (match_scratch:V4SI 3 ""))
5248 (clobber (match_scratch:V4SI 4 ""))
5249 (clobber (match_operand:DI 2 "memory_operand" ""))]
5250 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5251 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5252 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5253 && reload_completed"
5254 [(set (match_dup 2) (match_dup 3))
5255 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5256 {
5257 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5258 Assemble the 64-bit DImode value in an xmm register. */
5259 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5260 gen_rtx_SUBREG (SImode, operands[1], 0)));
5261 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5262 gen_rtx_SUBREG (SImode, operands[1], 4)));
5263 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5264 operands[4]));
5265
5266 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5267 })
5268
5269 (define_split
5270 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5272 (clobber (match_scratch:V4SI 3 ""))
5273 (clobber (match_scratch:V4SI 4 ""))
5274 (clobber (match_operand:DI 2 "memory_operand" ""))]
5275 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5276 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5277 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5278 && reload_completed"
5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5280
5281 ;; Avoid store forwarding (partial memory) stall penalty by extending
5282 ;; SImode value to DImode through XMM register instead of pushing two
5283 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5284 ;; targets benefit from this optimization. Also note that fild
5285 ;; loads from memory only.
5286
5287 (define_insn "*floatunssi<mode>2_1"
5288 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289 (unsigned_float:X87MODEF
5290 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5291 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5292 (clobber (match_scratch:SI 3 "=X,x"))]
5293 "!TARGET_64BIT
5294 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5295 && TARGET_SSE"
5296 "#"
5297 [(set_attr "type" "multi")
5298 (set_attr "mode" "<MODE>")])
5299
5300 (define_split
5301 [(set (match_operand:X87MODEF 0 "register_operand" "")
5302 (unsigned_float:X87MODEF
5303 (match_operand:SI 1 "register_operand" "")))
5304 (clobber (match_operand:DI 2 "memory_operand" ""))
5305 (clobber (match_scratch:SI 3 ""))]
5306 "!TARGET_64BIT
5307 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5308 && TARGET_SSE
5309 && reload_completed"
5310 [(set (match_dup 2) (match_dup 1))
5311 (set (match_dup 0)
5312 (float:X87MODEF (match_dup 2)))]
5313 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5314
5315 (define_split
5316 [(set (match_operand:X87MODEF 0 "register_operand" "")
5317 (unsigned_float:X87MODEF
5318 (match_operand:SI 1 "memory_operand" "")))
5319 (clobber (match_operand:DI 2 "memory_operand" ""))
5320 (clobber (match_scratch:SI 3 ""))]
5321 "!TARGET_64BIT
5322 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5323 && TARGET_SSE
5324 && reload_completed"
5325 [(set (match_dup 2) (match_dup 3))
5326 (set (match_dup 0)
5327 (float:X87MODEF (match_dup 2)))]
5328 {
5329 emit_move_insn (operands[3], operands[1]);
5330 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5331 })
5332
5333 (define_expand "floatunssi<mode>2"
5334 [(parallel
5335 [(set (match_operand:X87MODEF 0 "register_operand" "")
5336 (unsigned_float:X87MODEF
5337 (match_operand:SI 1 "nonimmediate_operand" "")))
5338 (clobber (match_dup 2))
5339 (clobber (match_scratch:SI 3 ""))])]
5340 "!TARGET_64BIT
5341 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5342 && TARGET_SSE)
5343 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5344 {
5345 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5346 {
5347 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5348 DONE;
5349 }
5350 else
5351 {
5352 enum ix86_stack_slot slot = (virtuals_instantiated
5353 ? SLOT_TEMP
5354 : SLOT_VIRTUAL);
5355 operands[2] = assign_386_stack_local (DImode, slot);
5356 }
5357 })
5358
5359 (define_expand "floatunsdisf2"
5360 [(use (match_operand:SF 0 "register_operand" ""))
5361 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5362 "TARGET_64BIT && TARGET_SSE_MATH"
5363 "x86_emit_floatuns (operands); DONE;")
5364
5365 (define_expand "floatunsdidf2"
5366 [(use (match_operand:DF 0 "register_operand" ""))
5367 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5368 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5369 && TARGET_SSE2 && TARGET_SSE_MATH"
5370 {
5371 if (TARGET_64BIT)
5372 x86_emit_floatuns (operands);
5373 else
5374 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5375 DONE;
5376 })
5377 \f
5378 ;; Add instructions
5379
5380 (define_expand "add<mode>3"
5381 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5382 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5383 (match_operand:SDWIM 2 "<general_operand>" "")))]
5384 ""
5385 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5386
5387 (define_insn_and_split "*add<dwi>3_doubleword"
5388 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5389 (plus:<DWI>
5390 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5391 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5394 "#"
5395 "reload_completed"
5396 [(parallel [(set (reg:CC FLAGS_REG)
5397 (unspec:CC [(match_dup 1) (match_dup 2)]
5398 UNSPEC_ADD_CARRY))
5399 (set (match_dup 0)
5400 (plus:DWIH (match_dup 1) (match_dup 2)))])
5401 (parallel [(set (match_dup 3)
5402 (plus:DWIH
5403 (match_dup 4)
5404 (plus:DWIH
5405 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5406 (match_dup 5))))
5407 (clobber (reg:CC FLAGS_REG))])]
5408 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5409
5410 (define_insn "*add<mode>3_cc"
5411 [(set (reg:CC FLAGS_REG)
5412 (unspec:CC
5413 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5414 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5415 UNSPEC_ADD_CARRY))
5416 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5417 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5418 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5419 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5420 [(set_attr "type" "alu")
5421 (set_attr "mode" "<MODE>")])
5422
5423 (define_insn "addqi3_cc"
5424 [(set (reg:CC FLAGS_REG)
5425 (unspec:CC
5426 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5427 (match_operand:QI 2 "general_operand" "qn,qm")]
5428 UNSPEC_ADD_CARRY))
5429 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5430 (plus:QI (match_dup 1) (match_dup 2)))]
5431 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5432 "add{b}\t{%2, %0|%0, %2}"
5433 [(set_attr "type" "alu")
5434 (set_attr "mode" "QI")])
5435
5436 (define_insn_and_split "*lea_1"
5437 [(set (match_operand:SI 0 "register_operand" "=r")
5438 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5439 "TARGET_64BIT"
5440 "lea{l}\t{%a1, %0|%0, %a1}"
5441 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5442 [(const_int 0)]
5443 {
5444 ix86_split_lea_for_addr (operands, SImode);
5445 DONE;
5446 }
5447 [(set_attr "type" "lea")
5448 (set_attr "mode" "SI")])
5449
5450 (define_insn_and_split "*lea<mode>_2"
5451 [(set (match_operand:SWI48 0 "register_operand" "=r")
5452 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5453 ""
5454 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5455 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5456 [(const_int 0)]
5457 {
5458 ix86_split_lea_for_addr (operands, <MODE>mode);
5459 DONE;
5460 }
5461 [(set_attr "type" "lea")
5462 (set_attr "mode" "<MODE>")])
5463
5464 (define_insn "*lea_3_zext"
5465 [(set (match_operand:DI 0 "register_operand" "=r")
5466 (zero_extend:DI
5467 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5468 "TARGET_64BIT"
5469 "lea{l}\t{%a1, %k0|%k0, %a1}"
5470 [(set_attr "type" "lea")
5471 (set_attr "mode" "SI")])
5472
5473 (define_insn "*lea_4_zext"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5475 (zero_extend:DI
5476 (match_operand:SI 1 "lea_address_operand" "j")))]
5477 "TARGET_64BIT"
5478 "lea{l}\t{%a1, %k0|%k0, %a1}"
5479 [(set_attr "type" "lea")
5480 (set_attr "mode" "SI")])
5481
5482 (define_insn "*lea_5_zext"
5483 [(set (match_operand:DI 0 "register_operand" "=r")
5484 (and:DI
5485 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5486 (match_operand:DI 2 "const_32bit_mask" "n")))]
5487 "TARGET_64BIT"
5488 "lea{l}\t{%a1, %k0|%k0, %a1}"
5489 [(set_attr "type" "lea")
5490 (set_attr "mode" "SI")])
5491
5492 (define_insn "*lea_6_zext"
5493 [(set (match_operand:DI 0 "register_operand" "=r")
5494 (and:DI
5495 (match_operand:DI 1 "lea_address_operand" "p")
5496 (match_operand:DI 2 "const_32bit_mask" "n")))]
5497 "TARGET_64BIT"
5498 "lea{l}\t{%a1, %k0|%k0, %a1}"
5499 [(set_attr "type" "lea")
5500 (set_attr "mode" "SI")])
5501
5502 (define_insn "*add<mode>_1"
5503 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5504 (plus:SWI48
5505 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5506 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5507 (clobber (reg:CC FLAGS_REG))]
5508 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5509 {
5510 switch (get_attr_type (insn))
5511 {
5512 case TYPE_LEA:
5513 return "#";
5514
5515 case TYPE_INCDEC:
5516 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5517 if (operands[2] == const1_rtx)
5518 return "inc{<imodesuffix>}\t%0";
5519 else
5520 {
5521 gcc_assert (operands[2] == constm1_rtx);
5522 return "dec{<imodesuffix>}\t%0";
5523 }
5524
5525 default:
5526 /* For most processors, ADD is faster than LEA. This alternative
5527 was added to use ADD as much as possible. */
5528 if (which_alternative == 2)
5529 {
5530 rtx tmp;
5531 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5532 }
5533
5534 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5535 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5536 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5537
5538 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5539 }
5540 }
5541 [(set (attr "type")
5542 (cond [(eq_attr "alternative" "3")
5543 (const_string "lea")
5544 (match_operand:SWI48 2 "incdec_operand" "")
5545 (const_string "incdec")
5546 ]
5547 (const_string "alu")))
5548 (set (attr "length_immediate")
5549 (if_then_else
5550 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5551 (const_string "1")
5552 (const_string "*")))
5553 (set_attr "mode" "<MODE>")])
5554
5555 ;; It may seem that nonimmediate operand is proper one for operand 1.
5556 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5557 ;; we take care in ix86_binary_operator_ok to not allow two memory
5558 ;; operands so proper swapping will be done in reload. This allow
5559 ;; patterns constructed from addsi_1 to match.
5560
5561 (define_insn "addsi_1_zext"
5562 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5563 (zero_extend:DI
5564 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5565 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5568 {
5569 switch (get_attr_type (insn))
5570 {
5571 case TYPE_LEA:
5572 return "#";
5573
5574 case TYPE_INCDEC:
5575 if (operands[2] == const1_rtx)
5576 return "inc{l}\t%k0";
5577 else
5578 {
5579 gcc_assert (operands[2] == constm1_rtx);
5580 return "dec{l}\t%k0";
5581 }
5582
5583 default:
5584 /* For most processors, ADD is faster than LEA. This alternative
5585 was added to use ADD as much as possible. */
5586 if (which_alternative == 1)
5587 {
5588 rtx tmp;
5589 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5590 }
5591
5592 if (x86_maybe_negate_const_int (&operands[2], SImode))
5593 return "sub{l}\t{%2, %k0|%k0, %2}";
5594
5595 return "add{l}\t{%2, %k0|%k0, %2}";
5596 }
5597 }
5598 [(set (attr "type")
5599 (cond [(eq_attr "alternative" "2")
5600 (const_string "lea")
5601 (match_operand:SI 2 "incdec_operand" "")
5602 (const_string "incdec")
5603 ]
5604 (const_string "alu")))
5605 (set (attr "length_immediate")
5606 (if_then_else
5607 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5608 (const_string "1")
5609 (const_string "*")))
5610 (set_attr "mode" "SI")])
5611
5612 (define_insn "*addhi_1"
5613 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5614 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5615 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5616 (clobber (reg:CC FLAGS_REG))]
5617 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5618 {
5619 switch (get_attr_type (insn))
5620 {
5621 case TYPE_LEA:
5622 return "#";
5623
5624 case TYPE_INCDEC:
5625 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5626 if (operands[2] == const1_rtx)
5627 return "inc{w}\t%0";
5628 else
5629 {
5630 gcc_assert (operands[2] == constm1_rtx);
5631 return "dec{w}\t%0";
5632 }
5633
5634 default:
5635 /* For most processors, ADD is faster than LEA. This alternative
5636 was added to use ADD as much as possible. */
5637 if (which_alternative == 2)
5638 {
5639 rtx tmp;
5640 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5641 }
5642
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 if (x86_maybe_negate_const_int (&operands[2], HImode))
5645 return "sub{w}\t{%2, %0|%0, %2}";
5646
5647 return "add{w}\t{%2, %0|%0, %2}";
5648 }
5649 }
5650 [(set (attr "type")
5651 (cond [(eq_attr "alternative" "3")
5652 (const_string "lea")
5653 (match_operand:HI 2 "incdec_operand" "")
5654 (const_string "incdec")
5655 ]
5656 (const_string "alu")))
5657 (set (attr "length_immediate")
5658 (if_then_else
5659 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5660 (const_string "1")
5661 (const_string "*")))
5662 (set_attr "mode" "HI,HI,HI,SI")])
5663
5664 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5665 (define_insn "*addqi_1"
5666 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5667 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5668 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5669 (clobber (reg:CC FLAGS_REG))]
5670 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5671 {
5672 bool widen = (which_alternative == 3 || which_alternative == 4);
5673
5674 switch (get_attr_type (insn))
5675 {
5676 case TYPE_LEA:
5677 return "#";
5678
5679 case TYPE_INCDEC:
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 if (operands[2] == const1_rtx)
5682 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5683 else
5684 {
5685 gcc_assert (operands[2] == constm1_rtx);
5686 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5687 }
5688
5689 default:
5690 /* For most processors, ADD is faster than LEA. These alternatives
5691 were added to use ADD as much as possible. */
5692 if (which_alternative == 2 || which_alternative == 4)
5693 {
5694 rtx tmp;
5695 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5696 }
5697
5698 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699 if (x86_maybe_negate_const_int (&operands[2], QImode))
5700 {
5701 if (widen)
5702 return "sub{l}\t{%2, %k0|%k0, %2}";
5703 else
5704 return "sub{b}\t{%2, %0|%0, %2}";
5705 }
5706 if (widen)
5707 return "add{l}\t{%k2, %k0|%k0, %k2}";
5708 else
5709 return "add{b}\t{%2, %0|%0, %2}";
5710 }
5711 }
5712 [(set (attr "type")
5713 (cond [(eq_attr "alternative" "5")
5714 (const_string "lea")
5715 (match_operand:QI 2 "incdec_operand" "")
5716 (const_string "incdec")
5717 ]
5718 (const_string "alu")))
5719 (set (attr "length_immediate")
5720 (if_then_else
5721 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5722 (const_string "1")
5723 (const_string "*")))
5724 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5725
5726 (define_insn "*addqi_1_slp"
5727 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5728 (plus:QI (match_dup 0)
5729 (match_operand:QI 1 "general_operand" "qn,qm")))
5730 (clobber (reg:CC FLAGS_REG))]
5731 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5732 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5733 {
5734 switch (get_attr_type (insn))
5735 {
5736 case TYPE_INCDEC:
5737 if (operands[1] == const1_rtx)
5738 return "inc{b}\t%0";
5739 else
5740 {
5741 gcc_assert (operands[1] == constm1_rtx);
5742 return "dec{b}\t%0";
5743 }
5744
5745 default:
5746 if (x86_maybe_negate_const_int (&operands[1], QImode))
5747 return "sub{b}\t{%1, %0|%0, %1}";
5748
5749 return "add{b}\t{%1, %0|%0, %1}";
5750 }
5751 }
5752 [(set (attr "type")
5753 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5754 (const_string "incdec")
5755 (const_string "alu1")))
5756 (set (attr "memory")
5757 (if_then_else (match_operand 1 "memory_operand" "")
5758 (const_string "load")
5759 (const_string "none")))
5760 (set_attr "mode" "QI")])
5761
5762 ;; Split non destructive adds if we cannot use lea.
5763 (define_split
5764 [(set (match_operand:SWI48 0 "register_operand" "")
5765 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5766 (match_operand:SWI48 2 "nonmemory_operand" "")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5769 [(set (match_dup 0) (match_dup 1))
5770 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5771 (clobber (reg:CC FLAGS_REG))])])
5772
5773 ;; Convert add to the lea pattern to avoid flags dependency.
5774 (define_split
5775 [(set (match_operand:SWI 0 "register_operand" "")
5776 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5777 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5780 [(const_int 0)]
5781 {
5782 enum machine_mode mode = <MODE>mode;
5783 rtx pat;
5784
5785 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5786 {
5787 mode = SImode;
5788 operands[0] = gen_lowpart (mode, operands[0]);
5789 operands[1] = gen_lowpart (mode, operands[1]);
5790 operands[2] = gen_lowpart (mode, operands[2]);
5791 }
5792
5793 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5794
5795 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5796 DONE;
5797 })
5798
5799 ;; Convert add to the lea pattern to avoid flags dependency.
5800 (define_split
5801 [(set (match_operand:DI 0 "register_operand" "")
5802 (zero_extend:DI
5803 (plus:SI (match_operand:SI 1 "register_operand" "")
5804 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5807 [(set (match_dup 0)
5808 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5809
5810 (define_insn "*add<mode>_2"
5811 [(set (reg FLAGS_REG)
5812 (compare
5813 (plus:SWI
5814 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5815 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5816 (const_int 0)))
5817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5818 (plus:SWI (match_dup 1) (match_dup 2)))]
5819 "ix86_match_ccmode (insn, CCGOCmode)
5820 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5821 {
5822 switch (get_attr_type (insn))
5823 {
5824 case TYPE_INCDEC:
5825 if (operands[2] == const1_rtx)
5826 return "inc{<imodesuffix>}\t%0";
5827 else
5828 {
5829 gcc_assert (operands[2] == constm1_rtx);
5830 return "dec{<imodesuffix>}\t%0";
5831 }
5832
5833 default:
5834 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5835 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5836
5837 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5838 }
5839 }
5840 [(set (attr "type")
5841 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5842 (const_string "incdec")
5843 (const_string "alu")))
5844 (set (attr "length_immediate")
5845 (if_then_else
5846 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5847 (const_string "1")
5848 (const_string "*")))
5849 (set_attr "mode" "<MODE>")])
5850
5851 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5852 (define_insn "*addsi_2_zext"
5853 [(set (reg FLAGS_REG)
5854 (compare
5855 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5856 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5857 (const_int 0)))
5858 (set (match_operand:DI 0 "register_operand" "=r")
5859 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5860 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5861 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5862 {
5863 switch (get_attr_type (insn))
5864 {
5865 case TYPE_INCDEC:
5866 if (operands[2] == const1_rtx)
5867 return "inc{l}\t%k0";
5868 else
5869 {
5870 gcc_assert (operands[2] == constm1_rtx);
5871 return "dec{l}\t%k0";
5872 }
5873
5874 default:
5875 if (x86_maybe_negate_const_int (&operands[2], SImode))
5876 return "sub{l}\t{%2, %k0|%k0, %2}";
5877
5878 return "add{l}\t{%2, %k0|%k0, %2}";
5879 }
5880 }
5881 [(set (attr "type")
5882 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5883 (const_string "incdec")
5884 (const_string "alu")))
5885 (set (attr "length_immediate")
5886 (if_then_else
5887 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5888 (const_string "1")
5889 (const_string "*")))
5890 (set_attr "mode" "SI")])
5891
5892 (define_insn "*add<mode>_3"
5893 [(set (reg FLAGS_REG)
5894 (compare
5895 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5896 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5897 (clobber (match_scratch:SWI 0 "=<r>"))]
5898 "ix86_match_ccmode (insn, CCZmode)
5899 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5900 {
5901 switch (get_attr_type (insn))
5902 {
5903 case TYPE_INCDEC:
5904 if (operands[2] == const1_rtx)
5905 return "inc{<imodesuffix>}\t%0";
5906 else
5907 {
5908 gcc_assert (operands[2] == constm1_rtx);
5909 return "dec{<imodesuffix>}\t%0";
5910 }
5911
5912 default:
5913 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5914 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5915
5916 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5917 }
5918 }
5919 [(set (attr "type")
5920 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5921 (const_string "incdec")
5922 (const_string "alu")))
5923 (set (attr "length_immediate")
5924 (if_then_else
5925 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5926 (const_string "1")
5927 (const_string "*")))
5928 (set_attr "mode" "<MODE>")])
5929
5930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5931 (define_insn "*addsi_3_zext"
5932 [(set (reg FLAGS_REG)
5933 (compare
5934 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5935 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5936 (set (match_operand:DI 0 "register_operand" "=r")
5937 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5939 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5940 {
5941 switch (get_attr_type (insn))
5942 {
5943 case TYPE_INCDEC:
5944 if (operands[2] == const1_rtx)
5945 return "inc{l}\t%k0";
5946 else
5947 {
5948 gcc_assert (operands[2] == constm1_rtx);
5949 return "dec{l}\t%k0";
5950 }
5951
5952 default:
5953 if (x86_maybe_negate_const_int (&operands[2], SImode))
5954 return "sub{l}\t{%2, %k0|%k0, %2}";
5955
5956 return "add{l}\t{%2, %k0|%k0, %2}";
5957 }
5958 }
5959 [(set (attr "type")
5960 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961 (const_string "incdec")
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5964 (if_then_else
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5966 (const_string "1")
5967 (const_string "*")))
5968 (set_attr "mode" "SI")])
5969
5970 ; For comparisons against 1, -1 and 128, we may generate better code
5971 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5972 ; is matched then. We can't accept general immediate, because for
5973 ; case of overflows, the result is messed up.
5974 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5975 ; only for comparisons not depending on it.
5976
5977 (define_insn "*adddi_4"
5978 [(set (reg FLAGS_REG)
5979 (compare
5980 (match_operand:DI 1 "nonimmediate_operand" "0")
5981 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5982 (clobber (match_scratch:DI 0 "=rm"))]
5983 "TARGET_64BIT
5984 && ix86_match_ccmode (insn, CCGCmode)"
5985 {
5986 switch (get_attr_type (insn))
5987 {
5988 case TYPE_INCDEC:
5989 if (operands[2] == constm1_rtx)
5990 return "inc{q}\t%0";
5991 else
5992 {
5993 gcc_assert (operands[2] == const1_rtx);
5994 return "dec{q}\t%0";
5995 }
5996
5997 default:
5998 if (x86_maybe_negate_const_int (&operands[2], DImode))
5999 return "add{q}\t{%2, %0|%0, %2}";
6000
6001 return "sub{q}\t{%2, %0|%0, %2}";
6002 }
6003 }
6004 [(set (attr "type")
6005 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6006 (const_string "incdec")
6007 (const_string "alu")))
6008 (set (attr "length_immediate")
6009 (if_then_else
6010 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6011 (const_string "1")
6012 (const_string "*")))
6013 (set_attr "mode" "DI")])
6014
6015 ; For comparisons against 1, -1 and 128, we may generate better code
6016 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6017 ; is matched then. We can't accept general immediate, because for
6018 ; case of overflows, the result is messed up.
6019 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6020 ; only for comparisons not depending on it.
6021
6022 (define_insn "*add<mode>_4"
6023 [(set (reg FLAGS_REG)
6024 (compare
6025 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6026 (match_operand:SWI124 2 "const_int_operand" "n")))
6027 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6028 "ix86_match_ccmode (insn, CCGCmode)"
6029 {
6030 switch (get_attr_type (insn))
6031 {
6032 case TYPE_INCDEC:
6033 if (operands[2] == constm1_rtx)
6034 return "inc{<imodesuffix>}\t%0";
6035 else
6036 {
6037 gcc_assert (operands[2] == const1_rtx);
6038 return "dec{<imodesuffix>}\t%0";
6039 }
6040
6041 default:
6042 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6043 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6044
6045 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6046 }
6047 }
6048 [(set (attr "type")
6049 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6050 (const_string "incdec")
6051 (const_string "alu")))
6052 (set (attr "length_immediate")
6053 (if_then_else
6054 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6055 (const_string "1")
6056 (const_string "*")))
6057 (set_attr "mode" "<MODE>")])
6058
6059 (define_insn "*add<mode>_5"
6060 [(set (reg FLAGS_REG)
6061 (compare
6062 (plus:SWI
6063 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6064 (match_operand:SWI 2 "<general_operand>" "<g>"))
6065 (const_int 0)))
6066 (clobber (match_scratch:SWI 0 "=<r>"))]
6067 "ix86_match_ccmode (insn, CCGOCmode)
6068 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6069 {
6070 switch (get_attr_type (insn))
6071 {
6072 case TYPE_INCDEC:
6073 if (operands[2] == const1_rtx)
6074 return "inc{<imodesuffix>}\t%0";
6075 else
6076 {
6077 gcc_assert (operands[2] == constm1_rtx);
6078 return "dec{<imodesuffix>}\t%0";
6079 }
6080
6081 default:
6082 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6083 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6084
6085 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6086 }
6087 }
6088 [(set (attr "type")
6089 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6090 (const_string "incdec")
6091 (const_string "alu")))
6092 (set (attr "length_immediate")
6093 (if_then_else
6094 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6095 (const_string "1")
6096 (const_string "*")))
6097 (set_attr "mode" "<MODE>")])
6098
6099 (define_insn "*addqi_ext_1_rex64"
6100 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6101 (const_int 8)
6102 (const_int 8))
6103 (plus:SI
6104 (zero_extract:SI
6105 (match_operand 1 "ext_register_operand" "0")
6106 (const_int 8)
6107 (const_int 8))
6108 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6109 (clobber (reg:CC FLAGS_REG))]
6110 "TARGET_64BIT"
6111 {
6112 switch (get_attr_type (insn))
6113 {
6114 case TYPE_INCDEC:
6115 if (operands[2] == const1_rtx)
6116 return "inc{b}\t%h0";
6117 else
6118 {
6119 gcc_assert (operands[2] == constm1_rtx);
6120 return "dec{b}\t%h0";
6121 }
6122
6123 default:
6124 return "add{b}\t{%2, %h0|%h0, %2}";
6125 }
6126 }
6127 [(set (attr "type")
6128 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6129 (const_string "incdec")
6130 (const_string "alu")))
6131 (set_attr "modrm" "1")
6132 (set_attr "mode" "QI")])
6133
6134 (define_insn "addqi_ext_1"
6135 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6136 (const_int 8)
6137 (const_int 8))
6138 (plus:SI
6139 (zero_extract:SI
6140 (match_operand 1 "ext_register_operand" "0")
6141 (const_int 8)
6142 (const_int 8))
6143 (match_operand:QI 2 "general_operand" "Qmn")))
6144 (clobber (reg:CC FLAGS_REG))]
6145 "!TARGET_64BIT"
6146 {
6147 switch (get_attr_type (insn))
6148 {
6149 case TYPE_INCDEC:
6150 if (operands[2] == const1_rtx)
6151 return "inc{b}\t%h0";
6152 else
6153 {
6154 gcc_assert (operands[2] == constm1_rtx);
6155 return "dec{b}\t%h0";
6156 }
6157
6158 default:
6159 return "add{b}\t{%2, %h0|%h0, %2}";
6160 }
6161 }
6162 [(set (attr "type")
6163 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6164 (const_string "incdec")
6165 (const_string "alu")))
6166 (set_attr "modrm" "1")
6167 (set_attr "mode" "QI")])
6168
6169 (define_insn "*addqi_ext_2"
6170 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6171 (const_int 8)
6172 (const_int 8))
6173 (plus:SI
6174 (zero_extract:SI
6175 (match_operand 1 "ext_register_operand" "%0")
6176 (const_int 8)
6177 (const_int 8))
6178 (zero_extract:SI
6179 (match_operand 2 "ext_register_operand" "Q")
6180 (const_int 8)
6181 (const_int 8))))
6182 (clobber (reg:CC FLAGS_REG))]
6183 ""
6184 "add{b}\t{%h2, %h0|%h0, %h2}"
6185 [(set_attr "type" "alu")
6186 (set_attr "mode" "QI")])
6187
6188 ;; The lea patterns for modes less than 32 bits need to be matched by
6189 ;; several insns converted to real lea by splitters.
6190
6191 (define_insn_and_split "*lea_general_1"
6192 [(set (match_operand 0 "register_operand" "=r")
6193 (plus (plus (match_operand 1 "index_register_operand" "l")
6194 (match_operand 2 "register_operand" "r"))
6195 (match_operand 3 "immediate_operand" "i")))]
6196 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6197 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6198 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6199 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6200 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6201 || GET_MODE (operands[3]) == VOIDmode)"
6202 "#"
6203 "&& reload_completed"
6204 [(const_int 0)]
6205 {
6206 enum machine_mode mode = SImode;
6207 rtx pat;
6208
6209 operands[0] = gen_lowpart (mode, operands[0]);
6210 operands[1] = gen_lowpart (mode, operands[1]);
6211 operands[2] = gen_lowpart (mode, operands[2]);
6212 operands[3] = gen_lowpart (mode, operands[3]);
6213
6214 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6215 operands[3]);
6216
6217 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6218 DONE;
6219 }
6220 [(set_attr "type" "lea")
6221 (set_attr "mode" "SI")])
6222
6223 (define_insn_and_split "*lea_general_2"
6224 [(set (match_operand 0 "register_operand" "=r")
6225 (plus (mult (match_operand 1 "index_register_operand" "l")
6226 (match_operand 2 "const248_operand" "n"))
6227 (match_operand 3 "nonmemory_operand" "ri")))]
6228 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6229 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6230 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6231 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6232 || GET_MODE (operands[3]) == VOIDmode)"
6233 "#"
6234 "&& reload_completed"
6235 [(const_int 0)]
6236 {
6237 enum machine_mode mode = SImode;
6238 rtx pat;
6239
6240 operands[0] = gen_lowpart (mode, operands[0]);
6241 operands[1] = gen_lowpart (mode, operands[1]);
6242 operands[3] = gen_lowpart (mode, operands[3]);
6243
6244 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6245 operands[3]);
6246
6247 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6248 DONE;
6249 }
6250 [(set_attr "type" "lea")
6251 (set_attr "mode" "SI")])
6252
6253 (define_insn_and_split "*lea_general_3"
6254 [(set (match_operand 0 "register_operand" "=r")
6255 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6256 (match_operand 2 "const248_operand" "n"))
6257 (match_operand 3 "register_operand" "r"))
6258 (match_operand 4 "immediate_operand" "i")))]
6259 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6260 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6261 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6262 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6263 "#"
6264 "&& reload_completed"
6265 [(const_int 0)]
6266 {
6267 enum machine_mode mode = SImode;
6268 rtx pat;
6269
6270 operands[0] = gen_lowpart (mode, operands[0]);
6271 operands[1] = gen_lowpart (mode, operands[1]);
6272 operands[3] = gen_lowpart (mode, operands[3]);
6273 operands[4] = gen_lowpart (mode, operands[4]);
6274
6275 pat = gen_rtx_PLUS (mode,
6276 gen_rtx_PLUS (mode,
6277 gen_rtx_MULT (mode, operands[1],
6278 operands[2]),
6279 operands[3]),
6280 operands[4]);
6281
6282 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6283 DONE;
6284 }
6285 [(set_attr "type" "lea")
6286 (set_attr "mode" "SI")])
6287
6288 (define_insn_and_split "*lea_general_4"
6289 [(set (match_operand 0 "register_operand" "=r")
6290 (any_or (ashift
6291 (match_operand 1 "index_register_operand" "l")
6292 (match_operand 2 "const_int_operand" "n"))
6293 (match_operand 3 "const_int_operand" "n")))]
6294 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6295 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6296 || GET_MODE (operands[0]) == SImode
6297 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6298 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6299 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6300 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6301 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6302 "#"
6303 "&& reload_completed"
6304 [(const_int 0)]
6305 {
6306 enum machine_mode mode = GET_MODE (operands[0]);
6307 rtx pat;
6308
6309 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6310 {
6311 mode = SImode;
6312 operands[0] = gen_lowpart (mode, operands[0]);
6313 operands[1] = gen_lowpart (mode, operands[1]);
6314 }
6315
6316 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6317
6318 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6319 INTVAL (operands[3]));
6320
6321 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6322 DONE;
6323 }
6324 [(set_attr "type" "lea")
6325 (set (attr "mode")
6326 (if_then_else (match_operand:DI 0 "" "")
6327 (const_string "DI")
6328 (const_string "SI")))])
6329 \f
6330 ;; Subtract instructions
6331
6332 (define_expand "sub<mode>3"
6333 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6334 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6335 (match_operand:SDWIM 2 "<general_operand>" "")))]
6336 ""
6337 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6338
6339 (define_insn_and_split "*sub<dwi>3_doubleword"
6340 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6341 (minus:<DWI>
6342 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6343 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6344 (clobber (reg:CC FLAGS_REG))]
6345 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6346 "#"
6347 "reload_completed"
6348 [(parallel [(set (reg:CC FLAGS_REG)
6349 (compare:CC (match_dup 1) (match_dup 2)))
6350 (set (match_dup 0)
6351 (minus:DWIH (match_dup 1) (match_dup 2)))])
6352 (parallel [(set (match_dup 3)
6353 (minus:DWIH
6354 (match_dup 4)
6355 (plus:DWIH
6356 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6357 (match_dup 5))))
6358 (clobber (reg:CC FLAGS_REG))])]
6359 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6360
6361 (define_insn "*sub<mode>_1"
6362 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6363 (minus:SWI
6364 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6365 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6366 (clobber (reg:CC FLAGS_REG))]
6367 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6368 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6369 [(set_attr "type" "alu")
6370 (set_attr "mode" "<MODE>")])
6371
6372 (define_insn "*subsi_1_zext"
6373 [(set (match_operand:DI 0 "register_operand" "=r")
6374 (zero_extend:DI
6375 (minus:SI (match_operand:SI 1 "register_operand" "0")
6376 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6377 (clobber (reg:CC FLAGS_REG))]
6378 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6379 "sub{l}\t{%2, %k0|%k0, %2}"
6380 [(set_attr "type" "alu")
6381 (set_attr "mode" "SI")])
6382
6383 (define_insn "*subqi_1_slp"
6384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6385 (minus:QI (match_dup 0)
6386 (match_operand:QI 1 "general_operand" "qn,qm")))
6387 (clobber (reg:CC FLAGS_REG))]
6388 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6389 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6390 "sub{b}\t{%1, %0|%0, %1}"
6391 [(set_attr "type" "alu1")
6392 (set_attr "mode" "QI")])
6393
6394 (define_insn "*sub<mode>_2"
6395 [(set (reg FLAGS_REG)
6396 (compare
6397 (minus:SWI
6398 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6399 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6400 (const_int 0)))
6401 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6402 (minus:SWI (match_dup 1) (match_dup 2)))]
6403 "ix86_match_ccmode (insn, CCGOCmode)
6404 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6405 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "mode" "<MODE>")])
6408
6409 (define_insn "*subsi_2_zext"
6410 [(set (reg FLAGS_REG)
6411 (compare
6412 (minus:SI (match_operand:SI 1 "register_operand" "0")
6413 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6414 (const_int 0)))
6415 (set (match_operand:DI 0 "register_operand" "=r")
6416 (zero_extend:DI
6417 (minus:SI (match_dup 1)
6418 (match_dup 2))))]
6419 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6420 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6421 "sub{l}\t{%2, %k0|%k0, %2}"
6422 [(set_attr "type" "alu")
6423 (set_attr "mode" "SI")])
6424
6425 (define_insn "*sub<mode>_3"
6426 [(set (reg FLAGS_REG)
6427 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6428 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6429 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6430 (minus:SWI (match_dup 1) (match_dup 2)))]
6431 "ix86_match_ccmode (insn, CCmode)
6432 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6433 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6434 [(set_attr "type" "alu")
6435 (set_attr "mode" "<MODE>")])
6436
6437 (define_insn "*subsi_3_zext"
6438 [(set (reg FLAGS_REG)
6439 (compare (match_operand:SI 1 "register_operand" "0")
6440 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6441 (set (match_operand:DI 0 "register_operand" "=r")
6442 (zero_extend:DI
6443 (minus:SI (match_dup 1)
6444 (match_dup 2))))]
6445 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6446 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6447 "sub{l}\t{%2, %1|%1, %2}"
6448 [(set_attr "type" "alu")
6449 (set_attr "mode" "SI")])
6450 \f
6451 ;; Add with carry and subtract with borrow
6452
6453 (define_expand "<plusminus_insn><mode>3_carry"
6454 [(parallel
6455 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6456 (plusminus:SWI
6457 (match_operand:SWI 1 "nonimmediate_operand" "")
6458 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6459 [(match_operand 3 "flags_reg_operand" "")
6460 (const_int 0)])
6461 (match_operand:SWI 2 "<general_operand>" ""))))
6462 (clobber (reg:CC FLAGS_REG))])]
6463 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6464
6465 (define_insn "*<plusminus_insn><mode>3_carry"
6466 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6467 (plusminus:SWI
6468 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6469 (plus:SWI
6470 (match_operator 3 "ix86_carry_flag_operator"
6471 [(reg FLAGS_REG) (const_int 0)])
6472 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6473 (clobber (reg:CC FLAGS_REG))]
6474 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6475 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6476 [(set_attr "type" "alu")
6477 (set_attr "use_carry" "1")
6478 (set_attr "pent_pair" "pu")
6479 (set_attr "mode" "<MODE>")])
6480
6481 (define_insn "*addsi3_carry_zext"
6482 [(set (match_operand:DI 0 "register_operand" "=r")
6483 (zero_extend:DI
6484 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6485 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6486 [(reg FLAGS_REG) (const_int 0)])
6487 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6488 (clobber (reg:CC FLAGS_REG))]
6489 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6490 "adc{l}\t{%2, %k0|%k0, %2}"
6491 [(set_attr "type" "alu")
6492 (set_attr "use_carry" "1")
6493 (set_attr "pent_pair" "pu")
6494 (set_attr "mode" "SI")])
6495
6496 (define_insn "*subsi3_carry_zext"
6497 [(set (match_operand:DI 0 "register_operand" "=r")
6498 (zero_extend:DI
6499 (minus:SI (match_operand:SI 1 "register_operand" "0")
6500 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6501 [(reg FLAGS_REG) (const_int 0)])
6502 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6503 (clobber (reg:CC FLAGS_REG))]
6504 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6505 "sbb{l}\t{%2, %k0|%k0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "pent_pair" "pu")
6508 (set_attr "mode" "SI")])
6509 \f
6510 ;; Overflow setting add and subtract instructions
6511
6512 (define_insn "*add<mode>3_cconly_overflow"
6513 [(set (reg:CCC FLAGS_REG)
6514 (compare:CCC
6515 (plus:SWI
6516 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6517 (match_operand:SWI 2 "<general_operand>" "<g>"))
6518 (match_dup 1)))
6519 (clobber (match_scratch:SWI 0 "=<r>"))]
6520 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6521 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "mode" "<MODE>")])
6524
6525 (define_insn "*sub<mode>3_cconly_overflow"
6526 [(set (reg:CCC FLAGS_REG)
6527 (compare:CCC
6528 (minus:SWI
6529 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6530 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6531 (match_dup 0)))]
6532 ""
6533 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6534 [(set_attr "type" "icmp")
6535 (set_attr "mode" "<MODE>")])
6536
6537 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6538 [(set (reg:CCC FLAGS_REG)
6539 (compare:CCC
6540 (plusminus:SWI
6541 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6542 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6543 (match_dup 1)))
6544 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6545 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6546 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6547 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6548 [(set_attr "type" "alu")
6549 (set_attr "mode" "<MODE>")])
6550
6551 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6552 [(set (reg:CCC FLAGS_REG)
6553 (compare:CCC
6554 (plusminus:SI
6555 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6556 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6557 (match_dup 1)))
6558 (set (match_operand:DI 0 "register_operand" "=r")
6559 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6560 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6561 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6562 [(set_attr "type" "alu")
6563 (set_attr "mode" "SI")])
6564
6565 ;; The patterns that match these are at the end of this file.
6566
6567 (define_expand "<plusminus_insn>xf3"
6568 [(set (match_operand:XF 0 "register_operand" "")
6569 (plusminus:XF
6570 (match_operand:XF 1 "register_operand" "")
6571 (match_operand:XF 2 "register_operand" "")))]
6572 "TARGET_80387")
6573
6574 (define_expand "<plusminus_insn><mode>3"
6575 [(set (match_operand:MODEF 0 "register_operand" "")
6576 (plusminus:MODEF
6577 (match_operand:MODEF 1 "register_operand" "")
6578 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6579 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6580 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6581 \f
6582 ;; Multiply instructions
6583
6584 (define_expand "mul<mode>3"
6585 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6586 (mult:SWIM248
6587 (match_operand:SWIM248 1 "register_operand" "")
6588 (match_operand:SWIM248 2 "<general_operand>" "")))
6589 (clobber (reg:CC FLAGS_REG))])])
6590
6591 (define_expand "mulqi3"
6592 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6593 (mult:QI
6594 (match_operand:QI 1 "register_operand" "")
6595 (match_operand:QI 2 "nonimmediate_operand" "")))
6596 (clobber (reg:CC FLAGS_REG))])]
6597 "TARGET_QIMODE_MATH")
6598
6599 ;; On AMDFAM10
6600 ;; IMUL reg32/64, reg32/64, imm8 Direct
6601 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6602 ;; IMUL reg32/64, reg32/64, imm32 Direct
6603 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6604 ;; IMUL reg32/64, reg32/64 Direct
6605 ;; IMUL reg32/64, mem32/64 Direct
6606 ;;
6607 ;; On BDVER1, all above IMULs use DirectPath
6608
6609 (define_insn "*mul<mode>3_1"
6610 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6611 (mult:SWI48
6612 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6613 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616 "@
6617 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6618 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6619 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6620 [(set_attr "type" "imul")
6621 (set_attr "prefix_0f" "0,0,1")
6622 (set (attr "athlon_decode")
6623 (cond [(eq_attr "cpu" "athlon")
6624 (const_string "vector")
6625 (eq_attr "alternative" "1")
6626 (const_string "vector")
6627 (and (eq_attr "alternative" "2")
6628 (match_operand 1 "memory_operand" ""))
6629 (const_string "vector")]
6630 (const_string "direct")))
6631 (set (attr "amdfam10_decode")
6632 (cond [(and (eq_attr "alternative" "0,1")
6633 (match_operand 1 "memory_operand" ""))
6634 (const_string "vector")]
6635 (const_string "direct")))
6636 (set_attr "bdver1_decode" "direct")
6637 (set_attr "mode" "<MODE>")])
6638
6639 (define_insn "*mulsi3_1_zext"
6640 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6641 (zero_extend:DI
6642 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6643 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6644 (clobber (reg:CC FLAGS_REG))]
6645 "TARGET_64BIT
6646 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6647 "@
6648 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6649 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6650 imul{l}\t{%2, %k0|%k0, %2}"
6651 [(set_attr "type" "imul")
6652 (set_attr "prefix_0f" "0,0,1")
6653 (set (attr "athlon_decode")
6654 (cond [(eq_attr "cpu" "athlon")
6655 (const_string "vector")
6656 (eq_attr "alternative" "1")
6657 (const_string "vector")
6658 (and (eq_attr "alternative" "2")
6659 (match_operand 1 "memory_operand" ""))
6660 (const_string "vector")]
6661 (const_string "direct")))
6662 (set (attr "amdfam10_decode")
6663 (cond [(and (eq_attr "alternative" "0,1")
6664 (match_operand 1 "memory_operand" ""))
6665 (const_string "vector")]
6666 (const_string "direct")))
6667 (set_attr "bdver1_decode" "direct")
6668 (set_attr "mode" "SI")])
6669
6670 ;; On AMDFAM10
6671 ;; IMUL reg16, reg16, imm8 VectorPath
6672 ;; IMUL reg16, mem16, imm8 VectorPath
6673 ;; IMUL reg16, reg16, imm16 VectorPath
6674 ;; IMUL reg16, mem16, imm16 VectorPath
6675 ;; IMUL reg16, reg16 Direct
6676 ;; IMUL reg16, mem16 Direct
6677 ;;
6678 ;; On BDVER1, all HI MULs use DoublePath
6679
6680 (define_insn "*mulhi3_1"
6681 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6682 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6683 (match_operand:HI 2 "general_operand" "K,n,mr")))
6684 (clobber (reg:CC FLAGS_REG))]
6685 "TARGET_HIMODE_MATH
6686 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6687 "@
6688 imul{w}\t{%2, %1, %0|%0, %1, %2}
6689 imul{w}\t{%2, %1, %0|%0, %1, %2}
6690 imul{w}\t{%2, %0|%0, %2}"
6691 [(set_attr "type" "imul")
6692 (set_attr "prefix_0f" "0,0,1")
6693 (set (attr "athlon_decode")
6694 (cond [(eq_attr "cpu" "athlon")
6695 (const_string "vector")
6696 (eq_attr "alternative" "1,2")
6697 (const_string "vector")]
6698 (const_string "direct")))
6699 (set (attr "amdfam10_decode")
6700 (cond [(eq_attr "alternative" "0,1")
6701 (const_string "vector")]
6702 (const_string "direct")))
6703 (set_attr "bdver1_decode" "double")
6704 (set_attr "mode" "HI")])
6705
6706 ;;On AMDFAM10 and BDVER1
6707 ;; MUL reg8 Direct
6708 ;; MUL mem8 Direct
6709
6710 (define_insn "*mulqi3_1"
6711 [(set (match_operand:QI 0 "register_operand" "=a")
6712 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6713 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6714 (clobber (reg:CC FLAGS_REG))]
6715 "TARGET_QIMODE_MATH
6716 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6717 "mul{b}\t%2"
6718 [(set_attr "type" "imul")
6719 (set_attr "length_immediate" "0")
6720 (set (attr "athlon_decode")
6721 (if_then_else (eq_attr "cpu" "athlon")
6722 (const_string "vector")
6723 (const_string "direct")))
6724 (set_attr "amdfam10_decode" "direct")
6725 (set_attr "bdver1_decode" "direct")
6726 (set_attr "mode" "QI")])
6727
6728 (define_expand "<u>mul<mode><dwi>3"
6729 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6730 (mult:<DWI>
6731 (any_extend:<DWI>
6732 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6733 (any_extend:<DWI>
6734 (match_operand:DWIH 2 "register_operand" ""))))
6735 (clobber (reg:CC FLAGS_REG))])])
6736
6737 (define_expand "<u>mulqihi3"
6738 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6739 (mult:HI
6740 (any_extend:HI
6741 (match_operand:QI 1 "nonimmediate_operand" ""))
6742 (any_extend:HI
6743 (match_operand:QI 2 "register_operand" ""))))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "TARGET_QIMODE_MATH")
6746
6747 (define_insn "*bmi2_umulditi3_1"
6748 [(set (match_operand:DI 0 "register_operand" "=r")
6749 (mult:DI
6750 (match_operand:DI 2 "nonimmediate_operand" "%d")
6751 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6752 (set (match_operand:DI 1 "register_operand" "=r")
6753 (truncate:DI
6754 (lshiftrt:TI
6755 (mult:TI (zero_extend:TI (match_dup 2))
6756 (zero_extend:TI (match_dup 3)))
6757 (const_int 64))))]
6758 "TARGET_64BIT && TARGET_BMI2
6759 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6760 "mulx\t{%3, %0, %1|%1, %0, %3}"
6761 [(set_attr "type" "imulx")
6762 (set_attr "prefix" "vex")
6763 (set_attr "mode" "DI")])
6764
6765 (define_insn "*bmi2_umulsidi3_1"
6766 [(set (match_operand:SI 0 "register_operand" "=r")
6767 (mult:SI
6768 (match_operand:SI 2 "nonimmediate_operand" "%d")
6769 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6770 (set (match_operand:SI 1 "register_operand" "=r")
6771 (truncate:SI
6772 (lshiftrt:DI
6773 (mult:DI (zero_extend:DI (match_dup 2))
6774 (zero_extend:DI (match_dup 3)))
6775 (const_int 32))))]
6776 "!TARGET_64BIT && TARGET_BMI2
6777 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6778 "mulx\t{%3, %0, %1|%1, %0, %3}"
6779 [(set_attr "type" "imulx")
6780 (set_attr "prefix" "vex")
6781 (set_attr "mode" "SI")])
6782
6783 (define_insn "*umul<mode><dwi>3_1"
6784 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6785 (mult:<DWI>
6786 (zero_extend:<DWI>
6787 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6788 (zero_extend:<DWI>
6789 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6790 (clobber (reg:CC FLAGS_REG))]
6791 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6792 "@
6793 mul{<imodesuffix>}\t%2
6794 #"
6795 [(set_attr "isa" "*,bmi2")
6796 (set_attr "type" "imul,imulx")
6797 (set_attr "length_immediate" "0,*")
6798 (set (attr "athlon_decode")
6799 (cond [(eq_attr "alternative" "0")
6800 (if_then_else (eq_attr "cpu" "athlon")
6801 (const_string "vector")
6802 (const_string "double"))]
6803 (const_string "*")))
6804 (set_attr "amdfam10_decode" "double,*")
6805 (set_attr "bdver1_decode" "direct,*")
6806 (set_attr "prefix" "orig,vex")
6807 (set_attr "mode" "<MODE>")])
6808
6809 ;; Convert mul to the mulx pattern to avoid flags dependency.
6810 (define_split
6811 [(set (match_operand:<DWI> 0 "register_operand" "")
6812 (mult:<DWI>
6813 (zero_extend:<DWI>
6814 (match_operand:DWIH 1 "register_operand" ""))
6815 (zero_extend:<DWI>
6816 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6817 (clobber (reg:CC FLAGS_REG))]
6818 "TARGET_BMI2 && reload_completed
6819 && true_regnum (operands[1]) == DX_REG"
6820 [(parallel [(set (match_dup 3)
6821 (mult:DWIH (match_dup 1) (match_dup 2)))
6822 (set (match_dup 4)
6823 (truncate:DWIH
6824 (lshiftrt:<DWI>
6825 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6826 (zero_extend:<DWI> (match_dup 2)))
6827 (match_dup 5))))])]
6828 {
6829 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6830
6831 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6832 })
6833
6834 (define_insn "*mul<mode><dwi>3_1"
6835 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6836 (mult:<DWI>
6837 (sign_extend:<DWI>
6838 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6839 (sign_extend:<DWI>
6840 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6841 (clobber (reg:CC FLAGS_REG))]
6842 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6843 "imul{<imodesuffix>}\t%2"
6844 [(set_attr "type" "imul")
6845 (set_attr "length_immediate" "0")
6846 (set (attr "athlon_decode")
6847 (if_then_else (eq_attr "cpu" "athlon")
6848 (const_string "vector")
6849 (const_string "double")))
6850 (set_attr "amdfam10_decode" "double")
6851 (set_attr "bdver1_decode" "direct")
6852 (set_attr "mode" "<MODE>")])
6853
6854 (define_insn "*<u>mulqihi3_1"
6855 [(set (match_operand:HI 0 "register_operand" "=a")
6856 (mult:HI
6857 (any_extend:HI
6858 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6859 (any_extend:HI
6860 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6861 (clobber (reg:CC FLAGS_REG))]
6862 "TARGET_QIMODE_MATH
6863 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864 "<sgnprefix>mul{b}\t%2"
6865 [(set_attr "type" "imul")
6866 (set_attr "length_immediate" "0")
6867 (set (attr "athlon_decode")
6868 (if_then_else (eq_attr "cpu" "athlon")
6869 (const_string "vector")
6870 (const_string "direct")))
6871 (set_attr "amdfam10_decode" "direct")
6872 (set_attr "bdver1_decode" "direct")
6873 (set_attr "mode" "QI")])
6874
6875 (define_expand "<s>mul<mode>3_highpart"
6876 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6877 (truncate:SWI48
6878 (lshiftrt:<DWI>
6879 (mult:<DWI>
6880 (any_extend:<DWI>
6881 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6882 (any_extend:<DWI>
6883 (match_operand:SWI48 2 "register_operand" "")))
6884 (match_dup 4))))
6885 (clobber (match_scratch:SWI48 3 ""))
6886 (clobber (reg:CC FLAGS_REG))])]
6887 ""
6888 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6889
6890 (define_insn "*<s>muldi3_highpart_1"
6891 [(set (match_operand:DI 0 "register_operand" "=d")
6892 (truncate:DI
6893 (lshiftrt:TI
6894 (mult:TI
6895 (any_extend:TI
6896 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6897 (any_extend:TI
6898 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6899 (const_int 64))))
6900 (clobber (match_scratch:DI 3 "=1"))
6901 (clobber (reg:CC FLAGS_REG))]
6902 "TARGET_64BIT
6903 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6904 "<sgnprefix>mul{q}\t%2"
6905 [(set_attr "type" "imul")
6906 (set_attr "length_immediate" "0")
6907 (set (attr "athlon_decode")
6908 (if_then_else (eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (const_string "double")))
6911 (set_attr "amdfam10_decode" "double")
6912 (set_attr "bdver1_decode" "direct")
6913 (set_attr "mode" "DI")])
6914
6915 (define_insn "*<s>mulsi3_highpart_1"
6916 [(set (match_operand:SI 0 "register_operand" "=d")
6917 (truncate:SI
6918 (lshiftrt:DI
6919 (mult:DI
6920 (any_extend:DI
6921 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6922 (any_extend:DI
6923 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6924 (const_int 32))))
6925 (clobber (match_scratch:SI 3 "=1"))
6926 (clobber (reg:CC FLAGS_REG))]
6927 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928 "<sgnprefix>mul{l}\t%2"
6929 [(set_attr "type" "imul")
6930 (set_attr "length_immediate" "0")
6931 (set (attr "athlon_decode")
6932 (if_then_else (eq_attr "cpu" "athlon")
6933 (const_string "vector")
6934 (const_string "double")))
6935 (set_attr "amdfam10_decode" "double")
6936 (set_attr "bdver1_decode" "direct")
6937 (set_attr "mode" "SI")])
6938
6939 (define_insn "*<s>mulsi3_highpart_zext"
6940 [(set (match_operand:DI 0 "register_operand" "=d")
6941 (zero_extend:DI (truncate:SI
6942 (lshiftrt:DI
6943 (mult:DI (any_extend:DI
6944 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6945 (any_extend:DI
6946 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6947 (const_int 32)))))
6948 (clobber (match_scratch:SI 3 "=1"))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_64BIT
6951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952 "<sgnprefix>mul{l}\t%2"
6953 [(set_attr "type" "imul")
6954 (set_attr "length_immediate" "0")
6955 (set (attr "athlon_decode")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "double")))
6959 (set_attr "amdfam10_decode" "double")
6960 (set_attr "bdver1_decode" "direct")
6961 (set_attr "mode" "SI")])
6962
6963 ;; The patterns that match these are at the end of this file.
6964
6965 (define_expand "mulxf3"
6966 [(set (match_operand:XF 0 "register_operand" "")
6967 (mult:XF (match_operand:XF 1 "register_operand" "")
6968 (match_operand:XF 2 "register_operand" "")))]
6969 "TARGET_80387")
6970
6971 (define_expand "mul<mode>3"
6972 [(set (match_operand:MODEF 0 "register_operand" "")
6973 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6974 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6975 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6976 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6977 \f
6978 ;; Divide instructions
6979
6980 ;; The patterns that match these are at the end of this file.
6981
6982 (define_expand "divxf3"
6983 [(set (match_operand:XF 0 "register_operand" "")
6984 (div:XF (match_operand:XF 1 "register_operand" "")
6985 (match_operand:XF 2 "register_operand" "")))]
6986 "TARGET_80387")
6987
6988 (define_expand "divdf3"
6989 [(set (match_operand:DF 0 "register_operand" "")
6990 (div:DF (match_operand:DF 1 "register_operand" "")
6991 (match_operand:DF 2 "nonimmediate_operand" "")))]
6992 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6993 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6994
6995 (define_expand "divsf3"
6996 [(set (match_operand:SF 0 "register_operand" "")
6997 (div:SF (match_operand:SF 1 "register_operand" "")
6998 (match_operand:SF 2 "nonimmediate_operand" "")))]
6999 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7000 || TARGET_SSE_MATH"
7001 {
7002 if (TARGET_SSE_MATH
7003 && TARGET_RECIP_DIV
7004 && optimize_insn_for_speed_p ()
7005 && flag_finite_math_only && !flag_trapping_math
7006 && flag_unsafe_math_optimizations)
7007 {
7008 ix86_emit_swdivsf (operands[0], operands[1],
7009 operands[2], SFmode);
7010 DONE;
7011 }
7012 })
7013 \f
7014 ;; Divmod instructions.
7015
7016 (define_expand "divmod<mode>4"
7017 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7018 (div:SWIM248
7019 (match_operand:SWIM248 1 "register_operand" "")
7020 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7021 (set (match_operand:SWIM248 3 "register_operand" "")
7022 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7023 (clobber (reg:CC FLAGS_REG))])])
7024
7025 ;; Split with 8bit unsigned divide:
7026 ;; if (dividend an divisor are in [0-255])
7027 ;; use 8bit unsigned integer divide
7028 ;; else
7029 ;; use original integer divide
7030 (define_split
7031 [(set (match_operand:SWI48 0 "register_operand" "")
7032 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7033 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7034 (set (match_operand:SWI48 1 "register_operand" "")
7035 (mod:SWI48 (match_dup 2) (match_dup 3)))
7036 (clobber (reg:CC FLAGS_REG))]
7037 "TARGET_USE_8BIT_IDIV
7038 && TARGET_QIMODE_MATH
7039 && can_create_pseudo_p ()
7040 && !optimize_insn_for_size_p ()"
7041 [(const_int 0)]
7042 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7043
7044 (define_insn_and_split "divmod<mode>4_1"
7045 [(set (match_operand:SWI48 0 "register_operand" "=a")
7046 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7047 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7048 (set (match_operand:SWI48 1 "register_operand" "=&d")
7049 (mod:SWI48 (match_dup 2) (match_dup 3)))
7050 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7051 (clobber (reg:CC FLAGS_REG))]
7052 ""
7053 "#"
7054 "reload_completed"
7055 [(parallel [(set (match_dup 1)
7056 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7057 (clobber (reg:CC FLAGS_REG))])
7058 (parallel [(set (match_dup 0)
7059 (div:SWI48 (match_dup 2) (match_dup 3)))
7060 (set (match_dup 1)
7061 (mod:SWI48 (match_dup 2) (match_dup 3)))
7062 (use (match_dup 1))
7063 (clobber (reg:CC FLAGS_REG))])]
7064 {
7065 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7066
7067 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7068 operands[4] = operands[2];
7069 else
7070 {
7071 /* Avoid use of cltd in favor of a mov+shift. */
7072 emit_move_insn (operands[1], operands[2]);
7073 operands[4] = operands[1];
7074 }
7075 }
7076 [(set_attr "type" "multi")
7077 (set_attr "mode" "<MODE>")])
7078
7079 (define_insn_and_split "*divmod<mode>4"
7080 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7081 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7082 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7083 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7084 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7085 (clobber (reg:CC FLAGS_REG))]
7086 ""
7087 "#"
7088 "reload_completed"
7089 [(parallel [(set (match_dup 1)
7090 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7091 (clobber (reg:CC FLAGS_REG))])
7092 (parallel [(set (match_dup 0)
7093 (div:SWIM248 (match_dup 2) (match_dup 3)))
7094 (set (match_dup 1)
7095 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7096 (use (match_dup 1))
7097 (clobber (reg:CC FLAGS_REG))])]
7098 {
7099 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7100
7101 if (<MODE>mode != HImode
7102 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7103 operands[4] = operands[2];
7104 else
7105 {
7106 /* Avoid use of cltd in favor of a mov+shift. */
7107 emit_move_insn (operands[1], operands[2]);
7108 operands[4] = operands[1];
7109 }
7110 }
7111 [(set_attr "type" "multi")
7112 (set_attr "mode" "<MODE>")])
7113
7114 (define_insn "*divmod<mode>4_noext"
7115 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7116 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7117 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7118 (set (match_operand:SWIM248 1 "register_operand" "=d")
7119 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7120 (use (match_operand:SWIM248 4 "register_operand" "1"))
7121 (clobber (reg:CC FLAGS_REG))]
7122 ""
7123 "idiv{<imodesuffix>}\t%3"
7124 [(set_attr "type" "idiv")
7125 (set_attr "mode" "<MODE>")])
7126
7127 (define_expand "divmodqi4"
7128 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7129 (div:QI
7130 (match_operand:QI 1 "register_operand" "")
7131 (match_operand:QI 2 "nonimmediate_operand" "")))
7132 (set (match_operand:QI 3 "register_operand" "")
7133 (mod:QI (match_dup 1) (match_dup 2)))
7134 (clobber (reg:CC FLAGS_REG))])]
7135 "TARGET_QIMODE_MATH"
7136 {
7137 rtx div, mod, insn;
7138 rtx tmp0, tmp1;
7139
7140 tmp0 = gen_reg_rtx (HImode);
7141 tmp1 = gen_reg_rtx (HImode);
7142
7143 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7144 in AX. */
7145 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7146 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7147
7148 /* Extract remainder from AH. */
7149 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7150 insn = emit_move_insn (operands[3], tmp1);
7151
7152 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7153 set_unique_reg_note (insn, REG_EQUAL, mod);
7154
7155 /* Extract quotient from AL. */
7156 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7157
7158 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7159 set_unique_reg_note (insn, REG_EQUAL, div);
7160
7161 DONE;
7162 })
7163
7164 ;; Divide AX by r/m8, with result stored in
7165 ;; AL <- Quotient
7166 ;; AH <- Remainder
7167 ;; Change div/mod to HImode and extend the second argument to HImode
7168 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7169 ;; combine may fail.
7170 (define_insn "divmodhiqi3"
7171 [(set (match_operand:HI 0 "register_operand" "=a")
7172 (ior:HI
7173 (ashift:HI
7174 (zero_extend:HI
7175 (truncate:QI
7176 (mod:HI (match_operand:HI 1 "register_operand" "0")
7177 (sign_extend:HI
7178 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7179 (const_int 8))
7180 (zero_extend:HI
7181 (truncate:QI
7182 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "TARGET_QIMODE_MATH"
7185 "idiv{b}\t%2"
7186 [(set_attr "type" "idiv")
7187 (set_attr "mode" "QI")])
7188
7189 (define_expand "udivmod<mode>4"
7190 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7191 (udiv:SWIM248
7192 (match_operand:SWIM248 1 "register_operand" "")
7193 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7194 (set (match_operand:SWIM248 3 "register_operand" "")
7195 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7196 (clobber (reg:CC FLAGS_REG))])])
7197
7198 ;; Split with 8bit unsigned divide:
7199 ;; if (dividend an divisor are in [0-255])
7200 ;; use 8bit unsigned integer divide
7201 ;; else
7202 ;; use original integer divide
7203 (define_split
7204 [(set (match_operand:SWI48 0 "register_operand" "")
7205 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7206 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7207 (set (match_operand:SWI48 1 "register_operand" "")
7208 (umod:SWI48 (match_dup 2) (match_dup 3)))
7209 (clobber (reg:CC FLAGS_REG))]
7210 "TARGET_USE_8BIT_IDIV
7211 && TARGET_QIMODE_MATH
7212 && can_create_pseudo_p ()
7213 && !optimize_insn_for_size_p ()"
7214 [(const_int 0)]
7215 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7216
7217 (define_insn_and_split "udivmod<mode>4_1"
7218 [(set (match_operand:SWI48 0 "register_operand" "=a")
7219 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7220 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7221 (set (match_operand:SWI48 1 "register_operand" "=&d")
7222 (umod:SWI48 (match_dup 2) (match_dup 3)))
7223 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7224 (clobber (reg:CC FLAGS_REG))]
7225 ""
7226 "#"
7227 "reload_completed"
7228 [(set (match_dup 1) (const_int 0))
7229 (parallel [(set (match_dup 0)
7230 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7231 (set (match_dup 1)
7232 (umod:SWI48 (match_dup 2) (match_dup 3)))
7233 (use (match_dup 1))
7234 (clobber (reg:CC FLAGS_REG))])]
7235 ""
7236 [(set_attr "type" "multi")
7237 (set_attr "mode" "<MODE>")])
7238
7239 (define_insn_and_split "*udivmod<mode>4"
7240 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7241 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7242 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7243 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7244 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7245 (clobber (reg:CC FLAGS_REG))]
7246 ""
7247 "#"
7248 "reload_completed"
7249 [(set (match_dup 1) (const_int 0))
7250 (parallel [(set (match_dup 0)
7251 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7252 (set (match_dup 1)
7253 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7254 (use (match_dup 1))
7255 (clobber (reg:CC FLAGS_REG))])]
7256 ""
7257 [(set_attr "type" "multi")
7258 (set_attr "mode" "<MODE>")])
7259
7260 (define_insn "*udivmod<mode>4_noext"
7261 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7262 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7263 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7264 (set (match_operand:SWIM248 1 "register_operand" "=d")
7265 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7266 (use (match_operand:SWIM248 4 "register_operand" "1"))
7267 (clobber (reg:CC FLAGS_REG))]
7268 ""
7269 "div{<imodesuffix>}\t%3"
7270 [(set_attr "type" "idiv")
7271 (set_attr "mode" "<MODE>")])
7272
7273 (define_expand "udivmodqi4"
7274 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7275 (udiv:QI
7276 (match_operand:QI 1 "register_operand" "")
7277 (match_operand:QI 2 "nonimmediate_operand" "")))
7278 (set (match_operand:QI 3 "register_operand" "")
7279 (umod:QI (match_dup 1) (match_dup 2)))
7280 (clobber (reg:CC FLAGS_REG))])]
7281 "TARGET_QIMODE_MATH"
7282 {
7283 rtx div, mod, insn;
7284 rtx tmp0, tmp1;
7285
7286 tmp0 = gen_reg_rtx (HImode);
7287 tmp1 = gen_reg_rtx (HImode);
7288
7289 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7290 in AX. */
7291 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7292 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7293
7294 /* Extract remainder from AH. */
7295 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7296 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7297 insn = emit_move_insn (operands[3], tmp1);
7298
7299 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7300 set_unique_reg_note (insn, REG_EQUAL, mod);
7301
7302 /* Extract quotient from AL. */
7303 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7304
7305 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7306 set_unique_reg_note (insn, REG_EQUAL, div);
7307
7308 DONE;
7309 })
7310
7311 (define_insn "udivmodhiqi3"
7312 [(set (match_operand:HI 0 "register_operand" "=a")
7313 (ior:HI
7314 (ashift:HI
7315 (zero_extend:HI
7316 (truncate:QI
7317 (mod:HI (match_operand:HI 1 "register_operand" "0")
7318 (zero_extend:HI
7319 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7320 (const_int 8))
7321 (zero_extend:HI
7322 (truncate:QI
7323 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7324 (clobber (reg:CC FLAGS_REG))]
7325 "TARGET_QIMODE_MATH"
7326 "div{b}\t%2"
7327 [(set_attr "type" "idiv")
7328 (set_attr "mode" "QI")])
7329
7330 ;; We cannot use div/idiv for double division, because it causes
7331 ;; "division by zero" on the overflow and that's not what we expect
7332 ;; from truncate. Because true (non truncating) double division is
7333 ;; never generated, we can't create this insn anyway.
7334 ;
7335 ;(define_insn ""
7336 ; [(set (match_operand:SI 0 "register_operand" "=a")
7337 ; (truncate:SI
7338 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7339 ; (zero_extend:DI
7340 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7341 ; (set (match_operand:SI 3 "register_operand" "=d")
7342 ; (truncate:SI
7343 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7344 ; (clobber (reg:CC FLAGS_REG))]
7345 ; ""
7346 ; "div{l}\t{%2, %0|%0, %2}"
7347 ; [(set_attr "type" "idiv")])
7348 \f
7349 ;;- Logical AND instructions
7350
7351 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7352 ;; Note that this excludes ah.
7353
7354 (define_expand "testsi_ccno_1"
7355 [(set (reg:CCNO FLAGS_REG)
7356 (compare:CCNO
7357 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7358 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7359 (const_int 0)))])
7360
7361 (define_expand "testqi_ccz_1"
7362 [(set (reg:CCZ FLAGS_REG)
7363 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7364 (match_operand:QI 1 "nonmemory_operand" ""))
7365 (const_int 0)))])
7366
7367 (define_expand "testdi_ccno_1"
7368 [(set (reg:CCNO FLAGS_REG)
7369 (compare:CCNO
7370 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7371 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7372 (const_int 0)))]
7373 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7374
7375 (define_insn "*testdi_1"
7376 [(set (reg FLAGS_REG)
7377 (compare
7378 (and:DI
7379 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7380 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7381 (const_int 0)))]
7382 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7383 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7384 "@
7385 test{l}\t{%k1, %k0|%k0, %k1}
7386 test{l}\t{%k1, %k0|%k0, %k1}
7387 test{q}\t{%1, %0|%0, %1}
7388 test{q}\t{%1, %0|%0, %1}
7389 test{q}\t{%1, %0|%0, %1}"
7390 [(set_attr "type" "test")
7391 (set_attr "modrm" "0,1,0,1,1")
7392 (set_attr "mode" "SI,SI,DI,DI,DI")])
7393
7394 (define_insn "*testqi_1_maybe_si"
7395 [(set (reg FLAGS_REG)
7396 (compare
7397 (and:QI
7398 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7399 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7400 (const_int 0)))]
7401 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7402 && ix86_match_ccmode (insn,
7403 CONST_INT_P (operands[1])
7404 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7405 {
7406 if (which_alternative == 3)
7407 {
7408 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7409 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7410 return "test{l}\t{%1, %k0|%k0, %1}";
7411 }
7412 return "test{b}\t{%1, %0|%0, %1}";
7413 }
7414 [(set_attr "type" "test")
7415 (set_attr "modrm" "0,1,1,1")
7416 (set_attr "mode" "QI,QI,QI,SI")
7417 (set_attr "pent_pair" "uv,np,uv,np")])
7418
7419 (define_insn "*test<mode>_1"
7420 [(set (reg FLAGS_REG)
7421 (compare
7422 (and:SWI124
7423 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7424 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7425 (const_int 0)))]
7426 "ix86_match_ccmode (insn, CCNOmode)
7427 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7428 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7429 [(set_attr "type" "test")
7430 (set_attr "modrm" "0,1,1")
7431 (set_attr "mode" "<MODE>")
7432 (set_attr "pent_pair" "uv,np,uv")])
7433
7434 (define_expand "testqi_ext_ccno_0"
7435 [(set (reg:CCNO FLAGS_REG)
7436 (compare:CCNO
7437 (and:SI
7438 (zero_extract:SI
7439 (match_operand 0 "ext_register_operand" "")
7440 (const_int 8)
7441 (const_int 8))
7442 (match_operand 1 "const_int_operand" ""))
7443 (const_int 0)))])
7444
7445 (define_insn "*testqi_ext_0"
7446 [(set (reg FLAGS_REG)
7447 (compare
7448 (and:SI
7449 (zero_extract:SI
7450 (match_operand 0 "ext_register_operand" "Q")
7451 (const_int 8)
7452 (const_int 8))
7453 (match_operand 1 "const_int_operand" "n"))
7454 (const_int 0)))]
7455 "ix86_match_ccmode (insn, CCNOmode)"
7456 "test{b}\t{%1, %h0|%h0, %1}"
7457 [(set_attr "type" "test")
7458 (set_attr "mode" "QI")
7459 (set_attr "length_immediate" "1")
7460 (set_attr "modrm" "1")
7461 (set_attr "pent_pair" "np")])
7462
7463 (define_insn "*testqi_ext_1_rex64"
7464 [(set (reg FLAGS_REG)
7465 (compare
7466 (and:SI
7467 (zero_extract:SI
7468 (match_operand 0 "ext_register_operand" "Q")
7469 (const_int 8)
7470 (const_int 8))
7471 (zero_extend:SI
7472 (match_operand:QI 1 "register_operand" "Q")))
7473 (const_int 0)))]
7474 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7475 "test{b}\t{%1, %h0|%h0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "mode" "QI")])
7478
7479 (define_insn "*testqi_ext_1"
7480 [(set (reg FLAGS_REG)
7481 (compare
7482 (and:SI
7483 (zero_extract:SI
7484 (match_operand 0 "ext_register_operand" "Q")
7485 (const_int 8)
7486 (const_int 8))
7487 (zero_extend:SI
7488 (match_operand:QI 1 "general_operand" "Qm")))
7489 (const_int 0)))]
7490 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7491 "test{b}\t{%1, %h0|%h0, %1}"
7492 [(set_attr "type" "test")
7493 (set_attr "mode" "QI")])
7494
7495 (define_insn "*testqi_ext_2"
7496 [(set (reg FLAGS_REG)
7497 (compare
7498 (and:SI
7499 (zero_extract:SI
7500 (match_operand 0 "ext_register_operand" "Q")
7501 (const_int 8)
7502 (const_int 8))
7503 (zero_extract:SI
7504 (match_operand 1 "ext_register_operand" "Q")
7505 (const_int 8)
7506 (const_int 8)))
7507 (const_int 0)))]
7508 "ix86_match_ccmode (insn, CCNOmode)"
7509 "test{b}\t{%h1, %h0|%h0, %h1}"
7510 [(set_attr "type" "test")
7511 (set_attr "mode" "QI")])
7512
7513 (define_insn "*testqi_ext_3_rex64"
7514 [(set (reg FLAGS_REG)
7515 (compare (zero_extract:DI
7516 (match_operand 0 "nonimmediate_operand" "rm")
7517 (match_operand:DI 1 "const_int_operand" "")
7518 (match_operand:DI 2 "const_int_operand" ""))
7519 (const_int 0)))]
7520 "TARGET_64BIT
7521 && ix86_match_ccmode (insn, CCNOmode)
7522 && INTVAL (operands[1]) > 0
7523 && INTVAL (operands[2]) >= 0
7524 /* Ensure that resulting mask is zero or sign extended operand. */
7525 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7526 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7527 && INTVAL (operands[1]) > 32))
7528 && (GET_MODE (operands[0]) == SImode
7529 || GET_MODE (operands[0]) == DImode
7530 || GET_MODE (operands[0]) == HImode
7531 || GET_MODE (operands[0]) == QImode)"
7532 "#")
7533
7534 ;; Combine likes to form bit extractions for some tests. Humor it.
7535 (define_insn "*testqi_ext_3"
7536 [(set (reg FLAGS_REG)
7537 (compare (zero_extract:SI
7538 (match_operand 0 "nonimmediate_operand" "rm")
7539 (match_operand:SI 1 "const_int_operand" "")
7540 (match_operand:SI 2 "const_int_operand" ""))
7541 (const_int 0)))]
7542 "ix86_match_ccmode (insn, CCNOmode)
7543 && INTVAL (operands[1]) > 0
7544 && INTVAL (operands[2]) >= 0
7545 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7546 && (GET_MODE (operands[0]) == SImode
7547 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7548 || GET_MODE (operands[0]) == HImode
7549 || GET_MODE (operands[0]) == QImode)"
7550 "#")
7551
7552 (define_split
7553 [(set (match_operand 0 "flags_reg_operand" "")
7554 (match_operator 1 "compare_operator"
7555 [(zero_extract
7556 (match_operand 2 "nonimmediate_operand" "")
7557 (match_operand 3 "const_int_operand" "")
7558 (match_operand 4 "const_int_operand" ""))
7559 (const_int 0)]))]
7560 "ix86_match_ccmode (insn, CCNOmode)"
7561 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7562 {
7563 rtx val = operands[2];
7564 HOST_WIDE_INT len = INTVAL (operands[3]);
7565 HOST_WIDE_INT pos = INTVAL (operands[4]);
7566 HOST_WIDE_INT mask;
7567 enum machine_mode mode, submode;
7568
7569 mode = GET_MODE (val);
7570 if (MEM_P (val))
7571 {
7572 /* ??? Combine likes to put non-volatile mem extractions in QImode
7573 no matter the size of the test. So find a mode that works. */
7574 if (! MEM_VOLATILE_P (val))
7575 {
7576 mode = smallest_mode_for_size (pos + len, MODE_INT);
7577 val = adjust_address (val, mode, 0);
7578 }
7579 }
7580 else if (GET_CODE (val) == SUBREG
7581 && (submode = GET_MODE (SUBREG_REG (val)),
7582 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7583 && pos + len <= GET_MODE_BITSIZE (submode)
7584 && GET_MODE_CLASS (submode) == MODE_INT)
7585 {
7586 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7587 mode = submode;
7588 val = SUBREG_REG (val);
7589 }
7590 else if (mode == HImode && pos + len <= 8)
7591 {
7592 /* Small HImode tests can be converted to QImode. */
7593 mode = QImode;
7594 val = gen_lowpart (QImode, val);
7595 }
7596
7597 if (len == HOST_BITS_PER_WIDE_INT)
7598 mask = -1;
7599 else
7600 mask = ((HOST_WIDE_INT)1 << len) - 1;
7601 mask <<= pos;
7602
7603 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7604 })
7605
7606 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7607 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7608 ;; this is relatively important trick.
7609 ;; Do the conversion only post-reload to avoid limiting of the register class
7610 ;; to QI regs.
7611 (define_split
7612 [(set (match_operand 0 "flags_reg_operand" "")
7613 (match_operator 1 "compare_operator"
7614 [(and (match_operand 2 "register_operand" "")
7615 (match_operand 3 "const_int_operand" ""))
7616 (const_int 0)]))]
7617 "reload_completed
7618 && QI_REG_P (operands[2])
7619 && GET_MODE (operands[2]) != QImode
7620 && ((ix86_match_ccmode (insn, CCZmode)
7621 && !(INTVAL (operands[3]) & ~(255 << 8)))
7622 || (ix86_match_ccmode (insn, CCNOmode)
7623 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7624 [(set (match_dup 0)
7625 (match_op_dup 1
7626 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7627 (match_dup 3))
7628 (const_int 0)]))]
7629 {
7630 operands[2] = gen_lowpart (SImode, operands[2]);
7631 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7632 })
7633
7634 (define_split
7635 [(set (match_operand 0 "flags_reg_operand" "")
7636 (match_operator 1 "compare_operator"
7637 [(and (match_operand 2 "nonimmediate_operand" "")
7638 (match_operand 3 "const_int_operand" ""))
7639 (const_int 0)]))]
7640 "reload_completed
7641 && GET_MODE (operands[2]) != QImode
7642 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7643 && ((ix86_match_ccmode (insn, CCZmode)
7644 && !(INTVAL (operands[3]) & ~255))
7645 || (ix86_match_ccmode (insn, CCNOmode)
7646 && !(INTVAL (operands[3]) & ~127)))"
7647 [(set (match_dup 0)
7648 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7649 (const_int 0)]))]
7650 {
7651 operands[2] = gen_lowpart (QImode, operands[2]);
7652 operands[3] = gen_lowpart (QImode, operands[3]);
7653 })
7654
7655 ;; %%% This used to optimize known byte-wide and operations to memory,
7656 ;; and sometimes to QImode registers. If this is considered useful,
7657 ;; it should be done with splitters.
7658
7659 (define_expand "and<mode>3"
7660 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7661 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7662 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7663 ""
7664 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7665
7666 (define_insn "*anddi_1"
7667 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7668 (and:DI
7669 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7670 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7671 (clobber (reg:CC FLAGS_REG))]
7672 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7673 {
7674 switch (get_attr_type (insn))
7675 {
7676 case TYPE_IMOVX:
7677 {
7678 enum machine_mode mode;
7679
7680 gcc_assert (CONST_INT_P (operands[2]));
7681 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7682 mode = SImode;
7683 else if (INTVAL (operands[2]) == 0xffff)
7684 mode = HImode;
7685 else
7686 {
7687 gcc_assert (INTVAL (operands[2]) == 0xff);
7688 mode = QImode;
7689 }
7690
7691 operands[1] = gen_lowpart (mode, operands[1]);
7692 if (mode == SImode)
7693 return "mov{l}\t{%1, %k0|%k0, %1}";
7694 else if (mode == HImode)
7695 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7696 else
7697 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7698 }
7699
7700 default:
7701 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7702 if (get_attr_mode (insn) == MODE_SI)
7703 return "and{l}\t{%k2, %k0|%k0, %k2}";
7704 else
7705 return "and{q}\t{%2, %0|%0, %2}";
7706 }
7707 }
7708 [(set_attr "type" "alu,alu,alu,imovx")
7709 (set_attr "length_immediate" "*,*,*,0")
7710 (set (attr "prefix_rex")
7711 (if_then_else
7712 (and (eq_attr "type" "imovx")
7713 (and (match_test "INTVAL (operands[2]) == 0xff")
7714 (match_operand 1 "ext_QIreg_operand" "")))
7715 (const_string "1")
7716 (const_string "*")))
7717 (set_attr "mode" "SI,DI,DI,SI")])
7718
7719 (define_insn "*andsi_1"
7720 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7721 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7722 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7723 (clobber (reg:CC FLAGS_REG))]
7724 "ix86_binary_operator_ok (AND, SImode, operands)"
7725 {
7726 switch (get_attr_type (insn))
7727 {
7728 case TYPE_IMOVX:
7729 {
7730 enum machine_mode mode;
7731
7732 gcc_assert (CONST_INT_P (operands[2]));
7733 if (INTVAL (operands[2]) == 0xffff)
7734 mode = HImode;
7735 else
7736 {
7737 gcc_assert (INTVAL (operands[2]) == 0xff);
7738 mode = QImode;
7739 }
7740
7741 operands[1] = gen_lowpart (mode, operands[1]);
7742 if (mode == HImode)
7743 return "movz{wl|x}\t{%1, %0|%0, %1}";
7744 else
7745 return "movz{bl|x}\t{%1, %0|%0, %1}";
7746 }
7747
7748 default:
7749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7750 return "and{l}\t{%2, %0|%0, %2}";
7751 }
7752 }
7753 [(set_attr "type" "alu,alu,imovx")
7754 (set (attr "prefix_rex")
7755 (if_then_else
7756 (and (eq_attr "type" "imovx")
7757 (and (match_test "INTVAL (operands[2]) == 0xff")
7758 (match_operand 1 "ext_QIreg_operand" "")))
7759 (const_string "1")
7760 (const_string "*")))
7761 (set_attr "length_immediate" "*,*,0")
7762 (set_attr "mode" "SI")])
7763
7764 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7765 (define_insn "*andsi_1_zext"
7766 [(set (match_operand:DI 0 "register_operand" "=r")
7767 (zero_extend:DI
7768 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7769 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7770 (clobber (reg:CC FLAGS_REG))]
7771 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7772 "and{l}\t{%2, %k0|%k0, %2}"
7773 [(set_attr "type" "alu")
7774 (set_attr "mode" "SI")])
7775
7776 (define_insn "*andhi_1"
7777 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7778 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7779 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7780 (clobber (reg:CC FLAGS_REG))]
7781 "ix86_binary_operator_ok (AND, HImode, operands)"
7782 {
7783 switch (get_attr_type (insn))
7784 {
7785 case TYPE_IMOVX:
7786 gcc_assert (CONST_INT_P (operands[2]));
7787 gcc_assert (INTVAL (operands[2]) == 0xff);
7788 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7789
7790 default:
7791 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7792
7793 return "and{w}\t{%2, %0|%0, %2}";
7794 }
7795 }
7796 [(set_attr "type" "alu,alu,imovx")
7797 (set_attr "length_immediate" "*,*,0")
7798 (set (attr "prefix_rex")
7799 (if_then_else
7800 (and (eq_attr "type" "imovx")
7801 (match_operand 1 "ext_QIreg_operand" ""))
7802 (const_string "1")
7803 (const_string "*")))
7804 (set_attr "mode" "HI,HI,SI")])
7805
7806 ;; %%% Potential partial reg stall on alternative 2. What to do?
7807 (define_insn "*andqi_1"
7808 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7809 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7810 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7811 (clobber (reg:CC FLAGS_REG))]
7812 "ix86_binary_operator_ok (AND, QImode, operands)"
7813 "@
7814 and{b}\t{%2, %0|%0, %2}
7815 and{b}\t{%2, %0|%0, %2}
7816 and{l}\t{%k2, %k0|%k0, %k2}"
7817 [(set_attr "type" "alu")
7818 (set_attr "mode" "QI,QI,SI")])
7819
7820 (define_insn "*andqi_1_slp"
7821 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7822 (and:QI (match_dup 0)
7823 (match_operand:QI 1 "general_operand" "qn,qmn")))
7824 (clobber (reg:CC FLAGS_REG))]
7825 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7826 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7827 "and{b}\t{%1, %0|%0, %1}"
7828 [(set_attr "type" "alu1")
7829 (set_attr "mode" "QI")])
7830
7831 (define_split
7832 [(set (match_operand 0 "register_operand" "")
7833 (and (match_dup 0)
7834 (const_int -65536)))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7837 || optimize_function_for_size_p (cfun)"
7838 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7839 "operands[1] = gen_lowpart (HImode, operands[0]);")
7840
7841 (define_split
7842 [(set (match_operand 0 "ext_register_operand" "")
7843 (and (match_dup 0)
7844 (const_int -256)))
7845 (clobber (reg:CC FLAGS_REG))]
7846 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7847 && reload_completed"
7848 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7849 "operands[1] = gen_lowpart (QImode, operands[0]);")
7850
7851 (define_split
7852 [(set (match_operand 0 "ext_register_operand" "")
7853 (and (match_dup 0)
7854 (const_int -65281)))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7857 && reload_completed"
7858 [(parallel [(set (zero_extract:SI (match_dup 0)
7859 (const_int 8)
7860 (const_int 8))
7861 (xor:SI
7862 (zero_extract:SI (match_dup 0)
7863 (const_int 8)
7864 (const_int 8))
7865 (zero_extract:SI (match_dup 0)
7866 (const_int 8)
7867 (const_int 8))))
7868 (clobber (reg:CC FLAGS_REG))])]
7869 "operands[0] = gen_lowpart (SImode, operands[0]);")
7870
7871 (define_insn "*anddi_2"
7872 [(set (reg FLAGS_REG)
7873 (compare
7874 (and:DI
7875 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7876 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7877 (const_int 0)))
7878 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7879 (and:DI (match_dup 1) (match_dup 2)))]
7880 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7881 && ix86_binary_operator_ok (AND, DImode, operands)"
7882 "@
7883 and{l}\t{%k2, %k0|%k0, %k2}
7884 and{q}\t{%2, %0|%0, %2}
7885 and{q}\t{%2, %0|%0, %2}"
7886 [(set_attr "type" "alu")
7887 (set_attr "mode" "SI,DI,DI")])
7888
7889 (define_insn "*andqi_2_maybe_si"
7890 [(set (reg FLAGS_REG)
7891 (compare (and:QI
7892 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7893 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7894 (const_int 0)))
7895 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7896 (and:QI (match_dup 1) (match_dup 2)))]
7897 "ix86_binary_operator_ok (AND, QImode, operands)
7898 && ix86_match_ccmode (insn,
7899 CONST_INT_P (operands[2])
7900 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7901 {
7902 if (which_alternative == 2)
7903 {
7904 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7905 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7906 return "and{l}\t{%2, %k0|%k0, %2}";
7907 }
7908 return "and{b}\t{%2, %0|%0, %2}";
7909 }
7910 [(set_attr "type" "alu")
7911 (set_attr "mode" "QI,QI,SI")])
7912
7913 (define_insn "*and<mode>_2"
7914 [(set (reg FLAGS_REG)
7915 (compare (and:SWI124
7916 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7917 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7918 (const_int 0)))
7919 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7920 (and:SWI124 (match_dup 1) (match_dup 2)))]
7921 "ix86_match_ccmode (insn, CCNOmode)
7922 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7923 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7924 [(set_attr "type" "alu")
7925 (set_attr "mode" "<MODE>")])
7926
7927 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7928 (define_insn "*andsi_2_zext"
7929 [(set (reg FLAGS_REG)
7930 (compare (and:SI
7931 (match_operand:SI 1 "nonimmediate_operand" "%0")
7932 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7933 (const_int 0)))
7934 (set (match_operand:DI 0 "register_operand" "=r")
7935 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7936 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937 && ix86_binary_operator_ok (AND, SImode, operands)"
7938 "and{l}\t{%2, %k0|%k0, %2}"
7939 [(set_attr "type" "alu")
7940 (set_attr "mode" "SI")])
7941
7942 (define_insn "*andqi_2_slp"
7943 [(set (reg FLAGS_REG)
7944 (compare (and:QI
7945 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7946 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7947 (const_int 0)))
7948 (set (strict_low_part (match_dup 0))
7949 (and:QI (match_dup 0) (match_dup 1)))]
7950 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7951 && ix86_match_ccmode (insn, CCNOmode)
7952 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7953 "and{b}\t{%1, %0|%0, %1}"
7954 [(set_attr "type" "alu1")
7955 (set_attr "mode" "QI")])
7956
7957 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7958 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7959 ;; for a QImode operand, which of course failed.
7960 (define_insn "andqi_ext_0"
7961 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7962 (const_int 8)
7963 (const_int 8))
7964 (and:SI
7965 (zero_extract:SI
7966 (match_operand 1 "ext_register_operand" "0")
7967 (const_int 8)
7968 (const_int 8))
7969 (match_operand 2 "const_int_operand" "n")))
7970 (clobber (reg:CC FLAGS_REG))]
7971 ""
7972 "and{b}\t{%2, %h0|%h0, %2}"
7973 [(set_attr "type" "alu")
7974 (set_attr "length_immediate" "1")
7975 (set_attr "modrm" "1")
7976 (set_attr "mode" "QI")])
7977
7978 ;; Generated by peephole translating test to and. This shows up
7979 ;; often in fp comparisons.
7980 (define_insn "*andqi_ext_0_cc"
7981 [(set (reg FLAGS_REG)
7982 (compare
7983 (and:SI
7984 (zero_extract:SI
7985 (match_operand 1 "ext_register_operand" "0")
7986 (const_int 8)
7987 (const_int 8))
7988 (match_operand 2 "const_int_operand" "n"))
7989 (const_int 0)))
7990 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7991 (const_int 8)
7992 (const_int 8))
7993 (and:SI
7994 (zero_extract:SI
7995 (match_dup 1)
7996 (const_int 8)
7997 (const_int 8))
7998 (match_dup 2)))]
7999 "ix86_match_ccmode (insn, CCNOmode)"
8000 "and{b}\t{%2, %h0|%h0, %2}"
8001 [(set_attr "type" "alu")
8002 (set_attr "length_immediate" "1")
8003 (set_attr "modrm" "1")
8004 (set_attr "mode" "QI")])
8005
8006 (define_insn "*andqi_ext_1_rex64"
8007 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8008 (const_int 8)
8009 (const_int 8))
8010 (and:SI
8011 (zero_extract:SI
8012 (match_operand 1 "ext_register_operand" "0")
8013 (const_int 8)
8014 (const_int 8))
8015 (zero_extend:SI
8016 (match_operand 2 "ext_register_operand" "Q"))))
8017 (clobber (reg:CC FLAGS_REG))]
8018 "TARGET_64BIT"
8019 "and{b}\t{%2, %h0|%h0, %2}"
8020 [(set_attr "type" "alu")
8021 (set_attr "length_immediate" "0")
8022 (set_attr "mode" "QI")])
8023
8024 (define_insn "*andqi_ext_1"
8025 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8026 (const_int 8)
8027 (const_int 8))
8028 (and:SI
8029 (zero_extract:SI
8030 (match_operand 1 "ext_register_operand" "0")
8031 (const_int 8)
8032 (const_int 8))
8033 (zero_extend:SI
8034 (match_operand:QI 2 "general_operand" "Qm"))))
8035 (clobber (reg:CC FLAGS_REG))]
8036 "!TARGET_64BIT"
8037 "and{b}\t{%2, %h0|%h0, %2}"
8038 [(set_attr "type" "alu")
8039 (set_attr "length_immediate" "0")
8040 (set_attr "mode" "QI")])
8041
8042 (define_insn "*andqi_ext_2"
8043 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8044 (const_int 8)
8045 (const_int 8))
8046 (and:SI
8047 (zero_extract:SI
8048 (match_operand 1 "ext_register_operand" "%0")
8049 (const_int 8)
8050 (const_int 8))
8051 (zero_extract:SI
8052 (match_operand 2 "ext_register_operand" "Q")
8053 (const_int 8)
8054 (const_int 8))))
8055 (clobber (reg:CC FLAGS_REG))]
8056 ""
8057 "and{b}\t{%h2, %h0|%h0, %h2}"
8058 [(set_attr "type" "alu")
8059 (set_attr "length_immediate" "0")
8060 (set_attr "mode" "QI")])
8061
8062 ;; Convert wide AND instructions with immediate operand to shorter QImode
8063 ;; equivalents when possible.
8064 ;; Don't do the splitting with memory operands, since it introduces risk
8065 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8066 ;; for size, but that can (should?) be handled by generic code instead.
8067 (define_split
8068 [(set (match_operand 0 "register_operand" "")
8069 (and (match_operand 1 "register_operand" "")
8070 (match_operand 2 "const_int_operand" "")))
8071 (clobber (reg:CC FLAGS_REG))]
8072 "reload_completed
8073 && QI_REG_P (operands[0])
8074 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8075 && !(~INTVAL (operands[2]) & ~(255 << 8))
8076 && GET_MODE (operands[0]) != QImode"
8077 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8078 (and:SI (zero_extract:SI (match_dup 1)
8079 (const_int 8) (const_int 8))
8080 (match_dup 2)))
8081 (clobber (reg:CC FLAGS_REG))])]
8082 {
8083 operands[0] = gen_lowpart (SImode, operands[0]);
8084 operands[1] = gen_lowpart (SImode, operands[1]);
8085 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8086 })
8087
8088 ;; Since AND can be encoded with sign extended immediate, this is only
8089 ;; profitable when 7th bit is not set.
8090 (define_split
8091 [(set (match_operand 0 "register_operand" "")
8092 (and (match_operand 1 "general_operand" "")
8093 (match_operand 2 "const_int_operand" "")))
8094 (clobber (reg:CC FLAGS_REG))]
8095 "reload_completed
8096 && ANY_QI_REG_P (operands[0])
8097 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8098 && !(~INTVAL (operands[2]) & ~255)
8099 && !(INTVAL (operands[2]) & 128)
8100 && GET_MODE (operands[0]) != QImode"
8101 [(parallel [(set (strict_low_part (match_dup 0))
8102 (and:QI (match_dup 1)
8103 (match_dup 2)))
8104 (clobber (reg:CC FLAGS_REG))])]
8105 {
8106 operands[0] = gen_lowpart (QImode, operands[0]);
8107 operands[1] = gen_lowpart (QImode, operands[1]);
8108 operands[2] = gen_lowpart (QImode, operands[2]);
8109 })
8110 \f
8111 ;; Logical inclusive and exclusive OR instructions
8112
8113 ;; %%% This used to optimize known byte-wide and operations to memory.
8114 ;; If this is considered useful, it should be done with splitters.
8115
8116 (define_expand "<code><mode>3"
8117 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8118 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8119 (match_operand:SWIM 2 "<general_operand>" "")))]
8120 ""
8121 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8122
8123 (define_insn "*<code><mode>_1"
8124 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8125 (any_or:SWI248
8126 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8127 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8130 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "<MODE>")])
8133
8134 ;; %%% Potential partial reg stall on alternative 2. What to do?
8135 (define_insn "*<code>qi_1"
8136 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8137 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8138 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8139 (clobber (reg:CC FLAGS_REG))]
8140 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8141 "@
8142 <logic>{b}\t{%2, %0|%0, %2}
8143 <logic>{b}\t{%2, %0|%0, %2}
8144 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8145 [(set_attr "type" "alu")
8146 (set_attr "mode" "QI,QI,SI")])
8147
8148 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8149 (define_insn "*<code>si_1_zext"
8150 [(set (match_operand:DI 0 "register_operand" "=r")
8151 (zero_extend:DI
8152 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8153 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
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>si_1_zext_imm"
8161 [(set (match_operand:DI 0 "register_operand" "=r")
8162 (any_or:DI
8163 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8164 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8165 (clobber (reg:CC FLAGS_REG))]
8166 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8167 "<logic>{l}\t{%2, %k0|%k0, %2}"
8168 [(set_attr "type" "alu")
8169 (set_attr "mode" "SI")])
8170
8171 (define_insn "*<code>qi_1_slp"
8172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8173 (any_or:QI (match_dup 0)
8174 (match_operand:QI 1 "general_operand" "qmn,qn")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8177 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8178 "<logic>{b}\t{%1, %0|%0, %1}"
8179 [(set_attr "type" "alu1")
8180 (set_attr "mode" "QI")])
8181
8182 (define_insn "*<code><mode>_2"
8183 [(set (reg FLAGS_REG)
8184 (compare (any_or:SWI
8185 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8186 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8187 (const_int 0)))
8188 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8189 (any_or:SWI (match_dup 1) (match_dup 2)))]
8190 "ix86_match_ccmode (insn, CCNOmode)
8191 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8192 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "mode" "<MODE>")])
8195
8196 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8197 ;; ??? Special case for immediate operand is missing - it is tricky.
8198 (define_insn "*<code>si_2_zext"
8199 [(set (reg FLAGS_REG)
8200 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8201 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8202 (const_int 0)))
8203 (set (match_operand:DI 0 "register_operand" "=r")
8204 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8205 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8206 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207 "<logic>{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8210
8211 (define_insn "*<code>si_2_zext_imm"
8212 [(set (reg FLAGS_REG)
8213 (compare (any_or:SI
8214 (match_operand:SI 1 "nonimmediate_operand" "%0")
8215 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8216 (const_int 0)))
8217 (set (match_operand:DI 0 "register_operand" "=r")
8218 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8219 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8220 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8221 "<logic>{l}\t{%2, %k0|%k0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "mode" "SI")])
8224
8225 (define_insn "*<code>qi_2_slp"
8226 [(set (reg FLAGS_REG)
8227 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8228 (match_operand:QI 1 "general_operand" "qmn,qn"))
8229 (const_int 0)))
8230 (set (strict_low_part (match_dup 0))
8231 (any_or:QI (match_dup 0) (match_dup 1)))]
8232 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8233 && ix86_match_ccmode (insn, CCNOmode)
8234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8235 "<logic>{b}\t{%1, %0|%0, %1}"
8236 [(set_attr "type" "alu1")
8237 (set_attr "mode" "QI")])
8238
8239 (define_insn "*<code><mode>_3"
8240 [(set (reg FLAGS_REG)
8241 (compare (any_or:SWI
8242 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8243 (match_operand:SWI 2 "<general_operand>" "<g>"))
8244 (const_int 0)))
8245 (clobber (match_scratch:SWI 0 "=<r>"))]
8246 "ix86_match_ccmode (insn, CCNOmode)
8247 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8248 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "<MODE>")])
8251
8252 (define_insn "*<code>qi_ext_0"
8253 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8254 (const_int 8)
8255 (const_int 8))
8256 (any_or:SI
8257 (zero_extract:SI
8258 (match_operand 1 "ext_register_operand" "0")
8259 (const_int 8)
8260 (const_int 8))
8261 (match_operand 2 "const_int_operand" "n")))
8262 (clobber (reg:CC FLAGS_REG))]
8263 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8264 "<logic>{b}\t{%2, %h0|%h0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "length_immediate" "1")
8267 (set_attr "modrm" "1")
8268 (set_attr "mode" "QI")])
8269
8270 (define_insn "*<code>qi_ext_1_rex64"
8271 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272 (const_int 8)
8273 (const_int 8))
8274 (any_or:SI
8275 (zero_extract:SI
8276 (match_operand 1 "ext_register_operand" "0")
8277 (const_int 8)
8278 (const_int 8))
8279 (zero_extend:SI
8280 (match_operand 2 "ext_register_operand" "Q"))))
8281 (clobber (reg:CC FLAGS_REG))]
8282 "TARGET_64BIT
8283 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8284 "<logic>{b}\t{%2, %h0|%h0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "length_immediate" "0")
8287 (set_attr "mode" "QI")])
8288
8289 (define_insn "*<code>qi_ext_1"
8290 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8291 (const_int 8)
8292 (const_int 8))
8293 (any_or:SI
8294 (zero_extract:SI
8295 (match_operand 1 "ext_register_operand" "0")
8296 (const_int 8)
8297 (const_int 8))
8298 (zero_extend:SI
8299 (match_operand:QI 2 "general_operand" "Qm"))))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "!TARGET_64BIT
8302 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8303 "<logic>{b}\t{%2, %h0|%h0, %2}"
8304 [(set_attr "type" "alu")
8305 (set_attr "length_immediate" "0")
8306 (set_attr "mode" "QI")])
8307
8308 (define_insn "*<code>qi_ext_2"
8309 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8310 (const_int 8)
8311 (const_int 8))
8312 (any_or:SI
8313 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8314 (const_int 8)
8315 (const_int 8))
8316 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8317 (const_int 8)
8318 (const_int 8))))
8319 (clobber (reg:CC FLAGS_REG))]
8320 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8321 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8322 [(set_attr "type" "alu")
8323 (set_attr "length_immediate" "0")
8324 (set_attr "mode" "QI")])
8325
8326 (define_split
8327 [(set (match_operand 0 "register_operand" "")
8328 (any_or (match_operand 1 "register_operand" "")
8329 (match_operand 2 "const_int_operand" "")))
8330 (clobber (reg:CC FLAGS_REG))]
8331 "reload_completed
8332 && QI_REG_P (operands[0])
8333 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8334 && !(INTVAL (operands[2]) & ~(255 << 8))
8335 && GET_MODE (operands[0]) != QImode"
8336 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8337 (any_or:SI (zero_extract:SI (match_dup 1)
8338 (const_int 8) (const_int 8))
8339 (match_dup 2)))
8340 (clobber (reg:CC FLAGS_REG))])]
8341 {
8342 operands[0] = gen_lowpart (SImode, operands[0]);
8343 operands[1] = gen_lowpart (SImode, operands[1]);
8344 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8345 })
8346
8347 ;; Since OR can be encoded with sign extended immediate, this is only
8348 ;; profitable when 7th bit is set.
8349 (define_split
8350 [(set (match_operand 0 "register_operand" "")
8351 (any_or (match_operand 1 "general_operand" "")
8352 (match_operand 2 "const_int_operand" "")))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "reload_completed
8355 && ANY_QI_REG_P (operands[0])
8356 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8357 && !(INTVAL (operands[2]) & ~255)
8358 && (INTVAL (operands[2]) & 128)
8359 && GET_MODE (operands[0]) != QImode"
8360 [(parallel [(set (strict_low_part (match_dup 0))
8361 (any_or:QI (match_dup 1)
8362 (match_dup 2)))
8363 (clobber (reg:CC FLAGS_REG))])]
8364 {
8365 operands[0] = gen_lowpart (QImode, operands[0]);
8366 operands[1] = gen_lowpart (QImode, operands[1]);
8367 operands[2] = gen_lowpart (QImode, operands[2]);
8368 })
8369
8370 (define_expand "xorqi_cc_ext_1"
8371 [(parallel [
8372 (set (reg:CCNO FLAGS_REG)
8373 (compare:CCNO
8374 (xor:SI
8375 (zero_extract:SI
8376 (match_operand 1 "ext_register_operand" "")
8377 (const_int 8)
8378 (const_int 8))
8379 (match_operand:QI 2 "general_operand" ""))
8380 (const_int 0)))
8381 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8382 (const_int 8)
8383 (const_int 8))
8384 (xor:SI
8385 (zero_extract:SI
8386 (match_dup 1)
8387 (const_int 8)
8388 (const_int 8))
8389 (match_dup 2)))])])
8390
8391 (define_insn "*xorqi_cc_ext_1_rex64"
8392 [(set (reg FLAGS_REG)
8393 (compare
8394 (xor:SI
8395 (zero_extract:SI
8396 (match_operand 1 "ext_register_operand" "0")
8397 (const_int 8)
8398 (const_int 8))
8399 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8400 (const_int 0)))
8401 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8402 (const_int 8)
8403 (const_int 8))
8404 (xor:SI
8405 (zero_extract:SI
8406 (match_dup 1)
8407 (const_int 8)
8408 (const_int 8))
8409 (match_dup 2)))]
8410 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8411 "xor{b}\t{%2, %h0|%h0, %2}"
8412 [(set_attr "type" "alu")
8413 (set_attr "modrm" "1")
8414 (set_attr "mode" "QI")])
8415
8416 (define_insn "*xorqi_cc_ext_1"
8417 [(set (reg FLAGS_REG)
8418 (compare
8419 (xor:SI
8420 (zero_extract:SI
8421 (match_operand 1 "ext_register_operand" "0")
8422 (const_int 8)
8423 (const_int 8))
8424 (match_operand:QI 2 "general_operand" "qmn"))
8425 (const_int 0)))
8426 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8427 (const_int 8)
8428 (const_int 8))
8429 (xor:SI
8430 (zero_extract:SI
8431 (match_dup 1)
8432 (const_int 8)
8433 (const_int 8))
8434 (match_dup 2)))]
8435 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8436 "xor{b}\t{%2, %h0|%h0, %2}"
8437 [(set_attr "type" "alu")
8438 (set_attr "modrm" "1")
8439 (set_attr "mode" "QI")])
8440 \f
8441 ;; Negation instructions
8442
8443 (define_expand "neg<mode>2"
8444 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8445 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8446 ""
8447 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8448
8449 (define_insn_and_split "*neg<dwi>2_doubleword"
8450 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8451 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8452 (clobber (reg:CC FLAGS_REG))]
8453 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8454 "#"
8455 "reload_completed"
8456 [(parallel
8457 [(set (reg:CCZ FLAGS_REG)
8458 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8459 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8460 (parallel
8461 [(set (match_dup 2)
8462 (plus:DWIH (match_dup 3)
8463 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8464 (const_int 0))))
8465 (clobber (reg:CC FLAGS_REG))])
8466 (parallel
8467 [(set (match_dup 2)
8468 (neg:DWIH (match_dup 2)))
8469 (clobber (reg:CC FLAGS_REG))])]
8470 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8471
8472 (define_insn "*neg<mode>2_1"
8473 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8474 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8475 (clobber (reg:CC FLAGS_REG))]
8476 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8477 "neg{<imodesuffix>}\t%0"
8478 [(set_attr "type" "negnot")
8479 (set_attr "mode" "<MODE>")])
8480
8481 ;; Combine is quite creative about this pattern.
8482 (define_insn "*negsi2_1_zext"
8483 [(set (match_operand:DI 0 "register_operand" "=r")
8484 (lshiftrt:DI
8485 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8486 (const_int 32)))
8487 (const_int 32)))
8488 (clobber (reg:CC FLAGS_REG))]
8489 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8490 "neg{l}\t%k0"
8491 [(set_attr "type" "negnot")
8492 (set_attr "mode" "SI")])
8493
8494 ;; The problem with neg is that it does not perform (compare x 0),
8495 ;; it really performs (compare 0 x), which leaves us with the zero
8496 ;; flag being the only useful item.
8497
8498 (define_insn "*neg<mode>2_cmpz"
8499 [(set (reg:CCZ FLAGS_REG)
8500 (compare:CCZ
8501 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8502 (const_int 0)))
8503 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8504 (neg:SWI (match_dup 1)))]
8505 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8506 "neg{<imodesuffix>}\t%0"
8507 [(set_attr "type" "negnot")
8508 (set_attr "mode" "<MODE>")])
8509
8510 (define_insn "*negsi2_cmpz_zext"
8511 [(set (reg:CCZ FLAGS_REG)
8512 (compare:CCZ
8513 (lshiftrt:DI
8514 (neg:DI (ashift:DI
8515 (match_operand:DI 1 "register_operand" "0")
8516 (const_int 32)))
8517 (const_int 32))
8518 (const_int 0)))
8519 (set (match_operand:DI 0 "register_operand" "=r")
8520 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8521 (const_int 32)))
8522 (const_int 32)))]
8523 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8524 "neg{l}\t%k0"
8525 [(set_attr "type" "negnot")
8526 (set_attr "mode" "SI")])
8527
8528 ;; Changing of sign for FP values is doable using integer unit too.
8529
8530 (define_expand "<code><mode>2"
8531 [(set (match_operand:X87MODEF 0 "register_operand" "")
8532 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8533 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8534 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8535
8536 (define_insn "*absneg<mode>2_mixed"
8537 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8538 (match_operator:MODEF 3 "absneg_operator"
8539 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8540 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8541 (clobber (reg:CC FLAGS_REG))]
8542 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8543 "#")
8544
8545 (define_insn "*absneg<mode>2_sse"
8546 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8547 (match_operator:MODEF 3 "absneg_operator"
8548 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8549 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8550 (clobber (reg:CC FLAGS_REG))]
8551 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8552 "#")
8553
8554 (define_insn "*absneg<mode>2_i387"
8555 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8556 (match_operator:X87MODEF 3 "absneg_operator"
8557 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8558 (use (match_operand 2 "" ""))
8559 (clobber (reg:CC FLAGS_REG))]
8560 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8561 "#")
8562
8563 (define_expand "<code>tf2"
8564 [(set (match_operand:TF 0 "register_operand" "")
8565 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8566 "TARGET_SSE2"
8567 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8568
8569 (define_insn "*absnegtf2_sse"
8570 [(set (match_operand:TF 0 "register_operand" "=x,x")
8571 (match_operator:TF 3 "absneg_operator"
8572 [(match_operand:TF 1 "register_operand" "0,x")]))
8573 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "TARGET_SSE2"
8576 "#")
8577
8578 ;; Splitters for fp abs and neg.
8579
8580 (define_split
8581 [(set (match_operand 0 "fp_register_operand" "")
8582 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8583 (use (match_operand 2 "" ""))
8584 (clobber (reg:CC FLAGS_REG))]
8585 "reload_completed"
8586 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8587
8588 (define_split
8589 [(set (match_operand 0 "register_operand" "")
8590 (match_operator 3 "absneg_operator"
8591 [(match_operand 1 "register_operand" "")]))
8592 (use (match_operand 2 "nonimmediate_operand" ""))
8593 (clobber (reg:CC FLAGS_REG))]
8594 "reload_completed && SSE_REG_P (operands[0])"
8595 [(set (match_dup 0) (match_dup 3))]
8596 {
8597 enum machine_mode mode = GET_MODE (operands[0]);
8598 enum machine_mode vmode = GET_MODE (operands[2]);
8599 rtx tmp;
8600
8601 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8602 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8603 if (operands_match_p (operands[0], operands[2]))
8604 {
8605 tmp = operands[1];
8606 operands[1] = operands[2];
8607 operands[2] = tmp;
8608 }
8609 if (GET_CODE (operands[3]) == ABS)
8610 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8611 else
8612 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8613 operands[3] = tmp;
8614 })
8615
8616 (define_split
8617 [(set (match_operand:SF 0 "register_operand" "")
8618 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8619 (use (match_operand:V4SF 2 "" ""))
8620 (clobber (reg:CC FLAGS_REG))]
8621 "reload_completed"
8622 [(parallel [(set (match_dup 0) (match_dup 1))
8623 (clobber (reg:CC FLAGS_REG))])]
8624 {
8625 rtx tmp;
8626 operands[0] = gen_lowpart (SImode, operands[0]);
8627 if (GET_CODE (operands[1]) == ABS)
8628 {
8629 tmp = gen_int_mode (0x7fffffff, SImode);
8630 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8631 }
8632 else
8633 {
8634 tmp = gen_int_mode (0x80000000, SImode);
8635 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8636 }
8637 operands[1] = tmp;
8638 })
8639
8640 (define_split
8641 [(set (match_operand:DF 0 "register_operand" "")
8642 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8643 (use (match_operand 2 "" ""))
8644 (clobber (reg:CC FLAGS_REG))]
8645 "reload_completed"
8646 [(parallel [(set (match_dup 0) (match_dup 1))
8647 (clobber (reg:CC FLAGS_REG))])]
8648 {
8649 rtx tmp;
8650 if (TARGET_64BIT)
8651 {
8652 tmp = gen_lowpart (DImode, operands[0]);
8653 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8654 operands[0] = tmp;
8655
8656 if (GET_CODE (operands[1]) == ABS)
8657 tmp = const0_rtx;
8658 else
8659 tmp = gen_rtx_NOT (DImode, tmp);
8660 }
8661 else
8662 {
8663 operands[0] = gen_highpart (SImode, operands[0]);
8664 if (GET_CODE (operands[1]) == ABS)
8665 {
8666 tmp = gen_int_mode (0x7fffffff, SImode);
8667 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8668 }
8669 else
8670 {
8671 tmp = gen_int_mode (0x80000000, SImode);
8672 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8673 }
8674 }
8675 operands[1] = tmp;
8676 })
8677
8678 (define_split
8679 [(set (match_operand:XF 0 "register_operand" "")
8680 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8681 (use (match_operand 2 "" ""))
8682 (clobber (reg:CC FLAGS_REG))]
8683 "reload_completed"
8684 [(parallel [(set (match_dup 0) (match_dup 1))
8685 (clobber (reg:CC FLAGS_REG))])]
8686 {
8687 rtx tmp;
8688 operands[0] = gen_rtx_REG (SImode,
8689 true_regnum (operands[0])
8690 + (TARGET_64BIT ? 1 : 2));
8691 if (GET_CODE (operands[1]) == ABS)
8692 {
8693 tmp = GEN_INT (0x7fff);
8694 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8695 }
8696 else
8697 {
8698 tmp = GEN_INT (0x8000);
8699 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8700 }
8701 operands[1] = tmp;
8702 })
8703
8704 ;; Conditionalize these after reload. If they match before reload, we
8705 ;; lose the clobber and ability to use integer instructions.
8706
8707 (define_insn "*<code><mode>2_1"
8708 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8709 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8710 "TARGET_80387
8711 && (reload_completed
8712 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8713 "f<absneg_mnemonic>"
8714 [(set_attr "type" "fsgn")
8715 (set_attr "mode" "<MODE>")])
8716
8717 (define_insn "*<code>extendsfdf2"
8718 [(set (match_operand:DF 0 "register_operand" "=f")
8719 (absneg:DF (float_extend:DF
8720 (match_operand:SF 1 "register_operand" "0"))))]
8721 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8722 "f<absneg_mnemonic>"
8723 [(set_attr "type" "fsgn")
8724 (set_attr "mode" "DF")])
8725
8726 (define_insn "*<code>extendsfxf2"
8727 [(set (match_operand:XF 0 "register_operand" "=f")
8728 (absneg:XF (float_extend:XF
8729 (match_operand:SF 1 "register_operand" "0"))))]
8730 "TARGET_80387"
8731 "f<absneg_mnemonic>"
8732 [(set_attr "type" "fsgn")
8733 (set_attr "mode" "XF")])
8734
8735 (define_insn "*<code>extenddfxf2"
8736 [(set (match_operand:XF 0 "register_operand" "=f")
8737 (absneg:XF (float_extend:XF
8738 (match_operand:DF 1 "register_operand" "0"))))]
8739 "TARGET_80387"
8740 "f<absneg_mnemonic>"
8741 [(set_attr "type" "fsgn")
8742 (set_attr "mode" "XF")])
8743
8744 ;; Copysign instructions
8745
8746 (define_mode_iterator CSGNMODE [SF DF TF])
8747 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8748
8749 (define_expand "copysign<mode>3"
8750 [(match_operand:CSGNMODE 0 "register_operand" "")
8751 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8752 (match_operand:CSGNMODE 2 "register_operand" "")]
8753 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8754 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8755 "ix86_expand_copysign (operands); DONE;")
8756
8757 (define_insn_and_split "copysign<mode>3_const"
8758 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8759 (unspec:CSGNMODE
8760 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8761 (match_operand:CSGNMODE 2 "register_operand" "0")
8762 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8763 UNSPEC_COPYSIGN))]
8764 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8765 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8766 "#"
8767 "&& reload_completed"
8768 [(const_int 0)]
8769 "ix86_split_copysign_const (operands); DONE;")
8770
8771 (define_insn "copysign<mode>3_var"
8772 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8773 (unspec:CSGNMODE
8774 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8775 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8776 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8777 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8778 UNSPEC_COPYSIGN))
8779 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8780 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8781 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8782 "#")
8783
8784 (define_split
8785 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8786 (unspec:CSGNMODE
8787 [(match_operand:CSGNMODE 2 "register_operand" "")
8788 (match_operand:CSGNMODE 3 "register_operand" "")
8789 (match_operand:<CSGNVMODE> 4 "" "")
8790 (match_operand:<CSGNVMODE> 5 "" "")]
8791 UNSPEC_COPYSIGN))
8792 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8793 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8794 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8795 && reload_completed"
8796 [(const_int 0)]
8797 "ix86_split_copysign_var (operands); DONE;")
8798 \f
8799 ;; One complement instructions
8800
8801 (define_expand "one_cmpl<mode>2"
8802 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8803 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8804 ""
8805 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8806
8807 (define_insn "*one_cmpl<mode>2_1"
8808 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8809 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8810 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8811 "not{<imodesuffix>}\t%0"
8812 [(set_attr "type" "negnot")
8813 (set_attr "mode" "<MODE>")])
8814
8815 ;; %%% Potential partial reg stall on alternative 1. What to do?
8816 (define_insn "*one_cmplqi2_1"
8817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8818 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8819 "ix86_unary_operator_ok (NOT, QImode, operands)"
8820 "@
8821 not{b}\t%0
8822 not{l}\t%k0"
8823 [(set_attr "type" "negnot")
8824 (set_attr "mode" "QI,SI")])
8825
8826 ;; ??? Currently never generated - xor is used instead.
8827 (define_insn "*one_cmplsi2_1_zext"
8828 [(set (match_operand:DI 0 "register_operand" "=r")
8829 (zero_extend:DI
8830 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8831 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8832 "not{l}\t%k0"
8833 [(set_attr "type" "negnot")
8834 (set_attr "mode" "SI")])
8835
8836 (define_insn "*one_cmpl<mode>2_2"
8837 [(set (reg FLAGS_REG)
8838 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8839 (const_int 0)))
8840 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8841 (not:SWI (match_dup 1)))]
8842 "ix86_match_ccmode (insn, CCNOmode)
8843 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8844 "#"
8845 [(set_attr "type" "alu1")
8846 (set_attr "mode" "<MODE>")])
8847
8848 (define_split
8849 [(set (match_operand 0 "flags_reg_operand" "")
8850 (match_operator 2 "compare_operator"
8851 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8852 (const_int 0)]))
8853 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8854 (not:SWI (match_dup 3)))]
8855 "ix86_match_ccmode (insn, CCNOmode)"
8856 [(parallel [(set (match_dup 0)
8857 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8858 (const_int 0)]))
8859 (set (match_dup 1)
8860 (xor:SWI (match_dup 3) (const_int -1)))])])
8861
8862 ;; ??? Currently never generated - xor is used instead.
8863 (define_insn "*one_cmplsi2_2_zext"
8864 [(set (reg FLAGS_REG)
8865 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8866 (const_int 0)))
8867 (set (match_operand:DI 0 "register_operand" "=r")
8868 (zero_extend:DI (not:SI (match_dup 1))))]
8869 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8870 && ix86_unary_operator_ok (NOT, SImode, operands)"
8871 "#"
8872 [(set_attr "type" "alu1")
8873 (set_attr "mode" "SI")])
8874
8875 (define_split
8876 [(set (match_operand 0 "flags_reg_operand" "")
8877 (match_operator 2 "compare_operator"
8878 [(not:SI (match_operand:SI 3 "register_operand" ""))
8879 (const_int 0)]))
8880 (set (match_operand:DI 1 "register_operand" "")
8881 (zero_extend:DI (not:SI (match_dup 3))))]
8882 "ix86_match_ccmode (insn, CCNOmode)"
8883 [(parallel [(set (match_dup 0)
8884 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8885 (const_int 0)]))
8886 (set (match_dup 1)
8887 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8888 \f
8889 ;; Shift instructions
8890
8891 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8892 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8893 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8894 ;; from the assembler input.
8895 ;;
8896 ;; This instruction shifts the target reg/mem as usual, but instead of
8897 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8898 ;; is a left shift double, bits are taken from the high order bits of
8899 ;; reg, else if the insn is a shift right double, bits are taken from the
8900 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8901 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8902 ;;
8903 ;; Since sh[lr]d does not change the `reg' operand, that is done
8904 ;; separately, making all shifts emit pairs of shift double and normal
8905 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8906 ;; support a 63 bit shift, each shift where the count is in a reg expands
8907 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8908 ;;
8909 ;; If the shift count is a constant, we need never emit more than one
8910 ;; shift pair, instead using moves and sign extension for counts greater
8911 ;; than 31.
8912
8913 (define_expand "ashl<mode>3"
8914 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8915 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8916 (match_operand:QI 2 "nonmemory_operand" "")))]
8917 ""
8918 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8919
8920 (define_insn "*ashl<mode>3_doubleword"
8921 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8922 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8923 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8924 (clobber (reg:CC FLAGS_REG))]
8925 ""
8926 "#"
8927 [(set_attr "type" "multi")])
8928
8929 (define_split
8930 [(set (match_operand:DWI 0 "register_operand" "")
8931 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8932 (match_operand:QI 2 "nonmemory_operand" "")))
8933 (clobber (reg:CC FLAGS_REG))]
8934 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8935 [(const_int 0)]
8936 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8937
8938 ;; By default we don't ask for a scratch register, because when DWImode
8939 ;; values are manipulated, registers are already at a premium. But if
8940 ;; we have one handy, we won't turn it away.
8941
8942 (define_peephole2
8943 [(match_scratch:DWIH 3 "r")
8944 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8945 (ashift:<DWI>
8946 (match_operand:<DWI> 1 "nonmemory_operand" "")
8947 (match_operand:QI 2 "nonmemory_operand" "")))
8948 (clobber (reg:CC FLAGS_REG))])
8949 (match_dup 3)]
8950 "TARGET_CMOVE"
8951 [(const_int 0)]
8952 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8953
8954 (define_insn "x86_64_shld"
8955 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8956 (ior:DI (ashift:DI (match_dup 0)
8957 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8958 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8959 (minus:QI (const_int 64) (match_dup 2)))))
8960 (clobber (reg:CC FLAGS_REG))]
8961 "TARGET_64BIT"
8962 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8963 [(set_attr "type" "ishift")
8964 (set_attr "prefix_0f" "1")
8965 (set_attr "mode" "DI")
8966 (set_attr "athlon_decode" "vector")
8967 (set_attr "amdfam10_decode" "vector")
8968 (set_attr "bdver1_decode" "vector")])
8969
8970 (define_insn "x86_shld"
8971 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8972 (ior:SI (ashift:SI (match_dup 0)
8973 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8974 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8975 (minus:QI (const_int 32) (match_dup 2)))))
8976 (clobber (reg:CC FLAGS_REG))]
8977 ""
8978 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8979 [(set_attr "type" "ishift")
8980 (set_attr "prefix_0f" "1")
8981 (set_attr "mode" "SI")
8982 (set_attr "pent_pair" "np")
8983 (set_attr "athlon_decode" "vector")
8984 (set_attr "amdfam10_decode" "vector")
8985 (set_attr "bdver1_decode" "vector")])
8986
8987 (define_expand "x86_shift<mode>_adj_1"
8988 [(set (reg:CCZ FLAGS_REG)
8989 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8990 (match_dup 4))
8991 (const_int 0)))
8992 (set (match_operand:SWI48 0 "register_operand" "")
8993 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8994 (match_operand:SWI48 1 "register_operand" "")
8995 (match_dup 0)))
8996 (set (match_dup 1)
8997 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8998 (match_operand:SWI48 3 "register_operand" "r")
8999 (match_dup 1)))]
9000 "TARGET_CMOVE"
9001 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9002
9003 (define_expand "x86_shift<mode>_adj_2"
9004 [(use (match_operand:SWI48 0 "register_operand" ""))
9005 (use (match_operand:SWI48 1 "register_operand" ""))
9006 (use (match_operand:QI 2 "register_operand" ""))]
9007 ""
9008 {
9009 rtx label = gen_label_rtx ();
9010 rtx tmp;
9011
9012 emit_insn (gen_testqi_ccz_1 (operands[2],
9013 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9014
9015 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9016 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9017 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9018 gen_rtx_LABEL_REF (VOIDmode, label),
9019 pc_rtx);
9020 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9021 JUMP_LABEL (tmp) = label;
9022
9023 emit_move_insn (operands[0], operands[1]);
9024 ix86_expand_clear (operands[1]);
9025
9026 emit_label (label);
9027 LABEL_NUSES (label) = 1;
9028
9029 DONE;
9030 })
9031
9032 ;; Avoid useless masking of count operand.
9033 (define_insn_and_split "*ashl<mode>3_mask"
9034 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9035 (ashift:SWI48
9036 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9037 (subreg:QI
9038 (and:SI
9039 (match_operand:SI 2 "nonimmediate_operand" "c")
9040 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9041 (clobber (reg:CC FLAGS_REG))]
9042 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9043 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9044 == GET_MODE_BITSIZE (<MODE>mode)-1"
9045 "#"
9046 "&& 1"
9047 [(parallel [(set (match_dup 0)
9048 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9049 (clobber (reg:CC FLAGS_REG))])]
9050 {
9051 if (can_create_pseudo_p ())
9052 operands [2] = force_reg (SImode, operands[2]);
9053
9054 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9055 }
9056 [(set_attr "type" "ishift")
9057 (set_attr "mode" "<MODE>")])
9058
9059 (define_insn "*bmi2_ashl<mode>3_1"
9060 [(set (match_operand:SWI48 0 "register_operand" "=r")
9061 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9062 (match_operand:SWI48 2 "register_operand" "r")))]
9063 "TARGET_BMI2"
9064 "shlx\t{%2, %1, %0|%0, %1, %2}"
9065 [(set_attr "type" "ishiftx")
9066 (set_attr "mode" "<MODE>")])
9067
9068 (define_insn "*ashl<mode>3_1"
9069 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9070 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9071 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9072 (clobber (reg:CC FLAGS_REG))]
9073 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9074 {
9075 switch (get_attr_type (insn))
9076 {
9077 case TYPE_LEA:
9078 case TYPE_ISHIFTX:
9079 return "#";
9080
9081 case TYPE_ALU:
9082 gcc_assert (operands[2] == const1_rtx);
9083 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9084 return "add{<imodesuffix>}\t%0, %0";
9085
9086 default:
9087 if (operands[2] == const1_rtx
9088 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9089 return "sal{<imodesuffix>}\t%0";
9090 else
9091 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9092 }
9093 }
9094 [(set_attr "isa" "*,*,bmi2")
9095 (set (attr "type")
9096 (cond [(eq_attr "alternative" "1")
9097 (const_string "lea")
9098 (eq_attr "alternative" "2")
9099 (const_string "ishiftx")
9100 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9101 (match_operand 0 "register_operand" ""))
9102 (match_operand 2 "const1_operand" ""))
9103 (const_string "alu")
9104 ]
9105 (const_string "ishift")))
9106 (set (attr "length_immediate")
9107 (if_then_else
9108 (ior (eq_attr "type" "alu")
9109 (and (eq_attr "type" "ishift")
9110 (and (match_operand 2 "const1_operand" "")
9111 (ior (match_test "TARGET_SHIFT1")
9112 (match_test "optimize_function_for_size_p (cfun)")))))
9113 (const_string "0")
9114 (const_string "*")))
9115 (set_attr "mode" "<MODE>")])
9116
9117 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9118 (define_split
9119 [(set (match_operand:SWI48 0 "register_operand" "")
9120 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9121 (match_operand:QI 2 "register_operand" "")))
9122 (clobber (reg:CC FLAGS_REG))]
9123 "TARGET_BMI2 && reload_completed"
9124 [(set (match_dup 0)
9125 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9126 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9127
9128 (define_insn "*bmi2_ashlsi3_1_zext"
9129 [(set (match_operand:DI 0 "register_operand" "=r")
9130 (zero_extend:DI
9131 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9132 (match_operand:SI 2 "register_operand" "r"))))]
9133 "TARGET_64BIT && TARGET_BMI2"
9134 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9135 [(set_attr "type" "ishiftx")
9136 (set_attr "mode" "SI")])
9137
9138 (define_insn "*ashlsi3_1_zext"
9139 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9140 (zero_extend:DI
9141 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9142 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9143 (clobber (reg:CC FLAGS_REG))]
9144 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9145 {
9146 switch (get_attr_type (insn))
9147 {
9148 case TYPE_LEA:
9149 case TYPE_ISHIFTX:
9150 return "#";
9151
9152 case TYPE_ALU:
9153 gcc_assert (operands[2] == const1_rtx);
9154 return "add{l}\t%k0, %k0";
9155
9156 default:
9157 if (operands[2] == const1_rtx
9158 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9159 return "sal{l}\t%k0";
9160 else
9161 return "sal{l}\t{%2, %k0|%k0, %2}";
9162 }
9163 }
9164 [(set_attr "isa" "*,*,bmi2")
9165 (set (attr "type")
9166 (cond [(eq_attr "alternative" "1")
9167 (const_string "lea")
9168 (eq_attr "alternative" "2")
9169 (const_string "ishiftx")
9170 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9171 (match_operand 2 "const1_operand" ""))
9172 (const_string "alu")
9173 ]
9174 (const_string "ishift")))
9175 (set (attr "length_immediate")
9176 (if_then_else
9177 (ior (eq_attr "type" "alu")
9178 (and (eq_attr "type" "ishift")
9179 (and (match_operand 2 "const1_operand" "")
9180 (ior (match_test "TARGET_SHIFT1")
9181 (match_test "optimize_function_for_size_p (cfun)")))))
9182 (const_string "0")
9183 (const_string "*")))
9184 (set_attr "mode" "SI")])
9185
9186 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9187 (define_split
9188 [(set (match_operand:DI 0 "register_operand" "")
9189 (zero_extend:DI
9190 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9191 (match_operand:QI 2 "register_operand" ""))))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9194 [(set (match_dup 0)
9195 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9196 "operands[2] = gen_lowpart (SImode, operands[2]);")
9197
9198 (define_insn "*ashlhi3_1"
9199 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9200 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9201 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9204 {
9205 switch (get_attr_type (insn))
9206 {
9207 case TYPE_LEA:
9208 return "#";
9209
9210 case TYPE_ALU:
9211 gcc_assert (operands[2] == const1_rtx);
9212 return "add{w}\t%0, %0";
9213
9214 default:
9215 if (operands[2] == const1_rtx
9216 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9217 return "sal{w}\t%0";
9218 else
9219 return "sal{w}\t{%2, %0|%0, %2}";
9220 }
9221 }
9222 [(set (attr "type")
9223 (cond [(eq_attr "alternative" "1")
9224 (const_string "lea")
9225 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9226 (match_operand 0 "register_operand" ""))
9227 (match_operand 2 "const1_operand" ""))
9228 (const_string "alu")
9229 ]
9230 (const_string "ishift")))
9231 (set (attr "length_immediate")
9232 (if_then_else
9233 (ior (eq_attr "type" "alu")
9234 (and (eq_attr "type" "ishift")
9235 (and (match_operand 2 "const1_operand" "")
9236 (ior (match_test "TARGET_SHIFT1")
9237 (match_test "optimize_function_for_size_p (cfun)")))))
9238 (const_string "0")
9239 (const_string "*")))
9240 (set_attr "mode" "HI,SI")])
9241
9242 ;; %%% Potential partial reg stall on alternative 1. What to do?
9243 (define_insn "*ashlqi3_1"
9244 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9245 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9246 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9247 (clobber (reg:CC FLAGS_REG))]
9248 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9249 {
9250 switch (get_attr_type (insn))
9251 {
9252 case TYPE_LEA:
9253 return "#";
9254
9255 case TYPE_ALU:
9256 gcc_assert (operands[2] == const1_rtx);
9257 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9258 return "add{l}\t%k0, %k0";
9259 else
9260 return "add{b}\t%0, %0";
9261
9262 default:
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 {
9266 if (get_attr_mode (insn) == MODE_SI)
9267 return "sal{l}\t%k0";
9268 else
9269 return "sal{b}\t%0";
9270 }
9271 else
9272 {
9273 if (get_attr_mode (insn) == MODE_SI)
9274 return "sal{l}\t{%2, %k0|%k0, %2}";
9275 else
9276 return "sal{b}\t{%2, %0|%0, %2}";
9277 }
9278 }
9279 }
9280 [(set (attr "type")
9281 (cond [(eq_attr "alternative" "2")
9282 (const_string "lea")
9283 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9284 (match_operand 0 "register_operand" ""))
9285 (match_operand 2 "const1_operand" ""))
9286 (const_string "alu")
9287 ]
9288 (const_string "ishift")))
9289 (set (attr "length_immediate")
9290 (if_then_else
9291 (ior (eq_attr "type" "alu")
9292 (and (eq_attr "type" "ishift")
9293 (and (match_operand 2 "const1_operand" "")
9294 (ior (match_test "TARGET_SHIFT1")
9295 (match_test "optimize_function_for_size_p (cfun)")))))
9296 (const_string "0")
9297 (const_string "*")))
9298 (set_attr "mode" "QI,SI,SI")])
9299
9300 (define_insn "*ashlqi3_1_slp"
9301 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9302 (ashift:QI (match_dup 0)
9303 (match_operand:QI 1 "nonmemory_operand" "cI")))
9304 (clobber (reg:CC FLAGS_REG))]
9305 "(optimize_function_for_size_p (cfun)
9306 || !TARGET_PARTIAL_FLAG_REG_STALL
9307 || (operands[1] == const1_rtx
9308 && (TARGET_SHIFT1
9309 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9310 {
9311 switch (get_attr_type (insn))
9312 {
9313 case TYPE_ALU:
9314 gcc_assert (operands[1] == const1_rtx);
9315 return "add{b}\t%0, %0";
9316
9317 default:
9318 if (operands[1] == const1_rtx
9319 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9320 return "sal{b}\t%0";
9321 else
9322 return "sal{b}\t{%1, %0|%0, %1}";
9323 }
9324 }
9325 [(set (attr "type")
9326 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9327 (match_operand 0 "register_operand" ""))
9328 (match_operand 1 "const1_operand" ""))
9329 (const_string "alu")
9330 ]
9331 (const_string "ishift1")))
9332 (set (attr "length_immediate")
9333 (if_then_else
9334 (ior (eq_attr "type" "alu")
9335 (and (eq_attr "type" "ishift1")
9336 (and (match_operand 1 "const1_operand" "")
9337 (ior (match_test "TARGET_SHIFT1")
9338 (match_test "optimize_function_for_size_p (cfun)")))))
9339 (const_string "0")
9340 (const_string "*")))
9341 (set_attr "mode" "QI")])
9342
9343 ;; Convert ashift to the lea pattern to avoid flags dependency.
9344 (define_split
9345 [(set (match_operand 0 "register_operand" "")
9346 (ashift (match_operand 1 "index_register_operand" "")
9347 (match_operand:QI 2 "const_int_operand" "")))
9348 (clobber (reg:CC FLAGS_REG))]
9349 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9350 && reload_completed
9351 && true_regnum (operands[0]) != true_regnum (operands[1])"
9352 [(const_int 0)]
9353 {
9354 enum machine_mode mode = GET_MODE (operands[0]);
9355 rtx pat;
9356
9357 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9358 {
9359 mode = SImode;
9360 operands[0] = gen_lowpart (mode, operands[0]);
9361 operands[1] = gen_lowpart (mode, operands[1]);
9362 }
9363
9364 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9365
9366 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9367
9368 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9369 DONE;
9370 })
9371
9372 ;; Convert ashift to the lea pattern to avoid flags dependency.
9373 (define_split
9374 [(set (match_operand:DI 0 "register_operand" "")
9375 (zero_extend:DI
9376 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9377 (match_operand:QI 2 "const_int_operand" ""))))
9378 (clobber (reg:CC FLAGS_REG))]
9379 "TARGET_64BIT && reload_completed
9380 && true_regnum (operands[0]) != true_regnum (operands[1])"
9381 [(set (match_dup 0)
9382 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9383 {
9384 operands[1] = gen_lowpart (DImode, operands[1]);
9385 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9386 })
9387
9388 ;; This pattern can't accept a variable shift count, since shifts by
9389 ;; zero don't affect the flags. We assume that shifts by constant
9390 ;; zero are optimized away.
9391 (define_insn "*ashl<mode>3_cmp"
9392 [(set (reg FLAGS_REG)
9393 (compare
9394 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9395 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9396 (const_int 0)))
9397 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9398 (ashift:SWI (match_dup 1) (match_dup 2)))]
9399 "(optimize_function_for_size_p (cfun)
9400 || !TARGET_PARTIAL_FLAG_REG_STALL
9401 || (operands[2] == const1_rtx
9402 && (TARGET_SHIFT1
9403 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9404 && ix86_match_ccmode (insn, CCGOCmode)
9405 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9406 {
9407 switch (get_attr_type (insn))
9408 {
9409 case TYPE_ALU:
9410 gcc_assert (operands[2] == const1_rtx);
9411 return "add{<imodesuffix>}\t%0, %0";
9412
9413 default:
9414 if (operands[2] == const1_rtx
9415 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9416 return "sal{<imodesuffix>}\t%0";
9417 else
9418 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9419 }
9420 }
9421 [(set (attr "type")
9422 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9423 (match_operand 0 "register_operand" ""))
9424 (match_operand 2 "const1_operand" ""))
9425 (const_string "alu")
9426 ]
9427 (const_string "ishift")))
9428 (set (attr "length_immediate")
9429 (if_then_else
9430 (ior (eq_attr "type" "alu")
9431 (and (eq_attr "type" "ishift")
9432 (and (match_operand 2 "const1_operand" "")
9433 (ior (match_test "TARGET_SHIFT1")
9434 (match_test "optimize_function_for_size_p (cfun)")))))
9435 (const_string "0")
9436 (const_string "*")))
9437 (set_attr "mode" "<MODE>")])
9438
9439 (define_insn "*ashlsi3_cmp_zext"
9440 [(set (reg FLAGS_REG)
9441 (compare
9442 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9443 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9444 (const_int 0)))
9445 (set (match_operand:DI 0 "register_operand" "=r")
9446 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9447 "TARGET_64BIT
9448 && (optimize_function_for_size_p (cfun)
9449 || !TARGET_PARTIAL_FLAG_REG_STALL
9450 || (operands[2] == const1_rtx
9451 && (TARGET_SHIFT1
9452 || TARGET_DOUBLE_WITH_ADD)))
9453 && ix86_match_ccmode (insn, CCGOCmode)
9454 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9455 {
9456 switch (get_attr_type (insn))
9457 {
9458 case TYPE_ALU:
9459 gcc_assert (operands[2] == const1_rtx);
9460 return "add{l}\t%k0, %k0";
9461
9462 default:
9463 if (operands[2] == const1_rtx
9464 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465 return "sal{l}\t%k0";
9466 else
9467 return "sal{l}\t{%2, %k0|%k0, %2}";
9468 }
9469 }
9470 [(set (attr "type")
9471 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9474 ]
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9477 (if_then_else
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ior (match_test "TARGET_SHIFT1")
9482 (match_test "optimize_function_for_size_p (cfun)")))))
9483 (const_string "0")
9484 (const_string "*")))
9485 (set_attr "mode" "SI")])
9486
9487 (define_insn "*ashl<mode>3_cconly"
9488 [(set (reg FLAGS_REG)
9489 (compare
9490 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9491 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9492 (const_int 0)))
9493 (clobber (match_scratch:SWI 0 "=<r>"))]
9494 "(optimize_function_for_size_p (cfun)
9495 || !TARGET_PARTIAL_FLAG_REG_STALL
9496 || (operands[2] == const1_rtx
9497 && (TARGET_SHIFT1
9498 || TARGET_DOUBLE_WITH_ADD)))
9499 && ix86_match_ccmode (insn, CCGOCmode)"
9500 {
9501 switch (get_attr_type (insn))
9502 {
9503 case TYPE_ALU:
9504 gcc_assert (operands[2] == const1_rtx);
9505 return "add{<imodesuffix>}\t%0, %0";
9506
9507 default:
9508 if (operands[2] == const1_rtx
9509 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9510 return "sal{<imodesuffix>}\t%0";
9511 else
9512 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9513 }
9514 }
9515 [(set (attr "type")
9516 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9517 (match_operand 0 "register_operand" ""))
9518 (match_operand 2 "const1_operand" ""))
9519 (const_string "alu")
9520 ]
9521 (const_string "ishift")))
9522 (set (attr "length_immediate")
9523 (if_then_else
9524 (ior (eq_attr "type" "alu")
9525 (and (eq_attr "type" "ishift")
9526 (and (match_operand 2 "const1_operand" "")
9527 (ior (match_test "TARGET_SHIFT1")
9528 (match_test "optimize_function_for_size_p (cfun)")))))
9529 (const_string "0")
9530 (const_string "*")))
9531 (set_attr "mode" "<MODE>")])
9532
9533 ;; See comment above `ashl<mode>3' about how this works.
9534
9535 (define_expand "<shift_insn><mode>3"
9536 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9537 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9538 (match_operand:QI 2 "nonmemory_operand" "")))]
9539 ""
9540 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9541
9542 ;; Avoid useless masking of count operand.
9543 (define_insn_and_split "*<shift_insn><mode>3_mask"
9544 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9545 (any_shiftrt:SWI48
9546 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9547 (subreg:QI
9548 (and:SI
9549 (match_operand:SI 2 "nonimmediate_operand" "c")
9550 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9551 (clobber (reg:CC FLAGS_REG))]
9552 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9553 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9554 == GET_MODE_BITSIZE (<MODE>mode)-1"
9555 "#"
9556 "&& 1"
9557 [(parallel [(set (match_dup 0)
9558 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9559 (clobber (reg:CC FLAGS_REG))])]
9560 {
9561 if (can_create_pseudo_p ())
9562 operands [2] = force_reg (SImode, operands[2]);
9563
9564 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9565 }
9566 [(set_attr "type" "ishift")
9567 (set_attr "mode" "<MODE>")])
9568
9569 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9570 [(set (match_operand:DWI 0 "register_operand" "=r")
9571 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9572 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9573 (clobber (reg:CC FLAGS_REG))]
9574 ""
9575 "#"
9576 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9577 [(const_int 0)]
9578 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9579 [(set_attr "type" "multi")])
9580
9581 ;; By default we don't ask for a scratch register, because when DWImode
9582 ;; values are manipulated, registers are already at a premium. But if
9583 ;; we have one handy, we won't turn it away.
9584
9585 (define_peephole2
9586 [(match_scratch:DWIH 3 "r")
9587 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9588 (any_shiftrt:<DWI>
9589 (match_operand:<DWI> 1 "register_operand" "")
9590 (match_operand:QI 2 "nonmemory_operand" "")))
9591 (clobber (reg:CC FLAGS_REG))])
9592 (match_dup 3)]
9593 "TARGET_CMOVE"
9594 [(const_int 0)]
9595 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9596
9597 (define_insn "x86_64_shrd"
9598 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9599 (ior:DI (ashiftrt:DI (match_dup 0)
9600 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9601 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9602 (minus:QI (const_int 64) (match_dup 2)))))
9603 (clobber (reg:CC FLAGS_REG))]
9604 "TARGET_64BIT"
9605 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9606 [(set_attr "type" "ishift")
9607 (set_attr "prefix_0f" "1")
9608 (set_attr "mode" "DI")
9609 (set_attr "athlon_decode" "vector")
9610 (set_attr "amdfam10_decode" "vector")
9611 (set_attr "bdver1_decode" "vector")])
9612
9613 (define_insn "x86_shrd"
9614 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9615 (ior:SI (ashiftrt:SI (match_dup 0)
9616 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9617 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9618 (minus:QI (const_int 32) (match_dup 2)))))
9619 (clobber (reg:CC FLAGS_REG))]
9620 ""
9621 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9622 [(set_attr "type" "ishift")
9623 (set_attr "prefix_0f" "1")
9624 (set_attr "mode" "SI")
9625 (set_attr "pent_pair" "np")
9626 (set_attr "athlon_decode" "vector")
9627 (set_attr "amdfam10_decode" "vector")
9628 (set_attr "bdver1_decode" "vector")])
9629
9630 (define_insn "ashrdi3_cvt"
9631 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9632 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9633 (match_operand:QI 2 "const_int_operand" "")))
9634 (clobber (reg:CC FLAGS_REG))]
9635 "TARGET_64BIT && INTVAL (operands[2]) == 63
9636 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9637 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9638 "@
9639 {cqto|cqo}
9640 sar{q}\t{%2, %0|%0, %2}"
9641 [(set_attr "type" "imovx,ishift")
9642 (set_attr "prefix_0f" "0,*")
9643 (set_attr "length_immediate" "0,*")
9644 (set_attr "modrm" "0,1")
9645 (set_attr "mode" "DI")])
9646
9647 (define_insn "ashrsi3_cvt"
9648 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9649 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9650 (match_operand:QI 2 "const_int_operand" "")))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "INTVAL (operands[2]) == 31
9653 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9654 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9655 "@
9656 {cltd|cdq}
9657 sar{l}\t{%2, %0|%0, %2}"
9658 [(set_attr "type" "imovx,ishift")
9659 (set_attr "prefix_0f" "0,*")
9660 (set_attr "length_immediate" "0,*")
9661 (set_attr "modrm" "0,1")
9662 (set_attr "mode" "SI")])
9663
9664 (define_insn "*ashrsi3_cvt_zext"
9665 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9666 (zero_extend:DI
9667 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9668 (match_operand:QI 2 "const_int_operand" ""))))
9669 (clobber (reg:CC FLAGS_REG))]
9670 "TARGET_64BIT && INTVAL (operands[2]) == 31
9671 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9672 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9673 "@
9674 {cltd|cdq}
9675 sar{l}\t{%2, %k0|%k0, %2}"
9676 [(set_attr "type" "imovx,ishift")
9677 (set_attr "prefix_0f" "0,*")
9678 (set_attr "length_immediate" "0,*")
9679 (set_attr "modrm" "0,1")
9680 (set_attr "mode" "SI")])
9681
9682 (define_expand "x86_shift<mode>_adj_3"
9683 [(use (match_operand:SWI48 0 "register_operand" ""))
9684 (use (match_operand:SWI48 1 "register_operand" ""))
9685 (use (match_operand:QI 2 "register_operand" ""))]
9686 ""
9687 {
9688 rtx label = gen_label_rtx ();
9689 rtx tmp;
9690
9691 emit_insn (gen_testqi_ccz_1 (operands[2],
9692 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9693
9694 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9695 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9696 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9697 gen_rtx_LABEL_REF (VOIDmode, label),
9698 pc_rtx);
9699 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9700 JUMP_LABEL (tmp) = label;
9701
9702 emit_move_insn (operands[0], operands[1]);
9703 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9704 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9705 emit_label (label);
9706 LABEL_NUSES (label) = 1;
9707
9708 DONE;
9709 })
9710
9711 (define_insn "*bmi2_<shift_insn><mode>3_1"
9712 [(set (match_operand:SWI48 0 "register_operand" "=r")
9713 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9714 (match_operand:SWI48 2 "register_operand" "r")))]
9715 "TARGET_BMI2"
9716 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9717 [(set_attr "type" "ishiftx")
9718 (set_attr "mode" "<MODE>")])
9719
9720 (define_insn "*<shift_insn><mode>3_1"
9721 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9722 (any_shiftrt:SWI48
9723 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9724 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9727 {
9728 switch (get_attr_type (insn))
9729 {
9730 case TYPE_ISHIFTX:
9731 return "#";
9732
9733 default:
9734 if (operands[2] == const1_rtx
9735 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9736 return "<shift>{<imodesuffix>}\t%0";
9737 else
9738 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9739 }
9740 }
9741 [(set_attr "isa" "*,bmi2")
9742 (set_attr "type" "ishift,ishiftx")
9743 (set (attr "length_immediate")
9744 (if_then_else
9745 (and (match_operand 2 "const1_operand" "")
9746 (ior (match_test "TARGET_SHIFT1")
9747 (match_test "optimize_function_for_size_p (cfun)")))
9748 (const_string "0")
9749 (const_string "*")))
9750 (set_attr "mode" "<MODE>")])
9751
9752 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9753 (define_split
9754 [(set (match_operand:SWI48 0 "register_operand" "")
9755 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9756 (match_operand:QI 2 "register_operand" "")))
9757 (clobber (reg:CC FLAGS_REG))]
9758 "TARGET_BMI2 && reload_completed"
9759 [(set (match_dup 0)
9760 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9761 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9762
9763 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9764 [(set (match_operand:DI 0 "register_operand" "=r")
9765 (zero_extend:DI
9766 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9767 (match_operand:SI 2 "register_operand" "r"))))]
9768 "TARGET_64BIT && TARGET_BMI2"
9769 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9770 [(set_attr "type" "ishiftx")
9771 (set_attr "mode" "SI")])
9772
9773 (define_insn "*<shift_insn>si3_1_zext"
9774 [(set (match_operand:DI 0 "register_operand" "=r,r")
9775 (zero_extend:DI
9776 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9777 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9778 (clobber (reg:CC FLAGS_REG))]
9779 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9780 {
9781 switch (get_attr_type (insn))
9782 {
9783 case TYPE_ISHIFTX:
9784 return "#";
9785
9786 default:
9787 if (operands[2] == const1_rtx
9788 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9789 return "<shift>{l}\t%k0";
9790 else
9791 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9792 }
9793 }
9794 [(set_attr "isa" "*,bmi2")
9795 (set_attr "type" "ishift,ishiftx")
9796 (set (attr "length_immediate")
9797 (if_then_else
9798 (and (match_operand 2 "const1_operand" "")
9799 (ior (match_test "TARGET_SHIFT1")
9800 (match_test "optimize_function_for_size_p (cfun)")))
9801 (const_string "0")
9802 (const_string "*")))
9803 (set_attr "mode" "SI")])
9804
9805 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9806 (define_split
9807 [(set (match_operand:DI 0 "register_operand" "")
9808 (zero_extend:DI
9809 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9810 (match_operand:QI 2 "register_operand" ""))))
9811 (clobber (reg:CC FLAGS_REG))]
9812 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9813 [(set (match_dup 0)
9814 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9815 "operands[2] = gen_lowpart (SImode, operands[2]);")
9816
9817 (define_insn "*<shift_insn><mode>3_1"
9818 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9819 (any_shiftrt:SWI12
9820 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9821 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9822 (clobber (reg:CC FLAGS_REG))]
9823 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9824 {
9825 if (operands[2] == const1_rtx
9826 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9827 return "<shift>{<imodesuffix>}\t%0";
9828 else
9829 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9830 }
9831 [(set_attr "type" "ishift")
9832 (set (attr "length_immediate")
9833 (if_then_else
9834 (and (match_operand 2 "const1_operand" "")
9835 (ior (match_test "TARGET_SHIFT1")
9836 (match_test "optimize_function_for_size_p (cfun)")))
9837 (const_string "0")
9838 (const_string "*")))
9839 (set_attr "mode" "<MODE>")])
9840
9841 (define_insn "*<shift_insn>qi3_1_slp"
9842 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9843 (any_shiftrt:QI (match_dup 0)
9844 (match_operand:QI 1 "nonmemory_operand" "cI")))
9845 (clobber (reg:CC FLAGS_REG))]
9846 "(optimize_function_for_size_p (cfun)
9847 || !TARGET_PARTIAL_REG_STALL
9848 || (operands[1] == const1_rtx
9849 && TARGET_SHIFT1))"
9850 {
9851 if (operands[1] == const1_rtx
9852 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9853 return "<shift>{b}\t%0";
9854 else
9855 return "<shift>{b}\t{%1, %0|%0, %1}";
9856 }
9857 [(set_attr "type" "ishift1")
9858 (set (attr "length_immediate")
9859 (if_then_else
9860 (and (match_operand 1 "const1_operand" "")
9861 (ior (match_test "TARGET_SHIFT1")
9862 (match_test "optimize_function_for_size_p (cfun)")))
9863 (const_string "0")
9864 (const_string "*")))
9865 (set_attr "mode" "QI")])
9866
9867 ;; This pattern can't accept a variable shift count, since shifts by
9868 ;; zero don't affect the flags. We assume that shifts by constant
9869 ;; zero are optimized away.
9870 (define_insn "*<shift_insn><mode>3_cmp"
9871 [(set (reg FLAGS_REG)
9872 (compare
9873 (any_shiftrt:SWI
9874 (match_operand:SWI 1 "nonimmediate_operand" "0")
9875 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9876 (const_int 0)))
9877 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9878 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9879 "(optimize_function_for_size_p (cfun)
9880 || !TARGET_PARTIAL_FLAG_REG_STALL
9881 || (operands[2] == const1_rtx
9882 && TARGET_SHIFT1))
9883 && ix86_match_ccmode (insn, CCGOCmode)
9884 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9885 {
9886 if (operands[2] == const1_rtx
9887 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9888 return "<shift>{<imodesuffix>}\t%0";
9889 else
9890 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9891 }
9892 [(set_attr "type" "ishift")
9893 (set (attr "length_immediate")
9894 (if_then_else
9895 (and (match_operand 2 "const1_operand" "")
9896 (ior (match_test "TARGET_SHIFT1")
9897 (match_test "optimize_function_for_size_p (cfun)")))
9898 (const_string "0")
9899 (const_string "*")))
9900 (set_attr "mode" "<MODE>")])
9901
9902 (define_insn "*<shift_insn>si3_cmp_zext"
9903 [(set (reg FLAGS_REG)
9904 (compare
9905 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9906 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9907 (const_int 0)))
9908 (set (match_operand:DI 0 "register_operand" "=r")
9909 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9910 "TARGET_64BIT
9911 && (optimize_function_for_size_p (cfun)
9912 || !TARGET_PARTIAL_FLAG_REG_STALL
9913 || (operands[2] == const1_rtx
9914 && TARGET_SHIFT1))
9915 && ix86_match_ccmode (insn, CCGOCmode)
9916 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9917 {
9918 if (operands[2] == const1_rtx
9919 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9920 return "<shift>{l}\t%k0";
9921 else
9922 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9923 }
9924 [(set_attr "type" "ishift")
9925 (set (attr "length_immediate")
9926 (if_then_else
9927 (and (match_operand 2 "const1_operand" "")
9928 (ior (match_test "TARGET_SHIFT1")
9929 (match_test "optimize_function_for_size_p (cfun)")))
9930 (const_string "0")
9931 (const_string "*")))
9932 (set_attr "mode" "SI")])
9933
9934 (define_insn "*<shift_insn><mode>3_cconly"
9935 [(set (reg FLAGS_REG)
9936 (compare
9937 (any_shiftrt:SWI
9938 (match_operand:SWI 1 "register_operand" "0")
9939 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9940 (const_int 0)))
9941 (clobber (match_scratch:SWI 0 "=<r>"))]
9942 "(optimize_function_for_size_p (cfun)
9943 || !TARGET_PARTIAL_FLAG_REG_STALL
9944 || (operands[2] == const1_rtx
9945 && TARGET_SHIFT1))
9946 && ix86_match_ccmode (insn, CCGOCmode)"
9947 {
9948 if (operands[2] == const1_rtx
9949 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9950 return "<shift>{<imodesuffix>}\t%0";
9951 else
9952 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9953 }
9954 [(set_attr "type" "ishift")
9955 (set (attr "length_immediate")
9956 (if_then_else
9957 (and (match_operand 2 "const1_operand" "")
9958 (ior (match_test "TARGET_SHIFT1")
9959 (match_test "optimize_function_for_size_p (cfun)")))
9960 (const_string "0")
9961 (const_string "*")))
9962 (set_attr "mode" "<MODE>")])
9963 \f
9964 ;; Rotate instructions
9965
9966 (define_expand "<rotate_insn>ti3"
9967 [(set (match_operand:TI 0 "register_operand" "")
9968 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9969 (match_operand:QI 2 "nonmemory_operand" "")))]
9970 "TARGET_64BIT"
9971 {
9972 if (const_1_to_63_operand (operands[2], VOIDmode))
9973 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9974 (operands[0], operands[1], operands[2]));
9975 else
9976 FAIL;
9977
9978 DONE;
9979 })
9980
9981 (define_expand "<rotate_insn>di3"
9982 [(set (match_operand:DI 0 "shiftdi_operand" "")
9983 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9984 (match_operand:QI 2 "nonmemory_operand" "")))]
9985 ""
9986 {
9987 if (TARGET_64BIT)
9988 ix86_expand_binary_operator (<CODE>, DImode, operands);
9989 else if (const_1_to_31_operand (operands[2], VOIDmode))
9990 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9991 (operands[0], operands[1], operands[2]));
9992 else
9993 FAIL;
9994
9995 DONE;
9996 })
9997
9998 (define_expand "<rotate_insn><mode>3"
9999 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10000 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10001 (match_operand:QI 2 "nonmemory_operand" "")))]
10002 ""
10003 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10004
10005 ;; Avoid useless masking of count operand.
10006 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10007 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10008 (any_rotate:SWI48
10009 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10010 (subreg:QI
10011 (and:SI
10012 (match_operand:SI 2 "nonimmediate_operand" "c")
10013 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10014 (clobber (reg:CC FLAGS_REG))]
10015 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10016 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10017 == GET_MODE_BITSIZE (<MODE>mode)-1"
10018 "#"
10019 "&& 1"
10020 [(parallel [(set (match_dup 0)
10021 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10022 (clobber (reg:CC FLAGS_REG))])]
10023 {
10024 if (can_create_pseudo_p ())
10025 operands [2] = force_reg (SImode, operands[2]);
10026
10027 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10028 }
10029 [(set_attr "type" "rotate")
10030 (set_attr "mode" "<MODE>")])
10031
10032 ;; Implement rotation using two double-precision
10033 ;; shift instructions and a scratch register.
10034
10035 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10036 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10037 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10038 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10039 (clobber (reg:CC FLAGS_REG))
10040 (clobber (match_scratch:DWIH 3 "=&r"))]
10041 ""
10042 "#"
10043 "reload_completed"
10044 [(set (match_dup 3) (match_dup 4))
10045 (parallel
10046 [(set (match_dup 4)
10047 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10048 (lshiftrt:DWIH (match_dup 5)
10049 (minus:QI (match_dup 6) (match_dup 2)))))
10050 (clobber (reg:CC FLAGS_REG))])
10051 (parallel
10052 [(set (match_dup 5)
10053 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10054 (lshiftrt:DWIH (match_dup 3)
10055 (minus:QI (match_dup 6) (match_dup 2)))))
10056 (clobber (reg:CC FLAGS_REG))])]
10057 {
10058 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10059
10060 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10061 })
10062
10063 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10064 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10065 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10066 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10067 (clobber (reg:CC FLAGS_REG))
10068 (clobber (match_scratch:DWIH 3 "=&r"))]
10069 ""
10070 "#"
10071 "reload_completed"
10072 [(set (match_dup 3) (match_dup 4))
10073 (parallel
10074 [(set (match_dup 4)
10075 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10076 (ashift:DWIH (match_dup 5)
10077 (minus:QI (match_dup 6) (match_dup 2)))))
10078 (clobber (reg:CC FLAGS_REG))])
10079 (parallel
10080 [(set (match_dup 5)
10081 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10082 (ashift:DWIH (match_dup 3)
10083 (minus:QI (match_dup 6) (match_dup 2)))))
10084 (clobber (reg:CC FLAGS_REG))])]
10085 {
10086 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10087
10088 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10089 })
10090
10091 (define_insn "*bmi2_rorx<mode>3_1"
10092 [(set (match_operand:SWI48 0 "register_operand" "=r")
10093 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10094 (match_operand:QI 2 "immediate_operand" "<S>")))]
10095 "TARGET_BMI2"
10096 "rorx\t{%2, %1, %0|%0, %1, %2}"
10097 [(set_attr "type" "rotatex")
10098 (set_attr "mode" "<MODE>")])
10099
10100 (define_insn "*<rotate_insn><mode>3_1"
10101 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10102 (any_rotate:SWI48
10103 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10104 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10105 (clobber (reg:CC FLAGS_REG))]
10106 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10107 {
10108 switch (get_attr_type (insn))
10109 {
10110 case TYPE_ROTATEX:
10111 return "#";
10112
10113 default:
10114 if (operands[2] == const1_rtx
10115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116 return "<rotate>{<imodesuffix>}\t%0";
10117 else
10118 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10119 }
10120 }
10121 [(set_attr "isa" "*,bmi2")
10122 (set_attr "type" "rotate,rotatex")
10123 (set (attr "length_immediate")
10124 (if_then_else
10125 (and (eq_attr "type" "rotate")
10126 (and (match_operand 2 "const1_operand" "")
10127 (ior (match_test "TARGET_SHIFT1")
10128 (match_test "optimize_function_for_size_p (cfun)"))))
10129 (const_string "0")
10130 (const_string "*")))
10131 (set_attr "mode" "<MODE>")])
10132
10133 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10134 (define_split
10135 [(set (match_operand:SWI48 0 "register_operand" "")
10136 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10137 (match_operand:QI 2 "immediate_operand" "")))
10138 (clobber (reg:CC FLAGS_REG))]
10139 "TARGET_BMI2 && reload_completed"
10140 [(set (match_dup 0)
10141 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10142 {
10143 operands[2]
10144 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10145 })
10146
10147 (define_split
10148 [(set (match_operand:SWI48 0 "register_operand" "")
10149 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10150 (match_operand:QI 2 "immediate_operand" "")))
10151 (clobber (reg:CC FLAGS_REG))]
10152 "TARGET_BMI2 && reload_completed"
10153 [(set (match_dup 0)
10154 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10155
10156 (define_insn "*bmi2_rorxsi3_1_zext"
10157 [(set (match_operand:DI 0 "register_operand" "=r")
10158 (zero_extend:DI
10159 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10160 (match_operand:QI 2 "immediate_operand" "I"))))]
10161 "TARGET_64BIT && TARGET_BMI2"
10162 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10163 [(set_attr "type" "rotatex")
10164 (set_attr "mode" "SI")])
10165
10166 (define_insn "*<rotate_insn>si3_1_zext"
10167 [(set (match_operand:DI 0 "register_operand" "=r,r")
10168 (zero_extend:DI
10169 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10170 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10171 (clobber (reg:CC FLAGS_REG))]
10172 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10173 {
10174 switch (get_attr_type (insn))
10175 {
10176 case TYPE_ROTATEX:
10177 return "#";
10178
10179 default:
10180 if (operands[2] == const1_rtx
10181 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10182 return "<rotate>{l}\t%k0";
10183 else
10184 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10185 }
10186 }
10187 [(set_attr "isa" "*,bmi2")
10188 (set_attr "type" "rotate,rotatex")
10189 (set (attr "length_immediate")
10190 (if_then_else
10191 (and (eq_attr "type" "rotate")
10192 (and (match_operand 2 "const1_operand" "")
10193 (ior (match_test "TARGET_SHIFT1")
10194 (match_test "optimize_function_for_size_p (cfun)"))))
10195 (const_string "0")
10196 (const_string "*")))
10197 (set_attr "mode" "SI")])
10198
10199 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10200 (define_split
10201 [(set (match_operand:DI 0 "register_operand" "")
10202 (zero_extend:DI
10203 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10204 (match_operand:QI 2 "immediate_operand" ""))))
10205 (clobber (reg:CC FLAGS_REG))]
10206 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10207 [(set (match_dup 0)
10208 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10209 {
10210 operands[2]
10211 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10212 })
10213
10214 (define_split
10215 [(set (match_operand:DI 0 "register_operand" "")
10216 (zero_extend:DI
10217 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10218 (match_operand:QI 2 "immediate_operand" ""))))
10219 (clobber (reg:CC FLAGS_REG))]
10220 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10221 [(set (match_dup 0)
10222 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10223
10224 (define_insn "*<rotate_insn><mode>3_1"
10225 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10226 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10227 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10228 (clobber (reg:CC FLAGS_REG))]
10229 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10230 {
10231 if (operands[2] == const1_rtx
10232 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10233 return "<rotate>{<imodesuffix>}\t%0";
10234 else
10235 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10236 }
10237 [(set_attr "type" "rotate")
10238 (set (attr "length_immediate")
10239 (if_then_else
10240 (and (match_operand 2 "const1_operand" "")
10241 (ior (match_test "TARGET_SHIFT1")
10242 (match_test "optimize_function_for_size_p (cfun)")))
10243 (const_string "0")
10244 (const_string "*")))
10245 (set_attr "mode" "<MODE>")])
10246
10247 (define_insn "*<rotate_insn>qi3_1_slp"
10248 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10249 (any_rotate:QI (match_dup 0)
10250 (match_operand:QI 1 "nonmemory_operand" "cI")))
10251 (clobber (reg:CC FLAGS_REG))]
10252 "(optimize_function_for_size_p (cfun)
10253 || !TARGET_PARTIAL_REG_STALL
10254 || (operands[1] == const1_rtx
10255 && TARGET_SHIFT1))"
10256 {
10257 if (operands[1] == const1_rtx
10258 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10259 return "<rotate>{b}\t%0";
10260 else
10261 return "<rotate>{b}\t{%1, %0|%0, %1}";
10262 }
10263 [(set_attr "type" "rotate1")
10264 (set (attr "length_immediate")
10265 (if_then_else
10266 (and (match_operand 1 "const1_operand" "")
10267 (ior (match_test "TARGET_SHIFT1")
10268 (match_test "optimize_function_for_size_p (cfun)")))
10269 (const_string "0")
10270 (const_string "*")))
10271 (set_attr "mode" "QI")])
10272
10273 (define_split
10274 [(set (match_operand:HI 0 "register_operand" "")
10275 (any_rotate:HI (match_dup 0) (const_int 8)))
10276 (clobber (reg:CC FLAGS_REG))]
10277 "reload_completed
10278 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10279 [(parallel [(set (strict_low_part (match_dup 0))
10280 (bswap:HI (match_dup 0)))
10281 (clobber (reg:CC FLAGS_REG))])])
10282 \f
10283 ;; Bit set / bit test instructions
10284
10285 (define_expand "extv"
10286 [(set (match_operand:SI 0 "register_operand" "")
10287 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10288 (match_operand:SI 2 "const8_operand" "")
10289 (match_operand:SI 3 "const8_operand" "")))]
10290 ""
10291 {
10292 /* Handle extractions from %ah et al. */
10293 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10294 FAIL;
10295
10296 /* From mips.md: extract_bit_field doesn't verify that our source
10297 matches the predicate, so check it again here. */
10298 if (! ext_register_operand (operands[1], VOIDmode))
10299 FAIL;
10300 })
10301
10302 (define_expand "extzv"
10303 [(set (match_operand:SI 0 "register_operand" "")
10304 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10305 (match_operand:SI 2 "const8_operand" "")
10306 (match_operand:SI 3 "const8_operand" "")))]
10307 ""
10308 {
10309 /* Handle extractions from %ah et al. */
10310 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10311 FAIL;
10312
10313 /* From mips.md: extract_bit_field doesn't verify that our source
10314 matches the predicate, so check it again here. */
10315 if (! ext_register_operand (operands[1], VOIDmode))
10316 FAIL;
10317 })
10318
10319 (define_expand "insv"
10320 [(set (zero_extract (match_operand 0 "register_operand" "")
10321 (match_operand 1 "const_int_operand" "")
10322 (match_operand 2 "const_int_operand" ""))
10323 (match_operand 3 "register_operand" ""))]
10324 ""
10325 {
10326 rtx (*gen_mov_insv_1) (rtx, rtx);
10327
10328 if (ix86_expand_pinsr (operands))
10329 DONE;
10330
10331 /* Handle insertions to %ah et al. */
10332 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10333 FAIL;
10334
10335 /* From mips.md: insert_bit_field doesn't verify that our source
10336 matches the predicate, so check it again here. */
10337 if (! ext_register_operand (operands[0], VOIDmode))
10338 FAIL;
10339
10340 gen_mov_insv_1 = (TARGET_64BIT
10341 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10342
10343 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10344 DONE;
10345 })
10346
10347 ;; %%% bts, btr, btc, bt.
10348 ;; In general these instructions are *slow* when applied to memory,
10349 ;; since they enforce atomic operation. When applied to registers,
10350 ;; it depends on the cpu implementation. They're never faster than
10351 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10352 ;; no point. But in 64-bit, we can't hold the relevant immediates
10353 ;; within the instruction itself, so operating on bits in the high
10354 ;; 32-bits of a register becomes easier.
10355 ;;
10356 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10357 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10358 ;; negdf respectively, so they can never be disabled entirely.
10359
10360 (define_insn "*btsq"
10361 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10362 (const_int 1)
10363 (match_operand:DI 1 "const_0_to_63_operand" ""))
10364 (const_int 1))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10367 "bts{q}\t{%1, %0|%0, %1}"
10368 [(set_attr "type" "alu1")
10369 (set_attr "prefix_0f" "1")
10370 (set_attr "mode" "DI")])
10371
10372 (define_insn "*btrq"
10373 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10374 (const_int 1)
10375 (match_operand:DI 1 "const_0_to_63_operand" ""))
10376 (const_int 0))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10379 "btr{q}\t{%1, %0|%0, %1}"
10380 [(set_attr "type" "alu1")
10381 (set_attr "prefix_0f" "1")
10382 (set_attr "mode" "DI")])
10383
10384 (define_insn "*btcq"
10385 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10386 (const_int 1)
10387 (match_operand:DI 1 "const_0_to_63_operand" ""))
10388 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10391 "btc{q}\t{%1, %0|%0, %1}"
10392 [(set_attr "type" "alu1")
10393 (set_attr "prefix_0f" "1")
10394 (set_attr "mode" "DI")])
10395
10396 ;; Allow Nocona to avoid these instructions if a register is available.
10397
10398 (define_peephole2
10399 [(match_scratch:DI 2 "r")
10400 (parallel [(set (zero_extract:DI
10401 (match_operand:DI 0 "register_operand" "")
10402 (const_int 1)
10403 (match_operand:DI 1 "const_0_to_63_operand" ""))
10404 (const_int 1))
10405 (clobber (reg:CC FLAGS_REG))])]
10406 "TARGET_64BIT && !TARGET_USE_BT"
10407 [(const_int 0)]
10408 {
10409 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10410 rtx op1;
10411
10412 if (HOST_BITS_PER_WIDE_INT >= 64)
10413 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10414 else if (i < HOST_BITS_PER_WIDE_INT)
10415 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10416 else
10417 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10418
10419 op1 = immed_double_const (lo, hi, DImode);
10420 if (i >= 31)
10421 {
10422 emit_move_insn (operands[2], op1);
10423 op1 = operands[2];
10424 }
10425
10426 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10427 DONE;
10428 })
10429
10430 (define_peephole2
10431 [(match_scratch:DI 2 "r")
10432 (parallel [(set (zero_extract:DI
10433 (match_operand:DI 0 "register_operand" "")
10434 (const_int 1)
10435 (match_operand:DI 1 "const_0_to_63_operand" ""))
10436 (const_int 0))
10437 (clobber (reg:CC FLAGS_REG))])]
10438 "TARGET_64BIT && !TARGET_USE_BT"
10439 [(const_int 0)]
10440 {
10441 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10442 rtx op1;
10443
10444 if (HOST_BITS_PER_WIDE_INT >= 64)
10445 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446 else if (i < HOST_BITS_PER_WIDE_INT)
10447 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10448 else
10449 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10450
10451 op1 = immed_double_const (~lo, ~hi, DImode);
10452 if (i >= 32)
10453 {
10454 emit_move_insn (operands[2], op1);
10455 op1 = operands[2];
10456 }
10457
10458 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10459 DONE;
10460 })
10461
10462 (define_peephole2
10463 [(match_scratch:DI 2 "r")
10464 (parallel [(set (zero_extract:DI
10465 (match_operand:DI 0 "register_operand" "")
10466 (const_int 1)
10467 (match_operand:DI 1 "const_0_to_63_operand" ""))
10468 (not:DI (zero_extract:DI
10469 (match_dup 0) (const_int 1) (match_dup 1))))
10470 (clobber (reg:CC FLAGS_REG))])]
10471 "TARGET_64BIT && !TARGET_USE_BT"
10472 [(const_int 0)]
10473 {
10474 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10475 rtx op1;
10476
10477 if (HOST_BITS_PER_WIDE_INT >= 64)
10478 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479 else if (i < HOST_BITS_PER_WIDE_INT)
10480 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10481 else
10482 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10483
10484 op1 = immed_double_const (lo, hi, DImode);
10485 if (i >= 31)
10486 {
10487 emit_move_insn (operands[2], op1);
10488 op1 = operands[2];
10489 }
10490
10491 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10492 DONE;
10493 })
10494
10495 (define_insn "*bt<mode>"
10496 [(set (reg:CCC FLAGS_REG)
10497 (compare:CCC
10498 (zero_extract:SWI48
10499 (match_operand:SWI48 0 "register_operand" "r")
10500 (const_int 1)
10501 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10502 (const_int 0)))]
10503 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10504 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10505 [(set_attr "type" "alu1")
10506 (set_attr "prefix_0f" "1")
10507 (set_attr "mode" "<MODE>")])
10508 \f
10509 ;; Store-flag instructions.
10510
10511 ;; For all sCOND expanders, also expand the compare or test insn that
10512 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10513
10514 (define_insn_and_split "*setcc_di_1"
10515 [(set (match_operand:DI 0 "register_operand" "=q")
10516 (match_operator:DI 1 "ix86_comparison_operator"
10517 [(reg FLAGS_REG) (const_int 0)]))]
10518 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10519 "#"
10520 "&& reload_completed"
10521 [(set (match_dup 2) (match_dup 1))
10522 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10523 {
10524 PUT_MODE (operands[1], QImode);
10525 operands[2] = gen_lowpart (QImode, operands[0]);
10526 })
10527
10528 (define_insn_and_split "*setcc_si_1_and"
10529 [(set (match_operand:SI 0 "register_operand" "=q")
10530 (match_operator:SI 1 "ix86_comparison_operator"
10531 [(reg FLAGS_REG) (const_int 0)]))
10532 (clobber (reg:CC FLAGS_REG))]
10533 "!TARGET_PARTIAL_REG_STALL
10534 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10535 "#"
10536 "&& reload_completed"
10537 [(set (match_dup 2) (match_dup 1))
10538 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10539 (clobber (reg:CC FLAGS_REG))])]
10540 {
10541 PUT_MODE (operands[1], QImode);
10542 operands[2] = gen_lowpart (QImode, operands[0]);
10543 })
10544
10545 (define_insn_and_split "*setcc_si_1_movzbl"
10546 [(set (match_operand:SI 0 "register_operand" "=q")
10547 (match_operator:SI 1 "ix86_comparison_operator"
10548 [(reg FLAGS_REG) (const_int 0)]))]
10549 "!TARGET_PARTIAL_REG_STALL
10550 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10551 "#"
10552 "&& reload_completed"
10553 [(set (match_dup 2) (match_dup 1))
10554 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10555 {
10556 PUT_MODE (operands[1], QImode);
10557 operands[2] = gen_lowpart (QImode, operands[0]);
10558 })
10559
10560 (define_insn "*setcc_qi"
10561 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10562 (match_operator:QI 1 "ix86_comparison_operator"
10563 [(reg FLAGS_REG) (const_int 0)]))]
10564 ""
10565 "set%C1\t%0"
10566 [(set_attr "type" "setcc")
10567 (set_attr "mode" "QI")])
10568
10569 (define_insn "*setcc_qi_slp"
10570 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10571 (match_operator:QI 1 "ix86_comparison_operator"
10572 [(reg FLAGS_REG) (const_int 0)]))]
10573 ""
10574 "set%C1\t%0"
10575 [(set_attr "type" "setcc")
10576 (set_attr "mode" "QI")])
10577
10578 ;; In general it is not safe to assume too much about CCmode registers,
10579 ;; so simplify-rtx stops when it sees a second one. Under certain
10580 ;; conditions this is safe on x86, so help combine not create
10581 ;;
10582 ;; seta %al
10583 ;; testb %al, %al
10584 ;; sete %al
10585
10586 (define_split
10587 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10588 (ne:QI (match_operator 1 "ix86_comparison_operator"
10589 [(reg FLAGS_REG) (const_int 0)])
10590 (const_int 0)))]
10591 ""
10592 [(set (match_dup 0) (match_dup 1))]
10593 "PUT_MODE (operands[1], QImode);")
10594
10595 (define_split
10596 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10597 (ne:QI (match_operator 1 "ix86_comparison_operator"
10598 [(reg FLAGS_REG) (const_int 0)])
10599 (const_int 0)))]
10600 ""
10601 [(set (match_dup 0) (match_dup 1))]
10602 "PUT_MODE (operands[1], QImode);")
10603
10604 (define_split
10605 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10606 (eq:QI (match_operator 1 "ix86_comparison_operator"
10607 [(reg FLAGS_REG) (const_int 0)])
10608 (const_int 0)))]
10609 ""
10610 [(set (match_dup 0) (match_dup 1))]
10611 {
10612 rtx new_op1 = copy_rtx (operands[1]);
10613 operands[1] = new_op1;
10614 PUT_MODE (new_op1, QImode);
10615 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10616 GET_MODE (XEXP (new_op1, 0))));
10617
10618 /* Make sure that (a) the CCmode we have for the flags is strong
10619 enough for the reversed compare or (b) we have a valid FP compare. */
10620 if (! ix86_comparison_operator (new_op1, VOIDmode))
10621 FAIL;
10622 })
10623
10624 (define_split
10625 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10626 (eq:QI (match_operator 1 "ix86_comparison_operator"
10627 [(reg FLAGS_REG) (const_int 0)])
10628 (const_int 0)))]
10629 ""
10630 [(set (match_dup 0) (match_dup 1))]
10631 {
10632 rtx new_op1 = copy_rtx (operands[1]);
10633 operands[1] = new_op1;
10634 PUT_MODE (new_op1, QImode);
10635 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10636 GET_MODE (XEXP (new_op1, 0))));
10637
10638 /* Make sure that (a) the CCmode we have for the flags is strong
10639 enough for the reversed compare or (b) we have a valid FP compare. */
10640 if (! ix86_comparison_operator (new_op1, VOIDmode))
10641 FAIL;
10642 })
10643
10644 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10645 ;; subsequent logical operations are used to imitate conditional moves.
10646 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10647 ;; it directly.
10648
10649 (define_insn "setcc_<mode>_sse"
10650 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10651 (match_operator:MODEF 3 "sse_comparison_operator"
10652 [(match_operand:MODEF 1 "register_operand" "0,x")
10653 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10654 "SSE_FLOAT_MODE_P (<MODE>mode)"
10655 "@
10656 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10657 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10658 [(set_attr "isa" "noavx,avx")
10659 (set_attr "type" "ssecmp")
10660 (set_attr "length_immediate" "1")
10661 (set_attr "prefix" "orig,vex")
10662 (set_attr "mode" "<MODE>")])
10663 \f
10664 ;; Basic conditional jump instructions.
10665 ;; We ignore the overflow flag for signed branch instructions.
10666
10667 (define_insn "*jcc_1"
10668 [(set (pc)
10669 (if_then_else (match_operator 1 "ix86_comparison_operator"
10670 [(reg FLAGS_REG) (const_int 0)])
10671 (label_ref (match_operand 0 "" ""))
10672 (pc)))]
10673 ""
10674 "%+j%C1\t%l0"
10675 [(set_attr "type" "ibr")
10676 (set_attr "modrm" "0")
10677 (set (attr "length")
10678 (if_then_else (and (ge (minus (match_dup 0) (pc))
10679 (const_int -126))
10680 (lt (minus (match_dup 0) (pc))
10681 (const_int 128)))
10682 (const_int 2)
10683 (const_int 6)))])
10684
10685 (define_insn "*jcc_2"
10686 [(set (pc)
10687 (if_then_else (match_operator 1 "ix86_comparison_operator"
10688 [(reg FLAGS_REG) (const_int 0)])
10689 (pc)
10690 (label_ref (match_operand 0 "" ""))))]
10691 ""
10692 "%+j%c1\t%l0"
10693 [(set_attr "type" "ibr")
10694 (set_attr "modrm" "0")
10695 (set (attr "length")
10696 (if_then_else (and (ge (minus (match_dup 0) (pc))
10697 (const_int -126))
10698 (lt (minus (match_dup 0) (pc))
10699 (const_int 128)))
10700 (const_int 2)
10701 (const_int 6)))])
10702
10703 ;; In general it is not safe to assume too much about CCmode registers,
10704 ;; so simplify-rtx stops when it sees a second one. Under certain
10705 ;; conditions this is safe on x86, so help combine not create
10706 ;;
10707 ;; seta %al
10708 ;; testb %al, %al
10709 ;; je Lfoo
10710
10711 (define_split
10712 [(set (pc)
10713 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10714 [(reg FLAGS_REG) (const_int 0)])
10715 (const_int 0))
10716 (label_ref (match_operand 1 "" ""))
10717 (pc)))]
10718 ""
10719 [(set (pc)
10720 (if_then_else (match_dup 0)
10721 (label_ref (match_dup 1))
10722 (pc)))]
10723 "PUT_MODE (operands[0], VOIDmode);")
10724
10725 (define_split
10726 [(set (pc)
10727 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10728 [(reg FLAGS_REG) (const_int 0)])
10729 (const_int 0))
10730 (label_ref (match_operand 1 "" ""))
10731 (pc)))]
10732 ""
10733 [(set (pc)
10734 (if_then_else (match_dup 0)
10735 (label_ref (match_dup 1))
10736 (pc)))]
10737 {
10738 rtx new_op0 = copy_rtx (operands[0]);
10739 operands[0] = new_op0;
10740 PUT_MODE (new_op0, VOIDmode);
10741 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10742 GET_MODE (XEXP (new_op0, 0))));
10743
10744 /* Make sure that (a) the CCmode we have for the flags is strong
10745 enough for the reversed compare or (b) we have a valid FP compare. */
10746 if (! ix86_comparison_operator (new_op0, VOIDmode))
10747 FAIL;
10748 })
10749
10750 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10751 ;; pass generates from shift insn with QImode operand. Actually, the mode
10752 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10753 ;; appropriate modulo of the bit offset value.
10754
10755 (define_insn_and_split "*jcc_bt<mode>"
10756 [(set (pc)
10757 (if_then_else (match_operator 0 "bt_comparison_operator"
10758 [(zero_extract:SWI48
10759 (match_operand:SWI48 1 "register_operand" "r")
10760 (const_int 1)
10761 (zero_extend:SI
10762 (match_operand:QI 2 "register_operand" "r")))
10763 (const_int 0)])
10764 (label_ref (match_operand 3 "" ""))
10765 (pc)))
10766 (clobber (reg:CC FLAGS_REG))]
10767 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10768 "#"
10769 "&& 1"
10770 [(set (reg:CCC FLAGS_REG)
10771 (compare:CCC
10772 (zero_extract:SWI48
10773 (match_dup 1)
10774 (const_int 1)
10775 (match_dup 2))
10776 (const_int 0)))
10777 (set (pc)
10778 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10779 (label_ref (match_dup 3))
10780 (pc)))]
10781 {
10782 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10783
10784 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10785 })
10786
10787 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10788 ;; also for DImode, this is what combine produces.
10789 (define_insn_and_split "*jcc_bt<mode>_mask"
10790 [(set (pc)
10791 (if_then_else (match_operator 0 "bt_comparison_operator"
10792 [(zero_extract:SWI48
10793 (match_operand:SWI48 1 "register_operand" "r")
10794 (const_int 1)
10795 (and:SI
10796 (match_operand:SI 2 "register_operand" "r")
10797 (match_operand:SI 3 "const_int_operand" "n")))])
10798 (label_ref (match_operand 4 "" ""))
10799 (pc)))
10800 (clobber (reg:CC FLAGS_REG))]
10801 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10802 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10803 == GET_MODE_BITSIZE (<MODE>mode)-1"
10804 "#"
10805 "&& 1"
10806 [(set (reg:CCC FLAGS_REG)
10807 (compare:CCC
10808 (zero_extract:SWI48
10809 (match_dup 1)
10810 (const_int 1)
10811 (match_dup 2))
10812 (const_int 0)))
10813 (set (pc)
10814 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10815 (label_ref (match_dup 4))
10816 (pc)))]
10817 {
10818 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10819
10820 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10821 })
10822
10823 (define_insn_and_split "*jcc_btsi_1"
10824 [(set (pc)
10825 (if_then_else (match_operator 0 "bt_comparison_operator"
10826 [(and:SI
10827 (lshiftrt:SI
10828 (match_operand:SI 1 "register_operand" "r")
10829 (match_operand:QI 2 "register_operand" "r"))
10830 (const_int 1))
10831 (const_int 0)])
10832 (label_ref (match_operand 3 "" ""))
10833 (pc)))
10834 (clobber (reg:CC FLAGS_REG))]
10835 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10836 "#"
10837 "&& 1"
10838 [(set (reg:CCC FLAGS_REG)
10839 (compare:CCC
10840 (zero_extract:SI
10841 (match_dup 1)
10842 (const_int 1)
10843 (match_dup 2))
10844 (const_int 0)))
10845 (set (pc)
10846 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10847 (label_ref (match_dup 3))
10848 (pc)))]
10849 {
10850 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10851
10852 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10853 })
10854
10855 ;; avoid useless masking of bit offset operand
10856 (define_insn_and_split "*jcc_btsi_mask_1"
10857 [(set (pc)
10858 (if_then_else
10859 (match_operator 0 "bt_comparison_operator"
10860 [(and:SI
10861 (lshiftrt:SI
10862 (match_operand:SI 1 "register_operand" "r")
10863 (subreg:QI
10864 (and:SI
10865 (match_operand:SI 2 "register_operand" "r")
10866 (match_operand:SI 3 "const_int_operand" "n")) 0))
10867 (const_int 1))
10868 (const_int 0)])
10869 (label_ref (match_operand 4 "" ""))
10870 (pc)))
10871 (clobber (reg:CC FLAGS_REG))]
10872 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10873 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10874 "#"
10875 "&& 1"
10876 [(set (reg:CCC FLAGS_REG)
10877 (compare:CCC
10878 (zero_extract:SI
10879 (match_dup 1)
10880 (const_int 1)
10881 (match_dup 2))
10882 (const_int 0)))
10883 (set (pc)
10884 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10885 (label_ref (match_dup 4))
10886 (pc)))]
10887 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10888
10889 ;; Define combination compare-and-branch fp compare instructions to help
10890 ;; combine.
10891
10892 (define_insn "*fp_jcc_1_387"
10893 [(set (pc)
10894 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10895 [(match_operand 1 "register_operand" "f")
10896 (match_operand 2 "nonimmediate_operand" "fm")])
10897 (label_ref (match_operand 3 "" ""))
10898 (pc)))
10899 (clobber (reg:CCFP FPSR_REG))
10900 (clobber (reg:CCFP FLAGS_REG))
10901 (clobber (match_scratch:HI 4 "=a"))]
10902 "TARGET_80387
10903 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10904 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10905 && SELECT_CC_MODE (GET_CODE (operands[0]),
10906 operands[1], operands[2]) == CCFPmode
10907 && !TARGET_CMOVE"
10908 "#")
10909
10910 (define_insn "*fp_jcc_1r_387"
10911 [(set (pc)
10912 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10913 [(match_operand 1 "register_operand" "f")
10914 (match_operand 2 "nonimmediate_operand" "fm")])
10915 (pc)
10916 (label_ref (match_operand 3 "" ""))))
10917 (clobber (reg:CCFP FPSR_REG))
10918 (clobber (reg:CCFP FLAGS_REG))
10919 (clobber (match_scratch:HI 4 "=a"))]
10920 "TARGET_80387
10921 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10922 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10923 && SELECT_CC_MODE (GET_CODE (operands[0]),
10924 operands[1], operands[2]) == CCFPmode
10925 && !TARGET_CMOVE"
10926 "#")
10927
10928 (define_insn "*fp_jcc_2_387"
10929 [(set (pc)
10930 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10931 [(match_operand 1 "register_operand" "f")
10932 (match_operand 2 "register_operand" "f")])
10933 (label_ref (match_operand 3 "" ""))
10934 (pc)))
10935 (clobber (reg:CCFP FPSR_REG))
10936 (clobber (reg:CCFP FLAGS_REG))
10937 (clobber (match_scratch:HI 4 "=a"))]
10938 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10939 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10940 && !TARGET_CMOVE"
10941 "#")
10942
10943 (define_insn "*fp_jcc_2r_387"
10944 [(set (pc)
10945 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946 [(match_operand 1 "register_operand" "f")
10947 (match_operand 2 "register_operand" "f")])
10948 (pc)
10949 (label_ref (match_operand 3 "" ""))))
10950 (clobber (reg:CCFP FPSR_REG))
10951 (clobber (reg:CCFP FLAGS_REG))
10952 (clobber (match_scratch:HI 4 "=a"))]
10953 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10954 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10955 && !TARGET_CMOVE"
10956 "#")
10957
10958 (define_insn "*fp_jcc_3_387"
10959 [(set (pc)
10960 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10961 [(match_operand 1 "register_operand" "f")
10962 (match_operand 2 "const0_operand" "")])
10963 (label_ref (match_operand 3 "" ""))
10964 (pc)))
10965 (clobber (reg:CCFP FPSR_REG))
10966 (clobber (reg:CCFP FLAGS_REG))
10967 (clobber (match_scratch:HI 4 "=a"))]
10968 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10969 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10970 && SELECT_CC_MODE (GET_CODE (operands[0]),
10971 operands[1], operands[2]) == CCFPmode
10972 && !TARGET_CMOVE"
10973 "#")
10974
10975 (define_split
10976 [(set (pc)
10977 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978 [(match_operand 1 "register_operand" "")
10979 (match_operand 2 "nonimmediate_operand" "")])
10980 (match_operand 3 "" "")
10981 (match_operand 4 "" "")))
10982 (clobber (reg:CCFP FPSR_REG))
10983 (clobber (reg:CCFP FLAGS_REG))]
10984 "reload_completed"
10985 [(const_int 0)]
10986 {
10987 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10988 operands[3], operands[4], NULL_RTX, NULL_RTX);
10989 DONE;
10990 })
10991
10992 (define_split
10993 [(set (pc)
10994 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10995 [(match_operand 1 "register_operand" "")
10996 (match_operand 2 "general_operand" "")])
10997 (match_operand 3 "" "")
10998 (match_operand 4 "" "")))
10999 (clobber (reg:CCFP FPSR_REG))
11000 (clobber (reg:CCFP FLAGS_REG))
11001 (clobber (match_scratch:HI 5 "=a"))]
11002 "reload_completed"
11003 [(const_int 0)]
11004 {
11005 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11006 operands[3], operands[4], operands[5], NULL_RTX);
11007 DONE;
11008 })
11009
11010 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11011 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11012 ;; with a precedence over other operators and is always put in the first
11013 ;; place. Swap condition and operands to match ficom instruction.
11014
11015 (define_insn "*fp_jcc_4_<mode>_387"
11016 [(set (pc)
11017 (if_then_else
11018 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11019 [(match_operator 1 "float_operator"
11020 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11021 (match_operand 3 "register_operand" "f,f")])
11022 (label_ref (match_operand 4 "" ""))
11023 (pc)))
11024 (clobber (reg:CCFP FPSR_REG))
11025 (clobber (reg:CCFP FLAGS_REG))
11026 (clobber (match_scratch:HI 5 "=a,a"))]
11027 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11028 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11029 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11030 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11031 && !TARGET_CMOVE"
11032 "#")
11033
11034 (define_split
11035 [(set (pc)
11036 (if_then_else
11037 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11038 [(match_operator 1 "float_operator"
11039 [(match_operand:SWI24 2 "memory_operand" "")])
11040 (match_operand 3 "register_operand" "")])
11041 (match_operand 4 "" "")
11042 (match_operand 5 "" "")))
11043 (clobber (reg:CCFP FPSR_REG))
11044 (clobber (reg:CCFP FLAGS_REG))
11045 (clobber (match_scratch:HI 6 "=a"))]
11046 "reload_completed"
11047 [(const_int 0)]
11048 {
11049 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11050
11051 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11052 operands[3], operands[7],
11053 operands[4], operands[5], operands[6], NULL_RTX);
11054 DONE;
11055 })
11056
11057 ;; %%% Kill this when reload knows how to do it.
11058 (define_split
11059 [(set (pc)
11060 (if_then_else
11061 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11062 [(match_operator 1 "float_operator"
11063 [(match_operand:SWI24 2 "register_operand" "")])
11064 (match_operand 3 "register_operand" "")])
11065 (match_operand 4 "" "")
11066 (match_operand 5 "" "")))
11067 (clobber (reg:CCFP FPSR_REG))
11068 (clobber (reg:CCFP FLAGS_REG))
11069 (clobber (match_scratch:HI 6 "=a"))]
11070 "reload_completed"
11071 [(const_int 0)]
11072 {
11073 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11074 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11075
11076 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11077 operands[3], operands[7],
11078 operands[4], operands[5], operands[6], operands[2]);
11079 DONE;
11080 })
11081 \f
11082 ;; Unconditional and other jump instructions
11083
11084 (define_insn "jump"
11085 [(set (pc)
11086 (label_ref (match_operand 0 "" "")))]
11087 ""
11088 "jmp\t%l0"
11089 [(set_attr "type" "ibr")
11090 (set (attr "length")
11091 (if_then_else (and (ge (minus (match_dup 0) (pc))
11092 (const_int -126))
11093 (lt (minus (match_dup 0) (pc))
11094 (const_int 128)))
11095 (const_int 2)
11096 (const_int 5)))
11097 (set_attr "modrm" "0")])
11098
11099 (define_expand "indirect_jump"
11100 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11101
11102 (define_insn "*indirect_jump"
11103 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11104 ""
11105 "jmp\t%A0"
11106 [(set_attr "type" "ibr")
11107 (set_attr "length_immediate" "0")])
11108
11109 (define_expand "tablejump"
11110 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11111 (use (label_ref (match_operand 1 "" "")))])]
11112 ""
11113 {
11114 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11115 relative. Convert the relative address to an absolute address. */
11116 if (flag_pic)
11117 {
11118 rtx op0, op1;
11119 enum rtx_code code;
11120
11121 /* We can't use @GOTOFF for text labels on VxWorks;
11122 see gotoff_operand. */
11123 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11124 {
11125 code = PLUS;
11126 op0 = operands[0];
11127 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11128 }
11129 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11130 {
11131 code = PLUS;
11132 op0 = operands[0];
11133 op1 = pic_offset_table_rtx;
11134 }
11135 else
11136 {
11137 code = MINUS;
11138 op0 = pic_offset_table_rtx;
11139 op1 = operands[0];
11140 }
11141
11142 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11143 OPTAB_DIRECT);
11144 }
11145 else if (TARGET_X32)
11146 operands[0] = convert_memory_address (Pmode, operands[0]);
11147 })
11148
11149 (define_insn "*tablejump_1"
11150 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11151 (use (label_ref (match_operand 1 "" "")))]
11152 ""
11153 "jmp\t%A0"
11154 [(set_attr "type" "ibr")
11155 (set_attr "length_immediate" "0")])
11156 \f
11157 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11158
11159 (define_peephole2
11160 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11161 (set (match_operand:QI 1 "register_operand" "")
11162 (match_operator:QI 2 "ix86_comparison_operator"
11163 [(reg FLAGS_REG) (const_int 0)]))
11164 (set (match_operand 3 "q_regs_operand" "")
11165 (zero_extend (match_dup 1)))]
11166 "(peep2_reg_dead_p (3, operands[1])
11167 || operands_match_p (operands[1], operands[3]))
11168 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11169 [(set (match_dup 4) (match_dup 0))
11170 (set (strict_low_part (match_dup 5))
11171 (match_dup 2))]
11172 {
11173 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11174 operands[5] = gen_lowpart (QImode, operands[3]);
11175 ix86_expand_clear (operands[3]);
11176 })
11177
11178 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11179
11180 (define_peephole2
11181 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11182 (set (match_operand:QI 1 "register_operand" "")
11183 (match_operator:QI 2 "ix86_comparison_operator"
11184 [(reg FLAGS_REG) (const_int 0)]))
11185 (parallel [(set (match_operand 3 "q_regs_operand" "")
11186 (zero_extend (match_dup 1)))
11187 (clobber (reg:CC FLAGS_REG))])]
11188 "(peep2_reg_dead_p (3, operands[1])
11189 || operands_match_p (operands[1], operands[3]))
11190 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11191 [(set (match_dup 4) (match_dup 0))
11192 (set (strict_low_part (match_dup 5))
11193 (match_dup 2))]
11194 {
11195 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11196 operands[5] = gen_lowpart (QImode, operands[3]);
11197 ix86_expand_clear (operands[3]);
11198 })
11199 \f
11200 ;; Call instructions.
11201
11202 ;; The predicates normally associated with named expanders are not properly
11203 ;; checked for calls. This is a bug in the generic code, but it isn't that
11204 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11205
11206 ;; P6 processors will jump to the address after the decrement when %esp
11207 ;; is used as a call operand, so they will execute return address as a code.
11208 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11209
11210 ;; Register constraint for call instruction.
11211 (define_mode_attr c [(SI "l") (DI "r")])
11212
11213 ;; Call subroutine returning no value.
11214
11215 (define_expand "call"
11216 [(call (match_operand:QI 0 "" "")
11217 (match_operand 1 "" ""))
11218 (use (match_operand 2 "" ""))]
11219 ""
11220 {
11221 ix86_expand_call (NULL, operands[0], operands[1],
11222 operands[2], NULL, false);
11223 DONE;
11224 })
11225
11226 (define_expand "sibcall"
11227 [(call (match_operand:QI 0 "" "")
11228 (match_operand 1 "" ""))
11229 (use (match_operand 2 "" ""))]
11230 ""
11231 {
11232 ix86_expand_call (NULL, operands[0], operands[1],
11233 operands[2], NULL, true);
11234 DONE;
11235 })
11236
11237 (define_insn_and_split "*call_vzeroupper"
11238 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11239 (match_operand 1 "" ""))
11240 (unspec [(match_operand 2 "const_int_operand" "")]
11241 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11242 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11243 "#"
11244 "&& reload_completed"
11245 [(const_int 0)]
11246 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11247 [(set_attr "type" "call")])
11248
11249 (define_insn "*call"
11250 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11251 (match_operand 1 "" ""))]
11252 "!SIBLING_CALL_P (insn)"
11253 "* return ix86_output_call_insn (insn, operands[0]);"
11254 [(set_attr "type" "call")])
11255
11256 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11257 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11258 (match_operand 1 "" ""))
11259 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11260 (clobber (reg:TI XMM6_REG))
11261 (clobber (reg:TI XMM7_REG))
11262 (clobber (reg:TI XMM8_REG))
11263 (clobber (reg:TI XMM9_REG))
11264 (clobber (reg:TI XMM10_REG))
11265 (clobber (reg:TI XMM11_REG))
11266 (clobber (reg:TI XMM12_REG))
11267 (clobber (reg:TI XMM13_REG))
11268 (clobber (reg:TI XMM14_REG))
11269 (clobber (reg:TI XMM15_REG))
11270 (clobber (reg:DI SI_REG))
11271 (clobber (reg:DI DI_REG))
11272 (unspec [(match_operand 2 "const_int_operand" "")]
11273 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11274 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11275 "#"
11276 "&& reload_completed"
11277 [(const_int 0)]
11278 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11279 [(set_attr "type" "call")])
11280
11281 (define_insn "*call_rex64_ms_sysv"
11282 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11283 (match_operand 1 "" ""))
11284 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11285 (clobber (reg:TI XMM6_REG))
11286 (clobber (reg:TI XMM7_REG))
11287 (clobber (reg:TI XMM8_REG))
11288 (clobber (reg:TI XMM9_REG))
11289 (clobber (reg:TI XMM10_REG))
11290 (clobber (reg:TI XMM11_REG))
11291 (clobber (reg:TI XMM12_REG))
11292 (clobber (reg:TI XMM13_REG))
11293 (clobber (reg:TI XMM14_REG))
11294 (clobber (reg:TI XMM15_REG))
11295 (clobber (reg:DI SI_REG))
11296 (clobber (reg:DI DI_REG))]
11297 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11298 "* return ix86_output_call_insn (insn, operands[0]);"
11299 [(set_attr "type" "call")])
11300
11301 (define_insn_and_split "*sibcall_vzeroupper"
11302 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11303 (match_operand 1 "" ""))
11304 (unspec [(match_operand 2 "const_int_operand" "")]
11305 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11306 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11307 "#"
11308 "&& reload_completed"
11309 [(const_int 0)]
11310 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11311 [(set_attr "type" "call")])
11312
11313 (define_insn "*sibcall"
11314 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11315 (match_operand 1 "" ""))]
11316 "SIBLING_CALL_P (insn)"
11317 "* return ix86_output_call_insn (insn, operands[0]);"
11318 [(set_attr "type" "call")])
11319
11320 (define_expand "call_pop"
11321 [(parallel [(call (match_operand:QI 0 "" "")
11322 (match_operand:SI 1 "" ""))
11323 (set (reg:SI SP_REG)
11324 (plus:SI (reg:SI SP_REG)
11325 (match_operand:SI 3 "" "")))])]
11326 "!TARGET_64BIT"
11327 {
11328 ix86_expand_call (NULL, operands[0], operands[1],
11329 operands[2], operands[3], false);
11330 DONE;
11331 })
11332
11333 (define_insn_and_split "*call_pop_vzeroupper"
11334 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11335 (match_operand:SI 1 "" ""))
11336 (set (reg:SI SP_REG)
11337 (plus:SI (reg:SI SP_REG)
11338 (match_operand:SI 2 "immediate_operand" "i")))
11339 (unspec [(match_operand 3 "const_int_operand" "")]
11340 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11341 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11342 "#"
11343 "&& reload_completed"
11344 [(const_int 0)]
11345 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11346 [(set_attr "type" "call")])
11347
11348 (define_insn "*call_pop"
11349 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11350 (match_operand 1 "" ""))
11351 (set (reg:SI SP_REG)
11352 (plus:SI (reg:SI SP_REG)
11353 (match_operand:SI 2 "immediate_operand" "i")))]
11354 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11355 "* return ix86_output_call_insn (insn, operands[0]);"
11356 [(set_attr "type" "call")])
11357
11358 (define_insn_and_split "*sibcall_pop_vzeroupper"
11359 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11360 (match_operand 1 "" ""))
11361 (set (reg:SI SP_REG)
11362 (plus:SI (reg:SI SP_REG)
11363 (match_operand:SI 2 "immediate_operand" "i")))
11364 (unspec [(match_operand 3 "const_int_operand" "")]
11365 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11366 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11367 "#"
11368 "&& reload_completed"
11369 [(const_int 0)]
11370 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11371 [(set_attr "type" "call")])
11372
11373 (define_insn "*sibcall_pop"
11374 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11375 (match_operand 1 "" ""))
11376 (set (reg:SI SP_REG)
11377 (plus:SI (reg:SI SP_REG)
11378 (match_operand:SI 2 "immediate_operand" "i")))]
11379 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11380 "* return ix86_output_call_insn (insn, operands[0]);"
11381 [(set_attr "type" "call")])
11382
11383 ;; Call subroutine, returning value in operand 0
11384
11385 (define_expand "call_value"
11386 [(set (match_operand 0 "" "")
11387 (call (match_operand:QI 1 "" "")
11388 (match_operand 2 "" "")))
11389 (use (match_operand 3 "" ""))]
11390 ""
11391 {
11392 ix86_expand_call (operands[0], operands[1], operands[2],
11393 operands[3], NULL, false);
11394 DONE;
11395 })
11396
11397 (define_expand "sibcall_value"
11398 [(set (match_operand 0 "" "")
11399 (call (match_operand:QI 1 "" "")
11400 (match_operand 2 "" "")))
11401 (use (match_operand 3 "" ""))]
11402 ""
11403 {
11404 ix86_expand_call (operands[0], operands[1], operands[2],
11405 operands[3], NULL, true);
11406 DONE;
11407 })
11408
11409 (define_insn_and_split "*call_value_vzeroupper"
11410 [(set (match_operand 0 "" "")
11411 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11412 (match_operand 2 "" "")))
11413 (unspec [(match_operand 3 "const_int_operand" "")]
11414 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11415 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11416 "#"
11417 "&& reload_completed"
11418 [(const_int 0)]
11419 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11420 [(set_attr "type" "callv")])
11421
11422 (define_insn "*call_value"
11423 [(set (match_operand 0 "" "")
11424 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11425 (match_operand 2 "" "")))]
11426 "!SIBLING_CALL_P (insn)"
11427 "* return ix86_output_call_insn (insn, operands[1]);"
11428 [(set_attr "type" "callv")])
11429
11430 (define_insn_and_split "*sibcall_value_vzeroupper"
11431 [(set (match_operand 0 "" "")
11432 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11433 (match_operand 2 "" "")))
11434 (unspec [(match_operand 3 "const_int_operand" "")]
11435 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11436 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11437 "#"
11438 "&& reload_completed"
11439 [(const_int 0)]
11440 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11441 [(set_attr "type" "callv")])
11442
11443 (define_insn "*sibcall_value"
11444 [(set (match_operand 0 "" "")
11445 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11446 (match_operand 2 "" "")))]
11447 "SIBLING_CALL_P (insn)"
11448 "* return ix86_output_call_insn (insn, operands[1]);"
11449 [(set_attr "type" "callv")])
11450
11451 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11452 [(set (match_operand 0 "" "")
11453 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11454 (match_operand 2 "" "")))
11455 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11456 (clobber (reg:TI XMM6_REG))
11457 (clobber (reg:TI XMM7_REG))
11458 (clobber (reg:TI XMM8_REG))
11459 (clobber (reg:TI XMM9_REG))
11460 (clobber (reg:TI XMM10_REG))
11461 (clobber (reg:TI XMM11_REG))
11462 (clobber (reg:TI XMM12_REG))
11463 (clobber (reg:TI XMM13_REG))
11464 (clobber (reg:TI XMM14_REG))
11465 (clobber (reg:TI XMM15_REG))
11466 (clobber (reg:DI SI_REG))
11467 (clobber (reg:DI DI_REG))
11468 (unspec [(match_operand 3 "const_int_operand" "")]
11469 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11470 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11471 "#"
11472 "&& reload_completed"
11473 [(const_int 0)]
11474 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11475 [(set_attr "type" "callv")])
11476
11477 (define_insn "*call_value_rex64_ms_sysv"
11478 [(set (match_operand 0 "" "")
11479 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11480 (match_operand 2 "" "")))
11481 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11482 (clobber (reg:TI XMM6_REG))
11483 (clobber (reg:TI XMM7_REG))
11484 (clobber (reg:TI XMM8_REG))
11485 (clobber (reg:TI XMM9_REG))
11486 (clobber (reg:TI XMM10_REG))
11487 (clobber (reg:TI XMM11_REG))
11488 (clobber (reg:TI XMM12_REG))
11489 (clobber (reg:TI XMM13_REG))
11490 (clobber (reg:TI XMM14_REG))
11491 (clobber (reg:TI XMM15_REG))
11492 (clobber (reg:DI SI_REG))
11493 (clobber (reg:DI DI_REG))]
11494 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11495 "* return ix86_output_call_insn (insn, operands[1]);"
11496 [(set_attr "type" "callv")])
11497
11498 (define_expand "call_value_pop"
11499 [(parallel [(set (match_operand 0 "" "")
11500 (call (match_operand:QI 1 "" "")
11501 (match_operand:SI 2 "" "")))
11502 (set (reg:SI SP_REG)
11503 (plus:SI (reg:SI SP_REG)
11504 (match_operand:SI 4 "" "")))])]
11505 "!TARGET_64BIT"
11506 {
11507 ix86_expand_call (operands[0], operands[1], operands[2],
11508 operands[3], operands[4], false);
11509 DONE;
11510 })
11511
11512 (define_insn_and_split "*call_value_pop_vzeroupper"
11513 [(set (match_operand 0 "" "")
11514 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11515 (match_operand 2 "" "")))
11516 (set (reg:SI SP_REG)
11517 (plus:SI (reg:SI SP_REG)
11518 (match_operand:SI 3 "immediate_operand" "i")))
11519 (unspec [(match_operand 4 "const_int_operand" "")]
11520 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11521 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11522 "#"
11523 "&& reload_completed"
11524 [(const_int 0)]
11525 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11526 [(set_attr "type" "callv")])
11527
11528 (define_insn "*call_value_pop"
11529 [(set (match_operand 0 "" "")
11530 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11531 (match_operand 2 "" "")))
11532 (set (reg:SI SP_REG)
11533 (plus:SI (reg:SI SP_REG)
11534 (match_operand:SI 3 "immediate_operand" "i")))]
11535 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11536 "* return ix86_output_call_insn (insn, operands[1]);"
11537 [(set_attr "type" "callv")])
11538
11539 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11540 [(set (match_operand 0 "" "")
11541 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11542 (match_operand 2 "" "")))
11543 (set (reg:SI SP_REG)
11544 (plus:SI (reg:SI SP_REG)
11545 (match_operand:SI 3 "immediate_operand" "i")))
11546 (unspec [(match_operand 4 "const_int_operand" "")]
11547 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11548 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11549 "#"
11550 "&& reload_completed"
11551 [(const_int 0)]
11552 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11553 [(set_attr "type" "callv")])
11554
11555 (define_insn "*sibcall_value_pop"
11556 [(set (match_operand 0 "" "")
11557 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11558 (match_operand 2 "" "")))
11559 (set (reg:SI SP_REG)
11560 (plus:SI (reg:SI SP_REG)
11561 (match_operand:SI 3 "immediate_operand" "i")))]
11562 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11563 "* return ix86_output_call_insn (insn, operands[1]);"
11564 [(set_attr "type" "callv")])
11565
11566 ;; Call subroutine returning any type.
11567
11568 (define_expand "untyped_call"
11569 [(parallel [(call (match_operand 0 "" "")
11570 (const_int 0))
11571 (match_operand 1 "" "")
11572 (match_operand 2 "" "")])]
11573 ""
11574 {
11575 int i;
11576
11577 /* In order to give reg-stack an easier job in validating two
11578 coprocessor registers as containing a possible return value,
11579 simply pretend the untyped call returns a complex long double
11580 value.
11581
11582 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11583 and should have the default ABI. */
11584
11585 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11586 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11587 operands[0], const0_rtx,
11588 GEN_INT ((TARGET_64BIT
11589 ? (ix86_abi == SYSV_ABI
11590 ? X86_64_SSE_REGPARM_MAX
11591 : X86_64_MS_SSE_REGPARM_MAX)
11592 : X86_32_SSE_REGPARM_MAX)
11593 - 1),
11594 NULL, false);
11595
11596 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11597 {
11598 rtx set = XVECEXP (operands[2], 0, i);
11599 emit_move_insn (SET_DEST (set), SET_SRC (set));
11600 }
11601
11602 /* The optimizer does not know that the call sets the function value
11603 registers we stored in the result block. We avoid problems by
11604 claiming that all hard registers are used and clobbered at this
11605 point. */
11606 emit_insn (gen_blockage ());
11607
11608 DONE;
11609 })
11610 \f
11611 ;; Prologue and epilogue instructions
11612
11613 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11614 ;; all of memory. This blocks insns from being moved across this point.
11615
11616 (define_insn "blockage"
11617 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11618 ""
11619 ""
11620 [(set_attr "length" "0")])
11621
11622 ;; Do not schedule instructions accessing memory across this point.
11623
11624 (define_expand "memory_blockage"
11625 [(set (match_dup 0)
11626 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11627 ""
11628 {
11629 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11630 MEM_VOLATILE_P (operands[0]) = 1;
11631 })
11632
11633 (define_insn "*memory_blockage"
11634 [(set (match_operand:BLK 0 "" "")
11635 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11636 ""
11637 ""
11638 [(set_attr "length" "0")])
11639
11640 ;; As USE insns aren't meaningful after reload, this is used instead
11641 ;; to prevent deleting instructions setting registers for PIC code
11642 (define_insn "prologue_use"
11643 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11644 ""
11645 ""
11646 [(set_attr "length" "0")])
11647
11648 ;; Insn emitted into the body of a function to return from a function.
11649 ;; This is only done if the function's epilogue is known to be simple.
11650 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11651
11652 (define_expand "return"
11653 [(simple_return)]
11654 "ix86_can_use_return_insn_p ()"
11655 {
11656 ix86_maybe_emit_epilogue_vzeroupper ();
11657 if (crtl->args.pops_args)
11658 {
11659 rtx popc = GEN_INT (crtl->args.pops_args);
11660 emit_jump_insn (gen_simple_return_pop_internal (popc));
11661 DONE;
11662 }
11663 })
11664
11665 ;; We need to disable this for TARGET_SEH, as otherwise
11666 ;; shrink-wrapped prologue gets enabled too. This might exceed
11667 ;; the maximum size of prologue in unwind information.
11668
11669 (define_expand "simple_return"
11670 [(simple_return)]
11671 "!TARGET_SEH"
11672 {
11673 ix86_maybe_emit_epilogue_vzeroupper ();
11674 if (crtl->args.pops_args)
11675 {
11676 rtx popc = GEN_INT (crtl->args.pops_args);
11677 emit_jump_insn (gen_simple_return_pop_internal (popc));
11678 DONE;
11679 }
11680 })
11681
11682 (define_insn "simple_return_internal"
11683 [(simple_return)]
11684 "reload_completed"
11685 "ret"
11686 [(set_attr "length" "1")
11687 (set_attr "atom_unit" "jeu")
11688 (set_attr "length_immediate" "0")
11689 (set_attr "modrm" "0")])
11690
11691 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11692 ;; instruction Athlon and K8 have.
11693
11694 (define_insn "simple_return_internal_long"
11695 [(simple_return)
11696 (unspec [(const_int 0)] UNSPEC_REP)]
11697 "reload_completed"
11698 "rep\;ret"
11699 [(set_attr "length" "2")
11700 (set_attr "atom_unit" "jeu")
11701 (set_attr "length_immediate" "0")
11702 (set_attr "prefix_rep" "1")
11703 (set_attr "modrm" "0")])
11704
11705 (define_insn "simple_return_pop_internal"
11706 [(simple_return)
11707 (use (match_operand:SI 0 "const_int_operand" ""))]
11708 "reload_completed"
11709 "ret\t%0"
11710 [(set_attr "length" "3")
11711 (set_attr "atom_unit" "jeu")
11712 (set_attr "length_immediate" "2")
11713 (set_attr "modrm" "0")])
11714
11715 (define_insn "simple_return_indirect_internal"
11716 [(simple_return)
11717 (use (match_operand:SI 0 "register_operand" "r"))]
11718 "reload_completed"
11719 "jmp\t%A0"
11720 [(set_attr "type" "ibr")
11721 (set_attr "length_immediate" "0")])
11722
11723 (define_insn "nop"
11724 [(const_int 0)]
11725 ""
11726 "nop"
11727 [(set_attr "length" "1")
11728 (set_attr "length_immediate" "0")
11729 (set_attr "modrm" "0")])
11730
11731 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11732 (define_insn "nops"
11733 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11734 UNSPECV_NOPS)]
11735 "reload_completed"
11736 {
11737 int num = INTVAL (operands[0]);
11738
11739 gcc_assert (num >= 1 && num <= 8);
11740
11741 while (num--)
11742 fputs ("\tnop\n", asm_out_file);
11743
11744 return "";
11745 }
11746 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11747 (set_attr "length_immediate" "0")
11748 (set_attr "modrm" "0")])
11749
11750 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11751 ;; branch prediction penalty for the third jump in a 16-byte
11752 ;; block on K8.
11753
11754 (define_insn "pad"
11755 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11756 ""
11757 {
11758 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11759 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11760 #else
11761 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11762 The align insn is used to avoid 3 jump instructions in the row to improve
11763 branch prediction and the benefits hardly outweigh the cost of extra 8
11764 nops on the average inserted by full alignment pseudo operation. */
11765 #endif
11766 return "";
11767 }
11768 [(set_attr "length" "16")])
11769
11770 (define_expand "prologue"
11771 [(const_int 0)]
11772 ""
11773 "ix86_expand_prologue (); DONE;")
11774
11775 (define_insn "set_got"
11776 [(set (match_operand:SI 0 "register_operand" "=r")
11777 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11778 (clobber (reg:CC FLAGS_REG))]
11779 "!TARGET_64BIT"
11780 "* return output_set_got (operands[0], NULL_RTX);"
11781 [(set_attr "type" "multi")
11782 (set_attr "length" "12")])
11783
11784 (define_insn "set_got_labelled"
11785 [(set (match_operand:SI 0 "register_operand" "=r")
11786 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11787 UNSPEC_SET_GOT))
11788 (clobber (reg:CC FLAGS_REG))]
11789 "!TARGET_64BIT"
11790 "* return output_set_got (operands[0], operands[1]);"
11791 [(set_attr "type" "multi")
11792 (set_attr "length" "12")])
11793
11794 (define_insn "set_got_rex64"
11795 [(set (match_operand:DI 0 "register_operand" "=r")
11796 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11797 "TARGET_64BIT"
11798 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11799 [(set_attr "type" "lea")
11800 (set_attr "length_address" "4")
11801 (set_attr "mode" "DI")])
11802
11803 (define_insn "set_rip_rex64"
11804 [(set (match_operand:DI 0 "register_operand" "=r")
11805 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11806 "TARGET_64BIT"
11807 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11808 [(set_attr "type" "lea")
11809 (set_attr "length_address" "4")
11810 (set_attr "mode" "DI")])
11811
11812 (define_insn "set_got_offset_rex64"
11813 [(set (match_operand:DI 0 "register_operand" "=r")
11814 (unspec:DI
11815 [(label_ref (match_operand 1 "" ""))]
11816 UNSPEC_SET_GOT_OFFSET))]
11817 "TARGET_LP64"
11818 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11819 [(set_attr "type" "imov")
11820 (set_attr "length_immediate" "0")
11821 (set_attr "length_address" "8")
11822 (set_attr "mode" "DI")])
11823
11824 (define_expand "epilogue"
11825 [(const_int 0)]
11826 ""
11827 "ix86_expand_epilogue (1); DONE;")
11828
11829 (define_expand "sibcall_epilogue"
11830 [(const_int 0)]
11831 ""
11832 "ix86_expand_epilogue (0); DONE;")
11833
11834 (define_expand "eh_return"
11835 [(use (match_operand 0 "register_operand" ""))]
11836 ""
11837 {
11838 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11839
11840 /* Tricky bit: we write the address of the handler to which we will
11841 be returning into someone else's stack frame, one word below the
11842 stack address we wish to restore. */
11843 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11844 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11845 tmp = gen_rtx_MEM (Pmode, tmp);
11846 emit_move_insn (tmp, ra);
11847
11848 emit_jump_insn (gen_eh_return_internal ());
11849 emit_barrier ();
11850 DONE;
11851 })
11852
11853 (define_insn_and_split "eh_return_internal"
11854 [(eh_return)]
11855 ""
11856 "#"
11857 "epilogue_completed"
11858 [(const_int 0)]
11859 "ix86_expand_epilogue (2); DONE;")
11860
11861 (define_insn "leave"
11862 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11863 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11864 (clobber (mem:BLK (scratch)))]
11865 "!TARGET_64BIT"
11866 "leave"
11867 [(set_attr "type" "leave")])
11868
11869 (define_insn "leave_rex64"
11870 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11871 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11872 (clobber (mem:BLK (scratch)))]
11873 "TARGET_64BIT"
11874 "leave"
11875 [(set_attr "type" "leave")])
11876 \f
11877 ;; Handle -fsplit-stack.
11878
11879 (define_expand "split_stack_prologue"
11880 [(const_int 0)]
11881 ""
11882 {
11883 ix86_expand_split_stack_prologue ();
11884 DONE;
11885 })
11886
11887 ;; In order to support the call/return predictor, we use a return
11888 ;; instruction which the middle-end doesn't see.
11889 (define_insn "split_stack_return"
11890 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11891 UNSPECV_SPLIT_STACK_RETURN)]
11892 ""
11893 {
11894 if (operands[0] == const0_rtx)
11895 return "ret";
11896 else
11897 return "ret\t%0";
11898 }
11899 [(set_attr "atom_unit" "jeu")
11900 (set_attr "modrm" "0")
11901 (set (attr "length")
11902 (if_then_else (match_operand:SI 0 "const0_operand" "")
11903 (const_int 1)
11904 (const_int 3)))
11905 (set (attr "length_immediate")
11906 (if_then_else (match_operand:SI 0 "const0_operand" "")
11907 (const_int 0)
11908 (const_int 2)))])
11909
11910 ;; If there are operand 0 bytes available on the stack, jump to
11911 ;; operand 1.
11912
11913 (define_expand "split_stack_space_check"
11914 [(set (pc) (if_then_else
11915 (ltu (minus (reg SP_REG)
11916 (match_operand 0 "register_operand" ""))
11917 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11918 (label_ref (match_operand 1 "" ""))
11919 (pc)))]
11920 ""
11921 {
11922 rtx reg, size, limit;
11923
11924 reg = gen_reg_rtx (Pmode);
11925 size = force_reg (Pmode, operands[0]);
11926 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11927 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11928 UNSPEC_STACK_CHECK);
11929 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11930 ix86_expand_branch (GEU, reg, limit, operands[1]);
11931
11932 DONE;
11933 })
11934 \f
11935 ;; Bit manipulation instructions.
11936
11937 (define_expand "ffs<mode>2"
11938 [(set (match_dup 2) (const_int -1))
11939 (parallel [(set (reg:CCZ FLAGS_REG)
11940 (compare:CCZ
11941 (match_operand:SWI48 1 "nonimmediate_operand" "")
11942 (const_int 0)))
11943 (set (match_operand:SWI48 0 "register_operand" "")
11944 (ctz:SWI48 (match_dup 1)))])
11945 (set (match_dup 0) (if_then_else:SWI48
11946 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11947 (match_dup 2)
11948 (match_dup 0)))
11949 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11950 (clobber (reg:CC FLAGS_REG))])]
11951 ""
11952 {
11953 if (<MODE>mode == SImode && !TARGET_CMOVE)
11954 {
11955 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11956 DONE;
11957 }
11958 operands[2] = gen_reg_rtx (<MODE>mode);
11959 })
11960
11961 (define_insn_and_split "ffssi2_no_cmove"
11962 [(set (match_operand:SI 0 "register_operand" "=r")
11963 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11964 (clobber (match_scratch:SI 2 "=&q"))
11965 (clobber (reg:CC FLAGS_REG))]
11966 "!TARGET_CMOVE"
11967 "#"
11968 "&& reload_completed"
11969 [(parallel [(set (reg:CCZ FLAGS_REG)
11970 (compare:CCZ (match_dup 1) (const_int 0)))
11971 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11972 (set (strict_low_part (match_dup 3))
11973 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11974 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11975 (clobber (reg:CC FLAGS_REG))])
11976 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11977 (clobber (reg:CC FLAGS_REG))])
11978 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11979 (clobber (reg:CC FLAGS_REG))])]
11980 {
11981 operands[3] = gen_lowpart (QImode, operands[2]);
11982 ix86_expand_clear (operands[2]);
11983 })
11984
11985 (define_insn "*ffs<mode>_1"
11986 [(set (reg:CCZ FLAGS_REG)
11987 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11988 (const_int 0)))
11989 (set (match_operand:SWI48 0 "register_operand" "=r")
11990 (ctz:SWI48 (match_dup 1)))]
11991 ""
11992 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11993 [(set_attr "type" "alu1")
11994 (set_attr "prefix_0f" "1")
11995 (set_attr "mode" "<MODE>")])
11996
11997 (define_insn "ctz<mode>2"
11998 [(set (match_operand:SWI248 0 "register_operand" "=r")
11999 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12000 (clobber (reg:CC FLAGS_REG))]
12001 ""
12002 {
12003 if (TARGET_BMI)
12004 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12005 else
12006 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12007 }
12008 [(set_attr "type" "alu1")
12009 (set_attr "prefix_0f" "1")
12010 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12011 (set_attr "mode" "<MODE>")])
12012
12013 (define_expand "clz<mode>2"
12014 [(parallel
12015 [(set (match_operand:SWI248 0 "register_operand" "")
12016 (minus:SWI248
12017 (match_dup 2)
12018 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12019 (clobber (reg:CC FLAGS_REG))])
12020 (parallel
12021 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12022 (clobber (reg:CC FLAGS_REG))])]
12023 ""
12024 {
12025 if (TARGET_LZCNT)
12026 {
12027 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12028 DONE;
12029 }
12030 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12031 })
12032
12033 (define_insn "clz<mode>2_lzcnt"
12034 [(set (match_operand:SWI248 0 "register_operand" "=r")
12035 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12036 (clobber (reg:CC FLAGS_REG))]
12037 "TARGET_LZCNT"
12038 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12039 [(set_attr "prefix_rep" "1")
12040 (set_attr "type" "bitmanip")
12041 (set_attr "mode" "<MODE>")])
12042
12043 ;; BMI instructions.
12044 (define_insn "*bmi_andn_<mode>"
12045 [(set (match_operand:SWI48 0 "register_operand" "=r")
12046 (and:SWI48
12047 (not:SWI48
12048 (match_operand:SWI48 1 "register_operand" "r"))
12049 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12050 (clobber (reg:CC FLAGS_REG))]
12051 "TARGET_BMI"
12052 "andn\t{%2, %1, %0|%0, %1, %2}"
12053 [(set_attr "type" "bitmanip")
12054 (set_attr "mode" "<MODE>")])
12055
12056 (define_insn "bmi_bextr_<mode>"
12057 [(set (match_operand:SWI48 0 "register_operand" "=r")
12058 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12059 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12060 UNSPEC_BEXTR))
12061 (clobber (reg:CC FLAGS_REG))]
12062 "TARGET_BMI"
12063 "bextr\t{%2, %1, %0|%0, %1, %2}"
12064 [(set_attr "type" "bitmanip")
12065 (set_attr "mode" "<MODE>")])
12066
12067 (define_insn "*bmi_blsi_<mode>"
12068 [(set (match_operand:SWI48 0 "register_operand" "=r")
12069 (and:SWI48
12070 (neg:SWI48
12071 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12072 (match_dup 1)))
12073 (clobber (reg:CC FLAGS_REG))]
12074 "TARGET_BMI"
12075 "blsi\t{%1, %0|%0, %1}"
12076 [(set_attr "type" "bitmanip")
12077 (set_attr "mode" "<MODE>")])
12078
12079 (define_insn "*bmi_blsmsk_<mode>"
12080 [(set (match_operand:SWI48 0 "register_operand" "=r")
12081 (xor:SWI48
12082 (plus:SWI48
12083 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12084 (const_int -1))
12085 (match_dup 1)))
12086 (clobber (reg:CC FLAGS_REG))]
12087 "TARGET_BMI"
12088 "blsmsk\t{%1, %0|%0, %1}"
12089 [(set_attr "type" "bitmanip")
12090 (set_attr "mode" "<MODE>")])
12091
12092 (define_insn "*bmi_blsr_<mode>"
12093 [(set (match_operand:SWI48 0 "register_operand" "=r")
12094 (and:SWI48
12095 (plus:SWI48
12096 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12097 (const_int -1))
12098 (match_dup 1)))
12099 (clobber (reg:CC FLAGS_REG))]
12100 "TARGET_BMI"
12101 "blsr\t{%1, %0|%0, %1}"
12102 [(set_attr "type" "bitmanip")
12103 (set_attr "mode" "<MODE>")])
12104
12105 ;; BMI2 instructions.
12106 (define_insn "bmi2_bzhi_<mode>3"
12107 [(set (match_operand:SWI48 0 "register_operand" "=r")
12108 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12109 (lshiftrt:SWI48 (const_int -1)
12110 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12111 (clobber (reg:CC FLAGS_REG))]
12112 "TARGET_BMI2"
12113 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12114 [(set_attr "type" "bitmanip")
12115 (set_attr "prefix" "vex")
12116 (set_attr "mode" "<MODE>")])
12117
12118 (define_insn "bmi2_pdep_<mode>3"
12119 [(set (match_operand:SWI48 0 "register_operand" "=r")
12120 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12121 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12122 UNSPEC_PDEP))]
12123 "TARGET_BMI2"
12124 "pdep\t{%2, %1, %0|%0, %1, %2}"
12125 [(set_attr "type" "bitmanip")
12126 (set_attr "prefix" "vex")
12127 (set_attr "mode" "<MODE>")])
12128
12129 (define_insn "bmi2_pext_<mode>3"
12130 [(set (match_operand:SWI48 0 "register_operand" "=r")
12131 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12132 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12133 UNSPEC_PEXT))]
12134 "TARGET_BMI2"
12135 "pext\t{%2, %1, %0|%0, %1, %2}"
12136 [(set_attr "type" "bitmanip")
12137 (set_attr "prefix" "vex")
12138 (set_attr "mode" "<MODE>")])
12139
12140 ;; TBM instructions.
12141 (define_insn "tbm_bextri_<mode>"
12142 [(set (match_operand:SWI48 0 "register_operand" "=r")
12143 (zero_extract:SWI48
12144 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12145 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12146 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12147 (clobber (reg:CC FLAGS_REG))]
12148 "TARGET_TBM"
12149 {
12150 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12151 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12152 }
12153 [(set_attr "type" "bitmanip")
12154 (set_attr "mode" "<MODE>")])
12155
12156 (define_insn "*tbm_blcfill_<mode>"
12157 [(set (match_operand:SWI48 0 "register_operand" "=r")
12158 (and:SWI48
12159 (plus:SWI48
12160 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12161 (const_int 1))
12162 (match_dup 1)))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "TARGET_TBM"
12165 "blcfill\t{%1, %0|%0, %1}"
12166 [(set_attr "type" "bitmanip")
12167 (set_attr "mode" "<MODE>")])
12168
12169 (define_insn "*tbm_blci_<mode>"
12170 [(set (match_operand:SWI48 0 "register_operand" "=r")
12171 (ior:SWI48
12172 (not:SWI48
12173 (plus:SWI48
12174 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12175 (const_int 1)))
12176 (match_dup 1)))
12177 (clobber (reg:CC FLAGS_REG))]
12178 "TARGET_TBM"
12179 "blci\t{%1, %0|%0, %1}"
12180 [(set_attr "type" "bitmanip")
12181 (set_attr "mode" "<MODE>")])
12182
12183 (define_insn "*tbm_blcic_<mode>"
12184 [(set (match_operand:SWI48 0 "register_operand" "=r")
12185 (and:SWI48
12186 (plus:SWI48
12187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12188 (const_int 1))
12189 (not:SWI48
12190 (match_dup 1))))
12191 (clobber (reg:CC FLAGS_REG))]
12192 "TARGET_TBM"
12193 "blcic\t{%1, %0|%0, %1}"
12194 [(set_attr "type" "bitmanip")
12195 (set_attr "mode" "<MODE>")])
12196
12197 (define_insn "*tbm_blcmsk_<mode>"
12198 [(set (match_operand:SWI48 0 "register_operand" "=r")
12199 (xor:SWI48
12200 (plus:SWI48
12201 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12202 (const_int 1))
12203 (match_dup 1)))
12204 (clobber (reg:CC FLAGS_REG))]
12205 "TARGET_TBM"
12206 "blcmsk\t{%1, %0|%0, %1}"
12207 [(set_attr "type" "bitmanip")
12208 (set_attr "mode" "<MODE>")])
12209
12210 (define_insn "*tbm_blcs_<mode>"
12211 [(set (match_operand:SWI48 0 "register_operand" "=r")
12212 (ior:SWI48
12213 (plus:SWI48
12214 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12215 (const_int 1))
12216 (match_dup 1)))
12217 (clobber (reg:CC FLAGS_REG))]
12218 "TARGET_TBM"
12219 "blcs\t{%1, %0|%0, %1}"
12220 [(set_attr "type" "bitmanip")
12221 (set_attr "mode" "<MODE>")])
12222
12223 (define_insn "*tbm_blsfill_<mode>"
12224 [(set (match_operand:SWI48 0 "register_operand" "=r")
12225 (ior:SWI48
12226 (plus:SWI48
12227 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12228 (const_int -1))
12229 (match_dup 1)))
12230 (clobber (reg:CC FLAGS_REG))]
12231 "TARGET_TBM"
12232 "blsfill\t{%1, %0|%0, %1}"
12233 [(set_attr "type" "bitmanip")
12234 (set_attr "mode" "<MODE>")])
12235
12236 (define_insn "*tbm_blsic_<mode>"
12237 [(set (match_operand:SWI48 0 "register_operand" "=r")
12238 (ior:SWI48
12239 (plus:SWI48
12240 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12241 (const_int -1))
12242 (not:SWI48
12243 (match_dup 1))))
12244 (clobber (reg:CC FLAGS_REG))]
12245 "TARGET_TBM"
12246 "blsic\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "bitmanip")
12248 (set_attr "mode" "<MODE>")])
12249
12250 (define_insn "*tbm_t1mskc_<mode>"
12251 [(set (match_operand:SWI48 0 "register_operand" "=r")
12252 (ior:SWI48
12253 (plus:SWI48
12254 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12255 (const_int 1))
12256 (not:SWI48
12257 (match_dup 1))))
12258 (clobber (reg:CC FLAGS_REG))]
12259 "TARGET_TBM"
12260 "t1mskc\t{%1, %0|%0, %1}"
12261 [(set_attr "type" "bitmanip")
12262 (set_attr "mode" "<MODE>")])
12263
12264 (define_insn "*tbm_tzmsk_<mode>"
12265 [(set (match_operand:SWI48 0 "register_operand" "=r")
12266 (and:SWI48
12267 (plus:SWI48
12268 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12269 (const_int -1))
12270 (not:SWI48
12271 (match_dup 1))))
12272 (clobber (reg:CC FLAGS_REG))]
12273 "TARGET_TBM"
12274 "tzmsk\t{%1, %0|%0, %1}"
12275 [(set_attr "type" "bitmanip")
12276 (set_attr "mode" "<MODE>")])
12277
12278 (define_insn "bsr_rex64"
12279 [(set (match_operand:DI 0 "register_operand" "=r")
12280 (minus:DI (const_int 63)
12281 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12282 (clobber (reg:CC FLAGS_REG))]
12283 "TARGET_64BIT"
12284 "bsr{q}\t{%1, %0|%0, %1}"
12285 [(set_attr "type" "alu1")
12286 (set_attr "prefix_0f" "1")
12287 (set_attr "mode" "DI")])
12288
12289 (define_insn "bsr"
12290 [(set (match_operand:SI 0 "register_operand" "=r")
12291 (minus:SI (const_int 31)
12292 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12293 (clobber (reg:CC FLAGS_REG))]
12294 ""
12295 "bsr{l}\t{%1, %0|%0, %1}"
12296 [(set_attr "type" "alu1")
12297 (set_attr "prefix_0f" "1")
12298 (set_attr "mode" "SI")])
12299
12300 (define_insn "*bsrhi"
12301 [(set (match_operand:HI 0 "register_operand" "=r")
12302 (minus:HI (const_int 15)
12303 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12304 (clobber (reg:CC FLAGS_REG))]
12305 ""
12306 "bsr{w}\t{%1, %0|%0, %1}"
12307 [(set_attr "type" "alu1")
12308 (set_attr "prefix_0f" "1")
12309 (set_attr "mode" "HI")])
12310
12311 (define_insn "popcount<mode>2"
12312 [(set (match_operand:SWI248 0 "register_operand" "=r")
12313 (popcount:SWI248
12314 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12315 (clobber (reg:CC FLAGS_REG))]
12316 "TARGET_POPCNT"
12317 {
12318 #if TARGET_MACHO
12319 return "popcnt\t{%1, %0|%0, %1}";
12320 #else
12321 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12322 #endif
12323 }
12324 [(set_attr "prefix_rep" "1")
12325 (set_attr "type" "bitmanip")
12326 (set_attr "mode" "<MODE>")])
12327
12328 (define_insn "*popcount<mode>2_cmp"
12329 [(set (reg FLAGS_REG)
12330 (compare
12331 (popcount:SWI248
12332 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12333 (const_int 0)))
12334 (set (match_operand:SWI248 0 "register_operand" "=r")
12335 (popcount:SWI248 (match_dup 1)))]
12336 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12337 {
12338 #if TARGET_MACHO
12339 return "popcnt\t{%1, %0|%0, %1}";
12340 #else
12341 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12342 #endif
12343 }
12344 [(set_attr "prefix_rep" "1")
12345 (set_attr "type" "bitmanip")
12346 (set_attr "mode" "<MODE>")])
12347
12348 (define_insn "*popcountsi2_cmp_zext"
12349 [(set (reg FLAGS_REG)
12350 (compare
12351 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12352 (const_int 0)))
12353 (set (match_operand:DI 0 "register_operand" "=r")
12354 (zero_extend:DI(popcount:SI (match_dup 1))))]
12355 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12356 {
12357 #if TARGET_MACHO
12358 return "popcnt\t{%1, %0|%0, %1}";
12359 #else
12360 return "popcnt{l}\t{%1, %0|%0, %1}";
12361 #endif
12362 }
12363 [(set_attr "prefix_rep" "1")
12364 (set_attr "type" "bitmanip")
12365 (set_attr "mode" "SI")])
12366
12367 (define_expand "bswap<mode>2"
12368 [(set (match_operand:SWI48 0 "register_operand" "")
12369 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12370 ""
12371 {
12372 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12373 {
12374 rtx x = operands[0];
12375
12376 emit_move_insn (x, operands[1]);
12377 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12378 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12379 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12380 DONE;
12381 }
12382 })
12383
12384 (define_insn "*bswap<mode>2_movbe"
12385 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12386 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12387 "TARGET_MOVBE
12388 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12389 "@
12390 bswap\t%0
12391 movbe\t{%1, %0|%0, %1}
12392 movbe\t{%1, %0|%0, %1}"
12393 [(set_attr "type" "bitmanip,imov,imov")
12394 (set_attr "modrm" "0,1,1")
12395 (set_attr "prefix_0f" "*,1,1")
12396 (set_attr "prefix_extra" "*,1,1")
12397 (set_attr "mode" "<MODE>")])
12398
12399 (define_insn "*bswap<mode>2_1"
12400 [(set (match_operand:SWI48 0 "register_operand" "=r")
12401 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12402 "TARGET_BSWAP"
12403 "bswap\t%0"
12404 [(set_attr "type" "bitmanip")
12405 (set_attr "modrm" "0")
12406 (set_attr "mode" "<MODE>")])
12407
12408 (define_insn "*bswaphi_lowpart_1"
12409 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12410 (bswap:HI (match_dup 0)))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12413 "@
12414 xchg{b}\t{%h0, %b0|%b0, %h0}
12415 rol{w}\t{$8, %0|%0, 8}"
12416 [(set_attr "length" "2,4")
12417 (set_attr "mode" "QI,HI")])
12418
12419 (define_insn "bswaphi_lowpart"
12420 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12421 (bswap:HI (match_dup 0)))
12422 (clobber (reg:CC FLAGS_REG))]
12423 ""
12424 "rol{w}\t{$8, %0|%0, 8}"
12425 [(set_attr "length" "4")
12426 (set_attr "mode" "HI")])
12427
12428 (define_expand "paritydi2"
12429 [(set (match_operand:DI 0 "register_operand" "")
12430 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12431 "! TARGET_POPCNT"
12432 {
12433 rtx scratch = gen_reg_rtx (QImode);
12434 rtx cond;
12435
12436 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12437 NULL_RTX, operands[1]));
12438
12439 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12440 gen_rtx_REG (CCmode, FLAGS_REG),
12441 const0_rtx);
12442 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12443
12444 if (TARGET_64BIT)
12445 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12446 else
12447 {
12448 rtx tmp = gen_reg_rtx (SImode);
12449
12450 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12451 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12452 }
12453 DONE;
12454 })
12455
12456 (define_expand "paritysi2"
12457 [(set (match_operand:SI 0 "register_operand" "")
12458 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12459 "! TARGET_POPCNT"
12460 {
12461 rtx scratch = gen_reg_rtx (QImode);
12462 rtx cond;
12463
12464 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12465
12466 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12467 gen_rtx_REG (CCmode, FLAGS_REG),
12468 const0_rtx);
12469 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12470
12471 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12472 DONE;
12473 })
12474
12475 (define_insn_and_split "paritydi2_cmp"
12476 [(set (reg:CC FLAGS_REG)
12477 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12478 UNSPEC_PARITY))
12479 (clobber (match_scratch:DI 0 "=r"))
12480 (clobber (match_scratch:SI 1 "=&r"))
12481 (clobber (match_scratch:HI 2 "=Q"))]
12482 "! TARGET_POPCNT"
12483 "#"
12484 "&& reload_completed"
12485 [(parallel
12486 [(set (match_dup 1)
12487 (xor:SI (match_dup 1) (match_dup 4)))
12488 (clobber (reg:CC FLAGS_REG))])
12489 (parallel
12490 [(set (reg:CC FLAGS_REG)
12491 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12492 (clobber (match_dup 1))
12493 (clobber (match_dup 2))])]
12494 {
12495 operands[4] = gen_lowpart (SImode, operands[3]);
12496
12497 if (TARGET_64BIT)
12498 {
12499 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12500 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12501 }
12502 else
12503 operands[1] = gen_highpart (SImode, operands[3]);
12504 })
12505
12506 (define_insn_and_split "paritysi2_cmp"
12507 [(set (reg:CC FLAGS_REG)
12508 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12509 UNSPEC_PARITY))
12510 (clobber (match_scratch:SI 0 "=r"))
12511 (clobber (match_scratch:HI 1 "=&Q"))]
12512 "! TARGET_POPCNT"
12513 "#"
12514 "&& reload_completed"
12515 [(parallel
12516 [(set (match_dup 1)
12517 (xor:HI (match_dup 1) (match_dup 3)))
12518 (clobber (reg:CC FLAGS_REG))])
12519 (parallel
12520 [(set (reg:CC FLAGS_REG)
12521 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12522 (clobber (match_dup 1))])]
12523 {
12524 operands[3] = gen_lowpart (HImode, operands[2]);
12525
12526 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12527 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12528 })
12529
12530 (define_insn "*parityhi2_cmp"
12531 [(set (reg:CC FLAGS_REG)
12532 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12533 UNSPEC_PARITY))
12534 (clobber (match_scratch:HI 0 "=Q"))]
12535 "! TARGET_POPCNT"
12536 "xor{b}\t{%h0, %b0|%b0, %h0}"
12537 [(set_attr "length" "2")
12538 (set_attr "mode" "HI")])
12539
12540 \f
12541 ;; Thread-local storage patterns for ELF.
12542 ;;
12543 ;; Note that these code sequences must appear exactly as shown
12544 ;; in order to allow linker relaxation.
12545
12546 (define_insn "*tls_global_dynamic_32_gnu"
12547 [(set (match_operand:SI 0 "register_operand" "=a")
12548 (unspec:SI
12549 [(match_operand:SI 1 "register_operand" "b")
12550 (match_operand:SI 2 "tls_symbolic_operand" "")
12551 (match_operand:SI 3 "constant_call_address_operand" "z")]
12552 UNSPEC_TLS_GD))
12553 (clobber (match_scratch:SI 4 "=d"))
12554 (clobber (match_scratch:SI 5 "=c"))
12555 (clobber (reg:CC FLAGS_REG))]
12556 "!TARGET_64BIT && TARGET_GNU_TLS"
12557 {
12558 output_asm_insn
12559 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12560 if (TARGET_SUN_TLS)
12561 #ifdef HAVE_AS_IX86_TLSGDPLT
12562 return "call\t%a2@tlsgdplt";
12563 #else
12564 return "call\t%p3@plt";
12565 #endif
12566 return "call\t%P3";
12567 }
12568 [(set_attr "type" "multi")
12569 (set_attr "length" "12")])
12570
12571 (define_expand "tls_global_dynamic_32"
12572 [(parallel
12573 [(set (match_operand:SI 0 "register_operand" "")
12574 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12575 (match_operand:SI 1 "tls_symbolic_operand" "")
12576 (match_operand:SI 3 "constant_call_address_operand" "")]
12577 UNSPEC_TLS_GD))
12578 (clobber (match_scratch:SI 4 ""))
12579 (clobber (match_scratch:SI 5 ""))
12580 (clobber (reg:CC FLAGS_REG))])])
12581
12582 (define_insn "*tls_global_dynamic_64"
12583 [(set (match_operand:DI 0 "register_operand" "=a")
12584 (call:DI
12585 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12586 (match_operand:DI 3 "" "")))
12587 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12588 UNSPEC_TLS_GD)]
12589 "TARGET_64BIT"
12590 {
12591 if (!TARGET_X32)
12592 fputs (ASM_BYTE "0x66\n", asm_out_file);
12593 output_asm_insn
12594 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12595 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12596 fputs ("\trex64\n", asm_out_file);
12597 if (TARGET_SUN_TLS)
12598 return "call\t%p2@plt";
12599 return "call\t%P2";
12600 }
12601 [(set_attr "type" "multi")
12602 (set (attr "length")
12603 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12604
12605 (define_expand "tls_global_dynamic_64"
12606 [(parallel
12607 [(set (match_operand:DI 0 "register_operand" "")
12608 (call:DI
12609 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12610 (const_int 0)))
12611 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12612 UNSPEC_TLS_GD)])])
12613
12614 (define_insn "*tls_local_dynamic_base_32_gnu"
12615 [(set (match_operand:SI 0 "register_operand" "=a")
12616 (unspec:SI
12617 [(match_operand:SI 1 "register_operand" "b")
12618 (match_operand:SI 2 "constant_call_address_operand" "z")]
12619 UNSPEC_TLS_LD_BASE))
12620 (clobber (match_scratch:SI 3 "=d"))
12621 (clobber (match_scratch:SI 4 "=c"))
12622 (clobber (reg:CC FLAGS_REG))]
12623 "!TARGET_64BIT && TARGET_GNU_TLS"
12624 {
12625 output_asm_insn
12626 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12627 if (TARGET_SUN_TLS)
12628 #ifdef HAVE_AS_IX86_TLSLDMPLT
12629 return "call\t%&@tlsldmplt";
12630 #else
12631 return "call\t%p2@plt";
12632 #endif
12633 return "call\t%P2";
12634 }
12635 [(set_attr "type" "multi")
12636 (set_attr "length" "11")])
12637
12638 (define_expand "tls_local_dynamic_base_32"
12639 [(parallel
12640 [(set (match_operand:SI 0 "register_operand" "")
12641 (unspec:SI
12642 [(match_operand:SI 1 "register_operand" "")
12643 (match_operand:SI 2 "constant_call_address_operand" "")]
12644 UNSPEC_TLS_LD_BASE))
12645 (clobber (match_scratch:SI 3 ""))
12646 (clobber (match_scratch:SI 4 ""))
12647 (clobber (reg:CC FLAGS_REG))])])
12648
12649 (define_insn "*tls_local_dynamic_base_64"
12650 [(set (match_operand:DI 0 "register_operand" "=a")
12651 (call:DI
12652 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12653 (match_operand:DI 2 "" "")))
12654 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12655 "TARGET_64BIT"
12656 {
12657 output_asm_insn
12658 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12659 if (TARGET_SUN_TLS)
12660 return "call\t%p1@plt";
12661 return "call\t%P1";
12662 }
12663 [(set_attr "type" "multi")
12664 (set_attr "length" "12")])
12665
12666 (define_expand "tls_local_dynamic_base_64"
12667 [(parallel
12668 [(set (match_operand:DI 0 "register_operand" "")
12669 (call:DI
12670 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12671 (const_int 0)))
12672 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12673
12674 ;; Local dynamic of a single variable is a lose. Show combine how
12675 ;; to convert that back to global dynamic.
12676
12677 (define_insn_and_split "*tls_local_dynamic_32_once"
12678 [(set (match_operand:SI 0 "register_operand" "=a")
12679 (plus:SI
12680 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12681 (match_operand:SI 2 "constant_call_address_operand" "z")]
12682 UNSPEC_TLS_LD_BASE)
12683 (const:SI (unspec:SI
12684 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12685 UNSPEC_DTPOFF))))
12686 (clobber (match_scratch:SI 4 "=d"))
12687 (clobber (match_scratch:SI 5 "=c"))
12688 (clobber (reg:CC FLAGS_REG))]
12689 ""
12690 "#"
12691 ""
12692 [(parallel
12693 [(set (match_dup 0)
12694 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12695 UNSPEC_TLS_GD))
12696 (clobber (match_dup 4))
12697 (clobber (match_dup 5))
12698 (clobber (reg:CC FLAGS_REG))])])
12699
12700 ;; Segment register for the thread base ptr load
12701 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12702
12703 ;; Load and add the thread base pointer from %<tp_seg>:0.
12704 (define_insn "*load_tp_x32"
12705 [(set (match_operand:SI 0 "register_operand" "=r")
12706 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12707 "TARGET_X32"
12708 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12709 [(set_attr "type" "imov")
12710 (set_attr "modrm" "0")
12711 (set_attr "length" "7")
12712 (set_attr "memory" "load")
12713 (set_attr "imm_disp" "false")])
12714
12715 (define_insn "*load_tp_x32_zext"
12716 [(set (match_operand:DI 0 "register_operand" "=r")
12717 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12718 "TARGET_X32"
12719 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12720 [(set_attr "type" "imov")
12721 (set_attr "modrm" "0")
12722 (set_attr "length" "7")
12723 (set_attr "memory" "load")
12724 (set_attr "imm_disp" "false")])
12725
12726 (define_insn "*load_tp_<mode>"
12727 [(set (match_operand:P 0 "register_operand" "=r")
12728 (unspec:P [(const_int 0)] UNSPEC_TP))]
12729 "!TARGET_X32"
12730 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12731 [(set_attr "type" "imov")
12732 (set_attr "modrm" "0")
12733 (set_attr "length" "7")
12734 (set_attr "memory" "load")
12735 (set_attr "imm_disp" "false")])
12736
12737 (define_insn "*add_tp_x32"
12738 [(set (match_operand:SI 0 "register_operand" "=r")
12739 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12740 (match_operand:SI 1 "register_operand" "0")))
12741 (clobber (reg:CC FLAGS_REG))]
12742 "TARGET_X32"
12743 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12744 [(set_attr "type" "alu")
12745 (set_attr "modrm" "0")
12746 (set_attr "length" "7")
12747 (set_attr "memory" "load")
12748 (set_attr "imm_disp" "false")])
12749
12750 (define_insn "*add_tp_x32_zext"
12751 [(set (match_operand:DI 0 "register_operand" "=r")
12752 (zero_extend:DI
12753 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12754 (match_operand:SI 1 "register_operand" "0"))))
12755 (clobber (reg:CC FLAGS_REG))]
12756 "TARGET_X32"
12757 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12758 [(set_attr "type" "alu")
12759 (set_attr "modrm" "0")
12760 (set_attr "length" "7")
12761 (set_attr "memory" "load")
12762 (set_attr "imm_disp" "false")])
12763
12764 (define_insn "*add_tp_<mode>"
12765 [(set (match_operand:P 0 "register_operand" "=r")
12766 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12767 (match_operand:P 1 "register_operand" "0")))
12768 (clobber (reg:CC FLAGS_REG))]
12769 "!TARGET_X32"
12770 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12771 [(set_attr "type" "alu")
12772 (set_attr "modrm" "0")
12773 (set_attr "length" "7")
12774 (set_attr "memory" "load")
12775 (set_attr "imm_disp" "false")])
12776
12777 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12778 ;; %rax as destination of the initial executable code sequence.
12779 (define_insn "tls_initial_exec_64_sun"
12780 [(set (match_operand:DI 0 "register_operand" "=a")
12781 (unspec:DI
12782 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12783 UNSPEC_TLS_IE_SUN))
12784 (clobber (reg:CC FLAGS_REG))]
12785 "TARGET_64BIT && TARGET_SUN_TLS"
12786 {
12787 output_asm_insn
12788 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12789 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12790 }
12791 [(set_attr "type" "multi")])
12792
12793 ;; GNU2 TLS patterns can be split.
12794
12795 (define_expand "tls_dynamic_gnu2_32"
12796 [(set (match_dup 3)
12797 (plus:SI (match_operand:SI 2 "register_operand" "")
12798 (const:SI
12799 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12800 UNSPEC_TLSDESC))))
12801 (parallel
12802 [(set (match_operand:SI 0 "register_operand" "")
12803 (unspec:SI [(match_dup 1) (match_dup 3)
12804 (match_dup 2) (reg:SI SP_REG)]
12805 UNSPEC_TLSDESC))
12806 (clobber (reg:CC FLAGS_REG))])]
12807 "!TARGET_64BIT && TARGET_GNU2_TLS"
12808 {
12809 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12810 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12811 })
12812
12813 (define_insn "*tls_dynamic_gnu2_lea_32"
12814 [(set (match_operand:SI 0 "register_operand" "=r")
12815 (plus:SI (match_operand:SI 1 "register_operand" "b")
12816 (const:SI
12817 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12818 UNSPEC_TLSDESC))))]
12819 "!TARGET_64BIT && TARGET_GNU2_TLS"
12820 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12821 [(set_attr "type" "lea")
12822 (set_attr "mode" "SI")
12823 (set_attr "length" "6")
12824 (set_attr "length_address" "4")])
12825
12826 (define_insn "*tls_dynamic_gnu2_call_32"
12827 [(set (match_operand:SI 0 "register_operand" "=a")
12828 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12829 (match_operand:SI 2 "register_operand" "0")
12830 ;; we have to make sure %ebx still points to the GOT
12831 (match_operand:SI 3 "register_operand" "b")
12832 (reg:SI SP_REG)]
12833 UNSPEC_TLSDESC))
12834 (clobber (reg:CC FLAGS_REG))]
12835 "!TARGET_64BIT && TARGET_GNU2_TLS"
12836 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12837 [(set_attr "type" "call")
12838 (set_attr "length" "2")
12839 (set_attr "length_address" "0")])
12840
12841 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12842 [(set (match_operand:SI 0 "register_operand" "=&a")
12843 (plus:SI
12844 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12845 (match_operand:SI 4 "" "")
12846 (match_operand:SI 2 "register_operand" "b")
12847 (reg:SI SP_REG)]
12848 UNSPEC_TLSDESC)
12849 (const:SI (unspec:SI
12850 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12851 UNSPEC_DTPOFF))))
12852 (clobber (reg:CC FLAGS_REG))]
12853 "!TARGET_64BIT && TARGET_GNU2_TLS"
12854 "#"
12855 ""
12856 [(set (match_dup 0) (match_dup 5))]
12857 {
12858 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12859 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12860 })
12861
12862 (define_expand "tls_dynamic_gnu2_64"
12863 [(set (match_dup 2)
12864 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12865 UNSPEC_TLSDESC))
12866 (parallel
12867 [(set (match_operand:DI 0 "register_operand" "")
12868 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12869 UNSPEC_TLSDESC))
12870 (clobber (reg:CC FLAGS_REG))])]
12871 "TARGET_64BIT && TARGET_GNU2_TLS"
12872 {
12873 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12874 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12875 })
12876
12877 (define_insn "*tls_dynamic_gnu2_lea_64"
12878 [(set (match_operand:DI 0 "register_operand" "=r")
12879 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12880 UNSPEC_TLSDESC))]
12881 "TARGET_64BIT && TARGET_GNU2_TLS"
12882 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12883 [(set_attr "type" "lea")
12884 (set_attr "mode" "DI")
12885 (set_attr "length" "7")
12886 (set_attr "length_address" "4")])
12887
12888 (define_insn "*tls_dynamic_gnu2_call_64"
12889 [(set (match_operand:DI 0 "register_operand" "=a")
12890 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12891 (match_operand:DI 2 "register_operand" "0")
12892 (reg:DI SP_REG)]
12893 UNSPEC_TLSDESC))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "TARGET_64BIT && TARGET_GNU2_TLS"
12896 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12897 [(set_attr "type" "call")
12898 (set_attr "length" "2")
12899 (set_attr "length_address" "0")])
12900
12901 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12902 [(set (match_operand:DI 0 "register_operand" "=&a")
12903 (plus:DI
12904 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12905 (match_operand:DI 3 "" "")
12906 (reg:DI SP_REG)]
12907 UNSPEC_TLSDESC)
12908 (const:DI (unspec:DI
12909 [(match_operand 1 "tls_symbolic_operand" "")]
12910 UNSPEC_DTPOFF))))
12911 (clobber (reg:CC FLAGS_REG))]
12912 "TARGET_64BIT && TARGET_GNU2_TLS"
12913 "#"
12914 ""
12915 [(set (match_dup 0) (match_dup 4))]
12916 {
12917 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12918 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12919 })
12920 \f
12921 ;; These patterns match the binary 387 instructions for addM3, subM3,
12922 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12923 ;; SFmode. The first is the normal insn, the second the same insn but
12924 ;; with one operand a conversion, and the third the same insn but with
12925 ;; the other operand a conversion. The conversion may be SFmode or
12926 ;; SImode if the target mode DFmode, but only SImode if the target mode
12927 ;; is SFmode.
12928
12929 ;; Gcc is slightly more smart about handling normal two address instructions
12930 ;; so use special patterns for add and mull.
12931
12932 (define_insn "*fop_<mode>_comm_mixed"
12933 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12934 (match_operator:MODEF 3 "binary_fp_operator"
12935 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12936 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12937 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12938 && COMMUTATIVE_ARITH_P (operands[3])
12939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12940 "* return output_387_binary_op (insn, operands);"
12941 [(set (attr "type")
12942 (if_then_else (eq_attr "alternative" "1,2")
12943 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12944 (const_string "ssemul")
12945 (const_string "sseadd"))
12946 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12947 (const_string "fmul")
12948 (const_string "fop"))))
12949 (set_attr "isa" "*,noavx,avx")
12950 (set_attr "prefix" "orig,orig,vex")
12951 (set_attr "mode" "<MODE>")])
12952
12953 (define_insn "*fop_<mode>_comm_sse"
12954 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12955 (match_operator:MODEF 3 "binary_fp_operator"
12956 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12957 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12958 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12959 && COMMUTATIVE_ARITH_P (operands[3])
12960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12961 "* return output_387_binary_op (insn, operands);"
12962 [(set (attr "type")
12963 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12964 (const_string "ssemul")
12965 (const_string "sseadd")))
12966 (set_attr "isa" "noavx,avx")
12967 (set_attr "prefix" "orig,vex")
12968 (set_attr "mode" "<MODE>")])
12969
12970 (define_insn "*fop_<mode>_comm_i387"
12971 [(set (match_operand:MODEF 0 "register_operand" "=f")
12972 (match_operator:MODEF 3 "binary_fp_operator"
12973 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12974 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12975 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12976 && COMMUTATIVE_ARITH_P (operands[3])
12977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12978 "* return output_387_binary_op (insn, operands);"
12979 [(set (attr "type")
12980 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12981 (const_string "fmul")
12982 (const_string "fop")))
12983 (set_attr "mode" "<MODE>")])
12984
12985 (define_insn "*fop_<mode>_1_mixed"
12986 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12987 (match_operator:MODEF 3 "binary_fp_operator"
12988 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12989 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12990 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12991 && !COMMUTATIVE_ARITH_P (operands[3])
12992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12993 "* return output_387_binary_op (insn, operands);"
12994 [(set (attr "type")
12995 (cond [(and (eq_attr "alternative" "2,3")
12996 (match_operand:MODEF 3 "mult_operator" ""))
12997 (const_string "ssemul")
12998 (and (eq_attr "alternative" "2,3")
12999 (match_operand:MODEF 3 "div_operator" ""))
13000 (const_string "ssediv")
13001 (eq_attr "alternative" "2,3")
13002 (const_string "sseadd")
13003 (match_operand:MODEF 3 "mult_operator" "")
13004 (const_string "fmul")
13005 (match_operand:MODEF 3 "div_operator" "")
13006 (const_string "fdiv")
13007 ]
13008 (const_string "fop")))
13009 (set_attr "isa" "*,*,noavx,avx")
13010 (set_attr "prefix" "orig,orig,orig,vex")
13011 (set_attr "mode" "<MODE>")])
13012
13013 (define_insn "*rcpsf2_sse"
13014 [(set (match_operand:SF 0 "register_operand" "=x")
13015 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13016 UNSPEC_RCP))]
13017 "TARGET_SSE_MATH"
13018 "%vrcpss\t{%1, %d0|%d0, %1}"
13019 [(set_attr "type" "sse")
13020 (set_attr "atom_sse_attr" "rcp")
13021 (set_attr "prefix" "maybe_vex")
13022 (set_attr "mode" "SF")])
13023
13024 (define_insn "*fop_<mode>_1_sse"
13025 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13026 (match_operator:MODEF 3 "binary_fp_operator"
13027 [(match_operand:MODEF 1 "register_operand" "0,x")
13028 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13029 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13030 && !COMMUTATIVE_ARITH_P (operands[3])"
13031 "* return output_387_binary_op (insn, operands);"
13032 [(set (attr "type")
13033 (cond [(match_operand:MODEF 3 "mult_operator" "")
13034 (const_string "ssemul")
13035 (match_operand:MODEF 3 "div_operator" "")
13036 (const_string "ssediv")
13037 ]
13038 (const_string "sseadd")))
13039 (set_attr "isa" "noavx,avx")
13040 (set_attr "prefix" "orig,vex")
13041 (set_attr "mode" "<MODE>")])
13042
13043 ;; This pattern is not fully shadowed by the pattern above.
13044 (define_insn "*fop_<mode>_1_i387"
13045 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13046 (match_operator:MODEF 3 "binary_fp_operator"
13047 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13048 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13049 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13050 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13051 && !COMMUTATIVE_ARITH_P (operands[3])
13052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13053 "* return output_387_binary_op (insn, operands);"
13054 [(set (attr "type")
13055 (cond [(match_operand:MODEF 3 "mult_operator" "")
13056 (const_string "fmul")
13057 (match_operand:MODEF 3 "div_operator" "")
13058 (const_string "fdiv")
13059 ]
13060 (const_string "fop")))
13061 (set_attr "mode" "<MODE>")])
13062
13063 ;; ??? Add SSE splitters for these!
13064 (define_insn "*fop_<MODEF:mode>_2_i387"
13065 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13067 [(float:MODEF
13068 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13069 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13070 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13071 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13072 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13073 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13074 [(set (attr "type")
13075 (cond [(match_operand:MODEF 3 "mult_operator" "")
13076 (const_string "fmul")
13077 (match_operand:MODEF 3 "div_operator" "")
13078 (const_string "fdiv")
13079 ]
13080 (const_string "fop")))
13081 (set_attr "fp_int_src" "true")
13082 (set_attr "mode" "<SWI24:MODE>")])
13083
13084 (define_insn "*fop_<MODEF:mode>_3_i387"
13085 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13086 (match_operator:MODEF 3 "binary_fp_operator"
13087 [(match_operand:MODEF 1 "register_operand" "0,0")
13088 (float:MODEF
13089 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13090 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13091 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13092 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13093 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13094 [(set (attr "type")
13095 (cond [(match_operand:MODEF 3 "mult_operator" "")
13096 (const_string "fmul")
13097 (match_operand:MODEF 3 "div_operator" "")
13098 (const_string "fdiv")
13099 ]
13100 (const_string "fop")))
13101 (set_attr "fp_int_src" "true")
13102 (set_attr "mode" "<MODE>")])
13103
13104 (define_insn "*fop_df_4_i387"
13105 [(set (match_operand:DF 0 "register_operand" "=f,f")
13106 (match_operator:DF 3 "binary_fp_operator"
13107 [(float_extend:DF
13108 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13109 (match_operand:DF 2 "register_operand" "0,f")]))]
13110 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13111 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13112 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13113 "* return output_387_binary_op (insn, operands);"
13114 [(set (attr "type")
13115 (cond [(match_operand:DF 3 "mult_operator" "")
13116 (const_string "fmul")
13117 (match_operand:DF 3 "div_operator" "")
13118 (const_string "fdiv")
13119 ]
13120 (const_string "fop")))
13121 (set_attr "mode" "SF")])
13122
13123 (define_insn "*fop_df_5_i387"
13124 [(set (match_operand:DF 0 "register_operand" "=f,f")
13125 (match_operator:DF 3 "binary_fp_operator"
13126 [(match_operand:DF 1 "register_operand" "0,f")
13127 (float_extend:DF
13128 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13129 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13130 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13131 "* return output_387_binary_op (insn, operands);"
13132 [(set (attr "type")
13133 (cond [(match_operand:DF 3 "mult_operator" "")
13134 (const_string "fmul")
13135 (match_operand:DF 3 "div_operator" "")
13136 (const_string "fdiv")
13137 ]
13138 (const_string "fop")))
13139 (set_attr "mode" "SF")])
13140
13141 (define_insn "*fop_df_6_i387"
13142 [(set (match_operand:DF 0 "register_operand" "=f,f")
13143 (match_operator:DF 3 "binary_fp_operator"
13144 [(float_extend:DF
13145 (match_operand:SF 1 "register_operand" "0,f"))
13146 (float_extend:DF
13147 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13148 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13149 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13150 "* return output_387_binary_op (insn, operands);"
13151 [(set (attr "type")
13152 (cond [(match_operand:DF 3 "mult_operator" "")
13153 (const_string "fmul")
13154 (match_operand:DF 3 "div_operator" "")
13155 (const_string "fdiv")
13156 ]
13157 (const_string "fop")))
13158 (set_attr "mode" "SF")])
13159
13160 (define_insn "*fop_xf_comm_i387"
13161 [(set (match_operand:XF 0 "register_operand" "=f")
13162 (match_operator:XF 3 "binary_fp_operator"
13163 [(match_operand:XF 1 "register_operand" "%0")
13164 (match_operand:XF 2 "register_operand" "f")]))]
13165 "TARGET_80387
13166 && COMMUTATIVE_ARITH_P (operands[3])"
13167 "* return output_387_binary_op (insn, operands);"
13168 [(set (attr "type")
13169 (if_then_else (match_operand:XF 3 "mult_operator" "")
13170 (const_string "fmul")
13171 (const_string "fop")))
13172 (set_attr "mode" "XF")])
13173
13174 (define_insn "*fop_xf_1_i387"
13175 [(set (match_operand:XF 0 "register_operand" "=f,f")
13176 (match_operator:XF 3 "binary_fp_operator"
13177 [(match_operand:XF 1 "register_operand" "0,f")
13178 (match_operand:XF 2 "register_operand" "f,0")]))]
13179 "TARGET_80387
13180 && !COMMUTATIVE_ARITH_P (operands[3])"
13181 "* return output_387_binary_op (insn, operands);"
13182 [(set (attr "type")
13183 (cond [(match_operand:XF 3 "mult_operator" "")
13184 (const_string "fmul")
13185 (match_operand:XF 3 "div_operator" "")
13186 (const_string "fdiv")
13187 ]
13188 (const_string "fop")))
13189 (set_attr "mode" "XF")])
13190
13191 (define_insn "*fop_xf_2_i387"
13192 [(set (match_operand:XF 0 "register_operand" "=f,f")
13193 (match_operator:XF 3 "binary_fp_operator"
13194 [(float:XF
13195 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13196 (match_operand:XF 2 "register_operand" "0,0")]))]
13197 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13198 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13199 [(set (attr "type")
13200 (cond [(match_operand:XF 3 "mult_operator" "")
13201 (const_string "fmul")
13202 (match_operand:XF 3 "div_operator" "")
13203 (const_string "fdiv")
13204 ]
13205 (const_string "fop")))
13206 (set_attr "fp_int_src" "true")
13207 (set_attr "mode" "<MODE>")])
13208
13209 (define_insn "*fop_xf_3_i387"
13210 [(set (match_operand:XF 0 "register_operand" "=f,f")
13211 (match_operator:XF 3 "binary_fp_operator"
13212 [(match_operand:XF 1 "register_operand" "0,0")
13213 (float:XF
13214 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13215 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13216 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13217 [(set (attr "type")
13218 (cond [(match_operand:XF 3 "mult_operator" "")
13219 (const_string "fmul")
13220 (match_operand:XF 3 "div_operator" "")
13221 (const_string "fdiv")
13222 ]
13223 (const_string "fop")))
13224 (set_attr "fp_int_src" "true")
13225 (set_attr "mode" "<MODE>")])
13226
13227 (define_insn "*fop_xf_4_i387"
13228 [(set (match_operand:XF 0 "register_operand" "=f,f")
13229 (match_operator:XF 3 "binary_fp_operator"
13230 [(float_extend:XF
13231 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13232 (match_operand:XF 2 "register_operand" "0,f")]))]
13233 "TARGET_80387"
13234 "* return output_387_binary_op (insn, operands);"
13235 [(set (attr "type")
13236 (cond [(match_operand:XF 3 "mult_operator" "")
13237 (const_string "fmul")
13238 (match_operand:XF 3 "div_operator" "")
13239 (const_string "fdiv")
13240 ]
13241 (const_string "fop")))
13242 (set_attr "mode" "<MODE>")])
13243
13244 (define_insn "*fop_xf_5_i387"
13245 [(set (match_operand:XF 0 "register_operand" "=f,f")
13246 (match_operator:XF 3 "binary_fp_operator"
13247 [(match_operand:XF 1 "register_operand" "0,f")
13248 (float_extend:XF
13249 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13250 "TARGET_80387"
13251 "* return output_387_binary_op (insn, operands);"
13252 [(set (attr "type")
13253 (cond [(match_operand:XF 3 "mult_operator" "")
13254 (const_string "fmul")
13255 (match_operand:XF 3 "div_operator" "")
13256 (const_string "fdiv")
13257 ]
13258 (const_string "fop")))
13259 (set_attr "mode" "<MODE>")])
13260
13261 (define_insn "*fop_xf_6_i387"
13262 [(set (match_operand:XF 0 "register_operand" "=f,f")
13263 (match_operator:XF 3 "binary_fp_operator"
13264 [(float_extend:XF
13265 (match_operand:MODEF 1 "register_operand" "0,f"))
13266 (float_extend:XF
13267 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13268 "TARGET_80387"
13269 "* return output_387_binary_op (insn, operands);"
13270 [(set (attr "type")
13271 (cond [(match_operand:XF 3 "mult_operator" "")
13272 (const_string "fmul")
13273 (match_operand:XF 3 "div_operator" "")
13274 (const_string "fdiv")
13275 ]
13276 (const_string "fop")))
13277 (set_attr "mode" "<MODE>")])
13278
13279 (define_split
13280 [(set (match_operand 0 "register_operand" "")
13281 (match_operator 3 "binary_fp_operator"
13282 [(float (match_operand:SWI24 1 "register_operand" ""))
13283 (match_operand 2 "register_operand" "")]))]
13284 "reload_completed
13285 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13286 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13287 [(const_int 0)]
13288 {
13289 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13290 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13291 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13292 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13293 GET_MODE (operands[3]),
13294 operands[4],
13295 operands[2])));
13296 ix86_free_from_memory (GET_MODE (operands[1]));
13297 DONE;
13298 })
13299
13300 (define_split
13301 [(set (match_operand 0 "register_operand" "")
13302 (match_operator 3 "binary_fp_operator"
13303 [(match_operand 1 "register_operand" "")
13304 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13305 "reload_completed
13306 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13307 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13308 [(const_int 0)]
13309 {
13310 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13311 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13312 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13313 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13314 GET_MODE (operands[3]),
13315 operands[1],
13316 operands[4])));
13317 ix86_free_from_memory (GET_MODE (operands[2]));
13318 DONE;
13319 })
13320 \f
13321 ;; FPU special functions.
13322
13323 ;; This pattern implements a no-op XFmode truncation for
13324 ;; all fancy i386 XFmode math functions.
13325
13326 (define_insn "truncxf<mode>2_i387_noop_unspec"
13327 [(set (match_operand:MODEF 0 "register_operand" "=f")
13328 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13329 UNSPEC_TRUNC_NOOP))]
13330 "TARGET_USE_FANCY_MATH_387"
13331 "* return output_387_reg_move (insn, operands);"
13332 [(set_attr "type" "fmov")
13333 (set_attr "mode" "<MODE>")])
13334
13335 (define_insn "sqrtxf2"
13336 [(set (match_operand:XF 0 "register_operand" "=f")
13337 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13338 "TARGET_USE_FANCY_MATH_387"
13339 "fsqrt"
13340 [(set_attr "type" "fpspc")
13341 (set_attr "mode" "XF")
13342 (set_attr "athlon_decode" "direct")
13343 (set_attr "amdfam10_decode" "direct")
13344 (set_attr "bdver1_decode" "direct")])
13345
13346 (define_insn "sqrt_extend<mode>xf2_i387"
13347 [(set (match_operand:XF 0 "register_operand" "=f")
13348 (sqrt:XF
13349 (float_extend:XF
13350 (match_operand:MODEF 1 "register_operand" "0"))))]
13351 "TARGET_USE_FANCY_MATH_387"
13352 "fsqrt"
13353 [(set_attr "type" "fpspc")
13354 (set_attr "mode" "XF")
13355 (set_attr "athlon_decode" "direct")
13356 (set_attr "amdfam10_decode" "direct")
13357 (set_attr "bdver1_decode" "direct")])
13358
13359 (define_insn "*rsqrtsf2_sse"
13360 [(set (match_operand:SF 0 "register_operand" "=x")
13361 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13362 UNSPEC_RSQRT))]
13363 "TARGET_SSE_MATH"
13364 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13365 [(set_attr "type" "sse")
13366 (set_attr "atom_sse_attr" "rcp")
13367 (set_attr "prefix" "maybe_vex")
13368 (set_attr "mode" "SF")])
13369
13370 (define_expand "rsqrtsf2"
13371 [(set (match_operand:SF 0 "register_operand" "")
13372 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13373 UNSPEC_RSQRT))]
13374 "TARGET_SSE_MATH"
13375 {
13376 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13377 DONE;
13378 })
13379
13380 (define_insn "*sqrt<mode>2_sse"
13381 [(set (match_operand:MODEF 0 "register_operand" "=x")
13382 (sqrt:MODEF
13383 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13384 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13385 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13386 [(set_attr "type" "sse")
13387 (set_attr "atom_sse_attr" "sqrt")
13388 (set_attr "prefix" "maybe_vex")
13389 (set_attr "mode" "<MODE>")
13390 (set_attr "athlon_decode" "*")
13391 (set_attr "amdfam10_decode" "*")
13392 (set_attr "bdver1_decode" "*")])
13393
13394 (define_expand "sqrt<mode>2"
13395 [(set (match_operand:MODEF 0 "register_operand" "")
13396 (sqrt:MODEF
13397 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13398 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13399 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13400 {
13401 if (<MODE>mode == SFmode
13402 && TARGET_SSE_MATH
13403 && TARGET_RECIP_SQRT
13404 && !optimize_function_for_size_p (cfun)
13405 && flag_finite_math_only && !flag_trapping_math
13406 && flag_unsafe_math_optimizations)
13407 {
13408 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13409 DONE;
13410 }
13411
13412 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13413 {
13414 rtx op0 = gen_reg_rtx (XFmode);
13415 rtx op1 = force_reg (<MODE>mode, operands[1]);
13416
13417 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13418 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13419 DONE;
13420 }
13421 })
13422
13423 (define_insn "fpremxf4_i387"
13424 [(set (match_operand:XF 0 "register_operand" "=f")
13425 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13426 (match_operand:XF 3 "register_operand" "1")]
13427 UNSPEC_FPREM_F))
13428 (set (match_operand:XF 1 "register_operand" "=u")
13429 (unspec:XF [(match_dup 2) (match_dup 3)]
13430 UNSPEC_FPREM_U))
13431 (set (reg:CCFP FPSR_REG)
13432 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13433 UNSPEC_C2_FLAG))]
13434 "TARGET_USE_FANCY_MATH_387"
13435 "fprem"
13436 [(set_attr "type" "fpspc")
13437 (set_attr "mode" "XF")])
13438
13439 (define_expand "fmodxf3"
13440 [(use (match_operand:XF 0 "register_operand" ""))
13441 (use (match_operand:XF 1 "general_operand" ""))
13442 (use (match_operand:XF 2 "general_operand" ""))]
13443 "TARGET_USE_FANCY_MATH_387"
13444 {
13445 rtx label = gen_label_rtx ();
13446
13447 rtx op1 = gen_reg_rtx (XFmode);
13448 rtx op2 = gen_reg_rtx (XFmode);
13449
13450 emit_move_insn (op2, operands[2]);
13451 emit_move_insn (op1, operands[1]);
13452
13453 emit_label (label);
13454 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13455 ix86_emit_fp_unordered_jump (label);
13456 LABEL_NUSES (label) = 1;
13457
13458 emit_move_insn (operands[0], op1);
13459 DONE;
13460 })
13461
13462 (define_expand "fmod<mode>3"
13463 [(use (match_operand:MODEF 0 "register_operand" ""))
13464 (use (match_operand:MODEF 1 "general_operand" ""))
13465 (use (match_operand:MODEF 2 "general_operand" ""))]
13466 "TARGET_USE_FANCY_MATH_387"
13467 {
13468 rtx (*gen_truncxf) (rtx, rtx);
13469
13470 rtx label = gen_label_rtx ();
13471
13472 rtx op1 = gen_reg_rtx (XFmode);
13473 rtx op2 = gen_reg_rtx (XFmode);
13474
13475 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13477
13478 emit_label (label);
13479 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13480 ix86_emit_fp_unordered_jump (label);
13481 LABEL_NUSES (label) = 1;
13482
13483 /* Truncate the result properly for strict SSE math. */
13484 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13485 && !TARGET_MIX_SSE_I387)
13486 gen_truncxf = gen_truncxf<mode>2;
13487 else
13488 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13489
13490 emit_insn (gen_truncxf (operands[0], op1));
13491 DONE;
13492 })
13493
13494 (define_insn "fprem1xf4_i387"
13495 [(set (match_operand:XF 0 "register_operand" "=f")
13496 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13497 (match_operand:XF 3 "register_operand" "1")]
13498 UNSPEC_FPREM1_F))
13499 (set (match_operand:XF 1 "register_operand" "=u")
13500 (unspec:XF [(match_dup 2) (match_dup 3)]
13501 UNSPEC_FPREM1_U))
13502 (set (reg:CCFP FPSR_REG)
13503 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13504 UNSPEC_C2_FLAG))]
13505 "TARGET_USE_FANCY_MATH_387"
13506 "fprem1"
13507 [(set_attr "type" "fpspc")
13508 (set_attr "mode" "XF")])
13509
13510 (define_expand "remainderxf3"
13511 [(use (match_operand:XF 0 "register_operand" ""))
13512 (use (match_operand:XF 1 "general_operand" ""))
13513 (use (match_operand:XF 2 "general_operand" ""))]
13514 "TARGET_USE_FANCY_MATH_387"
13515 {
13516 rtx label = gen_label_rtx ();
13517
13518 rtx op1 = gen_reg_rtx (XFmode);
13519 rtx op2 = gen_reg_rtx (XFmode);
13520
13521 emit_move_insn (op2, operands[2]);
13522 emit_move_insn (op1, operands[1]);
13523
13524 emit_label (label);
13525 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13526 ix86_emit_fp_unordered_jump (label);
13527 LABEL_NUSES (label) = 1;
13528
13529 emit_move_insn (operands[0], op1);
13530 DONE;
13531 })
13532
13533 (define_expand "remainder<mode>3"
13534 [(use (match_operand:MODEF 0 "register_operand" ""))
13535 (use (match_operand:MODEF 1 "general_operand" ""))
13536 (use (match_operand:MODEF 2 "general_operand" ""))]
13537 "TARGET_USE_FANCY_MATH_387"
13538 {
13539 rtx (*gen_truncxf) (rtx, rtx);
13540
13541 rtx label = gen_label_rtx ();
13542
13543 rtx op1 = gen_reg_rtx (XFmode);
13544 rtx op2 = gen_reg_rtx (XFmode);
13545
13546 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13547 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13548
13549 emit_label (label);
13550
13551 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13552 ix86_emit_fp_unordered_jump (label);
13553 LABEL_NUSES (label) = 1;
13554
13555 /* Truncate the result properly for strict SSE math. */
13556 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13557 && !TARGET_MIX_SSE_I387)
13558 gen_truncxf = gen_truncxf<mode>2;
13559 else
13560 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13561
13562 emit_insn (gen_truncxf (operands[0], op1));
13563 DONE;
13564 })
13565
13566 (define_insn "*sinxf2_i387"
13567 [(set (match_operand:XF 0 "register_operand" "=f")
13568 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13569 "TARGET_USE_FANCY_MATH_387
13570 && flag_unsafe_math_optimizations"
13571 "fsin"
13572 [(set_attr "type" "fpspc")
13573 (set_attr "mode" "XF")])
13574
13575 (define_insn "*sin_extend<mode>xf2_i387"
13576 [(set (match_operand:XF 0 "register_operand" "=f")
13577 (unspec:XF [(float_extend:XF
13578 (match_operand:MODEF 1 "register_operand" "0"))]
13579 UNSPEC_SIN))]
13580 "TARGET_USE_FANCY_MATH_387
13581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13582 || TARGET_MIX_SSE_I387)
13583 && flag_unsafe_math_optimizations"
13584 "fsin"
13585 [(set_attr "type" "fpspc")
13586 (set_attr "mode" "XF")])
13587
13588 (define_insn "*cosxf2_i387"
13589 [(set (match_operand:XF 0 "register_operand" "=f")
13590 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13591 "TARGET_USE_FANCY_MATH_387
13592 && flag_unsafe_math_optimizations"
13593 "fcos"
13594 [(set_attr "type" "fpspc")
13595 (set_attr "mode" "XF")])
13596
13597 (define_insn "*cos_extend<mode>xf2_i387"
13598 [(set (match_operand:XF 0 "register_operand" "=f")
13599 (unspec:XF [(float_extend:XF
13600 (match_operand:MODEF 1 "register_operand" "0"))]
13601 UNSPEC_COS))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13604 || TARGET_MIX_SSE_I387)
13605 && flag_unsafe_math_optimizations"
13606 "fcos"
13607 [(set_attr "type" "fpspc")
13608 (set_attr "mode" "XF")])
13609
13610 ;; When sincos pattern is defined, sin and cos builtin functions will be
13611 ;; expanded to sincos pattern with one of its outputs left unused.
13612 ;; CSE pass will figure out if two sincos patterns can be combined,
13613 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13614 ;; depending on the unused output.
13615
13616 (define_insn "sincosxf3"
13617 [(set (match_operand:XF 0 "register_operand" "=f")
13618 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13619 UNSPEC_SINCOS_COS))
13620 (set (match_operand:XF 1 "register_operand" "=u")
13621 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13622 "TARGET_USE_FANCY_MATH_387
13623 && flag_unsafe_math_optimizations"
13624 "fsincos"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")])
13627
13628 (define_split
13629 [(set (match_operand:XF 0 "register_operand" "")
13630 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13631 UNSPEC_SINCOS_COS))
13632 (set (match_operand:XF 1 "register_operand" "")
13633 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13634 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13635 && can_create_pseudo_p ()"
13636 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13637
13638 (define_split
13639 [(set (match_operand:XF 0 "register_operand" "")
13640 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13641 UNSPEC_SINCOS_COS))
13642 (set (match_operand:XF 1 "register_operand" "")
13643 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13644 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13645 && can_create_pseudo_p ()"
13646 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13647
13648 (define_insn "sincos_extend<mode>xf3_i387"
13649 [(set (match_operand:XF 0 "register_operand" "=f")
13650 (unspec:XF [(float_extend:XF
13651 (match_operand:MODEF 2 "register_operand" "0"))]
13652 UNSPEC_SINCOS_COS))
13653 (set (match_operand:XF 1 "register_operand" "=u")
13654 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13655 "TARGET_USE_FANCY_MATH_387
13656 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13657 || TARGET_MIX_SSE_I387)
13658 && flag_unsafe_math_optimizations"
13659 "fsincos"
13660 [(set_attr "type" "fpspc")
13661 (set_attr "mode" "XF")])
13662
13663 (define_split
13664 [(set (match_operand:XF 0 "register_operand" "")
13665 (unspec:XF [(float_extend:XF
13666 (match_operand:MODEF 2 "register_operand" ""))]
13667 UNSPEC_SINCOS_COS))
13668 (set (match_operand:XF 1 "register_operand" "")
13669 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13670 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13671 && can_create_pseudo_p ()"
13672 [(set (match_dup 1)
13673 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13674
13675 (define_split
13676 [(set (match_operand:XF 0 "register_operand" "")
13677 (unspec:XF [(float_extend:XF
13678 (match_operand:MODEF 2 "register_operand" ""))]
13679 UNSPEC_SINCOS_COS))
13680 (set (match_operand:XF 1 "register_operand" "")
13681 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13682 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13683 && can_create_pseudo_p ()"
13684 [(set (match_dup 0)
13685 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13686
13687 (define_expand "sincos<mode>3"
13688 [(use (match_operand:MODEF 0 "register_operand" ""))
13689 (use (match_operand:MODEF 1 "register_operand" ""))
13690 (use (match_operand:MODEF 2 "register_operand" ""))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693 || TARGET_MIX_SSE_I387)
13694 && flag_unsafe_math_optimizations"
13695 {
13696 rtx op0 = gen_reg_rtx (XFmode);
13697 rtx op1 = gen_reg_rtx (XFmode);
13698
13699 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13701 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13702 DONE;
13703 })
13704
13705 (define_insn "fptanxf4_i387"
13706 [(set (match_operand:XF 0 "register_operand" "=f")
13707 (match_operand:XF 3 "const_double_operand" "F"))
13708 (set (match_operand:XF 1 "register_operand" "=u")
13709 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13710 UNSPEC_TAN))]
13711 "TARGET_USE_FANCY_MATH_387
13712 && flag_unsafe_math_optimizations
13713 && standard_80387_constant_p (operands[3]) == 2"
13714 "fptan"
13715 [(set_attr "type" "fpspc")
13716 (set_attr "mode" "XF")])
13717
13718 (define_insn "fptan_extend<mode>xf4_i387"
13719 [(set (match_operand:MODEF 0 "register_operand" "=f")
13720 (match_operand:MODEF 3 "const_double_operand" "F"))
13721 (set (match_operand:XF 1 "register_operand" "=u")
13722 (unspec:XF [(float_extend:XF
13723 (match_operand:MODEF 2 "register_operand" "0"))]
13724 UNSPEC_TAN))]
13725 "TARGET_USE_FANCY_MATH_387
13726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13727 || TARGET_MIX_SSE_I387)
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_expand "tanxf2"
13735 [(use (match_operand:XF 0 "register_operand" ""))
13736 (use (match_operand:XF 1 "register_operand" ""))]
13737 "TARGET_USE_FANCY_MATH_387
13738 && flag_unsafe_math_optimizations"
13739 {
13740 rtx one = gen_reg_rtx (XFmode);
13741 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13742
13743 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13744 DONE;
13745 })
13746
13747 (define_expand "tan<mode>2"
13748 [(use (match_operand:MODEF 0 "register_operand" ""))
13749 (use (match_operand:MODEF 1 "register_operand" ""))]
13750 "TARGET_USE_FANCY_MATH_387
13751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13752 || TARGET_MIX_SSE_I387)
13753 && flag_unsafe_math_optimizations"
13754 {
13755 rtx op0 = gen_reg_rtx (XFmode);
13756
13757 rtx one = gen_reg_rtx (<MODE>mode);
13758 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13759
13760 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13761 operands[1], op2));
13762 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13763 DONE;
13764 })
13765
13766 (define_insn "*fpatanxf3_i387"
13767 [(set (match_operand:XF 0 "register_operand" "=f")
13768 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13769 (match_operand:XF 2 "register_operand" "u")]
13770 UNSPEC_FPATAN))
13771 (clobber (match_scratch:XF 3 "=2"))]
13772 "TARGET_USE_FANCY_MATH_387
13773 && flag_unsafe_math_optimizations"
13774 "fpatan"
13775 [(set_attr "type" "fpspc")
13776 (set_attr "mode" "XF")])
13777
13778 (define_insn "fpatan_extend<mode>xf3_i387"
13779 [(set (match_operand:XF 0 "register_operand" "=f")
13780 (unspec:XF [(float_extend:XF
13781 (match_operand:MODEF 1 "register_operand" "0"))
13782 (float_extend:XF
13783 (match_operand:MODEF 2 "register_operand" "u"))]
13784 UNSPEC_FPATAN))
13785 (clobber (match_scratch:XF 3 "=2"))]
13786 "TARGET_USE_FANCY_MATH_387
13787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13788 || TARGET_MIX_SSE_I387)
13789 && flag_unsafe_math_optimizations"
13790 "fpatan"
13791 [(set_attr "type" "fpspc")
13792 (set_attr "mode" "XF")])
13793
13794 (define_expand "atan2xf3"
13795 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13796 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13797 (match_operand:XF 1 "register_operand" "")]
13798 UNSPEC_FPATAN))
13799 (clobber (match_scratch:XF 3 ""))])]
13800 "TARGET_USE_FANCY_MATH_387
13801 && flag_unsafe_math_optimizations")
13802
13803 (define_expand "atan2<mode>3"
13804 [(use (match_operand:MODEF 0 "register_operand" ""))
13805 (use (match_operand:MODEF 1 "register_operand" ""))
13806 (use (match_operand:MODEF 2 "register_operand" ""))]
13807 "TARGET_USE_FANCY_MATH_387
13808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13809 || TARGET_MIX_SSE_I387)
13810 && flag_unsafe_math_optimizations"
13811 {
13812 rtx op0 = gen_reg_rtx (XFmode);
13813
13814 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13815 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13816 DONE;
13817 })
13818
13819 (define_expand "atanxf2"
13820 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13821 (unspec:XF [(match_dup 2)
13822 (match_operand:XF 1 "register_operand" "")]
13823 UNSPEC_FPATAN))
13824 (clobber (match_scratch:XF 3 ""))])]
13825 "TARGET_USE_FANCY_MATH_387
13826 && flag_unsafe_math_optimizations"
13827 {
13828 operands[2] = gen_reg_rtx (XFmode);
13829 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13830 })
13831
13832 (define_expand "atan<mode>2"
13833 [(use (match_operand:MODEF 0 "register_operand" ""))
13834 (use (match_operand:MODEF 1 "register_operand" ""))]
13835 "TARGET_USE_FANCY_MATH_387
13836 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13837 || TARGET_MIX_SSE_I387)
13838 && flag_unsafe_math_optimizations"
13839 {
13840 rtx op0 = gen_reg_rtx (XFmode);
13841
13842 rtx op2 = gen_reg_rtx (<MODE>mode);
13843 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13844
13845 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13846 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13847 DONE;
13848 })
13849
13850 (define_expand "asinxf2"
13851 [(set (match_dup 2)
13852 (mult:XF (match_operand:XF 1 "register_operand" "")
13853 (match_dup 1)))
13854 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13855 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13856 (parallel [(set (match_operand:XF 0 "register_operand" "")
13857 (unspec:XF [(match_dup 5) (match_dup 1)]
13858 UNSPEC_FPATAN))
13859 (clobber (match_scratch:XF 6 ""))])]
13860 "TARGET_USE_FANCY_MATH_387
13861 && flag_unsafe_math_optimizations"
13862 {
13863 int i;
13864
13865 if (optimize_insn_for_size_p ())
13866 FAIL;
13867
13868 for (i = 2; i < 6; i++)
13869 operands[i] = gen_reg_rtx (XFmode);
13870
13871 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13872 })
13873
13874 (define_expand "asin<mode>2"
13875 [(use (match_operand:MODEF 0 "register_operand" ""))
13876 (use (match_operand:MODEF 1 "general_operand" ""))]
13877 "TARGET_USE_FANCY_MATH_387
13878 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13879 || TARGET_MIX_SSE_I387)
13880 && flag_unsafe_math_optimizations"
13881 {
13882 rtx op0 = gen_reg_rtx (XFmode);
13883 rtx op1 = gen_reg_rtx (XFmode);
13884
13885 if (optimize_insn_for_size_p ())
13886 FAIL;
13887
13888 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13889 emit_insn (gen_asinxf2 (op0, op1));
13890 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13891 DONE;
13892 })
13893
13894 (define_expand "acosxf2"
13895 [(set (match_dup 2)
13896 (mult:XF (match_operand:XF 1 "register_operand" "")
13897 (match_dup 1)))
13898 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13899 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13900 (parallel [(set (match_operand:XF 0 "register_operand" "")
13901 (unspec:XF [(match_dup 1) (match_dup 5)]
13902 UNSPEC_FPATAN))
13903 (clobber (match_scratch:XF 6 ""))])]
13904 "TARGET_USE_FANCY_MATH_387
13905 && flag_unsafe_math_optimizations"
13906 {
13907 int i;
13908
13909 if (optimize_insn_for_size_p ())
13910 FAIL;
13911
13912 for (i = 2; i < 6; i++)
13913 operands[i] = gen_reg_rtx (XFmode);
13914
13915 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13916 })
13917
13918 (define_expand "acos<mode>2"
13919 [(use (match_operand:MODEF 0 "register_operand" ""))
13920 (use (match_operand:MODEF 1 "general_operand" ""))]
13921 "TARGET_USE_FANCY_MATH_387
13922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13923 || TARGET_MIX_SSE_I387)
13924 && flag_unsafe_math_optimizations"
13925 {
13926 rtx op0 = gen_reg_rtx (XFmode);
13927 rtx op1 = gen_reg_rtx (XFmode);
13928
13929 if (optimize_insn_for_size_p ())
13930 FAIL;
13931
13932 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13933 emit_insn (gen_acosxf2 (op0, op1));
13934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13935 DONE;
13936 })
13937
13938 (define_insn "fyl2xxf3_i387"
13939 [(set (match_operand:XF 0 "register_operand" "=f")
13940 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13941 (match_operand:XF 2 "register_operand" "u")]
13942 UNSPEC_FYL2X))
13943 (clobber (match_scratch:XF 3 "=2"))]
13944 "TARGET_USE_FANCY_MATH_387
13945 && flag_unsafe_math_optimizations"
13946 "fyl2x"
13947 [(set_attr "type" "fpspc")
13948 (set_attr "mode" "XF")])
13949
13950 (define_insn "fyl2x_extend<mode>xf3_i387"
13951 [(set (match_operand:XF 0 "register_operand" "=f")
13952 (unspec:XF [(float_extend:XF
13953 (match_operand:MODEF 1 "register_operand" "0"))
13954 (match_operand:XF 2 "register_operand" "u")]
13955 UNSPEC_FYL2X))
13956 (clobber (match_scratch:XF 3 "=2"))]
13957 "TARGET_USE_FANCY_MATH_387
13958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13959 || TARGET_MIX_SSE_I387)
13960 && flag_unsafe_math_optimizations"
13961 "fyl2x"
13962 [(set_attr "type" "fpspc")
13963 (set_attr "mode" "XF")])
13964
13965 (define_expand "logxf2"
13966 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13967 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13968 (match_dup 2)] UNSPEC_FYL2X))
13969 (clobber (match_scratch:XF 3 ""))])]
13970 "TARGET_USE_FANCY_MATH_387
13971 && flag_unsafe_math_optimizations"
13972 {
13973 operands[2] = gen_reg_rtx (XFmode);
13974 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13975 })
13976
13977 (define_expand "log<mode>2"
13978 [(use (match_operand:MODEF 0 "register_operand" ""))
13979 (use (match_operand:MODEF 1 "register_operand" ""))]
13980 "TARGET_USE_FANCY_MATH_387
13981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13982 || TARGET_MIX_SSE_I387)
13983 && flag_unsafe_math_optimizations"
13984 {
13985 rtx op0 = gen_reg_rtx (XFmode);
13986
13987 rtx op2 = gen_reg_rtx (XFmode);
13988 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13989
13990 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13992 DONE;
13993 })
13994
13995 (define_expand "log10xf2"
13996 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13997 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13998 (match_dup 2)] UNSPEC_FYL2X))
13999 (clobber (match_scratch:XF 3 ""))])]
14000 "TARGET_USE_FANCY_MATH_387
14001 && flag_unsafe_math_optimizations"
14002 {
14003 operands[2] = gen_reg_rtx (XFmode);
14004 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14005 })
14006
14007 (define_expand "log10<mode>2"
14008 [(use (match_operand:MODEF 0 "register_operand" ""))
14009 (use (match_operand:MODEF 1 "register_operand" ""))]
14010 "TARGET_USE_FANCY_MATH_387
14011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14012 || TARGET_MIX_SSE_I387)
14013 && flag_unsafe_math_optimizations"
14014 {
14015 rtx op0 = gen_reg_rtx (XFmode);
14016
14017 rtx op2 = gen_reg_rtx (XFmode);
14018 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14019
14020 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14021 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14022 DONE;
14023 })
14024
14025 (define_expand "log2xf2"
14026 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14027 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14028 (match_dup 2)] UNSPEC_FYL2X))
14029 (clobber (match_scratch:XF 3 ""))])]
14030 "TARGET_USE_FANCY_MATH_387
14031 && flag_unsafe_math_optimizations"
14032 {
14033 operands[2] = gen_reg_rtx (XFmode);
14034 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14035 })
14036
14037 (define_expand "log2<mode>2"
14038 [(use (match_operand:MODEF 0 "register_operand" ""))
14039 (use (match_operand:MODEF 1 "register_operand" ""))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14044 {
14045 rtx op0 = gen_reg_rtx (XFmode);
14046
14047 rtx op2 = gen_reg_rtx (XFmode);
14048 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14049
14050 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14052 DONE;
14053 })
14054
14055 (define_insn "fyl2xp1xf3_i387"
14056 [(set (match_operand:XF 0 "register_operand" "=f")
14057 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14058 (match_operand:XF 2 "register_operand" "u")]
14059 UNSPEC_FYL2XP1))
14060 (clobber (match_scratch:XF 3 "=2"))]
14061 "TARGET_USE_FANCY_MATH_387
14062 && flag_unsafe_math_optimizations"
14063 "fyl2xp1"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "XF")])
14066
14067 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14068 [(set (match_operand:XF 0 "register_operand" "=f")
14069 (unspec:XF [(float_extend:XF
14070 (match_operand:MODEF 1 "register_operand" "0"))
14071 (match_operand:XF 2 "register_operand" "u")]
14072 UNSPEC_FYL2XP1))
14073 (clobber (match_scratch:XF 3 "=2"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations"
14078 "fyl2xp1"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14081
14082 (define_expand "log1pxf2"
14083 [(use (match_operand:XF 0 "register_operand" ""))
14084 (use (match_operand:XF 1 "register_operand" ""))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && flag_unsafe_math_optimizations"
14087 {
14088 if (optimize_insn_for_size_p ())
14089 FAIL;
14090
14091 ix86_emit_i387_log1p (operands[0], operands[1]);
14092 DONE;
14093 })
14094
14095 (define_expand "log1p<mode>2"
14096 [(use (match_operand:MODEF 0 "register_operand" ""))
14097 (use (match_operand:MODEF 1 "register_operand" ""))]
14098 "TARGET_USE_FANCY_MATH_387
14099 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14100 || TARGET_MIX_SSE_I387)
14101 && flag_unsafe_math_optimizations"
14102 {
14103 rtx op0;
14104
14105 if (optimize_insn_for_size_p ())
14106 FAIL;
14107
14108 op0 = gen_reg_rtx (XFmode);
14109
14110 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14111
14112 ix86_emit_i387_log1p (op0, operands[1]);
14113 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14114 DONE;
14115 })
14116
14117 (define_insn "fxtractxf3_i387"
14118 [(set (match_operand:XF 0 "register_operand" "=f")
14119 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14120 UNSPEC_XTRACT_FRACT))
14121 (set (match_operand:XF 1 "register_operand" "=u")
14122 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && flag_unsafe_math_optimizations"
14125 "fxtract"
14126 [(set_attr "type" "fpspc")
14127 (set_attr "mode" "XF")])
14128
14129 (define_insn "fxtract_extend<mode>xf3_i387"
14130 [(set (match_operand:XF 0 "register_operand" "=f")
14131 (unspec:XF [(float_extend:XF
14132 (match_operand:MODEF 2 "register_operand" "0"))]
14133 UNSPEC_XTRACT_FRACT))
14134 (set (match_operand:XF 1 "register_operand" "=u")
14135 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14136 "TARGET_USE_FANCY_MATH_387
14137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14138 || TARGET_MIX_SSE_I387)
14139 && flag_unsafe_math_optimizations"
14140 "fxtract"
14141 [(set_attr "type" "fpspc")
14142 (set_attr "mode" "XF")])
14143
14144 (define_expand "logbxf2"
14145 [(parallel [(set (match_dup 2)
14146 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14147 UNSPEC_XTRACT_FRACT))
14148 (set (match_operand:XF 0 "register_operand" "")
14149 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14150 "TARGET_USE_FANCY_MATH_387
14151 && flag_unsafe_math_optimizations"
14152 "operands[2] = gen_reg_rtx (XFmode);")
14153
14154 (define_expand "logb<mode>2"
14155 [(use (match_operand:MODEF 0 "register_operand" ""))
14156 (use (match_operand:MODEF 1 "register_operand" ""))]
14157 "TARGET_USE_FANCY_MATH_387
14158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14159 || TARGET_MIX_SSE_I387)
14160 && flag_unsafe_math_optimizations"
14161 {
14162 rtx op0 = gen_reg_rtx (XFmode);
14163 rtx op1 = gen_reg_rtx (XFmode);
14164
14165 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14166 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14167 DONE;
14168 })
14169
14170 (define_expand "ilogbxf2"
14171 [(use (match_operand:SI 0 "register_operand" ""))
14172 (use (match_operand:XF 1 "register_operand" ""))]
14173 "TARGET_USE_FANCY_MATH_387
14174 && flag_unsafe_math_optimizations"
14175 {
14176 rtx op0, op1;
14177
14178 if (optimize_insn_for_size_p ())
14179 FAIL;
14180
14181 op0 = gen_reg_rtx (XFmode);
14182 op1 = gen_reg_rtx (XFmode);
14183
14184 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14185 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14186 DONE;
14187 })
14188
14189 (define_expand "ilogb<mode>2"
14190 [(use (match_operand:SI 0 "register_operand" ""))
14191 (use (match_operand:MODEF 1 "register_operand" ""))]
14192 "TARGET_USE_FANCY_MATH_387
14193 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14194 || TARGET_MIX_SSE_I387)
14195 && flag_unsafe_math_optimizations"
14196 {
14197 rtx op0, op1;
14198
14199 if (optimize_insn_for_size_p ())
14200 FAIL;
14201
14202 op0 = gen_reg_rtx (XFmode);
14203 op1 = gen_reg_rtx (XFmode);
14204
14205 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14206 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14207 DONE;
14208 })
14209
14210 (define_insn "*f2xm1xf2_i387"
14211 [(set (match_operand:XF 0 "register_operand" "=f")
14212 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14213 UNSPEC_F2XM1))]
14214 "TARGET_USE_FANCY_MATH_387
14215 && flag_unsafe_math_optimizations"
14216 "f2xm1"
14217 [(set_attr "type" "fpspc")
14218 (set_attr "mode" "XF")])
14219
14220 (define_insn "*fscalexf4_i387"
14221 [(set (match_operand:XF 0 "register_operand" "=f")
14222 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14223 (match_operand:XF 3 "register_operand" "1")]
14224 UNSPEC_FSCALE_FRACT))
14225 (set (match_operand:XF 1 "register_operand" "=u")
14226 (unspec:XF [(match_dup 2) (match_dup 3)]
14227 UNSPEC_FSCALE_EXP))]
14228 "TARGET_USE_FANCY_MATH_387
14229 && flag_unsafe_math_optimizations"
14230 "fscale"
14231 [(set_attr "type" "fpspc")
14232 (set_attr "mode" "XF")])
14233
14234 (define_expand "expNcorexf3"
14235 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14236 (match_operand:XF 2 "register_operand" "")))
14237 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14238 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14239 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14240 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14241 (parallel [(set (match_operand:XF 0 "register_operand" "")
14242 (unspec:XF [(match_dup 8) (match_dup 4)]
14243 UNSPEC_FSCALE_FRACT))
14244 (set (match_dup 9)
14245 (unspec:XF [(match_dup 8) (match_dup 4)]
14246 UNSPEC_FSCALE_EXP))])]
14247 "TARGET_USE_FANCY_MATH_387
14248 && flag_unsafe_math_optimizations"
14249 {
14250 int i;
14251
14252 if (optimize_insn_for_size_p ())
14253 FAIL;
14254
14255 for (i = 3; i < 10; i++)
14256 operands[i] = gen_reg_rtx (XFmode);
14257
14258 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14259 })
14260
14261 (define_expand "expxf2"
14262 [(use (match_operand:XF 0 "register_operand" ""))
14263 (use (match_operand:XF 1 "register_operand" ""))]
14264 "TARGET_USE_FANCY_MATH_387
14265 && flag_unsafe_math_optimizations"
14266 {
14267 rtx op2;
14268
14269 if (optimize_insn_for_size_p ())
14270 FAIL;
14271
14272 op2 = gen_reg_rtx (XFmode);
14273 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14274
14275 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14276 DONE;
14277 })
14278
14279 (define_expand "exp<mode>2"
14280 [(use (match_operand:MODEF 0 "register_operand" ""))
14281 (use (match_operand:MODEF 1 "general_operand" ""))]
14282 "TARGET_USE_FANCY_MATH_387
14283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14284 || TARGET_MIX_SSE_I387)
14285 && flag_unsafe_math_optimizations"
14286 {
14287 rtx op0, op1;
14288
14289 if (optimize_insn_for_size_p ())
14290 FAIL;
14291
14292 op0 = gen_reg_rtx (XFmode);
14293 op1 = gen_reg_rtx (XFmode);
14294
14295 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14296 emit_insn (gen_expxf2 (op0, op1));
14297 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14298 DONE;
14299 })
14300
14301 (define_expand "exp10xf2"
14302 [(use (match_operand:XF 0 "register_operand" ""))
14303 (use (match_operand:XF 1 "register_operand" ""))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && flag_unsafe_math_optimizations"
14306 {
14307 rtx op2;
14308
14309 if (optimize_insn_for_size_p ())
14310 FAIL;
14311
14312 op2 = gen_reg_rtx (XFmode);
14313 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14314
14315 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14316 DONE;
14317 })
14318
14319 (define_expand "exp10<mode>2"
14320 [(use (match_operand:MODEF 0 "register_operand" ""))
14321 (use (match_operand:MODEF 1 "general_operand" ""))]
14322 "TARGET_USE_FANCY_MATH_387
14323 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14324 || TARGET_MIX_SSE_I387)
14325 && flag_unsafe_math_optimizations"
14326 {
14327 rtx op0, op1;
14328
14329 if (optimize_insn_for_size_p ())
14330 FAIL;
14331
14332 op0 = gen_reg_rtx (XFmode);
14333 op1 = gen_reg_rtx (XFmode);
14334
14335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14336 emit_insn (gen_exp10xf2 (op0, op1));
14337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14338 DONE;
14339 })
14340
14341 (define_expand "exp2xf2"
14342 [(use (match_operand:XF 0 "register_operand" ""))
14343 (use (match_operand:XF 1 "register_operand" ""))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && flag_unsafe_math_optimizations"
14346 {
14347 rtx op2;
14348
14349 if (optimize_insn_for_size_p ())
14350 FAIL;
14351
14352 op2 = gen_reg_rtx (XFmode);
14353 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14354
14355 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14356 DONE;
14357 })
14358
14359 (define_expand "exp2<mode>2"
14360 [(use (match_operand:MODEF 0 "register_operand" ""))
14361 (use (match_operand:MODEF 1 "general_operand" ""))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364 || TARGET_MIX_SSE_I387)
14365 && flag_unsafe_math_optimizations"
14366 {
14367 rtx op0, op1;
14368
14369 if (optimize_insn_for_size_p ())
14370 FAIL;
14371
14372 op0 = gen_reg_rtx (XFmode);
14373 op1 = gen_reg_rtx (XFmode);
14374
14375 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14376 emit_insn (gen_exp2xf2 (op0, op1));
14377 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14378 DONE;
14379 })
14380
14381 (define_expand "expm1xf2"
14382 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14383 (match_dup 2)))
14384 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14385 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14386 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14387 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14388 (parallel [(set (match_dup 7)
14389 (unspec:XF [(match_dup 6) (match_dup 4)]
14390 UNSPEC_FSCALE_FRACT))
14391 (set (match_dup 8)
14392 (unspec:XF [(match_dup 6) (match_dup 4)]
14393 UNSPEC_FSCALE_EXP))])
14394 (parallel [(set (match_dup 10)
14395 (unspec:XF [(match_dup 9) (match_dup 8)]
14396 UNSPEC_FSCALE_FRACT))
14397 (set (match_dup 11)
14398 (unspec:XF [(match_dup 9) (match_dup 8)]
14399 UNSPEC_FSCALE_EXP))])
14400 (set (match_dup 12) (minus:XF (match_dup 10)
14401 (float_extend:XF (match_dup 13))))
14402 (set (match_operand:XF 0 "register_operand" "")
14403 (plus:XF (match_dup 12) (match_dup 7)))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && flag_unsafe_math_optimizations"
14406 {
14407 int i;
14408
14409 if (optimize_insn_for_size_p ())
14410 FAIL;
14411
14412 for (i = 2; i < 13; i++)
14413 operands[i] = gen_reg_rtx (XFmode);
14414
14415 operands[13]
14416 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14417
14418 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14419 })
14420
14421 (define_expand "expm1<mode>2"
14422 [(use (match_operand:MODEF 0 "register_operand" ""))
14423 (use (match_operand:MODEF 1 "general_operand" ""))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426 || TARGET_MIX_SSE_I387)
14427 && flag_unsafe_math_optimizations"
14428 {
14429 rtx op0, op1;
14430
14431 if (optimize_insn_for_size_p ())
14432 FAIL;
14433
14434 op0 = gen_reg_rtx (XFmode);
14435 op1 = gen_reg_rtx (XFmode);
14436
14437 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14438 emit_insn (gen_expm1xf2 (op0, op1));
14439 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14440 DONE;
14441 })
14442
14443 (define_expand "ldexpxf3"
14444 [(set (match_dup 3)
14445 (float:XF (match_operand:SI 2 "register_operand" "")))
14446 (parallel [(set (match_operand:XF 0 " register_operand" "")
14447 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14448 (match_dup 3)]
14449 UNSPEC_FSCALE_FRACT))
14450 (set (match_dup 4)
14451 (unspec:XF [(match_dup 1) (match_dup 3)]
14452 UNSPEC_FSCALE_EXP))])]
14453 "TARGET_USE_FANCY_MATH_387
14454 && flag_unsafe_math_optimizations"
14455 {
14456 if (optimize_insn_for_size_p ())
14457 FAIL;
14458
14459 operands[3] = gen_reg_rtx (XFmode);
14460 operands[4] = gen_reg_rtx (XFmode);
14461 })
14462
14463 (define_expand "ldexp<mode>3"
14464 [(use (match_operand:MODEF 0 "register_operand" ""))
14465 (use (match_operand:MODEF 1 "general_operand" ""))
14466 (use (match_operand:SI 2 "register_operand" ""))]
14467 "TARGET_USE_FANCY_MATH_387
14468 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14469 || TARGET_MIX_SSE_I387)
14470 && flag_unsafe_math_optimizations"
14471 {
14472 rtx op0, op1;
14473
14474 if (optimize_insn_for_size_p ())
14475 FAIL;
14476
14477 op0 = gen_reg_rtx (XFmode);
14478 op1 = gen_reg_rtx (XFmode);
14479
14480 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14481 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14482 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14483 DONE;
14484 })
14485
14486 (define_expand "scalbxf3"
14487 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14488 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14489 (match_operand:XF 2 "register_operand" "")]
14490 UNSPEC_FSCALE_FRACT))
14491 (set (match_dup 3)
14492 (unspec:XF [(match_dup 1) (match_dup 2)]
14493 UNSPEC_FSCALE_EXP))])]
14494 "TARGET_USE_FANCY_MATH_387
14495 && flag_unsafe_math_optimizations"
14496 {
14497 if (optimize_insn_for_size_p ())
14498 FAIL;
14499
14500 operands[3] = gen_reg_rtx (XFmode);
14501 })
14502
14503 (define_expand "scalb<mode>3"
14504 [(use (match_operand:MODEF 0 "register_operand" ""))
14505 (use (match_operand:MODEF 1 "general_operand" ""))
14506 (use (match_operand:MODEF 2 "general_operand" ""))]
14507 "TARGET_USE_FANCY_MATH_387
14508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509 || TARGET_MIX_SSE_I387)
14510 && flag_unsafe_math_optimizations"
14511 {
14512 rtx op0, op1, op2;
14513
14514 if (optimize_insn_for_size_p ())
14515 FAIL;
14516
14517 op0 = gen_reg_rtx (XFmode);
14518 op1 = gen_reg_rtx (XFmode);
14519 op2 = gen_reg_rtx (XFmode);
14520
14521 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14522 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14523 emit_insn (gen_scalbxf3 (op0, op1, op2));
14524 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14525 DONE;
14526 })
14527
14528 (define_expand "significandxf2"
14529 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14530 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14531 UNSPEC_XTRACT_FRACT))
14532 (set (match_dup 2)
14533 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14534 "TARGET_USE_FANCY_MATH_387
14535 && flag_unsafe_math_optimizations"
14536 "operands[2] = gen_reg_rtx (XFmode);")
14537
14538 (define_expand "significand<mode>2"
14539 [(use (match_operand:MODEF 0 "register_operand" ""))
14540 (use (match_operand:MODEF 1 "register_operand" ""))]
14541 "TARGET_USE_FANCY_MATH_387
14542 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14543 || TARGET_MIX_SSE_I387)
14544 && flag_unsafe_math_optimizations"
14545 {
14546 rtx op0 = gen_reg_rtx (XFmode);
14547 rtx op1 = gen_reg_rtx (XFmode);
14548
14549 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14550 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14551 DONE;
14552 })
14553 \f
14554
14555 (define_insn "sse4_1_round<mode>2"
14556 [(set (match_operand:MODEF 0 "register_operand" "=x")
14557 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14558 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14559 UNSPEC_ROUND))]
14560 "TARGET_ROUND"
14561 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14562 [(set_attr "type" "ssecvt")
14563 (set_attr "prefix_extra" "1")
14564 (set_attr "prefix" "maybe_vex")
14565 (set_attr "mode" "<MODE>")])
14566
14567 (define_insn "rintxf2"
14568 [(set (match_operand:XF 0 "register_operand" "=f")
14569 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14570 UNSPEC_FRNDINT))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && flag_unsafe_math_optimizations"
14573 "frndint"
14574 [(set_attr "type" "fpspc")
14575 (set_attr "mode" "XF")])
14576
14577 (define_expand "rint<mode>2"
14578 [(use (match_operand:MODEF 0 "register_operand" ""))
14579 (use (match_operand:MODEF 1 "register_operand" ""))]
14580 "(TARGET_USE_FANCY_MATH_387
14581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14582 || TARGET_MIX_SSE_I387)
14583 && flag_unsafe_math_optimizations)
14584 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585 && !flag_trapping_math)"
14586 {
14587 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14588 && !flag_trapping_math)
14589 {
14590 if (TARGET_ROUND)
14591 emit_insn (gen_sse4_1_round<mode>2
14592 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14593 else if (optimize_insn_for_size_p ())
14594 FAIL;
14595 else
14596 ix86_expand_rint (operands[0], operands[1]);
14597 }
14598 else
14599 {
14600 rtx op0 = gen_reg_rtx (XFmode);
14601 rtx op1 = gen_reg_rtx (XFmode);
14602
14603 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14604 emit_insn (gen_rintxf2 (op0, op1));
14605
14606 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14607 }
14608 DONE;
14609 })
14610
14611 (define_expand "round<mode>2"
14612 [(match_operand:X87MODEF 0 "register_operand" "")
14613 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14614 "(TARGET_USE_FANCY_MATH_387
14615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14616 || TARGET_MIX_SSE_I387)
14617 && flag_unsafe_math_optimizations)
14618 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14619 && !flag_trapping_math && !flag_rounding_math)"
14620 {
14621 if (optimize_insn_for_size_p ())
14622 FAIL;
14623
14624 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14625 && !flag_trapping_math && !flag_rounding_math)
14626 {
14627 if (TARGET_ROUND)
14628 {
14629 operands[1] = force_reg (<MODE>mode, operands[1]);
14630 ix86_expand_round_sse4 (operands[0], operands[1]);
14631 }
14632 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14633 ix86_expand_round (operands[0], operands[1]);
14634 else
14635 ix86_expand_rounddf_32 (operands[0], operands[1]);
14636 }
14637 else
14638 {
14639 operands[1] = force_reg (<MODE>mode, operands[1]);
14640 ix86_emit_i387_round (operands[0], operands[1]);
14641 }
14642 DONE;
14643 })
14644
14645 (define_insn_and_split "*fistdi2_1"
14646 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14647 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14648 UNSPEC_FIST))]
14649 "TARGET_USE_FANCY_MATH_387
14650 && can_create_pseudo_p ()"
14651 "#"
14652 "&& 1"
14653 [(const_int 0)]
14654 {
14655 if (memory_operand (operands[0], VOIDmode))
14656 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14657 else
14658 {
14659 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14660 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14661 operands[2]));
14662 }
14663 DONE;
14664 }
14665 [(set_attr "type" "fpspc")
14666 (set_attr "mode" "DI")])
14667
14668 (define_insn "fistdi2"
14669 [(set (match_operand:DI 0 "memory_operand" "=m")
14670 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14671 UNSPEC_FIST))
14672 (clobber (match_scratch:XF 2 "=&1f"))]
14673 "TARGET_USE_FANCY_MATH_387"
14674 "* return output_fix_trunc (insn, operands, false);"
14675 [(set_attr "type" "fpspc")
14676 (set_attr "mode" "DI")])
14677
14678 (define_insn "fistdi2_with_temp"
14679 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14680 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14681 UNSPEC_FIST))
14682 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14683 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14684 "TARGET_USE_FANCY_MATH_387"
14685 "#"
14686 [(set_attr "type" "fpspc")
14687 (set_attr "mode" "DI")])
14688
14689 (define_split
14690 [(set (match_operand:DI 0 "register_operand" "")
14691 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14692 UNSPEC_FIST))
14693 (clobber (match_operand:DI 2 "memory_operand" ""))
14694 (clobber (match_scratch 3 ""))]
14695 "reload_completed"
14696 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14697 (clobber (match_dup 3))])
14698 (set (match_dup 0) (match_dup 2))])
14699
14700 (define_split
14701 [(set (match_operand:DI 0 "memory_operand" "")
14702 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14703 UNSPEC_FIST))
14704 (clobber (match_operand:DI 2 "memory_operand" ""))
14705 (clobber (match_scratch 3 ""))]
14706 "reload_completed"
14707 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14708 (clobber (match_dup 3))])])
14709
14710 (define_insn_and_split "*fist<mode>2_1"
14711 [(set (match_operand:SWI24 0 "register_operand" "")
14712 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14713 UNSPEC_FIST))]
14714 "TARGET_USE_FANCY_MATH_387
14715 && can_create_pseudo_p ()"
14716 "#"
14717 "&& 1"
14718 [(const_int 0)]
14719 {
14720 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14721 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14722 operands[2]));
14723 DONE;
14724 }
14725 [(set_attr "type" "fpspc")
14726 (set_attr "mode" "<MODE>")])
14727
14728 (define_insn "fist<mode>2"
14729 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14730 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14731 UNSPEC_FIST))]
14732 "TARGET_USE_FANCY_MATH_387"
14733 "* return output_fix_trunc (insn, operands, false);"
14734 [(set_attr "type" "fpspc")
14735 (set_attr "mode" "<MODE>")])
14736
14737 (define_insn "fist<mode>2_with_temp"
14738 [(set (match_operand:SWI24 0 "register_operand" "=r")
14739 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14740 UNSPEC_FIST))
14741 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14742 "TARGET_USE_FANCY_MATH_387"
14743 "#"
14744 [(set_attr "type" "fpspc")
14745 (set_attr "mode" "<MODE>")])
14746
14747 (define_split
14748 [(set (match_operand:SWI24 0 "register_operand" "")
14749 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14750 UNSPEC_FIST))
14751 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14752 "reload_completed"
14753 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14754 (set (match_dup 0) (match_dup 2))])
14755
14756 (define_split
14757 [(set (match_operand:SWI24 0 "memory_operand" "")
14758 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14759 UNSPEC_FIST))
14760 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14761 "reload_completed"
14762 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14763
14764 (define_expand "lrintxf<mode>2"
14765 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14766 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14767 UNSPEC_FIST))]
14768 "TARGET_USE_FANCY_MATH_387")
14769
14770 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14771 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14772 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14773 UNSPEC_FIX_NOTRUNC))]
14774 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14775 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14776
14777 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14778 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14779 (match_operand:X87MODEF 1 "register_operand" "")]
14780 "(TARGET_USE_FANCY_MATH_387
14781 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14782 || TARGET_MIX_SSE_I387)
14783 && flag_unsafe_math_optimizations)
14784 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14785 && <SWI248x:MODE>mode != HImode
14786 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14787 && !flag_trapping_math && !flag_rounding_math)"
14788 {
14789 if (optimize_insn_for_size_p ())
14790 FAIL;
14791
14792 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14793 && <SWI248x:MODE>mode != HImode
14794 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14795 && !flag_trapping_math && !flag_rounding_math)
14796 ix86_expand_lround (operands[0], operands[1]);
14797 else
14798 ix86_emit_i387_round (operands[0], operands[1]);
14799 DONE;
14800 })
14801
14802 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14803 (define_insn_and_split "frndintxf2_floor"
14804 [(set (match_operand:XF 0 "register_operand" "")
14805 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14806 UNSPEC_FRNDINT_FLOOR))
14807 (clobber (reg:CC FLAGS_REG))]
14808 "TARGET_USE_FANCY_MATH_387
14809 && flag_unsafe_math_optimizations
14810 && can_create_pseudo_p ()"
14811 "#"
14812 "&& 1"
14813 [(const_int 0)]
14814 {
14815 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14816
14817 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14818 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14819
14820 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14821 operands[2], operands[3]));
14822 DONE;
14823 }
14824 [(set_attr "type" "frndint")
14825 (set_attr "i387_cw" "floor")
14826 (set_attr "mode" "XF")])
14827
14828 (define_insn "frndintxf2_floor_i387"
14829 [(set (match_operand:XF 0 "register_operand" "=f")
14830 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14831 UNSPEC_FRNDINT_FLOOR))
14832 (use (match_operand:HI 2 "memory_operand" "m"))
14833 (use (match_operand:HI 3 "memory_operand" "m"))]
14834 "TARGET_USE_FANCY_MATH_387
14835 && flag_unsafe_math_optimizations"
14836 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14837 [(set_attr "type" "frndint")
14838 (set_attr "i387_cw" "floor")
14839 (set_attr "mode" "XF")])
14840
14841 (define_expand "floorxf2"
14842 [(use (match_operand:XF 0 "register_operand" ""))
14843 (use (match_operand:XF 1 "register_operand" ""))]
14844 "TARGET_USE_FANCY_MATH_387
14845 && flag_unsafe_math_optimizations"
14846 {
14847 if (optimize_insn_for_size_p ())
14848 FAIL;
14849 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14850 DONE;
14851 })
14852
14853 (define_expand "floor<mode>2"
14854 [(use (match_operand:MODEF 0 "register_operand" ""))
14855 (use (match_operand:MODEF 1 "register_operand" ""))]
14856 "(TARGET_USE_FANCY_MATH_387
14857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14858 || TARGET_MIX_SSE_I387)
14859 && flag_unsafe_math_optimizations)
14860 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14861 && !flag_trapping_math)"
14862 {
14863 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14864 && !flag_trapping_math)
14865 {
14866 if (TARGET_ROUND)
14867 emit_insn (gen_sse4_1_round<mode>2
14868 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14869 else if (optimize_insn_for_size_p ())
14870 FAIL;
14871 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14872 ix86_expand_floorceil (operands[0], operands[1], true);
14873 else
14874 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14875 }
14876 else
14877 {
14878 rtx op0, op1;
14879
14880 if (optimize_insn_for_size_p ())
14881 FAIL;
14882
14883 op0 = gen_reg_rtx (XFmode);
14884 op1 = gen_reg_rtx (XFmode);
14885 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14886 emit_insn (gen_frndintxf2_floor (op0, op1));
14887
14888 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14889 }
14890 DONE;
14891 })
14892
14893 (define_insn_and_split "*fist<mode>2_floor_1"
14894 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14895 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14896 UNSPEC_FIST_FLOOR))
14897 (clobber (reg:CC FLAGS_REG))]
14898 "TARGET_USE_FANCY_MATH_387
14899 && flag_unsafe_math_optimizations
14900 && can_create_pseudo_p ()"
14901 "#"
14902 "&& 1"
14903 [(const_int 0)]
14904 {
14905 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14906
14907 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14908 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14909 if (memory_operand (operands[0], VOIDmode))
14910 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14911 operands[2], operands[3]));
14912 else
14913 {
14914 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14915 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14916 operands[2], operands[3],
14917 operands[4]));
14918 }
14919 DONE;
14920 }
14921 [(set_attr "type" "fistp")
14922 (set_attr "i387_cw" "floor")
14923 (set_attr "mode" "<MODE>")])
14924
14925 (define_insn "fistdi2_floor"
14926 [(set (match_operand:DI 0 "memory_operand" "=m")
14927 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14928 UNSPEC_FIST_FLOOR))
14929 (use (match_operand:HI 2 "memory_operand" "m"))
14930 (use (match_operand:HI 3 "memory_operand" "m"))
14931 (clobber (match_scratch:XF 4 "=&1f"))]
14932 "TARGET_USE_FANCY_MATH_387
14933 && flag_unsafe_math_optimizations"
14934 "* return output_fix_trunc (insn, operands, false);"
14935 [(set_attr "type" "fistp")
14936 (set_attr "i387_cw" "floor")
14937 (set_attr "mode" "DI")])
14938
14939 (define_insn "fistdi2_floor_with_temp"
14940 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14941 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14942 UNSPEC_FIST_FLOOR))
14943 (use (match_operand:HI 2 "memory_operand" "m,m"))
14944 (use (match_operand:HI 3 "memory_operand" "m,m"))
14945 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14946 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14947 "TARGET_USE_FANCY_MATH_387
14948 && flag_unsafe_math_optimizations"
14949 "#"
14950 [(set_attr "type" "fistp")
14951 (set_attr "i387_cw" "floor")
14952 (set_attr "mode" "DI")])
14953
14954 (define_split
14955 [(set (match_operand:DI 0 "register_operand" "")
14956 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14957 UNSPEC_FIST_FLOOR))
14958 (use (match_operand:HI 2 "memory_operand" ""))
14959 (use (match_operand:HI 3 "memory_operand" ""))
14960 (clobber (match_operand:DI 4 "memory_operand" ""))
14961 (clobber (match_scratch 5 ""))]
14962 "reload_completed"
14963 [(parallel [(set (match_dup 4)
14964 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14965 (use (match_dup 2))
14966 (use (match_dup 3))
14967 (clobber (match_dup 5))])
14968 (set (match_dup 0) (match_dup 4))])
14969
14970 (define_split
14971 [(set (match_operand:DI 0 "memory_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 0)
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
14985 (define_insn "fist<mode>2_floor"
14986 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14987 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14988 UNSPEC_FIST_FLOOR))
14989 (use (match_operand:HI 2 "memory_operand" "m"))
14990 (use (match_operand:HI 3 "memory_operand" "m"))]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14993 "* return output_fix_trunc (insn, operands, false);"
14994 [(set_attr "type" "fistp")
14995 (set_attr "i387_cw" "floor")
14996 (set_attr "mode" "<MODE>")])
14997
14998 (define_insn "fist<mode>2_floor_with_temp"
14999 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15000 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15001 UNSPEC_FIST_FLOOR))
15002 (use (match_operand:HI 2 "memory_operand" "m,m"))
15003 (use (match_operand:HI 3 "memory_operand" "m,m"))
15004 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15005 "TARGET_USE_FANCY_MATH_387
15006 && flag_unsafe_math_optimizations"
15007 "#"
15008 [(set_attr "type" "fistp")
15009 (set_attr "i387_cw" "floor")
15010 (set_attr "mode" "<MODE>")])
15011
15012 (define_split
15013 [(set (match_operand:SWI24 0 "register_operand" "")
15014 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15015 UNSPEC_FIST_FLOOR))
15016 (use (match_operand:HI 2 "memory_operand" ""))
15017 (use (match_operand:HI 3 "memory_operand" ""))
15018 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15019 "reload_completed"
15020 [(parallel [(set (match_dup 4)
15021 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15022 (use (match_dup 2))
15023 (use (match_dup 3))])
15024 (set (match_dup 0) (match_dup 4))])
15025
15026 (define_split
15027 [(set (match_operand:SWI24 0 "memory_operand" "")
15028 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15029 UNSPEC_FIST_FLOOR))
15030 (use (match_operand:HI 2 "memory_operand" ""))
15031 (use (match_operand:HI 3 "memory_operand" ""))
15032 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15033 "reload_completed"
15034 [(parallel [(set (match_dup 0)
15035 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15036 (use (match_dup 2))
15037 (use (match_dup 3))])])
15038
15039 (define_expand "lfloorxf<mode>2"
15040 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15041 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15042 UNSPEC_FIST_FLOOR))
15043 (clobber (reg:CC FLAGS_REG))])]
15044 "TARGET_USE_FANCY_MATH_387
15045 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15046 && flag_unsafe_math_optimizations")
15047
15048 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15049 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15050 (match_operand:MODEF 1 "register_operand" "")]
15051 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15052 && !flag_trapping_math"
15053 {
15054 if (TARGET_64BIT && optimize_insn_for_size_p ())
15055 FAIL;
15056 ix86_expand_lfloorceil (operands[0], operands[1], true);
15057 DONE;
15058 })
15059
15060 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15061 (define_insn_and_split "frndintxf2_ceil"
15062 [(set (match_operand:XF 0 "register_operand" "")
15063 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15064 UNSPEC_FRNDINT_CEIL))
15065 (clobber (reg:CC FLAGS_REG))]
15066 "TARGET_USE_FANCY_MATH_387
15067 && flag_unsafe_math_optimizations
15068 && can_create_pseudo_p ()"
15069 "#"
15070 "&& 1"
15071 [(const_int 0)]
15072 {
15073 ix86_optimize_mode_switching[I387_CEIL] = 1;
15074
15075 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15076 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15077
15078 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15079 operands[2], operands[3]));
15080 DONE;
15081 }
15082 [(set_attr "type" "frndint")
15083 (set_attr "i387_cw" "ceil")
15084 (set_attr "mode" "XF")])
15085
15086 (define_insn "frndintxf2_ceil_i387"
15087 [(set (match_operand:XF 0 "register_operand" "=f")
15088 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15089 UNSPEC_FRNDINT_CEIL))
15090 (use (match_operand:HI 2 "memory_operand" "m"))
15091 (use (match_operand:HI 3 "memory_operand" "m"))]
15092 "TARGET_USE_FANCY_MATH_387
15093 && flag_unsafe_math_optimizations"
15094 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15095 [(set_attr "type" "frndint")
15096 (set_attr "i387_cw" "ceil")
15097 (set_attr "mode" "XF")])
15098
15099 (define_expand "ceilxf2"
15100 [(use (match_operand:XF 0 "register_operand" ""))
15101 (use (match_operand:XF 1 "register_operand" ""))]
15102 "TARGET_USE_FANCY_MATH_387
15103 && flag_unsafe_math_optimizations"
15104 {
15105 if (optimize_insn_for_size_p ())
15106 FAIL;
15107 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15108 DONE;
15109 })
15110
15111 (define_expand "ceil<mode>2"
15112 [(use (match_operand:MODEF 0 "register_operand" ""))
15113 (use (match_operand:MODEF 1 "register_operand" ""))]
15114 "(TARGET_USE_FANCY_MATH_387
15115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15116 || TARGET_MIX_SSE_I387)
15117 && flag_unsafe_math_optimizations)
15118 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15119 && !flag_trapping_math)"
15120 {
15121 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15122 && !flag_trapping_math)
15123 {
15124 if (TARGET_ROUND)
15125 emit_insn (gen_sse4_1_round<mode>2
15126 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15127 else if (optimize_insn_for_size_p ())
15128 FAIL;
15129 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15130 ix86_expand_floorceil (operands[0], operands[1], false);
15131 else
15132 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15133 }
15134 else
15135 {
15136 rtx op0, op1;
15137
15138 if (optimize_insn_for_size_p ())
15139 FAIL;
15140
15141 op0 = gen_reg_rtx (XFmode);
15142 op1 = gen_reg_rtx (XFmode);
15143 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15144 emit_insn (gen_frndintxf2_ceil (op0, op1));
15145
15146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15147 }
15148 DONE;
15149 })
15150
15151 (define_insn_and_split "*fist<mode>2_ceil_1"
15152 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15153 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15154 UNSPEC_FIST_CEIL))
15155 (clobber (reg:CC FLAGS_REG))]
15156 "TARGET_USE_FANCY_MATH_387
15157 && flag_unsafe_math_optimizations
15158 && can_create_pseudo_p ()"
15159 "#"
15160 "&& 1"
15161 [(const_int 0)]
15162 {
15163 ix86_optimize_mode_switching[I387_CEIL] = 1;
15164
15165 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15166 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15167 if (memory_operand (operands[0], VOIDmode))
15168 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15169 operands[2], operands[3]));
15170 else
15171 {
15172 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15173 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15174 operands[2], operands[3],
15175 operands[4]));
15176 }
15177 DONE;
15178 }
15179 [(set_attr "type" "fistp")
15180 (set_attr "i387_cw" "ceil")
15181 (set_attr "mode" "<MODE>")])
15182
15183 (define_insn "fistdi2_ceil"
15184 [(set (match_operand:DI 0 "memory_operand" "=m")
15185 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15186 UNSPEC_FIST_CEIL))
15187 (use (match_operand:HI 2 "memory_operand" "m"))
15188 (use (match_operand:HI 3 "memory_operand" "m"))
15189 (clobber (match_scratch:XF 4 "=&1f"))]
15190 "TARGET_USE_FANCY_MATH_387
15191 && flag_unsafe_math_optimizations"
15192 "* return output_fix_trunc (insn, operands, false);"
15193 [(set_attr "type" "fistp")
15194 (set_attr "i387_cw" "ceil")
15195 (set_attr "mode" "DI")])
15196
15197 (define_insn "fistdi2_ceil_with_temp"
15198 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15199 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15200 UNSPEC_FIST_CEIL))
15201 (use (match_operand:HI 2 "memory_operand" "m,m"))
15202 (use (match_operand:HI 3 "memory_operand" "m,m"))
15203 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15204 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15205 "TARGET_USE_FANCY_MATH_387
15206 && flag_unsafe_math_optimizations"
15207 "#"
15208 [(set_attr "type" "fistp")
15209 (set_attr "i387_cw" "ceil")
15210 (set_attr "mode" "DI")])
15211
15212 (define_split
15213 [(set (match_operand:DI 0 "register_operand" "")
15214 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15215 UNSPEC_FIST_CEIL))
15216 (use (match_operand:HI 2 "memory_operand" ""))
15217 (use (match_operand:HI 3 "memory_operand" ""))
15218 (clobber (match_operand:DI 4 "memory_operand" ""))
15219 (clobber (match_scratch 5 ""))]
15220 "reload_completed"
15221 [(parallel [(set (match_dup 4)
15222 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15223 (use (match_dup 2))
15224 (use (match_dup 3))
15225 (clobber (match_dup 5))])
15226 (set (match_dup 0) (match_dup 4))])
15227
15228 (define_split
15229 [(set (match_operand:DI 0 "memory_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 0)
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
15243 (define_insn "fist<mode>2_ceil"
15244 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15245 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15246 UNSPEC_FIST_CEIL))
15247 (use (match_operand:HI 2 "memory_operand" "m"))
15248 (use (match_operand:HI 3 "memory_operand" "m"))]
15249 "TARGET_USE_FANCY_MATH_387
15250 && flag_unsafe_math_optimizations"
15251 "* return output_fix_trunc (insn, operands, false);"
15252 [(set_attr "type" "fistp")
15253 (set_attr "i387_cw" "ceil")
15254 (set_attr "mode" "<MODE>")])
15255
15256 (define_insn "fist<mode>2_ceil_with_temp"
15257 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15258 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15259 UNSPEC_FIST_CEIL))
15260 (use (match_operand:HI 2 "memory_operand" "m,m"))
15261 (use (match_operand:HI 3 "memory_operand" "m,m"))
15262 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && flag_unsafe_math_optimizations"
15265 "#"
15266 [(set_attr "type" "fistp")
15267 (set_attr "i387_cw" "ceil")
15268 (set_attr "mode" "<MODE>")])
15269
15270 (define_split
15271 [(set (match_operand:SWI24 0 "register_operand" "")
15272 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15273 UNSPEC_FIST_CEIL))
15274 (use (match_operand:HI 2 "memory_operand" ""))
15275 (use (match_operand:HI 3 "memory_operand" ""))
15276 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15277 "reload_completed"
15278 [(parallel [(set (match_dup 4)
15279 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15280 (use (match_dup 2))
15281 (use (match_dup 3))])
15282 (set (match_dup 0) (match_dup 4))])
15283
15284 (define_split
15285 [(set (match_operand:SWI24 0 "memory_operand" "")
15286 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15287 UNSPEC_FIST_CEIL))
15288 (use (match_operand:HI 2 "memory_operand" ""))
15289 (use (match_operand:HI 3 "memory_operand" ""))
15290 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15291 "reload_completed"
15292 [(parallel [(set (match_dup 0)
15293 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15294 (use (match_dup 2))
15295 (use (match_dup 3))])])
15296
15297 (define_expand "lceilxf<mode>2"
15298 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15299 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15300 UNSPEC_FIST_CEIL))
15301 (clobber (reg:CC FLAGS_REG))])]
15302 "TARGET_USE_FANCY_MATH_387
15303 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15304 && flag_unsafe_math_optimizations")
15305
15306 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15307 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15308 (match_operand:MODEF 1 "register_operand" "")]
15309 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15310 && !flag_trapping_math"
15311 {
15312 ix86_expand_lfloorceil (operands[0], operands[1], false);
15313 DONE;
15314 })
15315
15316 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15317 (define_insn_and_split "frndintxf2_trunc"
15318 [(set (match_operand:XF 0 "register_operand" "")
15319 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15320 UNSPEC_FRNDINT_TRUNC))
15321 (clobber (reg:CC FLAGS_REG))]
15322 "TARGET_USE_FANCY_MATH_387
15323 && flag_unsafe_math_optimizations
15324 && can_create_pseudo_p ()"
15325 "#"
15326 "&& 1"
15327 [(const_int 0)]
15328 {
15329 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15330
15331 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15332 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15333
15334 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15335 operands[2], operands[3]));
15336 DONE;
15337 }
15338 [(set_attr "type" "frndint")
15339 (set_attr "i387_cw" "trunc")
15340 (set_attr "mode" "XF")])
15341
15342 (define_insn "frndintxf2_trunc_i387"
15343 [(set (match_operand:XF 0 "register_operand" "=f")
15344 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15345 UNSPEC_FRNDINT_TRUNC))
15346 (use (match_operand:HI 2 "memory_operand" "m"))
15347 (use (match_operand:HI 3 "memory_operand" "m"))]
15348 "TARGET_USE_FANCY_MATH_387
15349 && flag_unsafe_math_optimizations"
15350 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15351 [(set_attr "type" "frndint")
15352 (set_attr "i387_cw" "trunc")
15353 (set_attr "mode" "XF")])
15354
15355 (define_expand "btruncxf2"
15356 [(use (match_operand:XF 0 "register_operand" ""))
15357 (use (match_operand:XF 1 "register_operand" ""))]
15358 "TARGET_USE_FANCY_MATH_387
15359 && flag_unsafe_math_optimizations"
15360 {
15361 if (optimize_insn_for_size_p ())
15362 FAIL;
15363 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15364 DONE;
15365 })
15366
15367 (define_expand "btrunc<mode>2"
15368 [(use (match_operand:MODEF 0 "register_operand" ""))
15369 (use (match_operand:MODEF 1 "register_operand" ""))]
15370 "(TARGET_USE_FANCY_MATH_387
15371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15372 || TARGET_MIX_SSE_I387)
15373 && flag_unsafe_math_optimizations)
15374 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15375 && !flag_trapping_math)"
15376 {
15377 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15378 && !flag_trapping_math)
15379 {
15380 if (TARGET_ROUND)
15381 emit_insn (gen_sse4_1_round<mode>2
15382 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15383 else if (optimize_insn_for_size_p ())
15384 FAIL;
15385 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15386 ix86_expand_trunc (operands[0], operands[1]);
15387 else
15388 ix86_expand_truncdf_32 (operands[0], operands[1]);
15389 }
15390 else
15391 {
15392 rtx op0, op1;
15393
15394 if (optimize_insn_for_size_p ())
15395 FAIL;
15396
15397 op0 = gen_reg_rtx (XFmode);
15398 op1 = gen_reg_rtx (XFmode);
15399 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15400 emit_insn (gen_frndintxf2_trunc (op0, op1));
15401
15402 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15403 }
15404 DONE;
15405 })
15406
15407 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15408 (define_insn_and_split "frndintxf2_mask_pm"
15409 [(set (match_operand:XF 0 "register_operand" "")
15410 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15411 UNSPEC_FRNDINT_MASK_PM))
15412 (clobber (reg:CC FLAGS_REG))]
15413 "TARGET_USE_FANCY_MATH_387
15414 && flag_unsafe_math_optimizations
15415 && can_create_pseudo_p ()"
15416 "#"
15417 "&& 1"
15418 [(const_int 0)]
15419 {
15420 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15421
15422 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15423 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15424
15425 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15426 operands[2], operands[3]));
15427 DONE;
15428 }
15429 [(set_attr "type" "frndint")
15430 (set_attr "i387_cw" "mask_pm")
15431 (set_attr "mode" "XF")])
15432
15433 (define_insn "frndintxf2_mask_pm_i387"
15434 [(set (match_operand:XF 0 "register_operand" "=f")
15435 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15436 UNSPEC_FRNDINT_MASK_PM))
15437 (use (match_operand:HI 2 "memory_operand" "m"))
15438 (use (match_operand:HI 3 "memory_operand" "m"))]
15439 "TARGET_USE_FANCY_MATH_387
15440 && flag_unsafe_math_optimizations"
15441 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15442 [(set_attr "type" "frndint")
15443 (set_attr "i387_cw" "mask_pm")
15444 (set_attr "mode" "XF")])
15445
15446 (define_expand "nearbyintxf2"
15447 [(use (match_operand:XF 0 "register_operand" ""))
15448 (use (match_operand:XF 1 "register_operand" ""))]
15449 "TARGET_USE_FANCY_MATH_387
15450 && flag_unsafe_math_optimizations"
15451 {
15452 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15453 DONE;
15454 })
15455
15456 (define_expand "nearbyint<mode>2"
15457 [(use (match_operand:MODEF 0 "register_operand" ""))
15458 (use (match_operand:MODEF 1 "register_operand" ""))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15461 || TARGET_MIX_SSE_I387)
15462 && flag_unsafe_math_optimizations"
15463 {
15464 rtx op0 = gen_reg_rtx (XFmode);
15465 rtx op1 = gen_reg_rtx (XFmode);
15466
15467 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15468 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15469
15470 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15471 DONE;
15472 })
15473
15474 (define_insn "fxam<mode>2_i387"
15475 [(set (match_operand:HI 0 "register_operand" "=a")
15476 (unspec:HI
15477 [(match_operand:X87MODEF 1 "register_operand" "f")]
15478 UNSPEC_FXAM))]
15479 "TARGET_USE_FANCY_MATH_387"
15480 "fxam\n\tfnstsw\t%0"
15481 [(set_attr "type" "multi")
15482 (set_attr "length" "4")
15483 (set_attr "unit" "i387")
15484 (set_attr "mode" "<MODE>")])
15485
15486 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15487 [(set (match_operand:HI 0 "register_operand" "")
15488 (unspec:HI
15489 [(match_operand:MODEF 1 "memory_operand" "")]
15490 UNSPEC_FXAM_MEM))]
15491 "TARGET_USE_FANCY_MATH_387
15492 && can_create_pseudo_p ()"
15493 "#"
15494 "&& 1"
15495 [(set (match_dup 2)(match_dup 1))
15496 (set (match_dup 0)
15497 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15498 {
15499 operands[2] = gen_reg_rtx (<MODE>mode);
15500
15501 MEM_VOLATILE_P (operands[1]) = 1;
15502 }
15503 [(set_attr "type" "multi")
15504 (set_attr "unit" "i387")
15505 (set_attr "mode" "<MODE>")])
15506
15507 (define_expand "isinfxf2"
15508 [(use (match_operand:SI 0 "register_operand" ""))
15509 (use (match_operand:XF 1 "register_operand" ""))]
15510 "TARGET_USE_FANCY_MATH_387
15511 && TARGET_C99_FUNCTIONS"
15512 {
15513 rtx mask = GEN_INT (0x45);
15514 rtx val = GEN_INT (0x05);
15515
15516 rtx cond;
15517
15518 rtx scratch = gen_reg_rtx (HImode);
15519 rtx res = gen_reg_rtx (QImode);
15520
15521 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15522
15523 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15524 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15525 cond = gen_rtx_fmt_ee (EQ, QImode,
15526 gen_rtx_REG (CCmode, FLAGS_REG),
15527 const0_rtx);
15528 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15529 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15530 DONE;
15531 })
15532
15533 (define_expand "isinf<mode>2"
15534 [(use (match_operand:SI 0 "register_operand" ""))
15535 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15536 "TARGET_USE_FANCY_MATH_387
15537 && TARGET_C99_FUNCTIONS
15538 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15539 {
15540 rtx mask = GEN_INT (0x45);
15541 rtx val = GEN_INT (0x05);
15542
15543 rtx cond;
15544
15545 rtx scratch = gen_reg_rtx (HImode);
15546 rtx res = gen_reg_rtx (QImode);
15547
15548 /* Remove excess precision by forcing value through memory. */
15549 if (memory_operand (operands[1], VOIDmode))
15550 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15551 else
15552 {
15553 enum ix86_stack_slot slot = (virtuals_instantiated
15554 ? SLOT_TEMP
15555 : SLOT_VIRTUAL);
15556 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15557
15558 emit_move_insn (temp, operands[1]);
15559 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15560 }
15561
15562 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15563 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15564 cond = gen_rtx_fmt_ee (EQ, QImode,
15565 gen_rtx_REG (CCmode, FLAGS_REG),
15566 const0_rtx);
15567 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15568 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15569 DONE;
15570 })
15571
15572 (define_expand "signbitxf2"
15573 [(use (match_operand:SI 0 "register_operand" ""))
15574 (use (match_operand:XF 1 "register_operand" ""))]
15575 "TARGET_USE_FANCY_MATH_387"
15576 {
15577 rtx scratch = gen_reg_rtx (HImode);
15578
15579 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15580 emit_insn (gen_andsi3 (operands[0],
15581 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15582 DONE;
15583 })
15584
15585 (define_insn "movmsk_df"
15586 [(set (match_operand:SI 0 "register_operand" "=r")
15587 (unspec:SI
15588 [(match_operand:DF 1 "register_operand" "x")]
15589 UNSPEC_MOVMSK))]
15590 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15591 "%vmovmskpd\t{%1, %0|%0, %1}"
15592 [(set_attr "type" "ssemov")
15593 (set_attr "prefix" "maybe_vex")
15594 (set_attr "mode" "DF")])
15595
15596 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15597 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15598 (define_expand "signbitdf2"
15599 [(use (match_operand:SI 0 "register_operand" ""))
15600 (use (match_operand:DF 1 "register_operand" ""))]
15601 "TARGET_USE_FANCY_MATH_387
15602 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15603 {
15604 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15605 {
15606 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15607 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15608 }
15609 else
15610 {
15611 rtx scratch = gen_reg_rtx (HImode);
15612
15613 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15614 emit_insn (gen_andsi3 (operands[0],
15615 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15616 }
15617 DONE;
15618 })
15619
15620 (define_expand "signbitsf2"
15621 [(use (match_operand:SI 0 "register_operand" ""))
15622 (use (match_operand:SF 1 "register_operand" ""))]
15623 "TARGET_USE_FANCY_MATH_387
15624 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15625 {
15626 rtx scratch = gen_reg_rtx (HImode);
15627
15628 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15629 emit_insn (gen_andsi3 (operands[0],
15630 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15631 DONE;
15632 })
15633 \f
15634 ;; Block operation instructions
15635
15636 (define_insn "cld"
15637 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15638 ""
15639 "cld"
15640 [(set_attr "length" "1")
15641 (set_attr "length_immediate" "0")
15642 (set_attr "modrm" "0")])
15643
15644 (define_expand "movmem<mode>"
15645 [(use (match_operand:BLK 0 "memory_operand" ""))
15646 (use (match_operand:BLK 1 "memory_operand" ""))
15647 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15648 (use (match_operand:SWI48 3 "const_int_operand" ""))
15649 (use (match_operand:SI 4 "const_int_operand" ""))
15650 (use (match_operand:SI 5 "const_int_operand" ""))]
15651 ""
15652 {
15653 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15654 operands[4], operands[5]))
15655 DONE;
15656 else
15657 FAIL;
15658 })
15659
15660 ;; Most CPUs don't like single string operations
15661 ;; Handle this case here to simplify previous expander.
15662
15663 (define_expand "strmov"
15664 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15665 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15666 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15667 (clobber (reg:CC FLAGS_REG))])
15668 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15669 (clobber (reg:CC FLAGS_REG))])]
15670 ""
15671 {
15672 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15673
15674 /* If .md ever supports :P for Pmode, these can be directly
15675 in the pattern above. */
15676 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15677 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15678
15679 /* Can't use this if the user has appropriated esi or edi. */
15680 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15681 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15682 {
15683 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15684 operands[2], operands[3],
15685 operands[5], operands[6]));
15686 DONE;
15687 }
15688
15689 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15690 })
15691
15692 (define_expand "strmov_singleop"
15693 [(parallel [(set (match_operand 1 "memory_operand" "")
15694 (match_operand 3 "memory_operand" ""))
15695 (set (match_operand 0 "register_operand" "")
15696 (match_operand 4 "" ""))
15697 (set (match_operand 2 "register_operand" "")
15698 (match_operand 5 "" ""))])]
15699 ""
15700 "ix86_current_function_needs_cld = 1;")
15701
15702 (define_insn "*strmovdi_rex_1"
15703 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15704 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15705 (set (match_operand:DI 0 "register_operand" "=D")
15706 (plus:DI (match_dup 2)
15707 (const_int 8)))
15708 (set (match_operand:DI 1 "register_operand" "=S")
15709 (plus:DI (match_dup 3)
15710 (const_int 8)))]
15711 "TARGET_64BIT
15712 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15713 "movsq"
15714 [(set_attr "type" "str")
15715 (set_attr "memory" "both")
15716 (set_attr "mode" "DI")])
15717
15718 (define_insn "*strmovsi_1"
15719 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15720 (mem:SI (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 4)))
15724 (set (match_operand:P 1 "register_operand" "=S")
15725 (plus:P (match_dup 3)
15726 (const_int 4)))]
15727 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15728 "movs{l|d}"
15729 [(set_attr "type" "str")
15730 (set_attr "memory" "both")
15731 (set_attr "mode" "SI")])
15732
15733 (define_insn "*strmovhi_1"
15734 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15735 (mem:HI (match_operand:P 3 "register_operand" "1")))
15736 (set (match_operand:P 0 "register_operand" "=D")
15737 (plus:P (match_dup 2)
15738 (const_int 2)))
15739 (set (match_operand:P 1 "register_operand" "=S")
15740 (plus:P (match_dup 3)
15741 (const_int 2)))]
15742 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743 "movsw"
15744 [(set_attr "type" "str")
15745 (set_attr "memory" "both")
15746 (set_attr "mode" "HI")])
15747
15748 (define_insn "*strmovqi_1"
15749 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15750 (mem:QI (match_operand:P 3 "register_operand" "1")))
15751 (set (match_operand:P 0 "register_operand" "=D")
15752 (plus:P (match_dup 2)
15753 (const_int 1)))
15754 (set (match_operand:P 1 "register_operand" "=S")
15755 (plus:P (match_dup 3)
15756 (const_int 1)))]
15757 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758 "movsb"
15759 [(set_attr "type" "str")
15760 (set_attr "memory" "both")
15761 (set (attr "prefix_rex")
15762 (if_then_else
15763 (match_test "<P:MODE>mode == DImode")
15764 (const_string "0")
15765 (const_string "*")))
15766 (set_attr "mode" "QI")])
15767
15768 (define_expand "rep_mov"
15769 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15770 (set (match_operand 0 "register_operand" "")
15771 (match_operand 5 "" ""))
15772 (set (match_operand 2 "register_operand" "")
15773 (match_operand 6 "" ""))
15774 (set (match_operand 1 "memory_operand" "")
15775 (match_operand 3 "memory_operand" ""))
15776 (use (match_dup 4))])]
15777 ""
15778 "ix86_current_function_needs_cld = 1;")
15779
15780 (define_insn "*rep_movdi_rex64"
15781 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15782 (set (match_operand:DI 0 "register_operand" "=D")
15783 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15784 (const_int 3))
15785 (match_operand:DI 3 "register_operand" "0")))
15786 (set (match_operand:DI 1 "register_operand" "=S")
15787 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15788 (match_operand:DI 4 "register_operand" "1")))
15789 (set (mem:BLK (match_dup 3))
15790 (mem:BLK (match_dup 4)))
15791 (use (match_dup 5))]
15792 "TARGET_64BIT
15793 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15794 "rep{%;} movsq"
15795 [(set_attr "type" "str")
15796 (set_attr "prefix_rep" "1")
15797 (set_attr "memory" "both")
15798 (set_attr "mode" "DI")])
15799
15800 (define_insn "*rep_movsi"
15801 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15802 (set (match_operand:P 0 "register_operand" "=D")
15803 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15804 (const_int 2))
15805 (match_operand:P 3 "register_operand" "0")))
15806 (set (match_operand:P 1 "register_operand" "=S")
15807 (plus:P (ashift:P (match_dup 5) (const_int 2))
15808 (match_operand:P 4 "register_operand" "1")))
15809 (set (mem:BLK (match_dup 3))
15810 (mem:BLK (match_dup 4)))
15811 (use (match_dup 5))]
15812 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15813 "rep{%;} movs{l|d}"
15814 [(set_attr "type" "str")
15815 (set_attr "prefix_rep" "1")
15816 (set_attr "memory" "both")
15817 (set_attr "mode" "SI")])
15818
15819 (define_insn "*rep_movqi"
15820 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15821 (set (match_operand:P 0 "register_operand" "=D")
15822 (plus:P (match_operand:P 3 "register_operand" "0")
15823 (match_operand:P 5 "register_operand" "2")))
15824 (set (match_operand:P 1 "register_operand" "=S")
15825 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15826 (set (mem:BLK (match_dup 3))
15827 (mem:BLK (match_dup 4)))
15828 (use (match_dup 5))]
15829 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15830 "rep{%;} movsb"
15831 [(set_attr "type" "str")
15832 (set_attr "prefix_rep" "1")
15833 (set_attr "memory" "both")
15834 (set_attr "mode" "QI")])
15835
15836 (define_expand "setmem<mode>"
15837 [(use (match_operand:BLK 0 "memory_operand" ""))
15838 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15839 (use (match_operand:QI 2 "nonmemory_operand" ""))
15840 (use (match_operand 3 "const_int_operand" ""))
15841 (use (match_operand:SI 4 "const_int_operand" ""))
15842 (use (match_operand:SI 5 "const_int_operand" ""))]
15843 ""
15844 {
15845 if (ix86_expand_setmem (operands[0], operands[1],
15846 operands[2], operands[3],
15847 operands[4], operands[5]))
15848 DONE;
15849 else
15850 FAIL;
15851 })
15852
15853 ;; Most CPUs don't like single string operations
15854 ;; Handle this case here to simplify previous expander.
15855
15856 (define_expand "strset"
15857 [(set (match_operand 1 "memory_operand" "")
15858 (match_operand 2 "register_operand" ""))
15859 (parallel [(set (match_operand 0 "register_operand" "")
15860 (match_dup 3))
15861 (clobber (reg:CC FLAGS_REG))])]
15862 ""
15863 {
15864 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15865 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15866
15867 /* If .md ever supports :P for Pmode, this can be directly
15868 in the pattern above. */
15869 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15870 GEN_INT (GET_MODE_SIZE (GET_MODE
15871 (operands[2]))));
15872 /* Can't use this if the user has appropriated eax or edi. */
15873 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15874 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15875 {
15876 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15877 operands[3]));
15878 DONE;
15879 }
15880 })
15881
15882 (define_expand "strset_singleop"
15883 [(parallel [(set (match_operand 1 "memory_operand" "")
15884 (match_operand 2 "register_operand" ""))
15885 (set (match_operand 0 "register_operand" "")
15886 (match_operand 3 "" ""))])]
15887 ""
15888 "ix86_current_function_needs_cld = 1;")
15889
15890 (define_insn "*strsetdi_rex_1"
15891 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15892 (match_operand:DI 2 "register_operand" "a"))
15893 (set (match_operand:DI 0 "register_operand" "=D")
15894 (plus:DI (match_dup 1)
15895 (const_int 8)))]
15896 "TARGET_64BIT
15897 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15898 "stosq"
15899 [(set_attr "type" "str")
15900 (set_attr "memory" "store")
15901 (set_attr "mode" "DI")])
15902
15903 (define_insn "*strsetsi_1"
15904 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15905 (match_operand:SI 2 "register_operand" "a"))
15906 (set (match_operand:P 0 "register_operand" "=D")
15907 (plus:P (match_dup 1)
15908 (const_int 4)))]
15909 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15910 "stos{l|d}"
15911 [(set_attr "type" "str")
15912 (set_attr "memory" "store")
15913 (set_attr "mode" "SI")])
15914
15915 (define_insn "*strsethi_1"
15916 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15917 (match_operand:HI 2 "register_operand" "a"))
15918 (set (match_operand:P 0 "register_operand" "=D")
15919 (plus:P (match_dup 1)
15920 (const_int 2)))]
15921 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15922 "stosw"
15923 [(set_attr "type" "str")
15924 (set_attr "memory" "store")
15925 (set_attr "mode" "HI")])
15926
15927 (define_insn "*strsetqi_1"
15928 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15929 (match_operand:QI 2 "register_operand" "a"))
15930 (set (match_operand:P 0 "register_operand" "=D")
15931 (plus:P (match_dup 1)
15932 (const_int 1)))]
15933 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15934 "stosb"
15935 [(set_attr "type" "str")
15936 (set_attr "memory" "store")
15937 (set (attr "prefix_rex")
15938 (if_then_else
15939 (match_test "<P:MODE>mode == DImode")
15940 (const_string "0")
15941 (const_string "*")))
15942 (set_attr "mode" "QI")])
15943
15944 (define_expand "rep_stos"
15945 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15946 (set (match_operand 0 "register_operand" "")
15947 (match_operand 4 "" ""))
15948 (set (match_operand 2 "memory_operand" "") (const_int 0))
15949 (use (match_operand 3 "register_operand" ""))
15950 (use (match_dup 1))])]
15951 ""
15952 "ix86_current_function_needs_cld = 1;")
15953
15954 (define_insn "*rep_stosdi_rex64"
15955 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15956 (set (match_operand:DI 0 "register_operand" "=D")
15957 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15958 (const_int 3))
15959 (match_operand:DI 3 "register_operand" "0")))
15960 (set (mem:BLK (match_dup 3))
15961 (const_int 0))
15962 (use (match_operand:DI 2 "register_operand" "a"))
15963 (use (match_dup 4))]
15964 "TARGET_64BIT
15965 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15966 "rep{%;} stosq"
15967 [(set_attr "type" "str")
15968 (set_attr "prefix_rep" "1")
15969 (set_attr "memory" "store")
15970 (set_attr "mode" "DI")])
15971
15972 (define_insn "*rep_stossi"
15973 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15974 (set (match_operand:P 0 "register_operand" "=D")
15975 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15976 (const_int 2))
15977 (match_operand:P 3 "register_operand" "0")))
15978 (set (mem:BLK (match_dup 3))
15979 (const_int 0))
15980 (use (match_operand:SI 2 "register_operand" "a"))
15981 (use (match_dup 4))]
15982 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15983 "rep{%;} stos{l|d}"
15984 [(set_attr "type" "str")
15985 (set_attr "prefix_rep" "1")
15986 (set_attr "memory" "store")
15987 (set_attr "mode" "SI")])
15988
15989 (define_insn "*rep_stosqi"
15990 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15991 (set (match_operand:P 0 "register_operand" "=D")
15992 (plus:P (match_operand:P 3 "register_operand" "0")
15993 (match_operand:P 4 "register_operand" "1")))
15994 (set (mem:BLK (match_dup 3))
15995 (const_int 0))
15996 (use (match_operand:QI 2 "register_operand" "a"))
15997 (use (match_dup 4))]
15998 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15999 "rep{%;} stosb"
16000 [(set_attr "type" "str")
16001 (set_attr "prefix_rep" "1")
16002 (set_attr "memory" "store")
16003 (set (attr "prefix_rex")
16004 (if_then_else
16005 (match_test "<P:MODE>mode == DImode")
16006 (const_string "0")
16007 (const_string "*")))
16008 (set_attr "mode" "QI")])
16009
16010 (define_expand "cmpstrnsi"
16011 [(set (match_operand:SI 0 "register_operand" "")
16012 (compare:SI (match_operand:BLK 1 "general_operand" "")
16013 (match_operand:BLK 2 "general_operand" "")))
16014 (use (match_operand 3 "general_operand" ""))
16015 (use (match_operand 4 "immediate_operand" ""))]
16016 ""
16017 {
16018 rtx addr1, addr2, out, outlow, count, countreg, align;
16019
16020 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16021 FAIL;
16022
16023 /* Can't use this if the user has appropriated ecx, esi or edi. */
16024 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16025 FAIL;
16026
16027 out = operands[0];
16028 if (!REG_P (out))
16029 out = gen_reg_rtx (SImode);
16030
16031 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16032 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16033 if (addr1 != XEXP (operands[1], 0))
16034 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16035 if (addr2 != XEXP (operands[2], 0))
16036 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16037
16038 count = operands[3];
16039 countreg = ix86_zero_extend_to_Pmode (count);
16040
16041 /* %%% Iff we are testing strict equality, we can use known alignment
16042 to good advantage. This may be possible with combine, particularly
16043 once cc0 is dead. */
16044 align = operands[4];
16045
16046 if (CONST_INT_P (count))
16047 {
16048 if (INTVAL (count) == 0)
16049 {
16050 emit_move_insn (operands[0], const0_rtx);
16051 DONE;
16052 }
16053 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16054 operands[1], operands[2]));
16055 }
16056 else
16057 {
16058 rtx (*gen_cmp) (rtx, rtx);
16059
16060 gen_cmp = (TARGET_64BIT
16061 ? gen_cmpdi_1 : gen_cmpsi_1);
16062
16063 emit_insn (gen_cmp (countreg, countreg));
16064 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16065 operands[1], operands[2]));
16066 }
16067
16068 outlow = gen_lowpart (QImode, out);
16069 emit_insn (gen_cmpintqi (outlow));
16070 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16071
16072 if (operands[0] != out)
16073 emit_move_insn (operands[0], out);
16074
16075 DONE;
16076 })
16077
16078 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16079
16080 (define_expand "cmpintqi"
16081 [(set (match_dup 1)
16082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16083 (set (match_dup 2)
16084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16085 (parallel [(set (match_operand:QI 0 "register_operand" "")
16086 (minus:QI (match_dup 1)
16087 (match_dup 2)))
16088 (clobber (reg:CC FLAGS_REG))])]
16089 ""
16090 {
16091 operands[1] = gen_reg_rtx (QImode);
16092 operands[2] = gen_reg_rtx (QImode);
16093 })
16094
16095 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16096 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16097
16098 (define_expand "cmpstrnqi_nz_1"
16099 [(parallel [(set (reg:CC FLAGS_REG)
16100 (compare:CC (match_operand 4 "memory_operand" "")
16101 (match_operand 5 "memory_operand" "")))
16102 (use (match_operand 2 "register_operand" ""))
16103 (use (match_operand:SI 3 "immediate_operand" ""))
16104 (clobber (match_operand 0 "register_operand" ""))
16105 (clobber (match_operand 1 "register_operand" ""))
16106 (clobber (match_dup 2))])]
16107 ""
16108 "ix86_current_function_needs_cld = 1;")
16109
16110 (define_insn "*cmpstrnqi_nz_1"
16111 [(set (reg:CC FLAGS_REG)
16112 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16113 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16114 (use (match_operand:P 6 "register_operand" "2"))
16115 (use (match_operand:SI 3 "immediate_operand" "i"))
16116 (clobber (match_operand:P 0 "register_operand" "=S"))
16117 (clobber (match_operand:P 1 "register_operand" "=D"))
16118 (clobber (match_operand:P 2 "register_operand" "=c"))]
16119 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16120 "repz{%;} cmpsb"
16121 [(set_attr "type" "str")
16122 (set_attr "mode" "QI")
16123 (set (attr "prefix_rex")
16124 (if_then_else
16125 (match_test "<P:MODE>mode == DImode")
16126 (const_string "0")
16127 (const_string "*")))
16128 (set_attr "prefix_rep" "1")])
16129
16130 ;; The same, but the count is not known to not be zero.
16131
16132 (define_expand "cmpstrnqi_1"
16133 [(parallel [(set (reg:CC FLAGS_REG)
16134 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16135 (const_int 0))
16136 (compare:CC (match_operand 4 "memory_operand" "")
16137 (match_operand 5 "memory_operand" ""))
16138 (const_int 0)))
16139 (use (match_operand:SI 3 "immediate_operand" ""))
16140 (use (reg:CC FLAGS_REG))
16141 (clobber (match_operand 0 "register_operand" ""))
16142 (clobber (match_operand 1 "register_operand" ""))
16143 (clobber (match_dup 2))])]
16144 ""
16145 "ix86_current_function_needs_cld = 1;")
16146
16147 (define_insn "*cmpstrnqi_1"
16148 [(set (reg:CC FLAGS_REG)
16149 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16150 (const_int 0))
16151 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16152 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16153 (const_int 0)))
16154 (use (match_operand:SI 3 "immediate_operand" "i"))
16155 (use (reg:CC FLAGS_REG))
16156 (clobber (match_operand:P 0 "register_operand" "=S"))
16157 (clobber (match_operand:P 1 "register_operand" "=D"))
16158 (clobber (match_operand:P 2 "register_operand" "=c"))]
16159 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16160 "repz{%;} cmpsb"
16161 [(set_attr "type" "str")
16162 (set_attr "mode" "QI")
16163 (set (attr "prefix_rex")
16164 (if_then_else
16165 (match_test "<P:MODE>mode == DImode")
16166 (const_string "0")
16167 (const_string "*")))
16168 (set_attr "prefix_rep" "1")])
16169
16170 (define_expand "strlen<mode>"
16171 [(set (match_operand:P 0 "register_operand" "")
16172 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16173 (match_operand:QI 2 "immediate_operand" "")
16174 (match_operand 3 "immediate_operand" "")]
16175 UNSPEC_SCAS))]
16176 ""
16177 {
16178 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16179 DONE;
16180 else
16181 FAIL;
16182 })
16183
16184 (define_expand "strlenqi_1"
16185 [(parallel [(set (match_operand 0 "register_operand" "")
16186 (match_operand 2 "" ""))
16187 (clobber (match_operand 1 "register_operand" ""))
16188 (clobber (reg:CC FLAGS_REG))])]
16189 ""
16190 "ix86_current_function_needs_cld = 1;")
16191
16192 (define_insn "*strlenqi_1"
16193 [(set (match_operand:P 0 "register_operand" "=&c")
16194 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16195 (match_operand:QI 2 "register_operand" "a")
16196 (match_operand:P 3 "immediate_operand" "i")
16197 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16198 (clobber (match_operand:P 1 "register_operand" "=D"))
16199 (clobber (reg:CC FLAGS_REG))]
16200 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16201 "repnz{%;} scasb"
16202 [(set_attr "type" "str")
16203 (set_attr "mode" "QI")
16204 (set (attr "prefix_rex")
16205 (if_then_else
16206 (match_test "<P:MODE>mode == DImode")
16207 (const_string "0")
16208 (const_string "*")))
16209 (set_attr "prefix_rep" "1")])
16210
16211 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16212 ;; handled in combine, but it is not currently up to the task.
16213 ;; When used for their truth value, the cmpstrn* expanders generate
16214 ;; code like this:
16215 ;;
16216 ;; repz cmpsb
16217 ;; seta %al
16218 ;; setb %dl
16219 ;; cmpb %al, %dl
16220 ;; jcc label
16221 ;;
16222 ;; The intermediate three instructions are unnecessary.
16223
16224 ;; This one handles cmpstrn*_nz_1...
16225 (define_peephole2
16226 [(parallel[
16227 (set (reg:CC FLAGS_REG)
16228 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16229 (mem:BLK (match_operand 5 "register_operand" ""))))
16230 (use (match_operand 6 "register_operand" ""))
16231 (use (match_operand:SI 3 "immediate_operand" ""))
16232 (clobber (match_operand 0 "register_operand" ""))
16233 (clobber (match_operand 1 "register_operand" ""))
16234 (clobber (match_operand 2 "register_operand" ""))])
16235 (set (match_operand:QI 7 "register_operand" "")
16236 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16237 (set (match_operand:QI 8 "register_operand" "")
16238 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16239 (set (reg FLAGS_REG)
16240 (compare (match_dup 7) (match_dup 8)))
16241 ]
16242 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16243 [(parallel[
16244 (set (reg:CC FLAGS_REG)
16245 (compare:CC (mem:BLK (match_dup 4))
16246 (mem:BLK (match_dup 5))))
16247 (use (match_dup 6))
16248 (use (match_dup 3))
16249 (clobber (match_dup 0))
16250 (clobber (match_dup 1))
16251 (clobber (match_dup 2))])])
16252
16253 ;; ...and this one handles cmpstrn*_1.
16254 (define_peephole2
16255 [(parallel[
16256 (set (reg:CC FLAGS_REG)
16257 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16258 (const_int 0))
16259 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16260 (mem:BLK (match_operand 5 "register_operand" "")))
16261 (const_int 0)))
16262 (use (match_operand:SI 3 "immediate_operand" ""))
16263 (use (reg:CC FLAGS_REG))
16264 (clobber (match_operand 0 "register_operand" ""))
16265 (clobber (match_operand 1 "register_operand" ""))
16266 (clobber (match_operand 2 "register_operand" ""))])
16267 (set (match_operand:QI 7 "register_operand" "")
16268 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16269 (set (match_operand:QI 8 "register_operand" "")
16270 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16271 (set (reg FLAGS_REG)
16272 (compare (match_dup 7) (match_dup 8)))
16273 ]
16274 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16275 [(parallel[
16276 (set (reg:CC FLAGS_REG)
16277 (if_then_else:CC (ne (match_dup 6)
16278 (const_int 0))
16279 (compare:CC (mem:BLK (match_dup 4))
16280 (mem:BLK (match_dup 5)))
16281 (const_int 0)))
16282 (use (match_dup 3))
16283 (use (reg:CC FLAGS_REG))
16284 (clobber (match_dup 0))
16285 (clobber (match_dup 1))
16286 (clobber (match_dup 2))])])
16287 \f
16288 ;; Conditional move instructions.
16289
16290 (define_expand "mov<mode>cc"
16291 [(set (match_operand:SWIM 0 "register_operand" "")
16292 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16293 (match_operand:SWIM 2 "<general_operand>" "")
16294 (match_operand:SWIM 3 "<general_operand>" "")))]
16295 ""
16296 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16297
16298 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16299 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16300 ;; So just document what we're doing explicitly.
16301
16302 (define_expand "x86_mov<mode>cc_0_m1"
16303 [(parallel
16304 [(set (match_operand:SWI48 0 "register_operand" "")
16305 (if_then_else:SWI48
16306 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16307 [(match_operand 1 "flags_reg_operand" "")
16308 (const_int 0)])
16309 (const_int -1)
16310 (const_int 0)))
16311 (clobber (reg:CC FLAGS_REG))])])
16312
16313 (define_insn "*x86_mov<mode>cc_0_m1"
16314 [(set (match_operand:SWI48 0 "register_operand" "=r")
16315 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16316 [(reg FLAGS_REG) (const_int 0)])
16317 (const_int -1)
16318 (const_int 0)))
16319 (clobber (reg:CC FLAGS_REG))]
16320 ""
16321 "sbb{<imodesuffix>}\t%0, %0"
16322 ; Since we don't have the proper number of operands for an alu insn,
16323 ; fill in all the blanks.
16324 [(set_attr "type" "alu")
16325 (set_attr "use_carry" "1")
16326 (set_attr "pent_pair" "pu")
16327 (set_attr "memory" "none")
16328 (set_attr "imm_disp" "false")
16329 (set_attr "mode" "<MODE>")
16330 (set_attr "length_immediate" "0")])
16331
16332 (define_insn "*x86_mov<mode>cc_0_m1_se"
16333 [(set (match_operand:SWI48 0 "register_operand" "=r")
16334 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16335 [(reg FLAGS_REG) (const_int 0)])
16336 (const_int 1)
16337 (const_int 0)))
16338 (clobber (reg:CC FLAGS_REG))]
16339 ""
16340 "sbb{<imodesuffix>}\t%0, %0"
16341 [(set_attr "type" "alu")
16342 (set_attr "use_carry" "1")
16343 (set_attr "pent_pair" "pu")
16344 (set_attr "memory" "none")
16345 (set_attr "imm_disp" "false")
16346 (set_attr "mode" "<MODE>")
16347 (set_attr "length_immediate" "0")])
16348
16349 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16350 [(set (match_operand:SWI48 0 "register_operand" "=r")
16351 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16352 [(reg FLAGS_REG) (const_int 0)])))]
16353 ""
16354 "sbb{<imodesuffix>}\t%0, %0"
16355 [(set_attr "type" "alu")
16356 (set_attr "use_carry" "1")
16357 (set_attr "pent_pair" "pu")
16358 (set_attr "memory" "none")
16359 (set_attr "imm_disp" "false")
16360 (set_attr "mode" "<MODE>")
16361 (set_attr "length_immediate" "0")])
16362
16363 (define_insn "*mov<mode>cc_noc"
16364 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16365 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16366 [(reg FLAGS_REG) (const_int 0)])
16367 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16368 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16369 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16370 "@
16371 cmov%O2%C1\t{%2, %0|%0, %2}
16372 cmov%O2%c1\t{%3, %0|%0, %3}"
16373 [(set_attr "type" "icmov")
16374 (set_attr "mode" "<MODE>")])
16375
16376 (define_insn_and_split "*movqicc_noc"
16377 [(set (match_operand:QI 0 "register_operand" "=r,r")
16378 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16379 [(match_operand 4 "flags_reg_operand" "")
16380 (const_int 0)])
16381 (match_operand:QI 2 "register_operand" "r,0")
16382 (match_operand:QI 3 "register_operand" "0,r")))]
16383 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16384 "#"
16385 "&& reload_completed"
16386 [(set (match_dup 0)
16387 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16388 (match_dup 2)
16389 (match_dup 3)))]
16390 "operands[0] = gen_lowpart (SImode, operands[0]);
16391 operands[2] = gen_lowpart (SImode, operands[2]);
16392 operands[3] = gen_lowpart (SImode, operands[3]);"
16393 [(set_attr "type" "icmov")
16394 (set_attr "mode" "SI")])
16395
16396 (define_expand "mov<mode>cc"
16397 [(set (match_operand:X87MODEF 0 "register_operand" "")
16398 (if_then_else:X87MODEF
16399 (match_operand 1 "ix86_fp_comparison_operator" "")
16400 (match_operand:X87MODEF 2 "register_operand" "")
16401 (match_operand:X87MODEF 3 "register_operand" "")))]
16402 "(TARGET_80387 && TARGET_CMOVE)
16403 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16404 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16405
16406 (define_insn "*movxfcc_1"
16407 [(set (match_operand:XF 0 "register_operand" "=f,f")
16408 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16409 [(reg FLAGS_REG) (const_int 0)])
16410 (match_operand:XF 2 "register_operand" "f,0")
16411 (match_operand:XF 3 "register_operand" "0,f")))]
16412 "TARGET_80387 && TARGET_CMOVE"
16413 "@
16414 fcmov%F1\t{%2, %0|%0, %2}
16415 fcmov%f1\t{%3, %0|%0, %3}"
16416 [(set_attr "type" "fcmov")
16417 (set_attr "mode" "XF")])
16418
16419 (define_insn "*movdfcc_1_rex64"
16420 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16421 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16422 [(reg FLAGS_REG) (const_int 0)])
16423 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16424 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16425 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16426 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16427 "@
16428 fcmov%F1\t{%2, %0|%0, %2}
16429 fcmov%f1\t{%3, %0|%0, %3}
16430 cmov%O2%C1\t{%2, %0|%0, %2}
16431 cmov%O2%c1\t{%3, %0|%0, %3}"
16432 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16433 (set_attr "mode" "DF,DF,DI,DI")])
16434
16435 (define_insn "*movdfcc_1"
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 #
16447 #"
16448 [(set_attr "type" "fcmov,fcmov,multi,multi")
16449 (set_attr "mode" "DF,DF,DI,DI")])
16450
16451 (define_split
16452 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16453 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16454 [(match_operand 4 "flags_reg_operand" "")
16455 (const_int 0)])
16456 (match_operand:DF 2 "nonimmediate_operand" "")
16457 (match_operand:DF 3 "nonimmediate_operand" "")))]
16458 "!TARGET_64BIT && reload_completed"
16459 [(set (match_dup 2)
16460 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16461 (match_dup 5)
16462 (match_dup 6)))
16463 (set (match_dup 3)
16464 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16465 (match_dup 7)
16466 (match_dup 8)))]
16467 {
16468 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16469 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16470 })
16471
16472 (define_insn "*movsfcc_1_387"
16473 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16474 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16475 [(reg FLAGS_REG) (const_int 0)])
16476 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16477 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16478 "TARGET_80387 && TARGET_CMOVE
16479 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16480 "@
16481 fcmov%F1\t{%2, %0|%0, %2}
16482 fcmov%f1\t{%3, %0|%0, %3}
16483 cmov%O2%C1\t{%2, %0|%0, %2}
16484 cmov%O2%c1\t{%3, %0|%0, %3}"
16485 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16486 (set_attr "mode" "SF,SF,SI,SI")])
16487
16488 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16489 ;; the scalar versions to have only XMM registers as operands.
16490
16491 ;; XOP conditional move
16492 (define_insn "*xop_pcmov_<mode>"
16493 [(set (match_operand:MODEF 0 "register_operand" "=x")
16494 (if_then_else:MODEF
16495 (match_operand:MODEF 1 "register_operand" "x")
16496 (match_operand:MODEF 2 "register_operand" "x")
16497 (match_operand:MODEF 3 "register_operand" "x")))]
16498 "TARGET_XOP"
16499 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16500 [(set_attr "type" "sse4arg")])
16501
16502 ;; These versions of the min/max patterns are intentionally ignorant of
16503 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16504 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16505 ;; are undefined in this condition, we're certain this is correct.
16506
16507 (define_insn "<code><mode>3"
16508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16509 (smaxmin:MODEF
16510 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16512 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16513 "@
16514 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16515 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16516 [(set_attr "isa" "noavx,avx")
16517 (set_attr "prefix" "orig,vex")
16518 (set_attr "type" "sseadd")
16519 (set_attr "mode" "<MODE>")])
16520
16521 ;; These versions of the min/max patterns implement exactly the operations
16522 ;; min = (op1 < op2 ? op1 : op2)
16523 ;; max = (!(op1 < op2) ? op1 : op2)
16524 ;; Their operands are not commutative, and thus they may be used in the
16525 ;; presence of -0.0 and NaN.
16526
16527 (define_insn "*ieee_smin<mode>3"
16528 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16529 (unspec:MODEF
16530 [(match_operand:MODEF 1 "register_operand" "0,x")
16531 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16532 UNSPEC_IEEE_MIN))]
16533 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16534 "@
16535 min<ssemodesuffix>\t{%2, %0|%0, %2}
16536 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16537 [(set_attr "isa" "noavx,avx")
16538 (set_attr "prefix" "orig,vex")
16539 (set_attr "type" "sseadd")
16540 (set_attr "mode" "<MODE>")])
16541
16542 (define_insn "*ieee_smax<mode>3"
16543 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16544 (unspec:MODEF
16545 [(match_operand:MODEF 1 "register_operand" "0,x")
16546 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16547 UNSPEC_IEEE_MAX))]
16548 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16549 "@
16550 max<ssemodesuffix>\t{%2, %0|%0, %2}
16551 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16552 [(set_attr "isa" "noavx,avx")
16553 (set_attr "prefix" "orig,vex")
16554 (set_attr "type" "sseadd")
16555 (set_attr "mode" "<MODE>")])
16556
16557 ;; Make two stack loads independent:
16558 ;; fld aa fld aa
16559 ;; fld %st(0) -> fld bb
16560 ;; fmul bb fmul %st(1), %st
16561 ;;
16562 ;; Actually we only match the last two instructions for simplicity.
16563 (define_peephole2
16564 [(set (match_operand 0 "fp_register_operand" "")
16565 (match_operand 1 "fp_register_operand" ""))
16566 (set (match_dup 0)
16567 (match_operator 2 "binary_fp_operator"
16568 [(match_dup 0)
16569 (match_operand 3 "memory_operand" "")]))]
16570 "REGNO (operands[0]) != REGNO (operands[1])"
16571 [(set (match_dup 0) (match_dup 3))
16572 (set (match_dup 0) (match_dup 4))]
16573
16574 ;; The % modifier is not operational anymore in peephole2's, so we have to
16575 ;; swap the operands manually in the case of addition and multiplication.
16576 {
16577 rtx op0, op1;
16578
16579 if (COMMUTATIVE_ARITH_P (operands[2]))
16580 op0 = operands[0], op1 = operands[1];
16581 else
16582 op0 = operands[1], op1 = operands[0];
16583
16584 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16585 GET_MODE (operands[2]),
16586 op0, op1);
16587 })
16588
16589 ;; Conditional addition patterns
16590 (define_expand "add<mode>cc"
16591 [(match_operand:SWI 0 "register_operand" "")
16592 (match_operand 1 "ordered_comparison_operator" "")
16593 (match_operand:SWI 2 "register_operand" "")
16594 (match_operand:SWI 3 "const_int_operand" "")]
16595 ""
16596 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16597 \f
16598 ;; Misc patterns (?)
16599
16600 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16601 ;; Otherwise there will be nothing to keep
16602 ;;
16603 ;; [(set (reg ebp) (reg esp))]
16604 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16605 ;; (clobber (eflags)]
16606 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16607 ;;
16608 ;; in proper program order.
16609
16610 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16611 [(set (match_operand:P 0 "register_operand" "=r,r")
16612 (plus:P (match_operand:P 1 "register_operand" "0,r")
16613 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16614 (clobber (reg:CC FLAGS_REG))
16615 (clobber (mem:BLK (scratch)))]
16616 ""
16617 {
16618 switch (get_attr_type (insn))
16619 {
16620 case TYPE_IMOV:
16621 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16622
16623 case TYPE_ALU:
16624 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16625 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16626 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16627
16628 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16629
16630 default:
16631 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16632 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16633 }
16634 }
16635 [(set (attr "type")
16636 (cond [(and (eq_attr "alternative" "0")
16637 (not (match_test "TARGET_OPT_AGU")))
16638 (const_string "alu")
16639 (match_operand:<MODE> 2 "const0_operand" "")
16640 (const_string "imov")
16641 ]
16642 (const_string "lea")))
16643 (set (attr "length_immediate")
16644 (cond [(eq_attr "type" "imov")
16645 (const_string "0")
16646 (and (eq_attr "type" "alu")
16647 (match_operand 2 "const128_operand" ""))
16648 (const_string "1")
16649 ]
16650 (const_string "*")))
16651 (set_attr "mode" "<MODE>")])
16652
16653 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16654 [(set (match_operand:P 0 "register_operand" "=r")
16655 (minus:P (match_operand:P 1 "register_operand" "0")
16656 (match_operand:P 2 "register_operand" "r")))
16657 (clobber (reg:CC FLAGS_REG))
16658 (clobber (mem:BLK (scratch)))]
16659 ""
16660 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16661 [(set_attr "type" "alu")
16662 (set_attr "mode" "<MODE>")])
16663
16664 (define_insn "allocate_stack_worker_probe_<mode>"
16665 [(set (match_operand:P 0 "register_operand" "=a")
16666 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16667 UNSPECV_STACK_PROBE))
16668 (clobber (reg:CC FLAGS_REG))]
16669 "ix86_target_stack_probe ()"
16670 "call\t___chkstk_ms"
16671 [(set_attr "type" "multi")
16672 (set_attr "length" "5")])
16673
16674 (define_expand "allocate_stack"
16675 [(match_operand 0 "register_operand" "")
16676 (match_operand 1 "general_operand" "")]
16677 "ix86_target_stack_probe ()"
16678 {
16679 rtx x;
16680
16681 #ifndef CHECK_STACK_LIMIT
16682 #define CHECK_STACK_LIMIT 0
16683 #endif
16684
16685 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16686 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16687 {
16688 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16689 stack_pointer_rtx, 0, OPTAB_DIRECT);
16690 if (x != stack_pointer_rtx)
16691 emit_move_insn (stack_pointer_rtx, x);
16692 }
16693 else
16694 {
16695 x = copy_to_mode_reg (Pmode, operands[1]);
16696 if (TARGET_64BIT)
16697 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16698 else
16699 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16700 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16701 stack_pointer_rtx, 0, OPTAB_DIRECT);
16702 if (x != stack_pointer_rtx)
16703 emit_move_insn (stack_pointer_rtx, x);
16704 }
16705
16706 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16707 DONE;
16708 })
16709
16710 ;; Use IOR for stack probes, this is shorter.
16711 (define_expand "probe_stack"
16712 [(match_operand 0 "memory_operand" "")]
16713 ""
16714 {
16715 rtx (*gen_ior3) (rtx, rtx, rtx);
16716
16717 gen_ior3 = (GET_MODE (operands[0]) == DImode
16718 ? gen_iordi3 : gen_iorsi3);
16719
16720 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16721 DONE;
16722 })
16723
16724 (define_insn "adjust_stack_and_probe<mode>"
16725 [(set (match_operand:P 0 "register_operand" "=r")
16726 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16727 UNSPECV_PROBE_STACK_RANGE))
16728 (set (reg:P SP_REG)
16729 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16730 (clobber (reg:CC FLAGS_REG))
16731 (clobber (mem:BLK (scratch)))]
16732 ""
16733 "* return output_adjust_stack_and_probe (operands[0]);"
16734 [(set_attr "type" "multi")])
16735
16736 (define_insn "probe_stack_range<mode>"
16737 [(set (match_operand:P 0 "register_operand" "=r")
16738 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16739 (match_operand:P 2 "const_int_operand" "n")]
16740 UNSPECV_PROBE_STACK_RANGE))
16741 (clobber (reg:CC FLAGS_REG))]
16742 ""
16743 "* return output_probe_stack_range (operands[0], operands[2]);"
16744 [(set_attr "type" "multi")])
16745
16746 (define_expand "builtin_setjmp_receiver"
16747 [(label_ref (match_operand 0 "" ""))]
16748 "!TARGET_64BIT && flag_pic"
16749 {
16750 #if TARGET_MACHO
16751 if (TARGET_MACHO)
16752 {
16753 rtx xops[3];
16754 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16755 rtx label_rtx = gen_label_rtx ();
16756 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16757 xops[0] = xops[1] = picreg;
16758 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16759 ix86_expand_binary_operator (MINUS, SImode, xops);
16760 }
16761 else
16762 #endif
16763 emit_insn (gen_set_got (pic_offset_table_rtx));
16764 DONE;
16765 })
16766 \f
16767 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16768
16769 (define_split
16770 [(set (match_operand 0 "register_operand" "")
16771 (match_operator 3 "promotable_binary_operator"
16772 [(match_operand 1 "register_operand" "")
16773 (match_operand 2 "aligned_operand" "")]))
16774 (clobber (reg:CC FLAGS_REG))]
16775 "! TARGET_PARTIAL_REG_STALL && reload_completed
16776 && ((GET_MODE (operands[0]) == HImode
16777 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16778 /* ??? next two lines just !satisfies_constraint_K (...) */
16779 || !CONST_INT_P (operands[2])
16780 || satisfies_constraint_K (operands[2])))
16781 || (GET_MODE (operands[0]) == QImode
16782 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16783 [(parallel [(set (match_dup 0)
16784 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16785 (clobber (reg:CC FLAGS_REG))])]
16786 {
16787 operands[0] = gen_lowpart (SImode, operands[0]);
16788 operands[1] = gen_lowpart (SImode, operands[1]);
16789 if (GET_CODE (operands[3]) != ASHIFT)
16790 operands[2] = gen_lowpart (SImode, operands[2]);
16791 PUT_MODE (operands[3], SImode);
16792 })
16793
16794 ; Promote the QImode tests, as i386 has encoding of the AND
16795 ; instruction with 32-bit sign-extended immediate and thus the
16796 ; instruction size is unchanged, except in the %eax case for
16797 ; which it is increased by one byte, hence the ! optimize_size.
16798 (define_split
16799 [(set (match_operand 0 "flags_reg_operand" "")
16800 (match_operator 2 "compare_operator"
16801 [(and (match_operand 3 "aligned_operand" "")
16802 (match_operand 4 "const_int_operand" ""))
16803 (const_int 0)]))
16804 (set (match_operand 1 "register_operand" "")
16805 (and (match_dup 3) (match_dup 4)))]
16806 "! TARGET_PARTIAL_REG_STALL && reload_completed
16807 && optimize_insn_for_speed_p ()
16808 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16809 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16810 /* Ensure that the operand will remain sign-extended immediate. */
16811 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16812 [(parallel [(set (match_dup 0)
16813 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16814 (const_int 0)]))
16815 (set (match_dup 1)
16816 (and:SI (match_dup 3) (match_dup 4)))])]
16817 {
16818 operands[4]
16819 = gen_int_mode (INTVAL (operands[4])
16820 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16821 operands[1] = gen_lowpart (SImode, operands[1]);
16822 operands[3] = gen_lowpart (SImode, operands[3]);
16823 })
16824
16825 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16826 ; the TEST instruction with 32-bit sign-extended immediate and thus
16827 ; the instruction size would at least double, which is not what we
16828 ; want even with ! optimize_size.
16829 (define_split
16830 [(set (match_operand 0 "flags_reg_operand" "")
16831 (match_operator 1 "compare_operator"
16832 [(and (match_operand:HI 2 "aligned_operand" "")
16833 (match_operand:HI 3 "const_int_operand" ""))
16834 (const_int 0)]))]
16835 "! TARGET_PARTIAL_REG_STALL && reload_completed
16836 && ! TARGET_FAST_PREFIX
16837 && optimize_insn_for_speed_p ()
16838 /* Ensure that the operand will remain sign-extended immediate. */
16839 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16840 [(set (match_dup 0)
16841 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16842 (const_int 0)]))]
16843 {
16844 operands[3]
16845 = gen_int_mode (INTVAL (operands[3])
16846 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16847 operands[2] = gen_lowpart (SImode, operands[2]);
16848 })
16849
16850 (define_split
16851 [(set (match_operand 0 "register_operand" "")
16852 (neg (match_operand 1 "register_operand" "")))
16853 (clobber (reg:CC FLAGS_REG))]
16854 "! TARGET_PARTIAL_REG_STALL && reload_completed
16855 && (GET_MODE (operands[0]) == HImode
16856 || (GET_MODE (operands[0]) == QImode
16857 && (TARGET_PROMOTE_QImode
16858 || optimize_insn_for_size_p ())))"
16859 [(parallel [(set (match_dup 0)
16860 (neg:SI (match_dup 1)))
16861 (clobber (reg:CC FLAGS_REG))])]
16862 {
16863 operands[0] = gen_lowpart (SImode, operands[0]);
16864 operands[1] = gen_lowpart (SImode, operands[1]);
16865 })
16866
16867 (define_split
16868 [(set (match_operand 0 "register_operand" "")
16869 (not (match_operand 1 "register_operand" "")))]
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 [(set (match_dup 0)
16876 (not:SI (match_dup 1)))]
16877 {
16878 operands[0] = gen_lowpart (SImode, operands[0]);
16879 operands[1] = gen_lowpart (SImode, operands[1]);
16880 })
16881
16882 (define_split
16883 [(set (match_operand 0 "register_operand" "")
16884 (if_then_else (match_operator 1 "ordered_comparison_operator"
16885 [(reg FLAGS_REG) (const_int 0)])
16886 (match_operand 2 "register_operand" "")
16887 (match_operand 3 "register_operand" "")))]
16888 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16889 && (GET_MODE (operands[0]) == HImode
16890 || (GET_MODE (operands[0]) == QImode
16891 && (TARGET_PROMOTE_QImode
16892 || optimize_insn_for_size_p ())))"
16893 [(set (match_dup 0)
16894 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16895 {
16896 operands[0] = gen_lowpart (SImode, operands[0]);
16897 operands[2] = gen_lowpart (SImode, operands[2]);
16898 operands[3] = gen_lowpart (SImode, operands[3]);
16899 })
16900 \f
16901 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16902 ;; transform a complex memory operation into two memory to register operations.
16903
16904 ;; Don't push memory operands
16905 (define_peephole2
16906 [(set (match_operand:SWI 0 "push_operand" "")
16907 (match_operand:SWI 1 "memory_operand" ""))
16908 (match_scratch:SWI 2 "<r>")]
16909 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16910 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16911 [(set (match_dup 2) (match_dup 1))
16912 (set (match_dup 0) (match_dup 2))])
16913
16914 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16915 ;; SImode pushes.
16916 (define_peephole2
16917 [(set (match_operand:SF 0 "push_operand" "")
16918 (match_operand:SF 1 "memory_operand" ""))
16919 (match_scratch:SF 2 "r")]
16920 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16921 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16922 [(set (match_dup 2) (match_dup 1))
16923 (set (match_dup 0) (match_dup 2))])
16924
16925 ;; Don't move an immediate directly to memory when the instruction
16926 ;; gets too big.
16927 (define_peephole2
16928 [(match_scratch:SWI124 1 "<r>")
16929 (set (match_operand:SWI124 0 "memory_operand" "")
16930 (const_int 0))]
16931 "optimize_insn_for_speed_p ()
16932 && !TARGET_USE_MOV0
16933 && TARGET_SPLIT_LONG_MOVES
16934 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16935 && peep2_regno_dead_p (0, FLAGS_REG)"
16936 [(parallel [(set (match_dup 2) (const_int 0))
16937 (clobber (reg:CC FLAGS_REG))])
16938 (set (match_dup 0) (match_dup 1))]
16939 "operands[2] = gen_lowpart (SImode, operands[1]);")
16940
16941 (define_peephole2
16942 [(match_scratch:SWI124 2 "<r>")
16943 (set (match_operand:SWI124 0 "memory_operand" "")
16944 (match_operand:SWI124 1 "immediate_operand" ""))]
16945 "optimize_insn_for_speed_p ()
16946 && TARGET_SPLIT_LONG_MOVES
16947 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16948 [(set (match_dup 2) (match_dup 1))
16949 (set (match_dup 0) (match_dup 2))])
16950
16951 ;; Don't compare memory with zero, load and use a test instead.
16952 (define_peephole2
16953 [(set (match_operand 0 "flags_reg_operand" "")
16954 (match_operator 1 "compare_operator"
16955 [(match_operand:SI 2 "memory_operand" "")
16956 (const_int 0)]))
16957 (match_scratch:SI 3 "r")]
16958 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16959 [(set (match_dup 3) (match_dup 2))
16960 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16961
16962 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16963 ;; Don't split NOTs with a displacement operand, because resulting XOR
16964 ;; will not be pairable anyway.
16965 ;;
16966 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16967 ;; represented using a modRM byte. The XOR replacement is long decoded,
16968 ;; so this split helps here as well.
16969 ;;
16970 ;; Note: Can't do this as a regular split because we can't get proper
16971 ;; lifetime information then.
16972
16973 (define_peephole2
16974 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16975 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16976 "optimize_insn_for_speed_p ()
16977 && ((TARGET_NOT_UNPAIRABLE
16978 && (!MEM_P (operands[0])
16979 || !memory_displacement_operand (operands[0], <MODE>mode)))
16980 || (TARGET_NOT_VECTORMODE
16981 && long_memory_operand (operands[0], <MODE>mode)))
16982 && peep2_regno_dead_p (0, FLAGS_REG)"
16983 [(parallel [(set (match_dup 0)
16984 (xor:SWI124 (match_dup 1) (const_int -1)))
16985 (clobber (reg:CC FLAGS_REG))])])
16986
16987 ;; Non pairable "test imm, reg" instructions can be translated to
16988 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16989 ;; byte opcode instead of two, have a short form for byte operands),
16990 ;; so do it for other CPUs as well. Given that the value was dead,
16991 ;; this should not create any new dependencies. Pass on the sub-word
16992 ;; versions if we're concerned about partial register stalls.
16993
16994 (define_peephole2
16995 [(set (match_operand 0 "flags_reg_operand" "")
16996 (match_operator 1 "compare_operator"
16997 [(and:SI (match_operand:SI 2 "register_operand" "")
16998 (match_operand:SI 3 "immediate_operand" ""))
16999 (const_int 0)]))]
17000 "ix86_match_ccmode (insn, CCNOmode)
17001 && (true_regnum (operands[2]) != AX_REG
17002 || satisfies_constraint_K (operands[3]))
17003 && peep2_reg_dead_p (1, operands[2])"
17004 [(parallel
17005 [(set (match_dup 0)
17006 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17007 (const_int 0)]))
17008 (set (match_dup 2)
17009 (and:SI (match_dup 2) (match_dup 3)))])])
17010
17011 ;; We don't need to handle HImode case, because it will be promoted to SImode
17012 ;; on ! TARGET_PARTIAL_REG_STALL
17013
17014 (define_peephole2
17015 [(set (match_operand 0 "flags_reg_operand" "")
17016 (match_operator 1 "compare_operator"
17017 [(and:QI (match_operand:QI 2 "register_operand" "")
17018 (match_operand:QI 3 "immediate_operand" ""))
17019 (const_int 0)]))]
17020 "! TARGET_PARTIAL_REG_STALL
17021 && ix86_match_ccmode (insn, CCNOmode)
17022 && true_regnum (operands[2]) != AX_REG
17023 && peep2_reg_dead_p (1, operands[2])"
17024 [(parallel
17025 [(set (match_dup 0)
17026 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17027 (const_int 0)]))
17028 (set (match_dup 2)
17029 (and:QI (match_dup 2) (match_dup 3)))])])
17030
17031 (define_peephole2
17032 [(set (match_operand 0 "flags_reg_operand" "")
17033 (match_operator 1 "compare_operator"
17034 [(and:SI
17035 (zero_extract:SI
17036 (match_operand 2 "ext_register_operand" "")
17037 (const_int 8)
17038 (const_int 8))
17039 (match_operand 3 "const_int_operand" ""))
17040 (const_int 0)]))]
17041 "! TARGET_PARTIAL_REG_STALL
17042 && ix86_match_ccmode (insn, CCNOmode)
17043 && true_regnum (operands[2]) != AX_REG
17044 && peep2_reg_dead_p (1, operands[2])"
17045 [(parallel [(set (match_dup 0)
17046 (match_op_dup 1
17047 [(and:SI
17048 (zero_extract:SI
17049 (match_dup 2)
17050 (const_int 8)
17051 (const_int 8))
17052 (match_dup 3))
17053 (const_int 0)]))
17054 (set (zero_extract:SI (match_dup 2)
17055 (const_int 8)
17056 (const_int 8))
17057 (and:SI
17058 (zero_extract:SI
17059 (match_dup 2)
17060 (const_int 8)
17061 (const_int 8))
17062 (match_dup 3)))])])
17063
17064 ;; Don't do logical operations with memory inputs.
17065 (define_peephole2
17066 [(match_scratch:SI 2 "r")
17067 (parallel [(set (match_operand:SI 0 "register_operand" "")
17068 (match_operator:SI 3 "arith_or_logical_operator"
17069 [(match_dup 0)
17070 (match_operand:SI 1 "memory_operand" "")]))
17071 (clobber (reg:CC FLAGS_REG))])]
17072 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17073 [(set (match_dup 2) (match_dup 1))
17074 (parallel [(set (match_dup 0)
17075 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17076 (clobber (reg:CC FLAGS_REG))])])
17077
17078 (define_peephole2
17079 [(match_scratch:SI 2 "r")
17080 (parallel [(set (match_operand:SI 0 "register_operand" "")
17081 (match_operator:SI 3 "arith_or_logical_operator"
17082 [(match_operand:SI 1 "memory_operand" "")
17083 (match_dup 0)]))
17084 (clobber (reg:CC FLAGS_REG))])]
17085 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17086 [(set (match_dup 2) (match_dup 1))
17087 (parallel [(set (match_dup 0)
17088 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17089 (clobber (reg:CC FLAGS_REG))])])
17090
17091 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17092 ;; refers to the destination of the load!
17093
17094 (define_peephole2
17095 [(set (match_operand:SI 0 "register_operand" "")
17096 (match_operand:SI 1 "register_operand" ""))
17097 (parallel [(set (match_dup 0)
17098 (match_operator:SI 3 "commutative_operator"
17099 [(match_dup 0)
17100 (match_operand:SI 2 "memory_operand" "")]))
17101 (clobber (reg:CC FLAGS_REG))])]
17102 "REGNO (operands[0]) != REGNO (operands[1])
17103 && GENERAL_REGNO_P (REGNO (operands[0]))
17104 && GENERAL_REGNO_P (REGNO (operands[1]))"
17105 [(set (match_dup 0) (match_dup 4))
17106 (parallel [(set (match_dup 0)
17107 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17108 (clobber (reg:CC FLAGS_REG))])]
17109 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17110
17111 (define_peephole2
17112 [(set (match_operand 0 "register_operand" "")
17113 (match_operand 1 "register_operand" ""))
17114 (set (match_dup 0)
17115 (match_operator 3 "commutative_operator"
17116 [(match_dup 0)
17117 (match_operand 2 "memory_operand" "")]))]
17118 "REGNO (operands[0]) != REGNO (operands[1])
17119 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17120 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17121 [(set (match_dup 0) (match_dup 2))
17122 (set (match_dup 0)
17123 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17124
17125 ; Don't do logical operations with memory outputs
17126 ;
17127 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17128 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17129 ; the same decoder scheduling characteristics as the original.
17130
17131 (define_peephole2
17132 [(match_scratch:SI 2 "r")
17133 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17134 (match_operator:SI 3 "arith_or_logical_operator"
17135 [(match_dup 0)
17136 (match_operand:SI 1 "nonmemory_operand" "")]))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17139 /* Do not split stack checking probes. */
17140 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17141 [(set (match_dup 2) (match_dup 0))
17142 (parallel [(set (match_dup 2)
17143 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17144 (clobber (reg:CC FLAGS_REG))])
17145 (set (match_dup 0) (match_dup 2))])
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_operand:SI 1 "nonmemory_operand" "")
17152 (match_dup 0)]))
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 1) (match_dup 2)]))
17160 (clobber (reg:CC FLAGS_REG))])
17161 (set (match_dup 0) (match_dup 2))])
17162
17163 ;; Attempt to use arith or logical operations with memory outputs with
17164 ;; setting of flags.
17165 (define_peephole2
17166 [(set (match_operand:SWI 0 "register_operand" "")
17167 (match_operand:SWI 1 "memory_operand" ""))
17168 (parallel [(set (match_dup 0)
17169 (match_operator:SWI 3 "plusminuslogic_operator"
17170 [(match_dup 0)
17171 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17172 (clobber (reg:CC FLAGS_REG))])
17173 (set (match_dup 1) (match_dup 0))
17174 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17175 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17176 && peep2_reg_dead_p (4, operands[0])
17177 && !reg_overlap_mentioned_p (operands[0], operands[1])
17178 && ix86_match_ccmode (peep2_next_insn (3),
17179 (GET_CODE (operands[3]) == PLUS
17180 || GET_CODE (operands[3]) == MINUS)
17181 ? CCGOCmode : CCNOmode)"
17182 [(parallel [(set (match_dup 4) (match_dup 5))
17183 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17184 (match_dup 2)]))])]
17185 {
17186 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17187 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17188 copy_rtx (operands[1]),
17189 copy_rtx (operands[2]));
17190 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17191 operands[5], const0_rtx);
17192 })
17193
17194 (define_peephole2
17195 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17196 (match_operator:SWI 2 "plusminuslogic_operator"
17197 [(match_dup 0)
17198 (match_operand:SWI 1 "memory_operand" "")]))
17199 (clobber (reg:CC FLAGS_REG))])
17200 (set (match_dup 1) (match_dup 0))
17201 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17202 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17203 && GET_CODE (operands[2]) != MINUS
17204 && peep2_reg_dead_p (3, operands[0])
17205 && !reg_overlap_mentioned_p (operands[0], operands[1])
17206 && ix86_match_ccmode (peep2_next_insn (2),
17207 GET_CODE (operands[2]) == PLUS
17208 ? CCGOCmode : CCNOmode)"
17209 [(parallel [(set (match_dup 3) (match_dup 4))
17210 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17211 (match_dup 0)]))])]
17212 {
17213 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17214 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17215 copy_rtx (operands[1]),
17216 copy_rtx (operands[0]));
17217 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17218 operands[4], const0_rtx);
17219 })
17220
17221 (define_peephole2
17222 [(set (match_operand:SWI12 0 "register_operand" "")
17223 (match_operand:SWI12 1 "memory_operand" ""))
17224 (parallel [(set (match_operand:SI 4 "register_operand" "")
17225 (match_operator:SI 3 "plusminuslogic_operator"
17226 [(match_dup 4)
17227 (match_operand:SI 2 "nonmemory_operand" "")]))
17228 (clobber (reg:CC FLAGS_REG))])
17229 (set (match_dup 1) (match_dup 0))
17230 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17231 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17232 && REG_P (operands[0]) && REG_P (operands[4])
17233 && REGNO (operands[0]) == REGNO (operands[4])
17234 && peep2_reg_dead_p (4, operands[0])
17235 && !reg_overlap_mentioned_p (operands[0], operands[1])
17236 && ix86_match_ccmode (peep2_next_insn (3),
17237 (GET_CODE (operands[3]) == PLUS
17238 || GET_CODE (operands[3]) == MINUS)
17239 ? CCGOCmode : CCNOmode)"
17240 [(parallel [(set (match_dup 4) (match_dup 5))
17241 (set (match_dup 1) (match_dup 6))])]
17242 {
17243 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17244 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17245 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17246 copy_rtx (operands[1]), operands[2]);
17247 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17248 operands[5], const0_rtx);
17249 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17250 copy_rtx (operands[1]),
17251 copy_rtx (operands[2]));
17252 })
17253
17254 ;; Attempt to always use XOR for zeroing registers.
17255 (define_peephole2
17256 [(set (match_operand 0 "register_operand" "")
17257 (match_operand 1 "const0_operand" ""))]
17258 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17259 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17260 && GENERAL_REG_P (operands[0])
17261 && peep2_regno_dead_p (0, FLAGS_REG)"
17262 [(parallel [(set (match_dup 0) (const_int 0))
17263 (clobber (reg:CC FLAGS_REG))])]
17264 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17265
17266 (define_peephole2
17267 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17268 (const_int 0))]
17269 "(GET_MODE (operands[0]) == QImode
17270 || GET_MODE (operands[0]) == HImode)
17271 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17272 && peep2_regno_dead_p (0, FLAGS_REG)"
17273 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17274 (clobber (reg:CC FLAGS_REG))])])
17275
17276 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17277 (define_peephole2
17278 [(set (match_operand:SWI248 0 "register_operand" "")
17279 (const_int -1))]
17280 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17281 && peep2_regno_dead_p (0, FLAGS_REG)"
17282 [(parallel [(set (match_dup 0) (const_int -1))
17283 (clobber (reg:CC FLAGS_REG))])]
17284 {
17285 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17286 operands[0] = gen_lowpart (SImode, operands[0]);
17287 })
17288
17289 ;; Attempt to convert simple lea to add/shift.
17290 ;; These can be created by move expanders.
17291
17292 (define_peephole2
17293 [(set (match_operand:SWI48 0 "register_operand" "")
17294 (plus:SWI48 (match_dup 0)
17295 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17296 "peep2_regno_dead_p (0, FLAGS_REG)"
17297 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17298 (clobber (reg:CC FLAGS_REG))])])
17299
17300 (define_peephole2
17301 [(set (match_operand:SI 0 "register_operand" "")
17302 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17303 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17304 "TARGET_64BIT
17305 && peep2_regno_dead_p (0, FLAGS_REG)
17306 && REGNO (operands[0]) == REGNO (operands[1])"
17307 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17308 (clobber (reg:CC FLAGS_REG))])]
17309 "operands[2] = gen_lowpart (SImode, operands[2]);")
17310
17311 (define_peephole2
17312 [(set (match_operand:SWI48 0 "register_operand" "")
17313 (mult:SWI48 (match_dup 0)
17314 (match_operand:SWI48 1 "const_int_operand" "")))]
17315 "exact_log2 (INTVAL (operands[1])) >= 0
17316 && peep2_regno_dead_p (0, FLAGS_REG)"
17317 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17318 (clobber (reg:CC FLAGS_REG))])]
17319 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17320
17321 (define_peephole2
17322 [(set (match_operand:SI 0 "register_operand" "")
17323 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17324 (match_operand:DI 2 "const_int_operand" "")) 0))]
17325 "TARGET_64BIT
17326 && exact_log2 (INTVAL (operands[2])) >= 0
17327 && REGNO (operands[0]) == REGNO (operands[1])
17328 && peep2_regno_dead_p (0, FLAGS_REG)"
17329 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17330 (clobber (reg:CC FLAGS_REG))])]
17331 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17332
17333 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17334 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17335 ;; On many CPUs it is also faster, since special hardware to avoid esp
17336 ;; dependencies is present.
17337
17338 ;; While some of these conversions may be done using splitters, we use
17339 ;; peepholes in order to allow combine_stack_adjustments pass to see
17340 ;; nonobfuscated RTL.
17341
17342 ;; Convert prologue esp subtractions to push.
17343 ;; We need register to push. In order to keep verify_flow_info happy we have
17344 ;; two choices
17345 ;; - use scratch and clobber it in order to avoid dependencies
17346 ;; - use already live register
17347 ;; We can't use the second way right now, since there is no reliable way how to
17348 ;; verify that given register is live. First choice will also most likely in
17349 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17350 ;; call clobbered registers are dead. We may want to use base pointer as an
17351 ;; alternative when no register is available later.
17352
17353 (define_peephole2
17354 [(match_scratch:P 1 "r")
17355 (parallel [(set (reg:P SP_REG)
17356 (plus:P (reg:P SP_REG)
17357 (match_operand:P 0 "const_int_operand" "")))
17358 (clobber (reg:CC FLAGS_REG))
17359 (clobber (mem:BLK (scratch)))])]
17360 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17361 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17362 [(clobber (match_dup 1))
17363 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17364 (clobber (mem:BLK (scratch)))])])
17365
17366 (define_peephole2
17367 [(match_scratch:P 1 "r")
17368 (parallel [(set (reg:P SP_REG)
17369 (plus:P (reg:P SP_REG)
17370 (match_operand:P 0 "const_int_operand" "")))
17371 (clobber (reg:CC FLAGS_REG))
17372 (clobber (mem:BLK (scratch)))])]
17373 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17374 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17375 [(clobber (match_dup 1))
17376 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17377 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17378 (clobber (mem:BLK (scratch)))])])
17379
17380 ;; Convert esp subtractions to push.
17381 (define_peephole2
17382 [(match_scratch:P 1 "r")
17383 (parallel [(set (reg:P SP_REG)
17384 (plus:P (reg:P SP_REG)
17385 (match_operand:P 0 "const_int_operand" "")))
17386 (clobber (reg:CC FLAGS_REG))])]
17387 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17388 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17389 [(clobber (match_dup 1))
17390 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17391
17392 (define_peephole2
17393 [(match_scratch:P 1 "r")
17394 (parallel [(set (reg:P SP_REG)
17395 (plus:P (reg:P SP_REG)
17396 (match_operand:P 0 "const_int_operand" "")))
17397 (clobber (reg:CC FLAGS_REG))])]
17398 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17399 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17400 [(clobber (match_dup 1))
17401 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17402 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17403
17404 ;; Convert epilogue deallocator to pop.
17405 (define_peephole2
17406 [(match_scratch:P 1 "r")
17407 (parallel [(set (reg:P SP_REG)
17408 (plus:P (reg:P SP_REG)
17409 (match_operand:P 0 "const_int_operand" "")))
17410 (clobber (reg:CC FLAGS_REG))
17411 (clobber (mem:BLK (scratch)))])]
17412 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17413 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17414 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17415 (clobber (mem:BLK (scratch)))])])
17416
17417 ;; Two pops case is tricky, since pop causes dependency
17418 ;; on destination register. We use two registers if available.
17419 (define_peephole2
17420 [(match_scratch:P 1 "r")
17421 (match_scratch:P 2 "r")
17422 (parallel [(set (reg:P SP_REG)
17423 (plus:P (reg:P SP_REG)
17424 (match_operand:P 0 "const_int_operand" "")))
17425 (clobber (reg:CC FLAGS_REG))
17426 (clobber (mem:BLK (scratch)))])]
17427 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17428 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17429 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17430 (clobber (mem:BLK (scratch)))])
17431 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17432
17433 (define_peephole2
17434 [(match_scratch:P 1 "r")
17435 (parallel [(set (reg:P SP_REG)
17436 (plus:P (reg:P SP_REG)
17437 (match_operand:P 0 "const_int_operand" "")))
17438 (clobber (reg:CC FLAGS_REG))
17439 (clobber (mem:BLK (scratch)))])]
17440 "optimize_insn_for_size_p ()
17441 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17442 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17443 (clobber (mem:BLK (scratch)))])
17444 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17445
17446 ;; Convert esp additions to pop.
17447 (define_peephole2
17448 [(match_scratch:P 1 "r")
17449 (parallel [(set (reg:P SP_REG)
17450 (plus:P (reg:P SP_REG)
17451 (match_operand:P 0 "const_int_operand" "")))
17452 (clobber (reg:CC FLAGS_REG))])]
17453 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17454 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17455
17456 ;; Two pops case is tricky, since pop causes dependency
17457 ;; on destination register. We use two registers if available.
17458 (define_peephole2
17459 [(match_scratch:P 1 "r")
17460 (match_scratch:P 2 "r")
17461 (parallel [(set (reg:P SP_REG)
17462 (plus:P (reg:P SP_REG)
17463 (match_operand:P 0 "const_int_operand" "")))
17464 (clobber (reg:CC FLAGS_REG))])]
17465 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17466 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17467 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17468
17469 (define_peephole2
17470 [(match_scratch:P 1 "r")
17471 (parallel [(set (reg:P SP_REG)
17472 (plus:P (reg:P SP_REG)
17473 (match_operand:P 0 "const_int_operand" "")))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "optimize_insn_for_size_p ()
17476 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17477 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17478 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17479 \f
17480 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17481 ;; required and register dies. Similarly for 128 to -128.
17482 (define_peephole2
17483 [(set (match_operand 0 "flags_reg_operand" "")
17484 (match_operator 1 "compare_operator"
17485 [(match_operand 2 "register_operand" "")
17486 (match_operand 3 "const_int_operand" "")]))]
17487 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17488 && incdec_operand (operands[3], GET_MODE (operands[3])))
17489 || (!TARGET_FUSE_CMP_AND_BRANCH
17490 && INTVAL (operands[3]) == 128))
17491 && ix86_match_ccmode (insn, CCGCmode)
17492 && peep2_reg_dead_p (1, operands[2])"
17493 [(parallel [(set (match_dup 0)
17494 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17495 (clobber (match_dup 2))])])
17496 \f
17497 ;; Convert imul by three, five and nine into lea
17498 (define_peephole2
17499 [(parallel
17500 [(set (match_operand:SWI48 0 "register_operand" "")
17501 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17502 (match_operand:SWI48 2 "const359_operand" "")))
17503 (clobber (reg:CC FLAGS_REG))])]
17504 "!TARGET_PARTIAL_REG_STALL
17505 || <MODE>mode == SImode
17506 || optimize_function_for_size_p (cfun)"
17507 [(set (match_dup 0)
17508 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17509 (match_dup 1)))]
17510 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17511
17512 (define_peephole2
17513 [(parallel
17514 [(set (match_operand:SWI48 0 "register_operand" "")
17515 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17516 (match_operand:SWI48 2 "const359_operand" "")))
17517 (clobber (reg:CC FLAGS_REG))])]
17518 "optimize_insn_for_speed_p ()
17519 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17520 [(set (match_dup 0) (match_dup 1))
17521 (set (match_dup 0)
17522 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17523 (match_dup 0)))]
17524 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17525
17526 ;; imul $32bit_imm, mem, reg is vector decoded, while
17527 ;; imul $32bit_imm, reg, reg is direct decoded.
17528 (define_peephole2
17529 [(match_scratch:SWI48 3 "r")
17530 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17531 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17532 (match_operand:SWI48 2 "immediate_operand" "")))
17533 (clobber (reg:CC FLAGS_REG))])]
17534 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17535 && !satisfies_constraint_K (operands[2])"
17536 [(set (match_dup 3) (match_dup 1))
17537 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17538 (clobber (reg:CC FLAGS_REG))])])
17539
17540 (define_peephole2
17541 [(match_scratch:SI 3 "r")
17542 (parallel [(set (match_operand:DI 0 "register_operand" "")
17543 (zero_extend:DI
17544 (mult:SI (match_operand:SI 1 "memory_operand" "")
17545 (match_operand:SI 2 "immediate_operand" ""))))
17546 (clobber (reg:CC FLAGS_REG))])]
17547 "TARGET_64BIT
17548 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17549 && !satisfies_constraint_K (operands[2])"
17550 [(set (match_dup 3) (match_dup 1))
17551 (parallel [(set (match_dup 0)
17552 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17553 (clobber (reg:CC FLAGS_REG))])])
17554
17555 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17556 ;; Convert it into imul reg, reg
17557 ;; It would be better to force assembler to encode instruction using long
17558 ;; immediate, but there is apparently no way to do so.
17559 (define_peephole2
17560 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17561 (mult:SWI248
17562 (match_operand:SWI248 1 "nonimmediate_operand" "")
17563 (match_operand:SWI248 2 "const_int_operand" "")))
17564 (clobber (reg:CC FLAGS_REG))])
17565 (match_scratch:SWI248 3 "r")]
17566 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17567 && satisfies_constraint_K (operands[2])"
17568 [(set (match_dup 3) (match_dup 2))
17569 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17570 (clobber (reg:CC FLAGS_REG))])]
17571 {
17572 if (!rtx_equal_p (operands[0], operands[1]))
17573 emit_move_insn (operands[0], operands[1]);
17574 })
17575
17576 ;; After splitting up read-modify operations, array accesses with memory
17577 ;; operands might end up in form:
17578 ;; sall $2, %eax
17579 ;; movl 4(%esp), %edx
17580 ;; addl %edx, %eax
17581 ;; instead of pre-splitting:
17582 ;; sall $2, %eax
17583 ;; addl 4(%esp), %eax
17584 ;; Turn it into:
17585 ;; movl 4(%esp), %edx
17586 ;; leal (%edx,%eax,4), %eax
17587
17588 (define_peephole2
17589 [(match_scratch:P 5 "r")
17590 (parallel [(set (match_operand 0 "register_operand" "")
17591 (ashift (match_operand 1 "register_operand" "")
17592 (match_operand 2 "const_int_operand" "")))
17593 (clobber (reg:CC FLAGS_REG))])
17594 (parallel [(set (match_operand 3 "register_operand" "")
17595 (plus (match_dup 0)
17596 (match_operand 4 "x86_64_general_operand" "")))
17597 (clobber (reg:CC FLAGS_REG))])]
17598 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17599 /* Validate MODE for lea. */
17600 && ((!TARGET_PARTIAL_REG_STALL
17601 && (GET_MODE (operands[0]) == QImode
17602 || GET_MODE (operands[0]) == HImode))
17603 || GET_MODE (operands[0]) == SImode
17604 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17605 && (rtx_equal_p (operands[0], operands[3])
17606 || peep2_reg_dead_p (2, operands[0]))
17607 /* We reorder load and the shift. */
17608 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17609 [(set (match_dup 5) (match_dup 4))
17610 (set (match_dup 0) (match_dup 1))]
17611 {
17612 enum machine_mode op1mode = GET_MODE (operands[1]);
17613 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17614 int scale = 1 << INTVAL (operands[2]);
17615 rtx index = gen_lowpart (Pmode, operands[1]);
17616 rtx base = gen_lowpart (Pmode, operands[5]);
17617 rtx dest = gen_lowpart (mode, operands[3]);
17618
17619 operands[1] = gen_rtx_PLUS (Pmode, base,
17620 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17621 operands[5] = base;
17622 if (mode != Pmode)
17623 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17624 if (op1mode != Pmode)
17625 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17626 operands[0] = dest;
17627 })
17628 \f
17629 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17630 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17631 ;; caught for use by garbage collectors and the like. Using an insn that
17632 ;; maps to SIGILL makes it more likely the program will rightfully die.
17633 ;; Keeping with tradition, "6" is in honor of #UD.
17634 (define_insn "trap"
17635 [(trap_if (const_int 1) (const_int 6))]
17636 ""
17637 { return ASM_SHORT "0x0b0f"; }
17638 [(set_attr "length" "2")])
17639
17640 (define_expand "prefetch"
17641 [(prefetch (match_operand 0 "address_operand" "")
17642 (match_operand:SI 1 "const_int_operand" "")
17643 (match_operand:SI 2 "const_int_operand" ""))]
17644 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17645 {
17646 int rw = INTVAL (operands[1]);
17647 int locality = INTVAL (operands[2]);
17648
17649 gcc_assert (rw == 0 || rw == 1);
17650 gcc_assert (locality >= 0 && locality <= 3);
17651 gcc_assert (GET_MODE (operands[0]) == Pmode
17652 || GET_MODE (operands[0]) == VOIDmode);
17653
17654 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17655 supported by SSE counterpart or the SSE prefetch is not available
17656 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17657 of locality. */
17658 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17659 operands[2] = GEN_INT (3);
17660 else
17661 operands[1] = const0_rtx;
17662 })
17663
17664 (define_insn "*prefetch_sse_<mode>"
17665 [(prefetch (match_operand:P 0 "address_operand" "p")
17666 (const_int 0)
17667 (match_operand:SI 1 "const_int_operand" ""))]
17668 "TARGET_PREFETCH_SSE"
17669 {
17670 static const char * const patterns[4] = {
17671 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17672 };
17673
17674 int locality = INTVAL (operands[1]);
17675 gcc_assert (locality >= 0 && locality <= 3);
17676
17677 return patterns[locality];
17678 }
17679 [(set_attr "type" "sse")
17680 (set_attr "atom_sse_attr" "prefetch")
17681 (set (attr "length_address")
17682 (symbol_ref "memory_address_length (operands[0])"))
17683 (set_attr "memory" "none")])
17684
17685 (define_insn "*prefetch_3dnow_<mode>"
17686 [(prefetch (match_operand:P 0 "address_operand" "p")
17687 (match_operand:SI 1 "const_int_operand" "n")
17688 (const_int 3))]
17689 "TARGET_3DNOW"
17690 {
17691 if (INTVAL (operands[1]) == 0)
17692 return "prefetch\t%a0";
17693 else
17694 return "prefetchw\t%a0";
17695 }
17696 [(set_attr "type" "mmx")
17697 (set (attr "length_address")
17698 (symbol_ref "memory_address_length (operands[0])"))
17699 (set_attr "memory" "none")])
17700
17701 (define_expand "stack_protect_set"
17702 [(match_operand 0 "memory_operand" "")
17703 (match_operand 1 "memory_operand" "")]
17704 ""
17705 {
17706 rtx (*insn)(rtx, rtx);
17707
17708 #ifdef TARGET_THREAD_SSP_OFFSET
17709 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17710 insn = (TARGET_LP64
17711 ? gen_stack_tls_protect_set_di
17712 : gen_stack_tls_protect_set_si);
17713 #else
17714 insn = (TARGET_LP64
17715 ? gen_stack_protect_set_di
17716 : gen_stack_protect_set_si);
17717 #endif
17718
17719 emit_insn (insn (operands[0], operands[1]));
17720 DONE;
17721 })
17722
17723 (define_insn "stack_protect_set_<mode>"
17724 [(set (match_operand:PTR 0 "memory_operand" "=m")
17725 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17726 UNSPEC_SP_SET))
17727 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17728 (clobber (reg:CC FLAGS_REG))]
17729 ""
17730 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17731 [(set_attr "type" "multi")])
17732
17733 (define_insn "stack_tls_protect_set_<mode>"
17734 [(set (match_operand:PTR 0 "memory_operand" "=m")
17735 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17736 UNSPEC_SP_TLS_SET))
17737 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17738 (clobber (reg:CC FLAGS_REG))]
17739 ""
17740 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17741 [(set_attr "type" "multi")])
17742
17743 (define_expand "stack_protect_test"
17744 [(match_operand 0 "memory_operand" "")
17745 (match_operand 1 "memory_operand" "")
17746 (match_operand 2 "" "")]
17747 ""
17748 {
17749 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17750
17751 rtx (*insn)(rtx, rtx, rtx);
17752
17753 #ifdef TARGET_THREAD_SSP_OFFSET
17754 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17755 insn = (TARGET_LP64
17756 ? gen_stack_tls_protect_test_di
17757 : gen_stack_tls_protect_test_si);
17758 #else
17759 insn = (TARGET_LP64
17760 ? gen_stack_protect_test_di
17761 : gen_stack_protect_test_si);
17762 #endif
17763
17764 emit_insn (insn (flags, operands[0], operands[1]));
17765
17766 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17767 flags, const0_rtx, operands[2]));
17768 DONE;
17769 })
17770
17771 (define_insn "stack_protect_test_<mode>"
17772 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17773 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17774 (match_operand:PTR 2 "memory_operand" "m")]
17775 UNSPEC_SP_TEST))
17776 (clobber (match_scratch:PTR 3 "=&r"))]
17777 ""
17778 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17779 [(set_attr "type" "multi")])
17780
17781 (define_insn "stack_tls_protect_test_<mode>"
17782 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17783 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17784 (match_operand:PTR 2 "const_int_operand" "i")]
17785 UNSPEC_SP_TLS_TEST))
17786 (clobber (match_scratch:PTR 3 "=r"))]
17787 ""
17788 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17789 [(set_attr "type" "multi")])
17790
17791 (define_insn "sse4_2_crc32<mode>"
17792 [(set (match_operand:SI 0 "register_operand" "=r")
17793 (unspec:SI
17794 [(match_operand:SI 1 "register_operand" "0")
17795 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17796 UNSPEC_CRC32))]
17797 "TARGET_SSE4_2 || TARGET_CRC32"
17798 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17799 [(set_attr "type" "sselog1")
17800 (set_attr "prefix_rep" "1")
17801 (set_attr "prefix_extra" "1")
17802 (set (attr "prefix_data16")
17803 (if_then_else (match_operand:HI 2 "" "")
17804 (const_string "1")
17805 (const_string "*")))
17806 (set (attr "prefix_rex")
17807 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17808 (const_string "1")
17809 (const_string "*")))
17810 (set_attr "mode" "SI")])
17811
17812 (define_insn "sse4_2_crc32di"
17813 [(set (match_operand:DI 0 "register_operand" "=r")
17814 (unspec:DI
17815 [(match_operand:DI 1 "register_operand" "0")
17816 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17817 UNSPEC_CRC32))]
17818 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17819 "crc32{q}\t{%2, %0|%0, %2}"
17820 [(set_attr "type" "sselog1")
17821 (set_attr "prefix_rep" "1")
17822 (set_attr "prefix_extra" "1")
17823 (set_attr "mode" "DI")])
17824
17825 (define_expand "rdpmc"
17826 [(match_operand:DI 0 "register_operand" "")
17827 (match_operand:SI 1 "register_operand" "")]
17828 ""
17829 {
17830 rtx reg = gen_reg_rtx (DImode);
17831 rtx si;
17832
17833 /* Force operand 1 into ECX. */
17834 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17835 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17836 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17837 UNSPECV_RDPMC);
17838
17839 if (TARGET_64BIT)
17840 {
17841 rtvec vec = rtvec_alloc (2);
17842 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17843 rtx upper = gen_reg_rtx (DImode);
17844 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17845 gen_rtvec (1, const0_rtx),
17846 UNSPECV_RDPMC);
17847 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17848 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17849 emit_insn (load);
17850 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17851 NULL, 1, OPTAB_DIRECT);
17852 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17853 OPTAB_DIRECT);
17854 }
17855 else
17856 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17857 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17858 DONE;
17859 })
17860
17861 (define_insn "*rdpmc"
17862 [(set (match_operand:DI 0 "register_operand" "=A")
17863 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17864 UNSPECV_RDPMC))]
17865 "!TARGET_64BIT"
17866 "rdpmc"
17867 [(set_attr "type" "other")
17868 (set_attr "length" "2")])
17869
17870 (define_insn "*rdpmc_rex64"
17871 [(set (match_operand:DI 0 "register_operand" "=a")
17872 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17873 UNSPECV_RDPMC))
17874 (set (match_operand:DI 1 "register_operand" "=d")
17875 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17876 "TARGET_64BIT"
17877 "rdpmc"
17878 [(set_attr "type" "other")
17879 (set_attr "length" "2")])
17880
17881 (define_expand "rdtsc"
17882 [(set (match_operand:DI 0 "register_operand" "")
17883 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17884 ""
17885 {
17886 if (TARGET_64BIT)
17887 {
17888 rtvec vec = rtvec_alloc (2);
17889 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17890 rtx upper = gen_reg_rtx (DImode);
17891 rtx lower = gen_reg_rtx (DImode);
17892 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17893 gen_rtvec (1, const0_rtx),
17894 UNSPECV_RDTSC);
17895 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17896 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17897 emit_insn (load);
17898 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17899 NULL, 1, OPTAB_DIRECT);
17900 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17901 OPTAB_DIRECT);
17902 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17903 DONE;
17904 }
17905 })
17906
17907 (define_insn "*rdtsc"
17908 [(set (match_operand:DI 0 "register_operand" "=A")
17909 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17910 "!TARGET_64BIT"
17911 "rdtsc"
17912 [(set_attr "type" "other")
17913 (set_attr "length" "2")])
17914
17915 (define_insn "*rdtsc_rex64"
17916 [(set (match_operand:DI 0 "register_operand" "=a")
17917 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17918 (set (match_operand:DI 1 "register_operand" "=d")
17919 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17920 "TARGET_64BIT"
17921 "rdtsc"
17922 [(set_attr "type" "other")
17923 (set_attr "length" "2")])
17924
17925 (define_expand "rdtscp"
17926 [(match_operand:DI 0 "register_operand" "")
17927 (match_operand:SI 1 "memory_operand" "")]
17928 ""
17929 {
17930 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17931 gen_rtvec (1, const0_rtx),
17932 UNSPECV_RDTSCP);
17933 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17934 gen_rtvec (1, const0_rtx),
17935 UNSPECV_RDTSCP);
17936 rtx reg = gen_reg_rtx (DImode);
17937 rtx tmp = gen_reg_rtx (SImode);
17938
17939 if (TARGET_64BIT)
17940 {
17941 rtvec vec = rtvec_alloc (3);
17942 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17943 rtx upper = gen_reg_rtx (DImode);
17944 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17945 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17946 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17947 emit_insn (load);
17948 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17949 NULL, 1, OPTAB_DIRECT);
17950 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17951 OPTAB_DIRECT);
17952 }
17953 else
17954 {
17955 rtvec vec = rtvec_alloc (2);
17956 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17957 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17958 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17959 emit_insn (load);
17960 }
17961 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17962 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17963 DONE;
17964 })
17965
17966 (define_insn "*rdtscp"
17967 [(set (match_operand:DI 0 "register_operand" "=A")
17968 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17969 (set (match_operand:SI 1 "register_operand" "=c")
17970 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17971 "!TARGET_64BIT"
17972 "rdtscp"
17973 [(set_attr "type" "other")
17974 (set_attr "length" "3")])
17975
17976 (define_insn "*rdtscp_rex64"
17977 [(set (match_operand:DI 0 "register_operand" "=a")
17978 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17979 (set (match_operand:DI 1 "register_operand" "=d")
17980 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17981 (set (match_operand:SI 2 "register_operand" "=c")
17982 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17983 "TARGET_64BIT"
17984 "rdtscp"
17985 [(set_attr "type" "other")
17986 (set_attr "length" "3")])
17987
17988 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17989 ;;
17990 ;; LWP instructions
17991 ;;
17992 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17993
17994 (define_expand "lwp_llwpcb"
17995 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17996 UNSPECV_LLWP_INTRINSIC)]
17997 "TARGET_LWP")
17998
17999 (define_insn "*lwp_llwpcb<mode>1"
18000 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18001 UNSPECV_LLWP_INTRINSIC)]
18002 "TARGET_LWP"
18003 "llwpcb\t%0"
18004 [(set_attr "type" "lwp")
18005 (set_attr "mode" "<MODE>")
18006 (set_attr "length" "5")])
18007
18008 (define_expand "lwp_slwpcb"
18009 [(set (match_operand 0 "register_operand" "=r")
18010 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18011 "TARGET_LWP"
18012 {
18013 rtx (*insn)(rtx);
18014
18015 insn = (TARGET_64BIT
18016 ? gen_lwp_slwpcbdi
18017 : gen_lwp_slwpcbsi);
18018
18019 emit_insn (insn (operands[0]));
18020 DONE;
18021 })
18022
18023 (define_insn "lwp_slwpcb<mode>"
18024 [(set (match_operand:P 0 "register_operand" "=r")
18025 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18026 "TARGET_LWP"
18027 "slwpcb\t%0"
18028 [(set_attr "type" "lwp")
18029 (set_attr "mode" "<MODE>")
18030 (set_attr "length" "5")])
18031
18032 (define_expand "lwp_lwpval<mode>3"
18033 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18034 (match_operand:SI 2 "nonimmediate_operand" "rm")
18035 (match_operand:SI 3 "const_int_operand" "i")]
18036 UNSPECV_LWPVAL_INTRINSIC)]
18037 "TARGET_LWP"
18038 ;; Avoid unused variable warning.
18039 "(void) operands[0];")
18040
18041 (define_insn "*lwp_lwpval<mode>3_1"
18042 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18043 (match_operand:SI 1 "nonimmediate_operand" "rm")
18044 (match_operand:SI 2 "const_int_operand" "i")]
18045 UNSPECV_LWPVAL_INTRINSIC)]
18046 "TARGET_LWP"
18047 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18048 [(set_attr "type" "lwp")
18049 (set_attr "mode" "<MODE>")
18050 (set (attr "length")
18051 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18052
18053 (define_expand "lwp_lwpins<mode>3"
18054 [(set (reg:CCC FLAGS_REG)
18055 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18056 (match_operand:SI 2 "nonimmediate_operand" "rm")
18057 (match_operand:SI 3 "const_int_operand" "i")]
18058 UNSPECV_LWPINS_INTRINSIC))
18059 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18060 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18061 "TARGET_LWP")
18062
18063 (define_insn "*lwp_lwpins<mode>3_1"
18064 [(set (reg:CCC FLAGS_REG)
18065 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18066 (match_operand:SI 1 "nonimmediate_operand" "rm")
18067 (match_operand:SI 2 "const_int_operand" "i")]
18068 UNSPECV_LWPINS_INTRINSIC))]
18069 "TARGET_LWP"
18070 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18071 [(set_attr "type" "lwp")
18072 (set_attr "mode" "<MODE>")
18073 (set (attr "length")
18074 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18075
18076 (define_insn "rdfsbase<mode>"
18077 [(set (match_operand:SWI48 0 "register_operand" "=r")
18078 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18079 "TARGET_64BIT && TARGET_FSGSBASE"
18080 "rdfsbase %0"
18081 [(set_attr "type" "other")
18082 (set_attr "prefix_extra" "2")])
18083
18084 (define_insn "rdgsbase<mode>"
18085 [(set (match_operand:SWI48 0 "register_operand" "=r")
18086 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18087 "TARGET_64BIT && TARGET_FSGSBASE"
18088 "rdgsbase %0"
18089 [(set_attr "type" "other")
18090 (set_attr "prefix_extra" "2")])
18091
18092 (define_insn "wrfsbase<mode>"
18093 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18094 UNSPECV_WRFSBASE)]
18095 "TARGET_64BIT && TARGET_FSGSBASE"
18096 "wrfsbase %0"
18097 [(set_attr "type" "other")
18098 (set_attr "prefix_extra" "2")])
18099
18100 (define_insn "wrgsbase<mode>"
18101 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18102 UNSPECV_WRGSBASE)]
18103 "TARGET_64BIT && TARGET_FSGSBASE"
18104 "wrgsbase %0"
18105 [(set_attr "type" "other")
18106 (set_attr "prefix_extra" "2")])
18107
18108 (define_insn "rdrand<mode>_1"
18109 [(set (match_operand:SWI248 0 "register_operand" "=r")
18110 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18111 (set (reg:CCC FLAGS_REG)
18112 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18113 "TARGET_RDRND"
18114 "rdrand\t%0"
18115 [(set_attr "type" "other")
18116 (set_attr "prefix_extra" "1")])
18117
18118 (define_expand "pause"
18119 [(set (match_dup 0)
18120 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18121 ""
18122 {
18123 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18124 MEM_VOLATILE_P (operands[0]) = 1;
18125 })
18126
18127 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18128 ;; They have the same encoding.
18129 (define_insn "*pause"
18130 [(set (match_operand:BLK 0 "" "")
18131 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18132 ""
18133 "rep; nop"
18134 [(set_attr "length" "2")
18135 (set_attr "memory" "unknown")])
18136
18137 (include "mmx.md")
18138 (include "sse.md")
18139 (include "sync.md")