re PR target/48860 (r173265 breaks bootstrap on x86_64-apple-darwin10)
[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 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
63
64 ;; UNSPEC usage:
65
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
68 UNSPEC_GOT
69 UNSPEC_GOTOFF
70 UNSPEC_GOTPCREL
71 UNSPEC_GOTTPOFF
72 UNSPEC_TPOFF
73 UNSPEC_NTPOFF
74 UNSPEC_DTPOFF
75 UNSPEC_GOTNTPOFF
76 UNSPEC_INDNTPOFF
77 UNSPEC_PLTOFF
78 UNSPEC_MACHOPIC_OFFSET
79 UNSPEC_PCREL
80
81 ;; Prologue support
82 UNSPEC_STACK_ALLOC
83 UNSPEC_SET_GOT
84 UNSPEC_REG_SAVE
85 UNSPEC_DEF_CFA
86 UNSPEC_SET_RIP
87 UNSPEC_SET_GOT_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
89 UNSPEC_STACK_CHECK
90
91 ;; TLS support
92 UNSPEC_TP
93 UNSPEC_TLS_GD
94 UNSPEC_TLS_LD_BASE
95 UNSPEC_TLSDESC
96 UNSPEC_TLS_IE_SUN
97
98 ;; Other random patterns
99 UNSPEC_SCAS
100 UNSPEC_FNSTSW
101 UNSPEC_SAHF
102 UNSPEC_PARITY
103 UNSPEC_FSTCW
104 UNSPEC_ADD_CARRY
105 UNSPEC_FLDCW
106 UNSPEC_REP
107 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_TRUNC_NOOP
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_CALL_NEEDS_VZEROUPPER
111
112 ;; For SSE/MMX support:
113 UNSPEC_FIX_NOTRUNC
114 UNSPEC_MASKMOV
115 UNSPEC_MOVMSK
116 UNSPEC_MOVNT
117 UNSPEC_MOVU
118 UNSPEC_RCP
119 UNSPEC_RSQRT
120 UNSPEC_SFENCE
121 UNSPEC_PFRCP
122 UNSPEC_PFRCPIT1
123 UNSPEC_PFRCPIT2
124 UNSPEC_PFRSQRT
125 UNSPEC_PFRSQIT1
126 UNSPEC_MFENCE
127 UNSPEC_LFENCE
128 UNSPEC_PSADBW
129 UNSPEC_LDDQU
130 UNSPEC_MS_TO_SYSV_CALL
131
132 ;; Generic math support
133 UNSPEC_COPYSIGN
134 UNSPEC_IEEE_MIN ; not commutative
135 UNSPEC_IEEE_MAX ; not commutative
136
137 ;; x87 Floating point
138 UNSPEC_SIN
139 UNSPEC_COS
140 UNSPEC_FPATAN
141 UNSPEC_FYL2X
142 UNSPEC_FYL2XP1
143 UNSPEC_FRNDINT
144 UNSPEC_FIST
145 UNSPEC_F2XM1
146 UNSPEC_TAN
147 UNSPEC_FXAM
148
149 ;; x87 Rounding
150 UNSPEC_FRNDINT_FLOOR
151 UNSPEC_FRNDINT_CEIL
152 UNSPEC_FRNDINT_TRUNC
153 UNSPEC_FRNDINT_MASK_PM
154 UNSPEC_FIST_FLOOR
155 UNSPEC_FIST_CEIL
156
157 ;; x87 Double output FP
158 UNSPEC_SINCOS_COS
159 UNSPEC_SINCOS_SIN
160 UNSPEC_XTRACT_FRACT
161 UNSPEC_XTRACT_EXP
162 UNSPEC_FSCALE_FRACT
163 UNSPEC_FSCALE_EXP
164 UNSPEC_FPREM_F
165 UNSPEC_FPREM_U
166 UNSPEC_FPREM1_F
167 UNSPEC_FPREM1_U
168
169 UNSPEC_C2_FLAG
170 UNSPEC_FXAM_MEM
171
172 ;; SSP patterns
173 UNSPEC_SP_SET
174 UNSPEC_SP_TEST
175 UNSPEC_SP_TLS_SET
176 UNSPEC_SP_TLS_TEST
177
178 ;; SSSE3
179 UNSPEC_PSHUFB
180 UNSPEC_PSIGN
181 UNSPEC_PALIGNR
182
183 ;; For SSE4A support
184 UNSPEC_EXTRQI
185 UNSPEC_EXTRQ
186 UNSPEC_INSERTQI
187 UNSPEC_INSERTQ
188
189 ;; For SSE4.1 support
190 UNSPEC_BLENDV
191 UNSPEC_INSERTPS
192 UNSPEC_DP
193 UNSPEC_MOVNTDQA
194 UNSPEC_MPSADBW
195 UNSPEC_PHMINPOSUW
196 UNSPEC_PTEST
197 UNSPEC_ROUND
198
199 ;; For SSE4.2 support
200 UNSPEC_CRC32
201 UNSPEC_PCMPESTR
202 UNSPEC_PCMPISTR
203
204 ;; For FMA4 support
205 UNSPEC_FMADDSUB
206 UNSPEC_XOP_UNSIGNED_CMP
207 UNSPEC_XOP_TRUEFALSE
208 UNSPEC_XOP_PERMUTE
209 UNSPEC_FRCZ
210
211 ;; For AES support
212 UNSPEC_AESENC
213 UNSPEC_AESENCLAST
214 UNSPEC_AESDEC
215 UNSPEC_AESDECLAST
216 UNSPEC_AESIMC
217 UNSPEC_AESKEYGENASSIST
218
219 ;; For PCLMUL support
220 UNSPEC_PCLMUL
221
222 ;; For AVX support
223 UNSPEC_PCMP
224 UNSPEC_VPERMIL
225 UNSPEC_VPERMIL2
226 UNSPEC_VPERMIL2F128
227 UNSPEC_CAST
228 UNSPEC_VTESTP
229 UNSPEC_VCVTPH2PS
230 UNSPEC_VCVTPS2PH
231
232 ;; For BMI support
233 UNSPEC_BEXTR
234
235 ;; For RDRAND support
236 UNSPEC_RDRAND
237 ])
238
239 (define_c_enum "unspecv" [
240 UNSPECV_BLOCKAGE
241 UNSPECV_STACK_PROBE
242 UNSPECV_PROBE_STACK_RANGE
243 UNSPECV_EMMS
244 UNSPECV_LDMXCSR
245 UNSPECV_STMXCSR
246 UNSPECV_FEMMS
247 UNSPECV_CLFLUSH
248 UNSPECV_ALIGN
249 UNSPECV_MONITOR
250 UNSPECV_MWAIT
251 UNSPECV_CMPXCHG
252 UNSPECV_XCHG
253 UNSPECV_LOCK
254 UNSPECV_PROLOGUE_USE
255 UNSPECV_CLD
256 UNSPECV_NOPS
257 UNSPECV_VZEROALL
258 UNSPECV_VZEROUPPER
259 UNSPECV_RDTSC
260 UNSPECV_RDTSCP
261 UNSPECV_RDPMC
262 UNSPECV_LLWP_INTRINSIC
263 UNSPECV_SLWP_INTRINSIC
264 UNSPECV_LWPVAL_INTRINSIC
265 UNSPECV_LWPINS_INTRINSIC
266 UNSPECV_RDFSBASE
267 UNSPECV_RDGSBASE
268 UNSPECV_WRFSBASE
269 UNSPECV_WRGSBASE
270 UNSPECV_SPLIT_STACK_RETURN
271 ])
272
273 ;; Constants to represent rounding modes in the ROUND instruction
274 (define_constants
275 [(ROUND_FLOOR 0x1)
276 (ROUND_CEIL 0x2)
277 (ROUND_TRUNC 0x3)
278 (ROUND_MXCSR 0x4)
279 (ROUND_NO_EXC 0x8)
280 ])
281
282 ;; Constants to represent pcomtrue/pcomfalse variants
283 (define_constants
284 [(PCOM_FALSE 0)
285 (PCOM_TRUE 1)
286 (COM_FALSE_S 2)
287 (COM_FALSE_P 3)
288 (COM_TRUE_S 4)
289 (COM_TRUE_P 5)
290 ])
291
292 ;; Constants used in the XOP pperm instruction
293 (define_constants
294 [(PPERM_SRC 0x00) /* copy source */
295 (PPERM_INVERT 0x20) /* invert source */
296 (PPERM_REVERSE 0x40) /* bit reverse source */
297 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
298 (PPERM_ZERO 0x80) /* all 0's */
299 (PPERM_ONES 0xa0) /* all 1's */
300 (PPERM_SIGN 0xc0) /* propagate sign bit */
301 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
302 (PPERM_SRC1 0x00) /* use first source byte */
303 (PPERM_SRC2 0x10) /* use second source byte */
304 ])
305
306 ;; Registers by name.
307 (define_constants
308 [(AX_REG 0)
309 (DX_REG 1)
310 (CX_REG 2)
311 (BX_REG 3)
312 (SI_REG 4)
313 (DI_REG 5)
314 (BP_REG 6)
315 (SP_REG 7)
316 (ST0_REG 8)
317 (ST1_REG 9)
318 (ST2_REG 10)
319 (ST3_REG 11)
320 (ST4_REG 12)
321 (ST5_REG 13)
322 (ST6_REG 14)
323 (ST7_REG 15)
324 (FLAGS_REG 17)
325 (FPSR_REG 18)
326 (FPCR_REG 19)
327 (XMM0_REG 21)
328 (XMM1_REG 22)
329 (XMM2_REG 23)
330 (XMM3_REG 24)
331 (XMM4_REG 25)
332 (XMM5_REG 26)
333 (XMM6_REG 27)
334 (XMM7_REG 28)
335 (MM0_REG 29)
336 (MM1_REG 30)
337 (MM2_REG 31)
338 (MM3_REG 32)
339 (MM4_REG 33)
340 (MM5_REG 34)
341 (MM6_REG 35)
342 (MM7_REG 36)
343 (R8_REG 37)
344 (R9_REG 38)
345 (R10_REG 39)
346 (R11_REG 40)
347 (R12_REG 41)
348 (R13_REG 42)
349 (XMM8_REG 45)
350 (XMM9_REG 46)
351 (XMM10_REG 47)
352 (XMM11_REG 48)
353 (XMM12_REG 49)
354 (XMM13_REG 50)
355 (XMM14_REG 51)
356 (XMM15_REG 52)
357 ])
358
359 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
360 ;; from i386.c.
361
362 ;; In C guard expressions, put expressions which may be compile-time
363 ;; constants first. This allows for better optimization. For
364 ;; example, write "TARGET_64BIT && reload_completed", not
365 ;; "reload_completed && TARGET_64BIT".
366
367 \f
368 ;; Processor type.
369 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
370 atom,generic64,amdfam10,bdver1,btver1"
371 (const (symbol_ref "ix86_schedule")))
372
373 ;; A basic instruction type. Refinements due to arguments to be
374 ;; provided in other attributes.
375 (define_attr "type"
376 "other,multi,
377 alu,alu1,negnot,imov,imovx,lea,
378 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
379 icmp,test,ibr,setcc,icmov,
380 push,pop,call,callv,leave,
381 str,bitmanip,
382 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
383 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
384 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
385 ssemuladd,sse4arg,lwp,
386 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
387 (const_string "other"))
388
389 ;; Main data type used by the insn
390 (define_attr "mode"
391 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
392 (const_string "unknown"))
393
394 ;; The CPU unit operations uses.
395 (define_attr "unit" "integer,i387,sse,mmx,unknown"
396 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
397 (const_string "i387")
398 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
399 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
400 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
401 (const_string "sse")
402 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
403 (const_string "mmx")
404 (eq_attr "type" "other")
405 (const_string "unknown")]
406 (const_string "integer")))
407
408 ;; The (bounding maximum) length of an instruction immediate.
409 (define_attr "length_immediate" ""
410 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
411 bitmanip")
412 (const_int 0)
413 (eq_attr "unit" "i387,sse,mmx")
414 (const_int 0)
415 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
416 imul,icmp,push,pop")
417 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
418 (eq_attr "type" "imov,test")
419 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
420 (eq_attr "type" "call")
421 (if_then_else (match_operand 0 "constant_call_address_operand" "")
422 (const_int 4)
423 (const_int 0))
424 (eq_attr "type" "callv")
425 (if_then_else (match_operand 1 "constant_call_address_operand" "")
426 (const_int 4)
427 (const_int 0))
428 ;; We don't know the size before shorten_branches. Expect
429 ;; the instruction to fit for better scheduling.
430 (eq_attr "type" "ibr")
431 (const_int 1)
432 ]
433 (symbol_ref "/* Update immediate_length and other attributes! */
434 gcc_unreachable (),1")))
435
436 ;; The (bounding maximum) length of an instruction address.
437 (define_attr "length_address" ""
438 (cond [(eq_attr "type" "str,other,multi,fxch")
439 (const_int 0)
440 (and (eq_attr "type" "call")
441 (match_operand 0 "constant_call_address_operand" ""))
442 (const_int 0)
443 (and (eq_attr "type" "callv")
444 (match_operand 1 "constant_call_address_operand" ""))
445 (const_int 0)
446 ]
447 (symbol_ref "ix86_attr_length_address_default (insn)")))
448
449 ;; Set when length prefix is used.
450 (define_attr "prefix_data16" ""
451 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
452 (const_int 0)
453 (eq_attr "mode" "HI")
454 (const_int 1)
455 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
456 (const_int 1)
457 ]
458 (const_int 0)))
459
460 ;; Set when string REP prefix is used.
461 (define_attr "prefix_rep" ""
462 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
463 (const_int 0)
464 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
465 (const_int 1)
466 ]
467 (const_int 0)))
468
469 ;; Set when 0f opcode prefix is used.
470 (define_attr "prefix_0f" ""
471 (if_then_else
472 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
473 (eq_attr "unit" "sse,mmx"))
474 (const_int 1)
475 (const_int 0)))
476
477 ;; Set when REX opcode prefix is used.
478 (define_attr "prefix_rex" ""
479 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
480 (const_int 0)
481 (and (eq_attr "mode" "DI")
482 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
483 (eq_attr "unit" "!mmx")))
484 (const_int 1)
485 (and (eq_attr "mode" "QI")
486 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
487 (const_int 0)))
488 (const_int 1)
489 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
490 (const_int 0))
491 (const_int 1)
492 (and (eq_attr "type" "imovx")
493 (match_operand:QI 1 "ext_QIreg_operand" ""))
494 (const_int 1)
495 ]
496 (const_int 0)))
497
498 ;; There are also additional prefixes in 3DNOW, SSSE3.
499 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
500 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
501 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
502 (define_attr "prefix_extra" ""
503 (cond [(eq_attr "type" "ssemuladd,sse4arg")
504 (const_int 2)
505 (eq_attr "type" "sseiadd1,ssecvt1")
506 (const_int 1)
507 ]
508 (const_int 0)))
509
510 ;; Prefix used: original, VEX or maybe VEX.
511 (define_attr "prefix" "orig,vex,maybe_vex"
512 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
513 (const_string "vex")
514 (const_string "orig")))
515
516 ;; VEX W bit is used.
517 (define_attr "prefix_vex_w" "" (const_int 0))
518
519 ;; The length of VEX prefix
520 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
521 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
522 ;; still prefix_0f 1, with prefix_extra 1.
523 (define_attr "length_vex" ""
524 (if_then_else (and (eq_attr "prefix_0f" "1")
525 (eq_attr "prefix_extra" "0"))
526 (if_then_else (eq_attr "prefix_vex_w" "1")
527 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
528 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
529 (if_then_else (eq_attr "prefix_vex_w" "1")
530 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
531 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
532
533 ;; Set when modrm byte is used.
534 (define_attr "modrm" ""
535 (cond [(eq_attr "type" "str,leave")
536 (const_int 0)
537 (eq_attr "unit" "i387")
538 (const_int 0)
539 (and (eq_attr "type" "incdec")
540 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
541 (ior (match_operand:SI 1 "register_operand" "")
542 (match_operand:HI 1 "register_operand" ""))))
543 (const_int 0)
544 (and (eq_attr "type" "push")
545 (not (match_operand 1 "memory_operand" "")))
546 (const_int 0)
547 (and (eq_attr "type" "pop")
548 (not (match_operand 0 "memory_operand" "")))
549 (const_int 0)
550 (and (eq_attr "type" "imov")
551 (and (not (eq_attr "mode" "DI"))
552 (ior (and (match_operand 0 "register_operand" "")
553 (match_operand 1 "immediate_operand" ""))
554 (ior (and (match_operand 0 "ax_reg_operand" "")
555 (match_operand 1 "memory_displacement_only_operand" ""))
556 (and (match_operand 0 "memory_displacement_only_operand" "")
557 (match_operand 1 "ax_reg_operand" ""))))))
558 (const_int 0)
559 (and (eq_attr "type" "call")
560 (match_operand 0 "constant_call_address_operand" ""))
561 (const_int 0)
562 (and (eq_attr "type" "callv")
563 (match_operand 1 "constant_call_address_operand" ""))
564 (const_int 0)
565 (and (eq_attr "type" "alu,alu1,icmp,test")
566 (match_operand 0 "ax_reg_operand" ""))
567 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
568 ]
569 (const_int 1)))
570
571 ;; The (bounding maximum) length of an instruction in bytes.
572 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
573 ;; Later we may want to split them and compute proper length as for
574 ;; other insns.
575 (define_attr "length" ""
576 (cond [(eq_attr "type" "other,multi,fistp,frndint")
577 (const_int 16)
578 (eq_attr "type" "fcmp")
579 (const_int 4)
580 (eq_attr "unit" "i387")
581 (plus (const_int 2)
582 (plus (attr "prefix_data16")
583 (attr "length_address")))
584 (ior (eq_attr "prefix" "vex")
585 (and (eq_attr "prefix" "maybe_vex")
586 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
587 (plus (attr "length_vex")
588 (plus (attr "length_immediate")
589 (plus (attr "modrm")
590 (attr "length_address"))))]
591 (plus (plus (attr "modrm")
592 (plus (attr "prefix_0f")
593 (plus (attr "prefix_rex")
594 (plus (attr "prefix_extra")
595 (const_int 1)))))
596 (plus (attr "prefix_rep")
597 (plus (attr "prefix_data16")
598 (plus (attr "length_immediate")
599 (attr "length_address")))))))
600
601 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
602 ;; `store' if there is a simple memory reference therein, or `unknown'
603 ;; if the instruction is complex.
604
605 (define_attr "memory" "none,load,store,both,unknown"
606 (cond [(eq_attr "type" "other,multi,str,lwp")
607 (const_string "unknown")
608 (eq_attr "type" "lea,fcmov,fpspc")
609 (const_string "none")
610 (eq_attr "type" "fistp,leave")
611 (const_string "both")
612 (eq_attr "type" "frndint")
613 (const_string "load")
614 (eq_attr "type" "push")
615 (if_then_else (match_operand 1 "memory_operand" "")
616 (const_string "both")
617 (const_string "store"))
618 (eq_attr "type" "pop")
619 (if_then_else (match_operand 0 "memory_operand" "")
620 (const_string "both")
621 (const_string "load"))
622 (eq_attr "type" "setcc")
623 (if_then_else (match_operand 0 "memory_operand" "")
624 (const_string "store")
625 (const_string "none"))
626 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
627 (if_then_else (ior (match_operand 0 "memory_operand" "")
628 (match_operand 1 "memory_operand" ""))
629 (const_string "load")
630 (const_string "none"))
631 (eq_attr "type" "ibr")
632 (if_then_else (match_operand 0 "memory_operand" "")
633 (const_string "load")
634 (const_string "none"))
635 (eq_attr "type" "call")
636 (if_then_else (match_operand 0 "constant_call_address_operand" "")
637 (const_string "none")
638 (const_string "load"))
639 (eq_attr "type" "callv")
640 (if_then_else (match_operand 1 "constant_call_address_operand" "")
641 (const_string "none")
642 (const_string "load"))
643 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
644 (match_operand 1 "memory_operand" ""))
645 (const_string "both")
646 (and (match_operand 0 "memory_operand" "")
647 (match_operand 1 "memory_operand" ""))
648 (const_string "both")
649 (match_operand 0 "memory_operand" "")
650 (const_string "store")
651 (match_operand 1 "memory_operand" "")
652 (const_string "load")
653 (and (eq_attr "type"
654 "!alu1,negnot,ishift1,
655 imov,imovx,icmp,test,bitmanip,
656 fmov,fcmp,fsgn,
657 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
658 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
659 (match_operand 2 "memory_operand" ""))
660 (const_string "load")
661 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
662 (match_operand 3 "memory_operand" ""))
663 (const_string "load")
664 ]
665 (const_string "none")))
666
667 ;; Indicates if an instruction has both an immediate and a displacement.
668
669 (define_attr "imm_disp" "false,true,unknown"
670 (cond [(eq_attr "type" "other,multi")
671 (const_string "unknown")
672 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
673 (and (match_operand 0 "memory_displacement_operand" "")
674 (match_operand 1 "immediate_operand" "")))
675 (const_string "true")
676 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
677 (and (match_operand 0 "memory_displacement_operand" "")
678 (match_operand 2 "immediate_operand" "")))
679 (const_string "true")
680 ]
681 (const_string "false")))
682
683 ;; Indicates if an FP operation has an integer source.
684
685 (define_attr "fp_int_src" "false,true"
686 (const_string "false"))
687
688 ;; Defines rounding mode of an FP operation.
689
690 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
691 (const_string "any"))
692
693 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
694 (define_attr "use_carry" "0,1" (const_string "0"))
695
696 ;; Define attribute to indicate unaligned ssemov insns
697 (define_attr "movu" "0,1" (const_string "0"))
698
699 ;; Used to control the "enabled" attribute on a per-instruction basis.
700 (define_attr "isa" "base,noavx,avx"
701 (const_string "base"))
702
703 (define_attr "enabled" ""
704 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
705 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
706 ]
707 (const_int 1)))
708
709 ;; Describe a user's asm statement.
710 (define_asm_attributes
711 [(set_attr "length" "128")
712 (set_attr "type" "multi")])
713
714 (define_code_iterator plusminus [plus minus])
715
716 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
717
718 ;; Base name for define_insn
719 (define_code_attr plusminus_insn
720 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
721 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
722
723 ;; Base name for insn mnemonic.
724 (define_code_attr plusminus_mnemonic
725 [(plus "add") (ss_plus "adds") (us_plus "addus")
726 (minus "sub") (ss_minus "subs") (us_minus "subus")])
727 (define_code_attr plusminus_carry_mnemonic
728 [(plus "adc") (minus "sbb")])
729
730 ;; Mark commutative operators as such in constraints.
731 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
732 (minus "") (ss_minus "") (us_minus "")])
733
734 ;; Mapping of signed max and min
735 (define_code_iterator smaxmin [smax smin])
736
737 ;; Mapping of unsigned max and min
738 (define_code_iterator umaxmin [umax umin])
739
740 ;; Base name for integer and FP insn mnemonic
741 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
742 (umax "maxu") (umin "minu")])
743 (define_code_attr maxmin_float [(smax "max") (smin "min")])
744
745 ;; Mapping of logic operators
746 (define_code_iterator any_logic [and ior xor])
747 (define_code_iterator any_or [ior xor])
748
749 ;; Base name for insn mnemonic.
750 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
751
752 ;; Mapping of shift-right operators
753 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
754
755 ;; Base name for define_insn
756 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
757
758 ;; Base name for insn mnemonic.
759 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
760
761 ;; Mapping of rotate operators
762 (define_code_iterator any_rotate [rotate rotatert])
763
764 ;; Base name for define_insn
765 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
766
767 ;; Base name for insn mnemonic.
768 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
769
770 ;; Mapping of abs neg operators
771 (define_code_iterator absneg [abs neg])
772
773 ;; Base name for x87 insn mnemonic.
774 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
775
776 ;; Used in signed and unsigned widening multiplications.
777 (define_code_iterator any_extend [sign_extend zero_extend])
778
779 ;; Various insn prefixes for signed and unsigned operations.
780 (define_code_attr u [(sign_extend "") (zero_extend "u")
781 (div "") (udiv "u")])
782 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
783
784 ;; Used in signed and unsigned divisions.
785 (define_code_iterator any_div [div udiv])
786
787 ;; Instruction prefix for signed and unsigned operations.
788 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
789 (div "i") (udiv "")])
790
791 ;; 64bit single word integer modes.
792 (define_mode_iterator SWI1248x [QI HI SI DI])
793
794 ;; 64bit single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48x [SI DI])
796
797 ;; Single word integer modes.
798 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
799
800 ;; Single word integer modes without SImode and DImode.
801 (define_mode_iterator SWI12 [QI HI])
802
803 ;; Single word integer modes without DImode.
804 (define_mode_iterator SWI124 [QI HI SI])
805
806 ;; Single word integer modes without QImode and DImode.
807 (define_mode_iterator SWI24 [HI SI])
808
809 ;; Single word integer modes without QImode.
810 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
811
812 ;; Single word integer modes without QImode and HImode.
813 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
814
815 ;; All math-dependant single and double word integer modes.
816 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
817 (HI "TARGET_HIMODE_MATH")
818 SI DI (TI "TARGET_64BIT")])
819
820 ;; Math-dependant single word integer modes.
821 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI (DI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes without DImode.
826 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
828 SI])
829
830 ;; Math-dependant single word integer modes without QImode.
831 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
832 SI (DI "TARGET_64BIT")])
833
834 ;; Double word integer modes.
835 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
836 (TI "TARGET_64BIT")])
837
838 ;; Double word integer modes as mode attribute.
839 (define_mode_attr DWI [(SI "DI") (DI "TI")])
840 (define_mode_attr dwi [(SI "di") (DI "ti")])
841
842 ;; Half mode for double word integer modes.
843 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
844 (DI "TARGET_64BIT")])
845
846 ;; Instruction suffix for integer modes.
847 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
848
849 ;; Pointer size prefix for integer modes (Intel asm dialect)
850 (define_mode_attr iptrsize [(QI "BYTE")
851 (HI "WORD")
852 (SI "DWORD")
853 (DI "QWORD")])
854
855 ;; Register class for integer modes.
856 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
857
858 ;; Immediate operand constraint for integer modes.
859 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
860
861 ;; General operand constraint for word modes.
862 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
863
864 ;; Immediate operand constraint for double integer modes.
865 (define_mode_attr di [(SI "iF") (DI "e")])
866
867 ;; Immediate operand constraint for shifts.
868 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
869
870 ;; General operand predicate for integer modes.
871 (define_mode_attr general_operand
872 [(QI "general_operand")
873 (HI "general_operand")
874 (SI "general_operand")
875 (DI "x86_64_general_operand")
876 (TI "x86_64_general_operand")])
877
878 ;; General sign/zero extend operand predicate for integer modes.
879 (define_mode_attr general_szext_operand
880 [(QI "general_operand")
881 (HI "general_operand")
882 (SI "general_operand")
883 (DI "x86_64_szext_general_operand")])
884
885 ;; Immediate operand predicate for integer modes.
886 (define_mode_attr immediate_operand
887 [(QI "immediate_operand")
888 (HI "immediate_operand")
889 (SI "immediate_operand")
890 (DI "x86_64_immediate_operand")])
891
892 ;; Nonmemory operand predicate for integer modes.
893 (define_mode_attr nonmemory_operand
894 [(QI "nonmemory_operand")
895 (HI "nonmemory_operand")
896 (SI "nonmemory_operand")
897 (DI "x86_64_nonmemory_operand")])
898
899 ;; Operand predicate for shifts.
900 (define_mode_attr shift_operand
901 [(QI "nonimmediate_operand")
902 (HI "nonimmediate_operand")
903 (SI "nonimmediate_operand")
904 (DI "shiftdi_operand")
905 (TI "register_operand")])
906
907 ;; Operand predicate for shift argument.
908 (define_mode_attr shift_immediate_operand
909 [(QI "const_1_to_31_operand")
910 (HI "const_1_to_31_operand")
911 (SI "const_1_to_31_operand")
912 (DI "const_1_to_63_operand")])
913
914 ;; Input operand predicate for arithmetic left shifts.
915 (define_mode_attr ashl_input_operand
916 [(QI "nonimmediate_operand")
917 (HI "nonimmediate_operand")
918 (SI "nonimmediate_operand")
919 (DI "ashldi_input_operand")
920 (TI "reg_or_pm1_operand")])
921
922 ;; SSE and x87 SFmode and DFmode floating point modes
923 (define_mode_iterator MODEF [SF DF])
924
925 ;; All x87 floating point modes
926 (define_mode_iterator X87MODEF [SF DF XF])
927
928 ;; All integer modes handled by x87 fisttp operator.
929 (define_mode_iterator X87MODEI [HI SI DI])
930
931 ;; All integer modes handled by integer x87 operators.
932 (define_mode_iterator X87MODEI12 [HI SI])
933
934 ;; All integer modes handled by SSE cvtts?2si* operators.
935 (define_mode_iterator SSEMODEI24 [SI DI])
936
937 ;; SSE instruction suffix for various modes
938 (define_mode_attr ssemodesuffix
939 [(SF "ss") (DF "sd")
940 (V8SF "ps") (V4DF "pd")
941 (V4SF "ps") (V2DF "pd")
942 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
943 (V8SI "si")])
944
945 ;; SSE vector suffix for floating point modes
946 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
947
948 ;; SSE vector mode corresponding to a scalar mode
949 (define_mode_attr ssevecmode
950 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
951
952 ;; Instruction suffix for REX 64bit operators.
953 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
954
955 ;; This mode iterator allows :P to be used for patterns that operate on
956 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
957 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
958 \f
959 ;; Scheduling descriptions
960
961 (include "pentium.md")
962 (include "ppro.md")
963 (include "k6.md")
964 (include "athlon.md")
965 (include "bdver1.md")
966 (include "geode.md")
967 (include "atom.md")
968 (include "core2.md")
969
970 \f
971 ;; Operand and operator predicates and constraints
972
973 (include "predicates.md")
974 (include "constraints.md")
975
976 \f
977 ;; Compare and branch/compare and store instructions.
978
979 (define_expand "cbranch<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
982 (match_operand:SDWIM 2 "<general_operand>" "")))
983 (set (pc) (if_then_else
984 (match_operator 0 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)])
986 (label_ref (match_operand 3 "" ""))
987 (pc)))]
988 ""
989 {
990 if (MEM_P (operands[1]) && MEM_P (operands[2]))
991 operands[1] = force_reg (<MODE>mode, operands[1]);
992 ix86_expand_branch (GET_CODE (operands[0]),
993 operands[1], operands[2], operands[3]);
994 DONE;
995 })
996
997 (define_expand "cstore<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1000 (match_operand:SWIM 3 "<general_operand>" "")))
1001 (set (match_operand:QI 0 "register_operand" "")
1002 (match_operator 1 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)]))]
1004 ""
1005 {
1006 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007 operands[2] = force_reg (<MODE>mode, operands[2]);
1008 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009 operands[2], operands[3]);
1010 DONE;
1011 })
1012
1013 (define_expand "cmp<mode>_1"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1016 (match_operand:SWI48 1 "<general_operand>" "")))])
1017
1018 (define_insn "*cmp<mode>_ccno_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021 (match_operand:SWI 1 "const0_operand" "")))]
1022 "ix86_match_ccmode (insn, CCNOmode)"
1023 "@
1024 test{<imodesuffix>}\t%0, %0
1025 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "test,icmp")
1027 (set_attr "length_immediate" "0,1")
1028 (set_attr "mode" "<MODE>")])
1029
1030 (define_insn "*cmp<mode>_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034 "ix86_match_ccmode (insn, CCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1038
1039 (define_insn "*cmp<mode>_minus_1"
1040 [(set (reg FLAGS_REG)
1041 (compare
1042 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1044 (const_int 0)))]
1045 "ix86_match_ccmode (insn, CCGOCmode)"
1046 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "<MODE>")])
1049
1050 (define_insn "*cmpqi_ext_1"
1051 [(set (reg FLAGS_REG)
1052 (compare
1053 (match_operand:QI 0 "general_operand" "Qm")
1054 (subreg:QI
1055 (zero_extract:SI
1056 (match_operand 1 "ext_register_operand" "Q")
1057 (const_int 8)
1058 (const_int 8)) 0)))]
1059 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1060 "cmp{b}\t{%h1, %0|%0, %h1}"
1061 [(set_attr "type" "icmp")
1062 (set_attr "mode" "QI")])
1063
1064 (define_insn "*cmpqi_ext_1_rex64"
1065 [(set (reg FLAGS_REG)
1066 (compare
1067 (match_operand:QI 0 "register_operand" "Q")
1068 (subreg:QI
1069 (zero_extract:SI
1070 (match_operand 1 "ext_register_operand" "Q")
1071 (const_int 8)
1072 (const_int 8)) 0)))]
1073 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074 "cmp{b}\t{%h1, %0|%0, %h1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "mode" "QI")])
1077
1078 (define_insn "*cmpqi_ext_2"
1079 [(set (reg FLAGS_REG)
1080 (compare
1081 (subreg:QI
1082 (zero_extract:SI
1083 (match_operand 0 "ext_register_operand" "Q")
1084 (const_int 8)
1085 (const_int 8)) 0)
1086 (match_operand:QI 1 "const0_operand" "")))]
1087 "ix86_match_ccmode (insn, CCNOmode)"
1088 "test{b}\t%h0, %h0"
1089 [(set_attr "type" "test")
1090 (set_attr "length_immediate" "0")
1091 (set_attr "mode" "QI")])
1092
1093 (define_expand "cmpqi_ext_3"
1094 [(set (reg:CC FLAGS_REG)
1095 (compare:CC
1096 (subreg:QI
1097 (zero_extract:SI
1098 (match_operand 0 "ext_register_operand" "")
1099 (const_int 8)
1100 (const_int 8)) 0)
1101 (match_operand:QI 1 "immediate_operand" "")))])
1102
1103 (define_insn "*cmpqi_ext_3_insn"
1104 [(set (reg FLAGS_REG)
1105 (compare
1106 (subreg:QI
1107 (zero_extract:SI
1108 (match_operand 0 "ext_register_operand" "Q")
1109 (const_int 8)
1110 (const_int 8)) 0)
1111 (match_operand:QI 1 "general_operand" "Qmn")))]
1112 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%1, %h0|%h0, %1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "modrm" "1")
1116 (set_attr "mode" "QI")])
1117
1118 (define_insn "*cmpqi_ext_3_insn_rex64"
1119 [(set (reg FLAGS_REG)
1120 (compare
1121 (subreg:QI
1122 (zero_extract:SI
1123 (match_operand 0 "ext_register_operand" "Q")
1124 (const_int 8)
1125 (const_int 8)) 0)
1126 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1127 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1128 "cmp{b}\t{%1, %h0|%h0, %1}"
1129 [(set_attr "type" "icmp")
1130 (set_attr "modrm" "1")
1131 (set_attr "mode" "QI")])
1132
1133 (define_insn "*cmpqi_ext_4"
1134 [(set (reg FLAGS_REG)
1135 (compare
1136 (subreg:QI
1137 (zero_extract:SI
1138 (match_operand 0 "ext_register_operand" "Q")
1139 (const_int 8)
1140 (const_int 8)) 0)
1141 (subreg:QI
1142 (zero_extract:SI
1143 (match_operand 1 "ext_register_operand" "Q")
1144 (const_int 8)
1145 (const_int 8)) 0)))]
1146 "ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "QI")])
1150
1151 ;; These implement float point compares.
1152 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1153 ;; which would allow mix and match FP modes on the compares. Which is what
1154 ;; the old patterns did, but with many more of them.
1155
1156 (define_expand "cbranchxf4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1159 (match_operand:XF 2 "nonmemory_operand" "")))
1160 (set (pc) (if_then_else
1161 (match_operator 0 "ix86_fp_comparison_operator"
1162 [(reg:CC FLAGS_REG)
1163 (const_int 0)])
1164 (label_ref (match_operand 3 "" ""))
1165 (pc)))]
1166 "TARGET_80387"
1167 {
1168 ix86_expand_branch (GET_CODE (operands[0]),
1169 operands[1], operands[2], operands[3]);
1170 DONE;
1171 })
1172
1173 (define_expand "cstorexf4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1176 (match_operand:XF 3 "nonmemory_operand" "")))
1177 (set (match_operand:QI 0 "register_operand" "")
1178 (match_operator 1 "ix86_fp_comparison_operator"
1179 [(reg:CC FLAGS_REG)
1180 (const_int 0)]))]
1181 "TARGET_80387"
1182 {
1183 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184 operands[2], operands[3]);
1185 DONE;
1186 })
1187
1188 (define_expand "cbranch<mode>4"
1189 [(set (reg:CC FLAGS_REG)
1190 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1191 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1192 (set (pc) (if_then_else
1193 (match_operator 0 "ix86_fp_comparison_operator"
1194 [(reg:CC FLAGS_REG)
1195 (const_int 0)])
1196 (label_ref (match_operand 3 "" ""))
1197 (pc)))]
1198 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1199 {
1200 ix86_expand_branch (GET_CODE (operands[0]),
1201 operands[1], operands[2], operands[3]);
1202 DONE;
1203 })
1204
1205 (define_expand "cstore<mode>4"
1206 [(set (reg:CC FLAGS_REG)
1207 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1208 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1209 (set (match_operand:QI 0 "register_operand" "")
1210 (match_operator 1 "ix86_fp_comparison_operator"
1211 [(reg:CC FLAGS_REG)
1212 (const_int 0)]))]
1213 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1214 {
1215 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216 operands[2], operands[3]);
1217 DONE;
1218 })
1219
1220 (define_expand "cbranchcc4"
1221 [(set (pc) (if_then_else
1222 (match_operator 0 "comparison_operator"
1223 [(match_operand 1 "flags_reg_operand" "")
1224 (match_operand 2 "const0_operand" "")])
1225 (label_ref (match_operand 3 "" ""))
1226 (pc)))]
1227 ""
1228 {
1229 ix86_expand_branch (GET_CODE (operands[0]),
1230 operands[1], operands[2], operands[3]);
1231 DONE;
1232 })
1233
1234 (define_expand "cstorecc4"
1235 [(set (match_operand:QI 0 "register_operand" "")
1236 (match_operator 1 "comparison_operator"
1237 [(match_operand 2 "flags_reg_operand" "")
1238 (match_operand 3 "const0_operand" "")]))]
1239 ""
1240 {
1241 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1242 operands[2], operands[3]);
1243 DONE;
1244 })
1245
1246
1247 ;; FP compares, step 1:
1248 ;; Set the FP condition codes.
1249 ;;
1250 ;; CCFPmode compare with exceptions
1251 ;; CCFPUmode compare with no exceptions
1252
1253 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1254 ;; used to manage the reg stack popping would not be preserved.
1255
1256 (define_insn "*cmpfp_0"
1257 [(set (match_operand:HI 0 "register_operand" "=a")
1258 (unspec:HI
1259 [(compare:CCFP
1260 (match_operand 1 "register_operand" "f")
1261 (match_operand 2 "const0_operand" ""))]
1262 UNSPEC_FNSTSW))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265 "* return output_fp_compare (insn, operands, 0, 0);"
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1268 (set (attr "mode")
1269 (cond [(match_operand:SF 1 "" "")
1270 (const_string "SF")
1271 (match_operand:DF 1 "" "")
1272 (const_string "DF")
1273 ]
1274 (const_string "XF")))])
1275
1276 (define_insn_and_split "*cmpfp_0_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1278 (compare:CCFP
1279 (match_operand 1 "register_operand" "f")
1280 (match_operand 2 "const0_operand" "")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283 && TARGET_SAHF && !TARGET_CMOVE
1284 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1285 "#"
1286 "&& reload_completed"
1287 [(set (match_dup 0)
1288 (unspec:HI
1289 [(compare:CCFP (match_dup 1)(match_dup 2))]
1290 UNSPEC_FNSTSW))
1291 (set (reg:CC FLAGS_REG)
1292 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293 ""
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1296 (set (attr "mode")
1297 (cond [(match_operand:SF 1 "" "")
1298 (const_string "SF")
1299 (match_operand:DF 1 "" "")
1300 (const_string "DF")
1301 ]
1302 (const_string "XF")))])
1303
1304 (define_insn "*cmpfp_xf"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1306 (unspec:HI
1307 [(compare:CCFP
1308 (match_operand:XF 1 "register_operand" "f")
1309 (match_operand:XF 2 "register_operand" "f"))]
1310 UNSPEC_FNSTSW))]
1311 "TARGET_80387"
1312 "* return output_fp_compare (insn, operands, 0, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "XF")])
1316
1317 (define_insn_and_split "*cmpfp_xf_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1319 (compare:CCFP
1320 (match_operand:XF 1 "register_operand" "f")
1321 (match_operand:XF 2 "register_operand" "f")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323 "TARGET_80387
1324 && TARGET_SAHF && !TARGET_CMOVE"
1325 "#"
1326 "&& reload_completed"
1327 [(set (match_dup 0)
1328 (unspec:HI
1329 [(compare:CCFP (match_dup 1)(match_dup 2))]
1330 UNSPEC_FNSTSW))
1331 (set (reg:CC FLAGS_REG)
1332 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1333 ""
1334 [(set_attr "type" "multi")
1335 (set_attr "unit" "i387")
1336 (set_attr "mode" "XF")])
1337
1338 (define_insn "*cmpfp_<mode>"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1340 (unspec:HI
1341 [(compare:CCFP
1342 (match_operand:MODEF 1 "register_operand" "f")
1343 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1344 UNSPEC_FNSTSW))]
1345 "TARGET_80387"
1346 "* return output_fp_compare (insn, operands, 0, 0);"
1347 [(set_attr "type" "multi")
1348 (set_attr "unit" "i387")
1349 (set_attr "mode" "<MODE>")])
1350
1351 (define_insn_and_split "*cmpfp_<mode>_cc"
1352 [(set (reg:CCFP FLAGS_REG)
1353 (compare:CCFP
1354 (match_operand:MODEF 1 "register_operand" "f")
1355 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1357 "TARGET_80387
1358 && TARGET_SAHF && !TARGET_CMOVE"
1359 "#"
1360 "&& reload_completed"
1361 [(set (match_dup 0)
1362 (unspec:HI
1363 [(compare:CCFP (match_dup 1)(match_dup 2))]
1364 UNSPEC_FNSTSW))
1365 (set (reg:CC FLAGS_REG)
1366 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1367 ""
1368 [(set_attr "type" "multi")
1369 (set_attr "unit" "i387")
1370 (set_attr "mode" "<MODE>")])
1371
1372 (define_insn "*cmpfp_u"
1373 [(set (match_operand:HI 0 "register_operand" "=a")
1374 (unspec:HI
1375 [(compare:CCFPU
1376 (match_operand 1 "register_operand" "f")
1377 (match_operand 2 "register_operand" "f"))]
1378 UNSPEC_FNSTSW))]
1379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1381 "* return output_fp_compare (insn, operands, 0, 1);"
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1384 (set (attr "mode")
1385 (cond [(match_operand:SF 1 "" "")
1386 (const_string "SF")
1387 (match_operand:DF 1 "" "")
1388 (const_string "DF")
1389 ]
1390 (const_string "XF")))])
1391
1392 (define_insn_and_split "*cmpfp_u_cc"
1393 [(set (reg:CCFPU FLAGS_REG)
1394 (compare:CCFPU
1395 (match_operand 1 "register_operand" "f")
1396 (match_operand 2 "register_operand" "f")))
1397 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399 && TARGET_SAHF && !TARGET_CMOVE
1400 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1401 "#"
1402 "&& reload_completed"
1403 [(set (match_dup 0)
1404 (unspec:HI
1405 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1406 UNSPEC_FNSTSW))
1407 (set (reg:CC FLAGS_REG)
1408 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1409 ""
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1412 (set (attr "mode")
1413 (cond [(match_operand:SF 1 "" "")
1414 (const_string "SF")
1415 (match_operand:DF 1 "" "")
1416 (const_string "DF")
1417 ]
1418 (const_string "XF")))])
1419
1420 (define_insn "*cmpfp_<mode>"
1421 [(set (match_operand:HI 0 "register_operand" "=a")
1422 (unspec:HI
1423 [(compare:CCFP
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1427 UNSPEC_FNSTSW))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1430 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1431 "* return output_fp_compare (insn, operands, 0, 0);"
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "fp_int_src" "true")
1435 (set_attr "mode" "<MODE>")])
1436
1437 (define_insn_and_split "*cmpfp_<mode>_cc"
1438 [(set (reg:CCFP FLAGS_REG)
1439 (compare:CCFP
1440 (match_operand 1 "register_operand" "f")
1441 (match_operator 3 "float_operator"
1442 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1443 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445 && TARGET_SAHF && !TARGET_CMOVE
1446 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1448 "#"
1449 "&& reload_completed"
1450 [(set (match_dup 0)
1451 (unspec:HI
1452 [(compare:CCFP
1453 (match_dup 1)
1454 (match_op_dup 3 [(match_dup 2)]))]
1455 UNSPEC_FNSTSW))
1456 (set (reg:CC FLAGS_REG)
1457 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1458 ""
1459 [(set_attr "type" "multi")
1460 (set_attr "unit" "i387")
1461 (set_attr "fp_int_src" "true")
1462 (set_attr "mode" "<MODE>")])
1463
1464 ;; FP compares, step 2
1465 ;; Move the fpsw to ax.
1466
1467 (define_insn "x86_fnstsw_1"
1468 [(set (match_operand:HI 0 "register_operand" "=a")
1469 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1470 "TARGET_80387"
1471 "fnstsw\t%0"
1472 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1473 (set_attr "mode" "SI")
1474 (set_attr "unit" "i387")])
1475
1476 ;; FP compares, step 3
1477 ;; Get ax into flags, general case.
1478
1479 (define_insn "x86_sahf_1"
1480 [(set (reg:CC FLAGS_REG)
1481 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1482 UNSPEC_SAHF))]
1483 "TARGET_SAHF"
1484 {
1485 #ifndef HAVE_AS_IX86_SAHF
1486 if (TARGET_64BIT)
1487 return ASM_BYTE "0x9e";
1488 else
1489 #endif
1490 return "sahf";
1491 }
1492 [(set_attr "length" "1")
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "direct")
1496 (set_attr "mode" "SI")])
1497
1498 ;; Pentium Pro can do steps 1 through 3 in one go.
1499 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1500 (define_insn "*cmpfp_i_mixed"
1501 [(set (reg:CCFP FLAGS_REG)
1502 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1503 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1504 "TARGET_MIX_SSE_I387
1505 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, 1, 0);"
1508 [(set_attr "type" "fcmp,ssecomi")
1509 (set_attr "prefix" "orig,maybe_vex")
1510 (set (attr "mode")
1511 (if_then_else (match_operand:SF 1 "" "")
1512 (const_string "SF")
1513 (const_string "DF")))
1514 (set (attr "prefix_rep")
1515 (if_then_else (eq_attr "type" "ssecomi")
1516 (const_string "0")
1517 (const_string "*")))
1518 (set (attr "prefix_data16")
1519 (cond [(eq_attr "type" "fcmp")
1520 (const_string "*")
1521 (eq_attr "mode" "DF")
1522 (const_string "1")
1523 ]
1524 (const_string "0")))
1525 (set_attr "athlon_decode" "vector")
1526 (set_attr "amdfam10_decode" "direct")
1527 (set_attr "bdver1_decode" "double")])
1528
1529 (define_insn "*cmpfp_i_sse"
1530 [(set (reg:CCFP FLAGS_REG)
1531 (compare:CCFP (match_operand 0 "register_operand" "x")
1532 (match_operand 1 "nonimmediate_operand" "xm")))]
1533 "TARGET_SSE_MATH
1534 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1535 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1536 "* return output_fp_compare (insn, operands, 1, 0);"
1537 [(set_attr "type" "ssecomi")
1538 (set_attr "prefix" "maybe_vex")
1539 (set (attr "mode")
1540 (if_then_else (match_operand:SF 1 "" "")
1541 (const_string "SF")
1542 (const_string "DF")))
1543 (set_attr "prefix_rep" "0")
1544 (set (attr "prefix_data16")
1545 (if_then_else (eq_attr "mode" "DF")
1546 (const_string "1")
1547 (const_string "0")))
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "direct")
1550 (set_attr "bdver1_decode" "double")])
1551
1552 (define_insn "*cmpfp_i_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1554 (compare:CCFP (match_operand 0 "register_operand" "f")
1555 (match_operand 1 "register_operand" "f")))]
1556 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1557 && TARGET_CMOVE
1558 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, 1, 0);"
1561 [(set_attr "type" "fcmp")
1562 (set (attr "mode")
1563 (cond [(match_operand:SF 1 "" "")
1564 (const_string "SF")
1565 (match_operand:DF 1 "" "")
1566 (const_string "DF")
1567 ]
1568 (const_string "XF")))
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "amdfam10_decode" "direct")
1571 (set_attr "bdver1_decode" "double")])
1572
1573 (define_insn "*cmpfp_iu_mixed"
1574 [(set (reg:CCFPU FLAGS_REG)
1575 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1576 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1577 "TARGET_MIX_SSE_I387
1578 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, 1, 1);"
1581 [(set_attr "type" "fcmp,ssecomi")
1582 (set_attr "prefix" "orig,maybe_vex")
1583 (set (attr "mode")
1584 (if_then_else (match_operand:SF 1 "" "")
1585 (const_string "SF")
1586 (const_string "DF")))
1587 (set (attr "prefix_rep")
1588 (if_then_else (eq_attr "type" "ssecomi")
1589 (const_string "0")
1590 (const_string "*")))
1591 (set (attr "prefix_data16")
1592 (cond [(eq_attr "type" "fcmp")
1593 (const_string "*")
1594 (eq_attr "mode" "DF")
1595 (const_string "1")
1596 ]
1597 (const_string "0")))
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "direct")
1600 (set_attr "bdver1_decode" "double")])
1601
1602 (define_insn "*cmpfp_iu_sse"
1603 [(set (reg:CCFPU FLAGS_REG)
1604 (compare:CCFPU (match_operand 0 "register_operand" "x")
1605 (match_operand 1 "nonimmediate_operand" "xm")))]
1606 "TARGET_SSE_MATH
1607 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1608 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1609 "* return output_fp_compare (insn, operands, 1, 1);"
1610 [(set_attr "type" "ssecomi")
1611 (set_attr "prefix" "maybe_vex")
1612 (set (attr "mode")
1613 (if_then_else (match_operand:SF 1 "" "")
1614 (const_string "SF")
1615 (const_string "DF")))
1616 (set_attr "prefix_rep" "0")
1617 (set (attr "prefix_data16")
1618 (if_then_else (eq_attr "mode" "DF")
1619 (const_string "1")
1620 (const_string "0")))
1621 (set_attr "athlon_decode" "vector")
1622 (set_attr "amdfam10_decode" "direct")
1623 (set_attr "bdver1_decode" "double")])
1624
1625 (define_insn "*cmpfp_iu_387"
1626 [(set (reg:CCFPU FLAGS_REG)
1627 (compare:CCFPU (match_operand 0 "register_operand" "f")
1628 (match_operand 1 "register_operand" "f")))]
1629 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1630 && TARGET_CMOVE
1631 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1632 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633 "* return output_fp_compare (insn, operands, 1, 1);"
1634 [(set_attr "type" "fcmp")
1635 (set (attr "mode")
1636 (cond [(match_operand:SF 1 "" "")
1637 (const_string "SF")
1638 (match_operand:DF 1 "" "")
1639 (const_string "DF")
1640 ]
1641 (const_string "XF")))
1642 (set_attr "athlon_decode" "vector")
1643 (set_attr "amdfam10_decode" "direct")
1644 (set_attr "bdver1_decode" "direct")])
1645 \f
1646 ;; Push/pop instructions.
1647
1648 (define_insn "*push<mode>2"
1649 [(set (match_operand:DWI 0 "push_operand" "=<")
1650 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1651 ""
1652 "#")
1653
1654 (define_split
1655 [(set (match_operand:TI 0 "push_operand" "")
1656 (match_operand:TI 1 "general_operand" ""))]
1657 "TARGET_64BIT && reload_completed
1658 && !SSE_REG_P (operands[1])"
1659 [(const_int 0)]
1660 "ix86_split_long_move (operands); DONE;")
1661
1662 (define_insn "*pushdi2_rex64"
1663 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665 "TARGET_64BIT"
1666 "@
1667 push{q}\t%1
1668 #"
1669 [(set_attr "type" "push,multi")
1670 (set_attr "mode" "DI")])
1671
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it. In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1676 (define_peephole2
1677 [(match_scratch:DI 2 "r")
1678 (set (match_operand:DI 0 "push_operand" "")
1679 (match_operand:DI 1 "immediate_operand" ""))]
1680 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681 && !x86_64_immediate_operand (operands[1], DImode)"
1682 [(set (match_dup 2) (match_dup 1))
1683 (set (match_dup 0) (match_dup 2))])
1684
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1688 (define_peephole2
1689 [(set (match_operand:DI 0 "push_operand" "")
1690 (match_operand:DI 1 "immediate_operand" ""))]
1691 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693 [(set (match_dup 0) (match_dup 1))
1694 (set (match_dup 2) (match_dup 3))]
1695 {
1696 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1697
1698 operands[1] = gen_lowpart (DImode, operands[2]);
1699 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1700 GEN_INT (4)));
1701 })
1702
1703 (define_split
1704 [(set (match_operand:DI 0 "push_operand" "")
1705 (match_operand:DI 1 "immediate_operand" ""))]
1706 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707 ? epilogue_completed : reload_completed)
1708 && !symbolic_operand (operands[1], DImode)
1709 && !x86_64_immediate_operand (operands[1], DImode)"
1710 [(set (match_dup 0) (match_dup 1))
1711 (set (match_dup 2) (match_dup 3))]
1712 {
1713 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1714
1715 operands[1] = gen_lowpart (DImode, operands[2]);
1716 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1717 GEN_INT (4)));
1718 })
1719
1720 (define_split
1721 [(set (match_operand:DI 0 "push_operand" "")
1722 (match_operand:DI 1 "general_operand" ""))]
1723 "!TARGET_64BIT && reload_completed
1724 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1725 [(const_int 0)]
1726 "ix86_split_long_move (operands); DONE;")
1727
1728 (define_insn "*pushsi2"
1729 [(set (match_operand:SI 0 "push_operand" "=<")
1730 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1731 "!TARGET_64BIT"
1732 "push{l}\t%1"
1733 [(set_attr "type" "push")
1734 (set_attr "mode" "SI")])
1735
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word". But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1739
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742 [(set (match_operand:SWI124 0 "push_operand" "=X")
1743 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1744 "TARGET_64BIT"
1745 "push{q}\t%q1"
1746 [(set_attr "type" "push")
1747 (set_attr "mode" "DI")])
1748
1749 (define_insn "*push<mode>2"
1750 [(set (match_operand:SWI12 0 "push_operand" "=X")
1751 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1752 "!TARGET_64BIT"
1753 "push{l}\t%k1"
1754 [(set_attr "type" "push")
1755 (set_attr "mode" "SI")])
1756
1757 (define_insn "*push<mode>2_prologue"
1758 [(set (match_operand:P 0 "push_operand" "=<")
1759 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1760 (clobber (mem:BLK (scratch)))]
1761 ""
1762 "push{<imodesuffix>}\t%1"
1763 [(set_attr "type" "push")
1764 (set_attr "mode" "<MODE>")])
1765
1766 (define_insn "*pop<mode>1"
1767 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768 (match_operand:P 1 "pop_operand" ">"))]
1769 ""
1770 "pop{<imodesuffix>}\t%0"
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "<MODE>")])
1773
1774 (define_insn "*pop<mode>1_epilogue"
1775 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1776 (match_operand:P 1 "pop_operand" ">"))
1777 (clobber (mem:BLK (scratch)))]
1778 ""
1779 "pop{<imodesuffix>}\t%0"
1780 [(set_attr "type" "pop")
1781 (set_attr "mode" "<MODE>")])
1782 \f
1783 ;; Move instructions.
1784
1785 (define_expand "movoi"
1786 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1787 (match_operand:OI 1 "general_operand" ""))]
1788 "TARGET_AVX"
1789 "ix86_expand_move (OImode, operands); DONE;")
1790
1791 (define_expand "movti"
1792 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1793 (match_operand:TI 1 "nonimmediate_operand" ""))]
1794 "TARGET_64BIT || TARGET_SSE"
1795 {
1796 if (TARGET_64BIT)
1797 ix86_expand_move (TImode, operands);
1798 else if (push_operand (operands[0], TImode))
1799 ix86_expand_push (TImode, operands[1]);
1800 else
1801 ix86_expand_vector_move (TImode, operands);
1802 DONE;
1803 })
1804
1805 ;; This expands to what emit_move_complex would generate if we didn't
1806 ;; have a movti pattern. Having this avoids problems with reload on
1807 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1808 ;; to have around all the time.
1809 (define_expand "movcdi"
1810 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1811 (match_operand:CDI 1 "general_operand" ""))]
1812 ""
1813 {
1814 if (push_operand (operands[0], CDImode))
1815 emit_move_complex_push (CDImode, operands[0], operands[1]);
1816 else
1817 emit_move_complex_parts (operands[0], operands[1]);
1818 DONE;
1819 })
1820
1821 (define_expand "mov<mode>"
1822 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1823 (match_operand:SWI1248x 1 "general_operand" ""))]
1824 ""
1825 "ix86_expand_move (<MODE>mode, operands); DONE;")
1826
1827 (define_insn "*mov<mode>_xor"
1828 [(set (match_operand:SWI48 0 "register_operand" "=r")
1829 (match_operand:SWI48 1 "const0_operand" ""))
1830 (clobber (reg:CC FLAGS_REG))]
1831 "reload_completed"
1832 "xor{l}\t%k0, %k0"
1833 [(set_attr "type" "alu1")
1834 (set_attr "mode" "SI")
1835 (set_attr "length_immediate" "0")])
1836
1837 (define_insn "*mov<mode>_or"
1838 [(set (match_operand:SWI48 0 "register_operand" "=r")
1839 (match_operand:SWI48 1 "const_int_operand" ""))
1840 (clobber (reg:CC FLAGS_REG))]
1841 "reload_completed
1842 && operands[1] == constm1_rtx"
1843 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1844 [(set_attr "type" "alu1")
1845 (set_attr "mode" "<MODE>")
1846 (set_attr "length_immediate" "1")])
1847
1848 (define_insn "*movoi_internal_avx"
1849 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1850 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1851 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852 {
1853 switch (which_alternative)
1854 {
1855 case 0:
1856 return "vxorps\t%0, %0, %0";
1857 case 1:
1858 case 2:
1859 if (misaligned_operand (operands[0], OImode)
1860 || misaligned_operand (operands[1], OImode))
1861 return "vmovdqu\t{%1, %0|%0, %1}";
1862 else
1863 return "vmovdqa\t{%1, %0|%0, %1}";
1864 default:
1865 gcc_unreachable ();
1866 }
1867 }
1868 [(set_attr "type" "sselog1,ssemov,ssemov")
1869 (set_attr "prefix" "vex")
1870 (set_attr "mode" "OI")])
1871
1872 (define_insn "*movti_internal_rex64"
1873 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1874 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1875 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1876 {
1877 switch (which_alternative)
1878 {
1879 case 0:
1880 case 1:
1881 return "#";
1882 case 2:
1883 if (get_attr_mode (insn) == MODE_V4SF)
1884 return "%vxorps\t%0, %d0";
1885 else
1886 return "%vpxor\t%0, %d0";
1887 case 3:
1888 case 4:
1889 /* TDmode values are passed as TImode on the stack. Moving them
1890 to stack may result in unaligned memory access. */
1891 if (misaligned_operand (operands[0], TImode)
1892 || misaligned_operand (operands[1], TImode))
1893 {
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovups\t{%1, %0|%0, %1}";
1896 else
1897 return "%vmovdqu\t{%1, %0|%0, %1}";
1898 }
1899 else
1900 {
1901 if (get_attr_mode (insn) == MODE_V4SF)
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1903 else
1904 return "%vmovdqa\t{%1, %0|%0, %1}";
1905 }
1906 default:
1907 gcc_unreachable ();
1908 }
1909 }
1910 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1912 (set (attr "mode")
1913 (cond [(eq_attr "alternative" "2,3")
1914 (if_then_else
1915 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1916 (const_int 0))
1917 (const_string "V4SF")
1918 (const_string "TI"))
1919 (eq_attr "alternative" "4")
1920 (if_then_else
1921 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1922 (const_int 0))
1923 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1924 (const_int 0)))
1925 (const_string "V4SF")
1926 (const_string "TI"))]
1927 (const_string "DI")))])
1928
1929 (define_split
1930 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931 (match_operand:TI 1 "general_operand" ""))]
1932 "reload_completed
1933 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1934 [(const_int 0)]
1935 "ix86_split_long_move (operands); DONE;")
1936
1937 (define_insn "*movti_internal_sse"
1938 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940 "TARGET_SSE && !TARGET_64BIT
1941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 {
1943 switch (which_alternative)
1944 {
1945 case 0:
1946 if (get_attr_mode (insn) == MODE_V4SF)
1947 return "%vxorps\t%0, %d0";
1948 else
1949 return "%vpxor\t%0, %d0";
1950 case 1:
1951 case 2:
1952 /* TDmode values are passed as TImode on the stack. Moving them
1953 to stack may result in unaligned memory access. */
1954 if (misaligned_operand (operands[0], TImode)
1955 || misaligned_operand (operands[1], TImode))
1956 {
1957 if (get_attr_mode (insn) == MODE_V4SF)
1958 return "%vmovups\t{%1, %0|%0, %1}";
1959 else
1960 return "%vmovdqu\t{%1, %0|%0, %1}";
1961 }
1962 else
1963 {
1964 if (get_attr_mode (insn) == MODE_V4SF)
1965 return "%vmovaps\t{%1, %0|%0, %1}";
1966 else
1967 return "%vmovdqa\t{%1, %0|%0, %1}";
1968 }
1969 default:
1970 gcc_unreachable ();
1971 }
1972 }
1973 [(set_attr "type" "sselog1,ssemov,ssemov")
1974 (set_attr "prefix" "maybe_vex")
1975 (set (attr "mode")
1976 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1977 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1978 (const_int 0)))
1979 (const_string "V4SF")
1980 (and (eq_attr "alternative" "2")
1981 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1982 (const_int 0)))
1983 (const_string "V4SF")]
1984 (const_string "TI")))])
1985
1986 (define_insn "*movdi_internal_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 {
1993 switch (get_attr_type (insn))
1994 {
1995 case TYPE_SSECVT:
1996 if (SSE_REG_P (operands[0]))
1997 return "movq2dq\t{%1, %0|%0, %1}";
1998 else
1999 return "movdq2q\t{%1, %0|%0, %1}";
2000
2001 case TYPE_SSEMOV:
2002 if (get_attr_mode (insn) == MODE_TI)
2003 return "%vmovdqa\t{%1, %0|%0, %1}";
2004 /* Handle broken assemblers that reqire movd instead of movq. */
2005 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006 return "%vmovd\t{%1, %0|%0, %1}";
2007 return "%vmovq\t{%1, %0|%0, %1}";
2008
2009 case TYPE_MMXMOV:
2010 /* Handle broken assemblers that reqire movd instead of movq. */
2011 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2012 return "movd\t{%1, %0|%0, %1}";
2013 return "movq\t{%1, %0|%0, %1}";
2014
2015 case TYPE_SSELOG1:
2016 return "%vpxor\t%0, %d0";
2017
2018 case TYPE_MMX:
2019 return "pxor\t%0, %0";
2020
2021 case TYPE_MULTI:
2022 return "#";
2023
2024 case TYPE_LEA:
2025 return "lea{q}\t{%a1, %0|%0, %a1}";
2026
2027 default:
2028 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2029 if (get_attr_mode (insn) == MODE_SI)
2030 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2031 else if (which_alternative == 2)
2032 return "movabs{q}\t{%1, %0|%0, %1}";
2033 else
2034 return "mov{q}\t{%1, %0|%0, %1}";
2035 }
2036 }
2037 [(set (attr "type")
2038 (cond [(eq_attr "alternative" "5")
2039 (const_string "mmx")
2040 (eq_attr "alternative" "6,7,8,9,10")
2041 (const_string "mmxmov")
2042 (eq_attr "alternative" "11")
2043 (const_string "sselog1")
2044 (eq_attr "alternative" "12,13,14,15,16")
2045 (const_string "ssemov")
2046 (eq_attr "alternative" "17,18")
2047 (const_string "ssecvt")
2048 (eq_attr "alternative" "4")
2049 (const_string "multi")
2050 (match_operand:DI 1 "pic_32bit_operand" "")
2051 (const_string "lea")
2052 ]
2053 (const_string "imov")))
2054 (set (attr "modrm")
2055 (if_then_else
2056 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2057 (const_string "0")
2058 (const_string "*")))
2059 (set (attr "length_immediate")
2060 (if_then_else
2061 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2062 (const_string "8")
2063 (const_string "*")))
2064 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2065 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2066 (set (attr "prefix")
2067 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2068 (const_string "maybe_vex")
2069 (const_string "orig")))
2070 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2071
2072 ;; Convert impossible stores of immediate to existing instructions.
2073 ;; First try to get scratch register and go through it. In case this
2074 ;; fails, move by 32bit parts.
2075 (define_peephole2
2076 [(match_scratch:DI 2 "r")
2077 (set (match_operand:DI 0 "memory_operand" "")
2078 (match_operand:DI 1 "immediate_operand" ""))]
2079 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2080 && !x86_64_immediate_operand (operands[1], DImode)"
2081 [(set (match_dup 2) (match_dup 1))
2082 (set (match_dup 0) (match_dup 2))])
2083
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 (define_peephole2
2088 [(set (match_operand:DI 0 "memory_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092 [(set (match_dup 2) (match_dup 3))
2093 (set (match_dup 4) (match_dup 5))]
2094 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2095
2096 (define_split
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100 ? epilogue_completed : reload_completed)
2101 && !symbolic_operand (operands[1], DImode)
2102 && !x86_64_immediate_operand (operands[1], DImode)"
2103 [(set (match_dup 2) (match_dup 3))
2104 (set (match_dup 4) (match_dup 5))]
2105 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2106
2107 (define_insn "*movdi_internal"
2108 [(set (match_operand:DI 0 "nonimmediate_operand"
2109 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2110 (match_operand:DI 1 "general_operand"
2111 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2112 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2113 "@
2114 #
2115 #
2116 pxor\t%0, %0
2117 movq\t{%1, %0|%0, %1}
2118 movq\t{%1, %0|%0, %1}
2119 %vpxor\t%0, %d0
2120 %vmovq\t{%1, %0|%0, %1}
2121 %vmovdqa\t{%1, %0|%0, %1}
2122 %vmovq\t{%1, %0|%0, %1}
2123 xorps\t%0, %0
2124 movlps\t{%1, %0|%0, %1}
2125 movaps\t{%1, %0|%0, %1}
2126 movlps\t{%1, %0|%0, %1}"
2127 [(set (attr "isa")
2128 (if_then_else (eq_attr "alternative" "9,10,11,12")
2129 (const_string "noavx")
2130 (const_string "base")))
2131 (set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2132 (set (attr "prefix")
2133 (if_then_else (eq_attr "alternative" "5,6,7,8")
2134 (const_string "maybe_vex")
2135 (const_string "orig")))
2136 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2137
2138 (define_split
2139 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2140 (match_operand:DI 1 "general_operand" ""))]
2141 "!TARGET_64BIT && reload_completed
2142 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2143 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2144 [(const_int 0)]
2145 "ix86_split_long_move (operands); DONE;")
2146
2147 (define_insn "*movsi_internal"
2148 [(set (match_operand:SI 0 "nonimmediate_operand"
2149 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2150 (match_operand:SI 1 "general_operand"
2151 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2152 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2153 {
2154 switch (get_attr_type (insn))
2155 {
2156 case TYPE_SSELOG1:
2157 if (get_attr_mode (insn) == MODE_TI)
2158 return "%vpxor\t%0, %d0";
2159 return "%vxorps\t%0, %d0";
2160
2161 case TYPE_SSEMOV:
2162 switch (get_attr_mode (insn))
2163 {
2164 case MODE_TI:
2165 return "%vmovdqa\t{%1, %0|%0, %1}";
2166 case MODE_V4SF:
2167 return "%vmovaps\t{%1, %0|%0, %1}";
2168 case MODE_SI:
2169 return "%vmovd\t{%1, %0|%0, %1}";
2170 case MODE_SF:
2171 return "%vmovss\t{%1, %0|%0, %1}";
2172 default:
2173 gcc_unreachable ();
2174 }
2175
2176 case TYPE_MMX:
2177 return "pxor\t%0, %0";
2178
2179 case TYPE_MMXMOV:
2180 if (get_attr_mode (insn) == MODE_DI)
2181 return "movq\t{%1, %0|%0, %1}";
2182 return "movd\t{%1, %0|%0, %1}";
2183
2184 case TYPE_LEA:
2185 return "lea{l}\t{%a1, %0|%0, %a1}";
2186
2187 default:
2188 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2189 return "mov{l}\t{%1, %0|%0, %1}";
2190 }
2191 }
2192 [(set (attr "type")
2193 (cond [(eq_attr "alternative" "2")
2194 (const_string "mmx")
2195 (eq_attr "alternative" "3,4,5")
2196 (const_string "mmxmov")
2197 (eq_attr "alternative" "6")
2198 (const_string "sselog1")
2199 (eq_attr "alternative" "7,8,9,10,11")
2200 (const_string "ssemov")
2201 (match_operand:DI 1 "pic_32bit_operand" "")
2202 (const_string "lea")
2203 ]
2204 (const_string "imov")))
2205 (set (attr "prefix")
2206 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2207 (const_string "orig")
2208 (const_string "maybe_vex")))
2209 (set (attr "prefix_data16")
2210 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2211 (const_string "1")
2212 (const_string "*")))
2213 (set (attr "mode")
2214 (cond [(eq_attr "alternative" "2,3")
2215 (const_string "DI")
2216 (eq_attr "alternative" "6,7")
2217 (if_then_else
2218 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2219 (const_string "V4SF")
2220 (const_string "TI"))
2221 (and (eq_attr "alternative" "8,9,10,11")
2222 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2223 (const_string "SF")
2224 ]
2225 (const_string "SI")))])
2226
2227 (define_insn "*movhi_internal"
2228 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2229 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2230 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2231 {
2232 switch (get_attr_type (insn))
2233 {
2234 case TYPE_IMOVX:
2235 /* movzwl is faster than movw on p2 due to partial word stalls,
2236 though not as fast as an aligned movl. */
2237 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2238 default:
2239 if (get_attr_mode (insn) == MODE_SI)
2240 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2241 else
2242 return "mov{w}\t{%1, %0|%0, %1}";
2243 }
2244 }
2245 [(set (attr "type")
2246 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2247 (const_int 0))
2248 (const_string "imov")
2249 (and (eq_attr "alternative" "0")
2250 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2251 (const_int 0))
2252 (eq (symbol_ref "TARGET_HIMODE_MATH")
2253 (const_int 0))))
2254 (const_string "imov")
2255 (and (eq_attr "alternative" "1,2")
2256 (match_operand:HI 1 "aligned_operand" ""))
2257 (const_string "imov")
2258 (and (ne (symbol_ref "TARGET_MOVX")
2259 (const_int 0))
2260 (eq_attr "alternative" "0,2"))
2261 (const_string "imovx")
2262 ]
2263 (const_string "imov")))
2264 (set (attr "mode")
2265 (cond [(eq_attr "type" "imovx")
2266 (const_string "SI")
2267 (and (eq_attr "alternative" "1,2")
2268 (match_operand:HI 1 "aligned_operand" ""))
2269 (const_string "SI")
2270 (and (eq_attr "alternative" "0")
2271 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2272 (const_int 0))
2273 (eq (symbol_ref "TARGET_HIMODE_MATH")
2274 (const_int 0))))
2275 (const_string "SI")
2276 ]
2277 (const_string "HI")))])
2278
2279 ;; Situation is quite tricky about when to choose full sized (SImode) move
2280 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2281 ;; partial register dependency machines (such as AMD Athlon), where QImode
2282 ;; moves issue extra dependency and for partial register stalls machines
2283 ;; that don't use QImode patterns (and QImode move cause stall on the next
2284 ;; instruction).
2285 ;;
2286 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2287 ;; register stall machines with, where we use QImode instructions, since
2288 ;; partial register stall can be caused there. Then we use movzx.
2289 (define_insn "*movqi_internal"
2290 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2291 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2292 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2293 {
2294 switch (get_attr_type (insn))
2295 {
2296 case TYPE_IMOVX:
2297 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2298 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2299 default:
2300 if (get_attr_mode (insn) == MODE_SI)
2301 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2302 else
2303 return "mov{b}\t{%1, %0|%0, %1}";
2304 }
2305 }
2306 [(set (attr "type")
2307 (cond [(and (eq_attr "alternative" "5")
2308 (not (match_operand:QI 1 "aligned_operand" "")))
2309 (const_string "imovx")
2310 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2311 (const_int 0))
2312 (const_string "imov")
2313 (and (eq_attr "alternative" "3")
2314 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2315 (const_int 0))
2316 (eq (symbol_ref "TARGET_QIMODE_MATH")
2317 (const_int 0))))
2318 (const_string "imov")
2319 (eq_attr "alternative" "3,5")
2320 (const_string "imovx")
2321 (and (ne (symbol_ref "TARGET_MOVX")
2322 (const_int 0))
2323 (eq_attr "alternative" "2"))
2324 (const_string "imovx")
2325 ]
2326 (const_string "imov")))
2327 (set (attr "mode")
2328 (cond [(eq_attr "alternative" "3,4,5")
2329 (const_string "SI")
2330 (eq_attr "alternative" "6")
2331 (const_string "QI")
2332 (eq_attr "type" "imovx")
2333 (const_string "SI")
2334 (and (eq_attr "type" "imov")
2335 (and (eq_attr "alternative" "0,1")
2336 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2337 (const_int 0))
2338 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2339 (const_int 0))
2340 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2341 (const_int 0))))))
2342 (const_string "SI")
2343 ;; Avoid partial register stalls when not using QImode arithmetic
2344 (and (eq_attr "type" "imov")
2345 (and (eq_attr "alternative" "0,1")
2346 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2347 (const_int 0))
2348 (eq (symbol_ref "TARGET_QIMODE_MATH")
2349 (const_int 0)))))
2350 (const_string "SI")
2351 ]
2352 (const_string "QI")))])
2353
2354 ;; Stores and loads of ax to arbitrary constant address.
2355 ;; We fake an second form of instruction to force reload to load address
2356 ;; into register when rax is not available
2357 (define_insn "*movabs<mode>_1"
2358 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2359 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2360 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2361 "@
2362 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2363 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2364 [(set_attr "type" "imov")
2365 (set_attr "modrm" "0,*")
2366 (set_attr "length_address" "8,0")
2367 (set_attr "length_immediate" "0,*")
2368 (set_attr "memory" "store")
2369 (set_attr "mode" "<MODE>")])
2370
2371 (define_insn "*movabs<mode>_2"
2372 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2373 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2374 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2375 "@
2376 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2377 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2378 [(set_attr "type" "imov")
2379 (set_attr "modrm" "0,*")
2380 (set_attr "length_address" "8,0")
2381 (set_attr "length_immediate" "0")
2382 (set_attr "memory" "load")
2383 (set_attr "mode" "<MODE>")])
2384
2385 (define_insn "*swap<mode>"
2386 [(set (match_operand:SWI48 0 "register_operand" "+r")
2387 (match_operand:SWI48 1 "register_operand" "+r"))
2388 (set (match_dup 1)
2389 (match_dup 0))]
2390 ""
2391 "xchg{<imodesuffix>}\t%1, %0"
2392 [(set_attr "type" "imov")
2393 (set_attr "mode" "<MODE>")
2394 (set_attr "pent_pair" "np")
2395 (set_attr "athlon_decode" "vector")
2396 (set_attr "amdfam10_decode" "double")
2397 (set_attr "bdver1_decode" "double")])
2398
2399 (define_insn "*swap<mode>_1"
2400 [(set (match_operand:SWI12 0 "register_operand" "+r")
2401 (match_operand:SWI12 1 "register_operand" "+r"))
2402 (set (match_dup 1)
2403 (match_dup 0))]
2404 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2405 "xchg{l}\t%k1, %k0"
2406 [(set_attr "type" "imov")
2407 (set_attr "mode" "SI")
2408 (set_attr "pent_pair" "np")
2409 (set_attr "athlon_decode" "vector")
2410 (set_attr "amdfam10_decode" "double")
2411 (set_attr "bdver1_decode" "double")])
2412
2413 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2414 ;; is disabled for AMDFAM10
2415 (define_insn "*swap<mode>_2"
2416 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2417 (match_operand:SWI12 1 "register_operand" "+<r>"))
2418 (set (match_dup 1)
2419 (match_dup 0))]
2420 "TARGET_PARTIAL_REG_STALL"
2421 "xchg{<imodesuffix>}\t%1, %0"
2422 [(set_attr "type" "imov")
2423 (set_attr "mode" "<MODE>")
2424 (set_attr "pent_pair" "np")
2425 (set_attr "athlon_decode" "vector")])
2426
2427 (define_expand "movstrict<mode>"
2428 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2429 (match_operand:SWI12 1 "general_operand" ""))]
2430 ""
2431 {
2432 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2433 FAIL;
2434 if (GET_CODE (operands[0]) == SUBREG
2435 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2436 FAIL;
2437 /* Don't generate memory->memory moves, go through a register */
2438 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2439 operands[1] = force_reg (<MODE>mode, operands[1]);
2440 })
2441
2442 (define_insn "*movstrict<mode>_1"
2443 [(set (strict_low_part
2444 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2445 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2446 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2448 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2449 [(set_attr "type" "imov")
2450 (set_attr "mode" "<MODE>")])
2451
2452 (define_insn "*movstrict<mode>_xor"
2453 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2454 (match_operand:SWI12 1 "const0_operand" ""))
2455 (clobber (reg:CC FLAGS_REG))]
2456 "reload_completed"
2457 "xor{<imodesuffix>}\t%0, %0"
2458 [(set_attr "type" "alu1")
2459 (set_attr "mode" "<MODE>")
2460 (set_attr "length_immediate" "0")])
2461
2462 (define_insn "*mov<mode>_extv_1"
2463 [(set (match_operand:SWI24 0 "register_operand" "=R")
2464 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2465 (const_int 8)
2466 (const_int 8)))]
2467 ""
2468 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2469 [(set_attr "type" "imovx")
2470 (set_attr "mode" "SI")])
2471
2472 (define_insn "*movqi_extv_1_rex64"
2473 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2474 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2475 (const_int 8)
2476 (const_int 8)))]
2477 "TARGET_64BIT"
2478 {
2479 switch (get_attr_type (insn))
2480 {
2481 case TYPE_IMOVX:
2482 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2483 default:
2484 return "mov{b}\t{%h1, %0|%0, %h1}";
2485 }
2486 }
2487 [(set (attr "type")
2488 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2489 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2490 (ne (symbol_ref "TARGET_MOVX")
2491 (const_int 0))))
2492 (const_string "imovx")
2493 (const_string "imov")))
2494 (set (attr "mode")
2495 (if_then_else (eq_attr "type" "imovx")
2496 (const_string "SI")
2497 (const_string "QI")))])
2498
2499 (define_insn "*movqi_extv_1"
2500 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2501 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2502 (const_int 8)
2503 (const_int 8)))]
2504 "!TARGET_64BIT"
2505 {
2506 switch (get_attr_type (insn))
2507 {
2508 case TYPE_IMOVX:
2509 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2510 default:
2511 return "mov{b}\t{%h1, %0|%0, %h1}";
2512 }
2513 }
2514 [(set (attr "type")
2515 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2516 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2517 (ne (symbol_ref "TARGET_MOVX")
2518 (const_int 0))))
2519 (const_string "imovx")
2520 (const_string "imov")))
2521 (set (attr "mode")
2522 (if_then_else (eq_attr "type" "imovx")
2523 (const_string "SI")
2524 (const_string "QI")))])
2525
2526 (define_insn "*mov<mode>_extzv_1"
2527 [(set (match_operand:SWI48 0 "register_operand" "=R")
2528 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2529 (const_int 8)
2530 (const_int 8)))]
2531 ""
2532 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2533 [(set_attr "type" "imovx")
2534 (set_attr "mode" "SI")])
2535
2536 (define_insn "*movqi_extzv_2_rex64"
2537 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2538 (subreg:QI
2539 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2540 (const_int 8)
2541 (const_int 8)) 0))]
2542 "TARGET_64BIT"
2543 {
2544 switch (get_attr_type (insn))
2545 {
2546 case TYPE_IMOVX:
2547 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2548 default:
2549 return "mov{b}\t{%h1, %0|%0, %h1}";
2550 }
2551 }
2552 [(set (attr "type")
2553 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2554 (ne (symbol_ref "TARGET_MOVX")
2555 (const_int 0)))
2556 (const_string "imovx")
2557 (const_string "imov")))
2558 (set (attr "mode")
2559 (if_then_else (eq_attr "type" "imovx")
2560 (const_string "SI")
2561 (const_string "QI")))])
2562
2563 (define_insn "*movqi_extzv_2"
2564 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2565 (subreg:QI
2566 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2567 (const_int 8)
2568 (const_int 8)) 0))]
2569 "!TARGET_64BIT"
2570 {
2571 switch (get_attr_type (insn))
2572 {
2573 case TYPE_IMOVX:
2574 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2575 default:
2576 return "mov{b}\t{%h1, %0|%0, %h1}";
2577 }
2578 }
2579 [(set (attr "type")
2580 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2581 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2582 (ne (symbol_ref "TARGET_MOVX")
2583 (const_int 0))))
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 (define_split
2643 [(set (match_operand:TF 0 "push_operand" "")
2644 (match_operand:TF 1 "sse_reg_operand" ""))]
2645 "TARGET_SSE2 && reload_completed"
2646 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2647 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2648
2649 (define_split
2650 [(set (match_operand:TF 0 "push_operand" "")
2651 (match_operand:TF 1 "general_operand" ""))]
2652 "TARGET_SSE2 && reload_completed
2653 && !SSE_REG_P (operands[1])"
2654 [(const_int 0)]
2655 "ix86_split_long_move (operands); DONE;")
2656
2657 (define_insn "*pushxf"
2658 [(set (match_operand:XF 0 "push_operand" "=<,<")
2659 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2660 "optimize_function_for_speed_p (cfun)"
2661 {
2662 /* This insn should be already split before reg-stack. */
2663 gcc_unreachable ();
2664 }
2665 [(set_attr "type" "multi")
2666 (set_attr "unit" "i387,*")
2667 (set_attr "mode" "XF,SI")])
2668
2669 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2670 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2671 ;; Pushing using integer instructions is longer except for constants
2672 ;; and direct memory references (assuming that any given constant is pushed
2673 ;; only once, but this ought to be handled elsewhere).
2674
2675 (define_insn "*pushxf_nointeger"
2676 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2677 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2678 "optimize_function_for_size_p (cfun)"
2679 {
2680 /* This insn should be already split before reg-stack. */
2681 gcc_unreachable ();
2682 }
2683 [(set_attr "type" "multi")
2684 (set_attr "unit" "i387,*,*")
2685 (set_attr "mode" "XF,SI,SI")])
2686
2687 (define_split
2688 [(set (match_operand:XF 0 "push_operand" "")
2689 (match_operand:XF 1 "fp_register_operand" ""))]
2690 "reload_completed"
2691 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2692 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2693 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2694
2695 (define_split
2696 [(set (match_operand:XF 0 "push_operand" "")
2697 (match_operand:XF 1 "general_operand" ""))]
2698 "reload_completed
2699 && !FP_REG_P (operands[1])"
2700 [(const_int 0)]
2701 "ix86_split_long_move (operands); DONE;")
2702
2703 (define_insn "*pushdf"
2704 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2705 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2706 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2707 {
2708 /* This insn should be already split before reg-stack. */
2709 gcc_unreachable ();
2710 }
2711 [(set_attr "type" "multi")
2712 (set_attr "unit" "i387,*,*")
2713 (set_attr "mode" "DF,SI,DF")])
2714
2715 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2716 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2717 ;; On the average, pushdf using integers can be still shorter. Allow this
2718 ;; pattern for optimize_size too.
2719
2720 (define_insn "*pushdf_nointeger"
2721 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2722 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2723 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2724 {
2725 /* This insn should be already split before reg-stack. */
2726 gcc_unreachable ();
2727 }
2728 [(set_attr "type" "multi")
2729 (set_attr "unit" "i387,*,*,*")
2730 (set_attr "mode" "DF,SI,SI,DF")])
2731
2732 ;; %%% Kill this when call knows how to work this out.
2733 (define_split
2734 [(set (match_operand:DF 0 "push_operand" "")
2735 (match_operand:DF 1 "any_fp_register_operand" ""))]
2736 "reload_completed"
2737 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2738 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2739
2740 (define_split
2741 [(set (match_operand:DF 0 "push_operand" "")
2742 (match_operand:DF 1 "general_operand" ""))]
2743 "reload_completed
2744 && !ANY_FP_REG_P (operands[1])"
2745 [(const_int 0)]
2746 "ix86_split_long_move (operands); DONE;")
2747
2748 (define_insn "*pushsf_rex64"
2749 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2750 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2751 "TARGET_64BIT"
2752 {
2753 /* Anything else should be already split before reg-stack. */
2754 gcc_assert (which_alternative == 1);
2755 return "push{q}\t%q1";
2756 }
2757 [(set_attr "type" "multi,push,multi")
2758 (set_attr "unit" "i387,*,*")
2759 (set_attr "mode" "SF,DI,SF")])
2760
2761 (define_insn "*pushsf"
2762 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2763 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2764 "!TARGET_64BIT"
2765 {
2766 /* Anything else should be already split before reg-stack. */
2767 gcc_assert (which_alternative == 1);
2768 return "push{l}\t%1";
2769 }
2770 [(set_attr "type" "multi,push,multi")
2771 (set_attr "unit" "i387,*,*")
2772 (set_attr "mode" "SF,SI,SF")])
2773
2774 (define_split
2775 [(set (match_operand:SF 0 "push_operand" "")
2776 (match_operand:SF 1 "memory_operand" ""))]
2777 "reload_completed
2778 && MEM_P (operands[1])
2779 && (operands[2] = find_constant_src (insn))"
2780 [(set (match_dup 0)
2781 (match_dup 2))])
2782
2783 ;; %%% Kill this when call knows how to work this out.
2784 (define_split
2785 [(set (match_operand:SF 0 "push_operand" "")
2786 (match_operand:SF 1 "any_fp_register_operand" ""))]
2787 "reload_completed"
2788 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2789 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2790 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2791 \f
2792 ;; Floating point move instructions.
2793
2794 (define_expand "movtf"
2795 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2796 (match_operand:TF 1 "nonimmediate_operand" ""))]
2797 "TARGET_SSE2"
2798 {
2799 ix86_expand_move (TFmode, operands);
2800 DONE;
2801 })
2802
2803 (define_expand "mov<mode>"
2804 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2805 (match_operand:X87MODEF 1 "general_operand" ""))]
2806 ""
2807 "ix86_expand_move (<MODE>mode, operands); DONE;")
2808
2809 (define_insn "*movtf_internal"
2810 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2811 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2812 "TARGET_SSE2
2813 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2814 {
2815 switch (which_alternative)
2816 {
2817 case 0:
2818 case 1:
2819 if (get_attr_mode (insn) == MODE_V4SF)
2820 return "%vmovaps\t{%1, %0|%0, %1}";
2821 else
2822 return "%vmovdqa\t{%1, %0|%0, %1}";
2823 case 2:
2824 if (get_attr_mode (insn) == MODE_V4SF)
2825 return "%vxorps\t%0, %d0";
2826 else
2827 return "%vpxor\t%0, %d0";
2828 case 3:
2829 case 4:
2830 return "#";
2831 default:
2832 gcc_unreachable ();
2833 }
2834 }
2835 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2836 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2837 (set (attr "mode")
2838 (cond [(eq_attr "alternative" "0,2")
2839 (if_then_else
2840 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2841 (const_int 0))
2842 (const_string "V4SF")
2843 (const_string "TI"))
2844 (eq_attr "alternative" "1")
2845 (if_then_else
2846 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2847 (const_int 0))
2848 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2849 (const_int 0)))
2850 (const_string "V4SF")
2851 (const_string "TI"))]
2852 (const_string "DI")))])
2853
2854 (define_split
2855 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2856 (match_operand:TF 1 "general_operand" ""))]
2857 "reload_completed
2858 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2859 [(const_int 0)]
2860 "ix86_split_long_move (operands); DONE;")
2861
2862 (define_insn "*movxf_internal"
2863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2864 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2865 "optimize_function_for_speed_p (cfun)
2866 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2867 && (reload_in_progress || reload_completed
2868 || GET_CODE (operands[1]) != CONST_DOUBLE
2869 || memory_operand (operands[0], XFmode))"
2870 {
2871 switch (which_alternative)
2872 {
2873 case 0:
2874 case 1:
2875 return output_387_reg_move (insn, operands);
2876
2877 case 2:
2878 return standard_80387_constant_opcode (operands[1]);
2879
2880 case 3: case 4:
2881 return "#";
2882
2883 default:
2884 gcc_unreachable ();
2885 }
2886 }
2887 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2888 (set_attr "mode" "XF,XF,XF,SI,SI")])
2889
2890 ;; Do not use integer registers when optimizing for size
2891 (define_insn "*movxf_internal_nointeger"
2892 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2893 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2894 "optimize_function_for_size_p (cfun)
2895 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2896 && (reload_in_progress || reload_completed
2897 || standard_80387_constant_p (operands[1])
2898 || GET_CODE (operands[1]) != CONST_DOUBLE
2899 || memory_operand (operands[0], XFmode))"
2900 {
2901 switch (which_alternative)
2902 {
2903 case 0:
2904 case 1:
2905 return output_387_reg_move (insn, operands);
2906
2907 case 2:
2908 return standard_80387_constant_opcode (operands[1]);
2909
2910 case 3: case 4:
2911 return "#";
2912 default:
2913 gcc_unreachable ();
2914 }
2915 }
2916 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2917 (set_attr "mode" "XF,XF,XF,SI,SI")])
2918
2919 (define_split
2920 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2921 (match_operand:XF 1 "general_operand" ""))]
2922 "reload_completed
2923 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2924 && ! (FP_REG_P (operands[0]) ||
2925 (GET_CODE (operands[0]) == SUBREG
2926 && FP_REG_P (SUBREG_REG (operands[0]))))
2927 && ! (FP_REG_P (operands[1]) ||
2928 (GET_CODE (operands[1]) == SUBREG
2929 && FP_REG_P (SUBREG_REG (operands[1]))))"
2930 [(const_int 0)]
2931 "ix86_split_long_move (operands); DONE;")
2932
2933 (define_insn "*movdf_internal_rex64"
2934 [(set (match_operand:DF 0 "nonimmediate_operand"
2935 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2936 (match_operand:DF 1 "general_operand"
2937 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2938 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2939 && (reload_in_progress || reload_completed
2940 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2941 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2942 && optimize_function_for_size_p (cfun)
2943 && standard_80387_constant_p (operands[1]))
2944 || GET_CODE (operands[1]) != CONST_DOUBLE
2945 || memory_operand (operands[0], DFmode))"
2946 {
2947 switch (which_alternative)
2948 {
2949 case 0:
2950 case 1:
2951 return output_387_reg_move (insn, operands);
2952
2953 case 2:
2954 return standard_80387_constant_opcode (operands[1]);
2955
2956 case 3:
2957 case 4:
2958 return "mov{q}\t{%1, %0|%0, %1}";
2959
2960 case 5:
2961 return "movabs{q}\t{%1, %0|%0, %1}";
2962
2963 case 6:
2964 return "#";
2965
2966 case 7:
2967 switch (get_attr_mode (insn))
2968 {
2969 case MODE_V4SF:
2970 return "%vxorps\t%0, %d0";
2971 case MODE_V2DF:
2972 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2973 return "%vxorps\t%0, %d0";
2974 else
2975 return "%vxorpd\t%0, %d0";
2976 case MODE_TI:
2977 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2978 return "%vxorps\t%0, %d0";
2979 else
2980 return "%vpxor\t%0, %d0";
2981 default:
2982 gcc_unreachable ();
2983 }
2984 case 8:
2985 case 9:
2986 case 10:
2987 switch (get_attr_mode (insn))
2988 {
2989 case MODE_V4SF:
2990 return "%vmovaps\t{%1, %0|%0, %1}";
2991 case MODE_V2DF:
2992 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2993 return "%vmovaps\t{%1, %0|%0, %1}";
2994 else
2995 return "%vmovapd\t{%1, %0|%0, %1}";
2996 case MODE_TI:
2997 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2998 return "%vmovaps\t{%1, %0|%0, %1}";
2999 else
3000 return "%vmovdqa\t{%1, %0|%0, %1}";
3001 case MODE_DI:
3002 return "%vmovq\t{%1, %0|%0, %1}";
3003 case MODE_DF:
3004 if (TARGET_AVX)
3005 {
3006 if (REG_P (operands[0]) && REG_P (operands[1]))
3007 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3008 else
3009 return "vmovsd\t{%1, %0|%0, %1}";
3010 }
3011 else
3012 return "movsd\t{%1, %0|%0, %1}";
3013 case MODE_V1DF:
3014 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3015 case MODE_V2SF:
3016 return "%vmovlps\t{%1, %d0|%d0, %1}";
3017 default:
3018 gcc_unreachable ();
3019 }
3020
3021 case 11:
3022 case 12:
3023 /* Handle broken assemblers that reqire movd instead of movq. */
3024 return "%vmovd\t{%1, %0|%0, %1}";
3025
3026 default:
3027 gcc_unreachable();
3028 }
3029 }
3030 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3031 (set (attr "modrm")
3032 (if_then_else
3033 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3034 (const_string "0")
3035 (const_string "*")))
3036 (set (attr "length_immediate")
3037 (if_then_else
3038 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3039 (const_string "8")
3040 (const_string "*")))
3041 (set (attr "prefix")
3042 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3043 (const_string "orig")
3044 (const_string "maybe_vex")))
3045 (set (attr "prefix_data16")
3046 (if_then_else (eq_attr "mode" "V1DF")
3047 (const_string "1")
3048 (const_string "*")))
3049 (set (attr "mode")
3050 (cond [(eq_attr "alternative" "0,1,2")
3051 (const_string "DF")
3052 (eq_attr "alternative" "3,4,5,6,11,12")
3053 (const_string "DI")
3054
3055 /* For SSE1, we have many fewer alternatives. */
3056 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3057 (cond [(eq_attr "alternative" "7,8")
3058 (const_string "V4SF")
3059 ]
3060 (const_string "V2SF"))
3061
3062 /* xorps is one byte shorter. */
3063 (eq_attr "alternative" "7")
3064 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3065 (const_int 0))
3066 (const_string "V4SF")
3067 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3068 (const_int 0))
3069 (const_string "TI")
3070 ]
3071 (const_string "V2DF"))
3072
3073 /* For architectures resolving dependencies on
3074 whole SSE registers use APD move to break dependency
3075 chains, otherwise use short move to avoid extra work.
3076
3077 movaps encodes one byte shorter. */
3078 (eq_attr "alternative" "8")
3079 (cond
3080 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3081 (const_int 0))
3082 (const_string "V4SF")
3083 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3084 (const_int 0))
3085 (const_string "V2DF")
3086 ]
3087 (const_string "DF"))
3088 /* For architectures resolving dependencies on register
3089 parts we may avoid extra work to zero out upper part
3090 of register. */
3091 (eq_attr "alternative" "9")
3092 (if_then_else
3093 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3094 (const_int 0))
3095 (const_string "V1DF")
3096 (const_string "DF"))
3097 ]
3098 (const_string "DF")))])
3099
3100 (define_insn "*movdf_internal"
3101 [(set (match_operand:DF 0 "nonimmediate_operand"
3102 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3103 (match_operand:DF 1 "general_operand"
3104 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3105 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3106 && optimize_function_for_speed_p (cfun)
3107 && TARGET_INTEGER_DFMODE_MOVES
3108 && (reload_in_progress || reload_completed
3109 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3110 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3111 && optimize_function_for_size_p (cfun)
3112 && standard_80387_constant_p (operands[1]))
3113 || GET_CODE (operands[1]) != CONST_DOUBLE
3114 || memory_operand (operands[0], DFmode))"
3115 {
3116 switch (which_alternative)
3117 {
3118 case 0:
3119 case 1:
3120 return output_387_reg_move (insn, operands);
3121
3122 case 2:
3123 return standard_80387_constant_opcode (operands[1]);
3124
3125 case 3:
3126 case 4:
3127 return "#";
3128
3129 case 5:
3130 switch (get_attr_mode (insn))
3131 {
3132 case MODE_V4SF:
3133 return "%vxorps\t%0, %d0";
3134 case MODE_V2DF:
3135 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3136 return "%vxorps\t%0, %d0";
3137 else
3138 return "%vxorpd\t%0, %d0";
3139 case MODE_TI:
3140 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3141 return "%vxorps\t%0, %d0";
3142 else
3143 return "%vpxor\t%0, %d0";
3144 default:
3145 gcc_unreachable ();
3146 }
3147 case 6:
3148 case 7:
3149 case 8:
3150 switch (get_attr_mode (insn))
3151 {
3152 case MODE_V4SF:
3153 return "%vmovaps\t{%1, %0|%0, %1}";
3154 case MODE_V2DF:
3155 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3156 return "%vmovaps\t{%1, %0|%0, %1}";
3157 else
3158 return "%vmovapd\t{%1, %0|%0, %1}";
3159 case MODE_TI:
3160 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3161 return "%vmovaps\t{%1, %0|%0, %1}";
3162 else
3163 return "%vmovdqa\t{%1, %0|%0, %1}";
3164 case MODE_DI:
3165 return "%vmovq\t{%1, %0|%0, %1}";
3166 case MODE_DF:
3167 if (TARGET_AVX)
3168 {
3169 if (REG_P (operands[0]) && REG_P (operands[1]))
3170 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3171 else
3172 return "vmovsd\t{%1, %0|%0, %1}";
3173 }
3174 else
3175 return "movsd\t{%1, %0|%0, %1}";
3176 case MODE_V1DF:
3177 if (TARGET_AVX)
3178 {
3179 if (REG_P (operands[0]))
3180 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3181 else
3182 return "vmovlpd\t{%1, %0|%0, %1}";
3183 }
3184 else
3185 return "movlpd\t{%1, %0|%0, %1}";
3186 case MODE_V2SF:
3187 if (TARGET_AVX)
3188 {
3189 if (REG_P (operands[0]))
3190 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3191 else
3192 return "vmovlps\t{%1, %0|%0, %1}";
3193 }
3194 else
3195 return "movlps\t{%1, %0|%0, %1}";
3196 default:
3197 gcc_unreachable ();
3198 }
3199
3200 default:
3201 gcc_unreachable ();
3202 }
3203 }
3204 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3205 (set (attr "prefix")
3206 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3207 (const_string "orig")
3208 (const_string "maybe_vex")))
3209 (set (attr "prefix_data16")
3210 (if_then_else (eq_attr "mode" "V1DF")
3211 (const_string "1")
3212 (const_string "*")))
3213 (set (attr "mode")
3214 (cond [(eq_attr "alternative" "0,1,2")
3215 (const_string "DF")
3216 (eq_attr "alternative" "3,4")
3217 (const_string "SI")
3218
3219 /* For SSE1, we have many fewer alternatives. */
3220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3221 (cond [(eq_attr "alternative" "5,6")
3222 (const_string "V4SF")
3223 ]
3224 (const_string "V2SF"))
3225
3226 /* xorps is one byte shorter. */
3227 (eq_attr "alternative" "5")
3228 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3229 (const_int 0))
3230 (const_string "V4SF")
3231 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3232 (const_int 0))
3233 (const_string "TI")
3234 ]
3235 (const_string "V2DF"))
3236
3237 /* For architectures resolving dependencies on
3238 whole SSE registers use APD move to break dependency
3239 chains, otherwise use short move to avoid extra work.
3240
3241 movaps encodes one byte shorter. */
3242 (eq_attr "alternative" "6")
3243 (cond
3244 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3245 (const_int 0))
3246 (const_string "V4SF")
3247 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3248 (const_int 0))
3249 (const_string "V2DF")
3250 ]
3251 (const_string "DF"))
3252 /* For architectures resolving dependencies on register
3253 parts we may avoid extra work to zero out upper part
3254 of register. */
3255 (eq_attr "alternative" "7")
3256 (if_then_else
3257 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3258 (const_int 0))
3259 (const_string "V1DF")
3260 (const_string "DF"))
3261 ]
3262 (const_string "DF")))])
3263
3264 ;; Moving is usually shorter when only FP registers are used. This separate
3265 ;; movdf pattern avoids the use of integer registers for FP operations
3266 ;; when optimizing for size.
3267
3268 (define_insn "*movdf_internal_nointeger"
3269 [(set (match_operand:DF 0 "nonimmediate_operand"
3270 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3271 (match_operand:DF 1 "general_operand"
3272 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3273 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3274 && (optimize_function_for_size_p (cfun)
3275 || !TARGET_INTEGER_DFMODE_MOVES)
3276 && (reload_in_progress || reload_completed
3277 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3278 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3279 && optimize_function_for_size_p (cfun)
3280 && !memory_operand (operands[0], DFmode)
3281 && standard_80387_constant_p (operands[1]))
3282 || GET_CODE (operands[1]) != CONST_DOUBLE
3283 || ((optimize_function_for_size_p (cfun)
3284 || !TARGET_MEMORY_MISMATCH_STALL
3285 || reload_in_progress || reload_completed)
3286 && memory_operand (operands[0], DFmode)))"
3287 {
3288 switch (which_alternative)
3289 {
3290 case 0:
3291 case 1:
3292 return output_387_reg_move (insn, operands);
3293
3294 case 2:
3295 return standard_80387_constant_opcode (operands[1]);
3296
3297 case 3:
3298 case 4:
3299 return "#";
3300
3301 case 5:
3302 switch (get_attr_mode (insn))
3303 {
3304 case MODE_V4SF:
3305 return "%vxorps\t%0, %d0";
3306 case MODE_V2DF:
3307 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3308 return "%vxorps\t%0, %d0";
3309 else
3310 return "%vxorpd\t%0, %d0";
3311 case MODE_TI:
3312 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3313 return "%vxorps\t%0, %d0";
3314 else
3315 return "%vpxor\t%0, %d0";
3316 default:
3317 gcc_unreachable ();
3318 }
3319 case 6:
3320 case 7:
3321 case 8:
3322 switch (get_attr_mode (insn))
3323 {
3324 case MODE_V4SF:
3325 return "%vmovaps\t{%1, %0|%0, %1}";
3326 case MODE_V2DF:
3327 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3328 return "%vmovaps\t{%1, %0|%0, %1}";
3329 else
3330 return "%vmovapd\t{%1, %0|%0, %1}";
3331 case MODE_TI:
3332 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3333 return "%vmovaps\t{%1, %0|%0, %1}";
3334 else
3335 return "%vmovdqa\t{%1, %0|%0, %1}";
3336 case MODE_DI:
3337 return "%vmovq\t{%1, %0|%0, %1}";
3338 case MODE_DF:
3339 if (TARGET_AVX)
3340 {
3341 if (REG_P (operands[0]) && REG_P (operands[1]))
3342 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3343 else
3344 return "vmovsd\t{%1, %0|%0, %1}";
3345 }
3346 else
3347 return "movsd\t{%1, %0|%0, %1}";
3348 case MODE_V1DF:
3349 if (TARGET_AVX)
3350 {
3351 if (REG_P (operands[0]))
3352 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3353 else
3354 return "vmovlpd\t{%1, %0|%0, %1}";
3355 }
3356 else
3357 return "movlpd\t{%1, %0|%0, %1}";
3358 case MODE_V2SF:
3359 if (TARGET_AVX)
3360 {
3361 if (REG_P (operands[0]))
3362 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3363 else
3364 return "vmovlps\t{%1, %0|%0, %1}";
3365 }
3366 else
3367 return "movlps\t{%1, %0|%0, %1}";
3368 default:
3369 gcc_unreachable ();
3370 }
3371
3372 default:
3373 gcc_unreachable ();
3374 }
3375 }
3376 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3377 (set (attr "prefix")
3378 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3379 (const_string "orig")
3380 (const_string "maybe_vex")))
3381 (set (attr "prefix_data16")
3382 (if_then_else (eq_attr "mode" "V1DF")
3383 (const_string "1")
3384 (const_string "*")))
3385 (set (attr "mode")
3386 (cond [(eq_attr "alternative" "0,1,2")
3387 (const_string "DF")
3388 (eq_attr "alternative" "3,4")
3389 (const_string "SI")
3390
3391 /* For SSE1, we have many fewer alternatives. */
3392 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3393 (cond [(eq_attr "alternative" "5,6")
3394 (const_string "V4SF")
3395 ]
3396 (const_string "V2SF"))
3397
3398 /* xorps is one byte shorter. */
3399 (eq_attr "alternative" "5")
3400 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3401 (const_int 0))
3402 (const_string "V4SF")
3403 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3404 (const_int 0))
3405 (const_string "TI")
3406 ]
3407 (const_string "V2DF"))
3408
3409 /* For architectures resolving dependencies on
3410 whole SSE registers use APD move to break dependency
3411 chains, otherwise use short move to avoid extra work.
3412
3413 movaps encodes one byte shorter. */
3414 (eq_attr "alternative" "6")
3415 (cond
3416 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3417 (const_int 0))
3418 (const_string "V4SF")
3419 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3420 (const_int 0))
3421 (const_string "V2DF")
3422 ]
3423 (const_string "DF"))
3424 /* For architectures resolving dependencies on register
3425 parts we may avoid extra work to zero out upper part
3426 of register. */
3427 (eq_attr "alternative" "7")
3428 (if_then_else
3429 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3430 (const_int 0))
3431 (const_string "V1DF")
3432 (const_string "DF"))
3433 ]
3434 (const_string "DF")))])
3435
3436 (define_split
3437 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3438 (match_operand:DF 1 "general_operand" ""))]
3439 "reload_completed
3440 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3441 && ! (ANY_FP_REG_P (operands[0]) ||
3442 (GET_CODE (operands[0]) == SUBREG
3443 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3444 && ! (ANY_FP_REG_P (operands[1]) ||
3445 (GET_CODE (operands[1]) == SUBREG
3446 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3447 [(const_int 0)]
3448 "ix86_split_long_move (operands); DONE;")
3449
3450 (define_insn "*movsf_internal"
3451 [(set (match_operand:SF 0 "nonimmediate_operand"
3452 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3453 (match_operand:SF 1 "general_operand"
3454 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3455 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3456 && (reload_in_progress || reload_completed
3457 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3458 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3459 && standard_80387_constant_p (operands[1]))
3460 || GET_CODE (operands[1]) != CONST_DOUBLE
3461 || memory_operand (operands[0], SFmode))"
3462 {
3463 switch (which_alternative)
3464 {
3465 case 0:
3466 case 1:
3467 return output_387_reg_move (insn, operands);
3468
3469 case 2:
3470 return standard_80387_constant_opcode (operands[1]);
3471
3472 case 3:
3473 case 4:
3474 return "mov{l}\t{%1, %0|%0, %1}";
3475 case 5:
3476 if (get_attr_mode (insn) == MODE_TI)
3477 return "%vpxor\t%0, %d0";
3478 else
3479 return "%vxorps\t%0, %d0";
3480 case 6:
3481 if (get_attr_mode (insn) == MODE_V4SF)
3482 return "%vmovaps\t{%1, %0|%0, %1}";
3483 else
3484 return "%vmovss\t{%1, %d0|%d0, %1}";
3485 case 7:
3486 if (TARGET_AVX)
3487 {
3488 if (REG_P (operands[1]))
3489 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3490 else
3491 return "vmovss\t{%1, %0|%0, %1}";
3492 }
3493 else
3494 return "movss\t{%1, %0|%0, %1}";
3495 case 8:
3496 return "%vmovss\t{%1, %0|%0, %1}";
3497
3498 case 9: case 10: case 14: case 15:
3499 return "movd\t{%1, %0|%0, %1}";
3500
3501 case 11:
3502 return "movq\t{%1, %0|%0, %1}";
3503
3504 case 12: case 13:
3505 return "%vmovd\t{%1, %0|%0, %1}";
3506
3507 default:
3508 gcc_unreachable ();
3509 }
3510 }
3511 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3512 (set (attr "prefix")
3513 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3514 (const_string "maybe_vex")
3515 (const_string "orig")))
3516 (set (attr "mode")
3517 (cond [(eq_attr "alternative" "3,4,9,10")
3518 (const_string "SI")
3519 (eq_attr "alternative" "5")
3520 (if_then_else
3521 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3522 (const_int 0))
3523 (ne (symbol_ref "TARGET_SSE2")
3524 (const_int 0)))
3525 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3526 (const_int 0)))
3527 (const_string "TI")
3528 (const_string "V4SF"))
3529 /* For architectures resolving dependencies on
3530 whole SSE registers use APS move to break dependency
3531 chains, otherwise use short move to avoid extra work.
3532
3533 Do the same for architectures resolving dependencies on
3534 the parts. While in DF mode it is better to always handle
3535 just register parts, the SF mode is different due to lack
3536 of instructions to load just part of the register. It is
3537 better to maintain the whole registers in single format
3538 to avoid problems on using packed logical operations. */
3539 (eq_attr "alternative" "6")
3540 (if_then_else
3541 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3542 (const_int 0))
3543 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3544 (const_int 0)))
3545 (const_string "V4SF")
3546 (const_string "SF"))
3547 (eq_attr "alternative" "11")
3548 (const_string "DI")]
3549 (const_string "SF")))])
3550
3551 (define_split
3552 [(set (match_operand 0 "register_operand" "")
3553 (match_operand 1 "memory_operand" ""))]
3554 "reload_completed
3555 && MEM_P (operands[1])
3556 && (GET_MODE (operands[0]) == TFmode
3557 || GET_MODE (operands[0]) == XFmode
3558 || GET_MODE (operands[0]) == DFmode
3559 || GET_MODE (operands[0]) == SFmode)
3560 && (operands[2] = find_constant_src (insn))"
3561 [(set (match_dup 0) (match_dup 2))]
3562 {
3563 rtx c = operands[2];
3564 rtx r = operands[0];
3565
3566 if (GET_CODE (r) == SUBREG)
3567 r = SUBREG_REG (r);
3568
3569 if (SSE_REG_P (r))
3570 {
3571 if (!standard_sse_constant_p (c))
3572 FAIL;
3573 }
3574 else if (FP_REG_P (r))
3575 {
3576 if (!standard_80387_constant_p (c))
3577 FAIL;
3578 }
3579 else if (MMX_REG_P (r))
3580 FAIL;
3581 })
3582
3583 (define_split
3584 [(set (match_operand 0 "register_operand" "")
3585 (float_extend (match_operand 1 "memory_operand" "")))]
3586 "reload_completed
3587 && MEM_P (operands[1])
3588 && (GET_MODE (operands[0]) == TFmode
3589 || GET_MODE (operands[0]) == XFmode
3590 || GET_MODE (operands[0]) == DFmode
3591 || GET_MODE (operands[0]) == SFmode)
3592 && (operands[2] = find_constant_src (insn))"
3593 [(set (match_dup 0) (match_dup 2))]
3594 {
3595 rtx c = operands[2];
3596 rtx r = operands[0];
3597
3598 if (GET_CODE (r) == SUBREG)
3599 r = SUBREG_REG (r);
3600
3601 if (SSE_REG_P (r))
3602 {
3603 if (!standard_sse_constant_p (c))
3604 FAIL;
3605 }
3606 else if (FP_REG_P (r))
3607 {
3608 if (!standard_80387_constant_p (c))
3609 FAIL;
3610 }
3611 else if (MMX_REG_P (r))
3612 FAIL;
3613 })
3614
3615 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3616 (define_split
3617 [(set (match_operand:X87MODEF 0 "register_operand" "")
3618 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3619 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3620 && (standard_80387_constant_p (operands[1]) == 8
3621 || standard_80387_constant_p (operands[1]) == 9)"
3622 [(set (match_dup 0)(match_dup 1))
3623 (set (match_dup 0)
3624 (neg:X87MODEF (match_dup 0)))]
3625 {
3626 REAL_VALUE_TYPE r;
3627
3628 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3629 if (real_isnegzero (&r))
3630 operands[1] = CONST0_RTX (<MODE>mode);
3631 else
3632 operands[1] = CONST1_RTX (<MODE>mode);
3633 })
3634
3635 (define_insn "swapxf"
3636 [(set (match_operand:XF 0 "register_operand" "+f")
3637 (match_operand:XF 1 "register_operand" "+f"))
3638 (set (match_dup 1)
3639 (match_dup 0))]
3640 "TARGET_80387"
3641 {
3642 if (STACK_TOP_P (operands[0]))
3643 return "fxch\t%1";
3644 else
3645 return "fxch\t%0";
3646 }
3647 [(set_attr "type" "fxch")
3648 (set_attr "mode" "XF")])
3649
3650 (define_insn "*swap<mode>"
3651 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3652 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3653 (set (match_dup 1)
3654 (match_dup 0))]
3655 "TARGET_80387 || reload_completed"
3656 {
3657 if (STACK_TOP_P (operands[0]))
3658 return "fxch\t%1";
3659 else
3660 return "fxch\t%0";
3661 }
3662 [(set_attr "type" "fxch")
3663 (set_attr "mode" "<MODE>")])
3664 \f
3665 ;; Zero extension instructions
3666
3667 (define_expand "zero_extendsidi2"
3668 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3669 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3670 ""
3671 {
3672 if (!TARGET_64BIT)
3673 {
3674 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3675 DONE;
3676 }
3677 })
3678
3679 (define_insn "*zero_extendsidi2_rex64"
3680 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3681 (zero_extend:DI
3682 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3683 "TARGET_64BIT"
3684 "@
3685 mov\t{%k1, %k0|%k0, %k1}
3686 #
3687 movd\t{%1, %0|%0, %1}
3688 movd\t{%1, %0|%0, %1}
3689 %vmovd\t{%1, %0|%0, %1}
3690 %vmovd\t{%1, %0|%0, %1}"
3691 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3692 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3693 (set_attr "prefix_0f" "0,*,*,*,*,*")
3694 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3695
3696 (define_split
3697 [(set (match_operand:DI 0 "memory_operand" "")
3698 (zero_extend:DI (match_dup 0)))]
3699 "TARGET_64BIT"
3700 [(set (match_dup 4) (const_int 0))]
3701 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3702
3703 ;; %%% Kill me once multi-word ops are sane.
3704 (define_insn "zero_extendsidi2_1"
3705 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3706 (zero_extend:DI
3707 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3708 (clobber (reg:CC FLAGS_REG))]
3709 "!TARGET_64BIT"
3710 "@
3711 #
3712 #
3713 #
3714 movd\t{%1, %0|%0, %1}
3715 movd\t{%1, %0|%0, %1}
3716 %vmovd\t{%1, %0|%0, %1}
3717 %vmovd\t{%1, %0|%0, %1}"
3718 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3719 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3720 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3721
3722 (define_split
3723 [(set (match_operand:DI 0 "register_operand" "")
3724 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3725 (clobber (reg:CC FLAGS_REG))]
3726 "!TARGET_64BIT && reload_completed
3727 && true_regnum (operands[0]) == true_regnum (operands[1])"
3728 [(set (match_dup 4) (const_int 0))]
3729 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3730
3731 (define_split
3732 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3733 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3734 (clobber (reg:CC FLAGS_REG))]
3735 "!TARGET_64BIT && reload_completed
3736 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3737 [(set (match_dup 3) (match_dup 1))
3738 (set (match_dup 4) (const_int 0))]
3739 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3740
3741 (define_insn "zero_extend<mode>di2"
3742 [(set (match_operand:DI 0 "register_operand" "=r")
3743 (zero_extend:DI
3744 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3745 "TARGET_64BIT"
3746 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "SI")])
3749
3750 (define_expand "zero_extendhisi2"
3751 [(set (match_operand:SI 0 "register_operand" "")
3752 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3753 ""
3754 {
3755 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3756 {
3757 operands[1] = force_reg (HImode, operands[1]);
3758 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3759 DONE;
3760 }
3761 })
3762
3763 (define_insn_and_split "zero_extendhisi2_and"
3764 [(set (match_operand:SI 0 "register_operand" "=r")
3765 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3766 (clobber (reg:CC FLAGS_REG))]
3767 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3768 "#"
3769 "&& reload_completed"
3770 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3771 (clobber (reg:CC FLAGS_REG))])]
3772 ""
3773 [(set_attr "type" "alu1")
3774 (set_attr "mode" "SI")])
3775
3776 (define_insn "*zero_extendhisi2_movzwl"
3777 [(set (match_operand:SI 0 "register_operand" "=r")
3778 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3779 "!TARGET_ZERO_EXTEND_WITH_AND
3780 || optimize_function_for_size_p (cfun)"
3781 "movz{wl|x}\t{%1, %0|%0, %1}"
3782 [(set_attr "type" "imovx")
3783 (set_attr "mode" "SI")])
3784
3785 (define_expand "zero_extendqi<mode>2"
3786 [(parallel
3787 [(set (match_operand:SWI24 0 "register_operand" "")
3788 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3789 (clobber (reg:CC FLAGS_REG))])])
3790
3791 (define_insn "*zero_extendqi<mode>2_and"
3792 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3793 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3794 (clobber (reg:CC FLAGS_REG))]
3795 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3796 "#"
3797 [(set_attr "type" "alu1")
3798 (set_attr "mode" "<MODE>")])
3799
3800 ;; When source and destination does not overlap, clear destination
3801 ;; first and then do the movb
3802 (define_split
3803 [(set (match_operand:SWI24 0 "register_operand" "")
3804 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3805 (clobber (reg:CC FLAGS_REG))]
3806 "reload_completed
3807 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3808 && ANY_QI_REG_P (operands[0])
3809 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3810 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3811 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3812 {
3813 operands[2] = gen_lowpart (QImode, operands[0]);
3814 ix86_expand_clear (operands[0]);
3815 })
3816
3817 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3818 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3819 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3820 (clobber (reg:CC FLAGS_REG))]
3821 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3822 "#"
3823 [(set_attr "type" "imovx,alu1")
3824 (set_attr "mode" "<MODE>")])
3825
3826 ;; For the movzbl case strip only the clobber
3827 (define_split
3828 [(set (match_operand:SWI24 0 "register_operand" "")
3829 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3830 (clobber (reg:CC FLAGS_REG))]
3831 "reload_completed
3832 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3833 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3834 [(set (match_dup 0)
3835 (zero_extend:SWI24 (match_dup 1)))])
3836
3837 ; zero extend to SImode to avoid partial register stalls
3838 (define_insn "*zero_extendqi<mode>2_movzbl"
3839 [(set (match_operand:SWI24 0 "register_operand" "=r")
3840 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3841 "reload_completed
3842 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3843 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3844 [(set_attr "type" "imovx")
3845 (set_attr "mode" "SI")])
3846
3847 ;; Rest is handled by single and.
3848 (define_split
3849 [(set (match_operand:SWI24 0 "register_operand" "")
3850 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3851 (clobber (reg:CC FLAGS_REG))]
3852 "reload_completed
3853 && true_regnum (operands[0]) == true_regnum (operands[1])"
3854 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3855 (clobber (reg:CC FLAGS_REG))])])
3856 \f
3857 ;; Sign extension instructions
3858
3859 (define_expand "extendsidi2"
3860 [(set (match_operand:DI 0 "register_operand" "")
3861 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3862 ""
3863 {
3864 if (!TARGET_64BIT)
3865 {
3866 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3867 DONE;
3868 }
3869 })
3870
3871 (define_insn "*extendsidi2_rex64"
3872 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3873 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3874 "TARGET_64BIT"
3875 "@
3876 {cltq|cdqe}
3877 movs{lq|x}\t{%1, %0|%0, %1}"
3878 [(set_attr "type" "imovx")
3879 (set_attr "mode" "DI")
3880 (set_attr "prefix_0f" "0")
3881 (set_attr "modrm" "0,1")])
3882
3883 (define_insn "extendsidi2_1"
3884 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3885 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3886 (clobber (reg:CC FLAGS_REG))
3887 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3888 "!TARGET_64BIT"
3889 "#")
3890
3891 ;; Extend to memory case when source register does die.
3892 (define_split
3893 [(set (match_operand:DI 0 "memory_operand" "")
3894 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3895 (clobber (reg:CC FLAGS_REG))
3896 (clobber (match_operand:SI 2 "register_operand" ""))]
3897 "(reload_completed
3898 && dead_or_set_p (insn, operands[1])
3899 && !reg_mentioned_p (operands[1], operands[0]))"
3900 [(set (match_dup 3) (match_dup 1))
3901 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3902 (clobber (reg:CC FLAGS_REG))])
3903 (set (match_dup 4) (match_dup 1))]
3904 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3905
3906 ;; Extend to memory case when source register does not die.
3907 (define_split
3908 [(set (match_operand:DI 0 "memory_operand" "")
3909 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3910 (clobber (reg:CC FLAGS_REG))
3911 (clobber (match_operand:SI 2 "register_operand" ""))]
3912 "reload_completed"
3913 [(const_int 0)]
3914 {
3915 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3916
3917 emit_move_insn (operands[3], operands[1]);
3918
3919 /* Generate a cltd if possible and doing so it profitable. */
3920 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3921 && true_regnum (operands[1]) == AX_REG
3922 && true_regnum (operands[2]) == DX_REG)
3923 {
3924 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3925 }
3926 else
3927 {
3928 emit_move_insn (operands[2], operands[1]);
3929 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3930 }
3931 emit_move_insn (operands[4], operands[2]);
3932 DONE;
3933 })
3934
3935 ;; Extend to register case. Optimize case where source and destination
3936 ;; registers match and cases where we can use cltd.
3937 (define_split
3938 [(set (match_operand:DI 0 "register_operand" "")
3939 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3940 (clobber (reg:CC FLAGS_REG))
3941 (clobber (match_scratch:SI 2 ""))]
3942 "reload_completed"
3943 [(const_int 0)]
3944 {
3945 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3946
3947 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3948 emit_move_insn (operands[3], operands[1]);
3949
3950 /* Generate a cltd if possible and doing so it profitable. */
3951 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3952 && true_regnum (operands[3]) == AX_REG
3953 && true_regnum (operands[4]) == DX_REG)
3954 {
3955 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3956 DONE;
3957 }
3958
3959 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3960 emit_move_insn (operands[4], operands[1]);
3961
3962 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3963 DONE;
3964 })
3965
3966 (define_insn "extend<mode>di2"
3967 [(set (match_operand:DI 0 "register_operand" "=r")
3968 (sign_extend:DI
3969 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3970 "TARGET_64BIT"
3971 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3972 [(set_attr "type" "imovx")
3973 (set_attr "mode" "DI")])
3974
3975 (define_insn "extendhisi2"
3976 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3977 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3978 ""
3979 {
3980 switch (get_attr_prefix_0f (insn))
3981 {
3982 case 0:
3983 return "{cwtl|cwde}";
3984 default:
3985 return "movs{wl|x}\t{%1, %0|%0, %1}";
3986 }
3987 }
3988 [(set_attr "type" "imovx")
3989 (set_attr "mode" "SI")
3990 (set (attr "prefix_0f")
3991 ;; movsx is short decodable while cwtl is vector decoded.
3992 (if_then_else (and (eq_attr "cpu" "!k6")
3993 (eq_attr "alternative" "0"))
3994 (const_string "0")
3995 (const_string "1")))
3996 (set (attr "modrm")
3997 (if_then_else (eq_attr "prefix_0f" "0")
3998 (const_string "0")
3999 (const_string "1")))])
4000
4001 (define_insn "*extendhisi2_zext"
4002 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4003 (zero_extend:DI
4004 (sign_extend:SI
4005 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4006 "TARGET_64BIT"
4007 {
4008 switch (get_attr_prefix_0f (insn))
4009 {
4010 case 0:
4011 return "{cwtl|cwde}";
4012 default:
4013 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4014 }
4015 }
4016 [(set_attr "type" "imovx")
4017 (set_attr "mode" "SI")
4018 (set (attr "prefix_0f")
4019 ;; movsx is short decodable while cwtl is vector decoded.
4020 (if_then_else (and (eq_attr "cpu" "!k6")
4021 (eq_attr "alternative" "0"))
4022 (const_string "0")
4023 (const_string "1")))
4024 (set (attr "modrm")
4025 (if_then_else (eq_attr "prefix_0f" "0")
4026 (const_string "0")
4027 (const_string "1")))])
4028
4029 (define_insn "extendqisi2"
4030 [(set (match_operand:SI 0 "register_operand" "=r")
4031 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4032 ""
4033 "movs{bl|x}\t{%1, %0|%0, %1}"
4034 [(set_attr "type" "imovx")
4035 (set_attr "mode" "SI")])
4036
4037 (define_insn "*extendqisi2_zext"
4038 [(set (match_operand:DI 0 "register_operand" "=r")
4039 (zero_extend:DI
4040 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4041 "TARGET_64BIT"
4042 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4043 [(set_attr "type" "imovx")
4044 (set_attr "mode" "SI")])
4045
4046 (define_insn "extendqihi2"
4047 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4048 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4049 ""
4050 {
4051 switch (get_attr_prefix_0f (insn))
4052 {
4053 case 0:
4054 return "{cbtw|cbw}";
4055 default:
4056 return "movs{bw|x}\t{%1, %0|%0, %1}";
4057 }
4058 }
4059 [(set_attr "type" "imovx")
4060 (set_attr "mode" "HI")
4061 (set (attr "prefix_0f")
4062 ;; movsx is short decodable while cwtl is vector decoded.
4063 (if_then_else (and (eq_attr "cpu" "!k6")
4064 (eq_attr "alternative" "0"))
4065 (const_string "0")
4066 (const_string "1")))
4067 (set (attr "modrm")
4068 (if_then_else (eq_attr "prefix_0f" "0")
4069 (const_string "0")
4070 (const_string "1")))])
4071 \f
4072 ;; Conversions between float and double.
4073
4074 ;; These are all no-ops in the model used for the 80387.
4075 ;; So just emit moves.
4076
4077 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4078 (define_split
4079 [(set (match_operand:DF 0 "push_operand" "")
4080 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4081 "reload_completed"
4082 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4083 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4084
4085 (define_split
4086 [(set (match_operand:XF 0 "push_operand" "")
4087 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4088 "reload_completed"
4089 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4090 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4091 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4092
4093 (define_expand "extendsfdf2"
4094 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4095 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4096 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4097 {
4098 /* ??? Needed for compress_float_constant since all fp constants
4099 are TARGET_LEGITIMATE_CONSTANT_P. */
4100 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4101 {
4102 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4103 && standard_80387_constant_p (operands[1]) > 0)
4104 {
4105 operands[1] = simplify_const_unary_operation
4106 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4107 emit_move_insn_1 (operands[0], operands[1]);
4108 DONE;
4109 }
4110 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4111 }
4112 })
4113
4114 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4115 cvtss2sd:
4116 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4117 cvtps2pd xmm2,xmm1
4118 We do the conversion post reload to avoid producing of 128bit spills
4119 that might lead to ICE on 32bit target. The sequence unlikely combine
4120 anyway. */
4121 (define_split
4122 [(set (match_operand:DF 0 "register_operand" "")
4123 (float_extend:DF
4124 (match_operand:SF 1 "nonimmediate_operand" "")))]
4125 "TARGET_USE_VECTOR_FP_CONVERTS
4126 && optimize_insn_for_speed_p ()
4127 && reload_completed && SSE_REG_P (operands[0])"
4128 [(set (match_dup 2)
4129 (float_extend:V2DF
4130 (vec_select:V2SF
4131 (match_dup 3)
4132 (parallel [(const_int 0) (const_int 1)]))))]
4133 {
4134 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4135 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4136 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4137 Try to avoid move when unpacking can be done in source. */
4138 if (REG_P (operands[1]))
4139 {
4140 /* If it is unsafe to overwrite upper half of source, we need
4141 to move to destination and unpack there. */
4142 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4143 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4144 && true_regnum (operands[0]) != true_regnum (operands[1]))
4145 {
4146 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4147 emit_move_insn (tmp, operands[1]);
4148 }
4149 else
4150 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4151 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4152 operands[3]));
4153 }
4154 else
4155 emit_insn (gen_vec_setv4sf_0 (operands[3],
4156 CONST0_RTX (V4SFmode), operands[1]));
4157 })
4158
4159 (define_insn "*extendsfdf2_mixed"
4160 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4161 (float_extend:DF
4162 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4163 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4164 {
4165 switch (which_alternative)
4166 {
4167 case 0:
4168 case 1:
4169 return output_387_reg_move (insn, operands);
4170
4171 case 2:
4172 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4173
4174 default:
4175 gcc_unreachable ();
4176 }
4177 }
4178 [(set_attr "type" "fmov,fmov,ssecvt")
4179 (set_attr "prefix" "orig,orig,maybe_vex")
4180 (set_attr "mode" "SF,XF,DF")])
4181
4182 (define_insn "*extendsfdf2_sse"
4183 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4184 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4185 "TARGET_SSE2 && TARGET_SSE_MATH"
4186 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4187 [(set_attr "type" "ssecvt")
4188 (set_attr "prefix" "maybe_vex")
4189 (set_attr "mode" "DF")])
4190
4191 (define_insn "*extendsfdf2_i387"
4192 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4193 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4194 "TARGET_80387"
4195 "* return output_387_reg_move (insn, operands);"
4196 [(set_attr "type" "fmov")
4197 (set_attr "mode" "SF,XF")])
4198
4199 (define_expand "extend<mode>xf2"
4200 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4201 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4202 "TARGET_80387"
4203 {
4204 /* ??? Needed for compress_float_constant since all fp constants
4205 are TARGET_LEGITIMATE_CONSTANT_P. */
4206 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4207 {
4208 if (standard_80387_constant_p (operands[1]) > 0)
4209 {
4210 operands[1] = simplify_const_unary_operation
4211 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4212 emit_move_insn_1 (operands[0], operands[1]);
4213 DONE;
4214 }
4215 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4216 }
4217 })
4218
4219 (define_insn "*extend<mode>xf2_i387"
4220 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4221 (float_extend:XF
4222 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4223 "TARGET_80387"
4224 "* return output_387_reg_move (insn, operands);"
4225 [(set_attr "type" "fmov")
4226 (set_attr "mode" "<MODE>,XF")])
4227
4228 ;; %%% This seems bad bad news.
4229 ;; This cannot output into an f-reg because there is no way to be sure
4230 ;; of truncating in that case. Otherwise this is just like a simple move
4231 ;; insn. So we pretend we can output to a reg in order to get better
4232 ;; register preferencing, but we really use a stack slot.
4233
4234 ;; Conversion from DFmode to SFmode.
4235
4236 (define_expand "truncdfsf2"
4237 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4238 (float_truncate:SF
4239 (match_operand:DF 1 "nonimmediate_operand" "")))]
4240 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4241 {
4242 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4243 ;
4244 else if (flag_unsafe_math_optimizations)
4245 ;
4246 else
4247 {
4248 enum ix86_stack_slot slot = (virtuals_instantiated
4249 ? SLOT_TEMP
4250 : SLOT_VIRTUAL);
4251 rtx temp = assign_386_stack_local (SFmode, slot);
4252 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4253 DONE;
4254 }
4255 })
4256
4257 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4258 cvtsd2ss:
4259 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4260 cvtpd2ps xmm2,xmm1
4261 We do the conversion post reload to avoid producing of 128bit spills
4262 that might lead to ICE on 32bit target. The sequence unlikely combine
4263 anyway. */
4264 (define_split
4265 [(set (match_operand:SF 0 "register_operand" "")
4266 (float_truncate:SF
4267 (match_operand:DF 1 "nonimmediate_operand" "")))]
4268 "TARGET_USE_VECTOR_FP_CONVERTS
4269 && optimize_insn_for_speed_p ()
4270 && reload_completed && SSE_REG_P (operands[0])"
4271 [(set (match_dup 2)
4272 (vec_concat:V4SF
4273 (float_truncate:V2SF
4274 (match_dup 4))
4275 (match_dup 3)))]
4276 {
4277 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4278 operands[3] = CONST0_RTX (V2SFmode);
4279 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4280 /* Use movsd for loading from memory, unpcklpd for registers.
4281 Try to avoid move when unpacking can be done in source, or SSE3
4282 movddup is available. */
4283 if (REG_P (operands[1]))
4284 {
4285 if (!TARGET_SSE3
4286 && true_regnum (operands[0]) != true_regnum (operands[1])
4287 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4288 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4289 {
4290 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4291 emit_move_insn (tmp, operands[1]);
4292 operands[1] = tmp;
4293 }
4294 else if (!TARGET_SSE3)
4295 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4296 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4297 }
4298 else
4299 emit_insn (gen_sse2_loadlpd (operands[4],
4300 CONST0_RTX (V2DFmode), operands[1]));
4301 })
4302
4303 (define_expand "truncdfsf2_with_temp"
4304 [(parallel [(set (match_operand:SF 0 "" "")
4305 (float_truncate:SF (match_operand:DF 1 "" "")))
4306 (clobber (match_operand:SF 2 "" ""))])])
4307
4308 (define_insn "*truncdfsf_fast_mixed"
4309 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4310 (float_truncate:SF
4311 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4312 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4313 {
4314 switch (which_alternative)
4315 {
4316 case 0:
4317 return output_387_reg_move (insn, operands);
4318 case 1:
4319 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4320 default:
4321 gcc_unreachable ();
4322 }
4323 }
4324 [(set_attr "type" "fmov,ssecvt")
4325 (set_attr "prefix" "orig,maybe_vex")
4326 (set_attr "mode" "SF")])
4327
4328 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4329 ;; because nothing we do here is unsafe.
4330 (define_insn "*truncdfsf_fast_sse"
4331 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4332 (float_truncate:SF
4333 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4334 "TARGET_SSE2 && TARGET_SSE_MATH"
4335 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4336 [(set_attr "type" "ssecvt")
4337 (set_attr "prefix" "maybe_vex")
4338 (set_attr "mode" "SF")])
4339
4340 (define_insn "*truncdfsf_fast_i387"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4342 (float_truncate:SF
4343 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4344 "TARGET_80387 && flag_unsafe_math_optimizations"
4345 "* return output_387_reg_move (insn, operands);"
4346 [(set_attr "type" "fmov")
4347 (set_attr "mode" "SF")])
4348
4349 (define_insn "*truncdfsf_mixed"
4350 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4351 (float_truncate:SF
4352 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4353 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4354 "TARGET_MIX_SSE_I387"
4355 {
4356 switch (which_alternative)
4357 {
4358 case 0:
4359 return output_387_reg_move (insn, operands);
4360 case 1:
4361 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4362
4363 default:
4364 return "#";
4365 }
4366 }
4367 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4368 (set_attr "unit" "*,*,i387,i387,i387")
4369 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4370 (set_attr "mode" "SF")])
4371
4372 (define_insn "*truncdfsf_i387"
4373 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4374 (float_truncate:SF
4375 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4376 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4377 "TARGET_80387"
4378 {
4379 switch (which_alternative)
4380 {
4381 case 0:
4382 return output_387_reg_move (insn, operands);
4383
4384 default:
4385 return "#";
4386 }
4387 }
4388 [(set_attr "type" "fmov,multi,multi,multi")
4389 (set_attr "unit" "*,i387,i387,i387")
4390 (set_attr "mode" "SF")])
4391
4392 (define_insn "*truncdfsf2_i387_1"
4393 [(set (match_operand:SF 0 "memory_operand" "=m")
4394 (float_truncate:SF
4395 (match_operand:DF 1 "register_operand" "f")))]
4396 "TARGET_80387
4397 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4398 && !TARGET_MIX_SSE_I387"
4399 "* return output_387_reg_move (insn, operands);"
4400 [(set_attr "type" "fmov")
4401 (set_attr "mode" "SF")])
4402
4403 (define_split
4404 [(set (match_operand:SF 0 "register_operand" "")
4405 (float_truncate:SF
4406 (match_operand:DF 1 "fp_register_operand" "")))
4407 (clobber (match_operand 2 "" ""))]
4408 "reload_completed"
4409 [(set (match_dup 2) (match_dup 1))
4410 (set (match_dup 0) (match_dup 2))]
4411 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4412
4413 ;; Conversion from XFmode to {SF,DF}mode
4414
4415 (define_expand "truncxf<mode>2"
4416 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4417 (float_truncate:MODEF
4418 (match_operand:XF 1 "register_operand" "")))
4419 (clobber (match_dup 2))])]
4420 "TARGET_80387"
4421 {
4422 if (flag_unsafe_math_optimizations)
4423 {
4424 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4425 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4426 if (reg != operands[0])
4427 emit_move_insn (operands[0], reg);
4428 DONE;
4429 }
4430 else
4431 {
4432 enum ix86_stack_slot slot = (virtuals_instantiated
4433 ? SLOT_TEMP
4434 : SLOT_VIRTUAL);
4435 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4436 }
4437 })
4438
4439 (define_insn "*truncxfsf2_mixed"
4440 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4441 (float_truncate:SF
4442 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4443 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4444 "TARGET_80387"
4445 {
4446 gcc_assert (!which_alternative);
4447 return output_387_reg_move (insn, operands);
4448 }
4449 [(set_attr "type" "fmov,multi,multi,multi")
4450 (set_attr "unit" "*,i387,i387,i387")
4451 (set_attr "mode" "SF")])
4452
4453 (define_insn "*truncxfdf2_mixed"
4454 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4455 (float_truncate:DF
4456 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4457 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4458 "TARGET_80387"
4459 {
4460 gcc_assert (!which_alternative);
4461 return output_387_reg_move (insn, operands);
4462 }
4463 [(set_attr "type" "fmov,multi,multi,multi")
4464 (set_attr "unit" "*,i387,i387,i387")
4465 (set_attr "mode" "DF")])
4466
4467 (define_insn "truncxf<mode>2_i387_noop"
4468 [(set (match_operand:MODEF 0 "register_operand" "=f")
4469 (float_truncate:MODEF
4470 (match_operand:XF 1 "register_operand" "f")))]
4471 "TARGET_80387 && flag_unsafe_math_optimizations"
4472 "* return output_387_reg_move (insn, operands);"
4473 [(set_attr "type" "fmov")
4474 (set_attr "mode" "<MODE>")])
4475
4476 (define_insn "*truncxf<mode>2_i387"
4477 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4478 (float_truncate:MODEF
4479 (match_operand:XF 1 "register_operand" "f")))]
4480 "TARGET_80387"
4481 "* return output_387_reg_move (insn, operands);"
4482 [(set_attr "type" "fmov")
4483 (set_attr "mode" "<MODE>")])
4484
4485 (define_split
4486 [(set (match_operand:MODEF 0 "register_operand" "")
4487 (float_truncate:MODEF
4488 (match_operand:XF 1 "register_operand" "")))
4489 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4490 "TARGET_80387 && reload_completed"
4491 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4492 (set (match_dup 0) (match_dup 2))])
4493
4494 (define_split
4495 [(set (match_operand:MODEF 0 "memory_operand" "")
4496 (float_truncate:MODEF
4497 (match_operand:XF 1 "register_operand" "")))
4498 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4499 "TARGET_80387"
4500 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4501 \f
4502 ;; Signed conversion to DImode.
4503
4504 (define_expand "fix_truncxfdi2"
4505 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4506 (fix:DI (match_operand:XF 1 "register_operand" "")))
4507 (clobber (reg:CC FLAGS_REG))])]
4508 "TARGET_80387"
4509 {
4510 if (TARGET_FISTTP)
4511 {
4512 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4513 DONE;
4514 }
4515 })
4516
4517 (define_expand "fix_trunc<mode>di2"
4518 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4519 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4520 (clobber (reg:CC FLAGS_REG))])]
4521 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4522 {
4523 if (TARGET_FISTTP
4524 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4525 {
4526 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4527 DONE;
4528 }
4529 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4530 {
4531 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4532 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4533 if (out != operands[0])
4534 emit_move_insn (operands[0], out);
4535 DONE;
4536 }
4537 })
4538
4539 ;; Signed conversion to SImode.
4540
4541 (define_expand "fix_truncxfsi2"
4542 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4543 (fix:SI (match_operand:XF 1 "register_operand" "")))
4544 (clobber (reg:CC FLAGS_REG))])]
4545 "TARGET_80387"
4546 {
4547 if (TARGET_FISTTP)
4548 {
4549 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4550 DONE;
4551 }
4552 })
4553
4554 (define_expand "fix_trunc<mode>si2"
4555 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4556 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4557 (clobber (reg:CC FLAGS_REG))])]
4558 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4559 {
4560 if (TARGET_FISTTP
4561 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4562 {
4563 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4564 DONE;
4565 }
4566 if (SSE_FLOAT_MODE_P (<MODE>mode))
4567 {
4568 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4569 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4570 if (out != operands[0])
4571 emit_move_insn (operands[0], out);
4572 DONE;
4573 }
4574 })
4575
4576 ;; Signed conversion to HImode.
4577
4578 (define_expand "fix_trunc<mode>hi2"
4579 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4580 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4581 (clobber (reg:CC FLAGS_REG))])]
4582 "TARGET_80387
4583 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4584 {
4585 if (TARGET_FISTTP)
4586 {
4587 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4588 DONE;
4589 }
4590 })
4591
4592 ;; Unsigned conversion to SImode.
4593
4594 (define_expand "fixuns_trunc<mode>si2"
4595 [(parallel
4596 [(set (match_operand:SI 0 "register_operand" "")
4597 (unsigned_fix:SI
4598 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4599 (use (match_dup 2))
4600 (clobber (match_scratch:<ssevecmode> 3 ""))
4601 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4602 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4603 {
4604 enum machine_mode mode = <MODE>mode;
4605 enum machine_mode vecmode = <ssevecmode>mode;
4606 REAL_VALUE_TYPE TWO31r;
4607 rtx two31;
4608
4609 if (optimize_insn_for_size_p ())
4610 FAIL;
4611
4612 real_ldexp (&TWO31r, &dconst1, 31);
4613 two31 = const_double_from_real_value (TWO31r, mode);
4614 two31 = ix86_build_const_vector (vecmode, true, two31);
4615 operands[2] = force_reg (vecmode, two31);
4616 })
4617
4618 (define_insn_and_split "*fixuns_trunc<mode>_1"
4619 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4620 (unsigned_fix:SI
4621 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4622 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4623 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4624 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4625 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4626 && optimize_function_for_speed_p (cfun)"
4627 "#"
4628 "&& reload_completed"
4629 [(const_int 0)]
4630 {
4631 ix86_split_convert_uns_si_sse (operands);
4632 DONE;
4633 })
4634
4635 ;; Unsigned conversion to HImode.
4636 ;; Without these patterns, we'll try the unsigned SI conversion which
4637 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4638
4639 (define_expand "fixuns_trunc<mode>hi2"
4640 [(set (match_dup 2)
4641 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4642 (set (match_operand:HI 0 "nonimmediate_operand" "")
4643 (subreg:HI (match_dup 2) 0))]
4644 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4645 "operands[2] = gen_reg_rtx (SImode);")
4646
4647 ;; When SSE is available, it is always faster to use it!
4648 (define_insn "fix_trunc<mode>di_sse"
4649 [(set (match_operand:DI 0 "register_operand" "=r,r")
4650 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4651 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4652 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4653 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4654 [(set_attr "type" "sseicvt")
4655 (set_attr "prefix" "maybe_vex")
4656 (set_attr "prefix_rex" "1")
4657 (set_attr "mode" "<MODE>")
4658 (set_attr "athlon_decode" "double,vector")
4659 (set_attr "amdfam10_decode" "double,double")
4660 (set_attr "bdver1_decode" "double,double")])
4661
4662 (define_insn "fix_trunc<mode>si_sse"
4663 [(set (match_operand:SI 0 "register_operand" "=r,r")
4664 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4665 "SSE_FLOAT_MODE_P (<MODE>mode)
4666 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4667 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4668 [(set_attr "type" "sseicvt")
4669 (set_attr "prefix" "maybe_vex")
4670 (set_attr "mode" "<MODE>")
4671 (set_attr "athlon_decode" "double,vector")
4672 (set_attr "amdfam10_decode" "double,double")
4673 (set_attr "bdver1_decode" "double,double")])
4674
4675 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4676 (define_peephole2
4677 [(set (match_operand:MODEF 0 "register_operand" "")
4678 (match_operand:MODEF 1 "memory_operand" ""))
4679 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4680 (fix:SSEMODEI24 (match_dup 0)))]
4681 "TARGET_SHORTEN_X87_SSE
4682 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4683 && peep2_reg_dead_p (2, operands[0])"
4684 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4685
4686 ;; Avoid vector decoded forms of the instruction.
4687 (define_peephole2
4688 [(match_scratch:DF 2 "Y2")
4689 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4690 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4691 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4692 [(set (match_dup 2) (match_dup 1))
4693 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4694
4695 (define_peephole2
4696 [(match_scratch:SF 2 "x")
4697 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4698 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4699 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4700 [(set (match_dup 2) (match_dup 1))
4701 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4702
4703 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4704 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4705 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4706 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4707 && TARGET_FISTTP
4708 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4709 && (TARGET_64BIT || <MODE>mode != DImode))
4710 && TARGET_SSE_MATH)
4711 && can_create_pseudo_p ()"
4712 "#"
4713 "&& 1"
4714 [(const_int 0)]
4715 {
4716 if (memory_operand (operands[0], VOIDmode))
4717 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4718 else
4719 {
4720 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4721 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4722 operands[1],
4723 operands[2]));
4724 }
4725 DONE;
4726 }
4727 [(set_attr "type" "fisttp")
4728 (set_attr "mode" "<MODE>")])
4729
4730 (define_insn "fix_trunc<mode>_i387_fisttp"
4731 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4732 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4733 (clobber (match_scratch:XF 2 "=&1f"))]
4734 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && TARGET_FISTTP
4736 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4737 && (TARGET_64BIT || <MODE>mode != DImode))
4738 && TARGET_SSE_MATH)"
4739 "* return output_fix_trunc (insn, operands, 1);"
4740 [(set_attr "type" "fisttp")
4741 (set_attr "mode" "<MODE>")])
4742
4743 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4744 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4745 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4746 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4747 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4748 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4749 && TARGET_FISTTP
4750 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4751 && (TARGET_64BIT || <MODE>mode != DImode))
4752 && TARGET_SSE_MATH)"
4753 "#"
4754 [(set_attr "type" "fisttp")
4755 (set_attr "mode" "<MODE>")])
4756
4757 (define_split
4758 [(set (match_operand:X87MODEI 0 "register_operand" "")
4759 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4760 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4761 (clobber (match_scratch 3 ""))]
4762 "reload_completed"
4763 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4764 (clobber (match_dup 3))])
4765 (set (match_dup 0) (match_dup 2))])
4766
4767 (define_split
4768 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4769 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4770 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4771 (clobber (match_scratch 3 ""))]
4772 "reload_completed"
4773 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4774 (clobber (match_dup 3))])])
4775
4776 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4777 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4778 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4779 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4780 ;; function in i386.c.
4781 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4782 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4783 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4784 (clobber (reg:CC FLAGS_REG))]
4785 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4786 && !TARGET_FISTTP
4787 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4788 && (TARGET_64BIT || <MODE>mode != DImode))
4789 && can_create_pseudo_p ()"
4790 "#"
4791 "&& 1"
4792 [(const_int 0)]
4793 {
4794 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4795
4796 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4797 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4798 if (memory_operand (operands[0], VOIDmode))
4799 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4800 operands[2], operands[3]));
4801 else
4802 {
4803 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4804 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4805 operands[2], operands[3],
4806 operands[4]));
4807 }
4808 DONE;
4809 }
4810 [(set_attr "type" "fistp")
4811 (set_attr "i387_cw" "trunc")
4812 (set_attr "mode" "<MODE>")])
4813
4814 (define_insn "fix_truncdi_i387"
4815 [(set (match_operand:DI 0 "memory_operand" "=m")
4816 (fix:DI (match_operand 1 "register_operand" "f")))
4817 (use (match_operand:HI 2 "memory_operand" "m"))
4818 (use (match_operand:HI 3 "memory_operand" "m"))
4819 (clobber (match_scratch:XF 4 "=&1f"))]
4820 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4821 && !TARGET_FISTTP
4822 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4823 "* return output_fix_trunc (insn, operands, 0);"
4824 [(set_attr "type" "fistp")
4825 (set_attr "i387_cw" "trunc")
4826 (set_attr "mode" "DI")])
4827
4828 (define_insn "fix_truncdi_i387_with_temp"
4829 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4830 (fix:DI (match_operand 1 "register_operand" "f,f")))
4831 (use (match_operand:HI 2 "memory_operand" "m,m"))
4832 (use (match_operand:HI 3 "memory_operand" "m,m"))
4833 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4834 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4835 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4836 && !TARGET_FISTTP
4837 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4838 "#"
4839 [(set_attr "type" "fistp")
4840 (set_attr "i387_cw" "trunc")
4841 (set_attr "mode" "DI")])
4842
4843 (define_split
4844 [(set (match_operand:DI 0 "register_operand" "")
4845 (fix:DI (match_operand 1 "register_operand" "")))
4846 (use (match_operand:HI 2 "memory_operand" ""))
4847 (use (match_operand:HI 3 "memory_operand" ""))
4848 (clobber (match_operand:DI 4 "memory_operand" ""))
4849 (clobber (match_scratch 5 ""))]
4850 "reload_completed"
4851 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4852 (use (match_dup 2))
4853 (use (match_dup 3))
4854 (clobber (match_dup 5))])
4855 (set (match_dup 0) (match_dup 4))])
4856
4857 (define_split
4858 [(set (match_operand:DI 0 "memory_operand" "")
4859 (fix:DI (match_operand 1 "register_operand" "")))
4860 (use (match_operand:HI 2 "memory_operand" ""))
4861 (use (match_operand:HI 3 "memory_operand" ""))
4862 (clobber (match_operand:DI 4 "memory_operand" ""))
4863 (clobber (match_scratch 5 ""))]
4864 "reload_completed"
4865 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4866 (use (match_dup 2))
4867 (use (match_dup 3))
4868 (clobber (match_dup 5))])])
4869
4870 (define_insn "fix_trunc<mode>_i387"
4871 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4872 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4873 (use (match_operand:HI 2 "memory_operand" "m"))
4874 (use (match_operand:HI 3 "memory_operand" "m"))]
4875 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4876 && !TARGET_FISTTP
4877 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4878 "* return output_fix_trunc (insn, operands, 0);"
4879 [(set_attr "type" "fistp")
4880 (set_attr "i387_cw" "trunc")
4881 (set_attr "mode" "<MODE>")])
4882
4883 (define_insn "fix_trunc<mode>_i387_with_temp"
4884 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4885 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4886 (use (match_operand:HI 2 "memory_operand" "m,m"))
4887 (use (match_operand:HI 3 "memory_operand" "m,m"))
4888 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4889 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4890 && !TARGET_FISTTP
4891 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4892 "#"
4893 [(set_attr "type" "fistp")
4894 (set_attr "i387_cw" "trunc")
4895 (set_attr "mode" "<MODE>")])
4896
4897 (define_split
4898 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4899 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4900 (use (match_operand:HI 2 "memory_operand" ""))
4901 (use (match_operand:HI 3 "memory_operand" ""))
4902 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4903 "reload_completed"
4904 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4905 (use (match_dup 2))
4906 (use (match_dup 3))])
4907 (set (match_dup 0) (match_dup 4))])
4908
4909 (define_split
4910 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4911 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4912 (use (match_operand:HI 2 "memory_operand" ""))
4913 (use (match_operand:HI 3 "memory_operand" ""))
4914 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4915 "reload_completed"
4916 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4917 (use (match_dup 2))
4918 (use (match_dup 3))])])
4919
4920 (define_insn "x86_fnstcw_1"
4921 [(set (match_operand:HI 0 "memory_operand" "=m")
4922 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4923 "TARGET_80387"
4924 "fnstcw\t%0"
4925 [(set (attr "length")
4926 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4927 (set_attr "mode" "HI")
4928 (set_attr "unit" "i387")
4929 (set_attr "bdver1_decode" "vector")])
4930
4931 (define_insn "x86_fldcw_1"
4932 [(set (reg:HI FPCR_REG)
4933 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4934 "TARGET_80387"
4935 "fldcw\t%0"
4936 [(set (attr "length")
4937 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4938 (set_attr "mode" "HI")
4939 (set_attr "unit" "i387")
4940 (set_attr "athlon_decode" "vector")
4941 (set_attr "amdfam10_decode" "vector")
4942 (set_attr "bdver1_decode" "vector")])
4943 \f
4944 ;; Conversion between fixed point and floating point.
4945
4946 ;; Even though we only accept memory inputs, the backend _really_
4947 ;; wants to be able to do this between registers.
4948
4949 (define_expand "floathi<mode>2"
4950 [(set (match_operand:X87MODEF 0 "register_operand" "")
4951 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4952 "TARGET_80387
4953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4954 || TARGET_MIX_SSE_I387)")
4955
4956 ;; Pre-reload splitter to add memory clobber to the pattern.
4957 (define_insn_and_split "*floathi<mode>2_1"
4958 [(set (match_operand:X87MODEF 0 "register_operand" "")
4959 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4960 "TARGET_80387
4961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4962 || TARGET_MIX_SSE_I387)
4963 && can_create_pseudo_p ()"
4964 "#"
4965 "&& 1"
4966 [(parallel [(set (match_dup 0)
4967 (float:X87MODEF (match_dup 1)))
4968 (clobber (match_dup 2))])]
4969 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4970
4971 (define_insn "*floathi<mode>2_i387_with_temp"
4972 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4973 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4974 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4975 "TARGET_80387
4976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4977 || TARGET_MIX_SSE_I387)"
4978 "#"
4979 [(set_attr "type" "fmov,multi")
4980 (set_attr "mode" "<MODE>")
4981 (set_attr "unit" "*,i387")
4982 (set_attr "fp_int_src" "true")])
4983
4984 (define_insn "*floathi<mode>2_i387"
4985 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4986 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4987 "TARGET_80387
4988 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4989 || TARGET_MIX_SSE_I387)"
4990 "fild%Z1\t%1"
4991 [(set_attr "type" "fmov")
4992 (set_attr "mode" "<MODE>")
4993 (set_attr "fp_int_src" "true")])
4994
4995 (define_split
4996 [(set (match_operand:X87MODEF 0 "register_operand" "")
4997 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4998 (clobber (match_operand:HI 2 "memory_operand" ""))]
4999 "TARGET_80387
5000 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5001 || TARGET_MIX_SSE_I387)
5002 && reload_completed"
5003 [(set (match_dup 2) (match_dup 1))
5004 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5005
5006 (define_split
5007 [(set (match_operand:X87MODEF 0 "register_operand" "")
5008 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5009 (clobber (match_operand:HI 2 "memory_operand" ""))]
5010 "TARGET_80387
5011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5012 || TARGET_MIX_SSE_I387)
5013 && reload_completed"
5014 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5015
5016 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5017 [(set (match_operand:X87MODEF 0 "register_operand" "")
5018 (float:X87MODEF
5019 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5020 "TARGET_80387
5021 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5022 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5023 {
5024 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5025 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5026 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5027 {
5028 rtx reg = gen_reg_rtx (XFmode);
5029 rtx (*insn)(rtx, rtx);
5030
5031 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5032
5033 if (<X87MODEF:MODE>mode == SFmode)
5034 insn = gen_truncxfsf2;
5035 else if (<X87MODEF:MODE>mode == DFmode)
5036 insn = gen_truncxfdf2;
5037 else
5038 gcc_unreachable ();
5039
5040 emit_insn (insn (operands[0], reg));
5041 DONE;
5042 }
5043 })
5044
5045 ;; Pre-reload splitter to add memory clobber to the pattern.
5046 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5047 [(set (match_operand:X87MODEF 0 "register_operand" "")
5048 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5049 "((TARGET_80387
5050 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5051 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5052 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5053 || TARGET_MIX_SSE_I387))
5054 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5055 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5056 && ((<SSEMODEI24:MODE>mode == SImode
5057 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5058 && optimize_function_for_speed_p (cfun)
5059 && flag_trapping_math)
5060 || !(TARGET_INTER_UNIT_CONVERSIONS
5061 || optimize_function_for_size_p (cfun)))))
5062 && can_create_pseudo_p ()"
5063 "#"
5064 "&& 1"
5065 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5066 (clobber (match_dup 2))])]
5067 {
5068 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5069
5070 /* Avoid store forwarding (partial memory) stall penalty
5071 by passing DImode value through XMM registers. */
5072 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5073 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5074 && optimize_function_for_speed_p (cfun))
5075 {
5076 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5077 operands[1],
5078 operands[2]));
5079 DONE;
5080 }
5081 })
5082
5083 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5084 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5085 (float:MODEF
5086 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5087 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5088 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5089 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5090 "#"
5091 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5092 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5093 (set_attr "unit" "*,i387,*,*,*")
5094 (set_attr "athlon_decode" "*,*,double,direct,double")
5095 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5096 (set_attr "bdver1_decode" "*,*,double,direct,double")
5097 (set_attr "fp_int_src" "true")])
5098
5099 (define_insn "*floatsi<mode>2_vector_mixed"
5100 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5101 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5102 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5103 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5104 "@
5105 fild%Z1\t%1
5106 #"
5107 [(set_attr "type" "fmov,sseicvt")
5108 (set_attr "mode" "<MODE>,<ssevecmode>")
5109 (set_attr "unit" "i387,*")
5110 (set_attr "athlon_decode" "*,direct")
5111 (set_attr "amdfam10_decode" "*,double")
5112 (set_attr "bdver1_decode" "*,direct")
5113 (set_attr "fp_int_src" "true")])
5114
5115 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5116 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5117 (float:MODEF
5118 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5119 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5120 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5121 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5122 "#"
5123 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5124 (set_attr "mode" "<MODEF:MODE>")
5125 (set_attr "unit" "*,i387,*,*")
5126 (set_attr "athlon_decode" "*,*,double,direct")
5127 (set_attr "amdfam10_decode" "*,*,vector,double")
5128 (set_attr "bdver1_decode" "*,*,double,direct")
5129 (set_attr "fp_int_src" "true")])
5130
5131 (define_split
5132 [(set (match_operand:MODEF 0 "register_operand" "")
5133 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5134 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5135 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5136 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5137 && TARGET_INTER_UNIT_CONVERSIONS
5138 && reload_completed
5139 && (SSE_REG_P (operands[0])
5140 || (GET_CODE (operands[0]) == SUBREG
5141 && SSE_REG_P (operands[0])))"
5142 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5143
5144 (define_split
5145 [(set (match_operand:MODEF 0 "register_operand" "")
5146 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5147 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5148 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5149 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5150 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5151 && reload_completed
5152 && (SSE_REG_P (operands[0])
5153 || (GET_CODE (operands[0]) == SUBREG
5154 && SSE_REG_P (operands[0])))"
5155 [(set (match_dup 2) (match_dup 1))
5156 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5157
5158 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5159 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5160 (float:MODEF
5161 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5162 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5163 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5164 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5165 "@
5166 fild%Z1\t%1
5167 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5168 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5169 [(set_attr "type" "fmov,sseicvt,sseicvt")
5170 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5171 (set_attr "mode" "<MODEF:MODE>")
5172 (set (attr "prefix_rex")
5173 (if_then_else
5174 (and (eq_attr "prefix" "maybe_vex")
5175 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5176 (const_string "1")
5177 (const_string "*")))
5178 (set_attr "unit" "i387,*,*")
5179 (set_attr "athlon_decode" "*,double,direct")
5180 (set_attr "amdfam10_decode" "*,vector,double")
5181 (set_attr "bdver1_decode" "*,double,direct")
5182 (set_attr "fp_int_src" "true")])
5183
5184 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5185 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5186 (float:MODEF
5187 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5188 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5189 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5190 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5191 "@
5192 fild%Z1\t%1
5193 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5194 [(set_attr "type" "fmov,sseicvt")
5195 (set_attr "prefix" "orig,maybe_vex")
5196 (set_attr "mode" "<MODEF:MODE>")
5197 (set (attr "prefix_rex")
5198 (if_then_else
5199 (and (eq_attr "prefix" "maybe_vex")
5200 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5201 (const_string "1")
5202 (const_string "*")))
5203 (set_attr "athlon_decode" "*,direct")
5204 (set_attr "amdfam10_decode" "*,double")
5205 (set_attr "bdver1_decode" "*,direct")
5206 (set_attr "fp_int_src" "true")])
5207
5208 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5209 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5210 (float:MODEF
5211 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5212 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5213 "TARGET_SSE2 && TARGET_SSE_MATH
5214 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5215 "#"
5216 [(set_attr "type" "sseicvt")
5217 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5218 (set_attr "athlon_decode" "double,direct,double")
5219 (set_attr "amdfam10_decode" "vector,double,double")
5220 (set_attr "bdver1_decode" "double,direct,double")
5221 (set_attr "fp_int_src" "true")])
5222
5223 (define_insn "*floatsi<mode>2_vector_sse"
5224 [(set (match_operand:MODEF 0 "register_operand" "=x")
5225 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5226 "TARGET_SSE2 && TARGET_SSE_MATH
5227 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5228 "#"
5229 [(set_attr "type" "sseicvt")
5230 (set_attr "mode" "<MODE>")
5231 (set_attr "athlon_decode" "direct")
5232 (set_attr "amdfam10_decode" "double")
5233 (set_attr "bdver1_decode" "direct")
5234 (set_attr "fp_int_src" "true")])
5235
5236 (define_split
5237 [(set (match_operand:MODEF 0 "register_operand" "")
5238 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5239 (clobber (match_operand:SI 2 "memory_operand" ""))]
5240 "TARGET_SSE2 && TARGET_SSE_MATH
5241 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5242 && reload_completed
5243 && (SSE_REG_P (operands[0])
5244 || (GET_CODE (operands[0]) == SUBREG
5245 && SSE_REG_P (operands[0])))"
5246 [(const_int 0)]
5247 {
5248 rtx op1 = operands[1];
5249
5250 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5251 <MODE>mode, 0);
5252 if (GET_CODE (op1) == SUBREG)
5253 op1 = SUBREG_REG (op1);
5254
5255 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5256 {
5257 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5258 emit_insn (gen_sse2_loadld (operands[4],
5259 CONST0_RTX (V4SImode), operands[1]));
5260 }
5261 /* We can ignore possible trapping value in the
5262 high part of SSE register for non-trapping math. */
5263 else if (SSE_REG_P (op1) && !flag_trapping_math)
5264 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5265 else
5266 {
5267 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5268 emit_move_insn (operands[2], operands[1]);
5269 emit_insn (gen_sse2_loadld (operands[4],
5270 CONST0_RTX (V4SImode), operands[2]));
5271 }
5272 emit_insn
5273 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5274 DONE;
5275 })
5276
5277 (define_split
5278 [(set (match_operand:MODEF 0 "register_operand" "")
5279 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5280 (clobber (match_operand:SI 2 "memory_operand" ""))]
5281 "TARGET_SSE2 && TARGET_SSE_MATH
5282 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5283 && reload_completed
5284 && (SSE_REG_P (operands[0])
5285 || (GET_CODE (operands[0]) == SUBREG
5286 && SSE_REG_P (operands[0])))"
5287 [(const_int 0)]
5288 {
5289 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5290 <MODE>mode, 0);
5291 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5292
5293 emit_insn (gen_sse2_loadld (operands[4],
5294 CONST0_RTX (V4SImode), operands[1]));
5295 emit_insn
5296 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5297 DONE;
5298 })
5299
5300 (define_split
5301 [(set (match_operand:MODEF 0 "register_operand" "")
5302 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5303 "TARGET_SSE2 && TARGET_SSE_MATH
5304 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5305 && reload_completed
5306 && (SSE_REG_P (operands[0])
5307 || (GET_CODE (operands[0]) == SUBREG
5308 && SSE_REG_P (operands[0])))"
5309 [(const_int 0)]
5310 {
5311 rtx op1 = operands[1];
5312
5313 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5314 <MODE>mode, 0);
5315 if (GET_CODE (op1) == SUBREG)
5316 op1 = SUBREG_REG (op1);
5317
5318 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5319 {
5320 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5321 emit_insn (gen_sse2_loadld (operands[4],
5322 CONST0_RTX (V4SImode), operands[1]));
5323 }
5324 /* We can ignore possible trapping value in the
5325 high part of SSE register for non-trapping math. */
5326 else if (SSE_REG_P (op1) && !flag_trapping_math)
5327 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5328 else
5329 gcc_unreachable ();
5330 emit_insn
5331 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5332 DONE;
5333 })
5334
5335 (define_split
5336 [(set (match_operand:MODEF 0 "register_operand" "")
5337 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5338 "TARGET_SSE2 && TARGET_SSE_MATH
5339 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5340 && reload_completed
5341 && (SSE_REG_P (operands[0])
5342 || (GET_CODE (operands[0]) == SUBREG
5343 && SSE_REG_P (operands[0])))"
5344 [(const_int 0)]
5345 {
5346 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5347 <MODE>mode, 0);
5348 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5349
5350 emit_insn (gen_sse2_loadld (operands[4],
5351 CONST0_RTX (V4SImode), operands[1]));
5352 emit_insn
5353 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5354 DONE;
5355 })
5356
5357 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5358 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5359 (float:MODEF
5360 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5361 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5362 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5363 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5364 "#"
5365 [(set_attr "type" "sseicvt")
5366 (set_attr "mode" "<MODEF:MODE>")
5367 (set_attr "athlon_decode" "double,direct")
5368 (set_attr "amdfam10_decode" "vector,double")
5369 (set_attr "bdver1_decode" "double,direct")
5370 (set_attr "fp_int_src" "true")])
5371
5372 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5373 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5374 (float:MODEF
5375 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5376 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5377 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5378 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5379 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5380 [(set_attr "type" "sseicvt")
5381 (set_attr "prefix" "maybe_vex")
5382 (set_attr "mode" "<MODEF:MODE>")
5383 (set (attr "prefix_rex")
5384 (if_then_else
5385 (and (eq_attr "prefix" "maybe_vex")
5386 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5387 (const_string "1")
5388 (const_string "*")))
5389 (set_attr "athlon_decode" "double,direct")
5390 (set_attr "amdfam10_decode" "vector,double")
5391 (set_attr "bdver1_decode" "double,direct")
5392 (set_attr "fp_int_src" "true")])
5393
5394 (define_split
5395 [(set (match_operand:MODEF 0 "register_operand" "")
5396 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5397 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5398 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5399 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5400 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5401 && reload_completed
5402 && (SSE_REG_P (operands[0])
5403 || (GET_CODE (operands[0]) == SUBREG
5404 && SSE_REG_P (operands[0])))"
5405 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5406
5407 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5408 [(set (match_operand:MODEF 0 "register_operand" "=x")
5409 (float:MODEF
5410 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5411 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5412 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5413 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5414 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5415 [(set_attr "type" "sseicvt")
5416 (set_attr "prefix" "maybe_vex")
5417 (set_attr "mode" "<MODEF:MODE>")
5418 (set (attr "prefix_rex")
5419 (if_then_else
5420 (and (eq_attr "prefix" "maybe_vex")
5421 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5422 (const_string "1")
5423 (const_string "*")))
5424 (set_attr "athlon_decode" "direct")
5425 (set_attr "amdfam10_decode" "double")
5426 (set_attr "bdver1_decode" "direct")
5427 (set_attr "fp_int_src" "true")])
5428
5429 (define_split
5430 [(set (match_operand:MODEF 0 "register_operand" "")
5431 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5432 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5433 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5434 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5435 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5436 && reload_completed
5437 && (SSE_REG_P (operands[0])
5438 || (GET_CODE (operands[0]) == SUBREG
5439 && SSE_REG_P (operands[0])))"
5440 [(set (match_dup 2) (match_dup 1))
5441 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5442
5443 (define_split
5444 [(set (match_operand:MODEF 0 "register_operand" "")
5445 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5446 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5447 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5448 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5449 && reload_completed
5450 && (SSE_REG_P (operands[0])
5451 || (GET_CODE (operands[0]) == SUBREG
5452 && SSE_REG_P (operands[0])))"
5453 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5454
5455 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5456 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5457 (float:X87MODEF
5458 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5459 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5460 "TARGET_80387
5461 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5462 "@
5463 fild%Z1\t%1
5464 #"
5465 [(set_attr "type" "fmov,multi")
5466 (set_attr "mode" "<X87MODEF:MODE>")
5467 (set_attr "unit" "*,i387")
5468 (set_attr "fp_int_src" "true")])
5469
5470 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5471 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5472 (float:X87MODEF
5473 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5474 "TARGET_80387
5475 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5476 "fild%Z1\t%1"
5477 [(set_attr "type" "fmov")
5478 (set_attr "mode" "<X87MODEF:MODE>")
5479 (set_attr "fp_int_src" "true")])
5480
5481 (define_split
5482 [(set (match_operand:X87MODEF 0 "register_operand" "")
5483 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5484 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5485 "TARGET_80387
5486 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5487 && reload_completed
5488 && FP_REG_P (operands[0])"
5489 [(set (match_dup 2) (match_dup 1))
5490 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5491
5492 (define_split
5493 [(set (match_operand:X87MODEF 0 "register_operand" "")
5494 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5495 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5496 "TARGET_80387
5497 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5498 && reload_completed
5499 && FP_REG_P (operands[0])"
5500 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5501
5502 ;; Avoid store forwarding (partial memory) stall penalty
5503 ;; by passing DImode value through XMM registers. */
5504
5505 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5506 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5507 (float:X87MODEF
5508 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5509 (clobber (match_scratch:V4SI 3 "=X,x"))
5510 (clobber (match_scratch:V4SI 4 "=X,x"))
5511 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5512 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5513 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5514 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5515 "#"
5516 [(set_attr "type" "multi")
5517 (set_attr "mode" "<X87MODEF:MODE>")
5518 (set_attr "unit" "i387")
5519 (set_attr "fp_int_src" "true")])
5520
5521 (define_split
5522 [(set (match_operand:X87MODEF 0 "register_operand" "")
5523 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5524 (clobber (match_scratch:V4SI 3 ""))
5525 (clobber (match_scratch:V4SI 4 ""))
5526 (clobber (match_operand:DI 2 "memory_operand" ""))]
5527 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5528 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5529 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5530 && reload_completed
5531 && FP_REG_P (operands[0])"
5532 [(set (match_dup 2) (match_dup 3))
5533 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5534 {
5535 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5536 Assemble the 64-bit DImode value in an xmm register. */
5537 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5538 gen_rtx_SUBREG (SImode, operands[1], 0)));
5539 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5540 gen_rtx_SUBREG (SImode, operands[1], 4)));
5541 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5542 operands[4]));
5543
5544 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5545 })
5546
5547 (define_split
5548 [(set (match_operand:X87MODEF 0 "register_operand" "")
5549 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5550 (clobber (match_scratch:V4SI 3 ""))
5551 (clobber (match_scratch:V4SI 4 ""))
5552 (clobber (match_operand:DI 2 "memory_operand" ""))]
5553 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5554 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5555 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5556 && reload_completed
5557 && FP_REG_P (operands[0])"
5558 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5559
5560 ;; Avoid store forwarding (partial memory) stall penalty by extending
5561 ;; SImode value to DImode through XMM register instead of pushing two
5562 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5563 ;; targets benefit from this optimization. Also note that fild
5564 ;; loads from memory only.
5565
5566 (define_insn "*floatunssi<mode>2_1"
5567 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5568 (unsigned_float:X87MODEF
5569 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5570 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5571 (clobber (match_scratch:SI 3 "=X,x"))]
5572 "!TARGET_64BIT
5573 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5574 && TARGET_SSE"
5575 "#"
5576 [(set_attr "type" "multi")
5577 (set_attr "mode" "<MODE>")])
5578
5579 (define_split
5580 [(set (match_operand:X87MODEF 0 "register_operand" "")
5581 (unsigned_float:X87MODEF
5582 (match_operand:SI 1 "register_operand" "")))
5583 (clobber (match_operand:DI 2 "memory_operand" ""))
5584 (clobber (match_scratch:SI 3 ""))]
5585 "!TARGET_64BIT
5586 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5587 && TARGET_SSE
5588 && reload_completed"
5589 [(set (match_dup 2) (match_dup 1))
5590 (set (match_dup 0)
5591 (float:X87MODEF (match_dup 2)))]
5592 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5593
5594 (define_split
5595 [(set (match_operand:X87MODEF 0 "register_operand" "")
5596 (unsigned_float:X87MODEF
5597 (match_operand:SI 1 "memory_operand" "")))
5598 (clobber (match_operand:DI 2 "memory_operand" ""))
5599 (clobber (match_scratch:SI 3 ""))]
5600 "!TARGET_64BIT
5601 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5602 && TARGET_SSE
5603 && reload_completed"
5604 [(set (match_dup 2) (match_dup 3))
5605 (set (match_dup 0)
5606 (float:X87MODEF (match_dup 2)))]
5607 {
5608 emit_move_insn (operands[3], operands[1]);
5609 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5610 })
5611
5612 (define_expand "floatunssi<mode>2"
5613 [(parallel
5614 [(set (match_operand:X87MODEF 0 "register_operand" "")
5615 (unsigned_float:X87MODEF
5616 (match_operand:SI 1 "nonimmediate_operand" "")))
5617 (clobber (match_dup 2))
5618 (clobber (match_scratch:SI 3 ""))])]
5619 "!TARGET_64BIT
5620 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5621 && TARGET_SSE)
5622 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5623 {
5624 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5625 {
5626 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5627 DONE;
5628 }
5629 else
5630 {
5631 enum ix86_stack_slot slot = (virtuals_instantiated
5632 ? SLOT_TEMP
5633 : SLOT_VIRTUAL);
5634 operands[2] = assign_386_stack_local (DImode, slot);
5635 }
5636 })
5637
5638 (define_expand "floatunsdisf2"
5639 [(use (match_operand:SF 0 "register_operand" ""))
5640 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5641 "TARGET_64BIT && TARGET_SSE_MATH"
5642 "x86_emit_floatuns (operands); DONE;")
5643
5644 (define_expand "floatunsdidf2"
5645 [(use (match_operand:DF 0 "register_operand" ""))
5646 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5647 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5648 && TARGET_SSE2 && TARGET_SSE_MATH"
5649 {
5650 if (TARGET_64BIT)
5651 x86_emit_floatuns (operands);
5652 else
5653 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5654 DONE;
5655 })
5656 \f
5657 ;; Add instructions
5658
5659 (define_expand "add<mode>3"
5660 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5661 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5662 (match_operand:SDWIM 2 "<general_operand>" "")))]
5663 ""
5664 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5665
5666 (define_insn_and_split "*add<dwi>3_doubleword"
5667 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5668 (plus:<DWI>
5669 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5670 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5671 (clobber (reg:CC FLAGS_REG))]
5672 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5673 "#"
5674 "reload_completed"
5675 [(parallel [(set (reg:CC FLAGS_REG)
5676 (unspec:CC [(match_dup 1) (match_dup 2)]
5677 UNSPEC_ADD_CARRY))
5678 (set (match_dup 0)
5679 (plus:DWIH (match_dup 1) (match_dup 2)))])
5680 (parallel [(set (match_dup 3)
5681 (plus:DWIH
5682 (match_dup 4)
5683 (plus:DWIH
5684 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5685 (match_dup 5))))
5686 (clobber (reg:CC FLAGS_REG))])]
5687 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5688
5689 (define_insn "*add<mode>3_cc"
5690 [(set (reg:CC FLAGS_REG)
5691 (unspec:CC
5692 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5693 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5694 UNSPEC_ADD_CARRY))
5695 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5696 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5697 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5698 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5699 [(set_attr "type" "alu")
5700 (set_attr "mode" "<MODE>")])
5701
5702 (define_insn "addqi3_cc"
5703 [(set (reg:CC FLAGS_REG)
5704 (unspec:CC
5705 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5706 (match_operand:QI 2 "general_operand" "qn,qm")]
5707 UNSPEC_ADD_CARRY))
5708 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5709 (plus:QI (match_dup 1) (match_dup 2)))]
5710 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5711 "add{b}\t{%2, %0|%0, %2}"
5712 [(set_attr "type" "alu")
5713 (set_attr "mode" "QI")])
5714
5715 (define_insn "*lea_1"
5716 [(set (match_operand:P 0 "register_operand" "=r")
5717 (match_operand:P 1 "no_seg_address_operand" "p"))]
5718 ""
5719 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5720 [(set_attr "type" "lea")
5721 (set_attr "mode" "<MODE>")])
5722
5723 (define_insn "*lea_2"
5724 [(set (match_operand:SI 0 "register_operand" "=r")
5725 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5726 "TARGET_64BIT"
5727 "lea{l}\t{%a1, %0|%0, %a1}"
5728 [(set_attr "type" "lea")
5729 (set_attr "mode" "SI")])
5730
5731 (define_insn "*lea_2_zext"
5732 [(set (match_operand:DI 0 "register_operand" "=r")
5733 (zero_extend:DI
5734 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5735 "TARGET_64BIT"
5736 "lea{l}\t{%a1, %k0|%k0, %a1}"
5737 [(set_attr "type" "lea")
5738 (set_attr "mode" "SI")])
5739
5740 (define_insn "*add<mode>_1"
5741 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5742 (plus:SWI48
5743 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5744 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5745 (clobber (reg:CC FLAGS_REG))]
5746 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5747 {
5748 switch (get_attr_type (insn))
5749 {
5750 case TYPE_LEA:
5751 return "#";
5752
5753 case TYPE_INCDEC:
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 if (operands[2] == const1_rtx)
5756 return "inc{<imodesuffix>}\t%0";
5757 else
5758 {
5759 gcc_assert (operands[2] == constm1_rtx);
5760 return "dec{<imodesuffix>}\t%0";
5761 }
5762
5763 default:
5764 /* For most processors, ADD is faster than LEA. This alternative
5765 was added to use ADD as much as possible. */
5766 if (which_alternative == 2)
5767 {
5768 rtx tmp;
5769 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5770 }
5771
5772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5774 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5775
5776 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5777 }
5778 }
5779 [(set (attr "type")
5780 (cond [(eq_attr "alternative" "3")
5781 (const_string "lea")
5782 (match_operand:SWI48 2 "incdec_operand" "")
5783 (const_string "incdec")
5784 ]
5785 (const_string "alu")))
5786 (set (attr "length_immediate")
5787 (if_then_else
5788 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5789 (const_string "1")
5790 (const_string "*")))
5791 (set_attr "mode" "<MODE>")])
5792
5793 ;; It may seem that nonimmediate operand is proper one for operand 1.
5794 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5795 ;; we take care in ix86_binary_operator_ok to not allow two memory
5796 ;; operands so proper swapping will be done in reload. This allow
5797 ;; patterns constructed from addsi_1 to match.
5798
5799 (define_insn "*addsi_1_zext"
5800 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5801 (zero_extend:DI
5802 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5803 (match_operand:SI 2 "general_operand" "g,0,li"))))
5804 (clobber (reg:CC FLAGS_REG))]
5805 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5806 {
5807 switch (get_attr_type (insn))
5808 {
5809 case TYPE_LEA:
5810 return "#";
5811
5812 case TYPE_INCDEC:
5813 if (operands[2] == const1_rtx)
5814 return "inc{l}\t%k0";
5815 else
5816 {
5817 gcc_assert (operands[2] == constm1_rtx);
5818 return "dec{l}\t%k0";
5819 }
5820
5821 default:
5822 /* For most processors, ADD is faster than LEA. This alternative
5823 was added to use ADD as much as possible. */
5824 if (which_alternative == 1)
5825 {
5826 rtx tmp;
5827 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5828 }
5829
5830 if (x86_maybe_negate_const_int (&operands[2], SImode))
5831 return "sub{l}\t{%2, %k0|%k0, %2}";
5832
5833 return "add{l}\t{%2, %k0|%k0, %2}";
5834 }
5835 }
5836 [(set (attr "type")
5837 (cond [(eq_attr "alternative" "2")
5838 (const_string "lea")
5839 (match_operand:SI 2 "incdec_operand" "")
5840 (const_string "incdec")
5841 ]
5842 (const_string "alu")))
5843 (set (attr "length_immediate")
5844 (if_then_else
5845 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5846 (const_string "1")
5847 (const_string "*")))
5848 (set_attr "mode" "SI")])
5849
5850 (define_insn "*addhi_1"
5851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5852 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5853 (match_operand:HI 2 "general_operand" "rn,rm")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "TARGET_PARTIAL_REG_STALL
5856 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5857 {
5858 switch (get_attr_type (insn))
5859 {
5860 case TYPE_INCDEC:
5861 if (operands[2] == const1_rtx)
5862 return "inc{w}\t%0";
5863 else
5864 {
5865 gcc_assert (operands[2] == constm1_rtx);
5866 return "dec{w}\t%0";
5867 }
5868
5869 default:
5870 if (x86_maybe_negate_const_int (&operands[2], HImode))
5871 return "sub{w}\t{%2, %0|%0, %2}";
5872
5873 return "add{w}\t{%2, %0|%0, %2}";
5874 }
5875 }
5876 [(set (attr "type")
5877 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5878 (const_string "incdec")
5879 (const_string "alu")))
5880 (set (attr "length_immediate")
5881 (if_then_else
5882 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5883 (const_string "1")
5884 (const_string "*")))
5885 (set_attr "mode" "HI")])
5886
5887 (define_insn "*addhi_1_lea"
5888 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5889 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5890 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5891 (clobber (reg:CC FLAGS_REG))]
5892 "!TARGET_PARTIAL_REG_STALL
5893 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5894 {
5895 switch (get_attr_type (insn))
5896 {
5897 case TYPE_LEA:
5898 return "#";
5899
5900 case TYPE_INCDEC:
5901 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5902 if (operands[2] == const1_rtx)
5903 return "inc{w}\t%0";
5904 else
5905 {
5906 gcc_assert (operands[2] == constm1_rtx);
5907 return "dec{w}\t%0";
5908 }
5909
5910 default:
5911 /* For most processors, ADD is faster than LEA. This alternative
5912 was added to use ADD as much as possible. */
5913 if (which_alternative == 2)
5914 {
5915 rtx tmp;
5916 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5917 }
5918
5919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920 if (x86_maybe_negate_const_int (&operands[2], HImode))
5921 return "sub{w}\t{%2, %0|%0, %2}";
5922
5923 return "add{w}\t{%2, %0|%0, %2}";
5924 }
5925 }
5926 [(set (attr "type")
5927 (cond [(eq_attr "alternative" "3")
5928 (const_string "lea")
5929 (match_operand:HI 2 "incdec_operand" "")
5930 (const_string "incdec")
5931 ]
5932 (const_string "alu")))
5933 (set (attr "length_immediate")
5934 (if_then_else
5935 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5936 (const_string "1")
5937 (const_string "*")))
5938 (set_attr "mode" "HI,HI,HI,SI")])
5939
5940 ;; %%% Potential partial reg stall on alternative 2. What to do?
5941 (define_insn "*addqi_1"
5942 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5943 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5944 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5945 (clobber (reg:CC FLAGS_REG))]
5946 "TARGET_PARTIAL_REG_STALL
5947 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5948 {
5949 int widen = (which_alternative == 2);
5950 switch (get_attr_type (insn))
5951 {
5952 case TYPE_INCDEC:
5953 if (operands[2] == const1_rtx)
5954 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5955 else
5956 {
5957 gcc_assert (operands[2] == constm1_rtx);
5958 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5959 }
5960
5961 default:
5962 if (x86_maybe_negate_const_int (&operands[2], QImode))
5963 {
5964 if (widen)
5965 return "sub{l}\t{%2, %k0|%k0, %2}";
5966 else
5967 return "sub{b}\t{%2, %0|%0, %2}";
5968 }
5969 if (widen)
5970 return "add{l}\t{%k2, %k0|%k0, %k2}";
5971 else
5972 return "add{b}\t{%2, %0|%0, %2}";
5973 }
5974 }
5975 [(set (attr "type")
5976 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5977 (const_string "incdec")
5978 (const_string "alu")))
5979 (set (attr "length_immediate")
5980 (if_then_else
5981 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5982 (const_string "1")
5983 (const_string "*")))
5984 (set_attr "mode" "QI,QI,SI")])
5985
5986 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5987 (define_insn "*addqi_1_lea"
5988 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5989 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5990 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5991 (clobber (reg:CC FLAGS_REG))]
5992 "!TARGET_PARTIAL_REG_STALL
5993 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5994 {
5995 int widen = (which_alternative == 3 || which_alternative == 4);
5996
5997 switch (get_attr_type (insn))
5998 {
5999 case TYPE_LEA:
6000 return "#";
6001
6002 case TYPE_INCDEC:
6003 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6004 if (operands[2] == const1_rtx)
6005 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6006 else
6007 {
6008 gcc_assert (operands[2] == constm1_rtx);
6009 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6010 }
6011
6012 default:
6013 /* For most processors, ADD is faster than LEA. These alternatives
6014 were added to use ADD as much as possible. */
6015 if (which_alternative == 2 || which_alternative == 4)
6016 {
6017 rtx tmp;
6018 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6019 }
6020
6021 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022 if (x86_maybe_negate_const_int (&operands[2], QImode))
6023 {
6024 if (widen)
6025 return "sub{l}\t{%2, %k0|%k0, %2}";
6026 else
6027 return "sub{b}\t{%2, %0|%0, %2}";
6028 }
6029 if (widen)
6030 return "add{l}\t{%k2, %k0|%k0, %k2}";
6031 else
6032 return "add{b}\t{%2, %0|%0, %2}";
6033 }
6034 }
6035 [(set (attr "type")
6036 (cond [(eq_attr "alternative" "5")
6037 (const_string "lea")
6038 (match_operand:QI 2 "incdec_operand" "")
6039 (const_string "incdec")
6040 ]
6041 (const_string "alu")))
6042 (set (attr "length_immediate")
6043 (if_then_else
6044 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6045 (const_string "1")
6046 (const_string "*")))
6047 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6048
6049 (define_insn "*addqi_1_slp"
6050 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6051 (plus:QI (match_dup 0)
6052 (match_operand:QI 1 "general_operand" "qn,qnm")))
6053 (clobber (reg:CC FLAGS_REG))]
6054 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6055 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6056 {
6057 switch (get_attr_type (insn))
6058 {
6059 case TYPE_INCDEC:
6060 if (operands[1] == const1_rtx)
6061 return "inc{b}\t%0";
6062 else
6063 {
6064 gcc_assert (operands[1] == constm1_rtx);
6065 return "dec{b}\t%0";
6066 }
6067
6068 default:
6069 if (x86_maybe_negate_const_int (&operands[1], QImode))
6070 return "sub{b}\t{%1, %0|%0, %1}";
6071
6072 return "add{b}\t{%1, %0|%0, %1}";
6073 }
6074 }
6075 [(set (attr "type")
6076 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6077 (const_string "incdec")
6078 (const_string "alu1")))
6079 (set (attr "memory")
6080 (if_then_else (match_operand 1 "memory_operand" "")
6081 (const_string "load")
6082 (const_string "none")))
6083 (set_attr "mode" "QI")])
6084
6085 ;; Convert lea to the lea pattern to avoid flags dependency.
6086 (define_split
6087 [(set (match_operand 0 "register_operand" "")
6088 (plus (match_operand 1 "register_operand" "")
6089 (match_operand 2 "nonmemory_operand" "")))
6090 (clobber (reg:CC FLAGS_REG))]
6091 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6092 [(const_int 0)]
6093 {
6094 rtx pat;
6095 enum machine_mode mode = GET_MODE (operands[0]);
6096
6097 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6098 may confuse gen_lowpart. */
6099 if (mode != Pmode)
6100 {
6101 operands[1] = gen_lowpart (Pmode, operands[1]);
6102 operands[2] = gen_lowpart (Pmode, operands[2]);
6103 }
6104
6105 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6106
6107 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6108 operands[0] = gen_lowpart (SImode, operands[0]);
6109
6110 if (TARGET_64BIT && mode != Pmode)
6111 pat = gen_rtx_SUBREG (SImode, pat, 0);
6112
6113 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6114 DONE;
6115 })
6116
6117 ;; Convert lea to the lea pattern to avoid flags dependency.
6118 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6119 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
6120 (define_split
6121 [(set (match_operand:DI 0 "register_operand" "")
6122 (plus:DI (match_operand:DI 1 "register_operand" "")
6123 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6124 (clobber (reg:CC FLAGS_REG))]
6125 "TARGET_64BIT && reload_completed
6126 && true_regnum (operands[0]) != true_regnum (operands[1])"
6127 [(set (match_dup 0)
6128 (plus:DI (match_dup 1) (match_dup 2)))])
6129
6130 ;; Convert lea to the lea pattern to avoid flags dependency.
6131 (define_split
6132 [(set (match_operand:DI 0 "register_operand" "")
6133 (zero_extend:DI
6134 (plus:SI (match_operand:SI 1 "register_operand" "")
6135 (match_operand:SI 2 "nonmemory_operand" ""))))
6136 (clobber (reg:CC FLAGS_REG))]
6137 "TARGET_64BIT && reload_completed
6138 && ix86_lea_for_add_ok (insn, operands)"
6139 [(set (match_dup 0)
6140 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6141 {
6142 operands[1] = gen_lowpart (DImode, operands[1]);
6143 operands[2] = gen_lowpart (DImode, operands[2]);
6144 })
6145
6146 (define_insn "*add<mode>_2"
6147 [(set (reg FLAGS_REG)
6148 (compare
6149 (plus:SWI
6150 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6151 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6152 (const_int 0)))
6153 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6154 (plus:SWI (match_dup 1) (match_dup 2)))]
6155 "ix86_match_ccmode (insn, CCGOCmode)
6156 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6157 {
6158 switch (get_attr_type (insn))
6159 {
6160 case TYPE_INCDEC:
6161 if (operands[2] == const1_rtx)
6162 return "inc{<imodesuffix>}\t%0";
6163 else
6164 {
6165 gcc_assert (operands[2] == constm1_rtx);
6166 return "dec{<imodesuffix>}\t%0";
6167 }
6168
6169 default:
6170 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6171 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6172
6173 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6174 }
6175 }
6176 [(set (attr "type")
6177 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6178 (const_string "incdec")
6179 (const_string "alu")))
6180 (set (attr "length_immediate")
6181 (if_then_else
6182 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6183 (const_string "1")
6184 (const_string "*")))
6185 (set_attr "mode" "<MODE>")])
6186
6187 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6188 (define_insn "*addsi_2_zext"
6189 [(set (reg FLAGS_REG)
6190 (compare
6191 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6192 (match_operand:SI 2 "general_operand" "g"))
6193 (const_int 0)))
6194 (set (match_operand:DI 0 "register_operand" "=r")
6195 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6196 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6197 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6198 {
6199 switch (get_attr_type (insn))
6200 {
6201 case TYPE_INCDEC:
6202 if (operands[2] == const1_rtx)
6203 return "inc{l}\t%k0";
6204 else
6205 {
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{l}\t%k0";
6208 }
6209
6210 default:
6211 if (x86_maybe_negate_const_int (&operands[2], SImode))
6212 return "sub{l}\t{%2, %k0|%k0, %2}";
6213
6214 return "add{l}\t{%2, %k0|%k0, %2}";
6215 }
6216 }
6217 [(set (attr "type")
6218 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6219 (const_string "incdec")
6220 (const_string "alu")))
6221 (set (attr "length_immediate")
6222 (if_then_else
6223 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6224 (const_string "1")
6225 (const_string "*")))
6226 (set_attr "mode" "SI")])
6227
6228 (define_insn "*add<mode>_3"
6229 [(set (reg FLAGS_REG)
6230 (compare
6231 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6232 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6233 (clobber (match_scratch:SWI 0 "=<r>"))]
6234 "ix86_match_ccmode (insn, CCZmode)
6235 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6236 {
6237 switch (get_attr_type (insn))
6238 {
6239 case TYPE_INCDEC:
6240 if (operands[2] == const1_rtx)
6241 return "inc{<imodesuffix>}\t%0";
6242 else
6243 {
6244 gcc_assert (operands[2] == constm1_rtx);
6245 return "dec{<imodesuffix>}\t%0";
6246 }
6247
6248 default:
6249 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6250 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6251
6252 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6253 }
6254 }
6255 [(set (attr "type")
6256 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu")))
6259 (set (attr "length_immediate")
6260 (if_then_else
6261 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6262 (const_string "1")
6263 (const_string "*")))
6264 (set_attr "mode" "<MODE>")])
6265
6266 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6267 (define_insn "*addsi_3_zext"
6268 [(set (reg FLAGS_REG)
6269 (compare
6270 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6271 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6272 (set (match_operand:DI 0 "register_operand" "=r")
6273 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6274 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6275 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6276 {
6277 switch (get_attr_type (insn))
6278 {
6279 case TYPE_INCDEC:
6280 if (operands[2] == const1_rtx)
6281 return "inc{l}\t%k0";
6282 else
6283 {
6284 gcc_assert (operands[2] == constm1_rtx);
6285 return "dec{l}\t%k0";
6286 }
6287
6288 default:
6289 if (x86_maybe_negate_const_int (&operands[2], SImode))
6290 return "sub{l}\t{%2, %k0|%k0, %2}";
6291
6292 return "add{l}\t{%2, %k0|%k0, %2}";
6293 }
6294 }
6295 [(set (attr "type")
6296 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6297 (const_string "incdec")
6298 (const_string "alu")))
6299 (set (attr "length_immediate")
6300 (if_then_else
6301 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6302 (const_string "1")
6303 (const_string "*")))
6304 (set_attr "mode" "SI")])
6305
6306 ; For comparisons against 1, -1 and 128, we may generate better code
6307 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6308 ; is matched then. We can't accept general immediate, because for
6309 ; case of overflows, the result is messed up.
6310 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6311 ; only for comparisons not depending on it.
6312
6313 (define_insn "*adddi_4"
6314 [(set (reg FLAGS_REG)
6315 (compare
6316 (match_operand:DI 1 "nonimmediate_operand" "0")
6317 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6318 (clobber (match_scratch:DI 0 "=rm"))]
6319 "TARGET_64BIT
6320 && ix86_match_ccmode (insn, CCGCmode)"
6321 {
6322 switch (get_attr_type (insn))
6323 {
6324 case TYPE_INCDEC:
6325 if (operands[2] == constm1_rtx)
6326 return "inc{q}\t%0";
6327 else
6328 {
6329 gcc_assert (operands[2] == const1_rtx);
6330 return "dec{q}\t%0";
6331 }
6332
6333 default:
6334 if (x86_maybe_negate_const_int (&operands[2], DImode))
6335 return "add{q}\t{%2, %0|%0, %2}";
6336
6337 return "sub{q}\t{%2, %0|%0, %2}";
6338 }
6339 }
6340 [(set (attr "type")
6341 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6342 (const_string "incdec")
6343 (const_string "alu")))
6344 (set (attr "length_immediate")
6345 (if_then_else
6346 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6347 (const_string "1")
6348 (const_string "*")))
6349 (set_attr "mode" "DI")])
6350
6351 ; For comparisons against 1, -1 and 128, we may generate better code
6352 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6353 ; is matched then. We can't accept general immediate, because for
6354 ; case of overflows, the result is messed up.
6355 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6356 ; only for comparisons not depending on it.
6357
6358 (define_insn "*add<mode>_4"
6359 [(set (reg FLAGS_REG)
6360 (compare
6361 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6362 (match_operand:SWI124 2 "const_int_operand" "n")))
6363 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6364 "ix86_match_ccmode (insn, CCGCmode)"
6365 {
6366 switch (get_attr_type (insn))
6367 {
6368 case TYPE_INCDEC:
6369 if (operands[2] == constm1_rtx)
6370 return "inc{<imodesuffix>}\t%0";
6371 else
6372 {
6373 gcc_assert (operands[2] == const1_rtx);
6374 return "dec{<imodesuffix>}\t%0";
6375 }
6376
6377 default:
6378 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6379 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6380
6381 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6382 }
6383 }
6384 [(set (attr "type")
6385 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6386 (const_string "incdec")
6387 (const_string "alu")))
6388 (set (attr "length_immediate")
6389 (if_then_else
6390 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6391 (const_string "1")
6392 (const_string "*")))
6393 (set_attr "mode" "<MODE>")])
6394
6395 (define_insn "*add<mode>_5"
6396 [(set (reg FLAGS_REG)
6397 (compare
6398 (plus:SWI
6399 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6400 (match_operand:SWI 2 "<general_operand>" "<g>"))
6401 (const_int 0)))
6402 (clobber (match_scratch:SWI 0 "=<r>"))]
6403 "ix86_match_ccmode (insn, CCGOCmode)
6404 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6405 {
6406 switch (get_attr_type (insn))
6407 {
6408 case TYPE_INCDEC:
6409 if (operands[2] == const1_rtx)
6410 return "inc{<imodesuffix>}\t%0";
6411 else
6412 {
6413 gcc_assert (operands[2] == constm1_rtx);
6414 return "dec{<imodesuffix>}\t%0";
6415 }
6416
6417 default:
6418 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6419 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6420
6421 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6422 }
6423 }
6424 [(set (attr "type")
6425 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6426 (const_string "incdec")
6427 (const_string "alu")))
6428 (set (attr "length_immediate")
6429 (if_then_else
6430 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6431 (const_string "1")
6432 (const_string "*")))
6433 (set_attr "mode" "<MODE>")])
6434
6435 (define_insn "*addqi_ext_1_rex64"
6436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6437 (const_int 8)
6438 (const_int 8))
6439 (plus:SI
6440 (zero_extract:SI
6441 (match_operand 1 "ext_register_operand" "0")
6442 (const_int 8)
6443 (const_int 8))
6444 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6445 (clobber (reg:CC FLAGS_REG))]
6446 "TARGET_64BIT"
6447 {
6448 switch (get_attr_type (insn))
6449 {
6450 case TYPE_INCDEC:
6451 if (operands[2] == const1_rtx)
6452 return "inc{b}\t%h0";
6453 else
6454 {
6455 gcc_assert (operands[2] == constm1_rtx);
6456 return "dec{b}\t%h0";
6457 }
6458
6459 default:
6460 return "add{b}\t{%2, %h0|%h0, %2}";
6461 }
6462 }
6463 [(set (attr "type")
6464 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465 (const_string "incdec")
6466 (const_string "alu")))
6467 (set_attr "modrm" "1")
6468 (set_attr "mode" "QI")])
6469
6470 (define_insn "addqi_ext_1"
6471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6472 (const_int 8)
6473 (const_int 8))
6474 (plus:SI
6475 (zero_extract:SI
6476 (match_operand 1 "ext_register_operand" "0")
6477 (const_int 8)
6478 (const_int 8))
6479 (match_operand:QI 2 "general_operand" "Qmn")))
6480 (clobber (reg:CC FLAGS_REG))]
6481 "!TARGET_64BIT"
6482 {
6483 switch (get_attr_type (insn))
6484 {
6485 case TYPE_INCDEC:
6486 if (operands[2] == const1_rtx)
6487 return "inc{b}\t%h0";
6488 else
6489 {
6490 gcc_assert (operands[2] == constm1_rtx);
6491 return "dec{b}\t%h0";
6492 }
6493
6494 default:
6495 return "add{b}\t{%2, %h0|%h0, %2}";
6496 }
6497 }
6498 [(set (attr "type")
6499 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6500 (const_string "incdec")
6501 (const_string "alu")))
6502 (set_attr "modrm" "1")
6503 (set_attr "mode" "QI")])
6504
6505 (define_insn "*addqi_ext_2"
6506 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6507 (const_int 8)
6508 (const_int 8))
6509 (plus:SI
6510 (zero_extract:SI
6511 (match_operand 1 "ext_register_operand" "%0")
6512 (const_int 8)
6513 (const_int 8))
6514 (zero_extract:SI
6515 (match_operand 2 "ext_register_operand" "Q")
6516 (const_int 8)
6517 (const_int 8))))
6518 (clobber (reg:CC FLAGS_REG))]
6519 ""
6520 "add{b}\t{%h2, %h0|%h0, %h2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "mode" "QI")])
6523
6524 ;; The lea patterns for non-Pmodes needs to be matched by
6525 ;; several insns converted to real lea by splitters.
6526
6527 (define_insn_and_split "*lea_general_1"
6528 [(set (match_operand 0 "register_operand" "=r")
6529 (plus (plus (match_operand 1 "index_register_operand" "l")
6530 (match_operand 2 "register_operand" "r"))
6531 (match_operand 3 "immediate_operand" "i")))]
6532 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6533 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6534 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6535 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6536 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6537 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6538 || GET_MODE (operands[3]) == VOIDmode)"
6539 "#"
6540 "&& reload_completed"
6541 [(const_int 0)]
6542 {
6543 rtx pat;
6544 operands[0] = gen_lowpart (SImode, operands[0]);
6545 operands[1] = gen_lowpart (Pmode, operands[1]);
6546 operands[2] = gen_lowpart (Pmode, operands[2]);
6547 operands[3] = gen_lowpart (Pmode, operands[3]);
6548 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6549 operands[3]);
6550 if (Pmode != SImode)
6551 pat = gen_rtx_SUBREG (SImode, pat, 0);
6552 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6553 DONE;
6554 }
6555 [(set_attr "type" "lea")
6556 (set_attr "mode" "SI")])
6557
6558 (define_insn_and_split "*lea_general_1_zext"
6559 [(set (match_operand:DI 0 "register_operand" "=r")
6560 (zero_extend:DI
6561 (plus:SI (plus:SI
6562 (match_operand:SI 1 "index_register_operand" "l")
6563 (match_operand:SI 2 "register_operand" "r"))
6564 (match_operand:SI 3 "immediate_operand" "i"))))]
6565 "TARGET_64BIT"
6566 "#"
6567 "&& reload_completed"
6568 [(set (match_dup 0)
6569 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6570 (match_dup 2))
6571 (match_dup 3)) 0)))]
6572 {
6573 operands[1] = gen_lowpart (Pmode, operands[1]);
6574 operands[2] = gen_lowpart (Pmode, operands[2]);
6575 operands[3] = gen_lowpart (Pmode, operands[3]);
6576 }
6577 [(set_attr "type" "lea")
6578 (set_attr "mode" "SI")])
6579
6580 (define_insn_and_split "*lea_general_2"
6581 [(set (match_operand 0 "register_operand" "=r")
6582 (plus (mult (match_operand 1 "index_register_operand" "l")
6583 (match_operand 2 "const248_operand" "i"))
6584 (match_operand 3 "nonmemory_operand" "ri")))]
6585 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6586 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6587 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6588 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6589 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6590 || GET_MODE (operands[3]) == VOIDmode)"
6591 "#"
6592 "&& reload_completed"
6593 [(const_int 0)]
6594 {
6595 rtx pat;
6596 operands[0] = gen_lowpart (SImode, operands[0]);
6597 operands[1] = gen_lowpart (Pmode, operands[1]);
6598 operands[3] = gen_lowpart (Pmode, operands[3]);
6599 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6600 operands[3]);
6601 if (Pmode != SImode)
6602 pat = gen_rtx_SUBREG (SImode, pat, 0);
6603 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6604 DONE;
6605 }
6606 [(set_attr "type" "lea")
6607 (set_attr "mode" "SI")])
6608
6609 (define_insn_and_split "*lea_general_2_zext"
6610 [(set (match_operand:DI 0 "register_operand" "=r")
6611 (zero_extend:DI
6612 (plus:SI (mult:SI
6613 (match_operand:SI 1 "index_register_operand" "l")
6614 (match_operand:SI 2 "const248_operand" "n"))
6615 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6616 "TARGET_64BIT"
6617 "#"
6618 "&& reload_completed"
6619 [(set (match_dup 0)
6620 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6621 (match_dup 2))
6622 (match_dup 3)) 0)))]
6623 {
6624 operands[1] = gen_lowpart (Pmode, operands[1]);
6625 operands[3] = gen_lowpart (Pmode, operands[3]);
6626 }
6627 [(set_attr "type" "lea")
6628 (set_attr "mode" "SI")])
6629
6630 (define_insn_and_split "*lea_general_3"
6631 [(set (match_operand 0 "register_operand" "=r")
6632 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6633 (match_operand 2 "const248_operand" "i"))
6634 (match_operand 3 "register_operand" "r"))
6635 (match_operand 4 "immediate_operand" "i")))]
6636 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6637 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6638 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6639 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6640 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6641 "#"
6642 "&& reload_completed"
6643 [(const_int 0)]
6644 {
6645 rtx pat;
6646 operands[0] = gen_lowpart (SImode, operands[0]);
6647 operands[1] = gen_lowpart (Pmode, operands[1]);
6648 operands[3] = gen_lowpart (Pmode, operands[3]);
6649 operands[4] = gen_lowpart (Pmode, operands[4]);
6650 pat = gen_rtx_PLUS (Pmode,
6651 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6652 operands[2]),
6653 operands[3]),
6654 operands[4]);
6655 if (Pmode != SImode)
6656 pat = gen_rtx_SUBREG (SImode, pat, 0);
6657 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6658 DONE;
6659 }
6660 [(set_attr "type" "lea")
6661 (set_attr "mode" "SI")])
6662
6663 (define_insn_and_split "*lea_general_3_zext"
6664 [(set (match_operand:DI 0 "register_operand" "=r")
6665 (zero_extend:DI
6666 (plus:SI (plus:SI
6667 (mult:SI
6668 (match_operand:SI 1 "index_register_operand" "l")
6669 (match_operand:SI 2 "const248_operand" "n"))
6670 (match_operand:SI 3 "register_operand" "r"))
6671 (match_operand:SI 4 "immediate_operand" "i"))))]
6672 "TARGET_64BIT"
6673 "#"
6674 "&& reload_completed"
6675 [(set (match_dup 0)
6676 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6677 (match_dup 2))
6678 (match_dup 3))
6679 (match_dup 4)) 0)))]
6680 {
6681 operands[1] = gen_lowpart (Pmode, operands[1]);
6682 operands[3] = gen_lowpart (Pmode, operands[3]);
6683 operands[4] = gen_lowpart (Pmode, operands[4]);
6684 }
6685 [(set_attr "type" "lea")
6686 (set_attr "mode" "SI")])
6687 \f
6688 ;; Subtract instructions
6689
6690 (define_expand "sub<mode>3"
6691 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6692 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6693 (match_operand:SDWIM 2 "<general_operand>" "")))]
6694 ""
6695 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6696
6697 (define_insn_and_split "*sub<dwi>3_doubleword"
6698 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6699 (minus:<DWI>
6700 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6701 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6702 (clobber (reg:CC FLAGS_REG))]
6703 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6704 "#"
6705 "reload_completed"
6706 [(parallel [(set (reg:CC FLAGS_REG)
6707 (compare:CC (match_dup 1) (match_dup 2)))
6708 (set (match_dup 0)
6709 (minus:DWIH (match_dup 1) (match_dup 2)))])
6710 (parallel [(set (match_dup 3)
6711 (minus:DWIH
6712 (match_dup 4)
6713 (plus:DWIH
6714 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6715 (match_dup 5))))
6716 (clobber (reg:CC FLAGS_REG))])]
6717 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6718
6719 (define_insn "*sub<mode>_1"
6720 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6721 (minus:SWI
6722 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6723 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6724 (clobber (reg:CC FLAGS_REG))]
6725 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6726 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "alu")
6728 (set_attr "mode" "<MODE>")])
6729
6730 (define_insn "*subsi_1_zext"
6731 [(set (match_operand:DI 0 "register_operand" "=r")
6732 (zero_extend:DI
6733 (minus:SI (match_operand:SI 1 "register_operand" "0")
6734 (match_operand:SI 2 "general_operand" "g"))))
6735 (clobber (reg:CC FLAGS_REG))]
6736 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6737 "sub{l}\t{%2, %k0|%k0, %2}"
6738 [(set_attr "type" "alu")
6739 (set_attr "mode" "SI")])
6740
6741 (define_insn "*subqi_1_slp"
6742 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6743 (minus:QI (match_dup 0)
6744 (match_operand:QI 1 "general_operand" "qn,qm")))
6745 (clobber (reg:CC FLAGS_REG))]
6746 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6747 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6748 "sub{b}\t{%1, %0|%0, %1}"
6749 [(set_attr "type" "alu1")
6750 (set_attr "mode" "QI")])
6751
6752 (define_insn "*sub<mode>_2"
6753 [(set (reg FLAGS_REG)
6754 (compare
6755 (minus:SWI
6756 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6757 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6758 (const_int 0)))
6759 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6760 (minus:SWI (match_dup 1) (match_dup 2)))]
6761 "ix86_match_ccmode (insn, CCGOCmode)
6762 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6763 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "<MODE>")])
6766
6767 (define_insn "*subsi_2_zext"
6768 [(set (reg FLAGS_REG)
6769 (compare
6770 (minus:SI (match_operand:SI 1 "register_operand" "0")
6771 (match_operand:SI 2 "general_operand" "g"))
6772 (const_int 0)))
6773 (set (match_operand:DI 0 "register_operand" "=r")
6774 (zero_extend:DI
6775 (minus:SI (match_dup 1)
6776 (match_dup 2))))]
6777 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6778 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779 "sub{l}\t{%2, %k0|%k0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "SI")])
6782
6783 (define_insn "*sub<mode>_3"
6784 [(set (reg FLAGS_REG)
6785 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6787 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6788 (minus:SWI (match_dup 1) (match_dup 2)))]
6789 "ix86_match_ccmode (insn, CCmode)
6790 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6791 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "<MODE>")])
6794
6795 (define_insn "*subsi_3_zext"
6796 [(set (reg FLAGS_REG)
6797 (compare (match_operand:SI 1 "register_operand" "0")
6798 (match_operand:SI 2 "general_operand" "g")))
6799 (set (match_operand:DI 0 "register_operand" "=r")
6800 (zero_extend:DI
6801 (minus:SI (match_dup 1)
6802 (match_dup 2))))]
6803 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6804 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805 "sub{l}\t{%2, %1|%1, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "SI")])
6808 \f
6809 ;; Add with carry and subtract with borrow
6810
6811 (define_expand "<plusminus_insn><mode>3_carry"
6812 [(parallel
6813 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6814 (plusminus:SWI
6815 (match_operand:SWI 1 "nonimmediate_operand" "")
6816 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6817 [(match_operand 3 "flags_reg_operand" "")
6818 (const_int 0)])
6819 (match_operand:SWI 2 "<general_operand>" ""))))
6820 (clobber (reg:CC FLAGS_REG))])]
6821 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6822
6823 (define_insn "*<plusminus_insn><mode>3_carry"
6824 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6825 (plusminus:SWI
6826 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6827 (plus:SWI
6828 (match_operator 3 "ix86_carry_flag_operator"
6829 [(reg FLAGS_REG) (const_int 0)])
6830 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6831 (clobber (reg:CC FLAGS_REG))]
6832 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6833 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6834 [(set_attr "type" "alu")
6835 (set_attr "use_carry" "1")
6836 (set_attr "pent_pair" "pu")
6837 (set_attr "mode" "<MODE>")])
6838
6839 (define_insn "*addsi3_carry_zext"
6840 [(set (match_operand:DI 0 "register_operand" "=r")
6841 (zero_extend:DI
6842 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6843 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6844 [(reg FLAGS_REG) (const_int 0)])
6845 (match_operand:SI 2 "general_operand" "g")))))
6846 (clobber (reg:CC FLAGS_REG))]
6847 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6848 "adc{l}\t{%2, %k0|%k0, %2}"
6849 [(set_attr "type" "alu")
6850 (set_attr "use_carry" "1")
6851 (set_attr "pent_pair" "pu")
6852 (set_attr "mode" "SI")])
6853
6854 (define_insn "*subsi3_carry_zext"
6855 [(set (match_operand:DI 0 "register_operand" "=r")
6856 (zero_extend:DI
6857 (minus:SI (match_operand:SI 1 "register_operand" "0")
6858 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6859 [(reg FLAGS_REG) (const_int 0)])
6860 (match_operand:SI 2 "general_operand" "g")))))
6861 (clobber (reg:CC FLAGS_REG))]
6862 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6863 "sbb{l}\t{%2, %k0|%k0, %2}"
6864 [(set_attr "type" "alu")
6865 (set_attr "pent_pair" "pu")
6866 (set_attr "mode" "SI")])
6867 \f
6868 ;; Overflow setting add and subtract instructions
6869
6870 (define_insn "*add<mode>3_cconly_overflow"
6871 [(set (reg:CCC FLAGS_REG)
6872 (compare:CCC
6873 (plus:SWI
6874 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6875 (match_operand:SWI 2 "<general_operand>" "<g>"))
6876 (match_dup 1)))
6877 (clobber (match_scratch:SWI 0 "=<r>"))]
6878 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6879 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6880 [(set_attr "type" "alu")
6881 (set_attr "mode" "<MODE>")])
6882
6883 (define_insn "*sub<mode>3_cconly_overflow"
6884 [(set (reg:CCC FLAGS_REG)
6885 (compare:CCC
6886 (minus:SWI
6887 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6888 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6889 (match_dup 0)))]
6890 ""
6891 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6892 [(set_attr "type" "icmp")
6893 (set_attr "mode" "<MODE>")])
6894
6895 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6896 [(set (reg:CCC FLAGS_REG)
6897 (compare:CCC
6898 (plusminus:SWI
6899 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6900 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6901 (match_dup 1)))
6902 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6903 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6904 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6905 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6906 [(set_attr "type" "alu")
6907 (set_attr "mode" "<MODE>")])
6908
6909 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6910 [(set (reg:CCC FLAGS_REG)
6911 (compare:CCC
6912 (plusminus:SI
6913 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6914 (match_operand:SI 2 "general_operand" "g"))
6915 (match_dup 1)))
6916 (set (match_operand:DI 0 "register_operand" "=r")
6917 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6918 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6919 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6920 [(set_attr "type" "alu")
6921 (set_attr "mode" "SI")])
6922
6923 ;; The patterns that match these are at the end of this file.
6924
6925 (define_expand "<plusminus_insn>xf3"
6926 [(set (match_operand:XF 0 "register_operand" "")
6927 (plusminus:XF
6928 (match_operand:XF 1 "register_operand" "")
6929 (match_operand:XF 2 "register_operand" "")))]
6930 "TARGET_80387")
6931
6932 (define_expand "<plusminus_insn><mode>3"
6933 [(set (match_operand:MODEF 0 "register_operand" "")
6934 (plusminus:MODEF
6935 (match_operand:MODEF 1 "register_operand" "")
6936 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6937 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6938 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6939 \f
6940 ;; Multiply instructions
6941
6942 (define_expand "mul<mode>3"
6943 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6944 (mult:SWIM248
6945 (match_operand:SWIM248 1 "register_operand" "")
6946 (match_operand:SWIM248 2 "<general_operand>" "")))
6947 (clobber (reg:CC FLAGS_REG))])])
6948
6949 (define_expand "mulqi3"
6950 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6951 (mult:QI
6952 (match_operand:QI 1 "register_operand" "")
6953 (match_operand:QI 2 "nonimmediate_operand" "")))
6954 (clobber (reg:CC FLAGS_REG))])]
6955 "TARGET_QIMODE_MATH")
6956
6957 ;; On AMDFAM10
6958 ;; IMUL reg32/64, reg32/64, imm8 Direct
6959 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6960 ;; IMUL reg32/64, reg32/64, imm32 Direct
6961 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6962 ;; IMUL reg32/64, reg32/64 Direct
6963 ;; IMUL reg32/64, mem32/64 Direct
6964 ;;
6965 ;; On BDVER1, all above IMULs use DirectPath
6966
6967 (define_insn "*mul<mode>3_1"
6968 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6969 (mult:SWI48
6970 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6971 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6972 (clobber (reg:CC FLAGS_REG))]
6973 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974 "@
6975 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6976 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6977 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6978 [(set_attr "type" "imul")
6979 (set_attr "prefix_0f" "0,0,1")
6980 (set (attr "athlon_decode")
6981 (cond [(eq_attr "cpu" "athlon")
6982 (const_string "vector")
6983 (eq_attr "alternative" "1")
6984 (const_string "vector")
6985 (and (eq_attr "alternative" "2")
6986 (match_operand 1 "memory_operand" ""))
6987 (const_string "vector")]
6988 (const_string "direct")))
6989 (set (attr "amdfam10_decode")
6990 (cond [(and (eq_attr "alternative" "0,1")
6991 (match_operand 1 "memory_operand" ""))
6992 (const_string "vector")]
6993 (const_string "direct")))
6994 (set_attr "bdver1_decode" "direct")
6995 (set_attr "mode" "<MODE>")])
6996
6997 (define_insn "*mulsi3_1_zext"
6998 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6999 (zero_extend:DI
7000 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7001 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7002 (clobber (reg:CC FLAGS_REG))]
7003 "TARGET_64BIT
7004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7005 "@
7006 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7007 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7008 imul{l}\t{%2, %k0|%k0, %2}"
7009 [(set_attr "type" "imul")
7010 (set_attr "prefix_0f" "0,0,1")
7011 (set (attr "athlon_decode")
7012 (cond [(eq_attr "cpu" "athlon")
7013 (const_string "vector")
7014 (eq_attr "alternative" "1")
7015 (const_string "vector")
7016 (and (eq_attr "alternative" "2")
7017 (match_operand 1 "memory_operand" ""))
7018 (const_string "vector")]
7019 (const_string "direct")))
7020 (set (attr "amdfam10_decode")
7021 (cond [(and (eq_attr "alternative" "0,1")
7022 (match_operand 1 "memory_operand" ""))
7023 (const_string "vector")]
7024 (const_string "direct")))
7025 (set_attr "bdver1_decode" "direct")
7026 (set_attr "mode" "SI")])
7027
7028 ;; On AMDFAM10
7029 ;; IMUL reg16, reg16, imm8 VectorPath
7030 ;; IMUL reg16, mem16, imm8 VectorPath
7031 ;; IMUL reg16, reg16, imm16 VectorPath
7032 ;; IMUL reg16, mem16, imm16 VectorPath
7033 ;; IMUL reg16, reg16 Direct
7034 ;; IMUL reg16, mem16 Direct
7035 ;;
7036 ;; On BDVER1, all HI MULs use DoublePath
7037
7038 (define_insn "*mulhi3_1"
7039 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7040 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7041 (match_operand:HI 2 "general_operand" "K,n,mr")))
7042 (clobber (reg:CC FLAGS_REG))]
7043 "TARGET_HIMODE_MATH
7044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7045 "@
7046 imul{w}\t{%2, %1, %0|%0, %1, %2}
7047 imul{w}\t{%2, %1, %0|%0, %1, %2}
7048 imul{w}\t{%2, %0|%0, %2}"
7049 [(set_attr "type" "imul")
7050 (set_attr "prefix_0f" "0,0,1")
7051 (set (attr "athlon_decode")
7052 (cond [(eq_attr "cpu" "athlon")
7053 (const_string "vector")
7054 (eq_attr "alternative" "1,2")
7055 (const_string "vector")]
7056 (const_string "direct")))
7057 (set (attr "amdfam10_decode")
7058 (cond [(eq_attr "alternative" "0,1")
7059 (const_string "vector")]
7060 (const_string "direct")))
7061 (set_attr "bdver1_decode" "double")
7062 (set_attr "mode" "HI")])
7063
7064 ;;On AMDFAM10 and BDVER1
7065 ;; MUL reg8 Direct
7066 ;; MUL mem8 Direct
7067
7068 (define_insn "*mulqi3_1"
7069 [(set (match_operand:QI 0 "register_operand" "=a")
7070 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7071 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7072 (clobber (reg:CC FLAGS_REG))]
7073 "TARGET_QIMODE_MATH
7074 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7075 "mul{b}\t%2"
7076 [(set_attr "type" "imul")
7077 (set_attr "length_immediate" "0")
7078 (set (attr "athlon_decode")
7079 (if_then_else (eq_attr "cpu" "athlon")
7080 (const_string "vector")
7081 (const_string "direct")))
7082 (set_attr "amdfam10_decode" "direct")
7083 (set_attr "bdver1_decode" "direct")
7084 (set_attr "mode" "QI")])
7085
7086 (define_expand "<u>mul<mode><dwi>3"
7087 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7088 (mult:<DWI>
7089 (any_extend:<DWI>
7090 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7091 (any_extend:<DWI>
7092 (match_operand:DWIH 2 "register_operand" ""))))
7093 (clobber (reg:CC FLAGS_REG))])])
7094
7095 (define_expand "<u>mulqihi3"
7096 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7097 (mult:HI
7098 (any_extend:HI
7099 (match_operand:QI 1 "nonimmediate_operand" ""))
7100 (any_extend:HI
7101 (match_operand:QI 2 "register_operand" ""))))
7102 (clobber (reg:CC FLAGS_REG))])]
7103 "TARGET_QIMODE_MATH")
7104
7105 (define_insn "*<u>mul<mode><dwi>3_1"
7106 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7107 (mult:<DWI>
7108 (any_extend:<DWI>
7109 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7110 (any_extend:<DWI>
7111 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7112 (clobber (reg:CC FLAGS_REG))]
7113 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7114 "<sgnprefix>mul{<imodesuffix>}\t%2"
7115 [(set_attr "type" "imul")
7116 (set_attr "length_immediate" "0")
7117 (set (attr "athlon_decode")
7118 (if_then_else (eq_attr "cpu" "athlon")
7119 (const_string "vector")
7120 (const_string "double")))
7121 (set_attr "amdfam10_decode" "double")
7122 (set_attr "bdver1_decode" "direct")
7123 (set_attr "mode" "<MODE>")])
7124
7125 (define_insn "*<u>mulqihi3_1"
7126 [(set (match_operand:HI 0 "register_operand" "=a")
7127 (mult:HI
7128 (any_extend:HI
7129 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7130 (any_extend:HI
7131 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7132 (clobber (reg:CC FLAGS_REG))]
7133 "TARGET_QIMODE_MATH
7134 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7135 "<sgnprefix>mul{b}\t%2"
7136 [(set_attr "type" "imul")
7137 (set_attr "length_immediate" "0")
7138 (set (attr "athlon_decode")
7139 (if_then_else (eq_attr "cpu" "athlon")
7140 (const_string "vector")
7141 (const_string "direct")))
7142 (set_attr "amdfam10_decode" "direct")
7143 (set_attr "bdver1_decode" "direct")
7144 (set_attr "mode" "QI")])
7145
7146 (define_expand "<s>mul<mode>3_highpart"
7147 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7148 (truncate:SWI48
7149 (lshiftrt:<DWI>
7150 (mult:<DWI>
7151 (any_extend:<DWI>
7152 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7153 (any_extend:<DWI>
7154 (match_operand:SWI48 2 "register_operand" "")))
7155 (match_dup 4))))
7156 (clobber (match_scratch:SWI48 3 ""))
7157 (clobber (reg:CC FLAGS_REG))])]
7158 ""
7159 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7160
7161 (define_insn "*<s>muldi3_highpart_1"
7162 [(set (match_operand:DI 0 "register_operand" "=d")
7163 (truncate:DI
7164 (lshiftrt:TI
7165 (mult:TI
7166 (any_extend:TI
7167 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7168 (any_extend:TI
7169 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7170 (const_int 64))))
7171 (clobber (match_scratch:DI 3 "=1"))
7172 (clobber (reg:CC FLAGS_REG))]
7173 "TARGET_64BIT
7174 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7175 "<sgnprefix>mul{q}\t%2"
7176 [(set_attr "type" "imul")
7177 (set_attr "length_immediate" "0")
7178 (set (attr "athlon_decode")
7179 (if_then_else (eq_attr "cpu" "athlon")
7180 (const_string "vector")
7181 (const_string "double")))
7182 (set_attr "amdfam10_decode" "double")
7183 (set_attr "bdver1_decode" "direct")
7184 (set_attr "mode" "DI")])
7185
7186 (define_insn "*<s>mulsi3_highpart_1"
7187 [(set (match_operand:SI 0 "register_operand" "=d")
7188 (truncate:SI
7189 (lshiftrt:DI
7190 (mult:DI
7191 (any_extend:DI
7192 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7193 (any_extend:DI
7194 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7195 (const_int 32))))
7196 (clobber (match_scratch:SI 3 "=1"))
7197 (clobber (reg:CC FLAGS_REG))]
7198 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7199 "<sgnprefix>mul{l}\t%2"
7200 [(set_attr "type" "imul")
7201 (set_attr "length_immediate" "0")
7202 (set (attr "athlon_decode")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double")))
7206 (set_attr "amdfam10_decode" "double")
7207 (set_attr "bdver1_decode" "direct")
7208 (set_attr "mode" "SI")])
7209
7210 (define_insn "*<s>mulsi3_highpart_zext"
7211 [(set (match_operand:DI 0 "register_operand" "=d")
7212 (zero_extend:DI (truncate:SI
7213 (lshiftrt:DI
7214 (mult:DI (any_extend:DI
7215 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7216 (any_extend:DI
7217 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7218 (const_int 32)))))
7219 (clobber (match_scratch:SI 3 "=1"))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "TARGET_64BIT
7222 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7223 "<sgnprefix>mul{l}\t%2"
7224 [(set_attr "type" "imul")
7225 (set_attr "length_immediate" "0")
7226 (set (attr "athlon_decode")
7227 (if_then_else (eq_attr "cpu" "athlon")
7228 (const_string "vector")
7229 (const_string "double")))
7230 (set_attr "amdfam10_decode" "double")
7231 (set_attr "bdver1_decode" "direct")
7232 (set_attr "mode" "SI")])
7233
7234 ;; The patterns that match these are at the end of this file.
7235
7236 (define_expand "mulxf3"
7237 [(set (match_operand:XF 0 "register_operand" "")
7238 (mult:XF (match_operand:XF 1 "register_operand" "")
7239 (match_operand:XF 2 "register_operand" "")))]
7240 "TARGET_80387")
7241
7242 (define_expand "mul<mode>3"
7243 [(set (match_operand:MODEF 0 "register_operand" "")
7244 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7245 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7246 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7247 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7248 \f
7249 ;; Divide instructions
7250
7251 ;; The patterns that match these are at the end of this file.
7252
7253 (define_expand "divxf3"
7254 [(set (match_operand:XF 0 "register_operand" "")
7255 (div:XF (match_operand:XF 1 "register_operand" "")
7256 (match_operand:XF 2 "register_operand" "")))]
7257 "TARGET_80387")
7258
7259 (define_expand "divdf3"
7260 [(set (match_operand:DF 0 "register_operand" "")
7261 (div:DF (match_operand:DF 1 "register_operand" "")
7262 (match_operand:DF 2 "nonimmediate_operand" "")))]
7263 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7264 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7265
7266 (define_expand "divsf3"
7267 [(set (match_operand:SF 0 "register_operand" "")
7268 (div:SF (match_operand:SF 1 "register_operand" "")
7269 (match_operand:SF 2 "nonimmediate_operand" "")))]
7270 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7271 || TARGET_SSE_MATH"
7272 {
7273 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7274 && flag_finite_math_only && !flag_trapping_math
7275 && flag_unsafe_math_optimizations)
7276 {
7277 ix86_emit_swdivsf (operands[0], operands[1],
7278 operands[2], SFmode);
7279 DONE;
7280 }
7281 })
7282 \f
7283 ;; Divmod instructions.
7284
7285 (define_expand "divmod<mode>4"
7286 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7287 (div:SWIM248
7288 (match_operand:SWIM248 1 "register_operand" "")
7289 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7290 (set (match_operand:SWIM248 3 "register_operand" "")
7291 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7292 (clobber (reg:CC FLAGS_REG))])])
7293
7294 ;; Split with 8bit unsigned divide:
7295 ;; if (dividend an divisor are in [0-255])
7296 ;; use 8bit unsigned integer divide
7297 ;; else
7298 ;; use original integer divide
7299 (define_split
7300 [(set (match_operand:SWI48 0 "register_operand" "")
7301 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7302 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7303 (set (match_operand:SWI48 1 "register_operand" "")
7304 (mod:SWI48 (match_dup 2) (match_dup 3)))
7305 (clobber (reg:CC FLAGS_REG))]
7306 "TARGET_USE_8BIT_IDIV
7307 && TARGET_QIMODE_MATH
7308 && can_create_pseudo_p ()
7309 && !optimize_insn_for_size_p ()"
7310 [(const_int 0)]
7311 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7312
7313 (define_insn_and_split "divmod<mode>4_1"
7314 [(set (match_operand:SWI48 0 "register_operand" "=a")
7315 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7316 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7317 (set (match_operand:SWI48 1 "register_operand" "=&d")
7318 (mod:SWI48 (match_dup 2) (match_dup 3)))
7319 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7320 (clobber (reg:CC FLAGS_REG))]
7321 ""
7322 "#"
7323 "reload_completed"
7324 [(parallel [(set (match_dup 1)
7325 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7326 (clobber (reg:CC FLAGS_REG))])
7327 (parallel [(set (match_dup 0)
7328 (div:SWI48 (match_dup 2) (match_dup 3)))
7329 (set (match_dup 1)
7330 (mod:SWI48 (match_dup 2) (match_dup 3)))
7331 (use (match_dup 1))
7332 (clobber (reg:CC FLAGS_REG))])]
7333 {
7334 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7335
7336 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7337 operands[4] = operands[2];
7338 else
7339 {
7340 /* Avoid use of cltd in favor of a mov+shift. */
7341 emit_move_insn (operands[1], operands[2]);
7342 operands[4] = operands[1];
7343 }
7344 }
7345 [(set_attr "type" "multi")
7346 (set_attr "mode" "<MODE>")])
7347
7348 (define_insn_and_split "*divmod<mode>4"
7349 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7350 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7351 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7352 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7353 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7354 (clobber (reg:CC FLAGS_REG))]
7355 ""
7356 "#"
7357 "reload_completed"
7358 [(parallel [(set (match_dup 1)
7359 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7360 (clobber (reg:CC FLAGS_REG))])
7361 (parallel [(set (match_dup 0)
7362 (div:SWIM248 (match_dup 2) (match_dup 3)))
7363 (set (match_dup 1)
7364 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7365 (use (match_dup 1))
7366 (clobber (reg:CC FLAGS_REG))])]
7367 {
7368 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7369
7370 if (<MODE>mode != HImode
7371 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7372 operands[4] = operands[2];
7373 else
7374 {
7375 /* Avoid use of cltd in favor of a mov+shift. */
7376 emit_move_insn (operands[1], operands[2]);
7377 operands[4] = operands[1];
7378 }
7379 }
7380 [(set_attr "type" "multi")
7381 (set_attr "mode" "<MODE>")])
7382
7383 (define_insn "*divmod<mode>4_noext"
7384 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7385 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7386 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7387 (set (match_operand:SWIM248 1 "register_operand" "=d")
7388 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7389 (use (match_operand:SWIM248 4 "register_operand" "1"))
7390 (clobber (reg:CC FLAGS_REG))]
7391 ""
7392 "idiv{<imodesuffix>}\t%3"
7393 [(set_attr "type" "idiv")
7394 (set_attr "mode" "<MODE>")])
7395
7396 (define_expand "divmodqi4"
7397 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7398 (div:QI
7399 (match_operand:QI 1 "register_operand" "")
7400 (match_operand:QI 2 "nonimmediate_operand" "")))
7401 (set (match_operand:QI 3 "register_operand" "")
7402 (mod:QI (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7404 "TARGET_QIMODE_MATH"
7405 {
7406 rtx div, mod, insn;
7407 rtx tmp0, tmp1;
7408
7409 tmp0 = gen_reg_rtx (HImode);
7410 tmp1 = gen_reg_rtx (HImode);
7411
7412 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7413 in AX. */
7414 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7415 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7416
7417 /* Extract remainder from AH. */
7418 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7419 insn = emit_move_insn (operands[3], tmp1);
7420
7421 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7422 set_unique_reg_note (insn, REG_EQUAL, mod);
7423
7424 /* Extract quotient from AL. */
7425 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7426
7427 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7428 set_unique_reg_note (insn, REG_EQUAL, div);
7429
7430 DONE;
7431 })
7432
7433 ;; Divide AX by r/m8, with result stored in
7434 ;; AL <- Quotient
7435 ;; AH <- Remainder
7436 ;; Change div/mod to HImode and extend the second argument to HImode
7437 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7438 ;; combine may fail.
7439 (define_insn "divmodhiqi3"
7440 [(set (match_operand:HI 0 "register_operand" "=a")
7441 (ior:HI
7442 (ashift:HI
7443 (zero_extend:HI
7444 (truncate:QI
7445 (mod:HI (match_operand:HI 1 "register_operand" "0")
7446 (sign_extend:HI
7447 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7448 (const_int 8))
7449 (zero_extend:HI
7450 (truncate:QI
7451 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7452 (clobber (reg:CC FLAGS_REG))]
7453 "TARGET_QIMODE_MATH"
7454 "idiv{b}\t%2"
7455 [(set_attr "type" "idiv")
7456 (set_attr "mode" "QI")])
7457
7458 (define_expand "udivmod<mode>4"
7459 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7460 (udiv:SWIM248
7461 (match_operand:SWIM248 1 "register_operand" "")
7462 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7463 (set (match_operand:SWIM248 3 "register_operand" "")
7464 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7465 (clobber (reg:CC FLAGS_REG))])])
7466
7467 ;; Split with 8bit unsigned divide:
7468 ;; if (dividend an divisor are in [0-255])
7469 ;; use 8bit unsigned integer divide
7470 ;; else
7471 ;; use original integer divide
7472 (define_split
7473 [(set (match_operand:SWI48 0 "register_operand" "")
7474 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7475 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7476 (set (match_operand:SWI48 1 "register_operand" "")
7477 (umod:SWI48 (match_dup 2) (match_dup 3)))
7478 (clobber (reg:CC FLAGS_REG))]
7479 "TARGET_USE_8BIT_IDIV
7480 && TARGET_QIMODE_MATH
7481 && can_create_pseudo_p ()
7482 && !optimize_insn_for_size_p ()"
7483 [(const_int 0)]
7484 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7485
7486 (define_insn_and_split "udivmod<mode>4_1"
7487 [(set (match_operand:SWI48 0 "register_operand" "=a")
7488 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7489 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7490 (set (match_operand:SWI48 1 "register_operand" "=&d")
7491 (umod:SWI48 (match_dup 2) (match_dup 3)))
7492 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7493 (clobber (reg:CC FLAGS_REG))]
7494 ""
7495 "#"
7496 "reload_completed"
7497 [(set (match_dup 1) (const_int 0))
7498 (parallel [(set (match_dup 0)
7499 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7500 (set (match_dup 1)
7501 (umod:SWI48 (match_dup 2) (match_dup 3)))
7502 (use (match_dup 1))
7503 (clobber (reg:CC FLAGS_REG))])]
7504 ""
7505 [(set_attr "type" "multi")
7506 (set_attr "mode" "<MODE>")])
7507
7508 (define_insn_and_split "*udivmod<mode>4"
7509 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7510 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7511 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7512 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7513 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7514 (clobber (reg:CC FLAGS_REG))]
7515 ""
7516 "#"
7517 "reload_completed"
7518 [(set (match_dup 1) (const_int 0))
7519 (parallel [(set (match_dup 0)
7520 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7521 (set (match_dup 1)
7522 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7523 (use (match_dup 1))
7524 (clobber (reg:CC FLAGS_REG))])]
7525 ""
7526 [(set_attr "type" "multi")
7527 (set_attr "mode" "<MODE>")])
7528
7529 (define_insn "*udivmod<mode>4_noext"
7530 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7531 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7532 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7533 (set (match_operand:SWIM248 1 "register_operand" "=d")
7534 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7535 (use (match_operand:SWIM248 4 "register_operand" "1"))
7536 (clobber (reg:CC FLAGS_REG))]
7537 ""
7538 "div{<imodesuffix>}\t%3"
7539 [(set_attr "type" "idiv")
7540 (set_attr "mode" "<MODE>")])
7541
7542 (define_expand "udivmodqi4"
7543 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7544 (udiv:QI
7545 (match_operand:QI 1 "register_operand" "")
7546 (match_operand:QI 2 "nonimmediate_operand" "")))
7547 (set (match_operand:QI 3 "register_operand" "")
7548 (umod:QI (match_dup 1) (match_dup 2)))
7549 (clobber (reg:CC FLAGS_REG))])]
7550 "TARGET_QIMODE_MATH"
7551 {
7552 rtx div, mod, insn;
7553 rtx tmp0, tmp1;
7554
7555 tmp0 = gen_reg_rtx (HImode);
7556 tmp1 = gen_reg_rtx (HImode);
7557
7558 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7559 in AX. */
7560 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7561 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7562
7563 /* Extract remainder from AH. */
7564 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7565 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7566 insn = emit_move_insn (operands[3], tmp1);
7567
7568 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7569 set_unique_reg_note (insn, REG_EQUAL, mod);
7570
7571 /* Extract quotient from AL. */
7572 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7573
7574 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7575 set_unique_reg_note (insn, REG_EQUAL, div);
7576
7577 DONE;
7578 })
7579
7580 (define_insn "udivmodhiqi3"
7581 [(set (match_operand:HI 0 "register_operand" "=a")
7582 (ior:HI
7583 (ashift:HI
7584 (zero_extend:HI
7585 (truncate:QI
7586 (mod:HI (match_operand:HI 1 "register_operand" "0")
7587 (zero_extend:HI
7588 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7589 (const_int 8))
7590 (zero_extend:HI
7591 (truncate:QI
7592 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7593 (clobber (reg:CC FLAGS_REG))]
7594 "TARGET_QIMODE_MATH"
7595 "div{b}\t%2"
7596 [(set_attr "type" "idiv")
7597 (set_attr "mode" "QI")])
7598
7599 ;; We cannot use div/idiv for double division, because it causes
7600 ;; "division by zero" on the overflow and that's not what we expect
7601 ;; from truncate. Because true (non truncating) double division is
7602 ;; never generated, we can't create this insn anyway.
7603 ;
7604 ;(define_insn ""
7605 ; [(set (match_operand:SI 0 "register_operand" "=a")
7606 ; (truncate:SI
7607 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7608 ; (zero_extend:DI
7609 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7610 ; (set (match_operand:SI 3 "register_operand" "=d")
7611 ; (truncate:SI
7612 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7613 ; (clobber (reg:CC FLAGS_REG))]
7614 ; ""
7615 ; "div{l}\t{%2, %0|%0, %2}"
7616 ; [(set_attr "type" "idiv")])
7617 \f
7618 ;;- Logical AND instructions
7619
7620 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7621 ;; Note that this excludes ah.
7622
7623 (define_expand "testsi_ccno_1"
7624 [(set (reg:CCNO FLAGS_REG)
7625 (compare:CCNO
7626 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7627 (match_operand:SI 1 "nonmemory_operand" ""))
7628 (const_int 0)))])
7629
7630 (define_expand "testqi_ccz_1"
7631 [(set (reg:CCZ FLAGS_REG)
7632 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7633 (match_operand:QI 1 "nonmemory_operand" ""))
7634 (const_int 0)))])
7635
7636 (define_expand "testdi_ccno_1"
7637 [(set (reg:CCNO FLAGS_REG)
7638 (compare:CCNO
7639 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7640 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7641 (const_int 0)))]
7642 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7643
7644 (define_insn "*testdi_1"
7645 [(set (reg FLAGS_REG)
7646 (compare
7647 (and:DI
7648 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7649 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7650 (const_int 0)))]
7651 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7652 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7653 "@
7654 test{l}\t{%k1, %k0|%k0, %k1}
7655 test{l}\t{%k1, %k0|%k0, %k1}
7656 test{q}\t{%1, %0|%0, %1}
7657 test{q}\t{%1, %0|%0, %1}
7658 test{q}\t{%1, %0|%0, %1}"
7659 [(set_attr "type" "test")
7660 (set_attr "modrm" "0,1,0,1,1")
7661 (set_attr "mode" "SI,SI,DI,DI,DI")])
7662
7663 (define_insn "*testqi_1_maybe_si"
7664 [(set (reg FLAGS_REG)
7665 (compare
7666 (and:QI
7667 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7668 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7669 (const_int 0)))]
7670 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7671 && ix86_match_ccmode (insn,
7672 CONST_INT_P (operands[1])
7673 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7674 {
7675 if (which_alternative == 3)
7676 {
7677 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7678 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7679 return "test{l}\t{%1, %k0|%k0, %1}";
7680 }
7681 return "test{b}\t{%1, %0|%0, %1}";
7682 }
7683 [(set_attr "type" "test")
7684 (set_attr "modrm" "0,1,1,1")
7685 (set_attr "mode" "QI,QI,QI,SI")
7686 (set_attr "pent_pair" "uv,np,uv,np")])
7687
7688 (define_insn "*test<mode>_1"
7689 [(set (reg FLAGS_REG)
7690 (compare
7691 (and:SWI124
7692 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7693 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7694 (const_int 0)))]
7695 "ix86_match_ccmode (insn, CCNOmode)
7696 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7697 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7698 [(set_attr "type" "test")
7699 (set_attr "modrm" "0,1,1")
7700 (set_attr "mode" "<MODE>")
7701 (set_attr "pent_pair" "uv,np,uv")])
7702
7703 (define_expand "testqi_ext_ccno_0"
7704 [(set (reg:CCNO FLAGS_REG)
7705 (compare:CCNO
7706 (and:SI
7707 (zero_extract:SI
7708 (match_operand 0 "ext_register_operand" "")
7709 (const_int 8)
7710 (const_int 8))
7711 (match_operand 1 "const_int_operand" ""))
7712 (const_int 0)))])
7713
7714 (define_insn "*testqi_ext_0"
7715 [(set (reg FLAGS_REG)
7716 (compare
7717 (and:SI
7718 (zero_extract:SI
7719 (match_operand 0 "ext_register_operand" "Q")
7720 (const_int 8)
7721 (const_int 8))
7722 (match_operand 1 "const_int_operand" "n"))
7723 (const_int 0)))]
7724 "ix86_match_ccmode (insn, CCNOmode)"
7725 "test{b}\t{%1, %h0|%h0, %1}"
7726 [(set_attr "type" "test")
7727 (set_attr "mode" "QI")
7728 (set_attr "length_immediate" "1")
7729 (set_attr "modrm" "1")
7730 (set_attr "pent_pair" "np")])
7731
7732 (define_insn "*testqi_ext_1_rex64"
7733 [(set (reg FLAGS_REG)
7734 (compare
7735 (and:SI
7736 (zero_extract:SI
7737 (match_operand 0 "ext_register_operand" "Q")
7738 (const_int 8)
7739 (const_int 8))
7740 (zero_extend:SI
7741 (match_operand:QI 1 "register_operand" "Q")))
7742 (const_int 0)))]
7743 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7744 "test{b}\t{%1, %h0|%h0, %1}"
7745 [(set_attr "type" "test")
7746 (set_attr "mode" "QI")])
7747
7748 (define_insn "*testqi_ext_1"
7749 [(set (reg FLAGS_REG)
7750 (compare
7751 (and:SI
7752 (zero_extract:SI
7753 (match_operand 0 "ext_register_operand" "Q")
7754 (const_int 8)
7755 (const_int 8))
7756 (zero_extend:SI
7757 (match_operand:QI 1 "general_operand" "Qm")))
7758 (const_int 0)))]
7759 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7760 "test{b}\t{%1, %h0|%h0, %1}"
7761 [(set_attr "type" "test")
7762 (set_attr "mode" "QI")])
7763
7764 (define_insn "*testqi_ext_2"
7765 [(set (reg FLAGS_REG)
7766 (compare
7767 (and:SI
7768 (zero_extract:SI
7769 (match_operand 0 "ext_register_operand" "Q")
7770 (const_int 8)
7771 (const_int 8))
7772 (zero_extract:SI
7773 (match_operand 1 "ext_register_operand" "Q")
7774 (const_int 8)
7775 (const_int 8)))
7776 (const_int 0)))]
7777 "ix86_match_ccmode (insn, CCNOmode)"
7778 "test{b}\t{%h1, %h0|%h0, %h1}"
7779 [(set_attr "type" "test")
7780 (set_attr "mode" "QI")])
7781
7782 (define_insn "*testqi_ext_3_rex64"
7783 [(set (reg FLAGS_REG)
7784 (compare (zero_extract:DI
7785 (match_operand 0 "nonimmediate_operand" "rm")
7786 (match_operand:DI 1 "const_int_operand" "")
7787 (match_operand:DI 2 "const_int_operand" ""))
7788 (const_int 0)))]
7789 "TARGET_64BIT
7790 && ix86_match_ccmode (insn, CCNOmode)
7791 && INTVAL (operands[1]) > 0
7792 && INTVAL (operands[2]) >= 0
7793 /* Ensure that resulting mask is zero or sign extended operand. */
7794 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7795 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7796 && INTVAL (operands[1]) > 32))
7797 && (GET_MODE (operands[0]) == SImode
7798 || GET_MODE (operands[0]) == DImode
7799 || GET_MODE (operands[0]) == HImode
7800 || GET_MODE (operands[0]) == QImode)"
7801 "#")
7802
7803 ;; Combine likes to form bit extractions for some tests. Humor it.
7804 (define_insn "*testqi_ext_3"
7805 [(set (reg FLAGS_REG)
7806 (compare (zero_extract:SI
7807 (match_operand 0 "nonimmediate_operand" "rm")
7808 (match_operand:SI 1 "const_int_operand" "")
7809 (match_operand:SI 2 "const_int_operand" ""))
7810 (const_int 0)))]
7811 "ix86_match_ccmode (insn, CCNOmode)
7812 && INTVAL (operands[1]) > 0
7813 && INTVAL (operands[2]) >= 0
7814 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7815 && (GET_MODE (operands[0]) == SImode
7816 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7817 || GET_MODE (operands[0]) == HImode
7818 || GET_MODE (operands[0]) == QImode)"
7819 "#")
7820
7821 (define_split
7822 [(set (match_operand 0 "flags_reg_operand" "")
7823 (match_operator 1 "compare_operator"
7824 [(zero_extract
7825 (match_operand 2 "nonimmediate_operand" "")
7826 (match_operand 3 "const_int_operand" "")
7827 (match_operand 4 "const_int_operand" ""))
7828 (const_int 0)]))]
7829 "ix86_match_ccmode (insn, CCNOmode)"
7830 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7831 {
7832 rtx val = operands[2];
7833 HOST_WIDE_INT len = INTVAL (operands[3]);
7834 HOST_WIDE_INT pos = INTVAL (operands[4]);
7835 HOST_WIDE_INT mask;
7836 enum machine_mode mode, submode;
7837
7838 mode = GET_MODE (val);
7839 if (MEM_P (val))
7840 {
7841 /* ??? Combine likes to put non-volatile mem extractions in QImode
7842 no matter the size of the test. So find a mode that works. */
7843 if (! MEM_VOLATILE_P (val))
7844 {
7845 mode = smallest_mode_for_size (pos + len, MODE_INT);
7846 val = adjust_address (val, mode, 0);
7847 }
7848 }
7849 else if (GET_CODE (val) == SUBREG
7850 && (submode = GET_MODE (SUBREG_REG (val)),
7851 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7852 && pos + len <= GET_MODE_BITSIZE (submode)
7853 && GET_MODE_CLASS (submode) == MODE_INT)
7854 {
7855 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7856 mode = submode;
7857 val = SUBREG_REG (val);
7858 }
7859 else if (mode == HImode && pos + len <= 8)
7860 {
7861 /* Small HImode tests can be converted to QImode. */
7862 mode = QImode;
7863 val = gen_lowpart (QImode, val);
7864 }
7865
7866 if (len == HOST_BITS_PER_WIDE_INT)
7867 mask = -1;
7868 else
7869 mask = ((HOST_WIDE_INT)1 << len) - 1;
7870 mask <<= pos;
7871
7872 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7873 })
7874
7875 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7876 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7877 ;; this is relatively important trick.
7878 ;; Do the conversion only post-reload to avoid limiting of the register class
7879 ;; to QI regs.
7880 (define_split
7881 [(set (match_operand 0 "flags_reg_operand" "")
7882 (match_operator 1 "compare_operator"
7883 [(and (match_operand 2 "register_operand" "")
7884 (match_operand 3 "const_int_operand" ""))
7885 (const_int 0)]))]
7886 "reload_completed
7887 && QI_REG_P (operands[2])
7888 && GET_MODE (operands[2]) != QImode
7889 && ((ix86_match_ccmode (insn, CCZmode)
7890 && !(INTVAL (operands[3]) & ~(255 << 8)))
7891 || (ix86_match_ccmode (insn, CCNOmode)
7892 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7893 [(set (match_dup 0)
7894 (match_op_dup 1
7895 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7896 (match_dup 3))
7897 (const_int 0)]))]
7898 "operands[2] = gen_lowpart (SImode, operands[2]);
7899 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7900
7901 (define_split
7902 [(set (match_operand 0 "flags_reg_operand" "")
7903 (match_operator 1 "compare_operator"
7904 [(and (match_operand 2 "nonimmediate_operand" "")
7905 (match_operand 3 "const_int_operand" ""))
7906 (const_int 0)]))]
7907 "reload_completed
7908 && GET_MODE (operands[2]) != QImode
7909 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7910 && ((ix86_match_ccmode (insn, CCZmode)
7911 && !(INTVAL (operands[3]) & ~255))
7912 || (ix86_match_ccmode (insn, CCNOmode)
7913 && !(INTVAL (operands[3]) & ~127)))"
7914 [(set (match_dup 0)
7915 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7916 (const_int 0)]))]
7917 "operands[2] = gen_lowpart (QImode, operands[2]);
7918 operands[3] = gen_lowpart (QImode, operands[3]);")
7919
7920 ;; %%% This used to optimize known byte-wide and operations to memory,
7921 ;; and sometimes to QImode registers. If this is considered useful,
7922 ;; it should be done with splitters.
7923
7924 (define_expand "and<mode>3"
7925 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7926 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7927 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7928 ""
7929 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7930
7931 (define_insn "*anddi_1"
7932 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7933 (and:DI
7934 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7935 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7936 (clobber (reg:CC FLAGS_REG))]
7937 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7938 {
7939 switch (get_attr_type (insn))
7940 {
7941 case TYPE_IMOVX:
7942 {
7943 enum machine_mode mode;
7944
7945 gcc_assert (CONST_INT_P (operands[2]));
7946 if (INTVAL (operands[2]) == 0xff)
7947 mode = QImode;
7948 else
7949 {
7950 gcc_assert (INTVAL (operands[2]) == 0xffff);
7951 mode = HImode;
7952 }
7953
7954 operands[1] = gen_lowpart (mode, operands[1]);
7955 if (mode == QImode)
7956 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7957 else
7958 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7959 }
7960
7961 default:
7962 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7963 if (get_attr_mode (insn) == MODE_SI)
7964 return "and{l}\t{%k2, %k0|%k0, %k2}";
7965 else
7966 return "and{q}\t{%2, %0|%0, %2}";
7967 }
7968 }
7969 [(set_attr "type" "alu,alu,alu,imovx")
7970 (set_attr "length_immediate" "*,*,*,0")
7971 (set (attr "prefix_rex")
7972 (if_then_else
7973 (and (eq_attr "type" "imovx")
7974 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7975 (match_operand 1 "ext_QIreg_operand" "")))
7976 (const_string "1")
7977 (const_string "*")))
7978 (set_attr "mode" "SI,DI,DI,SI")])
7979
7980 (define_insn "*andsi_1"
7981 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7982 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7983 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7984 (clobber (reg:CC FLAGS_REG))]
7985 "ix86_binary_operator_ok (AND, SImode, operands)"
7986 {
7987 switch (get_attr_type (insn))
7988 {
7989 case TYPE_IMOVX:
7990 {
7991 enum machine_mode mode;
7992
7993 gcc_assert (CONST_INT_P (operands[2]));
7994 if (INTVAL (operands[2]) == 0xff)
7995 mode = QImode;
7996 else
7997 {
7998 gcc_assert (INTVAL (operands[2]) == 0xffff);
7999 mode = HImode;
8000 }
8001
8002 operands[1] = gen_lowpart (mode, operands[1]);
8003 if (mode == QImode)
8004 return "movz{bl|x}\t{%1, %0|%0, %1}";
8005 else
8006 return "movz{wl|x}\t{%1, %0|%0, %1}";
8007 }
8008
8009 default:
8010 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8011 return "and{l}\t{%2, %0|%0, %2}";
8012 }
8013 }
8014 [(set_attr "type" "alu,alu,imovx")
8015 (set (attr "prefix_rex")
8016 (if_then_else
8017 (and (eq_attr "type" "imovx")
8018 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8019 (match_operand 1 "ext_QIreg_operand" "")))
8020 (const_string "1")
8021 (const_string "*")))
8022 (set_attr "length_immediate" "*,*,0")
8023 (set_attr "mode" "SI")])
8024
8025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8026 (define_insn "*andsi_1_zext"
8027 [(set (match_operand:DI 0 "register_operand" "=r")
8028 (zero_extend:DI
8029 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8030 (match_operand:SI 2 "general_operand" "g"))))
8031 (clobber (reg:CC FLAGS_REG))]
8032 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8033 "and{l}\t{%2, %k0|%k0, %2}"
8034 [(set_attr "type" "alu")
8035 (set_attr "mode" "SI")])
8036
8037 (define_insn "*andhi_1"
8038 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8039 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8040 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "ix86_binary_operator_ok (AND, HImode, operands)"
8043 {
8044 switch (get_attr_type (insn))
8045 {
8046 case TYPE_IMOVX:
8047 gcc_assert (CONST_INT_P (operands[2]));
8048 gcc_assert (INTVAL (operands[2]) == 0xff);
8049 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8050
8051 default:
8052 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8053
8054 return "and{w}\t{%2, %0|%0, %2}";
8055 }
8056 }
8057 [(set_attr "type" "alu,alu,imovx")
8058 (set_attr "length_immediate" "*,*,0")
8059 (set (attr "prefix_rex")
8060 (if_then_else
8061 (and (eq_attr "type" "imovx")
8062 (match_operand 1 "ext_QIreg_operand" ""))
8063 (const_string "1")
8064 (const_string "*")))
8065 (set_attr "mode" "HI,HI,SI")])
8066
8067 ;; %%% Potential partial reg stall on alternative 2. What to do?
8068 (define_insn "*andqi_1"
8069 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8070 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8071 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8072 (clobber (reg:CC FLAGS_REG))]
8073 "ix86_binary_operator_ok (AND, QImode, operands)"
8074 "@
8075 and{b}\t{%2, %0|%0, %2}
8076 and{b}\t{%2, %0|%0, %2}
8077 and{l}\t{%k2, %k0|%k0, %k2}"
8078 [(set_attr "type" "alu")
8079 (set_attr "mode" "QI,QI,SI")])
8080
8081 (define_insn "*andqi_1_slp"
8082 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8083 (and:QI (match_dup 0)
8084 (match_operand:QI 1 "general_operand" "qn,qmn")))
8085 (clobber (reg:CC FLAGS_REG))]
8086 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8087 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8088 "and{b}\t{%1, %0|%0, %1}"
8089 [(set_attr "type" "alu1")
8090 (set_attr "mode" "QI")])
8091
8092 (define_split
8093 [(set (match_operand 0 "register_operand" "")
8094 (and (match_dup 0)
8095 (const_int -65536)))
8096 (clobber (reg:CC FLAGS_REG))]
8097 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8098 || optimize_function_for_size_p (cfun)"
8099 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8100 "operands[1] = gen_lowpart (HImode, operands[0]);")
8101
8102 (define_split
8103 [(set (match_operand 0 "ext_register_operand" "")
8104 (and (match_dup 0)
8105 (const_int -256)))
8106 (clobber (reg:CC FLAGS_REG))]
8107 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8108 && reload_completed"
8109 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8110 "operands[1] = gen_lowpart (QImode, operands[0]);")
8111
8112 (define_split
8113 [(set (match_operand 0 "ext_register_operand" "")
8114 (and (match_dup 0)
8115 (const_int -65281)))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8118 && reload_completed"
8119 [(parallel [(set (zero_extract:SI (match_dup 0)
8120 (const_int 8)
8121 (const_int 8))
8122 (xor:SI
8123 (zero_extract:SI (match_dup 0)
8124 (const_int 8)
8125 (const_int 8))
8126 (zero_extract:SI (match_dup 0)
8127 (const_int 8)
8128 (const_int 8))))
8129 (clobber (reg:CC FLAGS_REG))])]
8130 "operands[0] = gen_lowpart (SImode, operands[0]);")
8131
8132 (define_insn "*anddi_2"
8133 [(set (reg FLAGS_REG)
8134 (compare
8135 (and:DI
8136 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8137 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8138 (const_int 0)))
8139 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8140 (and:DI (match_dup 1) (match_dup 2)))]
8141 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8142 && ix86_binary_operator_ok (AND, DImode, operands)"
8143 "@
8144 and{l}\t{%k2, %k0|%k0, %k2}
8145 and{q}\t{%2, %0|%0, %2}
8146 and{q}\t{%2, %0|%0, %2}"
8147 [(set_attr "type" "alu")
8148 (set_attr "mode" "SI,DI,DI")])
8149
8150 (define_insn "*andqi_2_maybe_si"
8151 [(set (reg FLAGS_REG)
8152 (compare (and:QI
8153 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8154 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8155 (const_int 0)))
8156 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8157 (and:QI (match_dup 1) (match_dup 2)))]
8158 "ix86_binary_operator_ok (AND, QImode, operands)
8159 && ix86_match_ccmode (insn,
8160 CONST_INT_P (operands[2])
8161 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8162 {
8163 if (which_alternative == 2)
8164 {
8165 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8166 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8167 return "and{l}\t{%2, %k0|%k0, %2}";
8168 }
8169 return "and{b}\t{%2, %0|%0, %2}";
8170 }
8171 [(set_attr "type" "alu")
8172 (set_attr "mode" "QI,QI,SI")])
8173
8174 (define_insn "*and<mode>_2"
8175 [(set (reg FLAGS_REG)
8176 (compare (and:SWI124
8177 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8178 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8179 (const_int 0)))
8180 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8181 (and:SWI124 (match_dup 1) (match_dup 2)))]
8182 "ix86_match_ccmode (insn, CCNOmode)
8183 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8184 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8185 [(set_attr "type" "alu")
8186 (set_attr "mode" "<MODE>")])
8187
8188 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8189 (define_insn "*andsi_2_zext"
8190 [(set (reg FLAGS_REG)
8191 (compare (and:SI
8192 (match_operand:SI 1 "nonimmediate_operand" "%0")
8193 (match_operand:SI 2 "general_operand" "g"))
8194 (const_int 0)))
8195 (set (match_operand:DI 0 "register_operand" "=r")
8196 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8197 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8198 && ix86_binary_operator_ok (AND, SImode, operands)"
8199 "and{l}\t{%2, %k0|%k0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "mode" "SI")])
8202
8203 (define_insn "*andqi_2_slp"
8204 [(set (reg FLAGS_REG)
8205 (compare (and:QI
8206 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8207 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8208 (const_int 0)))
8209 (set (strict_low_part (match_dup 0))
8210 (and:QI (match_dup 0) (match_dup 1)))]
8211 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8212 && ix86_match_ccmode (insn, CCNOmode)
8213 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8214 "and{b}\t{%1, %0|%0, %1}"
8215 [(set_attr "type" "alu1")
8216 (set_attr "mode" "QI")])
8217
8218 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8219 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8220 ;; for a QImode operand, which of course failed.
8221 (define_insn "andqi_ext_0"
8222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8223 (const_int 8)
8224 (const_int 8))
8225 (and:SI
8226 (zero_extract:SI
8227 (match_operand 1 "ext_register_operand" "0")
8228 (const_int 8)
8229 (const_int 8))
8230 (match_operand 2 "const_int_operand" "n")))
8231 (clobber (reg:CC FLAGS_REG))]
8232 ""
8233 "and{b}\t{%2, %h0|%h0, %2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "length_immediate" "1")
8236 (set_attr "modrm" "1")
8237 (set_attr "mode" "QI")])
8238
8239 ;; Generated by peephole translating test to and. This shows up
8240 ;; often in fp comparisons.
8241 (define_insn "*andqi_ext_0_cc"
8242 [(set (reg FLAGS_REG)
8243 (compare
8244 (and:SI
8245 (zero_extract:SI
8246 (match_operand 1 "ext_register_operand" "0")
8247 (const_int 8)
8248 (const_int 8))
8249 (match_operand 2 "const_int_operand" "n"))
8250 (const_int 0)))
8251 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8252 (const_int 8)
8253 (const_int 8))
8254 (and:SI
8255 (zero_extract:SI
8256 (match_dup 1)
8257 (const_int 8)
8258 (const_int 8))
8259 (match_dup 2)))]
8260 "ix86_match_ccmode (insn, CCNOmode)"
8261 "and{b}\t{%2, %h0|%h0, %2}"
8262 [(set_attr "type" "alu")
8263 (set_attr "length_immediate" "1")
8264 (set_attr "modrm" "1")
8265 (set_attr "mode" "QI")])
8266
8267 (define_insn "*andqi_ext_1_rex64"
8268 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8269 (const_int 8)
8270 (const_int 8))
8271 (and:SI
8272 (zero_extract:SI
8273 (match_operand 1 "ext_register_operand" "0")
8274 (const_int 8)
8275 (const_int 8))
8276 (zero_extend:SI
8277 (match_operand 2 "ext_register_operand" "Q"))))
8278 (clobber (reg:CC FLAGS_REG))]
8279 "TARGET_64BIT"
8280 "and{b}\t{%2, %h0|%h0, %2}"
8281 [(set_attr "type" "alu")
8282 (set_attr "length_immediate" "0")
8283 (set_attr "mode" "QI")])
8284
8285 (define_insn "*andqi_ext_1"
8286 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8287 (const_int 8)
8288 (const_int 8))
8289 (and:SI
8290 (zero_extract:SI
8291 (match_operand 1 "ext_register_operand" "0")
8292 (const_int 8)
8293 (const_int 8))
8294 (zero_extend:SI
8295 (match_operand:QI 2 "general_operand" "Qm"))))
8296 (clobber (reg:CC FLAGS_REG))]
8297 "!TARGET_64BIT"
8298 "and{b}\t{%2, %h0|%h0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "length_immediate" "0")
8301 (set_attr "mode" "QI")])
8302
8303 (define_insn "*andqi_ext_2"
8304 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8305 (const_int 8)
8306 (const_int 8))
8307 (and:SI
8308 (zero_extract:SI
8309 (match_operand 1 "ext_register_operand" "%0")
8310 (const_int 8)
8311 (const_int 8))
8312 (zero_extract:SI
8313 (match_operand 2 "ext_register_operand" "Q")
8314 (const_int 8)
8315 (const_int 8))))
8316 (clobber (reg:CC FLAGS_REG))]
8317 ""
8318 "and{b}\t{%h2, %h0|%h0, %h2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "length_immediate" "0")
8321 (set_attr "mode" "QI")])
8322
8323 ;; Convert wide AND instructions with immediate operand to shorter QImode
8324 ;; equivalents when possible.
8325 ;; Don't do the splitting with memory operands, since it introduces risk
8326 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8327 ;; for size, but that can (should?) be handled by generic code instead.
8328 (define_split
8329 [(set (match_operand 0 "register_operand" "")
8330 (and (match_operand 1 "register_operand" "")
8331 (match_operand 2 "const_int_operand" "")))
8332 (clobber (reg:CC FLAGS_REG))]
8333 "reload_completed
8334 && QI_REG_P (operands[0])
8335 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8336 && !(~INTVAL (operands[2]) & ~(255 << 8))
8337 && GET_MODE (operands[0]) != QImode"
8338 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8339 (and:SI (zero_extract:SI (match_dup 1)
8340 (const_int 8) (const_int 8))
8341 (match_dup 2)))
8342 (clobber (reg:CC FLAGS_REG))])]
8343 "operands[0] = gen_lowpart (SImode, operands[0]);
8344 operands[1] = gen_lowpart (SImode, operands[1]);
8345 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8346
8347 ;; Since AND can be encoded with sign extended immediate, this is only
8348 ;; profitable when 7th bit is not set.
8349 (define_split
8350 [(set (match_operand 0 "register_operand" "")
8351 (and (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 (and:QI (match_dup 1)
8362 (match_dup 2)))
8363 (clobber (reg:CC FLAGS_REG))])]
8364 "operands[0] = gen_lowpart (QImode, operands[0]);
8365 operands[1] = gen_lowpart (QImode, operands[1]);
8366 operands[2] = gen_lowpart (QImode, operands[2]);")
8367 \f
8368 ;; Logical inclusive and exclusive OR instructions
8369
8370 ;; %%% This used to optimize known byte-wide and operations to memory.
8371 ;; If this is considered useful, it should be done with splitters.
8372
8373 (define_expand "<code><mode>3"
8374 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8375 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8376 (match_operand:SWIM 2 "<general_operand>" "")))]
8377 ""
8378 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8379
8380 (define_insn "*<code><mode>_1"
8381 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8382 (any_or:SWI248
8383 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8384 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8385 (clobber (reg:CC FLAGS_REG))]
8386 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8387 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "mode" "<MODE>")])
8390
8391 ;; %%% Potential partial reg stall on alternative 2. What to do?
8392 (define_insn "*<code>qi_1"
8393 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8394 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8396 (clobber (reg:CC FLAGS_REG))]
8397 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8398 "@
8399 <logic>{b}\t{%2, %0|%0, %2}
8400 <logic>{b}\t{%2, %0|%0, %2}
8401 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "mode" "QI,QI,SI")])
8404
8405 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8406 (define_insn "*<code>si_1_zext"
8407 [(set (match_operand:DI 0 "register_operand" "=r")
8408 (zero_extend:DI
8409 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8410 (match_operand:SI 2 "general_operand" "g"))))
8411 (clobber (reg:CC FLAGS_REG))]
8412 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8413 "<logic>{l}\t{%2, %k0|%k0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "SI")])
8416
8417 (define_insn "*<code>si_1_zext_imm"
8418 [(set (match_operand:DI 0 "register_operand" "=r")
8419 (any_or:DI
8420 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8421 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8422 (clobber (reg:CC FLAGS_REG))]
8423 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8424 "<logic>{l}\t{%2, %k0|%k0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "mode" "SI")])
8427
8428 (define_insn "*<code>qi_1_slp"
8429 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8430 (any_or:QI (match_dup 0)
8431 (match_operand:QI 1 "general_operand" "qmn,qn")))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8435 "<logic>{b}\t{%1, %0|%0, %1}"
8436 [(set_attr "type" "alu1")
8437 (set_attr "mode" "QI")])
8438
8439 (define_insn "*<code><mode>_2"
8440 [(set (reg FLAGS_REG)
8441 (compare (any_or:SWI
8442 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8443 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8444 (const_int 0)))
8445 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8446 (any_or:SWI (match_dup 1) (match_dup 2)))]
8447 "ix86_match_ccmode (insn, CCNOmode)
8448 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8449 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8450 [(set_attr "type" "alu")
8451 (set_attr "mode" "<MODE>")])
8452
8453 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8454 ;; ??? Special case for immediate operand is missing - it is tricky.
8455 (define_insn "*<code>si_2_zext"
8456 [(set (reg FLAGS_REG)
8457 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8458 (match_operand:SI 2 "general_operand" "g"))
8459 (const_int 0)))
8460 (set (match_operand:DI 0 "register_operand" "=r")
8461 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8462 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8463 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8464 "<logic>{l}\t{%2, %k0|%k0, %2}"
8465 [(set_attr "type" "alu")
8466 (set_attr "mode" "SI")])
8467
8468 (define_insn "*<code>si_2_zext_imm"
8469 [(set (reg FLAGS_REG)
8470 (compare (any_or:SI
8471 (match_operand:SI 1 "nonimmediate_operand" "%0")
8472 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8473 (const_int 0)))
8474 (set (match_operand:DI 0 "register_operand" "=r")
8475 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8476 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8477 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8478 "<logic>{l}\t{%2, %k0|%k0, %2}"
8479 [(set_attr "type" "alu")
8480 (set_attr "mode" "SI")])
8481
8482 (define_insn "*<code>qi_2_slp"
8483 [(set (reg FLAGS_REG)
8484 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8485 (match_operand:QI 1 "general_operand" "qmn,qn"))
8486 (const_int 0)))
8487 (set (strict_low_part (match_dup 0))
8488 (any_or:QI (match_dup 0) (match_dup 1)))]
8489 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8490 && ix86_match_ccmode (insn, CCNOmode)
8491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8492 "<logic>{b}\t{%1, %0|%0, %1}"
8493 [(set_attr "type" "alu1")
8494 (set_attr "mode" "QI")])
8495
8496 (define_insn "*<code><mode>_3"
8497 [(set (reg FLAGS_REG)
8498 (compare (any_or:SWI
8499 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8500 (match_operand:SWI 2 "<general_operand>" "<g>"))
8501 (const_int 0)))
8502 (clobber (match_scratch:SWI 0 "=<r>"))]
8503 "ix86_match_ccmode (insn, CCNOmode)
8504 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8505 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8506 [(set_attr "type" "alu")
8507 (set_attr "mode" "<MODE>")])
8508
8509 (define_insn "*<code>qi_ext_0"
8510 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8511 (const_int 8)
8512 (const_int 8))
8513 (any_or:SI
8514 (zero_extract:SI
8515 (match_operand 1 "ext_register_operand" "0")
8516 (const_int 8)
8517 (const_int 8))
8518 (match_operand 2 "const_int_operand" "n")))
8519 (clobber (reg:CC FLAGS_REG))]
8520 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8521 "<logic>{b}\t{%2, %h0|%h0, %2}"
8522 [(set_attr "type" "alu")
8523 (set_attr "length_immediate" "1")
8524 (set_attr "modrm" "1")
8525 (set_attr "mode" "QI")])
8526
8527 (define_insn "*<code>qi_ext_1_rex64"
8528 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8529 (const_int 8)
8530 (const_int 8))
8531 (any_or:SI
8532 (zero_extract:SI
8533 (match_operand 1 "ext_register_operand" "0")
8534 (const_int 8)
8535 (const_int 8))
8536 (zero_extend:SI
8537 (match_operand 2 "ext_register_operand" "Q"))))
8538 (clobber (reg:CC FLAGS_REG))]
8539 "TARGET_64BIT
8540 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8541 "<logic>{b}\t{%2, %h0|%h0, %2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "length_immediate" "0")
8544 (set_attr "mode" "QI")])
8545
8546 (define_insn "*<code>qi_ext_1"
8547 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8548 (const_int 8)
8549 (const_int 8))
8550 (any_or:SI
8551 (zero_extract:SI
8552 (match_operand 1 "ext_register_operand" "0")
8553 (const_int 8)
8554 (const_int 8))
8555 (zero_extend:SI
8556 (match_operand:QI 2 "general_operand" "Qm"))))
8557 (clobber (reg:CC FLAGS_REG))]
8558 "!TARGET_64BIT
8559 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8560 "<logic>{b}\t{%2, %h0|%h0, %2}"
8561 [(set_attr "type" "alu")
8562 (set_attr "length_immediate" "0")
8563 (set_attr "mode" "QI")])
8564
8565 (define_insn "*<code>qi_ext_2"
8566 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8567 (const_int 8)
8568 (const_int 8))
8569 (any_or:SI
8570 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8571 (const_int 8)
8572 (const_int 8))
8573 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8574 (const_int 8)
8575 (const_int 8))))
8576 (clobber (reg:CC FLAGS_REG))]
8577 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8578 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8579 [(set_attr "type" "alu")
8580 (set_attr "length_immediate" "0")
8581 (set_attr "mode" "QI")])
8582
8583 (define_split
8584 [(set (match_operand 0 "register_operand" "")
8585 (any_or (match_operand 1 "register_operand" "")
8586 (match_operand 2 "const_int_operand" "")))
8587 (clobber (reg:CC FLAGS_REG))]
8588 "reload_completed
8589 && QI_REG_P (operands[0])
8590 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8591 && !(INTVAL (operands[2]) & ~(255 << 8))
8592 && GET_MODE (operands[0]) != QImode"
8593 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8594 (any_or:SI (zero_extract:SI (match_dup 1)
8595 (const_int 8) (const_int 8))
8596 (match_dup 2)))
8597 (clobber (reg:CC FLAGS_REG))])]
8598 "operands[0] = gen_lowpart (SImode, operands[0]);
8599 operands[1] = gen_lowpart (SImode, operands[1]);
8600 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8601
8602 ;; Since OR can be encoded with sign extended immediate, this is only
8603 ;; profitable when 7th bit is set.
8604 (define_split
8605 [(set (match_operand 0 "register_operand" "")
8606 (any_or (match_operand 1 "general_operand" "")
8607 (match_operand 2 "const_int_operand" "")))
8608 (clobber (reg:CC FLAGS_REG))]
8609 "reload_completed
8610 && ANY_QI_REG_P (operands[0])
8611 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8612 && !(INTVAL (operands[2]) & ~255)
8613 && (INTVAL (operands[2]) & 128)
8614 && GET_MODE (operands[0]) != QImode"
8615 [(parallel [(set (strict_low_part (match_dup 0))
8616 (any_or:QI (match_dup 1)
8617 (match_dup 2)))
8618 (clobber (reg:CC FLAGS_REG))])]
8619 "operands[0] = gen_lowpart (QImode, operands[0]);
8620 operands[1] = gen_lowpart (QImode, operands[1]);
8621 operands[2] = gen_lowpart (QImode, operands[2]);")
8622
8623 (define_expand "xorqi_cc_ext_1"
8624 [(parallel [
8625 (set (reg:CCNO FLAGS_REG)
8626 (compare:CCNO
8627 (xor:SI
8628 (zero_extract:SI
8629 (match_operand 1 "ext_register_operand" "")
8630 (const_int 8)
8631 (const_int 8))
8632 (match_operand:QI 2 "general_operand" ""))
8633 (const_int 0)))
8634 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8635 (const_int 8)
8636 (const_int 8))
8637 (xor:SI
8638 (zero_extract:SI
8639 (match_dup 1)
8640 (const_int 8)
8641 (const_int 8))
8642 (match_dup 2)))])])
8643
8644 (define_insn "*xorqi_cc_ext_1_rex64"
8645 [(set (reg FLAGS_REG)
8646 (compare
8647 (xor:SI
8648 (zero_extract:SI
8649 (match_operand 1 "ext_register_operand" "0")
8650 (const_int 8)
8651 (const_int 8))
8652 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8653 (const_int 0)))
8654 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8655 (const_int 8)
8656 (const_int 8))
8657 (xor:SI
8658 (zero_extract:SI
8659 (match_dup 1)
8660 (const_int 8)
8661 (const_int 8))
8662 (match_dup 2)))]
8663 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8664 "xor{b}\t{%2, %h0|%h0, %2}"
8665 [(set_attr "type" "alu")
8666 (set_attr "modrm" "1")
8667 (set_attr "mode" "QI")])
8668
8669 (define_insn "*xorqi_cc_ext_1"
8670 [(set (reg FLAGS_REG)
8671 (compare
8672 (xor:SI
8673 (zero_extract:SI
8674 (match_operand 1 "ext_register_operand" "0")
8675 (const_int 8)
8676 (const_int 8))
8677 (match_operand:QI 2 "general_operand" "qmn"))
8678 (const_int 0)))
8679 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8680 (const_int 8)
8681 (const_int 8))
8682 (xor:SI
8683 (zero_extract:SI
8684 (match_dup 1)
8685 (const_int 8)
8686 (const_int 8))
8687 (match_dup 2)))]
8688 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8689 "xor{b}\t{%2, %h0|%h0, %2}"
8690 [(set_attr "type" "alu")
8691 (set_attr "modrm" "1")
8692 (set_attr "mode" "QI")])
8693 \f
8694 ;; Negation instructions
8695
8696 (define_expand "neg<mode>2"
8697 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8698 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8699 ""
8700 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8701
8702 (define_insn_and_split "*neg<dwi>2_doubleword"
8703 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8704 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8705 (clobber (reg:CC FLAGS_REG))]
8706 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8707 "#"
8708 "reload_completed"
8709 [(parallel
8710 [(set (reg:CCZ FLAGS_REG)
8711 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8712 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8713 (parallel
8714 [(set (match_dup 2)
8715 (plus:DWIH (match_dup 3)
8716 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8717 (const_int 0))))
8718 (clobber (reg:CC FLAGS_REG))])
8719 (parallel
8720 [(set (match_dup 2)
8721 (neg:DWIH (match_dup 2)))
8722 (clobber (reg:CC FLAGS_REG))])]
8723 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8724
8725 (define_insn "*neg<mode>2_1"
8726 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8727 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8728 (clobber (reg:CC FLAGS_REG))]
8729 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8730 "neg{<imodesuffix>}\t%0"
8731 [(set_attr "type" "negnot")
8732 (set_attr "mode" "<MODE>")])
8733
8734 ;; Combine is quite creative about this pattern.
8735 (define_insn "*negsi2_1_zext"
8736 [(set (match_operand:DI 0 "register_operand" "=r")
8737 (lshiftrt:DI
8738 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8739 (const_int 32)))
8740 (const_int 32)))
8741 (clobber (reg:CC FLAGS_REG))]
8742 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8743 "neg{l}\t%k0"
8744 [(set_attr "type" "negnot")
8745 (set_attr "mode" "SI")])
8746
8747 ;; The problem with neg is that it does not perform (compare x 0),
8748 ;; it really performs (compare 0 x), which leaves us with the zero
8749 ;; flag being the only useful item.
8750
8751 (define_insn "*neg<mode>2_cmpz"
8752 [(set (reg:CCZ FLAGS_REG)
8753 (compare:CCZ
8754 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8755 (const_int 0)))
8756 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8757 (neg:SWI (match_dup 1)))]
8758 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8759 "neg{<imodesuffix>}\t%0"
8760 [(set_attr "type" "negnot")
8761 (set_attr "mode" "<MODE>")])
8762
8763 (define_insn "*negsi2_cmpz_zext"
8764 [(set (reg:CCZ FLAGS_REG)
8765 (compare:CCZ
8766 (lshiftrt:DI
8767 (neg:DI (ashift:DI
8768 (match_operand:DI 1 "register_operand" "0")
8769 (const_int 32)))
8770 (const_int 32))
8771 (const_int 0)))
8772 (set (match_operand:DI 0 "register_operand" "=r")
8773 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8774 (const_int 32)))
8775 (const_int 32)))]
8776 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8777 "neg{l}\t%k0"
8778 [(set_attr "type" "negnot")
8779 (set_attr "mode" "SI")])
8780
8781 ;; Changing of sign for FP values is doable using integer unit too.
8782
8783 (define_expand "<code><mode>2"
8784 [(set (match_operand:X87MODEF 0 "register_operand" "")
8785 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8786 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8787 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8788
8789 (define_insn "*absneg<mode>2_mixed"
8790 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8791 (match_operator:MODEF 3 "absneg_operator"
8792 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8793 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8794 (clobber (reg:CC FLAGS_REG))]
8795 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8796 "#")
8797
8798 (define_insn "*absneg<mode>2_sse"
8799 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8800 (match_operator:MODEF 3 "absneg_operator"
8801 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8802 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8803 (clobber (reg:CC FLAGS_REG))]
8804 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8805 "#")
8806
8807 (define_insn "*absneg<mode>2_i387"
8808 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8809 (match_operator:X87MODEF 3 "absneg_operator"
8810 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8811 (use (match_operand 2 "" ""))
8812 (clobber (reg:CC FLAGS_REG))]
8813 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8814 "#")
8815
8816 (define_expand "<code>tf2"
8817 [(set (match_operand:TF 0 "register_operand" "")
8818 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8819 "TARGET_SSE2"
8820 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8821
8822 (define_insn "*absnegtf2_sse"
8823 [(set (match_operand:TF 0 "register_operand" "=x,x")
8824 (match_operator:TF 3 "absneg_operator"
8825 [(match_operand:TF 1 "register_operand" "0,x")]))
8826 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8827 (clobber (reg:CC FLAGS_REG))]
8828 "TARGET_SSE2"
8829 "#")
8830
8831 ;; Splitters for fp abs and neg.
8832
8833 (define_split
8834 [(set (match_operand 0 "fp_register_operand" "")
8835 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8836 (use (match_operand 2 "" ""))
8837 (clobber (reg:CC FLAGS_REG))]
8838 "reload_completed"
8839 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8840
8841 (define_split
8842 [(set (match_operand 0 "register_operand" "")
8843 (match_operator 3 "absneg_operator"
8844 [(match_operand 1 "register_operand" "")]))
8845 (use (match_operand 2 "nonimmediate_operand" ""))
8846 (clobber (reg:CC FLAGS_REG))]
8847 "reload_completed && SSE_REG_P (operands[0])"
8848 [(set (match_dup 0) (match_dup 3))]
8849 {
8850 enum machine_mode mode = GET_MODE (operands[0]);
8851 enum machine_mode vmode = GET_MODE (operands[2]);
8852 rtx tmp;
8853
8854 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8855 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8856 if (operands_match_p (operands[0], operands[2]))
8857 {
8858 tmp = operands[1];
8859 operands[1] = operands[2];
8860 operands[2] = tmp;
8861 }
8862 if (GET_CODE (operands[3]) == ABS)
8863 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8864 else
8865 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8866 operands[3] = tmp;
8867 })
8868
8869 (define_split
8870 [(set (match_operand:SF 0 "register_operand" "")
8871 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8872 (use (match_operand:V4SF 2 "" ""))
8873 (clobber (reg:CC FLAGS_REG))]
8874 "reload_completed"
8875 [(parallel [(set (match_dup 0) (match_dup 1))
8876 (clobber (reg:CC FLAGS_REG))])]
8877 {
8878 rtx tmp;
8879 operands[0] = gen_lowpart (SImode, operands[0]);
8880 if (GET_CODE (operands[1]) == ABS)
8881 {
8882 tmp = gen_int_mode (0x7fffffff, SImode);
8883 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8884 }
8885 else
8886 {
8887 tmp = gen_int_mode (0x80000000, SImode);
8888 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8889 }
8890 operands[1] = tmp;
8891 })
8892
8893 (define_split
8894 [(set (match_operand:DF 0 "register_operand" "")
8895 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8896 (use (match_operand 2 "" ""))
8897 (clobber (reg:CC FLAGS_REG))]
8898 "reload_completed"
8899 [(parallel [(set (match_dup 0) (match_dup 1))
8900 (clobber (reg:CC FLAGS_REG))])]
8901 {
8902 rtx tmp;
8903 if (TARGET_64BIT)
8904 {
8905 tmp = gen_lowpart (DImode, operands[0]);
8906 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8907 operands[0] = tmp;
8908
8909 if (GET_CODE (operands[1]) == ABS)
8910 tmp = const0_rtx;
8911 else
8912 tmp = gen_rtx_NOT (DImode, tmp);
8913 }
8914 else
8915 {
8916 operands[0] = gen_highpart (SImode, operands[0]);
8917 if (GET_CODE (operands[1]) == ABS)
8918 {
8919 tmp = gen_int_mode (0x7fffffff, SImode);
8920 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8921 }
8922 else
8923 {
8924 tmp = gen_int_mode (0x80000000, SImode);
8925 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8926 }
8927 }
8928 operands[1] = tmp;
8929 })
8930
8931 (define_split
8932 [(set (match_operand:XF 0 "register_operand" "")
8933 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8934 (use (match_operand 2 "" ""))
8935 (clobber (reg:CC FLAGS_REG))]
8936 "reload_completed"
8937 [(parallel [(set (match_dup 0) (match_dup 1))
8938 (clobber (reg:CC FLAGS_REG))])]
8939 {
8940 rtx tmp;
8941 operands[0] = gen_rtx_REG (SImode,
8942 true_regnum (operands[0])
8943 + (TARGET_64BIT ? 1 : 2));
8944 if (GET_CODE (operands[1]) == ABS)
8945 {
8946 tmp = GEN_INT (0x7fff);
8947 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8948 }
8949 else
8950 {
8951 tmp = GEN_INT (0x8000);
8952 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8953 }
8954 operands[1] = tmp;
8955 })
8956
8957 ;; Conditionalize these after reload. If they match before reload, we
8958 ;; lose the clobber and ability to use integer instructions.
8959
8960 (define_insn "*<code><mode>2_1"
8961 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8962 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8963 "TARGET_80387
8964 && (reload_completed
8965 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8966 "f<absneg_mnemonic>"
8967 [(set_attr "type" "fsgn")
8968 (set_attr "mode" "<MODE>")])
8969
8970 (define_insn "*<code>extendsfdf2"
8971 [(set (match_operand:DF 0 "register_operand" "=f")
8972 (absneg:DF (float_extend:DF
8973 (match_operand:SF 1 "register_operand" "0"))))]
8974 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8975 "f<absneg_mnemonic>"
8976 [(set_attr "type" "fsgn")
8977 (set_attr "mode" "DF")])
8978
8979 (define_insn "*<code>extendsfxf2"
8980 [(set (match_operand:XF 0 "register_operand" "=f")
8981 (absneg:XF (float_extend:XF
8982 (match_operand:SF 1 "register_operand" "0"))))]
8983 "TARGET_80387"
8984 "f<absneg_mnemonic>"
8985 [(set_attr "type" "fsgn")
8986 (set_attr "mode" "XF")])
8987
8988 (define_insn "*<code>extenddfxf2"
8989 [(set (match_operand:XF 0 "register_operand" "=f")
8990 (absneg:XF (float_extend:XF
8991 (match_operand:DF 1 "register_operand" "0"))))]
8992 "TARGET_80387"
8993 "f<absneg_mnemonic>"
8994 [(set_attr "type" "fsgn")
8995 (set_attr "mode" "XF")])
8996
8997 ;; Copysign instructions
8998
8999 (define_mode_iterator CSGNMODE [SF DF TF])
9000 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9001
9002 (define_expand "copysign<mode>3"
9003 [(match_operand:CSGNMODE 0 "register_operand" "")
9004 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9005 (match_operand:CSGNMODE 2 "register_operand" "")]
9006 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9007 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9008 "ix86_expand_copysign (operands); DONE;")
9009
9010 (define_insn_and_split "copysign<mode>3_const"
9011 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9012 (unspec:CSGNMODE
9013 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9014 (match_operand:CSGNMODE 2 "register_operand" "0")
9015 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9016 UNSPEC_COPYSIGN))]
9017 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9018 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9019 "#"
9020 "&& reload_completed"
9021 [(const_int 0)]
9022 "ix86_split_copysign_const (operands); DONE;")
9023
9024 (define_insn "copysign<mode>3_var"
9025 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9026 (unspec:CSGNMODE
9027 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9028 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9029 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9030 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9031 UNSPEC_COPYSIGN))
9032 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9033 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9034 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9035 "#")
9036
9037 (define_split
9038 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9039 (unspec:CSGNMODE
9040 [(match_operand:CSGNMODE 2 "register_operand" "")
9041 (match_operand:CSGNMODE 3 "register_operand" "")
9042 (match_operand:<CSGNVMODE> 4 "" "")
9043 (match_operand:<CSGNVMODE> 5 "" "")]
9044 UNSPEC_COPYSIGN))
9045 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9046 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9047 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9048 && reload_completed"
9049 [(const_int 0)]
9050 "ix86_split_copysign_var (operands); DONE;")
9051 \f
9052 ;; One complement instructions
9053
9054 (define_expand "one_cmpl<mode>2"
9055 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9056 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9057 ""
9058 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9059
9060 (define_insn "*one_cmpl<mode>2_1"
9061 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9062 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9063 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9064 "not{<imodesuffix>}\t%0"
9065 [(set_attr "type" "negnot")
9066 (set_attr "mode" "<MODE>")])
9067
9068 ;; %%% Potential partial reg stall on alternative 1. What to do?
9069 (define_insn "*one_cmplqi2_1"
9070 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9071 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9072 "ix86_unary_operator_ok (NOT, QImode, operands)"
9073 "@
9074 not{b}\t%0
9075 not{l}\t%k0"
9076 [(set_attr "type" "negnot")
9077 (set_attr "mode" "QI,SI")])
9078
9079 ;; ??? Currently never generated - xor is used instead.
9080 (define_insn "*one_cmplsi2_1_zext"
9081 [(set (match_operand:DI 0 "register_operand" "=r")
9082 (zero_extend:DI
9083 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9084 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9085 "not{l}\t%k0"
9086 [(set_attr "type" "negnot")
9087 (set_attr "mode" "SI")])
9088
9089 (define_insn "*one_cmpl<mode>2_2"
9090 [(set (reg FLAGS_REG)
9091 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9092 (const_int 0)))
9093 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9094 (not:SWI (match_dup 1)))]
9095 "ix86_match_ccmode (insn, CCNOmode)
9096 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9097 "#"
9098 [(set_attr "type" "alu1")
9099 (set_attr "mode" "<MODE>")])
9100
9101 (define_split
9102 [(set (match_operand 0 "flags_reg_operand" "")
9103 (match_operator 2 "compare_operator"
9104 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9105 (const_int 0)]))
9106 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9107 (not:SWI (match_dup 3)))]
9108 "ix86_match_ccmode (insn, CCNOmode)"
9109 [(parallel [(set (match_dup 0)
9110 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9111 (const_int 0)]))
9112 (set (match_dup 1)
9113 (xor:SWI (match_dup 3) (const_int -1)))])])
9114
9115 ;; ??? Currently never generated - xor is used instead.
9116 (define_insn "*one_cmplsi2_2_zext"
9117 [(set (reg FLAGS_REG)
9118 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9119 (const_int 0)))
9120 (set (match_operand:DI 0 "register_operand" "=r")
9121 (zero_extend:DI (not:SI (match_dup 1))))]
9122 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9123 && ix86_unary_operator_ok (NOT, SImode, operands)"
9124 "#"
9125 [(set_attr "type" "alu1")
9126 (set_attr "mode" "SI")])
9127
9128 (define_split
9129 [(set (match_operand 0 "flags_reg_operand" "")
9130 (match_operator 2 "compare_operator"
9131 [(not:SI (match_operand:SI 3 "register_operand" ""))
9132 (const_int 0)]))
9133 (set (match_operand:DI 1 "register_operand" "")
9134 (zero_extend:DI (not:SI (match_dup 3))))]
9135 "ix86_match_ccmode (insn, CCNOmode)"
9136 [(parallel [(set (match_dup 0)
9137 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9138 (const_int 0)]))
9139 (set (match_dup 1)
9140 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9141 \f
9142 ;; Shift instructions
9143
9144 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9145 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9146 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9147 ;; from the assembler input.
9148 ;;
9149 ;; This instruction shifts the target reg/mem as usual, but instead of
9150 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9151 ;; is a left shift double, bits are taken from the high order bits of
9152 ;; reg, else if the insn is a shift right double, bits are taken from the
9153 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9154 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9155 ;;
9156 ;; Since sh[lr]d does not change the `reg' operand, that is done
9157 ;; separately, making all shifts emit pairs of shift double and normal
9158 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9159 ;; support a 63 bit shift, each shift where the count is in a reg expands
9160 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9161 ;;
9162 ;; If the shift count is a constant, we need never emit more than one
9163 ;; shift pair, instead using moves and sign extension for counts greater
9164 ;; than 31.
9165
9166 (define_expand "ashl<mode>3"
9167 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9168 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9169 (match_operand:QI 2 "nonmemory_operand" "")))]
9170 ""
9171 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9172
9173 (define_insn "*ashl<mode>3_doubleword"
9174 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9175 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9176 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9177 (clobber (reg:CC FLAGS_REG))]
9178 ""
9179 "#"
9180 [(set_attr "type" "multi")])
9181
9182 (define_split
9183 [(set (match_operand:DWI 0 "register_operand" "")
9184 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9185 (match_operand:QI 2 "nonmemory_operand" "")))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9188 [(const_int 0)]
9189 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9190
9191 ;; By default we don't ask for a scratch register, because when DWImode
9192 ;; values are manipulated, registers are already at a premium. But if
9193 ;; we have one handy, we won't turn it away.
9194
9195 (define_peephole2
9196 [(match_scratch:DWIH 3 "r")
9197 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9198 (ashift:<DWI>
9199 (match_operand:<DWI> 1 "nonmemory_operand" "")
9200 (match_operand:QI 2 "nonmemory_operand" "")))
9201 (clobber (reg:CC FLAGS_REG))])
9202 (match_dup 3)]
9203 "TARGET_CMOVE"
9204 [(const_int 0)]
9205 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9206
9207 (define_insn "x86_64_shld"
9208 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9209 (ior:DI (ashift:DI (match_dup 0)
9210 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9211 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9212 (minus:QI (const_int 64) (match_dup 2)))))
9213 (clobber (reg:CC FLAGS_REG))]
9214 "TARGET_64BIT"
9215 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9216 [(set_attr "type" "ishift")
9217 (set_attr "prefix_0f" "1")
9218 (set_attr "mode" "DI")
9219 (set_attr "athlon_decode" "vector")
9220 (set_attr "amdfam10_decode" "vector")
9221 (set_attr "bdver1_decode" "vector")])
9222
9223 (define_insn "x86_shld"
9224 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9225 (ior:SI (ashift:SI (match_dup 0)
9226 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9227 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9228 (minus:QI (const_int 32) (match_dup 2)))))
9229 (clobber (reg:CC FLAGS_REG))]
9230 ""
9231 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9232 [(set_attr "type" "ishift")
9233 (set_attr "prefix_0f" "1")
9234 (set_attr "mode" "SI")
9235 (set_attr "pent_pair" "np")
9236 (set_attr "athlon_decode" "vector")
9237 (set_attr "amdfam10_decode" "vector")
9238 (set_attr "bdver1_decode" "vector")])
9239
9240 (define_expand "x86_shift<mode>_adj_1"
9241 [(set (reg:CCZ FLAGS_REG)
9242 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9243 (match_dup 4))
9244 (const_int 0)))
9245 (set (match_operand:SWI48 0 "register_operand" "")
9246 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9247 (match_operand:SWI48 1 "register_operand" "")
9248 (match_dup 0)))
9249 (set (match_dup 1)
9250 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9251 (match_operand:SWI48 3 "register_operand" "r")
9252 (match_dup 1)))]
9253 "TARGET_CMOVE"
9254 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9255
9256 (define_expand "x86_shift<mode>_adj_2"
9257 [(use (match_operand:SWI48 0 "register_operand" ""))
9258 (use (match_operand:SWI48 1 "register_operand" ""))
9259 (use (match_operand:QI 2 "register_operand" ""))]
9260 ""
9261 {
9262 rtx label = gen_label_rtx ();
9263 rtx tmp;
9264
9265 emit_insn (gen_testqi_ccz_1 (operands[2],
9266 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9267
9268 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9269 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9270 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9271 gen_rtx_LABEL_REF (VOIDmode, label),
9272 pc_rtx);
9273 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9274 JUMP_LABEL (tmp) = label;
9275
9276 emit_move_insn (operands[0], operands[1]);
9277 ix86_expand_clear (operands[1]);
9278
9279 emit_label (label);
9280 LABEL_NUSES (label) = 1;
9281
9282 DONE;
9283 })
9284
9285 ;; Avoid useless masking of count operand.
9286 (define_insn_and_split "*ashl<mode>3_mask"
9287 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9288 (ashift:SWI48
9289 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9290 (subreg:QI
9291 (and:SI
9292 (match_operand:SI 2 "nonimmediate_operand" "c")
9293 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9294 (clobber (reg:CC FLAGS_REG))]
9295 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9296 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9297 == GET_MODE_BITSIZE (<MODE>mode)-1"
9298 "#"
9299 "&& 1"
9300 [(parallel [(set (match_dup 0)
9301 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9302 (clobber (reg:CC FLAGS_REG))])]
9303 {
9304 if (can_create_pseudo_p ())
9305 operands [2] = force_reg (SImode, operands[2]);
9306
9307 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9308 }
9309 [(set_attr "type" "ishift")
9310 (set_attr "mode" "<MODE>")])
9311
9312 (define_insn "*ashl<mode>3_1"
9313 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9314 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9315 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9318 {
9319 switch (get_attr_type (insn))
9320 {
9321 case TYPE_LEA:
9322 return "#";
9323
9324 case TYPE_ALU:
9325 gcc_assert (operands[2] == const1_rtx);
9326 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9327 return "add{<imodesuffix>}\t%0, %0";
9328
9329 default:
9330 if (operands[2] == const1_rtx
9331 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9332 return "sal{<imodesuffix>}\t%0";
9333 else
9334 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9335 }
9336 }
9337 [(set (attr "type")
9338 (cond [(eq_attr "alternative" "1")
9339 (const_string "lea")
9340 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9341 (const_int 0))
9342 (match_operand 0 "register_operand" ""))
9343 (match_operand 2 "const1_operand" ""))
9344 (const_string "alu")
9345 ]
9346 (const_string "ishift")))
9347 (set (attr "length_immediate")
9348 (if_then_else
9349 (ior (eq_attr "type" "alu")
9350 (and (eq_attr "type" "ishift")
9351 (and (match_operand 2 "const1_operand" "")
9352 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9353 (const_int 0)))))
9354 (const_string "0")
9355 (const_string "*")))
9356 (set_attr "mode" "<MODE>")])
9357
9358 (define_insn "*ashlsi3_1_zext"
9359 [(set (match_operand:DI 0 "register_operand" "=r,r")
9360 (zero_extend:DI
9361 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9362 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9363 (clobber (reg:CC FLAGS_REG))]
9364 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9365 {
9366 switch (get_attr_type (insn))
9367 {
9368 case TYPE_LEA:
9369 return "#";
9370
9371 case TYPE_ALU:
9372 gcc_assert (operands[2] == const1_rtx);
9373 return "add{l}\t%k0, %k0";
9374
9375 default:
9376 if (operands[2] == const1_rtx
9377 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9378 return "sal{l}\t%k0";
9379 else
9380 return "sal{l}\t{%2, %k0|%k0, %2}";
9381 }
9382 }
9383 [(set (attr "type")
9384 (cond [(eq_attr "alternative" "1")
9385 (const_string "lea")
9386 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9387 (const_int 0))
9388 (match_operand 2 "const1_operand" ""))
9389 (const_string "alu")
9390 ]
9391 (const_string "ishift")))
9392 (set (attr "length_immediate")
9393 (if_then_else
9394 (ior (eq_attr "type" "alu")
9395 (and (eq_attr "type" "ishift")
9396 (and (match_operand 2 "const1_operand" "")
9397 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9398 (const_int 0)))))
9399 (const_string "0")
9400 (const_string "*")))
9401 (set_attr "mode" "SI")])
9402
9403 (define_insn "*ashlhi3_1"
9404 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9405 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9406 (match_operand:QI 2 "nonmemory_operand" "cI")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "TARGET_PARTIAL_REG_STALL
9409 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9410 {
9411 switch (get_attr_type (insn))
9412 {
9413 case TYPE_ALU:
9414 gcc_assert (operands[2] == const1_rtx);
9415 return "add{w}\t%0, %0";
9416
9417 default:
9418 if (operands[2] == const1_rtx
9419 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9420 return "sal{w}\t%0";
9421 else
9422 return "sal{w}\t{%2, %0|%0, %2}";
9423 }
9424 }
9425 [(set (attr "type")
9426 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9427 (const_int 0))
9428 (match_operand 0 "register_operand" ""))
9429 (match_operand 2 "const1_operand" ""))
9430 (const_string "alu")
9431 ]
9432 (const_string "ishift")))
9433 (set (attr "length_immediate")
9434 (if_then_else
9435 (ior (eq_attr "type" "alu")
9436 (and (eq_attr "type" "ishift")
9437 (and (match_operand 2 "const1_operand" "")
9438 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9439 (const_int 0)))))
9440 (const_string "0")
9441 (const_string "*")))
9442 (set_attr "mode" "HI")])
9443
9444 (define_insn "*ashlhi3_1_lea"
9445 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9446 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9447 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9448 (clobber (reg:CC FLAGS_REG))]
9449 "!TARGET_PARTIAL_REG_STALL
9450 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9451 {
9452 switch (get_attr_type (insn))
9453 {
9454 case TYPE_LEA:
9455 return "#";
9456
9457 case TYPE_ALU:
9458 gcc_assert (operands[2] == const1_rtx);
9459 return "add{w}\t%0, %0";
9460
9461 default:
9462 if (operands[2] == const1_rtx
9463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9464 return "sal{w}\t%0";
9465 else
9466 return "sal{w}\t{%2, %0|%0, %2}";
9467 }
9468 }
9469 [(set (attr "type")
9470 (cond [(eq_attr "alternative" "1")
9471 (const_string "lea")
9472 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9473 (const_int 0))
9474 (match_operand 0 "register_operand" ""))
9475 (match_operand 2 "const1_operand" ""))
9476 (const_string "alu")
9477 ]
9478 (const_string "ishift")))
9479 (set (attr "length_immediate")
9480 (if_then_else
9481 (ior (eq_attr "type" "alu")
9482 (and (eq_attr "type" "ishift")
9483 (and (match_operand 2 "const1_operand" "")
9484 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9485 (const_int 0)))))
9486 (const_string "0")
9487 (const_string "*")))
9488 (set_attr "mode" "HI,SI")])
9489
9490 (define_insn "*ashlqi3_1"
9491 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9492 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9493 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9494 (clobber (reg:CC FLAGS_REG))]
9495 "TARGET_PARTIAL_REG_STALL
9496 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9497 {
9498 switch (get_attr_type (insn))
9499 {
9500 case TYPE_ALU:
9501 gcc_assert (operands[2] == const1_rtx);
9502 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9503 return "add{l}\t%k0, %k0";
9504 else
9505 return "add{b}\t%0, %0";
9506
9507 default:
9508 if (operands[2] == const1_rtx
9509 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9510 {
9511 if (get_attr_mode (insn) == MODE_SI)
9512 return "sal{l}\t%k0";
9513 else
9514 return "sal{b}\t%0";
9515 }
9516 else
9517 {
9518 if (get_attr_mode (insn) == MODE_SI)
9519 return "sal{l}\t{%2, %k0|%k0, %2}";
9520 else
9521 return "sal{b}\t{%2, %0|%0, %2}";
9522 }
9523 }
9524 }
9525 [(set (attr "type")
9526 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9527 (const_int 0))
9528 (match_operand 0 "register_operand" ""))
9529 (match_operand 2 "const1_operand" ""))
9530 (const_string "alu")
9531 ]
9532 (const_string "ishift")))
9533 (set (attr "length_immediate")
9534 (if_then_else
9535 (ior (eq_attr "type" "alu")
9536 (and (eq_attr "type" "ishift")
9537 (and (match_operand 2 "const1_operand" "")
9538 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9539 (const_int 0)))))
9540 (const_string "0")
9541 (const_string "*")))
9542 (set_attr "mode" "QI,SI")])
9543
9544 ;; %%% Potential partial reg stall on alternative 2. What to do?
9545 (define_insn "*ashlqi3_1_lea"
9546 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9547 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9548 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9549 (clobber (reg:CC FLAGS_REG))]
9550 "!TARGET_PARTIAL_REG_STALL
9551 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9552 {
9553 switch (get_attr_type (insn))
9554 {
9555 case TYPE_LEA:
9556 return "#";
9557
9558 case TYPE_ALU:
9559 gcc_assert (operands[2] == const1_rtx);
9560 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9561 return "add{l}\t%k0, %k0";
9562 else
9563 return "add{b}\t%0, %0";
9564
9565 default:
9566 if (operands[2] == const1_rtx
9567 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9568 {
9569 if (get_attr_mode (insn) == MODE_SI)
9570 return "sal{l}\t%k0";
9571 else
9572 return "sal{b}\t%0";
9573 }
9574 else
9575 {
9576 if (get_attr_mode (insn) == MODE_SI)
9577 return "sal{l}\t{%2, %k0|%k0, %2}";
9578 else
9579 return "sal{b}\t{%2, %0|%0, %2}";
9580 }
9581 }
9582 }
9583 [(set (attr "type")
9584 (cond [(eq_attr "alternative" "2")
9585 (const_string "lea")
9586 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9587 (const_int 0))
9588 (match_operand 0 "register_operand" ""))
9589 (match_operand 2 "const1_operand" ""))
9590 (const_string "alu")
9591 ]
9592 (const_string "ishift")))
9593 (set (attr "length_immediate")
9594 (if_then_else
9595 (ior (eq_attr "type" "alu")
9596 (and (eq_attr "type" "ishift")
9597 (and (match_operand 2 "const1_operand" "")
9598 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9599 (const_int 0)))))
9600 (const_string "0")
9601 (const_string "*")))
9602 (set_attr "mode" "QI,SI,SI")])
9603
9604 (define_insn "*ashlqi3_1_slp"
9605 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9606 (ashift:QI (match_dup 0)
9607 (match_operand:QI 1 "nonmemory_operand" "cI")))
9608 (clobber (reg:CC FLAGS_REG))]
9609 "(optimize_function_for_size_p (cfun)
9610 || !TARGET_PARTIAL_FLAG_REG_STALL
9611 || (operands[1] == const1_rtx
9612 && (TARGET_SHIFT1
9613 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9614 {
9615 switch (get_attr_type (insn))
9616 {
9617 case TYPE_ALU:
9618 gcc_assert (operands[1] == const1_rtx);
9619 return "add{b}\t%0, %0";
9620
9621 default:
9622 if (operands[1] == const1_rtx
9623 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9624 return "sal{b}\t%0";
9625 else
9626 return "sal{b}\t{%1, %0|%0, %1}";
9627 }
9628 }
9629 [(set (attr "type")
9630 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9631 (const_int 0))
9632 (match_operand 0 "register_operand" ""))
9633 (match_operand 1 "const1_operand" ""))
9634 (const_string "alu")
9635 ]
9636 (const_string "ishift1")))
9637 (set (attr "length_immediate")
9638 (if_then_else
9639 (ior (eq_attr "type" "alu")
9640 (and (eq_attr "type" "ishift1")
9641 (and (match_operand 1 "const1_operand" "")
9642 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9643 (const_int 0)))))
9644 (const_string "0")
9645 (const_string "*")))
9646 (set_attr "mode" "QI")])
9647
9648 ;; Convert lea to the lea pattern to avoid flags dependency.
9649 (define_split
9650 [(set (match_operand 0 "register_operand" "")
9651 (ashift (match_operand 1 "index_register_operand" "")
9652 (match_operand:QI 2 "const_int_operand" "")))
9653 (clobber (reg:CC FLAGS_REG))]
9654 "reload_completed
9655 && true_regnum (operands[0]) != true_regnum (operands[1])"
9656 [(const_int 0)]
9657 {
9658 rtx pat;
9659 enum machine_mode mode = GET_MODE (operands[0]);
9660
9661 if (mode != Pmode)
9662 operands[1] = gen_lowpart (Pmode, operands[1]);
9663 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9664
9665 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9666
9667 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9668 operands[0] = gen_lowpart (SImode, operands[0]);
9669
9670 if (TARGET_64BIT && mode != Pmode)
9671 pat = gen_rtx_SUBREG (SImode, pat, 0);
9672
9673 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9674 DONE;
9675 })
9676
9677 ;; Convert lea to the lea pattern to avoid flags dependency.
9678 (define_split
9679 [(set (match_operand:DI 0 "register_operand" "")
9680 (zero_extend:DI
9681 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9682 (match_operand:QI 2 "const_int_operand" ""))))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_64BIT && reload_completed
9685 && true_regnum (operands[0]) != true_regnum (operands[1])"
9686 [(set (match_dup 0)
9687 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9688 {
9689 operands[1] = gen_lowpart (DImode, operands[1]);
9690 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9691 })
9692
9693 ;; This pattern can't accept a variable shift count, since shifts by
9694 ;; zero don't affect the flags. We assume that shifts by constant
9695 ;; zero are optimized away.
9696 (define_insn "*ashl<mode>3_cmp"
9697 [(set (reg FLAGS_REG)
9698 (compare
9699 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9700 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9701 (const_int 0)))
9702 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9703 (ashift:SWI (match_dup 1) (match_dup 2)))]
9704 "(optimize_function_for_size_p (cfun)
9705 || !TARGET_PARTIAL_FLAG_REG_STALL
9706 || (operands[2] == const1_rtx
9707 && (TARGET_SHIFT1
9708 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9709 && ix86_match_ccmode (insn, CCGOCmode)
9710 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9711 {
9712 switch (get_attr_type (insn))
9713 {
9714 case TYPE_ALU:
9715 gcc_assert (operands[2] == const1_rtx);
9716 return "add{<imodesuffix>}\t%0, %0";
9717
9718 default:
9719 if (operands[2] == const1_rtx
9720 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9721 return "sal{<imodesuffix>}\t%0";
9722 else
9723 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9724 }
9725 }
9726 [(set (attr "type")
9727 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9728 (const_int 0))
9729 (match_operand 0 "register_operand" ""))
9730 (match_operand 2 "const1_operand" ""))
9731 (const_string "alu")
9732 ]
9733 (const_string "ishift")))
9734 (set (attr "length_immediate")
9735 (if_then_else
9736 (ior (eq_attr "type" "alu")
9737 (and (eq_attr "type" "ishift")
9738 (and (match_operand 2 "const1_operand" "")
9739 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9740 (const_int 0)))))
9741 (const_string "0")
9742 (const_string "*")))
9743 (set_attr "mode" "<MODE>")])
9744
9745 (define_insn "*ashlsi3_cmp_zext"
9746 [(set (reg FLAGS_REG)
9747 (compare
9748 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9749 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9750 (const_int 0)))
9751 (set (match_operand:DI 0 "register_operand" "=r")
9752 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9753 "TARGET_64BIT
9754 && (optimize_function_for_size_p (cfun)
9755 || !TARGET_PARTIAL_FLAG_REG_STALL
9756 || (operands[2] == const1_rtx
9757 && (TARGET_SHIFT1
9758 || TARGET_DOUBLE_WITH_ADD)))
9759 && ix86_match_ccmode (insn, CCGOCmode)
9760 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9761 {
9762 switch (get_attr_type (insn))
9763 {
9764 case TYPE_ALU:
9765 gcc_assert (operands[2] == const1_rtx);
9766 return "add{l}\t%k0, %k0";
9767
9768 default:
9769 if (operands[2] == const1_rtx
9770 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9771 return "sal{l}\t%k0";
9772 else
9773 return "sal{l}\t{%2, %k0|%k0, %2}";
9774 }
9775 }
9776 [(set (attr "type")
9777 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9778 (const_int 0))
9779 (match_operand 2 "const1_operand" ""))
9780 (const_string "alu")
9781 ]
9782 (const_string "ishift")))
9783 (set (attr "length_immediate")
9784 (if_then_else
9785 (ior (eq_attr "type" "alu")
9786 (and (eq_attr "type" "ishift")
9787 (and (match_operand 2 "const1_operand" "")
9788 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9789 (const_int 0)))))
9790 (const_string "0")
9791 (const_string "*")))
9792 (set_attr "mode" "SI")])
9793
9794 (define_insn "*ashl<mode>3_cconly"
9795 [(set (reg FLAGS_REG)
9796 (compare
9797 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9798 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9799 (const_int 0)))
9800 (clobber (match_scratch:SWI 0 "=<r>"))]
9801 "(optimize_function_for_size_p (cfun)
9802 || !TARGET_PARTIAL_FLAG_REG_STALL
9803 || (operands[2] == const1_rtx
9804 && (TARGET_SHIFT1
9805 || TARGET_DOUBLE_WITH_ADD)))
9806 && ix86_match_ccmode (insn, CCGOCmode)"
9807 {
9808 switch (get_attr_type (insn))
9809 {
9810 case TYPE_ALU:
9811 gcc_assert (operands[2] == const1_rtx);
9812 return "add{<imodesuffix>}\t%0, %0";
9813
9814 default:
9815 if (operands[2] == const1_rtx
9816 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9817 return "sal{<imodesuffix>}\t%0";
9818 else
9819 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9820 }
9821 }
9822 [(set (attr "type")
9823 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9824 (const_int 0))
9825 (match_operand 0 "register_operand" ""))
9826 (match_operand 2 "const1_operand" ""))
9827 (const_string "alu")
9828 ]
9829 (const_string "ishift")))
9830 (set (attr "length_immediate")
9831 (if_then_else
9832 (ior (eq_attr "type" "alu")
9833 (and (eq_attr "type" "ishift")
9834 (and (match_operand 2 "const1_operand" "")
9835 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9836 (const_int 0)))))
9837 (const_string "0")
9838 (const_string "*")))
9839 (set_attr "mode" "<MODE>")])
9840
9841 ;; See comment above `ashl<mode>3' about how this works.
9842
9843 (define_expand "<shiftrt_insn><mode>3"
9844 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9845 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9846 (match_operand:QI 2 "nonmemory_operand" "")))]
9847 ""
9848 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9849
9850 ;; Avoid useless masking of count operand.
9851 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9852 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9853 (any_shiftrt:SWI48
9854 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9855 (subreg:QI
9856 (and:SI
9857 (match_operand:SI 2 "nonimmediate_operand" "c")
9858 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9859 (clobber (reg:CC FLAGS_REG))]
9860 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9861 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9862 == GET_MODE_BITSIZE (<MODE>mode)-1"
9863 "#"
9864 "&& 1"
9865 [(parallel [(set (match_dup 0)
9866 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9867 (clobber (reg:CC FLAGS_REG))])]
9868 {
9869 if (can_create_pseudo_p ())
9870 operands [2] = force_reg (SImode, operands[2]);
9871
9872 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9873 }
9874 [(set_attr "type" "ishift")
9875 (set_attr "mode" "<MODE>")])
9876
9877 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9878 [(set (match_operand:DWI 0 "register_operand" "=r")
9879 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9880 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9881 (clobber (reg:CC FLAGS_REG))]
9882 ""
9883 "#"
9884 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9885 [(const_int 0)]
9886 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9887 [(set_attr "type" "multi")])
9888
9889 ;; By default we don't ask for a scratch register, because when DWImode
9890 ;; values are manipulated, registers are already at a premium. But if
9891 ;; we have one handy, we won't turn it away.
9892
9893 (define_peephole2
9894 [(match_scratch:DWIH 3 "r")
9895 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9896 (any_shiftrt:<DWI>
9897 (match_operand:<DWI> 1 "register_operand" "")
9898 (match_operand:QI 2 "nonmemory_operand" "")))
9899 (clobber (reg:CC FLAGS_REG))])
9900 (match_dup 3)]
9901 "TARGET_CMOVE"
9902 [(const_int 0)]
9903 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9904
9905 (define_insn "x86_64_shrd"
9906 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9907 (ior:DI (ashiftrt:DI (match_dup 0)
9908 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9909 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9910 (minus:QI (const_int 64) (match_dup 2)))))
9911 (clobber (reg:CC FLAGS_REG))]
9912 "TARGET_64BIT"
9913 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9914 [(set_attr "type" "ishift")
9915 (set_attr "prefix_0f" "1")
9916 (set_attr "mode" "DI")
9917 (set_attr "athlon_decode" "vector")
9918 (set_attr "amdfam10_decode" "vector")
9919 (set_attr "bdver1_decode" "vector")])
9920
9921 (define_insn "x86_shrd"
9922 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9923 (ior:SI (ashiftrt:SI (match_dup 0)
9924 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9925 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9926 (minus:QI (const_int 32) (match_dup 2)))))
9927 (clobber (reg:CC FLAGS_REG))]
9928 ""
9929 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9930 [(set_attr "type" "ishift")
9931 (set_attr "prefix_0f" "1")
9932 (set_attr "mode" "SI")
9933 (set_attr "pent_pair" "np")
9934 (set_attr "athlon_decode" "vector")
9935 (set_attr "amdfam10_decode" "vector")
9936 (set_attr "bdver1_decode" "vector")])
9937
9938 (define_insn "ashrdi3_cvt"
9939 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9940 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9941 (match_operand:QI 2 "const_int_operand" "")))
9942 (clobber (reg:CC FLAGS_REG))]
9943 "TARGET_64BIT && INTVAL (operands[2]) == 63
9944 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9945 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9946 "@
9947 {cqto|cqo}
9948 sar{q}\t{%2, %0|%0, %2}"
9949 [(set_attr "type" "imovx,ishift")
9950 (set_attr "prefix_0f" "0,*")
9951 (set_attr "length_immediate" "0,*")
9952 (set_attr "modrm" "0,1")
9953 (set_attr "mode" "DI")])
9954
9955 (define_insn "ashrsi3_cvt"
9956 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9957 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9958 (match_operand:QI 2 "const_int_operand" "")))
9959 (clobber (reg:CC FLAGS_REG))]
9960 "INTVAL (operands[2]) == 31
9961 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9962 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9963 "@
9964 {cltd|cdq}
9965 sar{l}\t{%2, %0|%0, %2}"
9966 [(set_attr "type" "imovx,ishift")
9967 (set_attr "prefix_0f" "0,*")
9968 (set_attr "length_immediate" "0,*")
9969 (set_attr "modrm" "0,1")
9970 (set_attr "mode" "SI")])
9971
9972 (define_insn "*ashrsi3_cvt_zext"
9973 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9974 (zero_extend:DI
9975 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9976 (match_operand:QI 2 "const_int_operand" ""))))
9977 (clobber (reg:CC FLAGS_REG))]
9978 "TARGET_64BIT && INTVAL (operands[2]) == 31
9979 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9980 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9981 "@
9982 {cltd|cdq}
9983 sar{l}\t{%2, %k0|%k0, %2}"
9984 [(set_attr "type" "imovx,ishift")
9985 (set_attr "prefix_0f" "0,*")
9986 (set_attr "length_immediate" "0,*")
9987 (set_attr "modrm" "0,1")
9988 (set_attr "mode" "SI")])
9989
9990 (define_expand "x86_shift<mode>_adj_3"
9991 [(use (match_operand:SWI48 0 "register_operand" ""))
9992 (use (match_operand:SWI48 1 "register_operand" ""))
9993 (use (match_operand:QI 2 "register_operand" ""))]
9994 ""
9995 {
9996 rtx label = gen_label_rtx ();
9997 rtx tmp;
9998
9999 emit_insn (gen_testqi_ccz_1 (operands[2],
10000 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10001
10002 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10003 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10004 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10005 gen_rtx_LABEL_REF (VOIDmode, label),
10006 pc_rtx);
10007 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10008 JUMP_LABEL (tmp) = label;
10009
10010 emit_move_insn (operands[0], operands[1]);
10011 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10012 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10013 emit_label (label);
10014 LABEL_NUSES (label) = 1;
10015
10016 DONE;
10017 })
10018
10019 (define_insn "*<shiftrt_insn><mode>3_1"
10020 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10021 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10022 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10023 (clobber (reg:CC FLAGS_REG))]
10024 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10025 {
10026 if (operands[2] == const1_rtx
10027 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10028 return "<shiftrt>{<imodesuffix>}\t%0";
10029 else
10030 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10031 }
10032 [(set_attr "type" "ishift")
10033 (set (attr "length_immediate")
10034 (if_then_else
10035 (and (match_operand 2 "const1_operand" "")
10036 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10037 (const_int 0)))
10038 (const_string "0")
10039 (const_string "*")))
10040 (set_attr "mode" "<MODE>")])
10041
10042 (define_insn "*<shiftrt_insn>si3_1_zext"
10043 [(set (match_operand:DI 0 "register_operand" "=r")
10044 (zero_extend:DI
10045 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10046 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10047 (clobber (reg:CC FLAGS_REG))]
10048 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10049 {
10050 if (operands[2] == const1_rtx
10051 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10052 return "<shiftrt>{l}\t%k0";
10053 else
10054 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10055 }
10056 [(set_attr "type" "ishift")
10057 (set (attr "length_immediate")
10058 (if_then_else
10059 (and (match_operand 2 "const1_operand" "")
10060 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10061 (const_int 0)))
10062 (const_string "0")
10063 (const_string "*")))
10064 (set_attr "mode" "SI")])
10065
10066 (define_insn "*<shiftrt_insn>qi3_1_slp"
10067 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10068 (any_shiftrt:QI (match_dup 0)
10069 (match_operand:QI 1 "nonmemory_operand" "cI")))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "(optimize_function_for_size_p (cfun)
10072 || !TARGET_PARTIAL_REG_STALL
10073 || (operands[1] == const1_rtx
10074 && TARGET_SHIFT1))"
10075 {
10076 if (operands[1] == const1_rtx
10077 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10078 return "<shiftrt>{b}\t%0";
10079 else
10080 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10081 }
10082 [(set_attr "type" "ishift1")
10083 (set (attr "length_immediate")
10084 (if_then_else
10085 (and (match_operand 1 "const1_operand" "")
10086 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10087 (const_int 0)))
10088 (const_string "0")
10089 (const_string "*")))
10090 (set_attr "mode" "QI")])
10091
10092 ;; This pattern can't accept a variable shift count, since shifts by
10093 ;; zero don't affect the flags. We assume that shifts by constant
10094 ;; zero are optimized away.
10095 (define_insn "*<shiftrt_insn><mode>3_cmp"
10096 [(set (reg FLAGS_REG)
10097 (compare
10098 (any_shiftrt:SWI
10099 (match_operand:SWI 1 "nonimmediate_operand" "0")
10100 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10101 (const_int 0)))
10102 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10103 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10104 "(optimize_function_for_size_p (cfun)
10105 || !TARGET_PARTIAL_FLAG_REG_STALL
10106 || (operands[2] == const1_rtx
10107 && TARGET_SHIFT1))
10108 && ix86_match_ccmode (insn, CCGOCmode)
10109 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10110 {
10111 if (operands[2] == const1_rtx
10112 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10113 return "<shiftrt>{<imodesuffix>}\t%0";
10114 else
10115 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10116 }
10117 [(set_attr "type" "ishift")
10118 (set (attr "length_immediate")
10119 (if_then_else
10120 (and (match_operand 2 "const1_operand" "")
10121 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10122 (const_int 0)))
10123 (const_string "0")
10124 (const_string "*")))
10125 (set_attr "mode" "<MODE>")])
10126
10127 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10128 [(set (reg FLAGS_REG)
10129 (compare
10130 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10131 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10132 (const_int 0)))
10133 (set (match_operand:DI 0 "register_operand" "=r")
10134 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10135 "TARGET_64BIT
10136 && (optimize_function_for_size_p (cfun)
10137 || !TARGET_PARTIAL_FLAG_REG_STALL
10138 || (operands[2] == const1_rtx
10139 && TARGET_SHIFT1))
10140 && ix86_match_ccmode (insn, CCGOCmode)
10141 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10142 {
10143 if (operands[2] == const1_rtx
10144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10145 return "<shiftrt>{l}\t%k0";
10146 else
10147 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10148 }
10149 [(set_attr "type" "ishift")
10150 (set (attr "length_immediate")
10151 (if_then_else
10152 (and (match_operand 2 "const1_operand" "")
10153 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10154 (const_int 0)))
10155 (const_string "0")
10156 (const_string "*")))
10157 (set_attr "mode" "SI")])
10158
10159 (define_insn "*<shiftrt_insn><mode>3_cconly"
10160 [(set (reg FLAGS_REG)
10161 (compare
10162 (any_shiftrt:SWI
10163 (match_operand:SWI 1 "register_operand" "0")
10164 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10165 (const_int 0)))
10166 (clobber (match_scratch:SWI 0 "=<r>"))]
10167 "(optimize_function_for_size_p (cfun)
10168 || !TARGET_PARTIAL_FLAG_REG_STALL
10169 || (operands[2] == const1_rtx
10170 && TARGET_SHIFT1))
10171 && ix86_match_ccmode (insn, CCGOCmode)"
10172 {
10173 if (operands[2] == const1_rtx
10174 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10175 return "<shiftrt>{<imodesuffix>}\t%0";
10176 else
10177 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10178 }
10179 [(set_attr "type" "ishift")
10180 (set (attr "length_immediate")
10181 (if_then_else
10182 (and (match_operand 2 "const1_operand" "")
10183 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10184 (const_int 0)))
10185 (const_string "0")
10186 (const_string "*")))
10187 (set_attr "mode" "<MODE>")])
10188 \f
10189 ;; Rotate instructions
10190
10191 (define_expand "<rotate_insn>ti3"
10192 [(set (match_operand:TI 0 "register_operand" "")
10193 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10194 (match_operand:QI 2 "nonmemory_operand" "")))]
10195 "TARGET_64BIT"
10196 {
10197 if (const_1_to_63_operand (operands[2], VOIDmode))
10198 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10199 (operands[0], operands[1], operands[2]));
10200 else
10201 FAIL;
10202
10203 DONE;
10204 })
10205
10206 (define_expand "<rotate_insn>di3"
10207 [(set (match_operand:DI 0 "shiftdi_operand" "")
10208 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10209 (match_operand:QI 2 "nonmemory_operand" "")))]
10210 ""
10211 {
10212 if (TARGET_64BIT)
10213 ix86_expand_binary_operator (<CODE>, DImode, operands);
10214 else if (const_1_to_31_operand (operands[2], VOIDmode))
10215 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10216 (operands[0], operands[1], operands[2]));
10217 else
10218 FAIL;
10219
10220 DONE;
10221 })
10222
10223 (define_expand "<rotate_insn><mode>3"
10224 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10225 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10226 (match_operand:QI 2 "nonmemory_operand" "")))]
10227 ""
10228 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10229
10230 ;; Avoid useless masking of count operand.
10231 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10232 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10233 (any_rotate:SWI48
10234 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10235 (subreg:QI
10236 (and:SI
10237 (match_operand:SI 2 "nonimmediate_operand" "c")
10238 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10239 (clobber (reg:CC FLAGS_REG))]
10240 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10241 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10242 == GET_MODE_BITSIZE (<MODE>mode)-1"
10243 "#"
10244 "&& 1"
10245 [(parallel [(set (match_dup 0)
10246 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10247 (clobber (reg:CC FLAGS_REG))])]
10248 {
10249 if (can_create_pseudo_p ())
10250 operands [2] = force_reg (SImode, operands[2]);
10251
10252 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10253 }
10254 [(set_attr "type" "rotate")
10255 (set_attr "mode" "<MODE>")])
10256
10257 ;; Implement rotation using two double-precision
10258 ;; shift instructions and a scratch register.
10259
10260 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10261 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10262 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10263 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10264 (clobber (reg:CC FLAGS_REG))
10265 (clobber (match_scratch:DWIH 3 "=&r"))]
10266 ""
10267 "#"
10268 "reload_completed"
10269 [(set (match_dup 3) (match_dup 4))
10270 (parallel
10271 [(set (match_dup 4)
10272 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10273 (lshiftrt:DWIH (match_dup 5)
10274 (minus:QI (match_dup 6) (match_dup 2)))))
10275 (clobber (reg:CC FLAGS_REG))])
10276 (parallel
10277 [(set (match_dup 5)
10278 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10279 (lshiftrt:DWIH (match_dup 3)
10280 (minus:QI (match_dup 6) (match_dup 2)))))
10281 (clobber (reg:CC FLAGS_REG))])]
10282 {
10283 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10284
10285 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10286 })
10287
10288 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10289 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10290 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10291 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10292 (clobber (reg:CC FLAGS_REG))
10293 (clobber (match_scratch:DWIH 3 "=&r"))]
10294 ""
10295 "#"
10296 "reload_completed"
10297 [(set (match_dup 3) (match_dup 4))
10298 (parallel
10299 [(set (match_dup 4)
10300 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10301 (ashift:DWIH (match_dup 5)
10302 (minus:QI (match_dup 6) (match_dup 2)))))
10303 (clobber (reg:CC FLAGS_REG))])
10304 (parallel
10305 [(set (match_dup 5)
10306 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10307 (ashift:DWIH (match_dup 3)
10308 (minus:QI (match_dup 6) (match_dup 2)))))
10309 (clobber (reg:CC FLAGS_REG))])]
10310 {
10311 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10312
10313 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10314 })
10315
10316 (define_insn "*<rotate_insn><mode>3_1"
10317 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10318 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10319 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10320 (clobber (reg:CC FLAGS_REG))]
10321 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10322 {
10323 if (operands[2] == const1_rtx
10324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10325 return "<rotate>{<imodesuffix>}\t%0";
10326 else
10327 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10328 }
10329 [(set_attr "type" "rotate")
10330 (set (attr "length_immediate")
10331 (if_then_else
10332 (and (match_operand 2 "const1_operand" "")
10333 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10334 (const_int 0)))
10335 (const_string "0")
10336 (const_string "*")))
10337 (set_attr "mode" "<MODE>")])
10338
10339 (define_insn "*<rotate_insn>si3_1_zext"
10340 [(set (match_operand:DI 0 "register_operand" "=r")
10341 (zero_extend:DI
10342 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10343 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10346 {
10347 if (operands[2] == const1_rtx
10348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10349 return "<rotate>{l}\t%k0";
10350 else
10351 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10352 }
10353 [(set_attr "type" "rotate")
10354 (set (attr "length_immediate")
10355 (if_then_else
10356 (and (match_operand 2 "const1_operand" "")
10357 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10358 (const_int 0)))
10359 (const_string "0")
10360 (const_string "*")))
10361 (set_attr "mode" "SI")])
10362
10363 (define_insn "*<rotate_insn>qi3_1_slp"
10364 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10365 (any_rotate:QI (match_dup 0)
10366 (match_operand:QI 1 "nonmemory_operand" "cI")))
10367 (clobber (reg:CC FLAGS_REG))]
10368 "(optimize_function_for_size_p (cfun)
10369 || !TARGET_PARTIAL_REG_STALL
10370 || (operands[1] == const1_rtx
10371 && TARGET_SHIFT1))"
10372 {
10373 if (operands[1] == const1_rtx
10374 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10375 return "<rotate>{b}\t%0";
10376 else
10377 return "<rotate>{b}\t{%1, %0|%0, %1}";
10378 }
10379 [(set_attr "type" "rotate1")
10380 (set (attr "length_immediate")
10381 (if_then_else
10382 (and (match_operand 1 "const1_operand" "")
10383 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10384 (const_int 0)))
10385 (const_string "0")
10386 (const_string "*")))
10387 (set_attr "mode" "QI")])
10388
10389 (define_split
10390 [(set (match_operand:HI 0 "register_operand" "")
10391 (any_rotate:HI (match_dup 0) (const_int 8)))
10392 (clobber (reg:CC FLAGS_REG))]
10393 "reload_completed
10394 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10395 [(parallel [(set (strict_low_part (match_dup 0))
10396 (bswap:HI (match_dup 0)))
10397 (clobber (reg:CC FLAGS_REG))])])
10398 \f
10399 ;; Bit set / bit test instructions
10400
10401 (define_expand "extv"
10402 [(set (match_operand:SI 0 "register_operand" "")
10403 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10404 (match_operand:SI 2 "const8_operand" "")
10405 (match_operand:SI 3 "const8_operand" "")))]
10406 ""
10407 {
10408 /* Handle extractions from %ah et al. */
10409 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10410 FAIL;
10411
10412 /* From mips.md: extract_bit_field doesn't verify that our source
10413 matches the predicate, so check it again here. */
10414 if (! ext_register_operand (operands[1], VOIDmode))
10415 FAIL;
10416 })
10417
10418 (define_expand "extzv"
10419 [(set (match_operand:SI 0 "register_operand" "")
10420 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10421 (match_operand:SI 2 "const8_operand" "")
10422 (match_operand:SI 3 "const8_operand" "")))]
10423 ""
10424 {
10425 /* Handle extractions from %ah et al. */
10426 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10427 FAIL;
10428
10429 /* From mips.md: extract_bit_field doesn't verify that our source
10430 matches the predicate, so check it again here. */
10431 if (! ext_register_operand (operands[1], VOIDmode))
10432 FAIL;
10433 })
10434
10435 (define_expand "insv"
10436 [(set (zero_extract (match_operand 0 "register_operand" "")
10437 (match_operand 1 "const_int_operand" "")
10438 (match_operand 2 "const_int_operand" ""))
10439 (match_operand 3 "register_operand" ""))]
10440 ""
10441 {
10442 rtx (*gen_mov_insv_1) (rtx, rtx);
10443
10444 if (ix86_expand_pinsr (operands))
10445 DONE;
10446
10447 /* Handle insertions to %ah et al. */
10448 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10449 FAIL;
10450
10451 /* From mips.md: insert_bit_field doesn't verify that our source
10452 matches the predicate, so check it again here. */
10453 if (! ext_register_operand (operands[0], VOIDmode))
10454 FAIL;
10455
10456 gen_mov_insv_1 = (TARGET_64BIT
10457 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10458
10459 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10460 DONE;
10461 })
10462
10463 ;; %%% bts, btr, btc, bt.
10464 ;; In general these instructions are *slow* when applied to memory,
10465 ;; since they enforce atomic operation. When applied to registers,
10466 ;; it depends on the cpu implementation. They're never faster than
10467 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10468 ;; no point. But in 64-bit, we can't hold the relevant immediates
10469 ;; within the instruction itself, so operating on bits in the high
10470 ;; 32-bits of a register becomes easier.
10471 ;;
10472 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10473 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10474 ;; negdf respectively, so they can never be disabled entirely.
10475
10476 (define_insn "*btsq"
10477 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10478 (const_int 1)
10479 (match_operand:DI 1 "const_0_to_63_operand" ""))
10480 (const_int 1))
10481 (clobber (reg:CC FLAGS_REG))]
10482 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10483 "bts{q}\t{%1, %0|%0, %1}"
10484 [(set_attr "type" "alu1")
10485 (set_attr "prefix_0f" "1")
10486 (set_attr "mode" "DI")])
10487
10488 (define_insn "*btrq"
10489 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10490 (const_int 1)
10491 (match_operand:DI 1 "const_0_to_63_operand" ""))
10492 (const_int 0))
10493 (clobber (reg:CC FLAGS_REG))]
10494 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10495 "btr{q}\t{%1, %0|%0, %1}"
10496 [(set_attr "type" "alu1")
10497 (set_attr "prefix_0f" "1")
10498 (set_attr "mode" "DI")])
10499
10500 (define_insn "*btcq"
10501 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10502 (const_int 1)
10503 (match_operand:DI 1 "const_0_to_63_operand" ""))
10504 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10505 (clobber (reg:CC FLAGS_REG))]
10506 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10507 "btc{q}\t{%1, %0|%0, %1}"
10508 [(set_attr "type" "alu1")
10509 (set_attr "prefix_0f" "1")
10510 (set_attr "mode" "DI")])
10511
10512 ;; Allow Nocona to avoid these instructions if a register is available.
10513
10514 (define_peephole2
10515 [(match_scratch:DI 2 "r")
10516 (parallel [(set (zero_extract:DI
10517 (match_operand:DI 0 "register_operand" "")
10518 (const_int 1)
10519 (match_operand:DI 1 "const_0_to_63_operand" ""))
10520 (const_int 1))
10521 (clobber (reg:CC FLAGS_REG))])]
10522 "TARGET_64BIT && !TARGET_USE_BT"
10523 [(const_int 0)]
10524 {
10525 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10526 rtx op1;
10527
10528 if (HOST_BITS_PER_WIDE_INT >= 64)
10529 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10530 else if (i < HOST_BITS_PER_WIDE_INT)
10531 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10532 else
10533 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10534
10535 op1 = immed_double_const (lo, hi, DImode);
10536 if (i >= 31)
10537 {
10538 emit_move_insn (operands[2], op1);
10539 op1 = operands[2];
10540 }
10541
10542 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10543 DONE;
10544 })
10545
10546 (define_peephole2
10547 [(match_scratch:DI 2 "r")
10548 (parallel [(set (zero_extract:DI
10549 (match_operand:DI 0 "register_operand" "")
10550 (const_int 1)
10551 (match_operand:DI 1 "const_0_to_63_operand" ""))
10552 (const_int 0))
10553 (clobber (reg:CC FLAGS_REG))])]
10554 "TARGET_64BIT && !TARGET_USE_BT"
10555 [(const_int 0)]
10556 {
10557 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10558 rtx op1;
10559
10560 if (HOST_BITS_PER_WIDE_INT >= 64)
10561 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10562 else if (i < HOST_BITS_PER_WIDE_INT)
10563 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10564 else
10565 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10566
10567 op1 = immed_double_const (~lo, ~hi, DImode);
10568 if (i >= 32)
10569 {
10570 emit_move_insn (operands[2], op1);
10571 op1 = operands[2];
10572 }
10573
10574 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10575 DONE;
10576 })
10577
10578 (define_peephole2
10579 [(match_scratch:DI 2 "r")
10580 (parallel [(set (zero_extract:DI
10581 (match_operand:DI 0 "register_operand" "")
10582 (const_int 1)
10583 (match_operand:DI 1 "const_0_to_63_operand" ""))
10584 (not:DI (zero_extract:DI
10585 (match_dup 0) (const_int 1) (match_dup 1))))
10586 (clobber (reg:CC FLAGS_REG))])]
10587 "TARGET_64BIT && !TARGET_USE_BT"
10588 [(const_int 0)]
10589 {
10590 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10591 rtx op1;
10592
10593 if (HOST_BITS_PER_WIDE_INT >= 64)
10594 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10595 else if (i < HOST_BITS_PER_WIDE_INT)
10596 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10597 else
10598 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10599
10600 op1 = immed_double_const (lo, hi, DImode);
10601 if (i >= 31)
10602 {
10603 emit_move_insn (operands[2], op1);
10604 op1 = operands[2];
10605 }
10606
10607 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10608 DONE;
10609 })
10610
10611 (define_insn "*bt<mode>"
10612 [(set (reg:CCC FLAGS_REG)
10613 (compare:CCC
10614 (zero_extract:SWI48
10615 (match_operand:SWI48 0 "register_operand" "r")
10616 (const_int 1)
10617 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10618 (const_int 0)))]
10619 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10620 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10621 [(set_attr "type" "alu1")
10622 (set_attr "prefix_0f" "1")
10623 (set_attr "mode" "<MODE>")])
10624 \f
10625 ;; Store-flag instructions.
10626
10627 ;; For all sCOND expanders, also expand the compare or test insn that
10628 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10629
10630 (define_insn_and_split "*setcc_di_1"
10631 [(set (match_operand:DI 0 "register_operand" "=q")
10632 (match_operator:DI 1 "ix86_comparison_operator"
10633 [(reg FLAGS_REG) (const_int 0)]))]
10634 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10635 "#"
10636 "&& reload_completed"
10637 [(set (match_dup 2) (match_dup 1))
10638 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10639 {
10640 PUT_MODE (operands[1], QImode);
10641 operands[2] = gen_lowpart (QImode, operands[0]);
10642 })
10643
10644 (define_insn_and_split "*setcc_si_1_and"
10645 [(set (match_operand:SI 0 "register_operand" "=q")
10646 (match_operator:SI 1 "ix86_comparison_operator"
10647 [(reg FLAGS_REG) (const_int 0)]))
10648 (clobber (reg:CC FLAGS_REG))]
10649 "!TARGET_PARTIAL_REG_STALL
10650 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10651 "#"
10652 "&& reload_completed"
10653 [(set (match_dup 2) (match_dup 1))
10654 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10655 (clobber (reg:CC FLAGS_REG))])]
10656 {
10657 PUT_MODE (operands[1], QImode);
10658 operands[2] = gen_lowpart (QImode, operands[0]);
10659 })
10660
10661 (define_insn_and_split "*setcc_si_1_movzbl"
10662 [(set (match_operand:SI 0 "register_operand" "=q")
10663 (match_operator:SI 1 "ix86_comparison_operator"
10664 [(reg FLAGS_REG) (const_int 0)]))]
10665 "!TARGET_PARTIAL_REG_STALL
10666 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10667 "#"
10668 "&& reload_completed"
10669 [(set (match_dup 2) (match_dup 1))
10670 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10671 {
10672 PUT_MODE (operands[1], QImode);
10673 operands[2] = gen_lowpart (QImode, operands[0]);
10674 })
10675
10676 (define_insn "*setcc_qi"
10677 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10678 (match_operator:QI 1 "ix86_comparison_operator"
10679 [(reg FLAGS_REG) (const_int 0)]))]
10680 ""
10681 "set%C1\t%0"
10682 [(set_attr "type" "setcc")
10683 (set_attr "mode" "QI")])
10684
10685 (define_insn "*setcc_qi_slp"
10686 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10687 (match_operator:QI 1 "ix86_comparison_operator"
10688 [(reg FLAGS_REG) (const_int 0)]))]
10689 ""
10690 "set%C1\t%0"
10691 [(set_attr "type" "setcc")
10692 (set_attr "mode" "QI")])
10693
10694 ;; In general it is not safe to assume too much about CCmode registers,
10695 ;; so simplify-rtx stops when it sees a second one. Under certain
10696 ;; conditions this is safe on x86, so help combine not create
10697 ;;
10698 ;; seta %al
10699 ;; testb %al, %al
10700 ;; sete %al
10701
10702 (define_split
10703 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10704 (ne:QI (match_operator 1 "ix86_comparison_operator"
10705 [(reg FLAGS_REG) (const_int 0)])
10706 (const_int 0)))]
10707 ""
10708 [(set (match_dup 0) (match_dup 1))]
10709 "PUT_MODE (operands[1], QImode);")
10710
10711 (define_split
10712 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10713 (ne:QI (match_operator 1 "ix86_comparison_operator"
10714 [(reg FLAGS_REG) (const_int 0)])
10715 (const_int 0)))]
10716 ""
10717 [(set (match_dup 0) (match_dup 1))]
10718 "PUT_MODE (operands[1], QImode);")
10719
10720 (define_split
10721 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10722 (eq:QI (match_operator 1 "ix86_comparison_operator"
10723 [(reg FLAGS_REG) (const_int 0)])
10724 (const_int 0)))]
10725 ""
10726 [(set (match_dup 0) (match_dup 1))]
10727 {
10728 rtx new_op1 = copy_rtx (operands[1]);
10729 operands[1] = new_op1;
10730 PUT_MODE (new_op1, QImode);
10731 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10732 GET_MODE (XEXP (new_op1, 0))));
10733
10734 /* Make sure that (a) the CCmode we have for the flags is strong
10735 enough for the reversed compare or (b) we have a valid FP compare. */
10736 if (! ix86_comparison_operator (new_op1, VOIDmode))
10737 FAIL;
10738 })
10739
10740 (define_split
10741 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10742 (eq:QI (match_operator 1 "ix86_comparison_operator"
10743 [(reg FLAGS_REG) (const_int 0)])
10744 (const_int 0)))]
10745 ""
10746 [(set (match_dup 0) (match_dup 1))]
10747 {
10748 rtx new_op1 = copy_rtx (operands[1]);
10749 operands[1] = new_op1;
10750 PUT_MODE (new_op1, QImode);
10751 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10752 GET_MODE (XEXP (new_op1, 0))));
10753
10754 /* Make sure that (a) the CCmode we have for the flags is strong
10755 enough for the reversed compare or (b) we have a valid FP compare. */
10756 if (! ix86_comparison_operator (new_op1, VOIDmode))
10757 FAIL;
10758 })
10759
10760 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10761 ;; subsequent logical operations are used to imitate conditional moves.
10762 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10763 ;; it directly.
10764
10765 (define_insn "setcc_<mode>_sse"
10766 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10767 (match_operator:MODEF 3 "sse_comparison_operator"
10768 [(match_operand:MODEF 1 "register_operand" "0,x")
10769 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10770 "SSE_FLOAT_MODE_P (<MODE>mode)"
10771 "@
10772 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10773 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10774 [(set_attr "isa" "noavx,avx")
10775 (set_attr "type" "ssecmp")
10776 (set_attr "length_immediate" "1")
10777 (set_attr "prefix" "orig,vex")
10778 (set_attr "mode" "<MODE>")])
10779 \f
10780 ;; Basic conditional jump instructions.
10781 ;; We ignore the overflow flag for signed branch instructions.
10782
10783 (define_insn "*jcc_1"
10784 [(set (pc)
10785 (if_then_else (match_operator 1 "ix86_comparison_operator"
10786 [(reg FLAGS_REG) (const_int 0)])
10787 (label_ref (match_operand 0 "" ""))
10788 (pc)))]
10789 ""
10790 "%+j%C1\t%l0"
10791 [(set_attr "type" "ibr")
10792 (set_attr "modrm" "0")
10793 (set (attr "length")
10794 (if_then_else (and (ge (minus (match_dup 0) (pc))
10795 (const_int -126))
10796 (lt (minus (match_dup 0) (pc))
10797 (const_int 128)))
10798 (const_int 2)
10799 (const_int 6)))])
10800
10801 (define_insn "*jcc_2"
10802 [(set (pc)
10803 (if_then_else (match_operator 1 "ix86_comparison_operator"
10804 [(reg FLAGS_REG) (const_int 0)])
10805 (pc)
10806 (label_ref (match_operand 0 "" ""))))]
10807 ""
10808 "%+j%c1\t%l0"
10809 [(set_attr "type" "ibr")
10810 (set_attr "modrm" "0")
10811 (set (attr "length")
10812 (if_then_else (and (ge (minus (match_dup 0) (pc))
10813 (const_int -126))
10814 (lt (minus (match_dup 0) (pc))
10815 (const_int 128)))
10816 (const_int 2)
10817 (const_int 6)))])
10818
10819 ;; In general it is not safe to assume too much about CCmode registers,
10820 ;; so simplify-rtx stops when it sees a second one. Under certain
10821 ;; conditions this is safe on x86, so help combine not create
10822 ;;
10823 ;; seta %al
10824 ;; testb %al, %al
10825 ;; je Lfoo
10826
10827 (define_split
10828 [(set (pc)
10829 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10830 [(reg FLAGS_REG) (const_int 0)])
10831 (const_int 0))
10832 (label_ref (match_operand 1 "" ""))
10833 (pc)))]
10834 ""
10835 [(set (pc)
10836 (if_then_else (match_dup 0)
10837 (label_ref (match_dup 1))
10838 (pc)))]
10839 "PUT_MODE (operands[0], VOIDmode);")
10840
10841 (define_split
10842 [(set (pc)
10843 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10844 [(reg FLAGS_REG) (const_int 0)])
10845 (const_int 0))
10846 (label_ref (match_operand 1 "" ""))
10847 (pc)))]
10848 ""
10849 [(set (pc)
10850 (if_then_else (match_dup 0)
10851 (label_ref (match_dup 1))
10852 (pc)))]
10853 {
10854 rtx new_op0 = copy_rtx (operands[0]);
10855 operands[0] = new_op0;
10856 PUT_MODE (new_op0, VOIDmode);
10857 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10858 GET_MODE (XEXP (new_op0, 0))));
10859
10860 /* Make sure that (a) the CCmode we have for the flags is strong
10861 enough for the reversed compare or (b) we have a valid FP compare. */
10862 if (! ix86_comparison_operator (new_op0, VOIDmode))
10863 FAIL;
10864 })
10865
10866 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10867 ;; pass generates from shift insn with QImode operand. Actually, the mode
10868 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10869 ;; appropriate modulo of the bit offset value.
10870
10871 (define_insn_and_split "*jcc_bt<mode>"
10872 [(set (pc)
10873 (if_then_else (match_operator 0 "bt_comparison_operator"
10874 [(zero_extract:SWI48
10875 (match_operand:SWI48 1 "register_operand" "r")
10876 (const_int 1)
10877 (zero_extend:SI
10878 (match_operand:QI 2 "register_operand" "r")))
10879 (const_int 0)])
10880 (label_ref (match_operand 3 "" ""))
10881 (pc)))
10882 (clobber (reg:CC FLAGS_REG))]
10883 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10884 "#"
10885 "&& 1"
10886 [(set (reg:CCC FLAGS_REG)
10887 (compare:CCC
10888 (zero_extract:SWI48
10889 (match_dup 1)
10890 (const_int 1)
10891 (match_dup 2))
10892 (const_int 0)))
10893 (set (pc)
10894 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10895 (label_ref (match_dup 3))
10896 (pc)))]
10897 {
10898 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10899
10900 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10901 })
10902
10903 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10904 ;; also for DImode, this is what combine produces.
10905 (define_insn_and_split "*jcc_bt<mode>_mask"
10906 [(set (pc)
10907 (if_then_else (match_operator 0 "bt_comparison_operator"
10908 [(zero_extract:SWI48
10909 (match_operand:SWI48 1 "register_operand" "r")
10910 (const_int 1)
10911 (and:SI
10912 (match_operand:SI 2 "register_operand" "r")
10913 (match_operand:SI 3 "const_int_operand" "n")))])
10914 (label_ref (match_operand 4 "" ""))
10915 (pc)))
10916 (clobber (reg:CC FLAGS_REG))]
10917 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10918 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10919 == GET_MODE_BITSIZE (<MODE>mode)-1"
10920 "#"
10921 "&& 1"
10922 [(set (reg:CCC FLAGS_REG)
10923 (compare:CCC
10924 (zero_extract:SWI48
10925 (match_dup 1)
10926 (const_int 1)
10927 (match_dup 2))
10928 (const_int 0)))
10929 (set (pc)
10930 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10931 (label_ref (match_dup 4))
10932 (pc)))]
10933 {
10934 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10935
10936 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10937 })
10938
10939 (define_insn_and_split "*jcc_btsi_1"
10940 [(set (pc)
10941 (if_then_else (match_operator 0 "bt_comparison_operator"
10942 [(and:SI
10943 (lshiftrt:SI
10944 (match_operand:SI 1 "register_operand" "r")
10945 (match_operand:QI 2 "register_operand" "r"))
10946 (const_int 1))
10947 (const_int 0)])
10948 (label_ref (match_operand 3 "" ""))
10949 (pc)))
10950 (clobber (reg:CC FLAGS_REG))]
10951 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10952 "#"
10953 "&& 1"
10954 [(set (reg:CCC FLAGS_REG)
10955 (compare:CCC
10956 (zero_extract:SI
10957 (match_dup 1)
10958 (const_int 1)
10959 (match_dup 2))
10960 (const_int 0)))
10961 (set (pc)
10962 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10963 (label_ref (match_dup 3))
10964 (pc)))]
10965 {
10966 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10967
10968 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10969 })
10970
10971 ;; avoid useless masking of bit offset operand
10972 (define_insn_and_split "*jcc_btsi_mask_1"
10973 [(set (pc)
10974 (if_then_else
10975 (match_operator 0 "bt_comparison_operator"
10976 [(and:SI
10977 (lshiftrt:SI
10978 (match_operand:SI 1 "register_operand" "r")
10979 (subreg:QI
10980 (and:SI
10981 (match_operand:SI 2 "register_operand" "r")
10982 (match_operand:SI 3 "const_int_operand" "n")) 0))
10983 (const_int 1))
10984 (const_int 0)])
10985 (label_ref (match_operand 4 "" ""))
10986 (pc)))
10987 (clobber (reg:CC FLAGS_REG))]
10988 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10989 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10990 "#"
10991 "&& 1"
10992 [(set (reg:CCC FLAGS_REG)
10993 (compare:CCC
10994 (zero_extract:SI
10995 (match_dup 1)
10996 (const_int 1)
10997 (match_dup 2))
10998 (const_int 0)))
10999 (set (pc)
11000 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11001 (label_ref (match_dup 4))
11002 (pc)))]
11003 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11004
11005 ;; Define combination compare-and-branch fp compare instructions to help
11006 ;; combine.
11007
11008 (define_insn "*fp_jcc_1_387"
11009 [(set (pc)
11010 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11011 [(match_operand 1 "register_operand" "f")
11012 (match_operand 2 "nonimmediate_operand" "fm")])
11013 (label_ref (match_operand 3 "" ""))
11014 (pc)))
11015 (clobber (reg:CCFP FPSR_REG))
11016 (clobber (reg:CCFP FLAGS_REG))
11017 (clobber (match_scratch:HI 4 "=a"))]
11018 "TARGET_80387
11019 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11020 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11021 && SELECT_CC_MODE (GET_CODE (operands[0]),
11022 operands[1], operands[2]) == CCFPmode
11023 && !TARGET_CMOVE"
11024 "#")
11025
11026 (define_insn "*fp_jcc_1r_387"
11027 [(set (pc)
11028 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11029 [(match_operand 1 "register_operand" "f")
11030 (match_operand 2 "nonimmediate_operand" "fm")])
11031 (pc)
11032 (label_ref (match_operand 3 "" ""))))
11033 (clobber (reg:CCFP FPSR_REG))
11034 (clobber (reg:CCFP FLAGS_REG))
11035 (clobber (match_scratch:HI 4 "=a"))]
11036 "TARGET_80387
11037 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11038 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11039 && SELECT_CC_MODE (GET_CODE (operands[0]),
11040 operands[1], operands[2]) == CCFPmode
11041 && !TARGET_CMOVE"
11042 "#")
11043
11044 (define_insn "*fp_jcc_2_387"
11045 [(set (pc)
11046 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11047 [(match_operand 1 "register_operand" "f")
11048 (match_operand 2 "register_operand" "f")])
11049 (label_ref (match_operand 3 "" ""))
11050 (pc)))
11051 (clobber (reg:CCFP FPSR_REG))
11052 (clobber (reg:CCFP FLAGS_REG))
11053 (clobber (match_scratch:HI 4 "=a"))]
11054 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11055 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11056 && !TARGET_CMOVE"
11057 "#")
11058
11059 (define_insn "*fp_jcc_2r_387"
11060 [(set (pc)
11061 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11062 [(match_operand 1 "register_operand" "f")
11063 (match_operand 2 "register_operand" "f")])
11064 (pc)
11065 (label_ref (match_operand 3 "" ""))))
11066 (clobber (reg:CCFP FPSR_REG))
11067 (clobber (reg:CCFP FLAGS_REG))
11068 (clobber (match_scratch:HI 4 "=a"))]
11069 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11070 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11071 && !TARGET_CMOVE"
11072 "#")
11073
11074 (define_insn "*fp_jcc_3_387"
11075 [(set (pc)
11076 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11077 [(match_operand 1 "register_operand" "f")
11078 (match_operand 2 "const0_operand" "")])
11079 (label_ref (match_operand 3 "" ""))
11080 (pc)))
11081 (clobber (reg:CCFP FPSR_REG))
11082 (clobber (reg:CCFP FLAGS_REG))
11083 (clobber (match_scratch:HI 4 "=a"))]
11084 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11085 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11086 && SELECT_CC_MODE (GET_CODE (operands[0]),
11087 operands[1], operands[2]) == CCFPmode
11088 && !TARGET_CMOVE"
11089 "#")
11090
11091 (define_split
11092 [(set (pc)
11093 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11094 [(match_operand 1 "register_operand" "")
11095 (match_operand 2 "nonimmediate_operand" "")])
11096 (match_operand 3 "" "")
11097 (match_operand 4 "" "")))
11098 (clobber (reg:CCFP FPSR_REG))
11099 (clobber (reg:CCFP FLAGS_REG))]
11100 "reload_completed"
11101 [(const_int 0)]
11102 {
11103 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11104 operands[3], operands[4], NULL_RTX, NULL_RTX);
11105 DONE;
11106 })
11107
11108 (define_split
11109 [(set (pc)
11110 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11111 [(match_operand 1 "register_operand" "")
11112 (match_operand 2 "general_operand" "")])
11113 (match_operand 3 "" "")
11114 (match_operand 4 "" "")))
11115 (clobber (reg:CCFP FPSR_REG))
11116 (clobber (reg:CCFP FLAGS_REG))
11117 (clobber (match_scratch:HI 5 "=a"))]
11118 "reload_completed"
11119 [(const_int 0)]
11120 {
11121 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11122 operands[3], operands[4], operands[5], NULL_RTX);
11123 DONE;
11124 })
11125
11126 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11127 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11128 ;; with a precedence over other operators and is always put in the first
11129 ;; place. Swap condition and operands to match ficom instruction.
11130
11131 (define_insn "*fp_jcc_4_<mode>_387"
11132 [(set (pc)
11133 (if_then_else
11134 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11135 [(match_operator 1 "float_operator"
11136 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11137 (match_operand 3 "register_operand" "f,f")])
11138 (label_ref (match_operand 4 "" ""))
11139 (pc)))
11140 (clobber (reg:CCFP FPSR_REG))
11141 (clobber (reg:CCFP FLAGS_REG))
11142 (clobber (match_scratch:HI 5 "=a,a"))]
11143 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11144 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11145 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11146 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11147 && !TARGET_CMOVE"
11148 "#")
11149
11150 (define_split
11151 [(set (pc)
11152 (if_then_else
11153 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11154 [(match_operator 1 "float_operator"
11155 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11156 (match_operand 3 "register_operand" "")])
11157 (match_operand 4 "" "")
11158 (match_operand 5 "" "")))
11159 (clobber (reg:CCFP FPSR_REG))
11160 (clobber (reg:CCFP FLAGS_REG))
11161 (clobber (match_scratch:HI 6 "=a"))]
11162 "reload_completed"
11163 [(const_int 0)]
11164 {
11165 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11166
11167 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11168 operands[3], operands[7],
11169 operands[4], operands[5], operands[6], NULL_RTX);
11170 DONE;
11171 })
11172
11173 ;; %%% Kill this when reload knows how to do it.
11174 (define_split
11175 [(set (pc)
11176 (if_then_else
11177 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11178 [(match_operator 1 "float_operator"
11179 [(match_operand:X87MODEI12 2 "register_operand" "")])
11180 (match_operand 3 "register_operand" "")])
11181 (match_operand 4 "" "")
11182 (match_operand 5 "" "")))
11183 (clobber (reg:CCFP FPSR_REG))
11184 (clobber (reg:CCFP FLAGS_REG))
11185 (clobber (match_scratch:HI 6 "=a"))]
11186 "reload_completed"
11187 [(const_int 0)]
11188 {
11189 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11190 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11191
11192 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11193 operands[3], operands[7],
11194 operands[4], operands[5], operands[6], operands[2]);
11195 DONE;
11196 })
11197 \f
11198 ;; Unconditional and other jump instructions
11199
11200 (define_insn "jump"
11201 [(set (pc)
11202 (label_ref (match_operand 0 "" "")))]
11203 ""
11204 "jmp\t%l0"
11205 [(set_attr "type" "ibr")
11206 (set (attr "length")
11207 (if_then_else (and (ge (minus (match_dup 0) (pc))
11208 (const_int -126))
11209 (lt (minus (match_dup 0) (pc))
11210 (const_int 128)))
11211 (const_int 2)
11212 (const_int 5)))
11213 (set_attr "modrm" "0")])
11214
11215 (define_expand "indirect_jump"
11216 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11217 ""
11218 "")
11219
11220 (define_insn "*indirect_jump"
11221 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11222 ""
11223 "jmp\t%A0"
11224 [(set_attr "type" "ibr")
11225 (set_attr "length_immediate" "0")])
11226
11227 (define_expand "tablejump"
11228 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11229 (use (label_ref (match_operand 1 "" "")))])]
11230 ""
11231 {
11232 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11233 relative. Convert the relative address to an absolute address. */
11234 if (flag_pic)
11235 {
11236 rtx op0, op1;
11237 enum rtx_code code;
11238
11239 /* We can't use @GOTOFF for text labels on VxWorks;
11240 see gotoff_operand. */
11241 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11242 {
11243 code = PLUS;
11244 op0 = operands[0];
11245 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11246 }
11247 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11248 {
11249 code = PLUS;
11250 op0 = operands[0];
11251 op1 = pic_offset_table_rtx;
11252 }
11253 else
11254 {
11255 code = MINUS;
11256 op0 = pic_offset_table_rtx;
11257 op1 = operands[0];
11258 }
11259
11260 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11261 OPTAB_DIRECT);
11262 }
11263 })
11264
11265 (define_insn "*tablejump_1"
11266 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11267 (use (label_ref (match_operand 1 "" "")))]
11268 ""
11269 "jmp\t%A0"
11270 [(set_attr "type" "ibr")
11271 (set_attr "length_immediate" "0")])
11272 \f
11273 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11274
11275 (define_peephole2
11276 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11277 (set (match_operand:QI 1 "register_operand" "")
11278 (match_operator:QI 2 "ix86_comparison_operator"
11279 [(reg FLAGS_REG) (const_int 0)]))
11280 (set (match_operand 3 "q_regs_operand" "")
11281 (zero_extend (match_dup 1)))]
11282 "(peep2_reg_dead_p (3, operands[1])
11283 || operands_match_p (operands[1], operands[3]))
11284 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11285 [(set (match_dup 4) (match_dup 0))
11286 (set (strict_low_part (match_dup 5))
11287 (match_dup 2))]
11288 {
11289 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11290 operands[5] = gen_lowpart (QImode, operands[3]);
11291 ix86_expand_clear (operands[3]);
11292 })
11293
11294 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11295
11296 (define_peephole2
11297 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11298 (set (match_operand:QI 1 "register_operand" "")
11299 (match_operator:QI 2 "ix86_comparison_operator"
11300 [(reg FLAGS_REG) (const_int 0)]))
11301 (parallel [(set (match_operand 3 "q_regs_operand" "")
11302 (zero_extend (match_dup 1)))
11303 (clobber (reg:CC FLAGS_REG))])]
11304 "(peep2_reg_dead_p (3, operands[1])
11305 || operands_match_p (operands[1], operands[3]))
11306 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11307 [(set (match_dup 4) (match_dup 0))
11308 (set (strict_low_part (match_dup 5))
11309 (match_dup 2))]
11310 {
11311 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11312 operands[5] = gen_lowpart (QImode, operands[3]);
11313 ix86_expand_clear (operands[3]);
11314 })
11315 \f
11316 ;; Call instructions.
11317
11318 ;; The predicates normally associated with named expanders are not properly
11319 ;; checked for calls. This is a bug in the generic code, but it isn't that
11320 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11321
11322 ;; P6 processors will jump to the address after the decrement when %esp
11323 ;; is used as a call operand, so they will execute return address as a code.
11324 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11325
11326 ;; Call subroutine returning no value.
11327
11328 (define_expand "call_pop"
11329 [(parallel [(call (match_operand:QI 0 "" "")
11330 (match_operand:SI 1 "" ""))
11331 (set (reg:SI SP_REG)
11332 (plus:SI (reg:SI SP_REG)
11333 (match_operand:SI 3 "" "")))])]
11334 "!TARGET_64BIT"
11335 {
11336 ix86_expand_call (NULL, operands[0], operands[1],
11337 operands[2], operands[3], 0);
11338 DONE;
11339 })
11340
11341 (define_insn_and_split "*call_pop_0_vzeroupper"
11342 [(parallel
11343 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11344 (match_operand:SI 1 "" ""))
11345 (set (reg:SI SP_REG)
11346 (plus:SI (reg:SI SP_REG)
11347 (match_operand:SI 2 "immediate_operand" "")))])
11348 (unspec [(match_operand 3 "const_int_operand" "")]
11349 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11350 "TARGET_VZEROUPPER && !TARGET_64BIT"
11351 "#"
11352 "&& reload_completed"
11353 [(const_int 0)]
11354 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11355 [(set_attr "type" "call")])
11356
11357 (define_insn "*call_pop_0"
11358 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11359 (match_operand:SI 1 "" ""))
11360 (set (reg:SI SP_REG)
11361 (plus:SI (reg:SI SP_REG)
11362 (match_operand:SI 2 "immediate_operand" "")))]
11363 "!TARGET_64BIT"
11364 {
11365 if (SIBLING_CALL_P (insn))
11366 return "jmp\t%P0";
11367 else
11368 return "call\t%P0";
11369 }
11370 [(set_attr "type" "call")])
11371
11372 (define_insn_and_split "*call_pop_1_vzeroupper"
11373 [(parallel
11374 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11375 (match_operand:SI 1 "" ""))
11376 (set (reg:SI SP_REG)
11377 (plus:SI (reg:SI SP_REG)
11378 (match_operand:SI 2 "immediate_operand" "i")))])
11379 (unspec [(match_operand 3 "const_int_operand" "")]
11380 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11381 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11382 "#"
11383 "&& reload_completed"
11384 [(const_int 0)]
11385 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11386 [(set_attr "type" "call")])
11387
11388 (define_insn "*call_pop_1"
11389 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11390 (match_operand:SI 1 "" ""))
11391 (set (reg:SI SP_REG)
11392 (plus:SI (reg:SI SP_REG)
11393 (match_operand:SI 2 "immediate_operand" "i")))]
11394 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11395 {
11396 if (constant_call_address_operand (operands[0], Pmode))
11397 return "call\t%P0";
11398 return "call\t%A0";
11399 }
11400 [(set_attr "type" "call")])
11401
11402 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11403 [(parallel
11404 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11405 (match_operand:SI 1 "" ""))
11406 (set (reg:SI SP_REG)
11407 (plus:SI (reg:SI SP_REG)
11408 (match_operand:SI 2 "immediate_operand" "i,i")))])
11409 (unspec [(match_operand 3 "const_int_operand" "")]
11410 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11411 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11412 "#"
11413 "&& reload_completed"
11414 [(const_int 0)]
11415 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11416 [(set_attr "type" "call")])
11417
11418 (define_insn "*sibcall_pop_1"
11419 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11420 (match_operand:SI 1 "" ""))
11421 (set (reg:SI SP_REG)
11422 (plus:SI (reg:SI SP_REG)
11423 (match_operand:SI 2 "immediate_operand" "i,i")))]
11424 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11425 "@
11426 jmp\t%P0
11427 jmp\t%A0"
11428 [(set_attr "type" "call")])
11429
11430 (define_expand "call"
11431 [(call (match_operand:QI 0 "" "")
11432 (match_operand 1 "" ""))
11433 (use (match_operand 2 "" ""))]
11434 ""
11435 {
11436 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11437 DONE;
11438 })
11439
11440 (define_expand "sibcall"
11441 [(call (match_operand:QI 0 "" "")
11442 (match_operand 1 "" ""))
11443 (use (match_operand 2 "" ""))]
11444 ""
11445 {
11446 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11447 DONE;
11448 })
11449
11450 (define_insn_and_split "*call_0_vzeroupper"
11451 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11452 (match_operand 1 "" ""))
11453 (unspec [(match_operand 2 "const_int_operand" "")]
11454 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11455 "TARGET_VZEROUPPER"
11456 "#"
11457 "&& reload_completed"
11458 [(const_int 0)]
11459 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11460 [(set_attr "type" "call")])
11461
11462 (define_insn "*call_0"
11463 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11464 (match_operand 1 "" ""))]
11465 ""
11466 { return ix86_output_call_insn (insn, operands[0], 0); }
11467 [(set_attr "type" "call")])
11468
11469 (define_insn_and_split "*call_1_vzeroupper"
11470 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11471 (match_operand 1 "" ""))
11472 (unspec [(match_operand 2 "const_int_operand" "")]
11473 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11474 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11475 "#"
11476 "&& reload_completed"
11477 [(const_int 0)]
11478 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11479 [(set_attr "type" "call")])
11480
11481 (define_insn "*call_1"
11482 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11483 (match_operand 1 "" ""))]
11484 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11485 { return ix86_output_call_insn (insn, operands[0], 0); }
11486 [(set_attr "type" "call")])
11487
11488 (define_insn_and_split "*sibcall_1_vzeroupper"
11489 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11490 (match_operand 1 "" ""))
11491 (unspec [(match_operand 2 "const_int_operand" "")]
11492 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11493 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11494 "#"
11495 "&& reload_completed"
11496 [(const_int 0)]
11497 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11498 [(set_attr "type" "call")])
11499
11500 (define_insn "*sibcall_1"
11501 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11502 (match_operand 1 "" ""))]
11503 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11504 { return ix86_output_call_insn (insn, operands[0], 0); }
11505 [(set_attr "type" "call")])
11506
11507 (define_insn_and_split "*call_1_rex64_vzeroupper"
11508 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11509 (match_operand 1 "" ""))
11510 (unspec [(match_operand 2 "const_int_operand" "")]
11511 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11512 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11513 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11514 "#"
11515 "&& reload_completed"
11516 [(const_int 0)]
11517 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11518 [(set_attr "type" "call")])
11519
11520 (define_insn "*call_1_rex64"
11521 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11522 (match_operand 1 "" ""))]
11523 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11524 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11525 { return ix86_output_call_insn (insn, operands[0], 0); }
11526 [(set_attr "type" "call")])
11527
11528 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11529 [(parallel
11530 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11531 (match_operand 1 "" ""))
11532 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11533 (clobber (reg:TI XMM6_REG))
11534 (clobber (reg:TI XMM7_REG))
11535 (clobber (reg:TI XMM8_REG))
11536 (clobber (reg:TI XMM9_REG))
11537 (clobber (reg:TI XMM10_REG))
11538 (clobber (reg:TI XMM11_REG))
11539 (clobber (reg:TI XMM12_REG))
11540 (clobber (reg:TI XMM13_REG))
11541 (clobber (reg:TI XMM14_REG))
11542 (clobber (reg:TI XMM15_REG))
11543 (clobber (reg:DI SI_REG))
11544 (clobber (reg:DI DI_REG))])
11545 (unspec [(match_operand 2 "const_int_operand" "")]
11546 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11547 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11548 "#"
11549 "&& reload_completed"
11550 [(const_int 0)]
11551 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11552 [(set_attr "type" "call")])
11553
11554 (define_insn "*call_1_rex64_ms_sysv"
11555 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11556 (match_operand 1 "" ""))
11557 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11558 (clobber (reg:TI XMM6_REG))
11559 (clobber (reg:TI XMM7_REG))
11560 (clobber (reg:TI XMM8_REG))
11561 (clobber (reg:TI XMM9_REG))
11562 (clobber (reg:TI XMM10_REG))
11563 (clobber (reg:TI XMM11_REG))
11564 (clobber (reg:TI XMM12_REG))
11565 (clobber (reg:TI XMM13_REG))
11566 (clobber (reg:TI XMM14_REG))
11567 (clobber (reg:TI XMM15_REG))
11568 (clobber (reg:DI SI_REG))
11569 (clobber (reg:DI DI_REG))]
11570 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11571 { return ix86_output_call_insn (insn, operands[0], 0); }
11572 [(set_attr "type" "call")])
11573
11574 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11575 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11576 (match_operand 1 "" ""))
11577 (unspec [(match_operand 2 "const_int_operand" "")]
11578 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11579 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11580 "#"
11581 "&& reload_completed"
11582 [(const_int 0)]
11583 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11584 [(set_attr "type" "call")])
11585
11586 (define_insn "*call_1_rex64_large"
11587 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11588 (match_operand 1 "" ""))]
11589 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11590 { return ix86_output_call_insn (insn, operands[0], 0); }
11591 [(set_attr "type" "call")])
11592
11593 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11594 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11595 (match_operand 1 "" ""))
11596 (unspec [(match_operand 2 "const_int_operand" "")]
11597 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11598 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11599 "#"
11600 "&& reload_completed"
11601 [(const_int 0)]
11602 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11603 [(set_attr "type" "call")])
11604
11605 (define_insn "*sibcall_1_rex64"
11606 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11607 (match_operand 1 "" ""))]
11608 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11609 { return ix86_output_call_insn (insn, operands[0], 0); }
11610 [(set_attr "type" "call")])
11611
11612 ;; Call subroutine, returning value in operand 0
11613 (define_expand "call_value_pop"
11614 [(parallel [(set (match_operand 0 "" "")
11615 (call (match_operand:QI 1 "" "")
11616 (match_operand:SI 2 "" "")))
11617 (set (reg:SI SP_REG)
11618 (plus:SI (reg:SI SP_REG)
11619 (match_operand:SI 4 "" "")))])]
11620 "!TARGET_64BIT"
11621 {
11622 ix86_expand_call (operands[0], operands[1], operands[2],
11623 operands[3], operands[4], 0);
11624 DONE;
11625 })
11626
11627 (define_expand "call_value"
11628 [(set (match_operand 0 "" "")
11629 (call (match_operand:QI 1 "" "")
11630 (match_operand:SI 2 "" "")))
11631 (use (match_operand:SI 3 "" ""))]
11632 ;; Operand 3 is not used on the i386.
11633 ""
11634 {
11635 ix86_expand_call (operands[0], operands[1], operands[2],
11636 operands[3], NULL, 0);
11637 DONE;
11638 })
11639
11640 (define_expand "sibcall_value"
11641 [(set (match_operand 0 "" "")
11642 (call (match_operand:QI 1 "" "")
11643 (match_operand:SI 2 "" "")))
11644 (use (match_operand:SI 3 "" ""))]
11645 ;; Operand 3 is not used on the i386.
11646 ""
11647 {
11648 ix86_expand_call (operands[0], operands[1], operands[2],
11649 operands[3], NULL, 1);
11650 DONE;
11651 })
11652
11653 ;; Call subroutine returning any type.
11654
11655 (define_expand "untyped_call"
11656 [(parallel [(call (match_operand 0 "" "")
11657 (const_int 0))
11658 (match_operand 1 "" "")
11659 (match_operand 2 "" "")])]
11660 ""
11661 {
11662 int i;
11663
11664 /* In order to give reg-stack an easier job in validating two
11665 coprocessor registers as containing a possible return value,
11666 simply pretend the untyped call returns a complex long double
11667 value.
11668
11669 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11670 and should have the default ABI. */
11671
11672 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11673 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11674 operands[0], const0_rtx,
11675 GEN_INT ((TARGET_64BIT
11676 ? (ix86_abi == SYSV_ABI
11677 ? X86_64_SSE_REGPARM_MAX
11678 : X86_64_MS_SSE_REGPARM_MAX)
11679 : X86_32_SSE_REGPARM_MAX)
11680 - 1),
11681 NULL, 0);
11682
11683 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11684 {
11685 rtx set = XVECEXP (operands[2], 0, i);
11686 emit_move_insn (SET_DEST (set), SET_SRC (set));
11687 }
11688
11689 /* The optimizer does not know that the call sets the function value
11690 registers we stored in the result block. We avoid problems by
11691 claiming that all hard registers are used and clobbered at this
11692 point. */
11693 emit_insn (gen_blockage ());
11694
11695 DONE;
11696 })
11697 \f
11698 ;; Prologue and epilogue instructions
11699
11700 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11701 ;; all of memory. This blocks insns from being moved across this point.
11702
11703 (define_insn "blockage"
11704 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11705 ""
11706 ""
11707 [(set_attr "length" "0")])
11708
11709 ;; Do not schedule instructions accessing memory across this point.
11710
11711 (define_expand "memory_blockage"
11712 [(set (match_dup 0)
11713 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11714 ""
11715 {
11716 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11717 MEM_VOLATILE_P (operands[0]) = 1;
11718 })
11719
11720 (define_insn "*memory_blockage"
11721 [(set (match_operand:BLK 0 "" "")
11722 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11723 ""
11724 ""
11725 [(set_attr "length" "0")])
11726
11727 ;; As USE insns aren't meaningful after reload, this is used instead
11728 ;; to prevent deleting instructions setting registers for PIC code
11729 (define_insn "prologue_use"
11730 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11731 ""
11732 ""
11733 [(set_attr "length" "0")])
11734
11735 ;; Insn emitted into the body of a function to return from a function.
11736 ;; This is only done if the function's epilogue is known to be simple.
11737 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11738
11739 (define_expand "return"
11740 [(return)]
11741 "ix86_can_use_return_insn_p ()"
11742 {
11743 if (crtl->args.pops_args)
11744 {
11745 rtx popc = GEN_INT (crtl->args.pops_args);
11746 emit_jump_insn (gen_return_pop_internal (popc));
11747 DONE;
11748 }
11749 })
11750
11751 (define_insn "return_internal"
11752 [(return)]
11753 "reload_completed"
11754 "ret"
11755 [(set_attr "length" "1")
11756 (set_attr "atom_unit" "jeu")
11757 (set_attr "length_immediate" "0")
11758 (set_attr "modrm" "0")])
11759
11760 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11761 ;; instruction Athlon and K8 have.
11762
11763 (define_insn "return_internal_long"
11764 [(return)
11765 (unspec [(const_int 0)] UNSPEC_REP)]
11766 "reload_completed"
11767 "rep\;ret"
11768 [(set_attr "length" "2")
11769 (set_attr "atom_unit" "jeu")
11770 (set_attr "length_immediate" "0")
11771 (set_attr "prefix_rep" "1")
11772 (set_attr "modrm" "0")])
11773
11774 (define_insn "return_pop_internal"
11775 [(return)
11776 (use (match_operand:SI 0 "const_int_operand" ""))]
11777 "reload_completed"
11778 "ret\t%0"
11779 [(set_attr "length" "3")
11780 (set_attr "atom_unit" "jeu")
11781 (set_attr "length_immediate" "2")
11782 (set_attr "modrm" "0")])
11783
11784 (define_insn "return_indirect_internal"
11785 [(return)
11786 (use (match_operand:SI 0 "register_operand" "r"))]
11787 "reload_completed"
11788 "jmp\t%A0"
11789 [(set_attr "type" "ibr")
11790 (set_attr "length_immediate" "0")])
11791
11792 (define_insn "nop"
11793 [(const_int 0)]
11794 ""
11795 "nop"
11796 [(set_attr "length" "1")
11797 (set_attr "length_immediate" "0")
11798 (set_attr "modrm" "0")])
11799
11800 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11801 (define_insn "nops"
11802 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11803 UNSPECV_NOPS)]
11804 "reload_completed"
11805 {
11806 int num = INTVAL (operands[0]);
11807
11808 gcc_assert (num >= 1 && num <= 8);
11809
11810 while (num--)
11811 fputs ("\tnop\n", asm_out_file);
11812
11813 return "";
11814 }
11815 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11816 (set_attr "length_immediate" "0")
11817 (set_attr "modrm" "0")])
11818
11819 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11820 ;; branch prediction penalty for the third jump in a 16-byte
11821 ;; block on K8.
11822
11823 (define_insn "pad"
11824 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11825 ""
11826 {
11827 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11828 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11829 #else
11830 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11831 The align insn is used to avoid 3 jump instructions in the row to improve
11832 branch prediction and the benefits hardly outweigh the cost of extra 8
11833 nops on the average inserted by full alignment pseudo operation. */
11834 #endif
11835 return "";
11836 }
11837 [(set_attr "length" "16")])
11838
11839 (define_expand "prologue"
11840 [(const_int 0)]
11841 ""
11842 "ix86_expand_prologue (); DONE;")
11843
11844 (define_insn "set_got"
11845 [(set (match_operand:SI 0 "register_operand" "=r")
11846 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "!TARGET_64BIT"
11849 "* return output_set_got (operands[0], NULL_RTX);"
11850 [(set_attr "type" "multi")
11851 (set_attr "length" "12")])
11852
11853 (define_insn "set_got_labelled"
11854 [(set (match_operand:SI 0 "register_operand" "=r")
11855 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11856 UNSPEC_SET_GOT))
11857 (clobber (reg:CC FLAGS_REG))]
11858 "!TARGET_64BIT"
11859 "* return output_set_got (operands[0], operands[1]);"
11860 [(set_attr "type" "multi")
11861 (set_attr "length" "12")])
11862
11863 (define_insn "set_got_rex64"
11864 [(set (match_operand:DI 0 "register_operand" "=r")
11865 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11866 "TARGET_64BIT"
11867 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11868 [(set_attr "type" "lea")
11869 (set_attr "length_address" "4")
11870 (set_attr "mode" "DI")])
11871
11872 (define_insn "set_rip_rex64"
11873 [(set (match_operand:DI 0 "register_operand" "=r")
11874 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11875 "TARGET_64BIT"
11876 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11877 [(set_attr "type" "lea")
11878 (set_attr "length_address" "4")
11879 (set_attr "mode" "DI")])
11880
11881 (define_insn "set_got_offset_rex64"
11882 [(set (match_operand:DI 0 "register_operand" "=r")
11883 (unspec:DI
11884 [(label_ref (match_operand 1 "" ""))]
11885 UNSPEC_SET_GOT_OFFSET))]
11886 "TARGET_64BIT"
11887 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11888 [(set_attr "type" "imov")
11889 (set_attr "length_immediate" "0")
11890 (set_attr "length_address" "8")
11891 (set_attr "mode" "DI")])
11892
11893 (define_expand "epilogue"
11894 [(const_int 0)]
11895 ""
11896 "ix86_expand_epilogue (1); DONE;")
11897
11898 (define_expand "sibcall_epilogue"
11899 [(const_int 0)]
11900 ""
11901 "ix86_expand_epilogue (0); DONE;")
11902
11903 (define_expand "eh_return"
11904 [(use (match_operand 0 "register_operand" ""))]
11905 ""
11906 {
11907 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11908
11909 /* Tricky bit: we write the address of the handler to which we will
11910 be returning into someone else's stack frame, one word below the
11911 stack address we wish to restore. */
11912 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11913 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11914 tmp = gen_rtx_MEM (Pmode, tmp);
11915 emit_move_insn (tmp, ra);
11916
11917 emit_jump_insn (gen_eh_return_internal ());
11918 emit_barrier ();
11919 DONE;
11920 })
11921
11922 (define_insn_and_split "eh_return_internal"
11923 [(eh_return)]
11924 ""
11925 "#"
11926 "epilogue_completed"
11927 [(const_int 0)]
11928 "ix86_expand_epilogue (2); DONE;")
11929
11930 (define_insn "leave"
11931 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11932 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11933 (clobber (mem:BLK (scratch)))]
11934 "!TARGET_64BIT"
11935 "leave"
11936 [(set_attr "type" "leave")])
11937
11938 (define_insn "leave_rex64"
11939 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11940 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11941 (clobber (mem:BLK (scratch)))]
11942 "TARGET_64BIT"
11943 "leave"
11944 [(set_attr "type" "leave")])
11945 \f
11946 ;; Handle -fsplit-stack.
11947
11948 (define_expand "split_stack_prologue"
11949 [(const_int 0)]
11950 ""
11951 {
11952 ix86_expand_split_stack_prologue ();
11953 DONE;
11954 })
11955
11956 ;; In order to support the call/return predictor, we use a return
11957 ;; instruction which the middle-end doesn't see.
11958 (define_insn "split_stack_return"
11959 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11960 UNSPECV_SPLIT_STACK_RETURN)]
11961 ""
11962 {
11963 if (operands[0] == const0_rtx)
11964 return "ret";
11965 else
11966 return "ret\t%0";
11967 }
11968 [(set_attr "atom_unit" "jeu")
11969 (set_attr "modrm" "0")
11970 (set (attr "length")
11971 (if_then_else (match_operand:SI 0 "const0_operand" "")
11972 (const_int 1)
11973 (const_int 3)))
11974 (set (attr "length_immediate")
11975 (if_then_else (match_operand:SI 0 "const0_operand" "")
11976 (const_int 0)
11977 (const_int 2)))])
11978
11979 ;; If there are operand 0 bytes available on the stack, jump to
11980 ;; operand 1.
11981
11982 (define_expand "split_stack_space_check"
11983 [(set (pc) (if_then_else
11984 (ltu (minus (reg SP_REG)
11985 (match_operand 0 "register_operand" ""))
11986 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11987 (label_ref (match_operand 1 "" ""))
11988 (pc)))]
11989 ""
11990 {
11991 rtx reg, size, limit;
11992
11993 reg = gen_reg_rtx (Pmode);
11994 size = force_reg (Pmode, operands[0]);
11995 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11996 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11997 UNSPEC_STACK_CHECK);
11998 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11999 ix86_expand_branch (GEU, reg, limit, operands[1]);
12000
12001 DONE;
12002 })
12003 \f
12004 ;; Bit manipulation instructions.
12005
12006 (define_expand "ffs<mode>2"
12007 [(set (match_dup 2) (const_int -1))
12008 (parallel [(set (reg:CCZ FLAGS_REG)
12009 (compare:CCZ
12010 (match_operand:SWI48 1 "nonimmediate_operand" "")
12011 (const_int 0)))
12012 (set (match_operand:SWI48 0 "register_operand" "")
12013 (ctz:SWI48 (match_dup 1)))])
12014 (set (match_dup 0) (if_then_else:SWI48
12015 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12016 (match_dup 2)
12017 (match_dup 0)))
12018 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12019 (clobber (reg:CC FLAGS_REG))])]
12020 ""
12021 {
12022 if (<MODE>mode == SImode && !TARGET_CMOVE)
12023 {
12024 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12025 DONE;
12026 }
12027 operands[2] = gen_reg_rtx (<MODE>mode);
12028 })
12029
12030 (define_insn_and_split "ffssi2_no_cmove"
12031 [(set (match_operand:SI 0 "register_operand" "=r")
12032 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12033 (clobber (match_scratch:SI 2 "=&q"))
12034 (clobber (reg:CC FLAGS_REG))]
12035 "!TARGET_CMOVE"
12036 "#"
12037 "&& reload_completed"
12038 [(parallel [(set (reg:CCZ FLAGS_REG)
12039 (compare:CCZ (match_dup 1) (const_int 0)))
12040 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12041 (set (strict_low_part (match_dup 3))
12042 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12043 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12044 (clobber (reg:CC FLAGS_REG))])
12045 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12046 (clobber (reg:CC FLAGS_REG))])
12047 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12048 (clobber (reg:CC FLAGS_REG))])]
12049 {
12050 operands[3] = gen_lowpart (QImode, operands[2]);
12051 ix86_expand_clear (operands[2]);
12052 })
12053
12054 (define_insn "*ffs<mode>_1"
12055 [(set (reg:CCZ FLAGS_REG)
12056 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12057 (const_int 0)))
12058 (set (match_operand:SWI48 0 "register_operand" "=r")
12059 (ctz:SWI48 (match_dup 1)))]
12060 ""
12061 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12062 [(set_attr "type" "alu1")
12063 (set_attr "prefix_0f" "1")
12064 (set_attr "mode" "<MODE>")])
12065
12066 (define_insn "ctz<mode>2"
12067 [(set (match_operand:SWI248 0 "register_operand" "=r")
12068 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12069 (clobber (reg:CC FLAGS_REG))]
12070 ""
12071 {
12072 if (TARGET_BMI)
12073 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12074 else
12075 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12076 }
12077 [(set_attr "type" "alu1")
12078 (set_attr "prefix_0f" "1")
12079 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12080 (set_attr "mode" "<MODE>")])
12081
12082 (define_expand "clz<mode>2"
12083 [(parallel
12084 [(set (match_operand:SWI248 0 "register_operand" "")
12085 (minus:SWI248
12086 (match_dup 2)
12087 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12088 (clobber (reg:CC FLAGS_REG))])
12089 (parallel
12090 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12091 (clobber (reg:CC FLAGS_REG))])]
12092 ""
12093 {
12094 if (TARGET_ABM)
12095 {
12096 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12097 DONE;
12098 }
12099 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12100 })
12101
12102 (define_insn "clz<mode>2_abm"
12103 [(set (match_operand:SWI248 0 "register_operand" "=r")
12104 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "TARGET_ABM || TARGET_BMI"
12107 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12108 [(set_attr "prefix_rep" "1")
12109 (set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12111
12112 ;; BMI instructions.
12113 (define_insn "*bmi_andn_<mode>"
12114 [(set (match_operand:SWI48 0 "register_operand" "=r")
12115 (and:SWI48
12116 (not:SWI48
12117 (match_operand:SWI48 1 "register_operand" "r"))
12118 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12119 (clobber (reg:CC FLAGS_REG))]
12120 "TARGET_BMI"
12121 "andn\t{%2, %1, %0|%0, %1, %2}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "mode" "<MODE>")])
12124
12125 (define_insn "bmi_bextr_<mode>"
12126 [(set (match_operand:SWI48 0 "register_operand" "=r")
12127 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12128 (match_operand:SWI48 2 "register_operand" "r")]
12129 UNSPEC_BEXTR))
12130 (clobber (reg:CC FLAGS_REG))]
12131 "TARGET_BMI"
12132 "bextr\t{%2, %1, %0|%0, %1, %2}"
12133 [(set_attr "type" "bitmanip")
12134 (set_attr "mode" "<MODE>")])
12135
12136 (define_insn "*bmi_blsi_<mode>"
12137 [(set (match_operand:SWI48 0 "register_operand" "=r")
12138 (and:SWI48
12139 (neg:SWI48
12140 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12141 (match_dup 1)))
12142 (clobber (reg:CC FLAGS_REG))]
12143 "TARGET_BMI"
12144 "blsi\t{%1, %0|%0, %1}"
12145 [(set_attr "type" "bitmanip")
12146 (set_attr "mode" "<MODE>")])
12147
12148 (define_insn "*bmi_blsmsk_<mode>"
12149 [(set (match_operand:SWI48 0 "register_operand" "=r")
12150 (xor:SWI48
12151 (plus:SWI48
12152 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12153 (const_int -1))
12154 (match_dup 1)))
12155 (clobber (reg:CC FLAGS_REG))]
12156 "TARGET_BMI"
12157 "blsmsk\t{%1, %0|%0, %1}"
12158 [(set_attr "type" "bitmanip")
12159 (set_attr "mode" "<MODE>")])
12160
12161 (define_insn "*bmi_blsr_<mode>"
12162 [(set (match_operand:SWI48 0 "register_operand" "=r")
12163 (and:SWI48
12164 (plus:SWI48
12165 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12166 (const_int -1))
12167 (match_dup 1)))
12168 (clobber (reg:CC FLAGS_REG))]
12169 "TARGET_BMI"
12170 "blsr\t{%1, %0|%0, %1}"
12171 [(set_attr "type" "bitmanip")
12172 (set_attr "mode" "<MODE>")])
12173
12174 ;; TBM instructions.
12175 (define_insn "tbm_bextri_<mode>"
12176 [(set (match_operand:SWI48 0 "register_operand" "=r")
12177 (zero_extract:SWI48
12178 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12179 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12180 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12181 (clobber (reg:CC FLAGS_REG))]
12182 "TARGET_TBM"
12183 {
12184 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12185 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12186 }
12187 [(set_attr "type" "bitmanip")
12188 (set_attr "mode" "<MODE>")])
12189
12190 (define_insn "*tbm_blcfill_<mode>"
12191 [(set (match_operand:SWI48 0 "register_operand" "=r")
12192 (and:SWI48
12193 (plus:SWI48
12194 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12195 (const_int 1))
12196 (match_dup 1)))
12197 (clobber (reg:CC FLAGS_REG))]
12198 "TARGET_TBM"
12199 "blcfill\t{%1, %0|%0, %1}"
12200 [(set_attr "type" "bitmanip")
12201 (set_attr "mode" "<MODE>")])
12202
12203 (define_insn "*tbm_blci_<mode>"
12204 [(set (match_operand:SWI48 0 "register_operand" "=r")
12205 (ior:SWI48
12206 (not:SWI48
12207 (plus:SWI48
12208 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12209 (const_int 1)))
12210 (match_dup 1)))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "TARGET_TBM"
12213 "blci\t{%1, %0|%0, %1}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "mode" "<MODE>")])
12216
12217 (define_insn "*tbm_blcic_<mode>"
12218 [(set (match_operand:SWI48 0 "register_operand" "=r")
12219 (and:SWI48
12220 (plus:SWI48
12221 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12222 (const_int 1))
12223 (not:SWI48
12224 (match_dup 1))))
12225 (clobber (reg:CC FLAGS_REG))]
12226 "TARGET_TBM"
12227 "blcic\t{%1, %0|%0, %1}"
12228 [(set_attr "type" "bitmanip")
12229 (set_attr "mode" "<MODE>")])
12230
12231 (define_insn "*tbm_blcmsk_<mode>"
12232 [(set (match_operand:SWI48 0 "register_operand" "=r")
12233 (xor:SWI48
12234 (plus:SWI48
12235 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12236 (const_int 1))
12237 (match_dup 1)))
12238 (clobber (reg:CC FLAGS_REG))]
12239 "TARGET_TBM"
12240 "blcmsk\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip")
12242 (set_attr "mode" "<MODE>")])
12243
12244 (define_insn "*tbm_blcs_<mode>"
12245 [(set (match_operand:SWI48 0 "register_operand" "=r")
12246 (ior:SWI48
12247 (plus:SWI48
12248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12249 (const_int 1))
12250 (match_dup 1)))
12251 (clobber (reg:CC FLAGS_REG))]
12252 "TARGET_TBM"
12253 "blcs\t{%1, %0|%0, %1}"
12254 [(set_attr "type" "bitmanip")
12255 (set_attr "mode" "<MODE>")])
12256
12257 (define_insn "*tbm_blsfill_<mode>"
12258 [(set (match_operand:SWI48 0 "register_operand" "=r")
12259 (ior:SWI48
12260 (plus:SWI48
12261 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12262 (const_int -1))
12263 (match_dup 1)))
12264 (clobber (reg:CC FLAGS_REG))]
12265 "TARGET_TBM"
12266 "blsfill\t{%1, %0|%0, %1}"
12267 [(set_attr "type" "bitmanip")
12268 (set_attr "mode" "<MODE>")])
12269
12270 (define_insn "*tbm_blsic_<mode>"
12271 [(set (match_operand:SWI48 0 "register_operand" "=r")
12272 (ior:SWI48
12273 (plus:SWI48
12274 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12275 (const_int -1))
12276 (not:SWI48
12277 (match_dup 1))))
12278 (clobber (reg:CC FLAGS_REG))]
12279 "TARGET_TBM"
12280 "blsic\t{%1, %0|%0, %1}"
12281 [(set_attr "type" "bitmanip")
12282 (set_attr "mode" "<MODE>")])
12283
12284 (define_insn "*tbm_t1mskc_<mode>"
12285 [(set (match_operand:SWI48 0 "register_operand" "=r")
12286 (ior:SWI48
12287 (plus:SWI48
12288 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12289 (const_int 1))
12290 (not:SWI48
12291 (match_dup 1))))
12292 (clobber (reg:CC FLAGS_REG))]
12293 "TARGET_TBM"
12294 "t1mskc\t{%1, %0|%0, %1}"
12295 [(set_attr "type" "bitmanip")
12296 (set_attr "mode" "<MODE>")])
12297
12298 (define_insn "*tbm_tzmsk_<mode>"
12299 [(set (match_operand:SWI48 0 "register_operand" "=r")
12300 (and:SWI48
12301 (plus:SWI48
12302 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12303 (const_int -1))
12304 (not:SWI48
12305 (match_dup 1))))
12306 (clobber (reg:CC FLAGS_REG))]
12307 "TARGET_TBM"
12308 "tzmsk\t{%1, %0|%0, %1}"
12309 [(set_attr "type" "bitmanip")
12310 (set_attr "mode" "<MODE>")])
12311
12312 (define_insn "bsr_rex64"
12313 [(set (match_operand:DI 0 "register_operand" "=r")
12314 (minus:DI (const_int 63)
12315 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12316 (clobber (reg:CC FLAGS_REG))]
12317 "TARGET_64BIT"
12318 "bsr{q}\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "alu1")
12320 (set_attr "prefix_0f" "1")
12321 (set_attr "mode" "DI")])
12322
12323 (define_insn "bsr"
12324 [(set (match_operand:SI 0 "register_operand" "=r")
12325 (minus:SI (const_int 31)
12326 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12327 (clobber (reg:CC FLAGS_REG))]
12328 ""
12329 "bsr{l}\t{%1, %0|%0, %1}"
12330 [(set_attr "type" "alu1")
12331 (set_attr "prefix_0f" "1")
12332 (set_attr "mode" "SI")])
12333
12334 (define_insn "*bsrhi"
12335 [(set (match_operand:HI 0 "register_operand" "=r")
12336 (minus:HI (const_int 15)
12337 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12338 (clobber (reg:CC FLAGS_REG))]
12339 ""
12340 "bsr{w}\t{%1, %0|%0, %1}"
12341 [(set_attr "type" "alu1")
12342 (set_attr "prefix_0f" "1")
12343 (set_attr "mode" "HI")])
12344
12345 (define_insn "popcount<mode>2"
12346 [(set (match_operand:SWI248 0 "register_operand" "=r")
12347 (popcount:SWI248
12348 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12349 (clobber (reg:CC FLAGS_REG))]
12350 "TARGET_POPCNT"
12351 {
12352 #if TARGET_MACHO
12353 return "popcnt\t{%1, %0|%0, %1}";
12354 #else
12355 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12356 #endif
12357 }
12358 [(set_attr "prefix_rep" "1")
12359 (set_attr "type" "bitmanip")
12360 (set_attr "mode" "<MODE>")])
12361
12362 (define_insn "*popcount<mode>2_cmp"
12363 [(set (reg FLAGS_REG)
12364 (compare
12365 (popcount:SWI248
12366 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12367 (const_int 0)))
12368 (set (match_operand:SWI248 0 "register_operand" "=r")
12369 (popcount:SWI248 (match_dup 1)))]
12370 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12371 {
12372 #if TARGET_MACHO
12373 return "popcnt\t{%1, %0|%0, %1}";
12374 #else
12375 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12376 #endif
12377 }
12378 [(set_attr "prefix_rep" "1")
12379 (set_attr "type" "bitmanip")
12380 (set_attr "mode" "<MODE>")])
12381
12382 (define_insn "*popcountsi2_cmp_zext"
12383 [(set (reg FLAGS_REG)
12384 (compare
12385 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12386 (const_int 0)))
12387 (set (match_operand:DI 0 "register_operand" "=r")
12388 (zero_extend:DI(popcount:SI (match_dup 1))))]
12389 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12390 {
12391 #if TARGET_MACHO
12392 return "popcnt\t{%1, %0|%0, %1}";
12393 #else
12394 return "popcnt{l}\t{%1, %0|%0, %1}";
12395 #endif
12396 }
12397 [(set_attr "prefix_rep" "1")
12398 (set_attr "type" "bitmanip")
12399 (set_attr "mode" "SI")])
12400
12401 (define_expand "bswap<mode>2"
12402 [(set (match_operand:SWI48 0 "register_operand" "")
12403 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12404 ""
12405 {
12406 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12407 {
12408 rtx x = operands[0];
12409
12410 emit_move_insn (x, operands[1]);
12411 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12412 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12413 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12414 DONE;
12415 }
12416 })
12417
12418 (define_insn "*bswap<mode>2_movbe"
12419 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12420 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12421 "TARGET_MOVBE
12422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12423 "@
12424 bswap\t%0
12425 movbe\t{%1, %0|%0, %1}
12426 movbe\t{%1, %0|%0, %1}"
12427 [(set_attr "type" "bitmanip,imov,imov")
12428 (set_attr "modrm" "0,1,1")
12429 (set_attr "prefix_0f" "*,1,1")
12430 (set_attr "prefix_extra" "*,1,1")
12431 (set_attr "mode" "<MODE>")])
12432
12433 (define_insn "*bswap<mode>2_1"
12434 [(set (match_operand:SWI48 0 "register_operand" "=r")
12435 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12436 "TARGET_BSWAP"
12437 "bswap\t%0"
12438 [(set_attr "type" "bitmanip")
12439 (set_attr "modrm" "0")
12440 (set_attr "mode" "<MODE>")])
12441
12442 (define_insn "*bswaphi_lowpart_1"
12443 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12444 (bswap:HI (match_dup 0)))
12445 (clobber (reg:CC FLAGS_REG))]
12446 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12447 "@
12448 xchg{b}\t{%h0, %b0|%b0, %h0}
12449 rol{w}\t{$8, %0|%0, 8}"
12450 [(set_attr "length" "2,4")
12451 (set_attr "mode" "QI,HI")])
12452
12453 (define_insn "bswaphi_lowpart"
12454 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12455 (bswap:HI (match_dup 0)))
12456 (clobber (reg:CC FLAGS_REG))]
12457 ""
12458 "rol{w}\t{$8, %0|%0, 8}"
12459 [(set_attr "length" "4")
12460 (set_attr "mode" "HI")])
12461
12462 (define_expand "paritydi2"
12463 [(set (match_operand:DI 0 "register_operand" "")
12464 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12465 "! TARGET_POPCNT"
12466 {
12467 rtx scratch = gen_reg_rtx (QImode);
12468 rtx cond;
12469
12470 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12471 NULL_RTX, operands[1]));
12472
12473 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12474 gen_rtx_REG (CCmode, FLAGS_REG),
12475 const0_rtx);
12476 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12477
12478 if (TARGET_64BIT)
12479 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12480 else
12481 {
12482 rtx tmp = gen_reg_rtx (SImode);
12483
12484 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12485 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12486 }
12487 DONE;
12488 })
12489
12490 (define_expand "paritysi2"
12491 [(set (match_operand:SI 0 "register_operand" "")
12492 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12493 "! TARGET_POPCNT"
12494 {
12495 rtx scratch = gen_reg_rtx (QImode);
12496 rtx cond;
12497
12498 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12499
12500 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12501 gen_rtx_REG (CCmode, FLAGS_REG),
12502 const0_rtx);
12503 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12504
12505 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12506 DONE;
12507 })
12508
12509 (define_insn_and_split "paritydi2_cmp"
12510 [(set (reg:CC FLAGS_REG)
12511 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12512 UNSPEC_PARITY))
12513 (clobber (match_scratch:DI 0 "=r"))
12514 (clobber (match_scratch:SI 1 "=&r"))
12515 (clobber (match_scratch:HI 2 "=Q"))]
12516 "! TARGET_POPCNT"
12517 "#"
12518 "&& reload_completed"
12519 [(parallel
12520 [(set (match_dup 1)
12521 (xor:SI (match_dup 1) (match_dup 4)))
12522 (clobber (reg:CC FLAGS_REG))])
12523 (parallel
12524 [(set (reg:CC FLAGS_REG)
12525 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12526 (clobber (match_dup 1))
12527 (clobber (match_dup 2))])]
12528 {
12529 operands[4] = gen_lowpart (SImode, operands[3]);
12530
12531 if (TARGET_64BIT)
12532 {
12533 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12534 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12535 }
12536 else
12537 operands[1] = gen_highpart (SImode, operands[3]);
12538 })
12539
12540 (define_insn_and_split "paritysi2_cmp"
12541 [(set (reg:CC FLAGS_REG)
12542 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12543 UNSPEC_PARITY))
12544 (clobber (match_scratch:SI 0 "=r"))
12545 (clobber (match_scratch:HI 1 "=&Q"))]
12546 "! TARGET_POPCNT"
12547 "#"
12548 "&& reload_completed"
12549 [(parallel
12550 [(set (match_dup 1)
12551 (xor:HI (match_dup 1) (match_dup 3)))
12552 (clobber (reg:CC FLAGS_REG))])
12553 (parallel
12554 [(set (reg:CC FLAGS_REG)
12555 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12556 (clobber (match_dup 1))])]
12557 {
12558 operands[3] = gen_lowpart (HImode, operands[2]);
12559
12560 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12561 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12562 })
12563
12564 (define_insn "*parityhi2_cmp"
12565 [(set (reg:CC FLAGS_REG)
12566 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12567 UNSPEC_PARITY))
12568 (clobber (match_scratch:HI 0 "=Q"))]
12569 "! TARGET_POPCNT"
12570 "xor{b}\t{%h0, %b0|%b0, %h0}"
12571 [(set_attr "length" "2")
12572 (set_attr "mode" "HI")])
12573 \f
12574 ;; Thread-local storage patterns for ELF.
12575 ;;
12576 ;; Note that these code sequences must appear exactly as shown
12577 ;; in order to allow linker relaxation.
12578
12579 (define_insn "*tls_global_dynamic_32_gnu"
12580 [(set (match_operand:SI 0 "register_operand" "=a")
12581 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12582 (match_operand:SI 2 "tls_symbolic_operand" "")
12583 (match_operand:SI 3 "call_insn_operand" "")]
12584 UNSPEC_TLS_GD))
12585 (clobber (match_scratch:SI 4 "=d"))
12586 (clobber (match_scratch:SI 5 "=c"))
12587 (clobber (reg:CC FLAGS_REG))]
12588 "!TARGET_64BIT && TARGET_GNU_TLS"
12589 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12590 [(set_attr "type" "multi")
12591 (set_attr "length" "12")])
12592
12593 (define_expand "tls_global_dynamic_32"
12594 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12595 (unspec:SI
12596 [(match_dup 2)
12597 (match_operand:SI 1 "tls_symbolic_operand" "")
12598 (match_dup 3)]
12599 UNSPEC_TLS_GD))
12600 (clobber (match_scratch:SI 4 ""))
12601 (clobber (match_scratch:SI 5 ""))
12602 (clobber (reg:CC FLAGS_REG))])]
12603 ""
12604 {
12605 if (flag_pic)
12606 operands[2] = pic_offset_table_rtx;
12607 else
12608 {
12609 operands[2] = gen_reg_rtx (Pmode);
12610 emit_insn (gen_set_got (operands[2]));
12611 }
12612 if (TARGET_GNU2_TLS)
12613 {
12614 emit_insn (gen_tls_dynamic_gnu2_32
12615 (operands[0], operands[1], operands[2]));
12616 DONE;
12617 }
12618 operands[3] = ix86_tls_get_addr ();
12619 })
12620
12621 (define_insn "*tls_global_dynamic_64"
12622 [(set (match_operand:DI 0 "register_operand" "=a")
12623 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12624 (match_operand:DI 3 "" "")))
12625 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12626 UNSPEC_TLS_GD)]
12627 "TARGET_64BIT"
12628 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12629 [(set_attr "type" "multi")
12630 (set_attr "length" "16")])
12631
12632 (define_expand "tls_global_dynamic_64"
12633 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12634 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12635 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12636 UNSPEC_TLS_GD)])]
12637 ""
12638 {
12639 if (TARGET_GNU2_TLS)
12640 {
12641 emit_insn (gen_tls_dynamic_gnu2_64
12642 (operands[0], operands[1]));
12643 DONE;
12644 }
12645 operands[2] = ix86_tls_get_addr ();
12646 })
12647
12648 (define_insn "*tls_local_dynamic_base_32_gnu"
12649 [(set (match_operand:SI 0 "register_operand" "=a")
12650 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12651 (match_operand:SI 2 "call_insn_operand" "")]
12652 UNSPEC_TLS_LD_BASE))
12653 (clobber (match_scratch:SI 3 "=d"))
12654 (clobber (match_scratch:SI 4 "=c"))
12655 (clobber (reg:CC FLAGS_REG))]
12656 "!TARGET_64BIT && TARGET_GNU_TLS"
12657 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12658 [(set_attr "type" "multi")
12659 (set_attr "length" "11")])
12660
12661 (define_expand "tls_local_dynamic_base_32"
12662 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12663 (unspec:SI [(match_dup 1) (match_dup 2)]
12664 UNSPEC_TLS_LD_BASE))
12665 (clobber (match_scratch:SI 3 ""))
12666 (clobber (match_scratch:SI 4 ""))
12667 (clobber (reg:CC FLAGS_REG))])]
12668 ""
12669 {
12670 if (flag_pic)
12671 operands[1] = pic_offset_table_rtx;
12672 else
12673 {
12674 operands[1] = gen_reg_rtx (Pmode);
12675 emit_insn (gen_set_got (operands[1]));
12676 }
12677 if (TARGET_GNU2_TLS)
12678 {
12679 emit_insn (gen_tls_dynamic_gnu2_32
12680 (operands[0], ix86_tls_module_base (), operands[1]));
12681 DONE;
12682 }
12683 operands[2] = ix86_tls_get_addr ();
12684 })
12685
12686 (define_insn "*tls_local_dynamic_base_64"
12687 [(set (match_operand:DI 0 "register_operand" "=a")
12688 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12689 (match_operand:DI 2 "" "")))
12690 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12691 "TARGET_64BIT"
12692 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12693 [(set_attr "type" "multi")
12694 (set_attr "length" "12")])
12695
12696 (define_expand "tls_local_dynamic_base_64"
12697 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12698 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12699 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12700 ""
12701 {
12702 if (TARGET_GNU2_TLS)
12703 {
12704 emit_insn (gen_tls_dynamic_gnu2_64
12705 (operands[0], ix86_tls_module_base ()));
12706 DONE;
12707 }
12708 operands[1] = ix86_tls_get_addr ();
12709 })
12710
12711 ;; Local dynamic of a single variable is a lose. Show combine how
12712 ;; to convert that back to global dynamic.
12713
12714 (define_insn_and_split "*tls_local_dynamic_32_once"
12715 [(set (match_operand:SI 0 "register_operand" "=a")
12716 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12717 (match_operand:SI 2 "call_insn_operand" "")]
12718 UNSPEC_TLS_LD_BASE)
12719 (const:SI (unspec:SI
12720 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12721 UNSPEC_DTPOFF))))
12722 (clobber (match_scratch:SI 4 "=d"))
12723 (clobber (match_scratch:SI 5 "=c"))
12724 (clobber (reg:CC FLAGS_REG))]
12725 ""
12726 "#"
12727 ""
12728 [(parallel [(set (match_dup 0)
12729 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12730 UNSPEC_TLS_GD))
12731 (clobber (match_dup 4))
12732 (clobber (match_dup 5))
12733 (clobber (reg:CC FLAGS_REG))])])
12734
12735 ;; Segment register for the thread base ptr load
12736 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12737
12738 ;; Load and add the thread base pointer from %gs:0.
12739 (define_insn "*load_tp_<mode>"
12740 [(set (match_operand:P 0 "register_operand" "=r")
12741 (unspec:P [(const_int 0)] UNSPEC_TP))]
12742 ""
12743 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12744 [(set_attr "type" "imov")
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_<mode>"
12751 [(set (match_operand:P 0 "register_operand" "=r")
12752 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12753 (match_operand:P 1 "register_operand" "0")))
12754 (clobber (reg:CC FLAGS_REG))]
12755 ""
12756 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12757 [(set_attr "type" "alu")
12758 (set_attr "modrm" "0")
12759 (set_attr "length" "7")
12760 (set_attr "memory" "load")
12761 (set_attr "imm_disp" "false")])
12762
12763 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12764 ;; %rax as destination of the initial executable code sequence.
12765 (define_insn "tls_initial_exec_64_sun"
12766 [(set (match_operand:DI 0 "register_operand" "=a")
12767 (unspec:DI
12768 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12769 UNSPEC_TLS_IE_SUN))
12770 (clobber (reg:CC FLAGS_REG))]
12771 "TARGET_64BIT && TARGET_SUN_TLS"
12772 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12773 [(set_attr "type" "multi")])
12774
12775 ;; GNU2 TLS patterns can be split.
12776
12777 (define_expand "tls_dynamic_gnu2_32"
12778 [(set (match_dup 3)
12779 (plus:SI (match_operand:SI 2 "register_operand" "")
12780 (const:SI
12781 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12782 UNSPEC_TLSDESC))))
12783 (parallel
12784 [(set (match_operand:SI 0 "register_operand" "")
12785 (unspec:SI [(match_dup 1) (match_dup 3)
12786 (match_dup 2) (reg:SI SP_REG)]
12787 UNSPEC_TLSDESC))
12788 (clobber (reg:CC FLAGS_REG))])]
12789 "!TARGET_64BIT && TARGET_GNU2_TLS"
12790 {
12791 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12792 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12793 })
12794
12795 (define_insn "*tls_dynamic_lea_32"
12796 [(set (match_operand:SI 0 "register_operand" "=r")
12797 (plus:SI (match_operand:SI 1 "register_operand" "b")
12798 (const:SI
12799 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12800 UNSPEC_TLSDESC))))]
12801 "!TARGET_64BIT && TARGET_GNU2_TLS"
12802 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12803 [(set_attr "type" "lea")
12804 (set_attr "mode" "SI")
12805 (set_attr "length" "6")
12806 (set_attr "length_address" "4")])
12807
12808 (define_insn "*tls_dynamic_call_32"
12809 [(set (match_operand:SI 0 "register_operand" "=a")
12810 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12811 (match_operand:SI 2 "register_operand" "0")
12812 ;; we have to make sure %ebx still points to the GOT
12813 (match_operand:SI 3 "register_operand" "b")
12814 (reg:SI SP_REG)]
12815 UNSPEC_TLSDESC))
12816 (clobber (reg:CC FLAGS_REG))]
12817 "!TARGET_64BIT && TARGET_GNU2_TLS"
12818 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12819 [(set_attr "type" "call")
12820 (set_attr "length" "2")
12821 (set_attr "length_address" "0")])
12822
12823 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12824 [(set (match_operand:SI 0 "register_operand" "=&a")
12825 (plus:SI
12826 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12827 (match_operand:SI 4 "" "")
12828 (match_operand:SI 2 "register_operand" "b")
12829 (reg:SI SP_REG)]
12830 UNSPEC_TLSDESC)
12831 (const:SI (unspec:SI
12832 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12833 UNSPEC_DTPOFF))))
12834 (clobber (reg:CC FLAGS_REG))]
12835 "!TARGET_64BIT && TARGET_GNU2_TLS"
12836 "#"
12837 ""
12838 [(set (match_dup 0) (match_dup 5))]
12839 {
12840 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12841 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12842 })
12843
12844 (define_expand "tls_dynamic_gnu2_64"
12845 [(set (match_dup 2)
12846 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12847 UNSPEC_TLSDESC))
12848 (parallel
12849 [(set (match_operand:DI 0 "register_operand" "")
12850 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12851 UNSPEC_TLSDESC))
12852 (clobber (reg:CC FLAGS_REG))])]
12853 "TARGET_64BIT && TARGET_GNU2_TLS"
12854 {
12855 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12856 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12857 })
12858
12859 (define_insn "*tls_dynamic_lea_64"
12860 [(set (match_operand:DI 0 "register_operand" "=r")
12861 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12862 UNSPEC_TLSDESC))]
12863 "TARGET_64BIT && TARGET_GNU2_TLS"
12864 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12865 [(set_attr "type" "lea")
12866 (set_attr "mode" "DI")
12867 (set_attr "length" "7")
12868 (set_attr "length_address" "4")])
12869
12870 (define_insn "*tls_dynamic_call_64"
12871 [(set (match_operand:DI 0 "register_operand" "=a")
12872 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12873 (match_operand:DI 2 "register_operand" "0")
12874 (reg:DI SP_REG)]
12875 UNSPEC_TLSDESC))
12876 (clobber (reg:CC FLAGS_REG))]
12877 "TARGET_64BIT && TARGET_GNU2_TLS"
12878 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12879 [(set_attr "type" "call")
12880 (set_attr "length" "2")
12881 (set_attr "length_address" "0")])
12882
12883 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12884 [(set (match_operand:DI 0 "register_operand" "=&a")
12885 (plus:DI
12886 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12887 (match_operand:DI 3 "" "")
12888 (reg:DI SP_REG)]
12889 UNSPEC_TLSDESC)
12890 (const:DI (unspec:DI
12891 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12892 UNSPEC_DTPOFF))))
12893 (clobber (reg:CC FLAGS_REG))]
12894 "TARGET_64BIT && TARGET_GNU2_TLS"
12895 "#"
12896 ""
12897 [(set (match_dup 0) (match_dup 4))]
12898 {
12899 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12900 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12901 })
12902 \f
12903 ;; These patterns match the binary 387 instructions for addM3, subM3,
12904 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12905 ;; SFmode. The first is the normal insn, the second the same insn but
12906 ;; with one operand a conversion, and the third the same insn but with
12907 ;; the other operand a conversion. The conversion may be SFmode or
12908 ;; SImode if the target mode DFmode, but only SImode if the target mode
12909 ;; is SFmode.
12910
12911 ;; Gcc is slightly more smart about handling normal two address instructions
12912 ;; so use special patterns for add and mull.
12913
12914 (define_insn "*fop_<mode>_comm_mixed"
12915 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12916 (match_operator:MODEF 3 "binary_fp_operator"
12917 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12918 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12919 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12920 && COMMUTATIVE_ARITH_P (operands[3])
12921 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12922 "* return output_387_binary_op (insn, operands);"
12923 [(set (attr "type")
12924 (if_then_else (eq_attr "alternative" "1,2")
12925 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12926 (const_string "ssemul")
12927 (const_string "sseadd"))
12928 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12929 (const_string "fmul")
12930 (const_string "fop"))))
12931 (set_attr "isa" "base,noavx,avx")
12932 (set_attr "prefix" "orig,orig,vex")
12933 (set_attr "mode" "<MODE>")])
12934
12935 (define_insn "*fop_<mode>_comm_sse"
12936 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12937 (match_operator:MODEF 3 "binary_fp_operator"
12938 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12939 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12940 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12941 && COMMUTATIVE_ARITH_P (operands[3])
12942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12943 "* return output_387_binary_op (insn, operands);"
12944 [(set (attr "type")
12945 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12946 (const_string "ssemul")
12947 (const_string "sseadd")))
12948 (set_attr "isa" "noavx,avx")
12949 (set_attr "prefix" "orig,vex")
12950 (set_attr "mode" "<MODE>")])
12951
12952 (define_insn "*fop_<mode>_comm_i387"
12953 [(set (match_operand:MODEF 0 "register_operand" "=f")
12954 (match_operator:MODEF 3 "binary_fp_operator"
12955 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12956 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12957 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12958 && COMMUTATIVE_ARITH_P (operands[3])
12959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12960 "* return output_387_binary_op (insn, operands);"
12961 [(set (attr "type")
12962 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12963 (const_string "fmul")
12964 (const_string "fop")))
12965 (set_attr "mode" "<MODE>")])
12966
12967 (define_insn "*fop_<mode>_1_mixed"
12968 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12969 (match_operator:MODEF 3 "binary_fp_operator"
12970 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12971 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12972 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12973 && !COMMUTATIVE_ARITH_P (operands[3])
12974 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12975 "* return output_387_binary_op (insn, operands);"
12976 [(set (attr "type")
12977 (cond [(and (eq_attr "alternative" "2,3")
12978 (match_operand:MODEF 3 "mult_operator" ""))
12979 (const_string "ssemul")
12980 (and (eq_attr "alternative" "2,3")
12981 (match_operand:MODEF 3 "div_operator" ""))
12982 (const_string "ssediv")
12983 (eq_attr "alternative" "2,3")
12984 (const_string "sseadd")
12985 (match_operand:MODEF 3 "mult_operator" "")
12986 (const_string "fmul")
12987 (match_operand:MODEF 3 "div_operator" "")
12988 (const_string "fdiv")
12989 ]
12990 (const_string "fop")))
12991 (set_attr "isa" "base,base,noavx,avx")
12992 (set_attr "prefix" "orig,orig,orig,vex")
12993 (set_attr "mode" "<MODE>")])
12994
12995 (define_insn "*rcpsf2_sse"
12996 [(set (match_operand:SF 0 "register_operand" "=x")
12997 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12998 UNSPEC_RCP))]
12999 "TARGET_SSE_MATH"
13000 "%vrcpss\t{%1, %d0|%d0, %1}"
13001 [(set_attr "type" "sse")
13002 (set_attr "atom_sse_attr" "rcp")
13003 (set_attr "prefix" "maybe_vex")
13004 (set_attr "mode" "SF")])
13005
13006 (define_insn "*fop_<mode>_1_sse"
13007 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13008 (match_operator:MODEF 3 "binary_fp_operator"
13009 [(match_operand:MODEF 1 "register_operand" "0,x")
13010 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13011 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13012 && !COMMUTATIVE_ARITH_P (operands[3])"
13013 "* return output_387_binary_op (insn, operands);"
13014 [(set (attr "type")
13015 (cond [(match_operand:MODEF 3 "mult_operator" "")
13016 (const_string "ssemul")
13017 (match_operand:MODEF 3 "div_operator" "")
13018 (const_string "ssediv")
13019 ]
13020 (const_string "sseadd")))
13021 (set_attr "isa" "noavx,avx")
13022 (set_attr "prefix" "orig,vex")
13023 (set_attr "mode" "<MODE>")])
13024
13025 ;; This pattern is not fully shadowed by the pattern above.
13026 (define_insn "*fop_<mode>_1_i387"
13027 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13028 (match_operator:MODEF 3 "binary_fp_operator"
13029 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13030 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13031 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13032 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13033 && !COMMUTATIVE_ARITH_P (operands[3])
13034 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13035 "* return output_387_binary_op (insn, operands);"
13036 [(set (attr "type")
13037 (cond [(match_operand:MODEF 3 "mult_operator" "")
13038 (const_string "fmul")
13039 (match_operand:MODEF 3 "div_operator" "")
13040 (const_string "fdiv")
13041 ]
13042 (const_string "fop")))
13043 (set_attr "mode" "<MODE>")])
13044
13045 ;; ??? Add SSE splitters for these!
13046 (define_insn "*fop_<MODEF:mode>_2_i387"
13047 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13048 (match_operator:MODEF 3 "binary_fp_operator"
13049 [(float:MODEF
13050 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13051 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13052 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13053 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13054 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13055 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13056 [(set (attr "type")
13057 (cond [(match_operand:MODEF 3 "mult_operator" "")
13058 (const_string "fmul")
13059 (match_operand:MODEF 3 "div_operator" "")
13060 (const_string "fdiv")
13061 ]
13062 (const_string "fop")))
13063 (set_attr "fp_int_src" "true")
13064 (set_attr "mode" "<X87MODEI12:MODE>")])
13065
13066 (define_insn "*fop_<MODEF:mode>_3_i387"
13067 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13068 (match_operator:MODEF 3 "binary_fp_operator"
13069 [(match_operand:MODEF 1 "register_operand" "0,0")
13070 (float:MODEF
13071 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13072 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13073 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13074 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13075 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13076 [(set (attr "type")
13077 (cond [(match_operand:MODEF 3 "mult_operator" "")
13078 (const_string "fmul")
13079 (match_operand:MODEF 3 "div_operator" "")
13080 (const_string "fdiv")
13081 ]
13082 (const_string "fop")))
13083 (set_attr "fp_int_src" "true")
13084 (set_attr "mode" "<MODE>")])
13085
13086 (define_insn "*fop_df_4_i387"
13087 [(set (match_operand:DF 0 "register_operand" "=f,f")
13088 (match_operator:DF 3 "binary_fp_operator"
13089 [(float_extend:DF
13090 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13091 (match_operand:DF 2 "register_operand" "0,f")]))]
13092 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13093 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13094 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13095 "* return output_387_binary_op (insn, operands);"
13096 [(set (attr "type")
13097 (cond [(match_operand:DF 3 "mult_operator" "")
13098 (const_string "fmul")
13099 (match_operand:DF 3 "div_operator" "")
13100 (const_string "fdiv")
13101 ]
13102 (const_string "fop")))
13103 (set_attr "mode" "SF")])
13104
13105 (define_insn "*fop_df_5_i387"
13106 [(set (match_operand:DF 0 "register_operand" "=f,f")
13107 (match_operator:DF 3 "binary_fp_operator"
13108 [(match_operand:DF 1 "register_operand" "0,f")
13109 (float_extend:DF
13110 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13111 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13112 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
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_6_i387"
13124 [(set (match_operand:DF 0 "register_operand" "=f,f")
13125 (match_operator:DF 3 "binary_fp_operator"
13126 [(float_extend:DF
13127 (match_operand:SF 1 "register_operand" "0,f"))
13128 (float_extend:DF
13129 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13130 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13131 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13132 "* return output_387_binary_op (insn, operands);"
13133 [(set (attr "type")
13134 (cond [(match_operand:DF 3 "mult_operator" "")
13135 (const_string "fmul")
13136 (match_operand:DF 3 "div_operator" "")
13137 (const_string "fdiv")
13138 ]
13139 (const_string "fop")))
13140 (set_attr "mode" "SF")])
13141
13142 (define_insn "*fop_xf_comm_i387"
13143 [(set (match_operand:XF 0 "register_operand" "=f")
13144 (match_operator:XF 3 "binary_fp_operator"
13145 [(match_operand:XF 1 "register_operand" "%0")
13146 (match_operand:XF 2 "register_operand" "f")]))]
13147 "TARGET_80387
13148 && COMMUTATIVE_ARITH_P (operands[3])"
13149 "* return output_387_binary_op (insn, operands);"
13150 [(set (attr "type")
13151 (if_then_else (match_operand:XF 3 "mult_operator" "")
13152 (const_string "fmul")
13153 (const_string "fop")))
13154 (set_attr "mode" "XF")])
13155
13156 (define_insn "*fop_xf_1_i387"
13157 [(set (match_operand:XF 0 "register_operand" "=f,f")
13158 (match_operator:XF 3 "binary_fp_operator"
13159 [(match_operand:XF 1 "register_operand" "0,f")
13160 (match_operand:XF 2 "register_operand" "f,0")]))]
13161 "TARGET_80387
13162 && !COMMUTATIVE_ARITH_P (operands[3])"
13163 "* return output_387_binary_op (insn, operands);"
13164 [(set (attr "type")
13165 (cond [(match_operand:XF 3 "mult_operator" "")
13166 (const_string "fmul")
13167 (match_operand:XF 3 "div_operator" "")
13168 (const_string "fdiv")
13169 ]
13170 (const_string "fop")))
13171 (set_attr "mode" "XF")])
13172
13173 (define_insn "*fop_xf_2_i387"
13174 [(set (match_operand:XF 0 "register_operand" "=f,f")
13175 (match_operator:XF 3 "binary_fp_operator"
13176 [(float:XF
13177 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13178 (match_operand:XF 2 "register_operand" "0,0")]))]
13179 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13180 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13181 [(set (attr "type")
13182 (cond [(match_operand:XF 3 "mult_operator" "")
13183 (const_string "fmul")
13184 (match_operand:XF 3 "div_operator" "")
13185 (const_string "fdiv")
13186 ]
13187 (const_string "fop")))
13188 (set_attr "fp_int_src" "true")
13189 (set_attr "mode" "<MODE>")])
13190
13191 (define_insn "*fop_xf_3_i387"
13192 [(set (match_operand:XF 0 "register_operand" "=f,f")
13193 (match_operator:XF 3 "binary_fp_operator"
13194 [(match_operand:XF 1 "register_operand" "0,0")
13195 (float:XF
13196 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
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_4_i387"
13210 [(set (match_operand:XF 0 "register_operand" "=f,f")
13211 (match_operator:XF 3 "binary_fp_operator"
13212 [(float_extend:XF
13213 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13214 (match_operand:XF 2 "register_operand" "0,f")]))]
13215 "TARGET_80387"
13216 "* return 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 "mode" "<MODE>")])
13225
13226 (define_insn "*fop_xf_5_i387"
13227 [(set (match_operand:XF 0 "register_operand" "=f,f")
13228 (match_operator:XF 3 "binary_fp_operator"
13229 [(match_operand:XF 1 "register_operand" "0,f")
13230 (float_extend:XF
13231 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13232 "TARGET_80387"
13233 "* return output_387_binary_op (insn, operands);"
13234 [(set (attr "type")
13235 (cond [(match_operand:XF 3 "mult_operator" "")
13236 (const_string "fmul")
13237 (match_operand:XF 3 "div_operator" "")
13238 (const_string "fdiv")
13239 ]
13240 (const_string "fop")))
13241 (set_attr "mode" "<MODE>")])
13242
13243 (define_insn "*fop_xf_6_i387"
13244 [(set (match_operand:XF 0 "register_operand" "=f,f")
13245 (match_operator:XF 3 "binary_fp_operator"
13246 [(float_extend:XF
13247 (match_operand:MODEF 1 "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_split
13262 [(set (match_operand 0 "register_operand" "")
13263 (match_operator 3 "binary_fp_operator"
13264 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13265 (match_operand 2 "register_operand" "")]))]
13266 "reload_completed
13267 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13268 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13269 [(const_int 0)]
13270 {
13271 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13272 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13273 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13274 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13275 GET_MODE (operands[3]),
13276 operands[4],
13277 operands[2])));
13278 ix86_free_from_memory (GET_MODE (operands[1]));
13279 DONE;
13280 })
13281
13282 (define_split
13283 [(set (match_operand 0 "register_operand" "")
13284 (match_operator 3 "binary_fp_operator"
13285 [(match_operand 1 "register_operand" "")
13286 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13287 "reload_completed
13288 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13289 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13290 [(const_int 0)]
13291 {
13292 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13293 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13294 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13295 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13296 GET_MODE (operands[3]),
13297 operands[1],
13298 operands[4])));
13299 ix86_free_from_memory (GET_MODE (operands[2]));
13300 DONE;
13301 })
13302 \f
13303 ;; FPU special functions.
13304
13305 ;; This pattern implements a no-op XFmode truncation for
13306 ;; all fancy i386 XFmode math functions.
13307
13308 (define_insn "truncxf<mode>2_i387_noop_unspec"
13309 [(set (match_operand:MODEF 0 "register_operand" "=f")
13310 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13311 UNSPEC_TRUNC_NOOP))]
13312 "TARGET_USE_FANCY_MATH_387"
13313 "* return output_387_reg_move (insn, operands);"
13314 [(set_attr "type" "fmov")
13315 (set_attr "mode" "<MODE>")])
13316
13317 (define_insn "sqrtxf2"
13318 [(set (match_operand:XF 0 "register_operand" "=f")
13319 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13320 "TARGET_USE_FANCY_MATH_387"
13321 "fsqrt"
13322 [(set_attr "type" "fpspc")
13323 (set_attr "mode" "XF")
13324 (set_attr "athlon_decode" "direct")
13325 (set_attr "amdfam10_decode" "direct")
13326 (set_attr "bdver1_decode" "direct")])
13327
13328 (define_insn "sqrt_extend<mode>xf2_i387"
13329 [(set (match_operand:XF 0 "register_operand" "=f")
13330 (sqrt:XF
13331 (float_extend:XF
13332 (match_operand:MODEF 1 "register_operand" "0"))))]
13333 "TARGET_USE_FANCY_MATH_387"
13334 "fsqrt"
13335 [(set_attr "type" "fpspc")
13336 (set_attr "mode" "XF")
13337 (set_attr "athlon_decode" "direct")
13338 (set_attr "amdfam10_decode" "direct")
13339 (set_attr "bdver1_decode" "direct")])
13340
13341 (define_insn "*rsqrtsf2_sse"
13342 [(set (match_operand:SF 0 "register_operand" "=x")
13343 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13344 UNSPEC_RSQRT))]
13345 "TARGET_SSE_MATH"
13346 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13347 [(set_attr "type" "sse")
13348 (set_attr "atom_sse_attr" "rcp")
13349 (set_attr "prefix" "maybe_vex")
13350 (set_attr "mode" "SF")])
13351
13352 (define_expand "rsqrtsf2"
13353 [(set (match_operand:SF 0 "register_operand" "")
13354 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13355 UNSPEC_RSQRT))]
13356 "TARGET_SSE_MATH"
13357 {
13358 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13359 DONE;
13360 })
13361
13362 (define_insn "*sqrt<mode>2_sse"
13363 [(set (match_operand:MODEF 0 "register_operand" "=x")
13364 (sqrt:MODEF
13365 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13366 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13367 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13368 [(set_attr "type" "sse")
13369 (set_attr "atom_sse_attr" "sqrt")
13370 (set_attr "prefix" "maybe_vex")
13371 (set_attr "mode" "<MODE>")
13372 (set_attr "athlon_decode" "*")
13373 (set_attr "amdfam10_decode" "*")
13374 (set_attr "bdver1_decode" "*")])
13375
13376 (define_expand "sqrt<mode>2"
13377 [(set (match_operand:MODEF 0 "register_operand" "")
13378 (sqrt:MODEF
13379 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13380 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13381 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13382 {
13383 if (<MODE>mode == SFmode
13384 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13385 && flag_finite_math_only && !flag_trapping_math
13386 && flag_unsafe_math_optimizations)
13387 {
13388 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13389 DONE;
13390 }
13391
13392 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13393 {
13394 rtx op0 = gen_reg_rtx (XFmode);
13395 rtx op1 = force_reg (<MODE>mode, operands[1]);
13396
13397 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13398 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13399 DONE;
13400 }
13401 })
13402
13403 (define_insn "fpremxf4_i387"
13404 [(set (match_operand:XF 0 "register_operand" "=f")
13405 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13406 (match_operand:XF 3 "register_operand" "1")]
13407 UNSPEC_FPREM_F))
13408 (set (match_operand:XF 1 "register_operand" "=u")
13409 (unspec:XF [(match_dup 2) (match_dup 3)]
13410 UNSPEC_FPREM_U))
13411 (set (reg:CCFP FPSR_REG)
13412 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13413 UNSPEC_C2_FLAG))]
13414 "TARGET_USE_FANCY_MATH_387"
13415 "fprem"
13416 [(set_attr "type" "fpspc")
13417 (set_attr "mode" "XF")])
13418
13419 (define_expand "fmodxf3"
13420 [(use (match_operand:XF 0 "register_operand" ""))
13421 (use (match_operand:XF 1 "general_operand" ""))
13422 (use (match_operand:XF 2 "general_operand" ""))]
13423 "TARGET_USE_FANCY_MATH_387"
13424 {
13425 rtx label = gen_label_rtx ();
13426
13427 rtx op1 = gen_reg_rtx (XFmode);
13428 rtx op2 = gen_reg_rtx (XFmode);
13429
13430 emit_move_insn (op2, operands[2]);
13431 emit_move_insn (op1, operands[1]);
13432
13433 emit_label (label);
13434 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13435 ix86_emit_fp_unordered_jump (label);
13436 LABEL_NUSES (label) = 1;
13437
13438 emit_move_insn (operands[0], op1);
13439 DONE;
13440 })
13441
13442 (define_expand "fmod<mode>3"
13443 [(use (match_operand:MODEF 0 "register_operand" ""))
13444 (use (match_operand:MODEF 1 "general_operand" ""))
13445 (use (match_operand:MODEF 2 "general_operand" ""))]
13446 "TARGET_USE_FANCY_MATH_387"
13447 {
13448 rtx (*gen_truncxf) (rtx, rtx);
13449
13450 rtx label = gen_label_rtx ();
13451
13452 rtx op1 = gen_reg_rtx (XFmode);
13453 rtx op2 = gen_reg_rtx (XFmode);
13454
13455 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13457
13458 emit_label (label);
13459 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13460 ix86_emit_fp_unordered_jump (label);
13461 LABEL_NUSES (label) = 1;
13462
13463 /* Truncate the result properly for strict SSE math. */
13464 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13465 && !TARGET_MIX_SSE_I387)
13466 gen_truncxf = gen_truncxf<mode>2;
13467 else
13468 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13469
13470 emit_insn (gen_truncxf (operands[0], op1));
13471 DONE;
13472 })
13473
13474 (define_insn "fprem1xf4_i387"
13475 [(set (match_operand:XF 0 "register_operand" "=f")
13476 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13477 (match_operand:XF 3 "register_operand" "1")]
13478 UNSPEC_FPREM1_F))
13479 (set (match_operand:XF 1 "register_operand" "=u")
13480 (unspec:XF [(match_dup 2) (match_dup 3)]
13481 UNSPEC_FPREM1_U))
13482 (set (reg:CCFP FPSR_REG)
13483 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13484 UNSPEC_C2_FLAG))]
13485 "TARGET_USE_FANCY_MATH_387"
13486 "fprem1"
13487 [(set_attr "type" "fpspc")
13488 (set_attr "mode" "XF")])
13489
13490 (define_expand "remainderxf3"
13491 [(use (match_operand:XF 0 "register_operand" ""))
13492 (use (match_operand:XF 1 "general_operand" ""))
13493 (use (match_operand:XF 2 "general_operand" ""))]
13494 "TARGET_USE_FANCY_MATH_387"
13495 {
13496 rtx label = gen_label_rtx ();
13497
13498 rtx op1 = gen_reg_rtx (XFmode);
13499 rtx op2 = gen_reg_rtx (XFmode);
13500
13501 emit_move_insn (op2, operands[2]);
13502 emit_move_insn (op1, operands[1]);
13503
13504 emit_label (label);
13505 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13506 ix86_emit_fp_unordered_jump (label);
13507 LABEL_NUSES (label) = 1;
13508
13509 emit_move_insn (operands[0], op1);
13510 DONE;
13511 })
13512
13513 (define_expand "remainder<mode>3"
13514 [(use (match_operand:MODEF 0 "register_operand" ""))
13515 (use (match_operand:MODEF 1 "general_operand" ""))
13516 (use (match_operand:MODEF 2 "general_operand" ""))]
13517 "TARGET_USE_FANCY_MATH_387"
13518 {
13519 rtx (*gen_truncxf) (rtx, rtx);
13520
13521 rtx label = gen_label_rtx ();
13522
13523 rtx op1 = gen_reg_rtx (XFmode);
13524 rtx op2 = gen_reg_rtx (XFmode);
13525
13526 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13527 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13528
13529 emit_label (label);
13530
13531 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13532 ix86_emit_fp_unordered_jump (label);
13533 LABEL_NUSES (label) = 1;
13534
13535 /* Truncate the result properly for strict SSE math. */
13536 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13537 && !TARGET_MIX_SSE_I387)
13538 gen_truncxf = gen_truncxf<mode>2;
13539 else
13540 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13541
13542 emit_insn (gen_truncxf (operands[0], op1));
13543 DONE;
13544 })
13545
13546 (define_insn "*sinxf2_i387"
13547 [(set (match_operand:XF 0 "register_operand" "=f")
13548 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13549 "TARGET_USE_FANCY_MATH_387
13550 && flag_unsafe_math_optimizations"
13551 "fsin"
13552 [(set_attr "type" "fpspc")
13553 (set_attr "mode" "XF")])
13554
13555 (define_insn "*sin_extend<mode>xf2_i387"
13556 [(set (match_operand:XF 0 "register_operand" "=f")
13557 (unspec:XF [(float_extend:XF
13558 (match_operand:MODEF 1 "register_operand" "0"))]
13559 UNSPEC_SIN))]
13560 "TARGET_USE_FANCY_MATH_387
13561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13562 || TARGET_MIX_SSE_I387)
13563 && flag_unsafe_math_optimizations"
13564 "fsin"
13565 [(set_attr "type" "fpspc")
13566 (set_attr "mode" "XF")])
13567
13568 (define_insn "*cosxf2_i387"
13569 [(set (match_operand:XF 0 "register_operand" "=f")
13570 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13571 "TARGET_USE_FANCY_MATH_387
13572 && flag_unsafe_math_optimizations"
13573 "fcos"
13574 [(set_attr "type" "fpspc")
13575 (set_attr "mode" "XF")])
13576
13577 (define_insn "*cos_extend<mode>xf2_i387"
13578 [(set (match_operand:XF 0 "register_operand" "=f")
13579 (unspec:XF [(float_extend:XF
13580 (match_operand:MODEF 1 "register_operand" "0"))]
13581 UNSPEC_COS))]
13582 "TARGET_USE_FANCY_MATH_387
13583 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13584 || TARGET_MIX_SSE_I387)
13585 && flag_unsafe_math_optimizations"
13586 "fcos"
13587 [(set_attr "type" "fpspc")
13588 (set_attr "mode" "XF")])
13589
13590 ;; When sincos pattern is defined, sin and cos builtin functions will be
13591 ;; expanded to sincos pattern with one of its outputs left unused.
13592 ;; CSE pass will figure out if two sincos patterns can be combined,
13593 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13594 ;; depending on the unused output.
13595
13596 (define_insn "sincosxf3"
13597 [(set (match_operand:XF 0 "register_operand" "=f")
13598 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13599 UNSPEC_SINCOS_COS))
13600 (set (match_operand:XF 1 "register_operand" "=u")
13601 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && flag_unsafe_math_optimizations"
13604 "fsincos"
13605 [(set_attr "type" "fpspc")
13606 (set_attr "mode" "XF")])
13607
13608 (define_split
13609 [(set (match_operand:XF 0 "register_operand" "")
13610 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13611 UNSPEC_SINCOS_COS))
13612 (set (match_operand:XF 1 "register_operand" "")
13613 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13614 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13615 && !(reload_completed || reload_in_progress)"
13616 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13617
13618 (define_split
13619 [(set (match_operand:XF 0 "register_operand" "")
13620 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13621 UNSPEC_SINCOS_COS))
13622 (set (match_operand:XF 1 "register_operand" "")
13623 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13624 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13625 && !(reload_completed || reload_in_progress)"
13626 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13627
13628 (define_insn "sincos_extend<mode>xf3_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(float_extend:XF
13631 (match_operand:MODEF 2 "register_operand" "0"))]
13632 UNSPEC_SINCOS_COS))
13633 (set (match_operand:XF 1 "register_operand" "=u")
13634 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637 || TARGET_MIX_SSE_I387)
13638 && flag_unsafe_math_optimizations"
13639 "fsincos"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13642
13643 (define_split
13644 [(set (match_operand:XF 0 "register_operand" "")
13645 (unspec:XF [(float_extend:XF
13646 (match_operand:MODEF 2 "register_operand" ""))]
13647 UNSPEC_SINCOS_COS))
13648 (set (match_operand:XF 1 "register_operand" "")
13649 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13650 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13651 && !(reload_completed || reload_in_progress)"
13652 [(set (match_dup 1)
13653 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13654
13655 (define_split
13656 [(set (match_operand:XF 0 "register_operand" "")
13657 (unspec:XF [(float_extend:XF
13658 (match_operand:MODEF 2 "register_operand" ""))]
13659 UNSPEC_SINCOS_COS))
13660 (set (match_operand:XF 1 "register_operand" "")
13661 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13662 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13663 && !(reload_completed || reload_in_progress)"
13664 [(set (match_dup 0)
13665 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13666
13667 (define_expand "sincos<mode>3"
13668 [(use (match_operand:MODEF 0 "register_operand" ""))
13669 (use (match_operand:MODEF 1 "register_operand" ""))
13670 (use (match_operand:MODEF 2 "register_operand" ""))]
13671 "TARGET_USE_FANCY_MATH_387
13672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13673 || TARGET_MIX_SSE_I387)
13674 && flag_unsafe_math_optimizations"
13675 {
13676 rtx op0 = gen_reg_rtx (XFmode);
13677 rtx op1 = gen_reg_rtx (XFmode);
13678
13679 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13680 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13682 DONE;
13683 })
13684
13685 (define_insn "fptanxf4_i387"
13686 [(set (match_operand:XF 0 "register_operand" "=f")
13687 (match_operand:XF 3 "const_double_operand" "F"))
13688 (set (match_operand:XF 1 "register_operand" "=u")
13689 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13690 UNSPEC_TAN))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && flag_unsafe_math_optimizations
13693 && standard_80387_constant_p (operands[3]) == 2"
13694 "fptan"
13695 [(set_attr "type" "fpspc")
13696 (set_attr "mode" "XF")])
13697
13698 (define_insn "fptan_extend<mode>xf4_i387"
13699 [(set (match_operand:MODEF 0 "register_operand" "=f")
13700 (match_operand:MODEF 3 "const_double_operand" "F"))
13701 (set (match_operand:XF 1 "register_operand" "=u")
13702 (unspec:XF [(float_extend:XF
13703 (match_operand:MODEF 2 "register_operand" "0"))]
13704 UNSPEC_TAN))]
13705 "TARGET_USE_FANCY_MATH_387
13706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13707 || TARGET_MIX_SSE_I387)
13708 && flag_unsafe_math_optimizations
13709 && standard_80387_constant_p (operands[3]) == 2"
13710 "fptan"
13711 [(set_attr "type" "fpspc")
13712 (set_attr "mode" "XF")])
13713
13714 (define_expand "tanxf2"
13715 [(use (match_operand:XF 0 "register_operand" ""))
13716 (use (match_operand:XF 1 "register_operand" ""))]
13717 "TARGET_USE_FANCY_MATH_387
13718 && flag_unsafe_math_optimizations"
13719 {
13720 rtx one = gen_reg_rtx (XFmode);
13721 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13722
13723 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13724 DONE;
13725 })
13726
13727 (define_expand "tan<mode>2"
13728 [(use (match_operand:MODEF 0 "register_operand" ""))
13729 (use (match_operand:MODEF 1 "register_operand" ""))]
13730 "TARGET_USE_FANCY_MATH_387
13731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13732 || TARGET_MIX_SSE_I387)
13733 && flag_unsafe_math_optimizations"
13734 {
13735 rtx op0 = gen_reg_rtx (XFmode);
13736
13737 rtx one = gen_reg_rtx (<MODE>mode);
13738 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13739
13740 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13741 operands[1], op2));
13742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13743 DONE;
13744 })
13745
13746 (define_insn "*fpatanxf3_i387"
13747 [(set (match_operand:XF 0 "register_operand" "=f")
13748 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13749 (match_operand:XF 2 "register_operand" "u")]
13750 UNSPEC_FPATAN))
13751 (clobber (match_scratch:XF 3 "=2"))]
13752 "TARGET_USE_FANCY_MATH_387
13753 && flag_unsafe_math_optimizations"
13754 "fpatan"
13755 [(set_attr "type" "fpspc")
13756 (set_attr "mode" "XF")])
13757
13758 (define_insn "fpatan_extend<mode>xf3_i387"
13759 [(set (match_operand:XF 0 "register_operand" "=f")
13760 (unspec:XF [(float_extend:XF
13761 (match_operand:MODEF 1 "register_operand" "0"))
13762 (float_extend:XF
13763 (match_operand:MODEF 2 "register_operand" "u"))]
13764 UNSPEC_FPATAN))
13765 (clobber (match_scratch:XF 3 "=2"))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768 || TARGET_MIX_SSE_I387)
13769 && flag_unsafe_math_optimizations"
13770 "fpatan"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13773
13774 (define_expand "atan2xf3"
13775 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13776 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13777 (match_operand:XF 1 "register_operand" "")]
13778 UNSPEC_FPATAN))
13779 (clobber (match_scratch:XF 3 ""))])]
13780 "TARGET_USE_FANCY_MATH_387
13781 && flag_unsafe_math_optimizations")
13782
13783 (define_expand "atan2<mode>3"
13784 [(use (match_operand:MODEF 0 "register_operand" ""))
13785 (use (match_operand:MODEF 1 "register_operand" ""))
13786 (use (match_operand:MODEF 2 "register_operand" ""))]
13787 "TARGET_USE_FANCY_MATH_387
13788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789 || TARGET_MIX_SSE_I387)
13790 && flag_unsafe_math_optimizations"
13791 {
13792 rtx op0 = gen_reg_rtx (XFmode);
13793
13794 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13796 DONE;
13797 })
13798
13799 (define_expand "atanxf2"
13800 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13801 (unspec:XF [(match_dup 2)
13802 (match_operand:XF 1 "register_operand" "")]
13803 UNSPEC_FPATAN))
13804 (clobber (match_scratch:XF 3 ""))])]
13805 "TARGET_USE_FANCY_MATH_387
13806 && flag_unsafe_math_optimizations"
13807 {
13808 operands[2] = gen_reg_rtx (XFmode);
13809 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13810 })
13811
13812 (define_expand "atan<mode>2"
13813 [(use (match_operand:MODEF 0 "register_operand" ""))
13814 (use (match_operand:MODEF 1 "register_operand" ""))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817 || TARGET_MIX_SSE_I387)
13818 && flag_unsafe_math_optimizations"
13819 {
13820 rtx op0 = gen_reg_rtx (XFmode);
13821
13822 rtx op2 = gen_reg_rtx (<MODE>mode);
13823 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13824
13825 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13826 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13827 DONE;
13828 })
13829
13830 (define_expand "asinxf2"
13831 [(set (match_dup 2)
13832 (mult:XF (match_operand:XF 1 "register_operand" "")
13833 (match_dup 1)))
13834 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13835 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13836 (parallel [(set (match_operand:XF 0 "register_operand" "")
13837 (unspec:XF [(match_dup 5) (match_dup 1)]
13838 UNSPEC_FPATAN))
13839 (clobber (match_scratch:XF 6 ""))])]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations"
13842 {
13843 int i;
13844
13845 if (optimize_insn_for_size_p ())
13846 FAIL;
13847
13848 for (i = 2; i < 6; i++)
13849 operands[i] = gen_reg_rtx (XFmode);
13850
13851 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13852 })
13853
13854 (define_expand "asin<mode>2"
13855 [(use (match_operand:MODEF 0 "register_operand" ""))
13856 (use (match_operand:MODEF 1 "general_operand" ""))]
13857 "TARGET_USE_FANCY_MATH_387
13858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13859 || TARGET_MIX_SSE_I387)
13860 && flag_unsafe_math_optimizations"
13861 {
13862 rtx op0 = gen_reg_rtx (XFmode);
13863 rtx op1 = gen_reg_rtx (XFmode);
13864
13865 if (optimize_insn_for_size_p ())
13866 FAIL;
13867
13868 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13869 emit_insn (gen_asinxf2 (op0, op1));
13870 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13871 DONE;
13872 })
13873
13874 (define_expand "acosxf2"
13875 [(set (match_dup 2)
13876 (mult:XF (match_operand:XF 1 "register_operand" "")
13877 (match_dup 1)))
13878 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13879 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13880 (parallel [(set (match_operand:XF 0 "register_operand" "")
13881 (unspec:XF [(match_dup 1) (match_dup 5)]
13882 UNSPEC_FPATAN))
13883 (clobber (match_scratch:XF 6 ""))])]
13884 "TARGET_USE_FANCY_MATH_387
13885 && flag_unsafe_math_optimizations"
13886 {
13887 int i;
13888
13889 if (optimize_insn_for_size_p ())
13890 FAIL;
13891
13892 for (i = 2; i < 6; i++)
13893 operands[i] = gen_reg_rtx (XFmode);
13894
13895 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13896 })
13897
13898 (define_expand "acos<mode>2"
13899 [(use (match_operand:MODEF 0 "register_operand" ""))
13900 (use (match_operand:MODEF 1 "general_operand" ""))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903 || TARGET_MIX_SSE_I387)
13904 && flag_unsafe_math_optimizations"
13905 {
13906 rtx op0 = gen_reg_rtx (XFmode);
13907 rtx op1 = gen_reg_rtx (XFmode);
13908
13909 if (optimize_insn_for_size_p ())
13910 FAIL;
13911
13912 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13913 emit_insn (gen_acosxf2 (op0, op1));
13914 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13915 DONE;
13916 })
13917
13918 (define_insn "fyl2xxf3_i387"
13919 [(set (match_operand:XF 0 "register_operand" "=f")
13920 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13921 (match_operand:XF 2 "register_operand" "u")]
13922 UNSPEC_FYL2X))
13923 (clobber (match_scratch:XF 3 "=2"))]
13924 "TARGET_USE_FANCY_MATH_387
13925 && flag_unsafe_math_optimizations"
13926 "fyl2x"
13927 [(set_attr "type" "fpspc")
13928 (set_attr "mode" "XF")])
13929
13930 (define_insn "fyl2x_extend<mode>xf3_i387"
13931 [(set (match_operand:XF 0 "register_operand" "=f")
13932 (unspec:XF [(float_extend:XF
13933 (match_operand:MODEF 1 "register_operand" "0"))
13934 (match_operand:XF 2 "register_operand" "u")]
13935 UNSPEC_FYL2X))
13936 (clobber (match_scratch:XF 3 "=2"))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13939 || TARGET_MIX_SSE_I387)
13940 && flag_unsafe_math_optimizations"
13941 "fyl2x"
13942 [(set_attr "type" "fpspc")
13943 (set_attr "mode" "XF")])
13944
13945 (define_expand "logxf2"
13946 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13947 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13948 (match_dup 2)] UNSPEC_FYL2X))
13949 (clobber (match_scratch:XF 3 ""))])]
13950 "TARGET_USE_FANCY_MATH_387
13951 && flag_unsafe_math_optimizations"
13952 {
13953 operands[2] = gen_reg_rtx (XFmode);
13954 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13955 })
13956
13957 (define_expand "log<mode>2"
13958 [(use (match_operand:MODEF 0 "register_operand" ""))
13959 (use (match_operand:MODEF 1 "register_operand" ""))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13962 || TARGET_MIX_SSE_I387)
13963 && flag_unsafe_math_optimizations"
13964 {
13965 rtx op0 = gen_reg_rtx (XFmode);
13966
13967 rtx op2 = gen_reg_rtx (XFmode);
13968 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13969
13970 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13971 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13972 DONE;
13973 })
13974
13975 (define_expand "log10xf2"
13976 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13977 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13978 (match_dup 2)] UNSPEC_FYL2X))
13979 (clobber (match_scratch:XF 3 ""))])]
13980 "TARGET_USE_FANCY_MATH_387
13981 && flag_unsafe_math_optimizations"
13982 {
13983 operands[2] = gen_reg_rtx (XFmode);
13984 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13985 })
13986
13987 (define_expand "log10<mode>2"
13988 [(use (match_operand:MODEF 0 "register_operand" ""))
13989 (use (match_operand:MODEF 1 "register_operand" ""))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13992 || TARGET_MIX_SSE_I387)
13993 && flag_unsafe_math_optimizations"
13994 {
13995 rtx op0 = gen_reg_rtx (XFmode);
13996
13997 rtx op2 = gen_reg_rtx (XFmode);
13998 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13999
14000 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14001 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14002 DONE;
14003 })
14004
14005 (define_expand "log2xf2"
14006 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14007 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14008 (match_dup 2)] UNSPEC_FYL2X))
14009 (clobber (match_scratch:XF 3 ""))])]
14010 "TARGET_USE_FANCY_MATH_387
14011 && flag_unsafe_math_optimizations"
14012 {
14013 operands[2] = gen_reg_rtx (XFmode);
14014 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14015 })
14016
14017 (define_expand "log2<mode>2"
14018 [(use (match_operand:MODEF 0 "register_operand" ""))
14019 (use (match_operand:MODEF 1 "register_operand" ""))]
14020 "TARGET_USE_FANCY_MATH_387
14021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14022 || TARGET_MIX_SSE_I387)
14023 && flag_unsafe_math_optimizations"
14024 {
14025 rtx op0 = gen_reg_rtx (XFmode);
14026
14027 rtx op2 = gen_reg_rtx (XFmode);
14028 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14029
14030 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14031 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14032 DONE;
14033 })
14034
14035 (define_insn "fyl2xp1xf3_i387"
14036 [(set (match_operand:XF 0 "register_operand" "=f")
14037 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14038 (match_operand:XF 2 "register_operand" "u")]
14039 UNSPEC_FYL2XP1))
14040 (clobber (match_scratch:XF 3 "=2"))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14043 "fyl2xp1"
14044 [(set_attr "type" "fpspc")
14045 (set_attr "mode" "XF")])
14046
14047 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14048 [(set (match_operand:XF 0 "register_operand" "=f")
14049 (unspec:XF [(float_extend:XF
14050 (match_operand:MODEF 1 "register_operand" "0"))
14051 (match_operand:XF 2 "register_operand" "u")]
14052 UNSPEC_FYL2XP1))
14053 (clobber (match_scratch:XF 3 "=2"))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14058 "fyl2xp1"
14059 [(set_attr "type" "fpspc")
14060 (set_attr "mode" "XF")])
14061
14062 (define_expand "log1pxf2"
14063 [(use (match_operand:XF 0 "register_operand" ""))
14064 (use (match_operand:XF 1 "register_operand" ""))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && flag_unsafe_math_optimizations"
14067 {
14068 if (optimize_insn_for_size_p ())
14069 FAIL;
14070
14071 ix86_emit_i387_log1p (operands[0], operands[1]);
14072 DONE;
14073 })
14074
14075 (define_expand "log1p<mode>2"
14076 [(use (match_operand:MODEF 0 "register_operand" ""))
14077 (use (match_operand:MODEF 1 "register_operand" ""))]
14078 "TARGET_USE_FANCY_MATH_387
14079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14080 || TARGET_MIX_SSE_I387)
14081 && flag_unsafe_math_optimizations"
14082 {
14083 rtx op0;
14084
14085 if (optimize_insn_for_size_p ())
14086 FAIL;
14087
14088 op0 = gen_reg_rtx (XFmode);
14089
14090 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14091
14092 ix86_emit_i387_log1p (op0, operands[1]);
14093 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14094 DONE;
14095 })
14096
14097 (define_insn "fxtractxf3_i387"
14098 [(set (match_operand:XF 0 "register_operand" "=f")
14099 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14100 UNSPEC_XTRACT_FRACT))
14101 (set (match_operand:XF 1 "register_operand" "=u")
14102 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && flag_unsafe_math_optimizations"
14105 "fxtract"
14106 [(set_attr "type" "fpspc")
14107 (set_attr "mode" "XF")])
14108
14109 (define_insn "fxtract_extend<mode>xf3_i387"
14110 [(set (match_operand:XF 0 "register_operand" "=f")
14111 (unspec:XF [(float_extend:XF
14112 (match_operand:MODEF 2 "register_operand" "0"))]
14113 UNSPEC_XTRACT_FRACT))
14114 (set (match_operand:XF 1 "register_operand" "=u")
14115 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations"
14120 "fxtract"
14121 [(set_attr "type" "fpspc")
14122 (set_attr "mode" "XF")])
14123
14124 (define_expand "logbxf2"
14125 [(parallel [(set (match_dup 2)
14126 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14127 UNSPEC_XTRACT_FRACT))
14128 (set (match_operand:XF 0 "register_operand" "")
14129 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14130 "TARGET_USE_FANCY_MATH_387
14131 && flag_unsafe_math_optimizations"
14132 "operands[2] = gen_reg_rtx (XFmode);")
14133
14134 (define_expand "logb<mode>2"
14135 [(use (match_operand:MODEF 0 "register_operand" ""))
14136 (use (match_operand:MODEF 1 "register_operand" ""))]
14137 "TARGET_USE_FANCY_MATH_387
14138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14139 || TARGET_MIX_SSE_I387)
14140 && flag_unsafe_math_optimizations"
14141 {
14142 rtx op0 = gen_reg_rtx (XFmode);
14143 rtx op1 = gen_reg_rtx (XFmode);
14144
14145 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14147 DONE;
14148 })
14149
14150 (define_expand "ilogbxf2"
14151 [(use (match_operand:SI 0 "register_operand" ""))
14152 (use (match_operand:XF 1 "register_operand" ""))]
14153 "TARGET_USE_FANCY_MATH_387
14154 && flag_unsafe_math_optimizations"
14155 {
14156 rtx op0, op1;
14157
14158 if (optimize_insn_for_size_p ())
14159 FAIL;
14160
14161 op0 = gen_reg_rtx (XFmode);
14162 op1 = gen_reg_rtx (XFmode);
14163
14164 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14165 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14166 DONE;
14167 })
14168
14169 (define_expand "ilogb<mode>2"
14170 [(use (match_operand:SI 0 "register_operand" ""))
14171 (use (match_operand:MODEF 1 "register_operand" ""))]
14172 "TARGET_USE_FANCY_MATH_387
14173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14174 || TARGET_MIX_SSE_I387)
14175 && flag_unsafe_math_optimizations"
14176 {
14177 rtx op0, op1;
14178
14179 if (optimize_insn_for_size_p ())
14180 FAIL;
14181
14182 op0 = gen_reg_rtx (XFmode);
14183 op1 = gen_reg_rtx (XFmode);
14184
14185 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14186 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14187 DONE;
14188 })
14189
14190 (define_insn "*f2xm1xf2_i387"
14191 [(set (match_operand:XF 0 "register_operand" "=f")
14192 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14193 UNSPEC_F2XM1))]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14196 "f2xm1"
14197 [(set_attr "type" "fpspc")
14198 (set_attr "mode" "XF")])
14199
14200 (define_insn "*fscalexf4_i387"
14201 [(set (match_operand:XF 0 "register_operand" "=f")
14202 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14203 (match_operand:XF 3 "register_operand" "1")]
14204 UNSPEC_FSCALE_FRACT))
14205 (set (match_operand:XF 1 "register_operand" "=u")
14206 (unspec:XF [(match_dup 2) (match_dup 3)]
14207 UNSPEC_FSCALE_EXP))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14210 "fscale"
14211 [(set_attr "type" "fpspc")
14212 (set_attr "mode" "XF")])
14213
14214 (define_expand "expNcorexf3"
14215 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14216 (match_operand:XF 2 "register_operand" "")))
14217 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14218 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14219 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14220 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14221 (parallel [(set (match_operand:XF 0 "register_operand" "")
14222 (unspec:XF [(match_dup 8) (match_dup 4)]
14223 UNSPEC_FSCALE_FRACT))
14224 (set (match_dup 9)
14225 (unspec:XF [(match_dup 8) (match_dup 4)]
14226 UNSPEC_FSCALE_EXP))])]
14227 "TARGET_USE_FANCY_MATH_387
14228 && flag_unsafe_math_optimizations"
14229 {
14230 int i;
14231
14232 if (optimize_insn_for_size_p ())
14233 FAIL;
14234
14235 for (i = 3; i < 10; i++)
14236 operands[i] = gen_reg_rtx (XFmode);
14237
14238 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14239 })
14240
14241 (define_expand "expxf2"
14242 [(use (match_operand:XF 0 "register_operand" ""))
14243 (use (match_operand:XF 1 "register_operand" ""))]
14244 "TARGET_USE_FANCY_MATH_387
14245 && flag_unsafe_math_optimizations"
14246 {
14247 rtx op2;
14248
14249 if (optimize_insn_for_size_p ())
14250 FAIL;
14251
14252 op2 = gen_reg_rtx (XFmode);
14253 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14254
14255 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14256 DONE;
14257 })
14258
14259 (define_expand "exp<mode>2"
14260 [(use (match_operand:MODEF 0 "register_operand" ""))
14261 (use (match_operand:MODEF 1 "general_operand" ""))]
14262 "TARGET_USE_FANCY_MATH_387
14263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264 || TARGET_MIX_SSE_I387)
14265 && flag_unsafe_math_optimizations"
14266 {
14267 rtx op0, op1;
14268
14269 if (optimize_insn_for_size_p ())
14270 FAIL;
14271
14272 op0 = gen_reg_rtx (XFmode);
14273 op1 = gen_reg_rtx (XFmode);
14274
14275 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14276 emit_insn (gen_expxf2 (op0, op1));
14277 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14278 DONE;
14279 })
14280
14281 (define_expand "exp10xf2"
14282 [(use (match_operand:XF 0 "register_operand" ""))
14283 (use (match_operand:XF 1 "register_operand" ""))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && flag_unsafe_math_optimizations"
14286 {
14287 rtx op2;
14288
14289 if (optimize_insn_for_size_p ())
14290 FAIL;
14291
14292 op2 = gen_reg_rtx (XFmode);
14293 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14294
14295 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14296 DONE;
14297 })
14298
14299 (define_expand "exp10<mode>2"
14300 [(use (match_operand:MODEF 0 "register_operand" ""))
14301 (use (match_operand:MODEF 1 "general_operand" ""))]
14302 "TARGET_USE_FANCY_MATH_387
14303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14304 || TARGET_MIX_SSE_I387)
14305 && flag_unsafe_math_optimizations"
14306 {
14307 rtx op0, op1;
14308
14309 if (optimize_insn_for_size_p ())
14310 FAIL;
14311
14312 op0 = gen_reg_rtx (XFmode);
14313 op1 = gen_reg_rtx (XFmode);
14314
14315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14316 emit_insn (gen_exp10xf2 (op0, op1));
14317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14318 DONE;
14319 })
14320
14321 (define_expand "exp2xf2"
14322 [(use (match_operand:XF 0 "register_operand" ""))
14323 (use (match_operand:XF 1 "register_operand" ""))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && flag_unsafe_math_optimizations"
14326 {
14327 rtx op2;
14328
14329 if (optimize_insn_for_size_p ())
14330 FAIL;
14331
14332 op2 = gen_reg_rtx (XFmode);
14333 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14334
14335 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14336 DONE;
14337 })
14338
14339 (define_expand "exp2<mode>2"
14340 [(use (match_operand:MODEF 0 "register_operand" ""))
14341 (use (match_operand:MODEF 1 "general_operand" ""))]
14342 "TARGET_USE_FANCY_MATH_387
14343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14344 || TARGET_MIX_SSE_I387)
14345 && flag_unsafe_math_optimizations"
14346 {
14347 rtx op0, op1;
14348
14349 if (optimize_insn_for_size_p ())
14350 FAIL;
14351
14352 op0 = gen_reg_rtx (XFmode);
14353 op1 = gen_reg_rtx (XFmode);
14354
14355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14356 emit_insn (gen_exp2xf2 (op0, op1));
14357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14358 DONE;
14359 })
14360
14361 (define_expand "expm1xf2"
14362 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14363 (match_dup 2)))
14364 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14365 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14366 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14367 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14368 (parallel [(set (match_dup 7)
14369 (unspec:XF [(match_dup 6) (match_dup 4)]
14370 UNSPEC_FSCALE_FRACT))
14371 (set (match_dup 8)
14372 (unspec:XF [(match_dup 6) (match_dup 4)]
14373 UNSPEC_FSCALE_EXP))])
14374 (parallel [(set (match_dup 10)
14375 (unspec:XF [(match_dup 9) (match_dup 8)]
14376 UNSPEC_FSCALE_FRACT))
14377 (set (match_dup 11)
14378 (unspec:XF [(match_dup 9) (match_dup 8)]
14379 UNSPEC_FSCALE_EXP))])
14380 (set (match_dup 12) (minus:XF (match_dup 10)
14381 (float_extend:XF (match_dup 13))))
14382 (set (match_operand:XF 0 "register_operand" "")
14383 (plus:XF (match_dup 12) (match_dup 7)))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14386 {
14387 int i;
14388
14389 if (optimize_insn_for_size_p ())
14390 FAIL;
14391
14392 for (i = 2; i < 13; i++)
14393 operands[i] = gen_reg_rtx (XFmode);
14394
14395 operands[13]
14396 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14397
14398 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14399 })
14400
14401 (define_expand "expm1<mode>2"
14402 [(use (match_operand:MODEF 0 "register_operand" ""))
14403 (use (match_operand:MODEF 1 "general_operand" ""))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14406 || TARGET_MIX_SSE_I387)
14407 && flag_unsafe_math_optimizations"
14408 {
14409 rtx op0, op1;
14410
14411 if (optimize_insn_for_size_p ())
14412 FAIL;
14413
14414 op0 = gen_reg_rtx (XFmode);
14415 op1 = gen_reg_rtx (XFmode);
14416
14417 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14418 emit_insn (gen_expm1xf2 (op0, op1));
14419 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14420 DONE;
14421 })
14422
14423 (define_expand "ldexpxf3"
14424 [(set (match_dup 3)
14425 (float:XF (match_operand:SI 2 "register_operand" "")))
14426 (parallel [(set (match_operand:XF 0 " register_operand" "")
14427 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14428 (match_dup 3)]
14429 UNSPEC_FSCALE_FRACT))
14430 (set (match_dup 4)
14431 (unspec:XF [(match_dup 1) (match_dup 3)]
14432 UNSPEC_FSCALE_EXP))])]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_unsafe_math_optimizations"
14435 {
14436 if (optimize_insn_for_size_p ())
14437 FAIL;
14438
14439 operands[3] = gen_reg_rtx (XFmode);
14440 operands[4] = gen_reg_rtx (XFmode);
14441 })
14442
14443 (define_expand "ldexp<mode>3"
14444 [(use (match_operand:MODEF 0 "register_operand" ""))
14445 (use (match_operand:MODEF 1 "general_operand" ""))
14446 (use (match_operand:SI 2 "register_operand" ""))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449 || TARGET_MIX_SSE_I387)
14450 && flag_unsafe_math_optimizations"
14451 {
14452 rtx op0, op1;
14453
14454 if (optimize_insn_for_size_p ())
14455 FAIL;
14456
14457 op0 = gen_reg_rtx (XFmode);
14458 op1 = gen_reg_rtx (XFmode);
14459
14460 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14461 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14462 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14463 DONE;
14464 })
14465
14466 (define_expand "scalbxf3"
14467 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14468 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14469 (match_operand:XF 2 "register_operand" "")]
14470 UNSPEC_FSCALE_FRACT))
14471 (set (match_dup 3)
14472 (unspec:XF [(match_dup 1) (match_dup 2)]
14473 UNSPEC_FSCALE_EXP))])]
14474 "TARGET_USE_FANCY_MATH_387
14475 && flag_unsafe_math_optimizations"
14476 {
14477 if (optimize_insn_for_size_p ())
14478 FAIL;
14479
14480 operands[3] = gen_reg_rtx (XFmode);
14481 })
14482
14483 (define_expand "scalb<mode>3"
14484 [(use (match_operand:MODEF 0 "register_operand" ""))
14485 (use (match_operand:MODEF 1 "general_operand" ""))
14486 (use (match_operand:MODEF 2 "general_operand" ""))]
14487 "TARGET_USE_FANCY_MATH_387
14488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14489 || TARGET_MIX_SSE_I387)
14490 && flag_unsafe_math_optimizations"
14491 {
14492 rtx op0, op1, op2;
14493
14494 if (optimize_insn_for_size_p ())
14495 FAIL;
14496
14497 op0 = gen_reg_rtx (XFmode);
14498 op1 = gen_reg_rtx (XFmode);
14499 op2 = gen_reg_rtx (XFmode);
14500
14501 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14502 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14503 emit_insn (gen_scalbxf3 (op0, op1, op2));
14504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14505 DONE;
14506 })
14507
14508 (define_expand "significandxf2"
14509 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14510 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14511 UNSPEC_XTRACT_FRACT))
14512 (set (match_dup 2)
14513 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14514 "TARGET_USE_FANCY_MATH_387
14515 && flag_unsafe_math_optimizations"
14516 "operands[2] = gen_reg_rtx (XFmode);")
14517
14518 (define_expand "significand<mode>2"
14519 [(use (match_operand:MODEF 0 "register_operand" ""))
14520 (use (match_operand:MODEF 1 "register_operand" ""))]
14521 "TARGET_USE_FANCY_MATH_387
14522 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14523 || TARGET_MIX_SSE_I387)
14524 && flag_unsafe_math_optimizations"
14525 {
14526 rtx op0 = gen_reg_rtx (XFmode);
14527 rtx op1 = gen_reg_rtx (XFmode);
14528
14529 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14530 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14531 DONE;
14532 })
14533 \f
14534
14535 (define_insn "sse4_1_round<mode>2"
14536 [(set (match_operand:MODEF 0 "register_operand" "=x")
14537 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14538 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14539 UNSPEC_ROUND))]
14540 "TARGET_ROUND"
14541 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14542 [(set_attr "type" "ssecvt")
14543 (set_attr "prefix_extra" "1")
14544 (set_attr "prefix" "maybe_vex")
14545 (set_attr "mode" "<MODE>")])
14546
14547 (define_insn "rintxf2"
14548 [(set (match_operand:XF 0 "register_operand" "=f")
14549 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14550 UNSPEC_FRNDINT))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14553 "frndint"
14554 [(set_attr "type" "fpspc")
14555 (set_attr "mode" "XF")])
14556
14557 (define_expand "rint<mode>2"
14558 [(use (match_operand:MODEF 0 "register_operand" ""))
14559 (use (match_operand:MODEF 1 "register_operand" ""))]
14560 "(TARGET_USE_FANCY_MATH_387
14561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14562 || TARGET_MIX_SSE_I387)
14563 && flag_unsafe_math_optimizations)
14564 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14565 && !flag_trapping_math)"
14566 {
14567 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14568 && !flag_trapping_math)
14569 {
14570 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14571 FAIL;
14572 if (TARGET_ROUND)
14573 emit_insn (gen_sse4_1_round<mode>2
14574 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14575 else
14576 ix86_expand_rint (operand0, operand1);
14577 }
14578 else
14579 {
14580 rtx op0 = gen_reg_rtx (XFmode);
14581 rtx op1 = gen_reg_rtx (XFmode);
14582
14583 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14584 emit_insn (gen_rintxf2 (op0, op1));
14585
14586 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14587 }
14588 DONE;
14589 })
14590
14591 (define_expand "round<mode>2"
14592 [(match_operand:MODEF 0 "register_operand" "")
14593 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14594 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14595 && !flag_trapping_math && !flag_rounding_math"
14596 {
14597 if (optimize_insn_for_size_p ())
14598 FAIL;
14599 if (TARGET_64BIT || (<MODE>mode != DFmode))
14600 ix86_expand_round (operand0, operand1);
14601 else
14602 ix86_expand_rounddf_32 (operand0, operand1);
14603 DONE;
14604 })
14605
14606 (define_insn_and_split "*fistdi2_1"
14607 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14608 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14609 UNSPEC_FIST))]
14610 "TARGET_USE_FANCY_MATH_387
14611 && can_create_pseudo_p ()"
14612 "#"
14613 "&& 1"
14614 [(const_int 0)]
14615 {
14616 if (memory_operand (operands[0], VOIDmode))
14617 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14618 else
14619 {
14620 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14621 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14622 operands[2]));
14623 }
14624 DONE;
14625 }
14626 [(set_attr "type" "fpspc")
14627 (set_attr "mode" "DI")])
14628
14629 (define_insn "fistdi2"
14630 [(set (match_operand:DI 0 "memory_operand" "=m")
14631 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14632 UNSPEC_FIST))
14633 (clobber (match_scratch:XF 2 "=&1f"))]
14634 "TARGET_USE_FANCY_MATH_387"
14635 "* return output_fix_trunc (insn, operands, 0);"
14636 [(set_attr "type" "fpspc")
14637 (set_attr "mode" "DI")])
14638
14639 (define_insn "fistdi2_with_temp"
14640 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14641 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14642 UNSPEC_FIST))
14643 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14644 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14645 "TARGET_USE_FANCY_MATH_387"
14646 "#"
14647 [(set_attr "type" "fpspc")
14648 (set_attr "mode" "DI")])
14649
14650 (define_split
14651 [(set (match_operand:DI 0 "register_operand" "")
14652 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14653 UNSPEC_FIST))
14654 (clobber (match_operand:DI 2 "memory_operand" ""))
14655 (clobber (match_scratch 3 ""))]
14656 "reload_completed"
14657 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14658 (clobber (match_dup 3))])
14659 (set (match_dup 0) (match_dup 2))])
14660
14661 (define_split
14662 [(set (match_operand:DI 0 "memory_operand" "")
14663 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14664 UNSPEC_FIST))
14665 (clobber (match_operand:DI 2 "memory_operand" ""))
14666 (clobber (match_scratch 3 ""))]
14667 "reload_completed"
14668 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14669 (clobber (match_dup 3))])])
14670
14671 (define_insn_and_split "*fist<mode>2_1"
14672 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14673 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14674 UNSPEC_FIST))]
14675 "TARGET_USE_FANCY_MATH_387
14676 && can_create_pseudo_p ()"
14677 "#"
14678 "&& 1"
14679 [(const_int 0)]
14680 {
14681 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14682 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14683 operands[2]));
14684 DONE;
14685 }
14686 [(set_attr "type" "fpspc")
14687 (set_attr "mode" "<MODE>")])
14688
14689 (define_insn "fist<mode>2"
14690 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14691 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14692 UNSPEC_FIST))]
14693 "TARGET_USE_FANCY_MATH_387"
14694 "* return output_fix_trunc (insn, operands, 0);"
14695 [(set_attr "type" "fpspc")
14696 (set_attr "mode" "<MODE>")])
14697
14698 (define_insn "fist<mode>2_with_temp"
14699 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14700 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14701 UNSPEC_FIST))
14702 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14703 "TARGET_USE_FANCY_MATH_387"
14704 "#"
14705 [(set_attr "type" "fpspc")
14706 (set_attr "mode" "<MODE>")])
14707
14708 (define_split
14709 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14710 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14711 UNSPEC_FIST))
14712 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14713 "reload_completed"
14714 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14715 (set (match_dup 0) (match_dup 2))])
14716
14717 (define_split
14718 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14719 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14720 UNSPEC_FIST))
14721 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14722 "reload_completed"
14723 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14724
14725 (define_expand "lrintxf<mode>2"
14726 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14727 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14728 UNSPEC_FIST))]
14729 "TARGET_USE_FANCY_MATH_387")
14730
14731 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14732 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14733 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14734 UNSPEC_FIX_NOTRUNC))]
14735 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14736 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14737
14738 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14739 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14740 (match_operand:MODEF 1 "register_operand" "")]
14741 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14742 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14743 && !flag_trapping_math && !flag_rounding_math"
14744 {
14745 if (optimize_insn_for_size_p ())
14746 FAIL;
14747 ix86_expand_lround (operand0, operand1);
14748 DONE;
14749 })
14750
14751 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14752 (define_insn_and_split "frndintxf2_floor"
14753 [(set (match_operand:XF 0 "register_operand" "")
14754 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14755 UNSPEC_FRNDINT_FLOOR))
14756 (clobber (reg:CC FLAGS_REG))]
14757 "TARGET_USE_FANCY_MATH_387
14758 && flag_unsafe_math_optimizations
14759 && can_create_pseudo_p ()"
14760 "#"
14761 "&& 1"
14762 [(const_int 0)]
14763 {
14764 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14765
14766 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14767 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14768
14769 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14770 operands[2], operands[3]));
14771 DONE;
14772 }
14773 [(set_attr "type" "frndint")
14774 (set_attr "i387_cw" "floor")
14775 (set_attr "mode" "XF")])
14776
14777 (define_insn "frndintxf2_floor_i387"
14778 [(set (match_operand:XF 0 "register_operand" "=f")
14779 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14780 UNSPEC_FRNDINT_FLOOR))
14781 (use (match_operand:HI 2 "memory_operand" "m"))
14782 (use (match_operand:HI 3 "memory_operand" "m"))]
14783 "TARGET_USE_FANCY_MATH_387
14784 && flag_unsafe_math_optimizations"
14785 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14786 [(set_attr "type" "frndint")
14787 (set_attr "i387_cw" "floor")
14788 (set_attr "mode" "XF")])
14789
14790 (define_expand "floorxf2"
14791 [(use (match_operand:XF 0 "register_operand" ""))
14792 (use (match_operand:XF 1 "register_operand" ""))]
14793 "TARGET_USE_FANCY_MATH_387
14794 && flag_unsafe_math_optimizations"
14795 {
14796 if (optimize_insn_for_size_p ())
14797 FAIL;
14798 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14799 DONE;
14800 })
14801
14802 (define_expand "floor<mode>2"
14803 [(use (match_operand:MODEF 0 "register_operand" ""))
14804 (use (match_operand:MODEF 1 "register_operand" ""))]
14805 "(TARGET_USE_FANCY_MATH_387
14806 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14807 || TARGET_MIX_SSE_I387)
14808 && flag_unsafe_math_optimizations)
14809 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14810 && !flag_trapping_math)"
14811 {
14812 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14813 && !flag_trapping_math
14814 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14815 {
14816 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14817 FAIL;
14818 if (TARGET_ROUND)
14819 emit_insn (gen_sse4_1_round<mode>2
14820 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14821 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14822 ix86_expand_floorceil (operand0, operand1, true);
14823 else
14824 ix86_expand_floorceildf_32 (operand0, operand1, true);
14825 }
14826 else
14827 {
14828 rtx op0, op1;
14829
14830 if (optimize_insn_for_size_p ())
14831 FAIL;
14832
14833 op0 = gen_reg_rtx (XFmode);
14834 op1 = gen_reg_rtx (XFmode);
14835 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14836 emit_insn (gen_frndintxf2_floor (op0, op1));
14837
14838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14839 }
14840 DONE;
14841 })
14842
14843 (define_insn_and_split "*fist<mode>2_floor_1"
14844 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14845 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14846 UNSPEC_FIST_FLOOR))
14847 (clobber (reg:CC FLAGS_REG))]
14848 "TARGET_USE_FANCY_MATH_387
14849 && flag_unsafe_math_optimizations
14850 && can_create_pseudo_p ()"
14851 "#"
14852 "&& 1"
14853 [(const_int 0)]
14854 {
14855 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14856
14857 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14858 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14859 if (memory_operand (operands[0], VOIDmode))
14860 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14861 operands[2], operands[3]));
14862 else
14863 {
14864 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14865 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14866 operands[2], operands[3],
14867 operands[4]));
14868 }
14869 DONE;
14870 }
14871 [(set_attr "type" "fistp")
14872 (set_attr "i387_cw" "floor")
14873 (set_attr "mode" "<MODE>")])
14874
14875 (define_insn "fistdi2_floor"
14876 [(set (match_operand:DI 0 "memory_operand" "=m")
14877 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14878 UNSPEC_FIST_FLOOR))
14879 (use (match_operand:HI 2 "memory_operand" "m"))
14880 (use (match_operand:HI 3 "memory_operand" "m"))
14881 (clobber (match_scratch:XF 4 "=&1f"))]
14882 "TARGET_USE_FANCY_MATH_387
14883 && flag_unsafe_math_optimizations"
14884 "* return output_fix_trunc (insn, operands, 0);"
14885 [(set_attr "type" "fistp")
14886 (set_attr "i387_cw" "floor")
14887 (set_attr "mode" "DI")])
14888
14889 (define_insn "fistdi2_floor_with_temp"
14890 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14891 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14892 UNSPEC_FIST_FLOOR))
14893 (use (match_operand:HI 2 "memory_operand" "m,m"))
14894 (use (match_operand:HI 3 "memory_operand" "m,m"))
14895 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14896 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14897 "TARGET_USE_FANCY_MATH_387
14898 && flag_unsafe_math_optimizations"
14899 "#"
14900 [(set_attr "type" "fistp")
14901 (set_attr "i387_cw" "floor")
14902 (set_attr "mode" "DI")])
14903
14904 (define_split
14905 [(set (match_operand:DI 0 "register_operand" "")
14906 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14907 UNSPEC_FIST_FLOOR))
14908 (use (match_operand:HI 2 "memory_operand" ""))
14909 (use (match_operand:HI 3 "memory_operand" ""))
14910 (clobber (match_operand:DI 4 "memory_operand" ""))
14911 (clobber (match_scratch 5 ""))]
14912 "reload_completed"
14913 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14914 (use (match_dup 2))
14915 (use (match_dup 3))
14916 (clobber (match_dup 5))])
14917 (set (match_dup 0) (match_dup 4))])
14918
14919 (define_split
14920 [(set (match_operand:DI 0 "memory_operand" "")
14921 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14922 UNSPEC_FIST_FLOOR))
14923 (use (match_operand:HI 2 "memory_operand" ""))
14924 (use (match_operand:HI 3 "memory_operand" ""))
14925 (clobber (match_operand:DI 4 "memory_operand" ""))
14926 (clobber (match_scratch 5 ""))]
14927 "reload_completed"
14928 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14929 (use (match_dup 2))
14930 (use (match_dup 3))
14931 (clobber (match_dup 5))])])
14932
14933 (define_insn "fist<mode>2_floor"
14934 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14935 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14936 UNSPEC_FIST_FLOOR))
14937 (use (match_operand:HI 2 "memory_operand" "m"))
14938 (use (match_operand:HI 3 "memory_operand" "m"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations"
14941 "* return output_fix_trunc (insn, operands, 0);"
14942 [(set_attr "type" "fistp")
14943 (set_attr "i387_cw" "floor")
14944 (set_attr "mode" "<MODE>")])
14945
14946 (define_insn "fist<mode>2_floor_with_temp"
14947 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14948 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14949 UNSPEC_FIST_FLOOR))
14950 (use (match_operand:HI 2 "memory_operand" "m,m"))
14951 (use (match_operand:HI 3 "memory_operand" "m,m"))
14952 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14955 "#"
14956 [(set_attr "type" "fistp")
14957 (set_attr "i387_cw" "floor")
14958 (set_attr "mode" "<MODE>")])
14959
14960 (define_split
14961 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14962 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14963 UNSPEC_FIST_FLOOR))
14964 (use (match_operand:HI 2 "memory_operand" ""))
14965 (use (match_operand:HI 3 "memory_operand" ""))
14966 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14967 "reload_completed"
14968 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14969 UNSPEC_FIST_FLOOR))
14970 (use (match_dup 2))
14971 (use (match_dup 3))])
14972 (set (match_dup 0) (match_dup 4))])
14973
14974 (define_split
14975 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14976 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14977 UNSPEC_FIST_FLOOR))
14978 (use (match_operand:HI 2 "memory_operand" ""))
14979 (use (match_operand:HI 3 "memory_operand" ""))
14980 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14981 "reload_completed"
14982 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14983 UNSPEC_FIST_FLOOR))
14984 (use (match_dup 2))
14985 (use (match_dup 3))])])
14986
14987 (define_expand "lfloorxf<mode>2"
14988 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14989 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14990 UNSPEC_FIST_FLOOR))
14991 (clobber (reg:CC FLAGS_REG))])]
14992 "TARGET_USE_FANCY_MATH_387
14993 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14994 && flag_unsafe_math_optimizations")
14995
14996 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14997 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14998 (match_operand:MODEF 1 "register_operand" "")]
14999 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15000 && !flag_trapping_math"
15001 {
15002 if (TARGET_64BIT && optimize_insn_for_size_p ())
15003 FAIL;
15004 ix86_expand_lfloorceil (operand0, operand1, true);
15005 DONE;
15006 })
15007
15008 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15009 (define_insn_and_split "frndintxf2_ceil"
15010 [(set (match_operand:XF 0 "register_operand" "")
15011 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15012 UNSPEC_FRNDINT_CEIL))
15013 (clobber (reg:CC FLAGS_REG))]
15014 "TARGET_USE_FANCY_MATH_387
15015 && flag_unsafe_math_optimizations
15016 && can_create_pseudo_p ()"
15017 "#"
15018 "&& 1"
15019 [(const_int 0)]
15020 {
15021 ix86_optimize_mode_switching[I387_CEIL] = 1;
15022
15023 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15024 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15025
15026 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15027 operands[2], operands[3]));
15028 DONE;
15029 }
15030 [(set_attr "type" "frndint")
15031 (set_attr "i387_cw" "ceil")
15032 (set_attr "mode" "XF")])
15033
15034 (define_insn "frndintxf2_ceil_i387"
15035 [(set (match_operand:XF 0 "register_operand" "=f")
15036 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15037 UNSPEC_FRNDINT_CEIL))
15038 (use (match_operand:HI 2 "memory_operand" "m"))
15039 (use (match_operand:HI 3 "memory_operand" "m"))]
15040 "TARGET_USE_FANCY_MATH_387
15041 && flag_unsafe_math_optimizations"
15042 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15043 [(set_attr "type" "frndint")
15044 (set_attr "i387_cw" "ceil")
15045 (set_attr "mode" "XF")])
15046
15047 (define_expand "ceilxf2"
15048 [(use (match_operand:XF 0 "register_operand" ""))
15049 (use (match_operand:XF 1 "register_operand" ""))]
15050 "TARGET_USE_FANCY_MATH_387
15051 && flag_unsafe_math_optimizations"
15052 {
15053 if (optimize_insn_for_size_p ())
15054 FAIL;
15055 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15056 DONE;
15057 })
15058
15059 (define_expand "ceil<mode>2"
15060 [(use (match_operand:MODEF 0 "register_operand" ""))
15061 (use (match_operand:MODEF 1 "register_operand" ""))]
15062 "(TARGET_USE_FANCY_MATH_387
15063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15064 || TARGET_MIX_SSE_I387)
15065 && flag_unsafe_math_optimizations)
15066 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15067 && !flag_trapping_math)"
15068 {
15069 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15070 && !flag_trapping_math
15071 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15072 {
15073 if (TARGET_ROUND)
15074 emit_insn (gen_sse4_1_round<mode>2
15075 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15076 else if (optimize_insn_for_size_p ())
15077 FAIL;
15078 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15079 ix86_expand_floorceil (operand0, operand1, false);
15080 else
15081 ix86_expand_floorceildf_32 (operand0, operand1, false);
15082 }
15083 else
15084 {
15085 rtx op0, op1;
15086
15087 if (optimize_insn_for_size_p ())
15088 FAIL;
15089
15090 op0 = gen_reg_rtx (XFmode);
15091 op1 = gen_reg_rtx (XFmode);
15092 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15093 emit_insn (gen_frndintxf2_ceil (op0, op1));
15094
15095 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15096 }
15097 DONE;
15098 })
15099
15100 (define_insn_and_split "*fist<mode>2_ceil_1"
15101 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15102 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15103 UNSPEC_FIST_CEIL))
15104 (clobber (reg:CC FLAGS_REG))]
15105 "TARGET_USE_FANCY_MATH_387
15106 && flag_unsafe_math_optimizations
15107 && can_create_pseudo_p ()"
15108 "#"
15109 "&& 1"
15110 [(const_int 0)]
15111 {
15112 ix86_optimize_mode_switching[I387_CEIL] = 1;
15113
15114 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15115 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15116 if (memory_operand (operands[0], VOIDmode))
15117 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15118 operands[2], operands[3]));
15119 else
15120 {
15121 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15122 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15123 operands[2], operands[3],
15124 operands[4]));
15125 }
15126 DONE;
15127 }
15128 [(set_attr "type" "fistp")
15129 (set_attr "i387_cw" "ceil")
15130 (set_attr "mode" "<MODE>")])
15131
15132 (define_insn "fistdi2_ceil"
15133 [(set (match_operand:DI 0 "memory_operand" "=m")
15134 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15135 UNSPEC_FIST_CEIL))
15136 (use (match_operand:HI 2 "memory_operand" "m"))
15137 (use (match_operand:HI 3 "memory_operand" "m"))
15138 (clobber (match_scratch:XF 4 "=&1f"))]
15139 "TARGET_USE_FANCY_MATH_387
15140 && flag_unsafe_math_optimizations"
15141 "* return output_fix_trunc (insn, operands, 0);"
15142 [(set_attr "type" "fistp")
15143 (set_attr "i387_cw" "ceil")
15144 (set_attr "mode" "DI")])
15145
15146 (define_insn "fistdi2_ceil_with_temp"
15147 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15148 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15149 UNSPEC_FIST_CEIL))
15150 (use (match_operand:HI 2 "memory_operand" "m,m"))
15151 (use (match_operand:HI 3 "memory_operand" "m,m"))
15152 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15153 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15154 "TARGET_USE_FANCY_MATH_387
15155 && flag_unsafe_math_optimizations"
15156 "#"
15157 [(set_attr "type" "fistp")
15158 (set_attr "i387_cw" "ceil")
15159 (set_attr "mode" "DI")])
15160
15161 (define_split
15162 [(set (match_operand:DI 0 "register_operand" "")
15163 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15164 UNSPEC_FIST_CEIL))
15165 (use (match_operand:HI 2 "memory_operand" ""))
15166 (use (match_operand:HI 3 "memory_operand" ""))
15167 (clobber (match_operand:DI 4 "memory_operand" ""))
15168 (clobber (match_scratch 5 ""))]
15169 "reload_completed"
15170 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15171 (use (match_dup 2))
15172 (use (match_dup 3))
15173 (clobber (match_dup 5))])
15174 (set (match_dup 0) (match_dup 4))])
15175
15176 (define_split
15177 [(set (match_operand:DI 0 "memory_operand" "")
15178 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15179 UNSPEC_FIST_CEIL))
15180 (use (match_operand:HI 2 "memory_operand" ""))
15181 (use (match_operand:HI 3 "memory_operand" ""))
15182 (clobber (match_operand:DI 4 "memory_operand" ""))
15183 (clobber (match_scratch 5 ""))]
15184 "reload_completed"
15185 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15186 (use (match_dup 2))
15187 (use (match_dup 3))
15188 (clobber (match_dup 5))])])
15189
15190 (define_insn "fist<mode>2_ceil"
15191 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15192 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15193 UNSPEC_FIST_CEIL))
15194 (use (match_operand:HI 2 "memory_operand" "m"))
15195 (use (match_operand:HI 3 "memory_operand" "m"))]
15196 "TARGET_USE_FANCY_MATH_387
15197 && flag_unsafe_math_optimizations"
15198 "* return output_fix_trunc (insn, operands, 0);"
15199 [(set_attr "type" "fistp")
15200 (set_attr "i387_cw" "ceil")
15201 (set_attr "mode" "<MODE>")])
15202
15203 (define_insn "fist<mode>2_ceil_with_temp"
15204 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15205 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15206 UNSPEC_FIST_CEIL))
15207 (use (match_operand:HI 2 "memory_operand" "m,m"))
15208 (use (match_operand:HI 3 "memory_operand" "m,m"))
15209 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15210 "TARGET_USE_FANCY_MATH_387
15211 && flag_unsafe_math_optimizations"
15212 "#"
15213 [(set_attr "type" "fistp")
15214 (set_attr "i387_cw" "ceil")
15215 (set_attr "mode" "<MODE>")])
15216
15217 (define_split
15218 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15219 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15220 UNSPEC_FIST_CEIL))
15221 (use (match_operand:HI 2 "memory_operand" ""))
15222 (use (match_operand:HI 3 "memory_operand" ""))
15223 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15224 "reload_completed"
15225 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15226 UNSPEC_FIST_CEIL))
15227 (use (match_dup 2))
15228 (use (match_dup 3))])
15229 (set (match_dup 0) (match_dup 4))])
15230
15231 (define_split
15232 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15233 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15234 UNSPEC_FIST_CEIL))
15235 (use (match_operand:HI 2 "memory_operand" ""))
15236 (use (match_operand:HI 3 "memory_operand" ""))
15237 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15238 "reload_completed"
15239 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15240 UNSPEC_FIST_CEIL))
15241 (use (match_dup 2))
15242 (use (match_dup 3))])])
15243
15244 (define_expand "lceilxf<mode>2"
15245 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15246 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15247 UNSPEC_FIST_CEIL))
15248 (clobber (reg:CC FLAGS_REG))])]
15249 "TARGET_USE_FANCY_MATH_387
15250 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15251 && flag_unsafe_math_optimizations")
15252
15253 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15254 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15255 (match_operand:MODEF 1 "register_operand" "")]
15256 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15257 && !flag_trapping_math"
15258 {
15259 ix86_expand_lfloorceil (operand0, operand1, false);
15260 DONE;
15261 })
15262
15263 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15264 (define_insn_and_split "frndintxf2_trunc"
15265 [(set (match_operand:XF 0 "register_operand" "")
15266 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15267 UNSPEC_FRNDINT_TRUNC))
15268 (clobber (reg:CC FLAGS_REG))]
15269 "TARGET_USE_FANCY_MATH_387
15270 && flag_unsafe_math_optimizations
15271 && can_create_pseudo_p ()"
15272 "#"
15273 "&& 1"
15274 [(const_int 0)]
15275 {
15276 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15277
15278 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15279 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15280
15281 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15282 operands[2], operands[3]));
15283 DONE;
15284 }
15285 [(set_attr "type" "frndint")
15286 (set_attr "i387_cw" "trunc")
15287 (set_attr "mode" "XF")])
15288
15289 (define_insn "frndintxf2_trunc_i387"
15290 [(set (match_operand:XF 0 "register_operand" "=f")
15291 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15292 UNSPEC_FRNDINT_TRUNC))
15293 (use (match_operand:HI 2 "memory_operand" "m"))
15294 (use (match_operand:HI 3 "memory_operand" "m"))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && flag_unsafe_math_optimizations"
15297 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15298 [(set_attr "type" "frndint")
15299 (set_attr "i387_cw" "trunc")
15300 (set_attr "mode" "XF")])
15301
15302 (define_expand "btruncxf2"
15303 [(use (match_operand:XF 0 "register_operand" ""))
15304 (use (match_operand:XF 1 "register_operand" ""))]
15305 "TARGET_USE_FANCY_MATH_387
15306 && flag_unsafe_math_optimizations"
15307 {
15308 if (optimize_insn_for_size_p ())
15309 FAIL;
15310 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15311 DONE;
15312 })
15313
15314 (define_expand "btrunc<mode>2"
15315 [(use (match_operand:MODEF 0 "register_operand" ""))
15316 (use (match_operand:MODEF 1 "register_operand" ""))]
15317 "(TARGET_USE_FANCY_MATH_387
15318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15319 || TARGET_MIX_SSE_I387)
15320 && flag_unsafe_math_optimizations)
15321 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15322 && !flag_trapping_math)"
15323 {
15324 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15325 && !flag_trapping_math
15326 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15327 {
15328 if (TARGET_ROUND)
15329 emit_insn (gen_sse4_1_round<mode>2
15330 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15331 else if (optimize_insn_for_size_p ())
15332 FAIL;
15333 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15334 ix86_expand_trunc (operand0, operand1);
15335 else
15336 ix86_expand_truncdf_32 (operand0, operand1);
15337 }
15338 else
15339 {
15340 rtx op0, op1;
15341
15342 if (optimize_insn_for_size_p ())
15343 FAIL;
15344
15345 op0 = gen_reg_rtx (XFmode);
15346 op1 = gen_reg_rtx (XFmode);
15347 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15348 emit_insn (gen_frndintxf2_trunc (op0, op1));
15349
15350 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15351 }
15352 DONE;
15353 })
15354
15355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15356 (define_insn_and_split "frndintxf2_mask_pm"
15357 [(set (match_operand:XF 0 "register_operand" "")
15358 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15359 UNSPEC_FRNDINT_MASK_PM))
15360 (clobber (reg:CC FLAGS_REG))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_unsafe_math_optimizations
15363 && can_create_pseudo_p ()"
15364 "#"
15365 "&& 1"
15366 [(const_int 0)]
15367 {
15368 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15369
15370 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15371 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15372
15373 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15374 operands[2], operands[3]));
15375 DONE;
15376 }
15377 [(set_attr "type" "frndint")
15378 (set_attr "i387_cw" "mask_pm")
15379 (set_attr "mode" "XF")])
15380
15381 (define_insn "frndintxf2_mask_pm_i387"
15382 [(set (match_operand:XF 0 "register_operand" "=f")
15383 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15384 UNSPEC_FRNDINT_MASK_PM))
15385 (use (match_operand:HI 2 "memory_operand" "m"))
15386 (use (match_operand:HI 3 "memory_operand" "m"))]
15387 "TARGET_USE_FANCY_MATH_387
15388 && flag_unsafe_math_optimizations"
15389 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15390 [(set_attr "type" "frndint")
15391 (set_attr "i387_cw" "mask_pm")
15392 (set_attr "mode" "XF")])
15393
15394 (define_expand "nearbyintxf2"
15395 [(use (match_operand:XF 0 "register_operand" ""))
15396 (use (match_operand:XF 1 "register_operand" ""))]
15397 "TARGET_USE_FANCY_MATH_387
15398 && flag_unsafe_math_optimizations"
15399 {
15400 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15401 DONE;
15402 })
15403
15404 (define_expand "nearbyint<mode>2"
15405 [(use (match_operand:MODEF 0 "register_operand" ""))
15406 (use (match_operand:MODEF 1 "register_operand" ""))]
15407 "TARGET_USE_FANCY_MATH_387
15408 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15409 || TARGET_MIX_SSE_I387)
15410 && flag_unsafe_math_optimizations"
15411 {
15412 rtx op0 = gen_reg_rtx (XFmode);
15413 rtx op1 = gen_reg_rtx (XFmode);
15414
15415 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15416 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15417
15418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15419 DONE;
15420 })
15421
15422 (define_insn "fxam<mode>2_i387"
15423 [(set (match_operand:HI 0 "register_operand" "=a")
15424 (unspec:HI
15425 [(match_operand:X87MODEF 1 "register_operand" "f")]
15426 UNSPEC_FXAM))]
15427 "TARGET_USE_FANCY_MATH_387"
15428 "fxam\n\tfnstsw\t%0"
15429 [(set_attr "type" "multi")
15430 (set_attr "length" "4")
15431 (set_attr "unit" "i387")
15432 (set_attr "mode" "<MODE>")])
15433
15434 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15435 [(set (match_operand:HI 0 "register_operand" "")
15436 (unspec:HI
15437 [(match_operand:MODEF 1 "memory_operand" "")]
15438 UNSPEC_FXAM_MEM))]
15439 "TARGET_USE_FANCY_MATH_387
15440 && can_create_pseudo_p ()"
15441 "#"
15442 "&& 1"
15443 [(set (match_dup 2)(match_dup 1))
15444 (set (match_dup 0)
15445 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15446 {
15447 operands[2] = gen_reg_rtx (<MODE>mode);
15448
15449 MEM_VOLATILE_P (operands[1]) = 1;
15450 }
15451 [(set_attr "type" "multi")
15452 (set_attr "unit" "i387")
15453 (set_attr "mode" "<MODE>")])
15454
15455 (define_expand "isinfxf2"
15456 [(use (match_operand:SI 0 "register_operand" ""))
15457 (use (match_operand:XF 1 "register_operand" ""))]
15458 "TARGET_USE_FANCY_MATH_387
15459 && TARGET_C99_FUNCTIONS"
15460 {
15461 rtx mask = GEN_INT (0x45);
15462 rtx val = GEN_INT (0x05);
15463
15464 rtx cond;
15465
15466 rtx scratch = gen_reg_rtx (HImode);
15467 rtx res = gen_reg_rtx (QImode);
15468
15469 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15470
15471 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15472 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15473 cond = gen_rtx_fmt_ee (EQ, QImode,
15474 gen_rtx_REG (CCmode, FLAGS_REG),
15475 const0_rtx);
15476 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15477 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15478 DONE;
15479 })
15480
15481 (define_expand "isinf<mode>2"
15482 [(use (match_operand:SI 0 "register_operand" ""))
15483 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15484 "TARGET_USE_FANCY_MATH_387
15485 && TARGET_C99_FUNCTIONS
15486 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15487 {
15488 rtx mask = GEN_INT (0x45);
15489 rtx val = GEN_INT (0x05);
15490
15491 rtx cond;
15492
15493 rtx scratch = gen_reg_rtx (HImode);
15494 rtx res = gen_reg_rtx (QImode);
15495
15496 /* Remove excess precision by forcing value through memory. */
15497 if (memory_operand (operands[1], VOIDmode))
15498 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15499 else
15500 {
15501 enum ix86_stack_slot slot = (virtuals_instantiated
15502 ? SLOT_TEMP
15503 : SLOT_VIRTUAL);
15504 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15505
15506 emit_move_insn (temp, operands[1]);
15507 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15508 }
15509
15510 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15511 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15512 cond = gen_rtx_fmt_ee (EQ, QImode,
15513 gen_rtx_REG (CCmode, FLAGS_REG),
15514 const0_rtx);
15515 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15516 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15517 DONE;
15518 })
15519
15520 (define_expand "signbitxf2"
15521 [(use (match_operand:SI 0 "register_operand" ""))
15522 (use (match_operand:XF 1 "register_operand" ""))]
15523 "TARGET_USE_FANCY_MATH_387"
15524 {
15525 rtx scratch = gen_reg_rtx (HImode);
15526
15527 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15528 emit_insn (gen_andsi3 (operands[0],
15529 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15530 DONE;
15531 })
15532
15533 (define_insn "movmsk_df"
15534 [(set (match_operand:SI 0 "register_operand" "=r")
15535 (unspec:SI
15536 [(match_operand:DF 1 "register_operand" "x")]
15537 UNSPEC_MOVMSK))]
15538 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15539 "%vmovmskpd\t{%1, %0|%0, %1}"
15540 [(set_attr "type" "ssemov")
15541 (set_attr "prefix" "maybe_vex")
15542 (set_attr "mode" "DF")])
15543
15544 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15545 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15546 (define_expand "signbitdf2"
15547 [(use (match_operand:SI 0 "register_operand" ""))
15548 (use (match_operand:DF 1 "register_operand" ""))]
15549 "TARGET_USE_FANCY_MATH_387
15550 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15551 {
15552 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15553 {
15554 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15555 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15556 }
15557 else
15558 {
15559 rtx scratch = gen_reg_rtx (HImode);
15560
15561 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15562 emit_insn (gen_andsi3 (operands[0],
15563 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15564 }
15565 DONE;
15566 })
15567
15568 (define_expand "signbitsf2"
15569 [(use (match_operand:SI 0 "register_operand" ""))
15570 (use (match_operand:SF 1 "register_operand" ""))]
15571 "TARGET_USE_FANCY_MATH_387
15572 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15573 {
15574 rtx scratch = gen_reg_rtx (HImode);
15575
15576 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15577 emit_insn (gen_andsi3 (operands[0],
15578 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15579 DONE;
15580 })
15581 \f
15582 ;; Block operation instructions
15583
15584 (define_insn "cld"
15585 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15586 ""
15587 "cld"
15588 [(set_attr "length" "1")
15589 (set_attr "length_immediate" "0")
15590 (set_attr "modrm" "0")])
15591
15592 (define_expand "movmem<mode>"
15593 [(use (match_operand:BLK 0 "memory_operand" ""))
15594 (use (match_operand:BLK 1 "memory_operand" ""))
15595 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15596 (use (match_operand:SWI48 3 "const_int_operand" ""))
15597 (use (match_operand:SI 4 "const_int_operand" ""))
15598 (use (match_operand:SI 5 "const_int_operand" ""))]
15599 ""
15600 {
15601 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15602 operands[4], operands[5]))
15603 DONE;
15604 else
15605 FAIL;
15606 })
15607
15608 ;; Most CPUs don't like single string operations
15609 ;; Handle this case here to simplify previous expander.
15610
15611 (define_expand "strmov"
15612 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15613 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15614 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15615 (clobber (reg:CC FLAGS_REG))])
15616 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15617 (clobber (reg:CC FLAGS_REG))])]
15618 ""
15619 {
15620 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15621
15622 /* If .md ever supports :P for Pmode, these can be directly
15623 in the pattern above. */
15624 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15625 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15626
15627 /* Can't use this if the user has appropriated esi or edi. */
15628 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15629 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15630 {
15631 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15632 operands[2], operands[3],
15633 operands[5], operands[6]));
15634 DONE;
15635 }
15636
15637 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15638 })
15639
15640 (define_expand "strmov_singleop"
15641 [(parallel [(set (match_operand 1 "memory_operand" "")
15642 (match_operand 3 "memory_operand" ""))
15643 (set (match_operand 0 "register_operand" "")
15644 (match_operand 4 "" ""))
15645 (set (match_operand 2 "register_operand" "")
15646 (match_operand 5 "" ""))])]
15647 ""
15648 "ix86_current_function_needs_cld = 1;")
15649
15650 (define_insn "*strmovdi_rex_1"
15651 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15652 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15653 (set (match_operand:DI 0 "register_operand" "=D")
15654 (plus:DI (match_dup 2)
15655 (const_int 8)))
15656 (set (match_operand:DI 1 "register_operand" "=S")
15657 (plus:DI (match_dup 3)
15658 (const_int 8)))]
15659 "TARGET_64BIT"
15660 "movsq"
15661 [(set_attr "type" "str")
15662 (set_attr "memory" "both")
15663 (set_attr "mode" "DI")])
15664
15665 (define_insn "*strmovsi_1"
15666 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15667 (mem:SI (match_operand:P 3 "register_operand" "1")))
15668 (set (match_operand:P 0 "register_operand" "=D")
15669 (plus:P (match_dup 2)
15670 (const_int 4)))
15671 (set (match_operand:P 1 "register_operand" "=S")
15672 (plus:P (match_dup 3)
15673 (const_int 4)))]
15674 ""
15675 "movs{l|d}"
15676 [(set_attr "type" "str")
15677 (set_attr "memory" "both")
15678 (set_attr "mode" "SI")])
15679
15680 (define_insn "*strmovhi_1"
15681 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15682 (mem:HI (match_operand:P 3 "register_operand" "1")))
15683 (set (match_operand:P 0 "register_operand" "=D")
15684 (plus:P (match_dup 2)
15685 (const_int 2)))
15686 (set (match_operand:P 1 "register_operand" "=S")
15687 (plus:P (match_dup 3)
15688 (const_int 2)))]
15689 ""
15690 "movsw"
15691 [(set_attr "type" "str")
15692 (set_attr "memory" "both")
15693 (set_attr "mode" "HI")])
15694
15695 (define_insn "*strmovqi_1"
15696 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15697 (mem:QI (match_operand:P 3 "register_operand" "1")))
15698 (set (match_operand:P 0 "register_operand" "=D")
15699 (plus:P (match_dup 2)
15700 (const_int 1)))
15701 (set (match_operand:P 1 "register_operand" "=S")
15702 (plus:P (match_dup 3)
15703 (const_int 1)))]
15704 ""
15705 "movsb"
15706 [(set_attr "type" "str")
15707 (set_attr "memory" "both")
15708 (set (attr "prefix_rex")
15709 (if_then_else
15710 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15711 (const_string "0")
15712 (const_string "*")))
15713 (set_attr "mode" "QI")])
15714
15715 (define_expand "rep_mov"
15716 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15717 (set (match_operand 0 "register_operand" "")
15718 (match_operand 5 "" ""))
15719 (set (match_operand 2 "register_operand" "")
15720 (match_operand 6 "" ""))
15721 (set (match_operand 1 "memory_operand" "")
15722 (match_operand 3 "memory_operand" ""))
15723 (use (match_dup 4))])]
15724 ""
15725 "ix86_current_function_needs_cld = 1;")
15726
15727 (define_insn "*rep_movdi_rex64"
15728 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15729 (set (match_operand:DI 0 "register_operand" "=D")
15730 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15731 (const_int 3))
15732 (match_operand:DI 3 "register_operand" "0")))
15733 (set (match_operand:DI 1 "register_operand" "=S")
15734 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15735 (match_operand:DI 4 "register_operand" "1")))
15736 (set (mem:BLK (match_dup 3))
15737 (mem:BLK (match_dup 4)))
15738 (use (match_dup 5))]
15739 "TARGET_64BIT"
15740 "rep{%;} movsq"
15741 [(set_attr "type" "str")
15742 (set_attr "prefix_rep" "1")
15743 (set_attr "memory" "both")
15744 (set_attr "mode" "DI")])
15745
15746 (define_insn "*rep_movsi"
15747 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15748 (set (match_operand:P 0 "register_operand" "=D")
15749 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15750 (const_int 2))
15751 (match_operand:P 3 "register_operand" "0")))
15752 (set (match_operand:P 1 "register_operand" "=S")
15753 (plus:P (ashift:P (match_dup 5) (const_int 2))
15754 (match_operand:P 4 "register_operand" "1")))
15755 (set (mem:BLK (match_dup 3))
15756 (mem:BLK (match_dup 4)))
15757 (use (match_dup 5))]
15758 ""
15759 "rep{%;} movs{l|d}"
15760 [(set_attr "type" "str")
15761 (set_attr "prefix_rep" "1")
15762 (set_attr "memory" "both")
15763 (set_attr "mode" "SI")])
15764
15765 (define_insn "*rep_movqi"
15766 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (match_operand:P 3 "register_operand" "0")
15769 (match_operand:P 5 "register_operand" "2")))
15770 (set (match_operand:P 1 "register_operand" "=S")
15771 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15772 (set (mem:BLK (match_dup 3))
15773 (mem:BLK (match_dup 4)))
15774 (use (match_dup 5))]
15775 ""
15776 "rep{%;} movsb"
15777 [(set_attr "type" "str")
15778 (set_attr "prefix_rep" "1")
15779 (set_attr "memory" "both")
15780 (set_attr "mode" "QI")])
15781
15782 (define_expand "setmem<mode>"
15783 [(use (match_operand:BLK 0 "memory_operand" ""))
15784 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15785 (use (match_operand:QI 2 "nonmemory_operand" ""))
15786 (use (match_operand 3 "const_int_operand" ""))
15787 (use (match_operand:SI 4 "const_int_operand" ""))
15788 (use (match_operand:SI 5 "const_int_operand" ""))]
15789 ""
15790 {
15791 if (ix86_expand_setmem (operands[0], operands[1],
15792 operands[2], operands[3],
15793 operands[4], operands[5]))
15794 DONE;
15795 else
15796 FAIL;
15797 })
15798
15799 ;; Most CPUs don't like single string operations
15800 ;; Handle this case here to simplify previous expander.
15801
15802 (define_expand "strset"
15803 [(set (match_operand 1 "memory_operand" "")
15804 (match_operand 2 "register_operand" ""))
15805 (parallel [(set (match_operand 0 "register_operand" "")
15806 (match_dup 3))
15807 (clobber (reg:CC FLAGS_REG))])]
15808 ""
15809 {
15810 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15811 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15812
15813 /* If .md ever supports :P for Pmode, this can be directly
15814 in the pattern above. */
15815 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15816 GEN_INT (GET_MODE_SIZE (GET_MODE
15817 (operands[2]))));
15818 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15819 {
15820 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15821 operands[3]));
15822 DONE;
15823 }
15824 })
15825
15826 (define_expand "strset_singleop"
15827 [(parallel [(set (match_operand 1 "memory_operand" "")
15828 (match_operand 2 "register_operand" ""))
15829 (set (match_operand 0 "register_operand" "")
15830 (match_operand 3 "" ""))])]
15831 ""
15832 "ix86_current_function_needs_cld = 1;")
15833
15834 (define_insn "*strsetdi_rex_1"
15835 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15836 (match_operand:DI 2 "register_operand" "a"))
15837 (set (match_operand:DI 0 "register_operand" "=D")
15838 (plus:DI (match_dup 1)
15839 (const_int 8)))]
15840 "TARGET_64BIT"
15841 "stosq"
15842 [(set_attr "type" "str")
15843 (set_attr "memory" "store")
15844 (set_attr "mode" "DI")])
15845
15846 (define_insn "*strsetsi_1"
15847 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15848 (match_operand:SI 2 "register_operand" "a"))
15849 (set (match_operand:P 0 "register_operand" "=D")
15850 (plus:P (match_dup 1)
15851 (const_int 4)))]
15852 ""
15853 "stos{l|d}"
15854 [(set_attr "type" "str")
15855 (set_attr "memory" "store")
15856 (set_attr "mode" "SI")])
15857
15858 (define_insn "*strsethi_1"
15859 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15860 (match_operand:HI 2 "register_operand" "a"))
15861 (set (match_operand:P 0 "register_operand" "=D")
15862 (plus:P (match_dup 1)
15863 (const_int 2)))]
15864 ""
15865 "stosw"
15866 [(set_attr "type" "str")
15867 (set_attr "memory" "store")
15868 (set_attr "mode" "HI")])
15869
15870 (define_insn "*strsetqi_1"
15871 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15872 (match_operand:QI 2 "register_operand" "a"))
15873 (set (match_operand:P 0 "register_operand" "=D")
15874 (plus:P (match_dup 1)
15875 (const_int 1)))]
15876 ""
15877 "stosb"
15878 [(set_attr "type" "str")
15879 (set_attr "memory" "store")
15880 (set (attr "prefix_rex")
15881 (if_then_else
15882 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15883 (const_string "0")
15884 (const_string "*")))
15885 (set_attr "mode" "QI")])
15886
15887 (define_expand "rep_stos"
15888 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15889 (set (match_operand 0 "register_operand" "")
15890 (match_operand 4 "" ""))
15891 (set (match_operand 2 "memory_operand" "") (const_int 0))
15892 (use (match_operand 3 "register_operand" ""))
15893 (use (match_dup 1))])]
15894 ""
15895 "ix86_current_function_needs_cld = 1;")
15896
15897 (define_insn "*rep_stosdi_rex64"
15898 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15899 (set (match_operand:DI 0 "register_operand" "=D")
15900 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15901 (const_int 3))
15902 (match_operand:DI 3 "register_operand" "0")))
15903 (set (mem:BLK (match_dup 3))
15904 (const_int 0))
15905 (use (match_operand:DI 2 "register_operand" "a"))
15906 (use (match_dup 4))]
15907 "TARGET_64BIT"
15908 "rep{%;} stosq"
15909 [(set_attr "type" "str")
15910 (set_attr "prefix_rep" "1")
15911 (set_attr "memory" "store")
15912 (set_attr "mode" "DI")])
15913
15914 (define_insn "*rep_stossi"
15915 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15916 (set (match_operand:P 0 "register_operand" "=D")
15917 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15918 (const_int 2))
15919 (match_operand:P 3 "register_operand" "0")))
15920 (set (mem:BLK (match_dup 3))
15921 (const_int 0))
15922 (use (match_operand:SI 2 "register_operand" "a"))
15923 (use (match_dup 4))]
15924 ""
15925 "rep{%;} stos{l|d}"
15926 [(set_attr "type" "str")
15927 (set_attr "prefix_rep" "1")
15928 (set_attr "memory" "store")
15929 (set_attr "mode" "SI")])
15930
15931 (define_insn "*rep_stosqi"
15932 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15933 (set (match_operand:P 0 "register_operand" "=D")
15934 (plus:P (match_operand:P 3 "register_operand" "0")
15935 (match_operand:P 4 "register_operand" "1")))
15936 (set (mem:BLK (match_dup 3))
15937 (const_int 0))
15938 (use (match_operand:QI 2 "register_operand" "a"))
15939 (use (match_dup 4))]
15940 ""
15941 "rep{%;} stosb"
15942 [(set_attr "type" "str")
15943 (set_attr "prefix_rep" "1")
15944 (set_attr "memory" "store")
15945 (set (attr "prefix_rex")
15946 (if_then_else
15947 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15948 (const_string "0")
15949 (const_string "*")))
15950 (set_attr "mode" "QI")])
15951
15952 (define_expand "cmpstrnsi"
15953 [(set (match_operand:SI 0 "register_operand" "")
15954 (compare:SI (match_operand:BLK 1 "general_operand" "")
15955 (match_operand:BLK 2 "general_operand" "")))
15956 (use (match_operand 3 "general_operand" ""))
15957 (use (match_operand 4 "immediate_operand" ""))]
15958 ""
15959 {
15960 rtx addr1, addr2, out, outlow, count, countreg, align;
15961
15962 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15963 FAIL;
15964
15965 /* Can't use this if the user has appropriated esi or edi. */
15966 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15967 FAIL;
15968
15969 out = operands[0];
15970 if (!REG_P (out))
15971 out = gen_reg_rtx (SImode);
15972
15973 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15974 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15975 if (addr1 != XEXP (operands[1], 0))
15976 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15977 if (addr2 != XEXP (operands[2], 0))
15978 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15979
15980 count = operands[3];
15981 countreg = ix86_zero_extend_to_Pmode (count);
15982
15983 /* %%% Iff we are testing strict equality, we can use known alignment
15984 to good advantage. This may be possible with combine, particularly
15985 once cc0 is dead. */
15986 align = operands[4];
15987
15988 if (CONST_INT_P (count))
15989 {
15990 if (INTVAL (count) == 0)
15991 {
15992 emit_move_insn (operands[0], const0_rtx);
15993 DONE;
15994 }
15995 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15996 operands[1], operands[2]));
15997 }
15998 else
15999 {
16000 rtx (*gen_cmp) (rtx, rtx);
16001
16002 gen_cmp = (TARGET_64BIT
16003 ? gen_cmpdi_1 : gen_cmpsi_1);
16004
16005 emit_insn (gen_cmp (countreg, countreg));
16006 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16007 operands[1], operands[2]));
16008 }
16009
16010 outlow = gen_lowpart (QImode, out);
16011 emit_insn (gen_cmpintqi (outlow));
16012 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16013
16014 if (operands[0] != out)
16015 emit_move_insn (operands[0], out);
16016
16017 DONE;
16018 })
16019
16020 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16021
16022 (define_expand "cmpintqi"
16023 [(set (match_dup 1)
16024 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16025 (set (match_dup 2)
16026 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16027 (parallel [(set (match_operand:QI 0 "register_operand" "")
16028 (minus:QI (match_dup 1)
16029 (match_dup 2)))
16030 (clobber (reg:CC FLAGS_REG))])]
16031 ""
16032 {
16033 operands[1] = gen_reg_rtx (QImode);
16034 operands[2] = gen_reg_rtx (QImode);
16035 })
16036
16037 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16038 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16039
16040 (define_expand "cmpstrnqi_nz_1"
16041 [(parallel [(set (reg:CC FLAGS_REG)
16042 (compare:CC (match_operand 4 "memory_operand" "")
16043 (match_operand 5 "memory_operand" "")))
16044 (use (match_operand 2 "register_operand" ""))
16045 (use (match_operand:SI 3 "immediate_operand" ""))
16046 (clobber (match_operand 0 "register_operand" ""))
16047 (clobber (match_operand 1 "register_operand" ""))
16048 (clobber (match_dup 2))])]
16049 ""
16050 "ix86_current_function_needs_cld = 1;")
16051
16052 (define_insn "*cmpstrnqi_nz_1"
16053 [(set (reg:CC FLAGS_REG)
16054 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16055 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16056 (use (match_operand:P 6 "register_operand" "2"))
16057 (use (match_operand:SI 3 "immediate_operand" "i"))
16058 (clobber (match_operand:P 0 "register_operand" "=S"))
16059 (clobber (match_operand:P 1 "register_operand" "=D"))
16060 (clobber (match_operand:P 2 "register_operand" "=c"))]
16061 ""
16062 "repz{%;} cmpsb"
16063 [(set_attr "type" "str")
16064 (set_attr "mode" "QI")
16065 (set (attr "prefix_rex")
16066 (if_then_else
16067 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16068 (const_string "0")
16069 (const_string "*")))
16070 (set_attr "prefix_rep" "1")])
16071
16072 ;; The same, but the count is not known to not be zero.
16073
16074 (define_expand "cmpstrnqi_1"
16075 [(parallel [(set (reg:CC FLAGS_REG)
16076 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16077 (const_int 0))
16078 (compare:CC (match_operand 4 "memory_operand" "")
16079 (match_operand 5 "memory_operand" ""))
16080 (const_int 0)))
16081 (use (match_operand:SI 3 "immediate_operand" ""))
16082 (use (reg:CC FLAGS_REG))
16083 (clobber (match_operand 0 "register_operand" ""))
16084 (clobber (match_operand 1 "register_operand" ""))
16085 (clobber (match_dup 2))])]
16086 ""
16087 "ix86_current_function_needs_cld = 1;")
16088
16089 (define_insn "*cmpstrnqi_1"
16090 [(set (reg:CC FLAGS_REG)
16091 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16092 (const_int 0))
16093 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16094 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16095 (const_int 0)))
16096 (use (match_operand:SI 3 "immediate_operand" "i"))
16097 (use (reg:CC FLAGS_REG))
16098 (clobber (match_operand:P 0 "register_operand" "=S"))
16099 (clobber (match_operand:P 1 "register_operand" "=D"))
16100 (clobber (match_operand:P 2 "register_operand" "=c"))]
16101 ""
16102 "repz{%;} cmpsb"
16103 [(set_attr "type" "str")
16104 (set_attr "mode" "QI")
16105 (set (attr "prefix_rex")
16106 (if_then_else
16107 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16108 (const_string "0")
16109 (const_string "*")))
16110 (set_attr "prefix_rep" "1")])
16111
16112 (define_expand "strlen<mode>"
16113 [(set (match_operand:SWI48x 0 "register_operand" "")
16114 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16115 (match_operand:QI 2 "immediate_operand" "")
16116 (match_operand 3 "immediate_operand" "")]
16117 UNSPEC_SCAS))]
16118 ""
16119 {
16120 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16121 DONE;
16122 else
16123 FAIL;
16124 })
16125
16126 (define_expand "strlenqi_1"
16127 [(parallel [(set (match_operand 0 "register_operand" "")
16128 (match_operand 2 "" ""))
16129 (clobber (match_operand 1 "register_operand" ""))
16130 (clobber (reg:CC FLAGS_REG))])]
16131 ""
16132 "ix86_current_function_needs_cld = 1;")
16133
16134 (define_insn "*strlenqi_1"
16135 [(set (match_operand:P 0 "register_operand" "=&c")
16136 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16137 (match_operand:QI 2 "register_operand" "a")
16138 (match_operand:P 3 "immediate_operand" "i")
16139 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16140 (clobber (match_operand:P 1 "register_operand" "=D"))
16141 (clobber (reg:CC FLAGS_REG))]
16142 ""
16143 "repnz{%;} scasb"
16144 [(set_attr "type" "str")
16145 (set_attr "mode" "QI")
16146 (set (attr "prefix_rex")
16147 (if_then_else
16148 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16149 (const_string "0")
16150 (const_string "*")))
16151 (set_attr "prefix_rep" "1")])
16152
16153 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16154 ;; handled in combine, but it is not currently up to the task.
16155 ;; When used for their truth value, the cmpstrn* expanders generate
16156 ;; code like this:
16157 ;;
16158 ;; repz cmpsb
16159 ;; seta %al
16160 ;; setb %dl
16161 ;; cmpb %al, %dl
16162 ;; jcc label
16163 ;;
16164 ;; The intermediate three instructions are unnecessary.
16165
16166 ;; This one handles cmpstrn*_nz_1...
16167 (define_peephole2
16168 [(parallel[
16169 (set (reg:CC FLAGS_REG)
16170 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16171 (mem:BLK (match_operand 5 "register_operand" ""))))
16172 (use (match_operand 6 "register_operand" ""))
16173 (use (match_operand:SI 3 "immediate_operand" ""))
16174 (clobber (match_operand 0 "register_operand" ""))
16175 (clobber (match_operand 1 "register_operand" ""))
16176 (clobber (match_operand 2 "register_operand" ""))])
16177 (set (match_operand:QI 7 "register_operand" "")
16178 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16179 (set (match_operand:QI 8 "register_operand" "")
16180 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16181 (set (reg FLAGS_REG)
16182 (compare (match_dup 7) (match_dup 8)))
16183 ]
16184 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16185 [(parallel[
16186 (set (reg:CC FLAGS_REG)
16187 (compare:CC (mem:BLK (match_dup 4))
16188 (mem:BLK (match_dup 5))))
16189 (use (match_dup 6))
16190 (use (match_dup 3))
16191 (clobber (match_dup 0))
16192 (clobber (match_dup 1))
16193 (clobber (match_dup 2))])])
16194
16195 ;; ...and this one handles cmpstrn*_1.
16196 (define_peephole2
16197 [(parallel[
16198 (set (reg:CC FLAGS_REG)
16199 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16200 (const_int 0))
16201 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16202 (mem:BLK (match_operand 5 "register_operand" "")))
16203 (const_int 0)))
16204 (use (match_operand:SI 3 "immediate_operand" ""))
16205 (use (reg:CC FLAGS_REG))
16206 (clobber (match_operand 0 "register_operand" ""))
16207 (clobber (match_operand 1 "register_operand" ""))
16208 (clobber (match_operand 2 "register_operand" ""))])
16209 (set (match_operand:QI 7 "register_operand" "")
16210 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16211 (set (match_operand:QI 8 "register_operand" "")
16212 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16213 (set (reg FLAGS_REG)
16214 (compare (match_dup 7) (match_dup 8)))
16215 ]
16216 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16217 [(parallel[
16218 (set (reg:CC FLAGS_REG)
16219 (if_then_else:CC (ne (match_dup 6)
16220 (const_int 0))
16221 (compare:CC (mem:BLK (match_dup 4))
16222 (mem:BLK (match_dup 5)))
16223 (const_int 0)))
16224 (use (match_dup 3))
16225 (use (reg:CC FLAGS_REG))
16226 (clobber (match_dup 0))
16227 (clobber (match_dup 1))
16228 (clobber (match_dup 2))])])
16229 \f
16230 ;; Conditional move instructions.
16231
16232 (define_expand "mov<mode>cc"
16233 [(set (match_operand:SWIM 0 "register_operand" "")
16234 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16235 (match_operand:SWIM 2 "general_operand" "")
16236 (match_operand:SWIM 3 "general_operand" "")))]
16237 ""
16238 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16239
16240 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16241 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16242 ;; So just document what we're doing explicitly.
16243
16244 (define_expand "x86_mov<mode>cc_0_m1"
16245 [(parallel
16246 [(set (match_operand:SWI48 0 "register_operand" "")
16247 (if_then_else:SWI48
16248 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16249 [(match_operand 1 "flags_reg_operand" "")
16250 (const_int 0)])
16251 (const_int -1)
16252 (const_int 0)))
16253 (clobber (reg:CC FLAGS_REG))])])
16254
16255 (define_insn "*x86_mov<mode>cc_0_m1"
16256 [(set (match_operand:SWI48 0 "register_operand" "=r")
16257 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16258 [(reg FLAGS_REG) (const_int 0)])
16259 (const_int -1)
16260 (const_int 0)))
16261 (clobber (reg:CC FLAGS_REG))]
16262 ""
16263 "sbb{<imodesuffix>}\t%0, %0"
16264 ; Since we don't have the proper number of operands for an alu insn,
16265 ; fill in all the blanks.
16266 [(set_attr "type" "alu")
16267 (set_attr "use_carry" "1")
16268 (set_attr "pent_pair" "pu")
16269 (set_attr "memory" "none")
16270 (set_attr "imm_disp" "false")
16271 (set_attr "mode" "<MODE>")
16272 (set_attr "length_immediate" "0")])
16273
16274 (define_insn "*x86_mov<mode>cc_0_m1_se"
16275 [(set (match_operand:SWI48 0 "register_operand" "=r")
16276 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16277 [(reg FLAGS_REG) (const_int 0)])
16278 (const_int 1)
16279 (const_int 0)))
16280 (clobber (reg:CC FLAGS_REG))]
16281 ""
16282 "sbb{<imodesuffix>}\t%0, %0"
16283 [(set_attr "type" "alu")
16284 (set_attr "use_carry" "1")
16285 (set_attr "pent_pair" "pu")
16286 (set_attr "memory" "none")
16287 (set_attr "imm_disp" "false")
16288 (set_attr "mode" "<MODE>")
16289 (set_attr "length_immediate" "0")])
16290
16291 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16292 [(set (match_operand:SWI48 0 "register_operand" "=r")
16293 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16294 [(reg FLAGS_REG) (const_int 0)])))]
16295 ""
16296 "sbb{<imodesuffix>}\t%0, %0"
16297 [(set_attr "type" "alu")
16298 (set_attr "use_carry" "1")
16299 (set_attr "pent_pair" "pu")
16300 (set_attr "memory" "none")
16301 (set_attr "imm_disp" "false")
16302 (set_attr "mode" "<MODE>")
16303 (set_attr "length_immediate" "0")])
16304
16305 (define_insn "*mov<mode>cc_noc"
16306 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16307 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16308 [(reg FLAGS_REG) (const_int 0)])
16309 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16310 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16311 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16312 "@
16313 cmov%O2%C1\t{%2, %0|%0, %2}
16314 cmov%O2%c1\t{%3, %0|%0, %3}"
16315 [(set_attr "type" "icmov")
16316 (set_attr "mode" "<MODE>")])
16317
16318 (define_insn_and_split "*movqicc_noc"
16319 [(set (match_operand:QI 0 "register_operand" "=r,r")
16320 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16321 [(match_operand 4 "flags_reg_operand" "")
16322 (const_int 0)])
16323 (match_operand:QI 2 "register_operand" "r,0")
16324 (match_operand:QI 3 "register_operand" "0,r")))]
16325 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16326 "#"
16327 "&& reload_completed"
16328 [(set (match_dup 0)
16329 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16330 (match_dup 2)
16331 (match_dup 3)))]
16332 "operands[0] = gen_lowpart (SImode, operands[0]);
16333 operands[2] = gen_lowpart (SImode, operands[2]);
16334 operands[3] = gen_lowpart (SImode, operands[3]);"
16335 [(set_attr "type" "icmov")
16336 (set_attr "mode" "SI")])
16337
16338 (define_expand "mov<mode>cc"
16339 [(set (match_operand:X87MODEF 0 "register_operand" "")
16340 (if_then_else:X87MODEF
16341 (match_operand 1 "ix86_fp_comparison_operator" "")
16342 (match_operand:X87MODEF 2 "register_operand" "")
16343 (match_operand:X87MODEF 3 "register_operand" "")))]
16344 "(TARGET_80387 && TARGET_CMOVE)
16345 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16346 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16347
16348 (define_insn "*movxfcc_1"
16349 [(set (match_operand:XF 0 "register_operand" "=f,f")
16350 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16351 [(reg FLAGS_REG) (const_int 0)])
16352 (match_operand:XF 2 "register_operand" "f,0")
16353 (match_operand:XF 3 "register_operand" "0,f")))]
16354 "TARGET_80387 && TARGET_CMOVE"
16355 "@
16356 fcmov%F1\t{%2, %0|%0, %2}
16357 fcmov%f1\t{%3, %0|%0, %3}"
16358 [(set_attr "type" "fcmov")
16359 (set_attr "mode" "XF")])
16360
16361 (define_insn "*movdfcc_1_rex64"
16362 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16363 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16364 [(reg FLAGS_REG) (const_int 0)])
16365 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16366 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16367 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16368 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16369 "@
16370 fcmov%F1\t{%2, %0|%0, %2}
16371 fcmov%f1\t{%3, %0|%0, %3}
16372 cmov%O2%C1\t{%2, %0|%0, %2}
16373 cmov%O2%c1\t{%3, %0|%0, %3}"
16374 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16375 (set_attr "mode" "DF,DF,DI,DI")])
16376
16377 (define_insn "*movdfcc_1"
16378 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16379 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16380 [(reg FLAGS_REG) (const_int 0)])
16381 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16382 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16383 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16384 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16385 "@
16386 fcmov%F1\t{%2, %0|%0, %2}
16387 fcmov%f1\t{%3, %0|%0, %3}
16388 #
16389 #"
16390 [(set_attr "type" "fcmov,fcmov,multi,multi")
16391 (set_attr "mode" "DF,DF,DI,DI")])
16392
16393 (define_split
16394 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16395 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16396 [(match_operand 4 "flags_reg_operand" "")
16397 (const_int 0)])
16398 (match_operand:DF 2 "nonimmediate_operand" "")
16399 (match_operand:DF 3 "nonimmediate_operand" "")))]
16400 "!TARGET_64BIT && reload_completed"
16401 [(set (match_dup 2)
16402 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16403 (match_dup 5)
16404 (match_dup 6)))
16405 (set (match_dup 3)
16406 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16407 (match_dup 7)
16408 (match_dup 8)))]
16409 {
16410 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16411 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16412 })
16413
16414 (define_insn "*movsfcc_1_387"
16415 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16416 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16417 [(reg FLAGS_REG) (const_int 0)])
16418 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16419 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16420 "TARGET_80387 && TARGET_CMOVE
16421 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16422 "@
16423 fcmov%F1\t{%2, %0|%0, %2}
16424 fcmov%f1\t{%3, %0|%0, %3}
16425 cmov%O2%C1\t{%2, %0|%0, %2}
16426 cmov%O2%c1\t{%3, %0|%0, %3}"
16427 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16428 (set_attr "mode" "SF,SF,SI,SI")])
16429
16430 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16431 ;; the scalar versions to have only XMM registers as operands.
16432
16433 ;; XOP conditional move
16434 (define_insn "*xop_pcmov_<mode>"
16435 [(set (match_operand:MODEF 0 "register_operand" "=x")
16436 (if_then_else:MODEF
16437 (match_operand:MODEF 1 "register_operand" "x")
16438 (match_operand:MODEF 2 "register_operand" "x")
16439 (match_operand:MODEF 3 "register_operand" "x")))]
16440 "TARGET_XOP"
16441 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16442 [(set_attr "type" "sse4arg")])
16443
16444 ;; These versions of the min/max patterns are intentionally ignorant of
16445 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16446 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16447 ;; are undefined in this condition, we're certain this is correct.
16448
16449 (define_insn "<code><mode>3"
16450 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16451 (smaxmin:MODEF
16452 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16453 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16454 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16455 "@
16456 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16457 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16458 [(set_attr "isa" "noavx,avx")
16459 (set_attr "prefix" "orig,vex")
16460 (set_attr "type" "sseadd")
16461 (set_attr "mode" "<MODE>")])
16462
16463 ;; These versions of the min/max patterns implement exactly the operations
16464 ;; min = (op1 < op2 ? op1 : op2)
16465 ;; max = (!(op1 < op2) ? op1 : op2)
16466 ;; Their operands are not commutative, and thus they may be used in the
16467 ;; presence of -0.0 and NaN.
16468
16469 (define_insn "*ieee_smin<mode>3"
16470 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16471 (unspec:MODEF
16472 [(match_operand:MODEF 1 "register_operand" "0,x")
16473 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16474 UNSPEC_IEEE_MIN))]
16475 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16476 "@
16477 min<ssemodesuffix>\t{%2, %0|%0, %2}
16478 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16479 [(set_attr "isa" "noavx,avx")
16480 (set_attr "prefix" "orig,vex")
16481 (set_attr "type" "sseadd")
16482 (set_attr "mode" "<MODE>")])
16483
16484 (define_insn "*ieee_smax<mode>3"
16485 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16486 (unspec:MODEF
16487 [(match_operand:MODEF 1 "register_operand" "0,x")
16488 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16489 UNSPEC_IEEE_MAX))]
16490 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16491 "@
16492 max<ssemodesuffix>\t{%2, %0|%0, %2}
16493 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16494 [(set_attr "isa" "noavx,avx")
16495 (set_attr "prefix" "orig,vex")
16496 (set_attr "type" "sseadd")
16497 (set_attr "mode" "<MODE>")])
16498
16499 ;; Make two stack loads independent:
16500 ;; fld aa fld aa
16501 ;; fld %st(0) -> fld bb
16502 ;; fmul bb fmul %st(1), %st
16503 ;;
16504 ;; Actually we only match the last two instructions for simplicity.
16505 (define_peephole2
16506 [(set (match_operand 0 "fp_register_operand" "")
16507 (match_operand 1 "fp_register_operand" ""))
16508 (set (match_dup 0)
16509 (match_operator 2 "binary_fp_operator"
16510 [(match_dup 0)
16511 (match_operand 3 "memory_operand" "")]))]
16512 "REGNO (operands[0]) != REGNO (operands[1])"
16513 [(set (match_dup 0) (match_dup 3))
16514 (set (match_dup 0) (match_dup 4))]
16515
16516 ;; The % modifier is not operational anymore in peephole2's, so we have to
16517 ;; swap the operands manually in the case of addition and multiplication.
16518 "if (COMMUTATIVE_ARITH_P (operands[2]))
16519 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16520 GET_MODE (operands[2]),
16521 operands[0], operands[1]);
16522 else
16523 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16524 GET_MODE (operands[2]),
16525 operands[1], operands[0]);")
16526
16527 ;; Conditional addition patterns
16528 (define_expand "add<mode>cc"
16529 [(match_operand:SWI 0 "register_operand" "")
16530 (match_operand 1 "ordered_comparison_operator" "")
16531 (match_operand:SWI 2 "register_operand" "")
16532 (match_operand:SWI 3 "const_int_operand" "")]
16533 ""
16534 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16535 \f
16536 ;; Misc patterns (?)
16537
16538 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16539 ;; Otherwise there will be nothing to keep
16540 ;;
16541 ;; [(set (reg ebp) (reg esp))]
16542 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16543 ;; (clobber (eflags)]
16544 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16545 ;;
16546 ;; in proper program order.
16547
16548 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16549 [(set (match_operand:P 0 "register_operand" "=r,r")
16550 (plus:P (match_operand:P 1 "register_operand" "0,r")
16551 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16552 (clobber (reg:CC FLAGS_REG))
16553 (clobber (mem:BLK (scratch)))]
16554 ""
16555 {
16556 switch (get_attr_type (insn))
16557 {
16558 case TYPE_IMOV:
16559 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16560
16561 case TYPE_ALU:
16562 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16563 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16564 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16565
16566 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16567
16568 default:
16569 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16570 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16571 }
16572 }
16573 [(set (attr "type")
16574 (cond [(and (eq_attr "alternative" "0")
16575 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16576 (const_string "alu")
16577 (match_operand:<MODE> 2 "const0_operand" "")
16578 (const_string "imov")
16579 ]
16580 (const_string "lea")))
16581 (set (attr "length_immediate")
16582 (cond [(eq_attr "type" "imov")
16583 (const_string "0")
16584 (and (eq_attr "type" "alu")
16585 (match_operand 2 "const128_operand" ""))
16586 (const_string "1")
16587 ]
16588 (const_string "*")))
16589 (set_attr "mode" "<MODE>")])
16590
16591 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16592 [(set (match_operand:P 0 "register_operand" "=r")
16593 (minus:P (match_operand:P 1 "register_operand" "0")
16594 (match_operand:P 2 "register_operand" "r")))
16595 (clobber (reg:CC FLAGS_REG))
16596 (clobber (mem:BLK (scratch)))]
16597 ""
16598 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16599 [(set_attr "type" "alu")
16600 (set_attr "mode" "<MODE>")])
16601
16602 (define_insn "allocate_stack_worker_probe_<mode>"
16603 [(set (match_operand:P 0 "register_operand" "=a")
16604 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16605 UNSPECV_STACK_PROBE))
16606 (clobber (reg:CC FLAGS_REG))]
16607 "ix86_target_stack_probe ()"
16608 "call\t___chkstk_ms"
16609 [(set_attr "type" "multi")
16610 (set_attr "length" "5")])
16611
16612 (define_expand "allocate_stack"
16613 [(match_operand 0 "register_operand" "")
16614 (match_operand 1 "general_operand" "")]
16615 "ix86_target_stack_probe ()"
16616 {
16617 rtx x;
16618
16619 #ifndef CHECK_STACK_LIMIT
16620 #define CHECK_STACK_LIMIT 0
16621 #endif
16622
16623 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16624 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16625 {
16626 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16627 stack_pointer_rtx, 0, OPTAB_DIRECT);
16628 if (x != stack_pointer_rtx)
16629 emit_move_insn (stack_pointer_rtx, x);
16630 }
16631 else
16632 {
16633 x = copy_to_mode_reg (Pmode, operands[1]);
16634 if (TARGET_64BIT)
16635 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16636 else
16637 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16638 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16639 stack_pointer_rtx, 0, OPTAB_DIRECT);
16640 if (x != stack_pointer_rtx)
16641 emit_move_insn (stack_pointer_rtx, x);
16642 }
16643
16644 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16645 DONE;
16646 })
16647
16648 ;; Use IOR for stack probes, this is shorter.
16649 (define_expand "probe_stack"
16650 [(match_operand 0 "memory_operand" "")]
16651 ""
16652 {
16653 rtx (*gen_ior3) (rtx, rtx, rtx);
16654
16655 gen_ior3 = (GET_MODE (operands[0]) == DImode
16656 ? gen_iordi3 : gen_iorsi3);
16657
16658 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16659 DONE;
16660 })
16661
16662 (define_insn "adjust_stack_and_probe<mode>"
16663 [(set (match_operand:P 0 "register_operand" "=r")
16664 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16665 UNSPECV_PROBE_STACK_RANGE))
16666 (set (reg:P SP_REG)
16667 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16668 (clobber (reg:CC FLAGS_REG))
16669 (clobber (mem:BLK (scratch)))]
16670 ""
16671 "* return output_adjust_stack_and_probe (operands[0]);"
16672 [(set_attr "type" "multi")])
16673
16674 (define_insn "probe_stack_range<mode>"
16675 [(set (match_operand:P 0 "register_operand" "=r")
16676 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16677 (match_operand:P 2 "const_int_operand" "n")]
16678 UNSPECV_PROBE_STACK_RANGE))
16679 (clobber (reg:CC FLAGS_REG))]
16680 ""
16681 "* return output_probe_stack_range (operands[0], operands[2]);"
16682 [(set_attr "type" "multi")])
16683
16684 (define_expand "builtin_setjmp_receiver"
16685 [(label_ref (match_operand 0 "" ""))]
16686 "!TARGET_64BIT && flag_pic"
16687 {
16688 #if TARGET_MACHO
16689 if (TARGET_MACHO)
16690 {
16691 rtx xops[3];
16692 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16693 rtx label_rtx = gen_label_rtx ();
16694 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16695 xops[0] = xops[1] = picreg;
16696 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16697 ix86_expand_binary_operator (MINUS, SImode, xops);
16698 }
16699 else
16700 #endif
16701 emit_insn (gen_set_got (pic_offset_table_rtx));
16702 DONE;
16703 })
16704 \f
16705 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16706
16707 (define_split
16708 [(set (match_operand 0 "register_operand" "")
16709 (match_operator 3 "promotable_binary_operator"
16710 [(match_operand 1 "register_operand" "")
16711 (match_operand 2 "aligned_operand" "")]))
16712 (clobber (reg:CC FLAGS_REG))]
16713 "! TARGET_PARTIAL_REG_STALL && reload_completed
16714 && ((GET_MODE (operands[0]) == HImode
16715 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16716 /* ??? next two lines just !satisfies_constraint_K (...) */
16717 || !CONST_INT_P (operands[2])
16718 || satisfies_constraint_K (operands[2])))
16719 || (GET_MODE (operands[0]) == QImode
16720 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16721 [(parallel [(set (match_dup 0)
16722 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16723 (clobber (reg:CC FLAGS_REG))])]
16724 "operands[0] = gen_lowpart (SImode, operands[0]);
16725 operands[1] = gen_lowpart (SImode, operands[1]);
16726 if (GET_CODE (operands[3]) != ASHIFT)
16727 operands[2] = gen_lowpart (SImode, operands[2]);
16728 PUT_MODE (operands[3], SImode);")
16729
16730 ; Promote the QImode tests, as i386 has encoding of the AND
16731 ; instruction with 32-bit sign-extended immediate and thus the
16732 ; instruction size is unchanged, except in the %eax case for
16733 ; which it is increased by one byte, hence the ! optimize_size.
16734 (define_split
16735 [(set (match_operand 0 "flags_reg_operand" "")
16736 (match_operator 2 "compare_operator"
16737 [(and (match_operand 3 "aligned_operand" "")
16738 (match_operand 4 "const_int_operand" ""))
16739 (const_int 0)]))
16740 (set (match_operand 1 "register_operand" "")
16741 (and (match_dup 3) (match_dup 4)))]
16742 "! TARGET_PARTIAL_REG_STALL && reload_completed
16743 && optimize_insn_for_speed_p ()
16744 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16745 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16746 /* Ensure that the operand will remain sign-extended immediate. */
16747 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16748 [(parallel [(set (match_dup 0)
16749 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16750 (const_int 0)]))
16751 (set (match_dup 1)
16752 (and:SI (match_dup 3) (match_dup 4)))])]
16753 {
16754 operands[4]
16755 = gen_int_mode (INTVAL (operands[4])
16756 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16757 operands[1] = gen_lowpart (SImode, operands[1]);
16758 operands[3] = gen_lowpart (SImode, operands[3]);
16759 })
16760
16761 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16762 ; the TEST instruction with 32-bit sign-extended immediate and thus
16763 ; the instruction size would at least double, which is not what we
16764 ; want even with ! optimize_size.
16765 (define_split
16766 [(set (match_operand 0 "flags_reg_operand" "")
16767 (match_operator 1 "compare_operator"
16768 [(and (match_operand:HI 2 "aligned_operand" "")
16769 (match_operand:HI 3 "const_int_operand" ""))
16770 (const_int 0)]))]
16771 "! TARGET_PARTIAL_REG_STALL && reload_completed
16772 && ! TARGET_FAST_PREFIX
16773 && optimize_insn_for_speed_p ()
16774 /* Ensure that the operand will remain sign-extended immediate. */
16775 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16776 [(set (match_dup 0)
16777 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16778 (const_int 0)]))]
16779 {
16780 operands[3]
16781 = gen_int_mode (INTVAL (operands[3])
16782 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16783 operands[2] = gen_lowpart (SImode, operands[2]);
16784 })
16785
16786 (define_split
16787 [(set (match_operand 0 "register_operand" "")
16788 (neg (match_operand 1 "register_operand" "")))
16789 (clobber (reg:CC FLAGS_REG))]
16790 "! TARGET_PARTIAL_REG_STALL && reload_completed
16791 && (GET_MODE (operands[0]) == HImode
16792 || (GET_MODE (operands[0]) == QImode
16793 && (TARGET_PROMOTE_QImode
16794 || optimize_insn_for_size_p ())))"
16795 [(parallel [(set (match_dup 0)
16796 (neg:SI (match_dup 1)))
16797 (clobber (reg:CC FLAGS_REG))])]
16798 "operands[0] = gen_lowpart (SImode, operands[0]);
16799 operands[1] = gen_lowpart (SImode, operands[1]);")
16800
16801 (define_split
16802 [(set (match_operand 0 "register_operand" "")
16803 (not (match_operand 1 "register_operand" "")))]
16804 "! TARGET_PARTIAL_REG_STALL && reload_completed
16805 && (GET_MODE (operands[0]) == HImode
16806 || (GET_MODE (operands[0]) == QImode
16807 && (TARGET_PROMOTE_QImode
16808 || optimize_insn_for_size_p ())))"
16809 [(set (match_dup 0)
16810 (not:SI (match_dup 1)))]
16811 "operands[0] = gen_lowpart (SImode, operands[0]);
16812 operands[1] = gen_lowpart (SImode, operands[1]);")
16813
16814 (define_split
16815 [(set (match_operand 0 "register_operand" "")
16816 (if_then_else (match_operator 1 "ordered_comparison_operator"
16817 [(reg FLAGS_REG) (const_int 0)])
16818 (match_operand 2 "register_operand" "")
16819 (match_operand 3 "register_operand" "")))]
16820 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16821 && (GET_MODE (operands[0]) == HImode
16822 || (GET_MODE (operands[0]) == QImode
16823 && (TARGET_PROMOTE_QImode
16824 || optimize_insn_for_size_p ())))"
16825 [(set (match_dup 0)
16826 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16827 "operands[0] = gen_lowpart (SImode, operands[0]);
16828 operands[2] = gen_lowpart (SImode, operands[2]);
16829 operands[3] = gen_lowpart (SImode, operands[3]);")
16830 \f
16831 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16832 ;; transform a complex memory operation into two memory to register operations.
16833
16834 ;; Don't push memory operands
16835 (define_peephole2
16836 [(set (match_operand:SWI 0 "push_operand" "")
16837 (match_operand:SWI 1 "memory_operand" ""))
16838 (match_scratch:SWI 2 "<r>")]
16839 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16840 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16841 [(set (match_dup 2) (match_dup 1))
16842 (set (match_dup 0) (match_dup 2))])
16843
16844 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16845 ;; SImode pushes.
16846 (define_peephole2
16847 [(set (match_operand:SF 0 "push_operand" "")
16848 (match_operand:SF 1 "memory_operand" ""))
16849 (match_scratch:SF 2 "r")]
16850 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16851 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16852 [(set (match_dup 2) (match_dup 1))
16853 (set (match_dup 0) (match_dup 2))])
16854
16855 ;; Don't move an immediate directly to memory when the instruction
16856 ;; gets too big.
16857 (define_peephole2
16858 [(match_scratch:SWI124 1 "<r>")
16859 (set (match_operand:SWI124 0 "memory_operand" "")
16860 (const_int 0))]
16861 "optimize_insn_for_speed_p ()
16862 && !TARGET_USE_MOV0
16863 && TARGET_SPLIT_LONG_MOVES
16864 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16865 && peep2_regno_dead_p (0, FLAGS_REG)"
16866 [(parallel [(set (match_dup 2) (const_int 0))
16867 (clobber (reg:CC FLAGS_REG))])
16868 (set (match_dup 0) (match_dup 1))]
16869 "operands[2] = gen_lowpart (SImode, operands[1]);")
16870
16871 (define_peephole2
16872 [(match_scratch:SWI124 2 "<r>")
16873 (set (match_operand:SWI124 0 "memory_operand" "")
16874 (match_operand:SWI124 1 "immediate_operand" ""))]
16875 "optimize_insn_for_speed_p ()
16876 && TARGET_SPLIT_LONG_MOVES
16877 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16878 [(set (match_dup 2) (match_dup 1))
16879 (set (match_dup 0) (match_dup 2))])
16880
16881 ;; Don't compare memory with zero, load and use a test instead.
16882 (define_peephole2
16883 [(set (match_operand 0 "flags_reg_operand" "")
16884 (match_operator 1 "compare_operator"
16885 [(match_operand:SI 2 "memory_operand" "")
16886 (const_int 0)]))
16887 (match_scratch:SI 3 "r")]
16888 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16889 [(set (match_dup 3) (match_dup 2))
16890 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16891
16892 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16893 ;; Don't split NOTs with a displacement operand, because resulting XOR
16894 ;; will not be pairable anyway.
16895 ;;
16896 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16897 ;; represented using a modRM byte. The XOR replacement is long decoded,
16898 ;; so this split helps here as well.
16899 ;;
16900 ;; Note: Can't do this as a regular split because we can't get proper
16901 ;; lifetime information then.
16902
16903 (define_peephole2
16904 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16905 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16906 "optimize_insn_for_speed_p ()
16907 && ((TARGET_NOT_UNPAIRABLE
16908 && (!MEM_P (operands[0])
16909 || !memory_displacement_operand (operands[0], <MODE>mode)))
16910 || (TARGET_NOT_VECTORMODE
16911 && long_memory_operand (operands[0], <MODE>mode)))
16912 && peep2_regno_dead_p (0, FLAGS_REG)"
16913 [(parallel [(set (match_dup 0)
16914 (xor:SWI124 (match_dup 1) (const_int -1)))
16915 (clobber (reg:CC FLAGS_REG))])])
16916
16917 ;; Non pairable "test imm, reg" instructions can be translated to
16918 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16919 ;; byte opcode instead of two, have a short form for byte operands),
16920 ;; so do it for other CPUs as well. Given that the value was dead,
16921 ;; this should not create any new dependencies. Pass on the sub-word
16922 ;; versions if we're concerned about partial register stalls.
16923
16924 (define_peephole2
16925 [(set (match_operand 0 "flags_reg_operand" "")
16926 (match_operator 1 "compare_operator"
16927 [(and:SI (match_operand:SI 2 "register_operand" "")
16928 (match_operand:SI 3 "immediate_operand" ""))
16929 (const_int 0)]))]
16930 "ix86_match_ccmode (insn, CCNOmode)
16931 && (true_regnum (operands[2]) != AX_REG
16932 || satisfies_constraint_K (operands[3]))
16933 && peep2_reg_dead_p (1, operands[2])"
16934 [(parallel
16935 [(set (match_dup 0)
16936 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16937 (const_int 0)]))
16938 (set (match_dup 2)
16939 (and:SI (match_dup 2) (match_dup 3)))])])
16940
16941 ;; We don't need to handle HImode case, because it will be promoted to SImode
16942 ;; on ! TARGET_PARTIAL_REG_STALL
16943
16944 (define_peephole2
16945 [(set (match_operand 0 "flags_reg_operand" "")
16946 (match_operator 1 "compare_operator"
16947 [(and:QI (match_operand:QI 2 "register_operand" "")
16948 (match_operand:QI 3 "immediate_operand" ""))
16949 (const_int 0)]))]
16950 "! TARGET_PARTIAL_REG_STALL
16951 && ix86_match_ccmode (insn, CCNOmode)
16952 && true_regnum (operands[2]) != AX_REG
16953 && peep2_reg_dead_p (1, operands[2])"
16954 [(parallel
16955 [(set (match_dup 0)
16956 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16957 (const_int 0)]))
16958 (set (match_dup 2)
16959 (and:QI (match_dup 2) (match_dup 3)))])])
16960
16961 (define_peephole2
16962 [(set (match_operand 0 "flags_reg_operand" "")
16963 (match_operator 1 "compare_operator"
16964 [(and:SI
16965 (zero_extract:SI
16966 (match_operand 2 "ext_register_operand" "")
16967 (const_int 8)
16968 (const_int 8))
16969 (match_operand 3 "const_int_operand" ""))
16970 (const_int 0)]))]
16971 "! TARGET_PARTIAL_REG_STALL
16972 && ix86_match_ccmode (insn, CCNOmode)
16973 && true_regnum (operands[2]) != AX_REG
16974 && peep2_reg_dead_p (1, operands[2])"
16975 [(parallel [(set (match_dup 0)
16976 (match_op_dup 1
16977 [(and:SI
16978 (zero_extract:SI
16979 (match_dup 2)
16980 (const_int 8)
16981 (const_int 8))
16982 (match_dup 3))
16983 (const_int 0)]))
16984 (set (zero_extract:SI (match_dup 2)
16985 (const_int 8)
16986 (const_int 8))
16987 (and:SI
16988 (zero_extract:SI
16989 (match_dup 2)
16990 (const_int 8)
16991 (const_int 8))
16992 (match_dup 3)))])])
16993
16994 ;; Don't do logical operations with memory inputs.
16995 (define_peephole2
16996 [(match_scratch:SI 2 "r")
16997 (parallel [(set (match_operand:SI 0 "register_operand" "")
16998 (match_operator:SI 3 "arith_or_logical_operator"
16999 [(match_dup 0)
17000 (match_operand:SI 1 "memory_operand" "")]))
17001 (clobber (reg:CC FLAGS_REG))])]
17002 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17003 [(set (match_dup 2) (match_dup 1))
17004 (parallel [(set (match_dup 0)
17005 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17006 (clobber (reg:CC FLAGS_REG))])])
17007
17008 (define_peephole2
17009 [(match_scratch:SI 2 "r")
17010 (parallel [(set (match_operand:SI 0 "register_operand" "")
17011 (match_operator:SI 3 "arith_or_logical_operator"
17012 [(match_operand:SI 1 "memory_operand" "")
17013 (match_dup 0)]))
17014 (clobber (reg:CC FLAGS_REG))])]
17015 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17016 [(set (match_dup 2) (match_dup 1))
17017 (parallel [(set (match_dup 0)
17018 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17019 (clobber (reg:CC FLAGS_REG))])])
17020
17021 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17022 ;; refers to the destination of the load!
17023
17024 (define_peephole2
17025 [(set (match_operand:SI 0 "register_operand" "")
17026 (match_operand:SI 1 "register_operand" ""))
17027 (parallel [(set (match_dup 0)
17028 (match_operator:SI 3 "commutative_operator"
17029 [(match_dup 0)
17030 (match_operand:SI 2 "memory_operand" "")]))
17031 (clobber (reg:CC FLAGS_REG))])]
17032 "REGNO (operands[0]) != REGNO (operands[1])
17033 && GENERAL_REGNO_P (REGNO (operands[0]))
17034 && GENERAL_REGNO_P (REGNO (operands[1]))"
17035 [(set (match_dup 0) (match_dup 4))
17036 (parallel [(set (match_dup 0)
17037 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17038 (clobber (reg:CC FLAGS_REG))])]
17039 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17040
17041 (define_peephole2
17042 [(set (match_operand 0 "register_operand" "")
17043 (match_operand 1 "register_operand" ""))
17044 (set (match_dup 0)
17045 (match_operator 3 "commutative_operator"
17046 [(match_dup 0)
17047 (match_operand 2 "memory_operand" "")]))]
17048 "REGNO (operands[0]) != REGNO (operands[1])
17049 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17050 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17051 [(set (match_dup 0) (match_dup 2))
17052 (set (match_dup 0)
17053 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17054
17055 ; Don't do logical operations with memory outputs
17056 ;
17057 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17058 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17059 ; the same decoder scheduling characteristics as the original.
17060
17061 (define_peephole2
17062 [(match_scratch:SI 2 "r")
17063 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17064 (match_operator:SI 3 "arith_or_logical_operator"
17065 [(match_dup 0)
17066 (match_operand:SI 1 "nonmemory_operand" "")]))
17067 (clobber (reg:CC FLAGS_REG))])]
17068 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17069 /* Do not split stack checking probes. */
17070 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17071 [(set (match_dup 2) (match_dup 0))
17072 (parallel [(set (match_dup 2)
17073 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17074 (clobber (reg:CC FLAGS_REG))])
17075 (set (match_dup 0) (match_dup 2))])
17076
17077 (define_peephole2
17078 [(match_scratch:SI 2 "r")
17079 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17080 (match_operator:SI 3 "arith_or_logical_operator"
17081 [(match_operand:SI 1 "nonmemory_operand" "")
17082 (match_dup 0)]))
17083 (clobber (reg:CC FLAGS_REG))])]
17084 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17085 /* Do not split stack checking probes. */
17086 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17087 [(set (match_dup 2) (match_dup 0))
17088 (parallel [(set (match_dup 2)
17089 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17090 (clobber (reg:CC FLAGS_REG))])
17091 (set (match_dup 0) (match_dup 2))])
17092
17093 ;; Attempt to always use XOR for zeroing registers.
17094 (define_peephole2
17095 [(set (match_operand 0 "register_operand" "")
17096 (match_operand 1 "const0_operand" ""))]
17097 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17098 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17099 && GENERAL_REG_P (operands[0])
17100 && peep2_regno_dead_p (0, FLAGS_REG)"
17101 [(parallel [(set (match_dup 0) (const_int 0))
17102 (clobber (reg:CC FLAGS_REG))])]
17103 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17104
17105 (define_peephole2
17106 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17107 (const_int 0))]
17108 "(GET_MODE (operands[0]) == QImode
17109 || GET_MODE (operands[0]) == HImode)
17110 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17111 && peep2_regno_dead_p (0, FLAGS_REG)"
17112 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17113 (clobber (reg:CC FLAGS_REG))])])
17114
17115 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17116 (define_peephole2
17117 [(set (match_operand:SWI248 0 "register_operand" "")
17118 (const_int -1))]
17119 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17120 && peep2_regno_dead_p (0, FLAGS_REG)"
17121 [(parallel [(set (match_dup 0) (const_int -1))
17122 (clobber (reg:CC FLAGS_REG))])]
17123 {
17124 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17125 operands[0] = gen_lowpart (SImode, operands[0]);
17126 })
17127
17128 ;; Attempt to convert simple lea to add/shift.
17129 ;; These can be created by move expanders.
17130
17131 (define_peephole2
17132 [(set (match_operand:SWI48 0 "register_operand" "")
17133 (plus:SWI48 (match_dup 0)
17134 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17135 "peep2_regno_dead_p (0, FLAGS_REG)"
17136 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17137 (clobber (reg:CC FLAGS_REG))])])
17138
17139 (define_peephole2
17140 [(set (match_operand:SI 0 "register_operand" "")
17141 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17142 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17143 "TARGET_64BIT
17144 && peep2_regno_dead_p (0, FLAGS_REG)
17145 && REGNO (operands[0]) == REGNO (operands[1])"
17146 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17147 (clobber (reg:CC FLAGS_REG))])]
17148 "operands[2] = gen_lowpart (SImode, operands[2]);")
17149
17150 (define_peephole2
17151 [(set (match_operand:SWI48 0 "register_operand" "")
17152 (mult:SWI48 (match_dup 0)
17153 (match_operand:SWI48 1 "const_int_operand" "")))]
17154 "exact_log2 (INTVAL (operands[1])) >= 0
17155 && peep2_regno_dead_p (0, FLAGS_REG)"
17156 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17157 (clobber (reg:CC FLAGS_REG))])]
17158 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17159
17160 (define_peephole2
17161 [(set (match_operand:SI 0 "register_operand" "")
17162 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17163 (match_operand:DI 2 "const_int_operand" "")) 0))]
17164 "TARGET_64BIT
17165 && exact_log2 (INTVAL (operands[2])) >= 0
17166 && REGNO (operands[0]) == REGNO (operands[1])
17167 && peep2_regno_dead_p (0, FLAGS_REG)"
17168 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17171
17172 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17173 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17174 ;; On many CPUs it is also faster, since special hardware to avoid esp
17175 ;; dependencies is present.
17176
17177 ;; While some of these conversions may be done using splitters, we use
17178 ;; peepholes in order to allow combine_stack_adjustments pass to see
17179 ;; nonobfuscated RTL.
17180
17181 ;; Convert prologue esp subtractions to push.
17182 ;; We need register to push. In order to keep verify_flow_info happy we have
17183 ;; two choices
17184 ;; - use scratch and clobber it in order to avoid dependencies
17185 ;; - use already live register
17186 ;; We can't use the second way right now, since there is no reliable way how to
17187 ;; verify that given register is live. First choice will also most likely in
17188 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17189 ;; call clobbered registers are dead. We may want to use base pointer as an
17190 ;; alternative when no register is available later.
17191
17192 (define_peephole2
17193 [(match_scratch:P 1 "r")
17194 (parallel [(set (reg:P SP_REG)
17195 (plus:P (reg:P SP_REG)
17196 (match_operand:P 0 "const_int_operand" "")))
17197 (clobber (reg:CC FLAGS_REG))
17198 (clobber (mem:BLK (scratch)))])]
17199 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17200 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17201 [(clobber (match_dup 1))
17202 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17203 (clobber (mem:BLK (scratch)))])])
17204
17205 (define_peephole2
17206 [(match_scratch:P 1 "r")
17207 (parallel [(set (reg:P SP_REG)
17208 (plus:P (reg:P SP_REG)
17209 (match_operand:P 0 "const_int_operand" "")))
17210 (clobber (reg:CC FLAGS_REG))
17211 (clobber (mem:BLK (scratch)))])]
17212 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17213 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17214 [(clobber (match_dup 1))
17215 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17216 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17217 (clobber (mem:BLK (scratch)))])])
17218
17219 ;; Convert esp subtractions to push.
17220 (define_peephole2
17221 [(match_scratch:P 1 "r")
17222 (parallel [(set (reg:P SP_REG)
17223 (plus:P (reg:P SP_REG)
17224 (match_operand:P 0 "const_int_operand" "")))
17225 (clobber (reg:CC FLAGS_REG))])]
17226 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17227 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17228 [(clobber (match_dup 1))
17229 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17230
17231 (define_peephole2
17232 [(match_scratch:P 1 "r")
17233 (parallel [(set (reg:P SP_REG)
17234 (plus:P (reg:P SP_REG)
17235 (match_operand:P 0 "const_int_operand" "")))
17236 (clobber (reg:CC FLAGS_REG))])]
17237 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17238 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17239 [(clobber (match_dup 1))
17240 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17241 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17242
17243 ;; Convert epilogue deallocator to pop.
17244 (define_peephole2
17245 [(match_scratch:P 1 "r")
17246 (parallel [(set (reg:P SP_REG)
17247 (plus:P (reg:P SP_REG)
17248 (match_operand:P 0 "const_int_operand" "")))
17249 (clobber (reg:CC FLAGS_REG))
17250 (clobber (mem:BLK (scratch)))])]
17251 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17252 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17253 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17254 (clobber (mem:BLK (scratch)))])])
17255
17256 ;; Two pops case is tricky, since pop causes dependency
17257 ;; on destination register. We use two registers if available.
17258 (define_peephole2
17259 [(match_scratch:P 1 "r")
17260 (match_scratch:P 2 "r")
17261 (parallel [(set (reg:P SP_REG)
17262 (plus:P (reg:P SP_REG)
17263 (match_operand:P 0 "const_int_operand" "")))
17264 (clobber (reg:CC FLAGS_REG))
17265 (clobber (mem:BLK (scratch)))])]
17266 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17267 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17268 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17269 (clobber (mem:BLK (scratch)))])
17270 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17271
17272 (define_peephole2
17273 [(match_scratch:P 1 "r")
17274 (parallel [(set (reg:P SP_REG)
17275 (plus:P (reg:P SP_REG)
17276 (match_operand:P 0 "const_int_operand" "")))
17277 (clobber (reg:CC FLAGS_REG))
17278 (clobber (mem:BLK (scratch)))])]
17279 "optimize_insn_for_size_p ()
17280 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17281 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17282 (clobber (mem:BLK (scratch)))])
17283 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17284
17285 ;; Convert esp additions to pop.
17286 (define_peephole2
17287 [(match_scratch:P 1 "r")
17288 (parallel [(set (reg:P SP_REG)
17289 (plus:P (reg:P SP_REG)
17290 (match_operand:P 0 "const_int_operand" "")))
17291 (clobber (reg:CC FLAGS_REG))])]
17292 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17293 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17294
17295 ;; Two pops case is tricky, since pop causes dependency
17296 ;; on destination register. We use two registers if available.
17297 (define_peephole2
17298 [(match_scratch:P 1 "r")
17299 (match_scratch:P 2 "r")
17300 (parallel [(set (reg:P SP_REG)
17301 (plus:P (reg:P SP_REG)
17302 (match_operand:P 0 "const_int_operand" "")))
17303 (clobber (reg:CC FLAGS_REG))])]
17304 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17305 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17306 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17307
17308 (define_peephole2
17309 [(match_scratch:P 1 "r")
17310 (parallel [(set (reg:P SP_REG)
17311 (plus:P (reg:P SP_REG)
17312 (match_operand:P 0 "const_int_operand" "")))
17313 (clobber (reg:CC FLAGS_REG))])]
17314 "optimize_insn_for_size_p ()
17315 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17316 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17317 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17318 \f
17319 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17320 ;; required and register dies. Similarly for 128 to -128.
17321 (define_peephole2
17322 [(set (match_operand 0 "flags_reg_operand" "")
17323 (match_operator 1 "compare_operator"
17324 [(match_operand 2 "register_operand" "")
17325 (match_operand 3 "const_int_operand" "")]))]
17326 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17327 && incdec_operand (operands[3], GET_MODE (operands[3])))
17328 || (!TARGET_FUSE_CMP_AND_BRANCH
17329 && INTVAL (operands[3]) == 128))
17330 && ix86_match_ccmode (insn, CCGCmode)
17331 && peep2_reg_dead_p (1, operands[2])"
17332 [(parallel [(set (match_dup 0)
17333 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17334 (clobber (match_dup 2))])])
17335 \f
17336 ;; Convert imul by three, five and nine into lea
17337 (define_peephole2
17338 [(parallel
17339 [(set (match_operand:SWI48 0 "register_operand" "")
17340 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17341 (match_operand:SWI48 2 "const_int_operand" "")))
17342 (clobber (reg:CC FLAGS_REG))])]
17343 "INTVAL (operands[2]) == 3
17344 || INTVAL (operands[2]) == 5
17345 || INTVAL (operands[2]) == 9"
17346 [(set (match_dup 0)
17347 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17348 (match_dup 1)))]
17349 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17350
17351 (define_peephole2
17352 [(parallel
17353 [(set (match_operand:SWI48 0 "register_operand" "")
17354 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17355 (match_operand:SWI48 2 "const_int_operand" "")))
17356 (clobber (reg:CC FLAGS_REG))])]
17357 "optimize_insn_for_speed_p ()
17358 && (INTVAL (operands[2]) == 3
17359 || INTVAL (operands[2]) == 5
17360 || INTVAL (operands[2]) == 9)"
17361 [(set (match_dup 0) (match_dup 1))
17362 (set (match_dup 0)
17363 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17364 (match_dup 0)))]
17365 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17366
17367 ;; imul $32bit_imm, mem, reg is vector decoded, while
17368 ;; imul $32bit_imm, reg, reg is direct decoded.
17369 (define_peephole2
17370 [(match_scratch:SWI48 3 "r")
17371 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17372 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17373 (match_operand:SWI48 2 "immediate_operand" "")))
17374 (clobber (reg:CC FLAGS_REG))])]
17375 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17376 && !satisfies_constraint_K (operands[2])"
17377 [(set (match_dup 3) (match_dup 1))
17378 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17379 (clobber (reg:CC FLAGS_REG))])])
17380
17381 (define_peephole2
17382 [(match_scratch:SI 3 "r")
17383 (parallel [(set (match_operand:DI 0 "register_operand" "")
17384 (zero_extend:DI
17385 (mult:SI (match_operand:SI 1 "memory_operand" "")
17386 (match_operand:SI 2 "immediate_operand" ""))))
17387 (clobber (reg:CC FLAGS_REG))])]
17388 "TARGET_64BIT
17389 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17390 && !satisfies_constraint_K (operands[2])"
17391 [(set (match_dup 3) (match_dup 1))
17392 (parallel [(set (match_dup 0)
17393 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17394 (clobber (reg:CC FLAGS_REG))])])
17395
17396 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17397 ;; Convert it into imul reg, reg
17398 ;; It would be better to force assembler to encode instruction using long
17399 ;; immediate, but there is apparently no way to do so.
17400 (define_peephole2
17401 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17402 (mult:SWI248
17403 (match_operand:SWI248 1 "nonimmediate_operand" "")
17404 (match_operand:SWI248 2 "const_int_operand" "")))
17405 (clobber (reg:CC FLAGS_REG))])
17406 (match_scratch:SWI248 3 "r")]
17407 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17408 && satisfies_constraint_K (operands[2])"
17409 [(set (match_dup 3) (match_dup 2))
17410 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17411 (clobber (reg:CC FLAGS_REG))])]
17412 {
17413 if (!rtx_equal_p (operands[0], operands[1]))
17414 emit_move_insn (operands[0], operands[1]);
17415 })
17416
17417 ;; After splitting up read-modify operations, array accesses with memory
17418 ;; operands might end up in form:
17419 ;; sall $2, %eax
17420 ;; movl 4(%esp), %edx
17421 ;; addl %edx, %eax
17422 ;; instead of pre-splitting:
17423 ;; sall $2, %eax
17424 ;; addl 4(%esp), %eax
17425 ;; Turn it into:
17426 ;; movl 4(%esp), %edx
17427 ;; leal (%edx,%eax,4), %eax
17428
17429 (define_peephole2
17430 [(match_scratch:P 5 "r")
17431 (parallel [(set (match_operand 0 "register_operand" "")
17432 (ashift (match_operand 1 "register_operand" "")
17433 (match_operand 2 "const_int_operand" "")))
17434 (clobber (reg:CC FLAGS_REG))])
17435 (parallel [(set (match_operand 3 "register_operand" "")
17436 (plus (match_dup 0)
17437 (match_operand 4 "x86_64_general_operand" "")))
17438 (clobber (reg:CC FLAGS_REG))])]
17439 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17440 /* Validate MODE for lea. */
17441 && ((!TARGET_PARTIAL_REG_STALL
17442 && (GET_MODE (operands[0]) == QImode
17443 || GET_MODE (operands[0]) == HImode))
17444 || GET_MODE (operands[0]) == SImode
17445 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17446 && (rtx_equal_p (operands[0], operands[3])
17447 || peep2_reg_dead_p (2, operands[0]))
17448 /* We reorder load and the shift. */
17449 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17450 [(set (match_dup 5) (match_dup 4))
17451 (set (match_dup 0) (match_dup 1))]
17452 {
17453 enum machine_mode op1mode = GET_MODE (operands[1]);
17454 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17455 int scale = 1 << INTVAL (operands[2]);
17456 rtx index = gen_lowpart (Pmode, operands[1]);
17457 rtx base = gen_lowpart (Pmode, operands[5]);
17458 rtx dest = gen_lowpart (mode, operands[3]);
17459
17460 operands[1] = gen_rtx_PLUS (Pmode, base,
17461 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17462 operands[5] = base;
17463 if (mode != Pmode)
17464 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17465 if (op1mode != Pmode)
17466 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17467 operands[0] = dest;
17468 })
17469 \f
17470 ;; Call-value patterns last so that the wildcard operand does not
17471 ;; disrupt insn-recog's switch tables.
17472
17473 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17474 [(parallel
17475 [(set (match_operand 0 "" "")
17476 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17477 (match_operand:SI 2 "" "")))
17478 (set (reg:SI SP_REG)
17479 (plus:SI (reg:SI SP_REG)
17480 (match_operand:SI 3 "immediate_operand" "")))])
17481 (unspec [(match_operand 4 "const_int_operand" "")]
17482 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17483 "TARGET_VZEROUPPER && !TARGET_64BIT"
17484 "#"
17485 "&& reload_completed"
17486 [(const_int 0)]
17487 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17488 [(set_attr "type" "callv")])
17489
17490 (define_insn "*call_value_pop_0"
17491 [(set (match_operand 0 "" "")
17492 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17493 (match_operand:SI 2 "" "")))
17494 (set (reg:SI SP_REG)
17495 (plus:SI (reg:SI SP_REG)
17496 (match_operand:SI 3 "immediate_operand" "")))]
17497 "!TARGET_64BIT"
17498 { return ix86_output_call_insn (insn, operands[1], 1); }
17499 [(set_attr "type" "callv")])
17500
17501 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17502 [(parallel
17503 [(set (match_operand 0 "" "")
17504 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17505 (match_operand:SI 2 "" "")))
17506 (set (reg:SI SP_REG)
17507 (plus:SI (reg:SI SP_REG)
17508 (match_operand:SI 3 "immediate_operand" "i")))])
17509 (unspec [(match_operand 4 "const_int_operand" "")]
17510 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17511 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17512 "#"
17513 "&& reload_completed"
17514 [(const_int 0)]
17515 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17516 [(set_attr "type" "callv")])
17517
17518 (define_insn "*call_value_pop_1"
17519 [(set (match_operand 0 "" "")
17520 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17521 (match_operand:SI 2 "" "")))
17522 (set (reg:SI SP_REG)
17523 (plus:SI (reg:SI SP_REG)
17524 (match_operand:SI 3 "immediate_operand" "i")))]
17525 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17526 { return ix86_output_call_insn (insn, operands[1], 1); }
17527 [(set_attr "type" "callv")])
17528
17529 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17530 [(parallel
17531 [(set (match_operand 0 "" "")
17532 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17533 (match_operand:SI 2 "" "")))
17534 (set (reg:SI SP_REG)
17535 (plus:SI (reg:SI SP_REG)
17536 (match_operand:SI 3 "immediate_operand" "i,i")))])
17537 (unspec [(match_operand 4 "const_int_operand" "")]
17538 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17539 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17540 "#"
17541 "&& reload_completed"
17542 [(const_int 0)]
17543 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17544 [(set_attr "type" "callv")])
17545
17546 (define_insn "*sibcall_value_pop_1"
17547 [(set (match_operand 0 "" "")
17548 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17549 (match_operand:SI 2 "" "")))
17550 (set (reg:SI SP_REG)
17551 (plus:SI (reg:SI SP_REG)
17552 (match_operand:SI 3 "immediate_operand" "i,i")))]
17553 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17554 { return ix86_output_call_insn (insn, operands[1], 1); }
17555 [(set_attr "type" "callv")])
17556
17557 (define_insn_and_split "*call_value_0_vzeroupper"
17558 [(set (match_operand 0 "" "")
17559 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17560 (match_operand:SI 2 "" "")))
17561 (unspec [(match_operand 3 "const_int_operand" "")]
17562 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17563 "TARGET_VZEROUPPER && !TARGET_64BIT"
17564 "#"
17565 "&& reload_completed"
17566 [(const_int 0)]
17567 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17568 [(set_attr "type" "callv")])
17569
17570 (define_insn "*call_value_0"
17571 [(set (match_operand 0 "" "")
17572 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17573 (match_operand:SI 2 "" "")))]
17574 "!TARGET_64BIT"
17575 { return ix86_output_call_insn (insn, operands[1], 1); }
17576 [(set_attr "type" "callv")])
17577
17578 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17579 [(set (match_operand 0 "" "")
17580 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17581 (match_operand:DI 2 "const_int_operand" "")))
17582 (unspec [(match_operand 3 "const_int_operand" "")]
17583 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17584 "TARGET_VZEROUPPER && TARGET_64BIT"
17585 "#"
17586 "&& reload_completed"
17587 [(const_int 0)]
17588 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17589 [(set_attr "type" "callv")])
17590
17591 (define_insn "*call_value_0_rex64"
17592 [(set (match_operand 0 "" "")
17593 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17594 (match_operand:DI 2 "const_int_operand" "")))]
17595 "TARGET_64BIT"
17596 { return ix86_output_call_insn (insn, operands[1], 1); }
17597 [(set_attr "type" "callv")])
17598
17599 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17600 [(parallel
17601 [(set (match_operand 0 "" "")
17602 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17603 (match_operand:DI 2 "const_int_operand" "")))
17604 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17605 (clobber (reg:TI XMM6_REG))
17606 (clobber (reg:TI XMM7_REG))
17607 (clobber (reg:TI XMM8_REG))
17608 (clobber (reg:TI XMM9_REG))
17609 (clobber (reg:TI XMM10_REG))
17610 (clobber (reg:TI XMM11_REG))
17611 (clobber (reg:TI XMM12_REG))
17612 (clobber (reg:TI XMM13_REG))
17613 (clobber (reg:TI XMM14_REG))
17614 (clobber (reg:TI XMM15_REG))
17615 (clobber (reg:DI SI_REG))
17616 (clobber (reg:DI DI_REG))])
17617 (unspec [(match_operand 3 "const_int_operand" "")]
17618 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17619 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17620 "#"
17621 "&& reload_completed"
17622 [(const_int 0)]
17623 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17624 [(set_attr "type" "callv")])
17625
17626 (define_insn "*call_value_0_rex64_ms_sysv"
17627 [(set (match_operand 0 "" "")
17628 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17629 (match_operand:DI 2 "const_int_operand" "")))
17630 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17631 (clobber (reg:TI XMM6_REG))
17632 (clobber (reg:TI XMM7_REG))
17633 (clobber (reg:TI XMM8_REG))
17634 (clobber (reg:TI XMM9_REG))
17635 (clobber (reg:TI XMM10_REG))
17636 (clobber (reg:TI XMM11_REG))
17637 (clobber (reg:TI XMM12_REG))
17638 (clobber (reg:TI XMM13_REG))
17639 (clobber (reg:TI XMM14_REG))
17640 (clobber (reg:TI XMM15_REG))
17641 (clobber (reg:DI SI_REG))
17642 (clobber (reg:DI DI_REG))]
17643 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17644 { return ix86_output_call_insn (insn, operands[1], 1); }
17645 [(set_attr "type" "callv")])
17646
17647 (define_insn_and_split "*call_value_1_vzeroupper"
17648 [(set (match_operand 0 "" "")
17649 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17650 (match_operand:SI 2 "" "")))
17651 (unspec [(match_operand 3 "const_int_operand" "")]
17652 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17653 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17654 "#"
17655 "&& reload_completed"
17656 [(const_int 0)]
17657 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17658 [(set_attr "type" "callv")])
17659
17660 (define_insn "*call_value_1"
17661 [(set (match_operand 0 "" "")
17662 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17663 (match_operand:SI 2 "" "")))]
17664 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17665 { return ix86_output_call_insn (insn, operands[1], 1); }
17666 [(set_attr "type" "callv")])
17667
17668 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17669 [(set (match_operand 0 "" "")
17670 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17671 (match_operand:SI 2 "" "")))
17672 (unspec [(match_operand 3 "const_int_operand" "")]
17673 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17674 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17675 "#"
17676 "&& reload_completed"
17677 [(const_int 0)]
17678 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17679 [(set_attr "type" "callv")])
17680
17681 (define_insn "*sibcall_value_1"
17682 [(set (match_operand 0 "" "")
17683 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17684 (match_operand:SI 2 "" "")))]
17685 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17686 { return ix86_output_call_insn (insn, operands[1], 1); }
17687 [(set_attr "type" "callv")])
17688
17689 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17690 [(set (match_operand 0 "" "")
17691 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17692 (match_operand:DI 2 "" "")))
17693 (unspec [(match_operand 3 "const_int_operand" "")]
17694 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17695 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17696 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17697 "#"
17698 "&& reload_completed"
17699 [(const_int 0)]
17700 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17701 [(set_attr "type" "callv")])
17702
17703 (define_insn "*call_value_1_rex64"
17704 [(set (match_operand 0 "" "")
17705 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17706 (match_operand:DI 2 "" "")))]
17707 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17708 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17709 { return ix86_output_call_insn (insn, operands[1], 1); }
17710 [(set_attr "type" "callv")])
17711
17712 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17713 [(parallel
17714 [(set (match_operand 0 "" "")
17715 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17716 (match_operand:DI 2 "" "")))
17717 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17718 (clobber (reg:TI XMM6_REG))
17719 (clobber (reg:TI XMM7_REG))
17720 (clobber (reg:TI XMM8_REG))
17721 (clobber (reg:TI XMM9_REG))
17722 (clobber (reg:TI XMM10_REG))
17723 (clobber (reg:TI XMM11_REG))
17724 (clobber (reg:TI XMM12_REG))
17725 (clobber (reg:TI XMM13_REG))
17726 (clobber (reg:TI XMM14_REG))
17727 (clobber (reg:TI XMM15_REG))
17728 (clobber (reg:DI SI_REG))
17729 (clobber (reg:DI DI_REG))])
17730 (unspec [(match_operand 3 "const_int_operand" "")]
17731 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17732 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17733 "#"
17734 "&& reload_completed"
17735 [(const_int 0)]
17736 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17737 [(set_attr "type" "callv")])
17738
17739 (define_insn "*call_value_1_rex64_ms_sysv"
17740 [(set (match_operand 0 "" "")
17741 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17742 (match_operand:DI 2 "" "")))
17743 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17744 (clobber (reg:TI XMM6_REG))
17745 (clobber (reg:TI XMM7_REG))
17746 (clobber (reg:TI XMM8_REG))
17747 (clobber (reg:TI XMM9_REG))
17748 (clobber (reg:TI XMM10_REG))
17749 (clobber (reg:TI XMM11_REG))
17750 (clobber (reg:TI XMM12_REG))
17751 (clobber (reg:TI XMM13_REG))
17752 (clobber (reg:TI XMM14_REG))
17753 (clobber (reg:TI XMM15_REG))
17754 (clobber (reg:DI SI_REG))
17755 (clobber (reg:DI DI_REG))]
17756 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17757 { return ix86_output_call_insn (insn, operands[1], 1); }
17758 [(set_attr "type" "callv")])
17759
17760 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17761 [(set (match_operand 0 "" "")
17762 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17763 (match_operand:DI 2 "" "")))
17764 (unspec [(match_operand 3 "const_int_operand" "")]
17765 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17766 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17767 "#"
17768 "&& reload_completed"
17769 [(const_int 0)]
17770 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17771 [(set_attr "type" "callv")])
17772
17773 (define_insn "*call_value_1_rex64_large"
17774 [(set (match_operand 0 "" "")
17775 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17776 (match_operand:DI 2 "" "")))]
17777 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17778 { return ix86_output_call_insn (insn, operands[1], 1); }
17779 [(set_attr "type" "callv")])
17780
17781 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17782 [(set (match_operand 0 "" "")
17783 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17784 (match_operand:DI 2 "" "")))
17785 (unspec [(match_operand 3 "const_int_operand" "")]
17786 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17787 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17788 "#"
17789 "&& reload_completed"
17790 [(const_int 0)]
17791 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17792 [(set_attr "type" "callv")])
17793
17794 (define_insn "*sibcall_value_1_rex64"
17795 [(set (match_operand 0 "" "")
17796 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17797 (match_operand:DI 2 "" "")))]
17798 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17799 { return ix86_output_call_insn (insn, operands[1], 1); }
17800 [(set_attr "type" "callv")])
17801 \f
17802 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17803 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17804 ;; caught for use by garbage collectors and the like. Using an insn that
17805 ;; maps to SIGILL makes it more likely the program will rightfully die.
17806 ;; Keeping with tradition, "6" is in honor of #UD.
17807 (define_insn "trap"
17808 [(trap_if (const_int 1) (const_int 6))]
17809 ""
17810 { return ASM_SHORT "0x0b0f"; }
17811 [(set_attr "length" "2")])
17812
17813 (define_expand "prefetch"
17814 [(prefetch (match_operand 0 "address_operand" "")
17815 (match_operand:SI 1 "const_int_operand" "")
17816 (match_operand:SI 2 "const_int_operand" ""))]
17817 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17818 {
17819 int rw = INTVAL (operands[1]);
17820 int locality = INTVAL (operands[2]);
17821
17822 gcc_assert (rw == 0 || rw == 1);
17823 gcc_assert (locality >= 0 && locality <= 3);
17824 gcc_assert (GET_MODE (operands[0]) == Pmode
17825 || GET_MODE (operands[0]) == VOIDmode);
17826
17827 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17828 supported by SSE counterpart or the SSE prefetch is not available
17829 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17830 of locality. */
17831 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17832 operands[2] = GEN_INT (3);
17833 else
17834 operands[1] = const0_rtx;
17835 })
17836
17837 (define_insn "*prefetch_sse_<mode>"
17838 [(prefetch (match_operand:P 0 "address_operand" "p")
17839 (const_int 0)
17840 (match_operand:SI 1 "const_int_operand" ""))]
17841 "TARGET_PREFETCH_SSE"
17842 {
17843 static const char * const patterns[4] = {
17844 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17845 };
17846
17847 int locality = INTVAL (operands[1]);
17848 gcc_assert (locality >= 0 && locality <= 3);
17849
17850 return patterns[locality];
17851 }
17852 [(set_attr "type" "sse")
17853 (set_attr "atom_sse_attr" "prefetch")
17854 (set (attr "length_address")
17855 (symbol_ref "memory_address_length (operands[0])"))
17856 (set_attr "memory" "none")])
17857
17858 (define_insn "*prefetch_3dnow_<mode>"
17859 [(prefetch (match_operand:P 0 "address_operand" "p")
17860 (match_operand:SI 1 "const_int_operand" "n")
17861 (const_int 3))]
17862 "TARGET_3DNOW"
17863 {
17864 if (INTVAL (operands[1]) == 0)
17865 return "prefetch\t%a0";
17866 else
17867 return "prefetchw\t%a0";
17868 }
17869 [(set_attr "type" "mmx")
17870 (set (attr "length_address")
17871 (symbol_ref "memory_address_length (operands[0])"))
17872 (set_attr "memory" "none")])
17873
17874 (define_expand "stack_protect_set"
17875 [(match_operand 0 "memory_operand" "")
17876 (match_operand 1 "memory_operand" "")]
17877 ""
17878 {
17879 rtx (*insn)(rtx, rtx);
17880
17881 #ifdef TARGET_THREAD_SSP_OFFSET
17882 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17883 insn = (TARGET_64BIT
17884 ? gen_stack_tls_protect_set_di
17885 : gen_stack_tls_protect_set_si);
17886 #else
17887 insn = (TARGET_64BIT
17888 ? gen_stack_protect_set_di
17889 : gen_stack_protect_set_si);
17890 #endif
17891
17892 emit_insn (insn (operands[0], operands[1]));
17893 DONE;
17894 })
17895
17896 (define_insn "stack_protect_set_<mode>"
17897 [(set (match_operand:P 0 "memory_operand" "=m")
17898 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17899 (set (match_scratch:P 2 "=&r") (const_int 0))
17900 (clobber (reg:CC FLAGS_REG))]
17901 ""
17902 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17903 [(set_attr "type" "multi")])
17904
17905 (define_insn "stack_tls_protect_set_<mode>"
17906 [(set (match_operand:P 0 "memory_operand" "=m")
17907 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17908 UNSPEC_SP_TLS_SET))
17909 (set (match_scratch:P 2 "=&r") (const_int 0))
17910 (clobber (reg:CC FLAGS_REG))]
17911 ""
17912 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17913 [(set_attr "type" "multi")])
17914
17915 (define_expand "stack_protect_test"
17916 [(match_operand 0 "memory_operand" "")
17917 (match_operand 1 "memory_operand" "")
17918 (match_operand 2 "" "")]
17919 ""
17920 {
17921 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17922
17923 rtx (*insn)(rtx, rtx, rtx);
17924
17925 #ifdef TARGET_THREAD_SSP_OFFSET
17926 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17927 insn = (TARGET_64BIT
17928 ? gen_stack_tls_protect_test_di
17929 : gen_stack_tls_protect_test_si);
17930 #else
17931 insn = (TARGET_64BIT
17932 ? gen_stack_protect_test_di
17933 : gen_stack_protect_test_si);
17934 #endif
17935
17936 emit_insn (insn (flags, operands[0], operands[1]));
17937
17938 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17939 flags, const0_rtx, operands[2]));
17940 DONE;
17941 })
17942
17943 (define_insn "stack_protect_test_<mode>"
17944 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17945 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17946 (match_operand:P 2 "memory_operand" "m")]
17947 UNSPEC_SP_TEST))
17948 (clobber (match_scratch:P 3 "=&r"))]
17949 ""
17950 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17951 [(set_attr "type" "multi")])
17952
17953 (define_insn "stack_tls_protect_test_<mode>"
17954 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17955 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17956 (match_operand:P 2 "const_int_operand" "i")]
17957 UNSPEC_SP_TLS_TEST))
17958 (clobber (match_scratch:P 3 "=r"))]
17959 ""
17960 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17961 [(set_attr "type" "multi")])
17962
17963 (define_insn "sse4_2_crc32<mode>"
17964 [(set (match_operand:SI 0 "register_operand" "=r")
17965 (unspec:SI
17966 [(match_operand:SI 1 "register_operand" "0")
17967 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17968 UNSPEC_CRC32))]
17969 "TARGET_SSE4_2 || TARGET_CRC32"
17970 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17971 [(set_attr "type" "sselog1")
17972 (set_attr "prefix_rep" "1")
17973 (set_attr "prefix_extra" "1")
17974 (set (attr "prefix_data16")
17975 (if_then_else (match_operand:HI 2 "" "")
17976 (const_string "1")
17977 (const_string "*")))
17978 (set (attr "prefix_rex")
17979 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17980 (const_string "1")
17981 (const_string "*")))
17982 (set_attr "mode" "SI")])
17983
17984 (define_insn "sse4_2_crc32di"
17985 [(set (match_operand:DI 0 "register_operand" "=r")
17986 (unspec:DI
17987 [(match_operand:DI 1 "register_operand" "0")
17988 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17989 UNSPEC_CRC32))]
17990 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17991 "crc32{q}\t{%2, %0|%0, %2}"
17992 [(set_attr "type" "sselog1")
17993 (set_attr "prefix_rep" "1")
17994 (set_attr "prefix_extra" "1")
17995 (set_attr "mode" "DI")])
17996
17997 (define_expand "rdpmc"
17998 [(match_operand:DI 0 "register_operand" "")
17999 (match_operand:SI 1 "register_operand" "")]
18000 ""
18001 {
18002 rtx reg = gen_reg_rtx (DImode);
18003 rtx si;
18004
18005 /* Force operand 1 into ECX. */
18006 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18007 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18008 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18009 UNSPECV_RDPMC);
18010
18011 if (TARGET_64BIT)
18012 {
18013 rtvec vec = rtvec_alloc (2);
18014 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18015 rtx upper = gen_reg_rtx (DImode);
18016 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18017 gen_rtvec (1, const0_rtx),
18018 UNSPECV_RDPMC);
18019 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18020 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18021 emit_insn (load);
18022 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18023 NULL, 1, OPTAB_DIRECT);
18024 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18025 OPTAB_DIRECT);
18026 }
18027 else
18028 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18029 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18030 DONE;
18031 })
18032
18033 (define_insn "*rdpmc"
18034 [(set (match_operand:DI 0 "register_operand" "=A")
18035 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18036 UNSPECV_RDPMC))]
18037 "!TARGET_64BIT"
18038 "rdpmc"
18039 [(set_attr "type" "other")
18040 (set_attr "length" "2")])
18041
18042 (define_insn "*rdpmc_rex64"
18043 [(set (match_operand:DI 0 "register_operand" "=a")
18044 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18045 UNSPECV_RDPMC))
18046 (set (match_operand:DI 1 "register_operand" "=d")
18047 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18048 "TARGET_64BIT"
18049 "rdpmc"
18050 [(set_attr "type" "other")
18051 (set_attr "length" "2")])
18052
18053 (define_expand "rdtsc"
18054 [(set (match_operand:DI 0 "register_operand" "")
18055 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18056 ""
18057 {
18058 if (TARGET_64BIT)
18059 {
18060 rtvec vec = rtvec_alloc (2);
18061 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18062 rtx upper = gen_reg_rtx (DImode);
18063 rtx lower = gen_reg_rtx (DImode);
18064 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18065 gen_rtvec (1, const0_rtx),
18066 UNSPECV_RDTSC);
18067 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18068 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18069 emit_insn (load);
18070 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18071 NULL, 1, OPTAB_DIRECT);
18072 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18073 OPTAB_DIRECT);
18074 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18075 DONE;
18076 }
18077 })
18078
18079 (define_insn "*rdtsc"
18080 [(set (match_operand:DI 0 "register_operand" "=A")
18081 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18082 "!TARGET_64BIT"
18083 "rdtsc"
18084 [(set_attr "type" "other")
18085 (set_attr "length" "2")])
18086
18087 (define_insn "*rdtsc_rex64"
18088 [(set (match_operand:DI 0 "register_operand" "=a")
18089 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18090 (set (match_operand:DI 1 "register_operand" "=d")
18091 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18092 "TARGET_64BIT"
18093 "rdtsc"
18094 [(set_attr "type" "other")
18095 (set_attr "length" "2")])
18096
18097 (define_expand "rdtscp"
18098 [(match_operand:DI 0 "register_operand" "")
18099 (match_operand:SI 1 "memory_operand" "")]
18100 ""
18101 {
18102 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18103 gen_rtvec (1, const0_rtx),
18104 UNSPECV_RDTSCP);
18105 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18106 gen_rtvec (1, const0_rtx),
18107 UNSPECV_RDTSCP);
18108 rtx reg = gen_reg_rtx (DImode);
18109 rtx tmp = gen_reg_rtx (SImode);
18110
18111 if (TARGET_64BIT)
18112 {
18113 rtvec vec = rtvec_alloc (3);
18114 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18115 rtx upper = gen_reg_rtx (DImode);
18116 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18117 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18118 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18119 emit_insn (load);
18120 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18121 NULL, 1, OPTAB_DIRECT);
18122 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18123 OPTAB_DIRECT);
18124 }
18125 else
18126 {
18127 rtvec vec = rtvec_alloc (2);
18128 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18129 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18130 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18131 emit_insn (load);
18132 }
18133 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18134 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18135 DONE;
18136 })
18137
18138 (define_insn "*rdtscp"
18139 [(set (match_operand:DI 0 "register_operand" "=A")
18140 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18141 (set (match_operand:SI 1 "register_operand" "=c")
18142 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18143 "!TARGET_64BIT"
18144 "rdtscp"
18145 [(set_attr "type" "other")
18146 (set_attr "length" "3")])
18147
18148 (define_insn "*rdtscp_rex64"
18149 [(set (match_operand:DI 0 "register_operand" "=a")
18150 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18151 (set (match_operand:DI 1 "register_operand" "=d")
18152 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18153 (set (match_operand:SI 2 "register_operand" "=c")
18154 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18155 "TARGET_64BIT"
18156 "rdtscp"
18157 [(set_attr "type" "other")
18158 (set_attr "length" "3")])
18159
18160 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18161 ;;
18162 ;; LWP instructions
18163 ;;
18164 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18165
18166 (define_expand "lwp_llwpcb"
18167 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18168 UNSPECV_LLWP_INTRINSIC)]
18169 "TARGET_LWP")
18170
18171 (define_insn "*lwp_llwpcb<mode>1"
18172 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18173 UNSPECV_LLWP_INTRINSIC)]
18174 "TARGET_LWP"
18175 "llwpcb\t%0"
18176 [(set_attr "type" "lwp")
18177 (set_attr "mode" "<MODE>")
18178 (set_attr "length" "5")])
18179
18180 (define_expand "lwp_slwpcb"
18181 [(set (match_operand 0 "register_operand" "=r")
18182 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18183 "TARGET_LWP"
18184 {
18185 rtx (*insn)(rtx);
18186
18187 insn = (TARGET_64BIT
18188 ? gen_lwp_slwpcbdi
18189 : gen_lwp_slwpcbsi);
18190
18191 emit_insn (insn (operands[0]));
18192 DONE;
18193 })
18194
18195 (define_insn "lwp_slwpcb<mode>"
18196 [(set (match_operand:P 0 "register_operand" "=r")
18197 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18198 "TARGET_LWP"
18199 "slwpcb\t%0"
18200 [(set_attr "type" "lwp")
18201 (set_attr "mode" "<MODE>")
18202 (set_attr "length" "5")])
18203
18204 (define_expand "lwp_lwpval<mode>3"
18205 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18206 (match_operand:SI 2 "nonimmediate_operand" "rm")
18207 (match_operand:SI 3 "const_int_operand" "i")]
18208 UNSPECV_LWPVAL_INTRINSIC)]
18209 "TARGET_LWP"
18210 "/* Avoid unused variable warning. */
18211 (void) operand0;")
18212
18213 (define_insn "*lwp_lwpval<mode>3_1"
18214 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18215 (match_operand:SI 1 "nonimmediate_operand" "rm")
18216 (match_operand:SI 2 "const_int_operand" "i")]
18217 UNSPECV_LWPVAL_INTRINSIC)]
18218 "TARGET_LWP"
18219 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18220 [(set_attr "type" "lwp")
18221 (set_attr "mode" "<MODE>")
18222 (set (attr "length")
18223 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18224
18225 (define_expand "lwp_lwpins<mode>3"
18226 [(set (reg:CCC FLAGS_REG)
18227 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18228 (match_operand:SI 2 "nonimmediate_operand" "rm")
18229 (match_operand:SI 3 "const_int_operand" "i")]
18230 UNSPECV_LWPINS_INTRINSIC))
18231 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18232 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18233 "TARGET_LWP")
18234
18235 (define_insn "*lwp_lwpins<mode>3_1"
18236 [(set (reg:CCC FLAGS_REG)
18237 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18238 (match_operand:SI 1 "nonimmediate_operand" "rm")
18239 (match_operand:SI 2 "const_int_operand" "i")]
18240 UNSPECV_LWPINS_INTRINSIC))]
18241 "TARGET_LWP"
18242 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18243 [(set_attr "type" "lwp")
18244 (set_attr "mode" "<MODE>")
18245 (set (attr "length")
18246 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18247
18248 (define_insn "rdfsbase<mode>"
18249 [(set (match_operand:SWI48 0 "register_operand" "=r")
18250 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18251 "TARGET_64BIT && TARGET_FSGSBASE"
18252 "rdfsbase %0"
18253 [(set_attr "type" "other")
18254 (set_attr "prefix_extra" "2")])
18255
18256 (define_insn "rdgsbase<mode>"
18257 [(set (match_operand:SWI48 0 "register_operand" "=r")
18258 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18259 "TARGET_64BIT && TARGET_FSGSBASE"
18260 "rdgsbase %0"
18261 [(set_attr "type" "other")
18262 (set_attr "prefix_extra" "2")])
18263
18264 (define_insn "wrfsbase<mode>"
18265 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18266 UNSPECV_WRFSBASE)]
18267 "TARGET_64BIT && TARGET_FSGSBASE"
18268 "wrfsbase %0"
18269 [(set_attr "type" "other")
18270 (set_attr "prefix_extra" "2")])
18271
18272 (define_insn "wrgsbase<mode>"
18273 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18274 UNSPECV_WRGSBASE)]
18275 "TARGET_64BIT && TARGET_FSGSBASE"
18276 "wrgsbase %0"
18277 [(set_attr "type" "other")
18278 (set_attr "prefix_extra" "2")])
18279
18280 (define_insn "rdrand<mode>_1"
18281 [(set (match_operand:SWI248 0 "register_operand" "=r")
18282 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18283 (set (reg:CCC FLAGS_REG)
18284 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18285 "TARGET_RDRND"
18286 "rdrand\t%0"
18287 [(set_attr "type" "other")
18288 (set_attr "prefix_extra" "1")])
18289
18290 (include "mmx.md")
18291 (include "sse.md")
18292 (include "sync.md")