51e375470e1433e0c4fe039e26c862163f2c148c
[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
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
80 ;; Prologue support
81 UNSPEC_STACK_ALLOC
82 UNSPEC_SET_GOT
83 UNSPEC_REG_SAVE
84 UNSPEC_DEF_CFA
85 UNSPEC_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_STACK_CHECK
89
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
95
96 ;; Other random patterns
97 UNSPEC_SCAS
98 UNSPEC_FNSTSW
99 UNSPEC_SAHF
100 UNSPEC_PARITY
101 UNSPEC_FSTCW
102 UNSPEC_ADD_CARRY
103 UNSPEC_FLDCW
104 UNSPEC_REP
105 UNSPEC_LD_MPIC ; load_macho_picbase
106 UNSPEC_TRUNC_NOOP
107 UNSPEC_DIV_ALREADY_SPLIT
108
109 ;; For SSE/MMX support:
110 UNSPEC_FIX_NOTRUNC
111 UNSPEC_MASKMOV
112 UNSPEC_MOVMSK
113 UNSPEC_MOVNT
114 UNSPEC_MOVU
115 UNSPEC_RCP
116 UNSPEC_RSQRT
117 UNSPEC_SFENCE
118 UNSPEC_PFRCP
119 UNSPEC_PFRCPIT1
120 UNSPEC_PFRCPIT2
121 UNSPEC_PFRSQRT
122 UNSPEC_PFRSQIT1
123 UNSPEC_MFENCE
124 UNSPEC_LFENCE
125 UNSPEC_PSADBW
126 UNSPEC_LDDQU
127 UNSPEC_MS_TO_SYSV_CALL
128
129 ;; Generic math support
130 UNSPEC_COPYSIGN
131 UNSPEC_IEEE_MIN ; not commutative
132 UNSPEC_IEEE_MAX ; not commutative
133
134 ;; x87 Floating point
135 UNSPEC_SIN
136 UNSPEC_COS
137 UNSPEC_FPATAN
138 UNSPEC_FYL2X
139 UNSPEC_FYL2XP1
140 UNSPEC_FRNDINT
141 UNSPEC_FIST
142 UNSPEC_F2XM1
143 UNSPEC_TAN
144 UNSPEC_FXAM
145
146 ;; x87 Rounding
147 UNSPEC_FRNDINT_FLOOR
148 UNSPEC_FRNDINT_CEIL
149 UNSPEC_FRNDINT_TRUNC
150 UNSPEC_FRNDINT_MASK_PM
151 UNSPEC_FIST_FLOOR
152 UNSPEC_FIST_CEIL
153
154 ;; x87 Double output FP
155 UNSPEC_SINCOS_COS
156 UNSPEC_SINCOS_SIN
157 UNSPEC_XTRACT_FRACT
158 UNSPEC_XTRACT_EXP
159 UNSPEC_FSCALE_FRACT
160 UNSPEC_FSCALE_EXP
161 UNSPEC_FPREM_F
162 UNSPEC_FPREM_U
163 UNSPEC_FPREM1_F
164 UNSPEC_FPREM1_U
165
166 UNSPEC_C2_FLAG
167 UNSPEC_FXAM_MEM
168
169 ;; SSP patterns
170 UNSPEC_SP_SET
171 UNSPEC_SP_TEST
172 UNSPEC_SP_TLS_SET
173 UNSPEC_SP_TLS_TEST
174
175 ;; SSSE3
176 UNSPEC_PSHUFB
177 UNSPEC_PSIGN
178 UNSPEC_PALIGNR
179
180 ;; For SSE4A support
181 UNSPEC_EXTRQI
182 UNSPEC_EXTRQ
183 UNSPEC_INSERTQI
184 UNSPEC_INSERTQ
185
186 ;; For SSE4.1 support
187 UNSPEC_BLENDV
188 UNSPEC_INSERTPS
189 UNSPEC_DP
190 UNSPEC_MOVNTDQA
191 UNSPEC_MPSADBW
192 UNSPEC_PHMINPOSUW
193 UNSPEC_PTEST
194 UNSPEC_ROUND
195
196 ;; For SSE4.2 support
197 UNSPEC_CRC32
198 UNSPEC_PCMPESTR
199 UNSPEC_PCMPISTR
200
201 ;; For FMA4 support
202 UNSPEC_FMA4_INTRINSIC
203 UNSPEC_FMA4_FMADDSUB
204 UNSPEC_FMA4_FMSUBADD
205 UNSPEC_XOP_UNSIGNED_CMP
206 UNSPEC_XOP_TRUEFALSE
207 UNSPEC_XOP_PERMUTE
208 UNSPEC_FRCZ
209
210 ;; For AES support
211 UNSPEC_AESENC
212 UNSPEC_AESENCLAST
213 UNSPEC_AESDEC
214 UNSPEC_AESDECLAST
215 UNSPEC_AESIMC
216 UNSPEC_AESKEYGENASSIST
217
218 ;; For PCLMUL support
219 UNSPEC_PCLMUL
220
221 ;; For AVX support
222 UNSPEC_PCMP
223 UNSPEC_VPERMIL
224 UNSPEC_VPERMIL2
225 UNSPEC_VPERMIL2F128
226 UNSPEC_MASKLOAD
227 UNSPEC_MASKSTORE
228 UNSPEC_CAST
229 UNSPEC_VTESTP
230 UNSPEC_VCVTPH2PS
231 UNSPEC_VCVTPS2PH
232 ])
233
234 (define_c_enum "unspecv" [
235 UNSPECV_BLOCKAGE
236 UNSPECV_STACK_PROBE
237 UNSPECV_PROBE_STACK_RANGE
238 UNSPECV_EMMS
239 UNSPECV_LDMXCSR
240 UNSPECV_STMXCSR
241 UNSPECV_FEMMS
242 UNSPECV_CLFLUSH
243 UNSPECV_ALIGN
244 UNSPECV_MONITOR
245 UNSPECV_MWAIT
246 UNSPECV_CMPXCHG
247 UNSPECV_XCHG
248 UNSPECV_LOCK
249 UNSPECV_PROLOGUE_USE
250 UNSPECV_CLD
251 UNSPECV_NOPS
252 UNSPECV_VZEROALL
253 UNSPECV_VZEROUPPER
254 UNSPECV_RDTSC
255 UNSPECV_RDTSCP
256 UNSPECV_RDPMC
257 UNSPECV_LLWP_INTRINSIC
258 UNSPECV_SLWP_INTRINSIC
259 UNSPECV_LWPVAL_INTRINSIC
260 UNSPECV_LWPINS_INTRINSIC
261 UNSPECV_RDFSBASE
262 UNSPECV_RDGSBASE
263 UNSPECV_WRFSBASE
264 UNSPECV_WRGSBASE
265 UNSPECV_RDRAND
266 ])
267
268 ;; Constants to represent pcomtrue/pcomfalse variants
269 (define_constants
270 [(PCOM_FALSE 0)
271 (PCOM_TRUE 1)
272 (COM_FALSE_S 2)
273 (COM_FALSE_P 3)
274 (COM_TRUE_S 4)
275 (COM_TRUE_P 5)
276 ])
277
278 ;; Constants used in the XOP pperm instruction
279 (define_constants
280 [(PPERM_SRC 0x00) /* copy source */
281 (PPERM_INVERT 0x20) /* invert source */
282 (PPERM_REVERSE 0x40) /* bit reverse source */
283 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
284 (PPERM_ZERO 0x80) /* all 0's */
285 (PPERM_ONES 0xa0) /* all 1's */
286 (PPERM_SIGN 0xc0) /* propagate sign bit */
287 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
288 (PPERM_SRC1 0x00) /* use first source byte */
289 (PPERM_SRC2 0x10) /* use second source byte */
290 ])
291
292 ;; Registers by name.
293 (define_constants
294 [(AX_REG 0)
295 (DX_REG 1)
296 (CX_REG 2)
297 (BX_REG 3)
298 (SI_REG 4)
299 (DI_REG 5)
300 (BP_REG 6)
301 (SP_REG 7)
302 (ST0_REG 8)
303 (ST1_REG 9)
304 (ST2_REG 10)
305 (ST3_REG 11)
306 (ST4_REG 12)
307 (ST5_REG 13)
308 (ST6_REG 14)
309 (ST7_REG 15)
310 (FLAGS_REG 17)
311 (FPSR_REG 18)
312 (FPCR_REG 19)
313 (XMM0_REG 21)
314 (XMM1_REG 22)
315 (XMM2_REG 23)
316 (XMM3_REG 24)
317 (XMM4_REG 25)
318 (XMM5_REG 26)
319 (XMM6_REG 27)
320 (XMM7_REG 28)
321 (MM0_REG 29)
322 (MM1_REG 30)
323 (MM2_REG 31)
324 (MM3_REG 32)
325 (MM4_REG 33)
326 (MM5_REG 34)
327 (MM6_REG 35)
328 (MM7_REG 36)
329 (R8_REG 37)
330 (R9_REG 38)
331 (R10_REG 39)
332 (R11_REG 40)
333 (R12_REG 41)
334 (R13_REG 42)
335 (XMM8_REG 45)
336 (XMM9_REG 46)
337 (XMM10_REG 47)
338 (XMM11_REG 48)
339 (XMM12_REG 49)
340 (XMM13_REG 50)
341 (XMM14_REG 51)
342 (XMM15_REG 52)
343 ])
344
345 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
346 ;; from i386.c.
347
348 ;; In C guard expressions, put expressions which may be compile-time
349 ;; constants first. This allows for better optimization. For
350 ;; example, write "TARGET_64BIT && reload_completed", not
351 ;; "reload_completed && TARGET_64BIT".
352
353 \f
354 ;; Processor type.
355 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
356 generic64,amdfam10,bdver1"
357 (const (symbol_ref "ix86_schedule")))
358
359 ;; A basic instruction type. Refinements due to arguments to be
360 ;; provided in other attributes.
361 (define_attr "type"
362 "other,multi,
363 alu,alu1,negnot,imov,imovx,lea,
364 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
365 icmp,test,ibr,setcc,icmov,
366 push,pop,call,callv,leave,
367 str,bitmanip,
368 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
369 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
370 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
371 ssemuladd,sse4arg,lwp,
372 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
373 (const_string "other"))
374
375 ;; Main data type used by the insn
376 (define_attr "mode"
377 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
378 (const_string "unknown"))
379
380 ;; The CPU unit operations uses.
381 (define_attr "unit" "integer,i387,sse,mmx,unknown"
382 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
383 (const_string "i387")
384 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
385 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
386 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
387 (const_string "sse")
388 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
389 (const_string "mmx")
390 (eq_attr "type" "other")
391 (const_string "unknown")]
392 (const_string "integer")))
393
394 ;; The (bounding maximum) length of an instruction immediate.
395 (define_attr "length_immediate" ""
396 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
397 bitmanip")
398 (const_int 0)
399 (eq_attr "unit" "i387,sse,mmx")
400 (const_int 0)
401 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
402 imul,icmp,push,pop")
403 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
404 (eq_attr "type" "imov,test")
405 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
406 (eq_attr "type" "call")
407 (if_then_else (match_operand 0 "constant_call_address_operand" "")
408 (const_int 4)
409 (const_int 0))
410 (eq_attr "type" "callv")
411 (if_then_else (match_operand 1 "constant_call_address_operand" "")
412 (const_int 4)
413 (const_int 0))
414 ;; We don't know the size before shorten_branches. Expect
415 ;; the instruction to fit for better scheduling.
416 (eq_attr "type" "ibr")
417 (const_int 1)
418 ]
419 (symbol_ref "/* Update immediate_length and other attributes! */
420 gcc_unreachable (),1")))
421
422 ;; The (bounding maximum) length of an instruction address.
423 (define_attr "length_address" ""
424 (cond [(eq_attr "type" "str,other,multi,fxch")
425 (const_int 0)
426 (and (eq_attr "type" "call")
427 (match_operand 0 "constant_call_address_operand" ""))
428 (const_int 0)
429 (and (eq_attr "type" "callv")
430 (match_operand 1 "constant_call_address_operand" ""))
431 (const_int 0)
432 ]
433 (symbol_ref "ix86_attr_length_address_default (insn)")))
434
435 ;; Set when length prefix is used.
436 (define_attr "prefix_data16" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438 (const_int 0)
439 (eq_attr "mode" "HI")
440 (const_int 1)
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
442 (const_int 1)
443 ]
444 (const_int 0)))
445
446 ;; Set when string REP prefix is used.
447 (define_attr "prefix_rep" ""
448 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
449 (const_int 0)
450 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
451 (const_int 1)
452 ]
453 (const_int 0)))
454
455 ;; Set when 0f opcode prefix is used.
456 (define_attr "prefix_0f" ""
457 (if_then_else
458 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
459 (eq_attr "unit" "sse,mmx"))
460 (const_int 1)
461 (const_int 0)))
462
463 ;; Set when REX opcode prefix is used.
464 (define_attr "prefix_rex" ""
465 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
466 (const_int 0)
467 (and (eq_attr "mode" "DI")
468 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
469 (eq_attr "unit" "!mmx")))
470 (const_int 1)
471 (and (eq_attr "mode" "QI")
472 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
473 (const_int 0)))
474 (const_int 1)
475 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
476 (const_int 0))
477 (const_int 1)
478 (and (eq_attr "type" "imovx")
479 (match_operand:QI 1 "ext_QIreg_operand" ""))
480 (const_int 1)
481 ]
482 (const_int 0)))
483
484 ;; There are also additional prefixes in 3DNOW, SSSE3.
485 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
486 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
487 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
488 (define_attr "prefix_extra" ""
489 (cond [(eq_attr "type" "ssemuladd,sse4arg")
490 (const_int 2)
491 (eq_attr "type" "sseiadd1,ssecvt1")
492 (const_int 1)
493 ]
494 (const_int 0)))
495
496 ;; Prefix used: original, VEX or maybe VEX.
497 (define_attr "prefix" "orig,vex,maybe_vex"
498 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
499 (const_string "vex")
500 (const_string "orig")))
501
502 ;; VEX W bit is used.
503 (define_attr "prefix_vex_w" "" (const_int 0))
504
505 ;; The length of VEX prefix
506 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
507 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
508 ;; still prefix_0f 1, with prefix_extra 1.
509 (define_attr "length_vex" ""
510 (if_then_else (and (eq_attr "prefix_0f" "1")
511 (eq_attr "prefix_extra" "0"))
512 (if_then_else (eq_attr "prefix_vex_w" "1")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
515 (if_then_else (eq_attr "prefix_vex_w" "1")
516 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
517 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
518
519 ;; Set when modrm byte is used.
520 (define_attr "modrm" ""
521 (cond [(eq_attr "type" "str,leave")
522 (const_int 0)
523 (eq_attr "unit" "i387")
524 (const_int 0)
525 (and (eq_attr "type" "incdec")
526 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
527 (ior (match_operand:SI 1 "register_operand" "")
528 (match_operand:HI 1 "register_operand" ""))))
529 (const_int 0)
530 (and (eq_attr "type" "push")
531 (not (match_operand 1 "memory_operand" "")))
532 (const_int 0)
533 (and (eq_attr "type" "pop")
534 (not (match_operand 0 "memory_operand" "")))
535 (const_int 0)
536 (and (eq_attr "type" "imov")
537 (and (not (eq_attr "mode" "DI"))
538 (ior (and (match_operand 0 "register_operand" "")
539 (match_operand 1 "immediate_operand" ""))
540 (ior (and (match_operand 0 "ax_reg_operand" "")
541 (match_operand 1 "memory_displacement_only_operand" ""))
542 (and (match_operand 0 "memory_displacement_only_operand" "")
543 (match_operand 1 "ax_reg_operand" ""))))))
544 (const_int 0)
545 (and (eq_attr "type" "call")
546 (match_operand 0 "constant_call_address_operand" ""))
547 (const_int 0)
548 (and (eq_attr "type" "callv")
549 (match_operand 1 "constant_call_address_operand" ""))
550 (const_int 0)
551 (and (eq_attr "type" "alu,alu1,icmp,test")
552 (match_operand 0 "ax_reg_operand" ""))
553 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
554 ]
555 (const_int 1)))
556
557 ;; The (bounding maximum) length of an instruction in bytes.
558 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
559 ;; Later we may want to split them and compute proper length as for
560 ;; other insns.
561 (define_attr "length" ""
562 (cond [(eq_attr "type" "other,multi,fistp,frndint")
563 (const_int 16)
564 (eq_attr "type" "fcmp")
565 (const_int 4)
566 (eq_attr "unit" "i387")
567 (plus (const_int 2)
568 (plus (attr "prefix_data16")
569 (attr "length_address")))
570 (ior (eq_attr "prefix" "vex")
571 (and (eq_attr "prefix" "maybe_vex")
572 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
573 (plus (attr "length_vex")
574 (plus (attr "length_immediate")
575 (plus (attr "modrm")
576 (attr "length_address"))))]
577 (plus (plus (attr "modrm")
578 (plus (attr "prefix_0f")
579 (plus (attr "prefix_rex")
580 (plus (attr "prefix_extra")
581 (const_int 1)))))
582 (plus (attr "prefix_rep")
583 (plus (attr "prefix_data16")
584 (plus (attr "length_immediate")
585 (attr "length_address")))))))
586
587 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
588 ;; `store' if there is a simple memory reference therein, or `unknown'
589 ;; if the instruction is complex.
590
591 (define_attr "memory" "none,load,store,both,unknown"
592 (cond [(eq_attr "type" "other,multi,str,lwp")
593 (const_string "unknown")
594 (eq_attr "type" "lea,fcmov,fpspc")
595 (const_string "none")
596 (eq_attr "type" "fistp,leave")
597 (const_string "both")
598 (eq_attr "type" "frndint")
599 (const_string "load")
600 (eq_attr "type" "push")
601 (if_then_else (match_operand 1 "memory_operand" "")
602 (const_string "both")
603 (const_string "store"))
604 (eq_attr "type" "pop")
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "both")
607 (const_string "load"))
608 (eq_attr "type" "setcc")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "store")
611 (const_string "none"))
612 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
613 (if_then_else (ior (match_operand 0 "memory_operand" "")
614 (match_operand 1 "memory_operand" ""))
615 (const_string "load")
616 (const_string "none"))
617 (eq_attr "type" "ibr")
618 (if_then_else (match_operand 0 "memory_operand" "")
619 (const_string "load")
620 (const_string "none"))
621 (eq_attr "type" "call")
622 (if_then_else (match_operand 0 "constant_call_address_operand" "")
623 (const_string "none")
624 (const_string "load"))
625 (eq_attr "type" "callv")
626 (if_then_else (match_operand 1 "constant_call_address_operand" "")
627 (const_string "none")
628 (const_string "load"))
629 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "both")
632 (and (match_operand 0 "memory_operand" "")
633 (match_operand 1 "memory_operand" ""))
634 (const_string "both")
635 (match_operand 0 "memory_operand" "")
636 (const_string "store")
637 (match_operand 1 "memory_operand" "")
638 (const_string "load")
639 (and (eq_attr "type"
640 "!alu1,negnot,ishift1,
641 imov,imovx,icmp,test,bitmanip,
642 fmov,fcmp,fsgn,
643 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
644 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
645 (match_operand 2 "memory_operand" ""))
646 (const_string "load")
647 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
648 (match_operand 3 "memory_operand" ""))
649 (const_string "load")
650 ]
651 (const_string "none")))
652
653 ;; Indicates if an instruction has both an immediate and a displacement.
654
655 (define_attr "imm_disp" "false,true,unknown"
656 (cond [(eq_attr "type" "other,multi")
657 (const_string "unknown")
658 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 1 "immediate_operand" "")))
661 (const_string "true")
662 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
663 (and (match_operand 0 "memory_displacement_operand" "")
664 (match_operand 2 "immediate_operand" "")))
665 (const_string "true")
666 ]
667 (const_string "false")))
668
669 ;; Indicates if an FP operation has an integer source.
670
671 (define_attr "fp_int_src" "false,true"
672 (const_string "false"))
673
674 ;; Defines rounding mode of an FP operation.
675
676 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
677 (const_string "any"))
678
679 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
680 (define_attr "use_carry" "0,1" (const_string "0"))
681
682 ;; Define attribute to indicate unaligned ssemov insns
683 (define_attr "movu" "0,1" (const_string "0"))
684
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687 [(set_attr "length" "128")
688 (set_attr "type" "multi")])
689
690 (define_code_iterator plusminus [plus minus])
691
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
693
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
698
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701 [(plus "add") (ss_plus "adds") (us_plus "addus")
702 (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704 [(plus "adc") (minus "sbb")])
705
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708 (minus "") (ss_minus "") (us_minus "")])
709
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
712
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
715
716 ;; Mapping of signed/unsigned max and min
717 (define_code_iterator maxmin [smax smin umax umin])
718
719 ;; Base name for integer and FP insn mnemonic
720 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
721 (umax "maxu") (umin "minu")])
722 (define_code_attr maxmin_float [(smax "max") (smin "min")])
723
724 ;; Mapping of logic operators
725 (define_code_iterator any_logic [and ior xor])
726 (define_code_iterator any_or [ior xor])
727
728 ;; Base name for insn mnemonic.
729 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
730
731 ;; Mapping of shift-right operators
732 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
733
734 ;; Base name for define_insn
735 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
736
737 ;; Base name for insn mnemonic.
738 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
739
740 ;; Mapping of rotate operators
741 (define_code_iterator any_rotate [rotate rotatert])
742
743 ;; Base name for define_insn
744 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
745
746 ;; Base name for insn mnemonic.
747 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
748
749 ;; Mapping of abs neg operators
750 (define_code_iterator absneg [abs neg])
751
752 ;; Base name for x87 insn mnemonic.
753 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
754
755 ;; Used in signed and unsigned widening multiplications.
756 (define_code_iterator any_extend [sign_extend zero_extend])
757
758 ;; Various insn prefixes for signed and unsigned operations.
759 (define_code_attr u [(sign_extend "") (zero_extend "u")
760 (div "") (udiv "u")])
761 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
762
763 ;; Used in signed and unsigned divisions.
764 (define_code_iterator any_div [div udiv])
765
766 ;; Instruction prefix for signed and unsigned operations.
767 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
768 (div "i") (udiv "")])
769
770 ;; 64bit single word integer modes.
771 (define_mode_iterator SWI1248x [QI HI SI DI])
772
773 ;; 64bit single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48x [SI DI])
775
776 ;; Single word integer modes.
777 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
778
779 ;; Single word integer modes without SImode and DImode.
780 (define_mode_iterator SWI12 [QI HI])
781
782 ;; Single word integer modes without DImode.
783 (define_mode_iterator SWI124 [QI HI SI])
784
785 ;; Single word integer modes without QImode and DImode.
786 (define_mode_iterator SWI24 [HI SI])
787
788 ;; Single word integer modes without QImode.
789 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
790
791 ;; Single word integer modes without QImode and HImode.
792 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
793
794 ;; All math-dependant single and double word integer modes.
795 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
796 (HI "TARGET_HIMODE_MATH")
797 SI DI (TI "TARGET_64BIT")])
798
799 ;; Math-dependant single word integer modes.
800 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
801 (HI "TARGET_HIMODE_MATH")
802 SI (DI "TARGET_64BIT")])
803
804 ;; Math-dependant single word integer modes without DImode.
805 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
806 (HI "TARGET_HIMODE_MATH")
807 SI])
808
809 ;; Math-dependant single word integer modes without QImode.
810 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
811 SI (DI "TARGET_64BIT")])
812
813 ;; Double word integer modes.
814 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
815 (TI "TARGET_64BIT")])
816
817 ;; Double word integer modes as mode attribute.
818 (define_mode_attr DWI [(SI "DI") (DI "TI")])
819 (define_mode_attr dwi [(SI "di") (DI "ti")])
820
821 ;; Half mode for double word integer modes.
822 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
823 (DI "TARGET_64BIT")])
824
825 ;; Instruction suffix for integer modes.
826 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
827
828 ;; Pointer size prefix for integer modes (Intel asm dialect)
829 (define_mode_attr iptrsize [(QI "BYTE")
830 (HI "WORD")
831 (SI "DWORD")
832 (DI "QWORD")])
833
834 ;; Register class for integer modes.
835 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
836
837 ;; Immediate operand constraint for integer modes.
838 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
839
840 ;; General operand constraint for word modes.
841 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
842
843 ;; Immediate operand constraint for double integer modes.
844 (define_mode_attr di [(SI "iF") (DI "e")])
845
846 ;; Immediate operand constraint for shifts.
847 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
848
849 ;; General operand predicate for integer modes.
850 (define_mode_attr general_operand
851 [(QI "general_operand")
852 (HI "general_operand")
853 (SI "general_operand")
854 (DI "x86_64_general_operand")
855 (TI "x86_64_general_operand")])
856
857 ;; General sign/zero extend operand predicate for integer modes.
858 (define_mode_attr general_szext_operand
859 [(QI "general_operand")
860 (HI "general_operand")
861 (SI "general_operand")
862 (DI "x86_64_szext_general_operand")])
863
864 ;; Immediate operand predicate for integer modes.
865 (define_mode_attr immediate_operand
866 [(QI "immediate_operand")
867 (HI "immediate_operand")
868 (SI "immediate_operand")
869 (DI "x86_64_immediate_operand")])
870
871 ;; Nonmemory operand predicate for integer modes.
872 (define_mode_attr nonmemory_operand
873 [(QI "nonmemory_operand")
874 (HI "nonmemory_operand")
875 (SI "nonmemory_operand")
876 (DI "x86_64_nonmemory_operand")])
877
878 ;; Operand predicate for shifts.
879 (define_mode_attr shift_operand
880 [(QI "nonimmediate_operand")
881 (HI "nonimmediate_operand")
882 (SI "nonimmediate_operand")
883 (DI "shiftdi_operand")
884 (TI "register_operand")])
885
886 ;; Operand predicate for shift argument.
887 (define_mode_attr shift_immediate_operand
888 [(QI "const_1_to_31_operand")
889 (HI "const_1_to_31_operand")
890 (SI "const_1_to_31_operand")
891 (DI "const_1_to_63_operand")])
892
893 ;; Input operand predicate for arithmetic left shifts.
894 (define_mode_attr ashl_input_operand
895 [(QI "nonimmediate_operand")
896 (HI "nonimmediate_operand")
897 (SI "nonimmediate_operand")
898 (DI "ashldi_input_operand")
899 (TI "reg_or_pm1_operand")])
900
901 ;; SSE and x87 SFmode and DFmode floating point modes
902 (define_mode_iterator MODEF [SF DF])
903
904 ;; All x87 floating point modes
905 (define_mode_iterator X87MODEF [SF DF XF])
906
907 ;; All integer modes handled by x87 fisttp operator.
908 (define_mode_iterator X87MODEI [HI SI DI])
909
910 ;; All integer modes handled by integer x87 operators.
911 (define_mode_iterator X87MODEI12 [HI SI])
912
913 ;; All integer modes handled by SSE cvtts?2si* operators.
914 (define_mode_iterator SSEMODEI24 [SI DI])
915
916 ;; SSE asm suffix for floating point modes
917 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
918
919 ;; SSE vector mode corresponding to a scalar mode
920 (define_mode_attr ssevecmode
921 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
922
923 ;; Instruction suffix for REX 64bit operators.
924 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
925
926 ;; This mode iterator allows :P to be used for patterns that operate on
927 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
928 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
929 \f
930 ;; Scheduling descriptions
931
932 (include "pentium.md")
933 (include "ppro.md")
934 (include "k6.md")
935 (include "athlon.md")
936 (include "geode.md")
937 (include "atom.md")
938
939 \f
940 ;; Operand and operator predicates and constraints
941
942 (include "predicates.md")
943 (include "constraints.md")
944
945 \f
946 ;; Compare and branch/compare and store instructions.
947
948 (define_expand "cbranch<mode>4"
949 [(set (reg:CC FLAGS_REG)
950 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
951 (match_operand:SDWIM 2 "<general_operand>" "")))
952 (set (pc) (if_then_else
953 (match_operator 0 "ordered_comparison_operator"
954 [(reg:CC FLAGS_REG) (const_int 0)])
955 (label_ref (match_operand 3 "" ""))
956 (pc)))]
957 ""
958 {
959 if (MEM_P (operands[1]) && MEM_P (operands[2]))
960 operands[1] = force_reg (<MODE>mode, operands[1]);
961 ix86_expand_branch (GET_CODE (operands[0]),
962 operands[1], operands[2], operands[3]);
963 DONE;
964 })
965
966 (define_expand "cstore<mode>4"
967 [(set (reg:CC FLAGS_REG)
968 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
969 (match_operand:SWIM 3 "<general_operand>" "")))
970 (set (match_operand:QI 0 "register_operand" "")
971 (match_operator 1 "ordered_comparison_operator"
972 [(reg:CC FLAGS_REG) (const_int 0)]))]
973 ""
974 {
975 if (MEM_P (operands[2]) && MEM_P (operands[3]))
976 operands[2] = force_reg (<MODE>mode, operands[2]);
977 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
978 operands[2], operands[3]);
979 DONE;
980 })
981
982 (define_expand "cmp<mode>_1"
983 [(set (reg:CC FLAGS_REG)
984 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
985 (match_operand:SWI48 1 "<general_operand>" "")))])
986
987 (define_insn "*cmp<mode>_ccno_1"
988 [(set (reg FLAGS_REG)
989 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
990 (match_operand:SWI 1 "const0_operand" "")))]
991 "ix86_match_ccmode (insn, CCNOmode)"
992 "@
993 test{<imodesuffix>}\t%0, %0
994 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995 [(set_attr "type" "test,icmp")
996 (set_attr "length_immediate" "0,1")
997 (set_attr "mode" "<MODE>")])
998
999 (define_insn "*cmp<mode>_1"
1000 [(set (reg FLAGS_REG)
1001 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1002 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1003 "ix86_match_ccmode (insn, CCmode)"
1004 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1005 [(set_attr "type" "icmp")
1006 (set_attr "mode" "<MODE>")])
1007
1008 (define_insn "*cmp<mode>_minus_1"
1009 [(set (reg FLAGS_REG)
1010 (compare
1011 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1012 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1013 (const_int 0)))]
1014 "ix86_match_ccmode (insn, CCGOCmode)"
1015 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1016 [(set_attr "type" "icmp")
1017 (set_attr "mode" "<MODE>")])
1018
1019 (define_insn "*cmpqi_ext_1"
1020 [(set (reg FLAGS_REG)
1021 (compare
1022 (match_operand:QI 0 "general_operand" "Qm")
1023 (subreg:QI
1024 (zero_extract:SI
1025 (match_operand 1 "ext_register_operand" "Q")
1026 (const_int 8)
1027 (const_int 8)) 0)))]
1028 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1029 "cmp{b}\t{%h1, %0|%0, %h1}"
1030 [(set_attr "type" "icmp")
1031 (set_attr "mode" "QI")])
1032
1033 (define_insn "*cmpqi_ext_1_rex64"
1034 [(set (reg FLAGS_REG)
1035 (compare
1036 (match_operand:QI 0 "register_operand" "Q")
1037 (subreg:QI
1038 (zero_extract:SI
1039 (match_operand 1 "ext_register_operand" "Q")
1040 (const_int 8)
1041 (const_int 8)) 0)))]
1042 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1043 "cmp{b}\t{%h1, %0|%0, %h1}"
1044 [(set_attr "type" "icmp")
1045 (set_attr "mode" "QI")])
1046
1047 (define_insn "*cmpqi_ext_2"
1048 [(set (reg FLAGS_REG)
1049 (compare
1050 (subreg:QI
1051 (zero_extract:SI
1052 (match_operand 0 "ext_register_operand" "Q")
1053 (const_int 8)
1054 (const_int 8)) 0)
1055 (match_operand:QI 1 "const0_operand" "")))]
1056 "ix86_match_ccmode (insn, CCNOmode)"
1057 "test{b}\t%h0, %h0"
1058 [(set_attr "type" "test")
1059 (set_attr "length_immediate" "0")
1060 (set_attr "mode" "QI")])
1061
1062 (define_expand "cmpqi_ext_3"
1063 [(set (reg:CC FLAGS_REG)
1064 (compare:CC
1065 (subreg:QI
1066 (zero_extract:SI
1067 (match_operand 0 "ext_register_operand" "")
1068 (const_int 8)
1069 (const_int 8)) 0)
1070 (match_operand:QI 1 "immediate_operand" "")))])
1071
1072 (define_insn "*cmpqi_ext_3_insn"
1073 [(set (reg FLAGS_REG)
1074 (compare
1075 (subreg:QI
1076 (zero_extract:SI
1077 (match_operand 0 "ext_register_operand" "Q")
1078 (const_int 8)
1079 (const_int 8)) 0)
1080 (match_operand:QI 1 "general_operand" "Qmn")))]
1081 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1082 "cmp{b}\t{%1, %h0|%h0, %1}"
1083 [(set_attr "type" "icmp")
1084 (set_attr "modrm" "1")
1085 (set_attr "mode" "QI")])
1086
1087 (define_insn "*cmpqi_ext_3_insn_rex64"
1088 [(set (reg FLAGS_REG)
1089 (compare
1090 (subreg:QI
1091 (zero_extract:SI
1092 (match_operand 0 "ext_register_operand" "Q")
1093 (const_int 8)
1094 (const_int 8)) 0)
1095 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1096 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1097 "cmp{b}\t{%1, %h0|%h0, %1}"
1098 [(set_attr "type" "icmp")
1099 (set_attr "modrm" "1")
1100 (set_attr "mode" "QI")])
1101
1102 (define_insn "*cmpqi_ext_4"
1103 [(set (reg FLAGS_REG)
1104 (compare
1105 (subreg:QI
1106 (zero_extract:SI
1107 (match_operand 0 "ext_register_operand" "Q")
1108 (const_int 8)
1109 (const_int 8)) 0)
1110 (subreg:QI
1111 (zero_extract:SI
1112 (match_operand 1 "ext_register_operand" "Q")
1113 (const_int 8)
1114 (const_int 8)) 0)))]
1115 "ix86_match_ccmode (insn, CCmode)"
1116 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1117 [(set_attr "type" "icmp")
1118 (set_attr "mode" "QI")])
1119
1120 ;; These implement float point compares.
1121 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1122 ;; which would allow mix and match FP modes on the compares. Which is what
1123 ;; the old patterns did, but with many more of them.
1124
1125 (define_expand "cbranchxf4"
1126 [(set (reg:CC FLAGS_REG)
1127 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1128 (match_operand:XF 2 "nonmemory_operand" "")))
1129 (set (pc) (if_then_else
1130 (match_operator 0 "ix86_fp_comparison_operator"
1131 [(reg:CC FLAGS_REG)
1132 (const_int 0)])
1133 (label_ref (match_operand 3 "" ""))
1134 (pc)))]
1135 "TARGET_80387"
1136 {
1137 ix86_expand_branch (GET_CODE (operands[0]),
1138 operands[1], operands[2], operands[3]);
1139 DONE;
1140 })
1141
1142 (define_expand "cstorexf4"
1143 [(set (reg:CC FLAGS_REG)
1144 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1145 (match_operand:XF 3 "nonmemory_operand" "")))
1146 (set (match_operand:QI 0 "register_operand" "")
1147 (match_operator 1 "ix86_fp_comparison_operator"
1148 [(reg:CC FLAGS_REG)
1149 (const_int 0)]))]
1150 "TARGET_80387"
1151 {
1152 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1153 operands[2], operands[3]);
1154 DONE;
1155 })
1156
1157 (define_expand "cbranch<mode>4"
1158 [(set (reg:CC FLAGS_REG)
1159 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1160 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1161 (set (pc) (if_then_else
1162 (match_operator 0 "ix86_fp_comparison_operator"
1163 [(reg:CC FLAGS_REG)
1164 (const_int 0)])
1165 (label_ref (match_operand 3 "" ""))
1166 (pc)))]
1167 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1168 {
1169 ix86_expand_branch (GET_CODE (operands[0]),
1170 operands[1], operands[2], operands[3]);
1171 DONE;
1172 })
1173
1174 (define_expand "cstore<mode>4"
1175 [(set (reg:CC FLAGS_REG)
1176 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1177 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1178 (set (match_operand:QI 0 "register_operand" "")
1179 (match_operator 1 "ix86_fp_comparison_operator"
1180 [(reg:CC FLAGS_REG)
1181 (const_int 0)]))]
1182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1183 {
1184 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1185 operands[2], operands[3]);
1186 DONE;
1187 })
1188
1189 (define_expand "cbranchcc4"
1190 [(set (pc) (if_then_else
1191 (match_operator 0 "comparison_operator"
1192 [(match_operand 1 "flags_reg_operand" "")
1193 (match_operand 2 "const0_operand" "")])
1194 (label_ref (match_operand 3 "" ""))
1195 (pc)))]
1196 ""
1197 {
1198 ix86_expand_branch (GET_CODE (operands[0]),
1199 operands[1], operands[2], operands[3]);
1200 DONE;
1201 })
1202
1203 (define_expand "cstorecc4"
1204 [(set (match_operand:QI 0 "register_operand" "")
1205 (match_operator 1 "comparison_operator"
1206 [(match_operand 2 "flags_reg_operand" "")
1207 (match_operand 3 "const0_operand" "")]))]
1208 ""
1209 {
1210 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1211 operands[2], operands[3]);
1212 DONE;
1213 })
1214
1215
1216 ;; FP compares, step 1:
1217 ;; Set the FP condition codes.
1218 ;;
1219 ;; CCFPmode compare with exceptions
1220 ;; CCFPUmode compare with no exceptions
1221
1222 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1223 ;; used to manage the reg stack popping would not be preserved.
1224
1225 (define_insn "*cmpfp_0"
1226 [(set (match_operand:HI 0 "register_operand" "=a")
1227 (unspec:HI
1228 [(compare:CCFP
1229 (match_operand 1 "register_operand" "f")
1230 (match_operand 2 "const0_operand" ""))]
1231 UNSPEC_FNSTSW))]
1232 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1233 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1234 "* return output_fp_compare (insn, operands, 0, 0);"
1235 [(set_attr "type" "multi")
1236 (set_attr "unit" "i387")
1237 (set (attr "mode")
1238 (cond [(match_operand:SF 1 "" "")
1239 (const_string "SF")
1240 (match_operand:DF 1 "" "")
1241 (const_string "DF")
1242 ]
1243 (const_string "XF")))])
1244
1245 (define_insn_and_split "*cmpfp_0_cc"
1246 [(set (reg:CCFP FLAGS_REG)
1247 (compare:CCFP
1248 (match_operand 1 "register_operand" "f")
1249 (match_operand 2 "const0_operand" "")))
1250 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1251 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1252 && TARGET_SAHF && !TARGET_CMOVE
1253 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1254 "#"
1255 "&& reload_completed"
1256 [(set (match_dup 0)
1257 (unspec:HI
1258 [(compare:CCFP (match_dup 1)(match_dup 2))]
1259 UNSPEC_FNSTSW))
1260 (set (reg:CC FLAGS_REG)
1261 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1262 ""
1263 [(set_attr "type" "multi")
1264 (set_attr "unit" "i387")
1265 (set (attr "mode")
1266 (cond [(match_operand:SF 1 "" "")
1267 (const_string "SF")
1268 (match_operand:DF 1 "" "")
1269 (const_string "DF")
1270 ]
1271 (const_string "XF")))])
1272
1273 (define_insn "*cmpfp_xf"
1274 [(set (match_operand:HI 0 "register_operand" "=a")
1275 (unspec:HI
1276 [(compare:CCFP
1277 (match_operand:XF 1 "register_operand" "f")
1278 (match_operand:XF 2 "register_operand" "f"))]
1279 UNSPEC_FNSTSW))]
1280 "TARGET_80387"
1281 "* return output_fp_compare (insn, operands, 0, 0);"
1282 [(set_attr "type" "multi")
1283 (set_attr "unit" "i387")
1284 (set_attr "mode" "XF")])
1285
1286 (define_insn_and_split "*cmpfp_xf_cc"
1287 [(set (reg:CCFP FLAGS_REG)
1288 (compare:CCFP
1289 (match_operand:XF 1 "register_operand" "f")
1290 (match_operand:XF 2 "register_operand" "f")))
1291 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1292 "TARGET_80387
1293 && TARGET_SAHF && !TARGET_CMOVE"
1294 "#"
1295 "&& reload_completed"
1296 [(set (match_dup 0)
1297 (unspec:HI
1298 [(compare:CCFP (match_dup 1)(match_dup 2))]
1299 UNSPEC_FNSTSW))
1300 (set (reg:CC FLAGS_REG)
1301 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1302 ""
1303 [(set_attr "type" "multi")
1304 (set_attr "unit" "i387")
1305 (set_attr "mode" "XF")])
1306
1307 (define_insn "*cmpfp_<mode>"
1308 [(set (match_operand:HI 0 "register_operand" "=a")
1309 (unspec:HI
1310 [(compare:CCFP
1311 (match_operand:MODEF 1 "register_operand" "f")
1312 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1313 UNSPEC_FNSTSW))]
1314 "TARGET_80387"
1315 "* return output_fp_compare (insn, operands, 0, 0);"
1316 [(set_attr "type" "multi")
1317 (set_attr "unit" "i387")
1318 (set_attr "mode" "<MODE>")])
1319
1320 (define_insn_and_split "*cmpfp_<mode>_cc"
1321 [(set (reg:CCFP FLAGS_REG)
1322 (compare:CCFP
1323 (match_operand:MODEF 1 "register_operand" "f")
1324 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1325 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1326 "TARGET_80387
1327 && TARGET_SAHF && !TARGET_CMOVE"
1328 "#"
1329 "&& reload_completed"
1330 [(set (match_dup 0)
1331 (unspec:HI
1332 [(compare:CCFP (match_dup 1)(match_dup 2))]
1333 UNSPEC_FNSTSW))
1334 (set (reg:CC FLAGS_REG)
1335 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1336 ""
1337 [(set_attr "type" "multi")
1338 (set_attr "unit" "i387")
1339 (set_attr "mode" "<MODE>")])
1340
1341 (define_insn "*cmpfp_u"
1342 [(set (match_operand:HI 0 "register_operand" "=a")
1343 (unspec:HI
1344 [(compare:CCFPU
1345 (match_operand 1 "register_operand" "f")
1346 (match_operand 2 "register_operand" "f"))]
1347 UNSPEC_FNSTSW))]
1348 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1349 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1350 "* return output_fp_compare (insn, operands, 0, 1);"
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1353 (set (attr "mode")
1354 (cond [(match_operand:SF 1 "" "")
1355 (const_string "SF")
1356 (match_operand:DF 1 "" "")
1357 (const_string "DF")
1358 ]
1359 (const_string "XF")))])
1360
1361 (define_insn_and_split "*cmpfp_u_cc"
1362 [(set (reg:CCFPU FLAGS_REG)
1363 (compare:CCFPU
1364 (match_operand 1 "register_operand" "f")
1365 (match_operand 2 "register_operand" "f")))
1366 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1367 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1368 && TARGET_SAHF && !TARGET_CMOVE
1369 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1370 "#"
1371 "&& reload_completed"
1372 [(set (match_dup 0)
1373 (unspec:HI
1374 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1375 UNSPEC_FNSTSW))
1376 (set (reg:CC FLAGS_REG)
1377 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1378 ""
1379 [(set_attr "type" "multi")
1380 (set_attr "unit" "i387")
1381 (set (attr "mode")
1382 (cond [(match_operand:SF 1 "" "")
1383 (const_string "SF")
1384 (match_operand:DF 1 "" "")
1385 (const_string "DF")
1386 ]
1387 (const_string "XF")))])
1388
1389 (define_insn "*cmpfp_<mode>"
1390 [(set (match_operand:HI 0 "register_operand" "=a")
1391 (unspec:HI
1392 [(compare:CCFP
1393 (match_operand 1 "register_operand" "f")
1394 (match_operator 3 "float_operator"
1395 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1396 UNSPEC_FNSTSW))]
1397 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1398 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1399 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1400 "* return output_fp_compare (insn, operands, 0, 0);"
1401 [(set_attr "type" "multi")
1402 (set_attr "unit" "i387")
1403 (set_attr "fp_int_src" "true")
1404 (set_attr "mode" "<MODE>")])
1405
1406 (define_insn_and_split "*cmpfp_<mode>_cc"
1407 [(set (reg:CCFP FLAGS_REG)
1408 (compare:CCFP
1409 (match_operand 1 "register_operand" "f")
1410 (match_operator 3 "float_operator"
1411 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1412 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1414 && TARGET_SAHF && !TARGET_CMOVE
1415 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1416 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1417 "#"
1418 "&& reload_completed"
1419 [(set (match_dup 0)
1420 (unspec:HI
1421 [(compare:CCFP
1422 (match_dup 1)
1423 (match_op_dup 3 [(match_dup 2)]))]
1424 UNSPEC_FNSTSW))
1425 (set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1427 ""
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1432
1433 ;; FP compares, step 2
1434 ;; Move the fpsw to ax.
1435
1436 (define_insn "x86_fnstsw_1"
1437 [(set (match_operand:HI 0 "register_operand" "=a")
1438 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1439 "TARGET_80387"
1440 "fnstsw\t%0"
1441 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1442 (set_attr "mode" "SI")
1443 (set_attr "unit" "i387")])
1444
1445 ;; FP compares, step 3
1446 ;; Get ax into flags, general case.
1447
1448 (define_insn "x86_sahf_1"
1449 [(set (reg:CC FLAGS_REG)
1450 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1451 UNSPEC_SAHF))]
1452 "TARGET_SAHF"
1453 {
1454 #ifndef HAVE_AS_IX86_SAHF
1455 if (TARGET_64BIT)
1456 return ASM_BYTE "0x9e";
1457 else
1458 #endif
1459 return "sahf";
1460 }
1461 [(set_attr "length" "1")
1462 (set_attr "athlon_decode" "vector")
1463 (set_attr "amdfam10_decode" "direct")
1464 (set_attr "mode" "SI")])
1465
1466 ;; Pentium Pro can do steps 1 through 3 in one go.
1467 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1468 (define_insn "*cmpfp_i_mixed"
1469 [(set (reg:CCFP FLAGS_REG)
1470 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1471 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1472 "TARGET_MIX_SSE_I387
1473 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1474 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1475 "* return output_fp_compare (insn, operands, 1, 0);"
1476 [(set_attr "type" "fcmp,ssecomi")
1477 (set_attr "prefix" "orig,maybe_vex")
1478 (set (attr "mode")
1479 (if_then_else (match_operand:SF 1 "" "")
1480 (const_string "SF")
1481 (const_string "DF")))
1482 (set (attr "prefix_rep")
1483 (if_then_else (eq_attr "type" "ssecomi")
1484 (const_string "0")
1485 (const_string "*")))
1486 (set (attr "prefix_data16")
1487 (cond [(eq_attr "type" "fcmp")
1488 (const_string "*")
1489 (eq_attr "mode" "DF")
1490 (const_string "1")
1491 ]
1492 (const_string "0")))
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")])
1495
1496 (define_insn "*cmpfp_i_sse"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "x")
1499 (match_operand 1 "nonimmediate_operand" "xm")))]
1500 "TARGET_SSE_MATH
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, 1, 0);"
1504 [(set_attr "type" "ssecomi")
1505 (set_attr "prefix" "maybe_vex")
1506 (set (attr "mode")
1507 (if_then_else (match_operand:SF 1 "" "")
1508 (const_string "SF")
1509 (const_string "DF")))
1510 (set_attr "prefix_rep" "0")
1511 (set (attr "prefix_data16")
1512 (if_then_else (eq_attr "mode" "DF")
1513 (const_string "1")
1514 (const_string "0")))
1515 (set_attr "athlon_decode" "vector")
1516 (set_attr "amdfam10_decode" "direct")])
1517
1518 (define_insn "*cmpfp_i_i387"
1519 [(set (reg:CCFP FLAGS_REG)
1520 (compare:CCFP (match_operand 0 "register_operand" "f")
1521 (match_operand 1 "register_operand" "f")))]
1522 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1523 && TARGET_CMOVE
1524 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1525 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526 "* return output_fp_compare (insn, operands, 1, 0);"
1527 [(set_attr "type" "fcmp")
1528 (set (attr "mode")
1529 (cond [(match_operand:SF 1 "" "")
1530 (const_string "SF")
1531 (match_operand:DF 1 "" "")
1532 (const_string "DF")
1533 ]
1534 (const_string "XF")))
1535 (set_attr "athlon_decode" "vector")
1536 (set_attr "amdfam10_decode" "direct")])
1537
1538 (define_insn "*cmpfp_iu_mixed"
1539 [(set (reg:CCFPU FLAGS_REG)
1540 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1541 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1542 "TARGET_MIX_SSE_I387
1543 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1545 "* return output_fp_compare (insn, operands, 1, 1);"
1546 [(set_attr "type" "fcmp,ssecomi")
1547 (set_attr "prefix" "orig,maybe_vex")
1548 (set (attr "mode")
1549 (if_then_else (match_operand:SF 1 "" "")
1550 (const_string "SF")
1551 (const_string "DF")))
1552 (set (attr "prefix_rep")
1553 (if_then_else (eq_attr "type" "ssecomi")
1554 (const_string "0")
1555 (const_string "*")))
1556 (set (attr "prefix_data16")
1557 (cond [(eq_attr "type" "fcmp")
1558 (const_string "*")
1559 (eq_attr "mode" "DF")
1560 (const_string "1")
1561 ]
1562 (const_string "0")))
1563 (set_attr "athlon_decode" "vector")
1564 (set_attr "amdfam10_decode" "direct")])
1565
1566 (define_insn "*cmpfp_iu_sse"
1567 [(set (reg:CCFPU FLAGS_REG)
1568 (compare:CCFPU (match_operand 0 "register_operand" "x")
1569 (match_operand 1 "nonimmediate_operand" "xm")))]
1570 "TARGET_SSE_MATH
1571 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573 "* return output_fp_compare (insn, operands, 1, 1);"
1574 [(set_attr "type" "ssecomi")
1575 (set_attr "prefix" "maybe_vex")
1576 (set (attr "mode")
1577 (if_then_else (match_operand:SF 1 "" "")
1578 (const_string "SF")
1579 (const_string "DF")))
1580 (set_attr "prefix_rep" "0")
1581 (set (attr "prefix_data16")
1582 (if_then_else (eq_attr "mode" "DF")
1583 (const_string "1")
1584 (const_string "0")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")])
1587
1588 (define_insn "*cmpfp_iu_387"
1589 [(set (reg:CCFPU FLAGS_REG)
1590 (compare:CCFPU (match_operand 0 "register_operand" "f")
1591 (match_operand 1 "register_operand" "f")))]
1592 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1593 && TARGET_CMOVE
1594 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1595 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1596 "* return output_fp_compare (insn, operands, 1, 1);"
1597 [(set_attr "type" "fcmp")
1598 (set (attr "mode")
1599 (cond [(match_operand:SF 1 "" "")
1600 (const_string "SF")
1601 (match_operand:DF 1 "" "")
1602 (const_string "DF")
1603 ]
1604 (const_string "XF")))
1605 (set_attr "athlon_decode" "vector")
1606 (set_attr "amdfam10_decode" "direct")])
1607 \f
1608 ;; Push/pop instructions.
1609
1610 (define_insn "*pushdi2_rex64"
1611 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1613 "TARGET_64BIT"
1614 "@
1615 push{q}\t%1
1616 #"
1617 [(set_attr "type" "push,multi")
1618 (set_attr "mode" "DI")])
1619
1620 ;; Convert impossible pushes of immediate to existing instructions.
1621 ;; First try to get scratch register and go through it. In case this
1622 ;; fails, push sign extended lower part first and then overwrite
1623 ;; upper part by 32bit move.
1624 (define_peephole2
1625 [(match_scratch:DI 2 "r")
1626 (set (match_operand:DI 0 "push_operand" "")
1627 (match_operand:DI 1 "immediate_operand" ""))]
1628 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629 && !x86_64_immediate_operand (operands[1], DImode)"
1630 [(set (match_dup 2) (match_dup 1))
1631 (set (match_dup 0) (match_dup 2))])
1632
1633 ;; We need to define this as both peepholer and splitter for case
1634 ;; peephole2 pass is not run.
1635 ;; "&& 1" is needed to keep it from matching the previous pattern.
1636 (define_peephole2
1637 [(set (match_operand:DI 0 "push_operand" "")
1638 (match_operand:DI 1 "immediate_operand" ""))]
1639 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641 [(set (match_dup 0) (match_dup 1))
1642 (set (match_dup 2) (match_dup 3))]
1643 {
1644 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1645
1646 operands[1] = gen_lowpart (DImode, operands[2]);
1647 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1648 GEN_INT (4)));
1649 })
1650
1651 (define_split
1652 [(set (match_operand:DI 0 "push_operand" "")
1653 (match_operand:DI 1 "immediate_operand" ""))]
1654 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655 ? epilogue_completed : reload_completed)
1656 && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode)"
1658 [(set (match_dup 0) (match_dup 1))
1659 (set (match_dup 2) (match_dup 3))]
1660 {
1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662
1663 operands[1] = gen_lowpart (DImode, operands[2]);
1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665 GEN_INT (4)));
1666 })
1667
1668 (define_insn "*pushdi2"
1669 [(set (match_operand:DI 0 "push_operand" "=<")
1670 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1671 "!TARGET_64BIT"
1672 "#")
1673
1674 (define_split
1675 [(set (match_operand:DI 0 "push_operand" "")
1676 (match_operand:DI 1 "general_operand" ""))]
1677 "!TARGET_64BIT && reload_completed
1678 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1679 [(const_int 0)]
1680 "ix86_split_long_move (operands); DONE;")
1681
1682 (define_insn "*pushsi2"
1683 [(set (match_operand:SI 0 "push_operand" "=<")
1684 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1685 "!TARGET_64BIT"
1686 "push{l}\t%1"
1687 [(set_attr "type" "push")
1688 (set_attr "mode" "SI")])
1689
1690 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1691 ;; "push a byte/word". But actually we use pushl, which has the effect
1692 ;; of rounding the amount pushed up to a word.
1693
1694 ;; For TARGET_64BIT we always round up to 8 bytes.
1695 (define_insn "*push<mode>2_rex64"
1696 [(set (match_operand:SWI124 0 "push_operand" "=X")
1697 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1698 "TARGET_64BIT"
1699 "push{q}\t%q1"
1700 [(set_attr "type" "push")
1701 (set_attr "mode" "DI")])
1702
1703 (define_insn "*push<mode>2"
1704 [(set (match_operand:SWI12 0 "push_operand" "=X")
1705 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1706 "!TARGET_64BIT"
1707 "push{l}\t%k1"
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "SI")])
1710
1711 (define_insn "*push<mode>2_prologue"
1712 [(set (match_operand:P 0 "push_operand" "=<")
1713 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1714 (clobber (mem:BLK (scratch)))]
1715 ""
1716 "push{<imodesuffix>}\t%1"
1717 [(set_attr "type" "push")
1718 (set_attr "mode" "<MODE>")])
1719
1720 (define_insn "*pop<mode>1"
1721 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1722 (match_operand:P 1 "pop_operand" ">"))]
1723 ""
1724 "pop{<imodesuffix>}\t%0"
1725 [(set_attr "type" "pop")
1726 (set_attr "mode" "<MODE>")])
1727
1728 (define_insn "*pop<mode>1_epilogue"
1729 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1730 (match_operand:P 1 "pop_operand" ">"))
1731 (clobber (mem:BLK (scratch)))]
1732 ""
1733 "pop{<imodesuffix>}\t%0"
1734 [(set_attr "type" "pop")
1735 (set_attr "mode" "<MODE>")])
1736 \f
1737 ;; Move instructions.
1738
1739 (define_expand "movoi"
1740 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1741 (match_operand:OI 1 "general_operand" ""))]
1742 "TARGET_AVX"
1743 "ix86_expand_move (OImode, operands); DONE;")
1744
1745 (define_expand "movti"
1746 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1747 (match_operand:TI 1 "nonimmediate_operand" ""))]
1748 "TARGET_64BIT || TARGET_SSE"
1749 {
1750 if (TARGET_64BIT)
1751 ix86_expand_move (TImode, operands);
1752 else if (push_operand (operands[0], TImode))
1753 ix86_expand_push (TImode, operands[1]);
1754 else
1755 ix86_expand_vector_move (TImode, operands);
1756 DONE;
1757 })
1758
1759 ;; This expands to what emit_move_complex would generate if we didn't
1760 ;; have a movti pattern. Having this avoids problems with reload on
1761 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1762 ;; to have around all the time.
1763 (define_expand "movcdi"
1764 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1765 (match_operand:CDI 1 "general_operand" ""))]
1766 ""
1767 {
1768 if (push_operand (operands[0], CDImode))
1769 emit_move_complex_push (CDImode, operands[0], operands[1]);
1770 else
1771 emit_move_complex_parts (operands[0], operands[1]);
1772 DONE;
1773 })
1774
1775 (define_expand "mov<mode>"
1776 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1777 (match_operand:SWI1248x 1 "general_operand" ""))]
1778 ""
1779 "ix86_expand_move (<MODE>mode, operands); DONE;")
1780
1781 (define_insn "*mov<mode>_xor"
1782 [(set (match_operand:SWI48 0 "register_operand" "=r")
1783 (match_operand:SWI48 1 "const0_operand" ""))
1784 (clobber (reg:CC FLAGS_REG))]
1785 "reload_completed"
1786 "xor{l}\t%k0, %k0"
1787 [(set_attr "type" "alu1")
1788 (set_attr "mode" "SI")
1789 (set_attr "length_immediate" "0")])
1790
1791 (define_insn "*mov<mode>_or"
1792 [(set (match_operand:SWI48 0 "register_operand" "=r")
1793 (match_operand:SWI48 1 "const_int_operand" ""))
1794 (clobber (reg:CC FLAGS_REG))]
1795 "reload_completed
1796 && operands[1] == constm1_rtx"
1797 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1798 [(set_attr "type" "alu1")
1799 (set_attr "mode" "<MODE>")
1800 (set_attr "length_immediate" "1")])
1801
1802 (define_insn "*movoi_internal_avx"
1803 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1804 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1805 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1806 {
1807 switch (which_alternative)
1808 {
1809 case 0:
1810 return "vxorps\t%0, %0, %0";
1811 case 1:
1812 case 2:
1813 if (misaligned_operand (operands[0], OImode)
1814 || misaligned_operand (operands[1], OImode))
1815 return "vmovdqu\t{%1, %0|%0, %1}";
1816 else
1817 return "vmovdqa\t{%1, %0|%0, %1}";
1818 default:
1819 gcc_unreachable ();
1820 }
1821 }
1822 [(set_attr "type" "sselog1,ssemov,ssemov")
1823 (set_attr "prefix" "vex")
1824 (set_attr "mode" "OI")])
1825
1826 (define_insn "*movti_internal_rex64"
1827 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1828 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1829 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1830 {
1831 switch (which_alternative)
1832 {
1833 case 0:
1834 case 1:
1835 return "#";
1836 case 2:
1837 if (get_attr_mode (insn) == MODE_V4SF)
1838 return "%vxorps\t%0, %d0";
1839 else
1840 return "%vpxor\t%0, %d0";
1841 case 3:
1842 case 4:
1843 /* TDmode values are passed as TImode on the stack. Moving them
1844 to stack may result in unaligned memory access. */
1845 if (misaligned_operand (operands[0], TImode)
1846 || misaligned_operand (operands[1], TImode))
1847 {
1848 if (get_attr_mode (insn) == MODE_V4SF)
1849 return "%vmovups\t{%1, %0|%0, %1}";
1850 else
1851 return "%vmovdqu\t{%1, %0|%0, %1}";
1852 }
1853 else
1854 {
1855 if (get_attr_mode (insn) == MODE_V4SF)
1856 return "%vmovaps\t{%1, %0|%0, %1}";
1857 else
1858 return "%vmovdqa\t{%1, %0|%0, %1}";
1859 }
1860 default:
1861 gcc_unreachable ();
1862 }
1863 }
1864 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1866 (set (attr "mode")
1867 (cond [(eq_attr "alternative" "2,3")
1868 (if_then_else
1869 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1870 (const_int 0))
1871 (const_string "V4SF")
1872 (const_string "TI"))
1873 (eq_attr "alternative" "4")
1874 (if_then_else
1875 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1876 (const_int 0))
1877 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1878 (const_int 0)))
1879 (const_string "V4SF")
1880 (const_string "TI"))]
1881 (const_string "DI")))])
1882
1883 (define_split
1884 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1885 (match_operand:TI 1 "general_operand" ""))]
1886 "reload_completed
1887 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1888 [(const_int 0)]
1889 "ix86_split_long_move (operands); DONE;")
1890
1891 (define_insn "*movti_internal_sse"
1892 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1893 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1894 "TARGET_SSE && !TARGET_64BIT
1895 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1896 {
1897 switch (which_alternative)
1898 {
1899 case 0:
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vxorps\t%0, %d0";
1902 else
1903 return "%vpxor\t%0, %d0";
1904 case 1:
1905 case 2:
1906 /* TDmode values are passed as TImode on the stack. Moving them
1907 to stack may result in unaligned memory access. */
1908 if (misaligned_operand (operands[0], TImode)
1909 || misaligned_operand (operands[1], TImode))
1910 {
1911 if (get_attr_mode (insn) == MODE_V4SF)
1912 return "%vmovups\t{%1, %0|%0, %1}";
1913 else
1914 return "%vmovdqu\t{%1, %0|%0, %1}";
1915 }
1916 else
1917 {
1918 if (get_attr_mode (insn) == MODE_V4SF)
1919 return "%vmovaps\t{%1, %0|%0, %1}";
1920 else
1921 return "%vmovdqa\t{%1, %0|%0, %1}";
1922 }
1923 default:
1924 gcc_unreachable ();
1925 }
1926 }
1927 [(set_attr "type" "sselog1,ssemov,ssemov")
1928 (set_attr "prefix" "maybe_vex")
1929 (set (attr "mode")
1930 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1931 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1932 (const_int 0)))
1933 (const_string "V4SF")
1934 (and (eq_attr "alternative" "2")
1935 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1936 (const_int 0)))
1937 (const_string "V4SF")]
1938 (const_string "TI")))])
1939
1940 (define_insn "*movdi_internal_rex64"
1941 [(set (match_operand:DI 0 "nonimmediate_operand"
1942 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1943 (match_operand:DI 1 "general_operand"
1944 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1945 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946 {
1947 switch (get_attr_type (insn))
1948 {
1949 case TYPE_SSECVT:
1950 if (SSE_REG_P (operands[0]))
1951 return "movq2dq\t{%1, %0|%0, %1}";
1952 else
1953 return "movdq2q\t{%1, %0|%0, %1}";
1954
1955 case TYPE_SSEMOV:
1956 if (TARGET_AVX)
1957 {
1958 if (get_attr_mode (insn) == MODE_TI)
1959 return "vmovdqa\t{%1, %0|%0, %1}";
1960 else
1961 return "vmovq\t{%1, %0|%0, %1}";
1962 }
1963
1964 if (get_attr_mode (insn) == MODE_TI)
1965 return "movdqa\t{%1, %0|%0, %1}";
1966 /* FALLTHRU */
1967
1968 case TYPE_MMXMOV:
1969 /* Moves from and into integer register is done using movd
1970 opcode with REX prefix. */
1971 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1972 return "movd\t{%1, %0|%0, %1}";
1973 return "movq\t{%1, %0|%0, %1}";
1974
1975 case TYPE_SSELOG1:
1976 return "%vpxor\t%0, %d0";
1977
1978 case TYPE_MMX:
1979 return "pxor\t%0, %0";
1980
1981 case TYPE_MULTI:
1982 return "#";
1983
1984 case TYPE_LEA:
1985 return "lea{q}\t{%a1, %0|%0, %a1}";
1986
1987 default:
1988 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1989 if (get_attr_mode (insn) == MODE_SI)
1990 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1991 else if (which_alternative == 2)
1992 return "movabs{q}\t{%1, %0|%0, %1}";
1993 else
1994 return "mov{q}\t{%1, %0|%0, %1}";
1995 }
1996 }
1997 [(set (attr "type")
1998 (cond [(eq_attr "alternative" "5")
1999 (const_string "mmx")
2000 (eq_attr "alternative" "6,7,8,9,10")
2001 (const_string "mmxmov")
2002 (eq_attr "alternative" "11")
2003 (const_string "sselog1")
2004 (eq_attr "alternative" "12,13,14,15,16")
2005 (const_string "ssemov")
2006 (eq_attr "alternative" "17,18")
2007 (const_string "ssecvt")
2008 (eq_attr "alternative" "4")
2009 (const_string "multi")
2010 (match_operand:DI 1 "pic_32bit_operand" "")
2011 (const_string "lea")
2012 ]
2013 (const_string "imov")))
2014 (set (attr "modrm")
2015 (if_then_else
2016 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2017 (const_string "0")
2018 (const_string "*")))
2019 (set (attr "length_immediate")
2020 (if_then_else
2021 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2022 (const_string "8")
2023 (const_string "*")))
2024 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2025 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2026 (set (attr "prefix")
2027 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2028 (const_string "maybe_vex")
2029 (const_string "orig")))
2030 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2031
2032 ;; Convert impossible stores of immediate to existing instructions.
2033 ;; First try to get scratch register and go through it. In case this
2034 ;; fails, move by 32bit parts.
2035 (define_peephole2
2036 [(match_scratch:DI 2 "r")
2037 (set (match_operand:DI 0 "memory_operand" "")
2038 (match_operand:DI 1 "immediate_operand" ""))]
2039 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2040 && !x86_64_immediate_operand (operands[1], DImode)"
2041 [(set (match_dup 2) (match_dup 1))
2042 (set (match_dup 0) (match_dup 2))])
2043
2044 ;; We need to define this as both peepholer and splitter for case
2045 ;; peephole2 pass is not run.
2046 ;; "&& 1" is needed to keep it from matching the previous pattern.
2047 (define_peephole2
2048 [(set (match_operand:DI 0 "memory_operand" "")
2049 (match_operand:DI 1 "immediate_operand" ""))]
2050 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2051 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2052 [(set (match_dup 2) (match_dup 3))
2053 (set (match_dup 4) (match_dup 5))]
2054 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2055
2056 (define_split
2057 [(set (match_operand:DI 0 "memory_operand" "")
2058 (match_operand:DI 1 "immediate_operand" ""))]
2059 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2060 ? epilogue_completed : reload_completed)
2061 && !symbolic_operand (operands[1], DImode)
2062 && !x86_64_immediate_operand (operands[1], DImode)"
2063 [(set (match_dup 2) (match_dup 3))
2064 (set (match_dup 4) (match_dup 5))]
2065 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2066
2067 (define_insn "*movdi_internal"
2068 [(set (match_operand:DI 0 "nonimmediate_operand"
2069 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2070 (match_operand:DI 1 "general_operand"
2071 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2072 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2073 "@
2074 #
2075 #
2076 pxor\t%0, %0
2077 movq\t{%1, %0|%0, %1}
2078 movq\t{%1, %0|%0, %1}
2079 %vpxor\t%0, %d0
2080 %vmovq\t{%1, %0|%0, %1}
2081 %vmovdqa\t{%1, %0|%0, %1}
2082 %vmovq\t{%1, %0|%0, %1}
2083 xorps\t%0, %0
2084 movlps\t{%1, %0|%0, %1}
2085 movaps\t{%1, %0|%0, %1}
2086 movlps\t{%1, %0|%0, %1}"
2087 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2088 (set (attr "prefix")
2089 (if_then_else (eq_attr "alternative" "5,6,7,8")
2090 (const_string "vex")
2091 (const_string "orig")))
2092 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2093
2094 (define_split
2095 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2096 (match_operand:DI 1 "general_operand" ""))]
2097 "!TARGET_64BIT && reload_completed
2098 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2099 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2100 [(const_int 0)]
2101 "ix86_split_long_move (operands); DONE;")
2102
2103 (define_insn "*movsi_internal"
2104 [(set (match_operand:SI 0 "nonimmediate_operand"
2105 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2106 (match_operand:SI 1 "general_operand"
2107 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2108 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2109 {
2110 switch (get_attr_type (insn))
2111 {
2112 case TYPE_SSELOG1:
2113 if (get_attr_mode (insn) == MODE_TI)
2114 return "%vpxor\t%0, %d0";
2115 return "%vxorps\t%0, %d0";
2116
2117 case TYPE_SSEMOV:
2118 switch (get_attr_mode (insn))
2119 {
2120 case MODE_TI:
2121 return "%vmovdqa\t{%1, %0|%0, %1}";
2122 case MODE_V4SF:
2123 return "%vmovaps\t{%1, %0|%0, %1}";
2124 case MODE_SI:
2125 return "%vmovd\t{%1, %0|%0, %1}";
2126 case MODE_SF:
2127 return "%vmovss\t{%1, %0|%0, %1}";
2128 default:
2129 gcc_unreachable ();
2130 }
2131
2132 case TYPE_MMX:
2133 return "pxor\t%0, %0";
2134
2135 case TYPE_MMXMOV:
2136 if (get_attr_mode (insn) == MODE_DI)
2137 return "movq\t{%1, %0|%0, %1}";
2138 return "movd\t{%1, %0|%0, %1}";
2139
2140 case TYPE_LEA:
2141 return "lea{l}\t{%a1, %0|%0, %a1}";
2142
2143 default:
2144 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2145 return "mov{l}\t{%1, %0|%0, %1}";
2146 }
2147 }
2148 [(set (attr "type")
2149 (cond [(eq_attr "alternative" "2")
2150 (const_string "mmx")
2151 (eq_attr "alternative" "3,4,5")
2152 (const_string "mmxmov")
2153 (eq_attr "alternative" "6")
2154 (const_string "sselog1")
2155 (eq_attr "alternative" "7,8,9,10,11")
2156 (const_string "ssemov")
2157 (match_operand:DI 1 "pic_32bit_operand" "")
2158 (const_string "lea")
2159 ]
2160 (const_string "imov")))
2161 (set (attr "prefix")
2162 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2163 (const_string "orig")
2164 (const_string "maybe_vex")))
2165 (set (attr "prefix_data16")
2166 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2167 (const_string "1")
2168 (const_string "*")))
2169 (set (attr "mode")
2170 (cond [(eq_attr "alternative" "2,3")
2171 (const_string "DI")
2172 (eq_attr "alternative" "6,7")
2173 (if_then_else
2174 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2175 (const_string "V4SF")
2176 (const_string "TI"))
2177 (and (eq_attr "alternative" "8,9,10,11")
2178 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2179 (const_string "SF")
2180 ]
2181 (const_string "SI")))])
2182
2183 (define_insn "*movhi_internal"
2184 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2185 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2186 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2187 {
2188 switch (get_attr_type (insn))
2189 {
2190 case TYPE_IMOVX:
2191 /* movzwl is faster than movw on p2 due to partial word stalls,
2192 though not as fast as an aligned movl. */
2193 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2194 default:
2195 if (get_attr_mode (insn) == MODE_SI)
2196 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2197 else
2198 return "mov{w}\t{%1, %0|%0, %1}";
2199 }
2200 }
2201 [(set (attr "type")
2202 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2203 (const_int 0))
2204 (const_string "imov")
2205 (and (eq_attr "alternative" "0")
2206 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2207 (const_int 0))
2208 (eq (symbol_ref "TARGET_HIMODE_MATH")
2209 (const_int 0))))
2210 (const_string "imov")
2211 (and (eq_attr "alternative" "1,2")
2212 (match_operand:HI 1 "aligned_operand" ""))
2213 (const_string "imov")
2214 (and (ne (symbol_ref "TARGET_MOVX")
2215 (const_int 0))
2216 (eq_attr "alternative" "0,2"))
2217 (const_string "imovx")
2218 ]
2219 (const_string "imov")))
2220 (set (attr "mode")
2221 (cond [(eq_attr "type" "imovx")
2222 (const_string "SI")
2223 (and (eq_attr "alternative" "1,2")
2224 (match_operand:HI 1 "aligned_operand" ""))
2225 (const_string "SI")
2226 (and (eq_attr "alternative" "0")
2227 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2228 (const_int 0))
2229 (eq (symbol_ref "TARGET_HIMODE_MATH")
2230 (const_int 0))))
2231 (const_string "SI")
2232 ]
2233 (const_string "HI")))])
2234
2235 ;; Situation is quite tricky about when to choose full sized (SImode) move
2236 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2237 ;; partial register dependency machines (such as AMD Athlon), where QImode
2238 ;; moves issue extra dependency and for partial register stalls machines
2239 ;; that don't use QImode patterns (and QImode move cause stall on the next
2240 ;; instruction).
2241 ;;
2242 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2243 ;; register stall machines with, where we use QImode instructions, since
2244 ;; partial register stall can be caused there. Then we use movzx.
2245 (define_insn "*movqi_internal"
2246 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2247 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2248 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2249 {
2250 switch (get_attr_type (insn))
2251 {
2252 case TYPE_IMOVX:
2253 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2254 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2255 default:
2256 if (get_attr_mode (insn) == MODE_SI)
2257 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2258 else
2259 return "mov{b}\t{%1, %0|%0, %1}";
2260 }
2261 }
2262 [(set (attr "type")
2263 (cond [(and (eq_attr "alternative" "5")
2264 (not (match_operand:QI 1 "aligned_operand" "")))
2265 (const_string "imovx")
2266 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2267 (const_int 0))
2268 (const_string "imov")
2269 (and (eq_attr "alternative" "3")
2270 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2271 (const_int 0))
2272 (eq (symbol_ref "TARGET_QIMODE_MATH")
2273 (const_int 0))))
2274 (const_string "imov")
2275 (eq_attr "alternative" "3,5")
2276 (const_string "imovx")
2277 (and (ne (symbol_ref "TARGET_MOVX")
2278 (const_int 0))
2279 (eq_attr "alternative" "2"))
2280 (const_string "imovx")
2281 ]
2282 (const_string "imov")))
2283 (set (attr "mode")
2284 (cond [(eq_attr "alternative" "3,4,5")
2285 (const_string "SI")
2286 (eq_attr "alternative" "6")
2287 (const_string "QI")
2288 (eq_attr "type" "imovx")
2289 (const_string "SI")
2290 (and (eq_attr "type" "imov")
2291 (and (eq_attr "alternative" "0,1")
2292 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2293 (const_int 0))
2294 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2295 (const_int 0))
2296 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2297 (const_int 0))))))
2298 (const_string "SI")
2299 ;; Avoid partial register stalls when not using QImode arithmetic
2300 (and (eq_attr "type" "imov")
2301 (and (eq_attr "alternative" "0,1")
2302 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2303 (const_int 0))
2304 (eq (symbol_ref "TARGET_QIMODE_MATH")
2305 (const_int 0)))))
2306 (const_string "SI")
2307 ]
2308 (const_string "QI")))])
2309
2310 ;; Stores and loads of ax to arbitrary constant address.
2311 ;; We fake an second form of instruction to force reload to load address
2312 ;; into register when rax is not available
2313 (define_insn "*movabs<mode>_1"
2314 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2315 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2316 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2317 "@
2318 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2319 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2320 [(set_attr "type" "imov")
2321 (set_attr "modrm" "0,*")
2322 (set_attr "length_address" "8,0")
2323 (set_attr "length_immediate" "0,*")
2324 (set_attr "memory" "store")
2325 (set_attr "mode" "<MODE>")])
2326
2327 (define_insn "*movabs<mode>_2"
2328 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2329 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2330 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2331 "@
2332 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2333 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2334 [(set_attr "type" "imov")
2335 (set_attr "modrm" "0,*")
2336 (set_attr "length_address" "8,0")
2337 (set_attr "length_immediate" "0")
2338 (set_attr "memory" "load")
2339 (set_attr "mode" "<MODE>")])
2340
2341 (define_insn "*swap<mode>"
2342 [(set (match_operand:SWI48 0 "register_operand" "+r")
2343 (match_operand:SWI48 1 "register_operand" "+r"))
2344 (set (match_dup 1)
2345 (match_dup 0))]
2346 ""
2347 "xchg{<imodesuffix>}\t%1, %0"
2348 [(set_attr "type" "imov")
2349 (set_attr "mode" "<MODE>")
2350 (set_attr "pent_pair" "np")
2351 (set_attr "athlon_decode" "vector")
2352 (set_attr "amdfam10_decode" "double")])
2353
2354 (define_insn "*swap<mode>_1"
2355 [(set (match_operand:SWI12 0 "register_operand" "+r")
2356 (match_operand:SWI12 1 "register_operand" "+r"))
2357 (set (match_dup 1)
2358 (match_dup 0))]
2359 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2360 "xchg{l}\t%k1, %k0"
2361 [(set_attr "type" "imov")
2362 (set_attr "mode" "SI")
2363 (set_attr "pent_pair" "np")
2364 (set_attr "athlon_decode" "vector")
2365 (set_attr "amdfam10_decode" "double")])
2366
2367 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2368 ;; is disabled for AMDFAM10
2369 (define_insn "*swap<mode>_2"
2370 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2371 (match_operand:SWI12 1 "register_operand" "+<r>"))
2372 (set (match_dup 1)
2373 (match_dup 0))]
2374 "TARGET_PARTIAL_REG_STALL"
2375 "xchg{<imodesuffix>}\t%1, %0"
2376 [(set_attr "type" "imov")
2377 (set_attr "mode" "<MODE>")
2378 (set_attr "pent_pair" "np")
2379 (set_attr "athlon_decode" "vector")])
2380
2381 (define_expand "movstrict<mode>"
2382 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2383 (match_operand:SWI12 1 "general_operand" ""))]
2384 ""
2385 {
2386 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2387 FAIL;
2388 /* Don't generate memory->memory moves, go through a register */
2389 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2390 operands[1] = force_reg (<MODE>mode, operands[1]);
2391 })
2392
2393 (define_insn "*movstrict<mode>_1"
2394 [(set (strict_low_part
2395 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2396 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2399 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2400 [(set_attr "type" "imov")
2401 (set_attr "mode" "<MODE>")])
2402
2403 (define_insn "*movstrict<mode>_xor"
2404 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2405 (match_operand:SWI12 1 "const0_operand" ""))
2406 (clobber (reg:CC FLAGS_REG))]
2407 "reload_completed"
2408 "xor{<imodesuffix>}\t%0, %0"
2409 [(set_attr "type" "alu1")
2410 (set_attr "mode" "<MODE>")
2411 (set_attr "length_immediate" "0")])
2412
2413 (define_insn "*mov<mode>_extv_1"
2414 [(set (match_operand:SWI24 0 "register_operand" "=R")
2415 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2416 (const_int 8)
2417 (const_int 8)))]
2418 ""
2419 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2420 [(set_attr "type" "imovx")
2421 (set_attr "mode" "SI")])
2422
2423 (define_insn "*movqi_extv_1_rex64"
2424 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2425 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2426 (const_int 8)
2427 (const_int 8)))]
2428 "TARGET_64BIT"
2429 {
2430 switch (get_attr_type (insn))
2431 {
2432 case TYPE_IMOVX:
2433 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2434 default:
2435 return "mov{b}\t{%h1, %0|%0, %h1}";
2436 }
2437 }
2438 [(set (attr "type")
2439 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2440 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2441 (ne (symbol_ref "TARGET_MOVX")
2442 (const_int 0))))
2443 (const_string "imovx")
2444 (const_string "imov")))
2445 (set (attr "mode")
2446 (if_then_else (eq_attr "type" "imovx")
2447 (const_string "SI")
2448 (const_string "QI")))])
2449
2450 (define_insn "*movqi_extv_1"
2451 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2452 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2453 (const_int 8)
2454 (const_int 8)))]
2455 "!TARGET_64BIT"
2456 {
2457 switch (get_attr_type (insn))
2458 {
2459 case TYPE_IMOVX:
2460 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2461 default:
2462 return "mov{b}\t{%h1, %0|%0, %h1}";
2463 }
2464 }
2465 [(set (attr "type")
2466 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2467 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2468 (ne (symbol_ref "TARGET_MOVX")
2469 (const_int 0))))
2470 (const_string "imovx")
2471 (const_string "imov")))
2472 (set (attr "mode")
2473 (if_then_else (eq_attr "type" "imovx")
2474 (const_string "SI")
2475 (const_string "QI")))])
2476
2477 (define_insn "*mov<mode>_extzv_1"
2478 [(set (match_operand:SWI48 0 "register_operand" "=R")
2479 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2480 (const_int 8)
2481 (const_int 8)))]
2482 ""
2483 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2484 [(set_attr "type" "imovx")
2485 (set_attr "mode" "SI")])
2486
2487 (define_insn "*movqi_extzv_2_rex64"
2488 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2489 (subreg:QI
2490 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2491 (const_int 8)
2492 (const_int 8)) 0))]
2493 "TARGET_64BIT"
2494 {
2495 switch (get_attr_type (insn))
2496 {
2497 case TYPE_IMOVX:
2498 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2499 default:
2500 return "mov{b}\t{%h1, %0|%0, %h1}";
2501 }
2502 }
2503 [(set (attr "type")
2504 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2505 (ne (symbol_ref "TARGET_MOVX")
2506 (const_int 0)))
2507 (const_string "imovx")
2508 (const_string "imov")))
2509 (set (attr "mode")
2510 (if_then_else (eq_attr "type" "imovx")
2511 (const_string "SI")
2512 (const_string "QI")))])
2513
2514 (define_insn "*movqi_extzv_2"
2515 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2516 (subreg:QI
2517 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2518 (const_int 8)
2519 (const_int 8)) 0))]
2520 "!TARGET_64BIT"
2521 {
2522 switch (get_attr_type (insn))
2523 {
2524 case TYPE_IMOVX:
2525 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2526 default:
2527 return "mov{b}\t{%h1, %0|%0, %h1}";
2528 }
2529 }
2530 [(set (attr "type")
2531 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2532 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2533 (ne (symbol_ref "TARGET_MOVX")
2534 (const_int 0))))
2535 (const_string "imovx")
2536 (const_string "imov")))
2537 (set (attr "mode")
2538 (if_then_else (eq_attr "type" "imovx")
2539 (const_string "SI")
2540 (const_string "QI")))])
2541
2542 (define_expand "mov<mode>_insv_1"
2543 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2544 (const_int 8)
2545 (const_int 8))
2546 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2547
2548 (define_insn "*mov<mode>_insv_1_rex64"
2549 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2550 (const_int 8)
2551 (const_int 8))
2552 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2553 "TARGET_64BIT"
2554 "mov{b}\t{%b1, %h0|%h0, %b1}"
2555 [(set_attr "type" "imov")
2556 (set_attr "mode" "QI")])
2557
2558 (define_insn "*movsi_insv_1"
2559 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2560 (const_int 8)
2561 (const_int 8))
2562 (match_operand:SI 1 "general_operand" "Qmn"))]
2563 "!TARGET_64BIT"
2564 "mov{b}\t{%b1, %h0|%h0, %b1}"
2565 [(set_attr "type" "imov")
2566 (set_attr "mode" "QI")])
2567
2568 (define_insn "*movqi_insv_2"
2569 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2570 (const_int 8)
2571 (const_int 8))
2572 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2573 (const_int 8)))]
2574 ""
2575 "mov{b}\t{%h1, %h0|%h0, %h1}"
2576 [(set_attr "type" "imov")
2577 (set_attr "mode" "QI")])
2578 \f
2579 ;; Floating point push instructions.
2580
2581 (define_insn "*pushtf"
2582 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2583 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2584 "TARGET_SSE2"
2585 {
2586 /* This insn should be already split before reg-stack. */
2587 gcc_unreachable ();
2588 }
2589 [(set_attr "type" "multi")
2590 (set_attr "unit" "sse,*,*")
2591 (set_attr "mode" "TF,SI,SI")])
2592
2593 (define_split
2594 [(set (match_operand:TF 0 "push_operand" "")
2595 (match_operand:TF 1 "sse_reg_operand" ""))]
2596 "TARGET_SSE2 && reload_completed"
2597 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2598 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2599
2600 (define_split
2601 [(set (match_operand:TF 0 "push_operand" "")
2602 (match_operand:TF 1 "general_operand" ""))]
2603 "TARGET_SSE2 && reload_completed
2604 && !SSE_REG_P (operands[1])"
2605 [(const_int 0)]
2606 "ix86_split_long_move (operands); DONE;")
2607
2608 (define_insn "*pushxf"
2609 [(set (match_operand:XF 0 "push_operand" "=<,<")
2610 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2611 "optimize_function_for_speed_p (cfun)"
2612 {
2613 /* This insn should be already split before reg-stack. */
2614 gcc_unreachable ();
2615 }
2616 [(set_attr "type" "multi")
2617 (set_attr "unit" "i387,*")
2618 (set_attr "mode" "XF,SI")])
2619
2620 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2621 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2622 ;; Pushing using integer instructions is longer except for constants
2623 ;; and direct memory references (assuming that any given constant is pushed
2624 ;; only once, but this ought to be handled elsewhere).
2625
2626 (define_insn "*pushxf_nointeger"
2627 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2628 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2629 "optimize_function_for_size_p (cfun)"
2630 {
2631 /* This insn should be already split before reg-stack. */
2632 gcc_unreachable ();
2633 }
2634 [(set_attr "type" "multi")
2635 (set_attr "unit" "i387,*,*")
2636 (set_attr "mode" "XF,SI,SI")])
2637
2638 (define_split
2639 [(set (match_operand:XF 0 "push_operand" "")
2640 (match_operand:XF 1 "fp_register_operand" ""))]
2641 "reload_completed"
2642 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2643 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2644 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2645
2646 (define_split
2647 [(set (match_operand:XF 0 "push_operand" "")
2648 (match_operand:XF 1 "general_operand" ""))]
2649 "reload_completed
2650 && !FP_REG_P (operands[1])"
2651 [(const_int 0)]
2652 "ix86_split_long_move (operands); DONE;")
2653
2654 (define_insn "*pushdf"
2655 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2656 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2657 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2658 {
2659 /* This insn should be already split before reg-stack. */
2660 gcc_unreachable ();
2661 }
2662 [(set_attr "type" "multi")
2663 (set_attr "unit" "i387,*,*")
2664 (set_attr "mode" "DF,SI,DF")])
2665
2666 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2667 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2668 ;; On the average, pushdf using integers can be still shorter. Allow this
2669 ;; pattern for optimize_size too.
2670
2671 (define_insn "*pushdf_nointeger"
2672 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2673 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2674 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2675 {
2676 /* This insn should be already split before reg-stack. */
2677 gcc_unreachable ();
2678 }
2679 [(set_attr "type" "multi")
2680 (set_attr "unit" "i387,*,*,*")
2681 (set_attr "mode" "DF,SI,SI,DF")])
2682
2683 ;; %%% Kill this when call knows how to work this out.
2684 (define_split
2685 [(set (match_operand:DF 0 "push_operand" "")
2686 (match_operand:DF 1 "any_fp_register_operand" ""))]
2687 "reload_completed"
2688 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2689 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2690
2691 (define_split
2692 [(set (match_operand:DF 0 "push_operand" "")
2693 (match_operand:DF 1 "general_operand" ""))]
2694 "reload_completed
2695 && !ANY_FP_REG_P (operands[1])"
2696 [(const_int 0)]
2697 "ix86_split_long_move (operands); DONE;")
2698
2699 (define_insn "*pushsf_rex64"
2700 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2701 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2702 "TARGET_64BIT"
2703 {
2704 /* Anything else should be already split before reg-stack. */
2705 gcc_assert (which_alternative == 1);
2706 return "push{q}\t%q1";
2707 }
2708 [(set_attr "type" "multi,push,multi")
2709 (set_attr "unit" "i387,*,*")
2710 (set_attr "mode" "SF,DI,SF")])
2711
2712 (define_insn "*pushsf"
2713 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2714 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2715 "!TARGET_64BIT"
2716 {
2717 /* Anything else should be already split before reg-stack. */
2718 gcc_assert (which_alternative == 1);
2719 return "push{l}\t%1";
2720 }
2721 [(set_attr "type" "multi,push,multi")
2722 (set_attr "unit" "i387,*,*")
2723 (set_attr "mode" "SF,SI,SF")])
2724
2725 (define_split
2726 [(set (match_operand:SF 0 "push_operand" "")
2727 (match_operand:SF 1 "memory_operand" ""))]
2728 "reload_completed
2729 && MEM_P (operands[1])
2730 && (operands[2] = find_constant_src (insn))"
2731 [(set (match_dup 0)
2732 (match_dup 2))])
2733
2734 ;; %%% Kill this when call knows how to work this out.
2735 (define_split
2736 [(set (match_operand:SF 0 "push_operand" "")
2737 (match_operand:SF 1 "any_fp_register_operand" ""))]
2738 "reload_completed"
2739 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2740 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2741 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2742 \f
2743 ;; Floating point move instructions.
2744
2745 (define_expand "movtf"
2746 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2747 (match_operand:TF 1 "nonimmediate_operand" ""))]
2748 "TARGET_SSE2"
2749 {
2750 ix86_expand_move (TFmode, operands);
2751 DONE;
2752 })
2753
2754 (define_expand "mov<mode>"
2755 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2756 (match_operand:X87MODEF 1 "general_operand" ""))]
2757 ""
2758 "ix86_expand_move (<MODE>mode, operands); DONE;")
2759
2760 (define_insn "*movtf_internal"
2761 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2762 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2763 "TARGET_SSE2
2764 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2765 {
2766 switch (which_alternative)
2767 {
2768 case 0:
2769 case 1:
2770 if (get_attr_mode (insn) == MODE_V4SF)
2771 return "%vmovaps\t{%1, %0|%0, %1}";
2772 else
2773 return "%vmovdqa\t{%1, %0|%0, %1}";
2774 case 2:
2775 if (get_attr_mode (insn) == MODE_V4SF)
2776 return "%vxorps\t%0, %d0";
2777 else
2778 return "%vpxor\t%0, %d0";
2779 case 3:
2780 case 4:
2781 return "#";
2782 default:
2783 gcc_unreachable ();
2784 }
2785 }
2786 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2787 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2788 (set (attr "mode")
2789 (cond [(eq_attr "alternative" "0,2")
2790 (if_then_else
2791 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2792 (const_int 0))
2793 (const_string "V4SF")
2794 (const_string "TI"))
2795 (eq_attr "alternative" "1")
2796 (if_then_else
2797 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2798 (const_int 0))
2799 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2800 (const_int 0)))
2801 (const_string "V4SF")
2802 (const_string "TI"))]
2803 (const_string "DI")))])
2804
2805 (define_split
2806 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2807 (match_operand:TF 1 "general_operand" ""))]
2808 "reload_completed
2809 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2810 [(const_int 0)]
2811 "ix86_split_long_move (operands); DONE;")
2812
2813 (define_insn "*movxf_internal"
2814 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2815 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2816 "optimize_function_for_speed_p (cfun)
2817 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2818 && (reload_in_progress || reload_completed
2819 || GET_CODE (operands[1]) != CONST_DOUBLE
2820 || memory_operand (operands[0], XFmode))"
2821 {
2822 switch (which_alternative)
2823 {
2824 case 0:
2825 case 1:
2826 return output_387_reg_move (insn, operands);
2827
2828 case 2:
2829 return standard_80387_constant_opcode (operands[1]);
2830
2831 case 3: case 4:
2832 return "#";
2833
2834 default:
2835 gcc_unreachable ();
2836 }
2837 }
2838 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839 (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 ;; Do not use integer registers when optimizing for size
2842 (define_insn "*movxf_internal_nointeger"
2843 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2844 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2845 "optimize_function_for_size_p (cfun)
2846 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2847 && (reload_in_progress || reload_completed
2848 || standard_80387_constant_p (operands[1])
2849 || GET_CODE (operands[1]) != CONST_DOUBLE
2850 || memory_operand (operands[0], XFmode))"
2851 {
2852 switch (which_alternative)
2853 {
2854 case 0:
2855 case 1:
2856 return output_387_reg_move (insn, operands);
2857
2858 case 2:
2859 return standard_80387_constant_opcode (operands[1]);
2860
2861 case 3: case 4:
2862 return "#";
2863 default:
2864 gcc_unreachable ();
2865 }
2866 }
2867 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2868 (set_attr "mode" "XF,XF,XF,SI,SI")])
2869
2870 (define_split
2871 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2872 (match_operand:XF 1 "general_operand" ""))]
2873 "reload_completed
2874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2875 && ! (FP_REG_P (operands[0]) ||
2876 (GET_CODE (operands[0]) == SUBREG
2877 && FP_REG_P (SUBREG_REG (operands[0]))))
2878 && ! (FP_REG_P (operands[1]) ||
2879 (GET_CODE (operands[1]) == SUBREG
2880 && FP_REG_P (SUBREG_REG (operands[1]))))"
2881 [(const_int 0)]
2882 "ix86_split_long_move (operands); DONE;")
2883
2884 (define_insn "*movdf_internal_rex64"
2885 [(set (match_operand:DF 0 "nonimmediate_operand"
2886 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2887 (match_operand:DF 1 "general_operand"
2888 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2889 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2890 && (reload_in_progress || reload_completed
2891 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2892 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2893 && optimize_function_for_size_p (cfun)
2894 && standard_80387_constant_p (operands[1]))
2895 || GET_CODE (operands[1]) != CONST_DOUBLE
2896 || memory_operand (operands[0], DFmode))"
2897 {
2898 switch (which_alternative)
2899 {
2900 case 0:
2901 case 1:
2902 return output_387_reg_move (insn, operands);
2903
2904 case 2:
2905 return standard_80387_constant_opcode (operands[1]);
2906
2907 case 3:
2908 case 4:
2909 return "#";
2910
2911 case 5:
2912 switch (get_attr_mode (insn))
2913 {
2914 case MODE_V4SF:
2915 return "%vxorps\t%0, %d0";
2916 case MODE_V2DF:
2917 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2918 return "%vxorps\t%0, %d0";
2919 else
2920 return "%vxorpd\t%0, %d0";
2921 case MODE_TI:
2922 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2923 return "%vxorps\t%0, %d0";
2924 else
2925 return "%vpxor\t%0, %d0";
2926 default:
2927 gcc_unreachable ();
2928 }
2929 case 6:
2930 case 7:
2931 case 8:
2932 switch (get_attr_mode (insn))
2933 {
2934 case MODE_V4SF:
2935 return "%vmovaps\t{%1, %0|%0, %1}";
2936 case MODE_V2DF:
2937 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938 return "%vmovaps\t{%1, %0|%0, %1}";
2939 else
2940 return "%vmovapd\t{%1, %0|%0, %1}";
2941 case MODE_TI:
2942 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2943 return "%vmovaps\t{%1, %0|%0, %1}";
2944 else
2945 return "%vmovdqa\t{%1, %0|%0, %1}";
2946 case MODE_DI:
2947 return "%vmovq\t{%1, %0|%0, %1}";
2948 case MODE_DF:
2949 if (TARGET_AVX)
2950 {
2951 if (REG_P (operands[0]) && REG_P (operands[1]))
2952 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2953 else
2954 return "vmovsd\t{%1, %0|%0, %1}";
2955 }
2956 else
2957 return "movsd\t{%1, %0|%0, %1}";
2958 case MODE_V1DF:
2959 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2960 case MODE_V2SF:
2961 return "%vmovlps\t{%1, %d0|%d0, %1}";
2962 default:
2963 gcc_unreachable ();
2964 }
2965
2966 case 9:
2967 case 10:
2968 return "%vmovd\t{%1, %0|%0, %1}";
2969
2970 default:
2971 gcc_unreachable();
2972 }
2973 }
2974 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2975 (set (attr "prefix")
2976 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2977 (const_string "orig")
2978 (const_string "maybe_vex")))
2979 (set (attr "prefix_data16")
2980 (if_then_else (eq_attr "mode" "V1DF")
2981 (const_string "1")
2982 (const_string "*")))
2983 (set (attr "mode")
2984 (cond [(eq_attr "alternative" "0,1,2")
2985 (const_string "DF")
2986 (eq_attr "alternative" "3,4,9,10")
2987 (const_string "DI")
2988
2989 /* For SSE1, we have many fewer alternatives. */
2990 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2991 (cond [(eq_attr "alternative" "5,6")
2992 (const_string "V4SF")
2993 ]
2994 (const_string "V2SF"))
2995
2996 /* xorps is one byte shorter. */
2997 (eq_attr "alternative" "5")
2998 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2999 (const_int 0))
3000 (const_string "V4SF")
3001 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3002 (const_int 0))
3003 (const_string "TI")
3004 ]
3005 (const_string "V2DF"))
3006
3007 /* For architectures resolving dependencies on
3008 whole SSE registers use APD move to break dependency
3009 chains, otherwise use short move to avoid extra work.
3010
3011 movaps encodes one byte shorter. */
3012 (eq_attr "alternative" "6")
3013 (cond
3014 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3015 (const_int 0))
3016 (const_string "V4SF")
3017 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3018 (const_int 0))
3019 (const_string "V2DF")
3020 ]
3021 (const_string "DF"))
3022 /* For architectures resolving dependencies on register
3023 parts we may avoid extra work to zero out upper part
3024 of register. */
3025 (eq_attr "alternative" "7")
3026 (if_then_else
3027 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3028 (const_int 0))
3029 (const_string "V1DF")
3030 (const_string "DF"))
3031 ]
3032 (const_string "DF")))])
3033
3034 (define_insn "*movdf_internal"
3035 [(set (match_operand:DF 0 "nonimmediate_operand"
3036 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3037 (match_operand:DF 1 "general_operand"
3038 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3039 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3040 && optimize_function_for_speed_p (cfun)
3041 && TARGET_INTEGER_DFMODE_MOVES
3042 && (reload_in_progress || reload_completed
3043 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3044 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3045 && optimize_function_for_size_p (cfun)
3046 && standard_80387_constant_p (operands[1]))
3047 || GET_CODE (operands[1]) != CONST_DOUBLE
3048 || memory_operand (operands[0], DFmode))"
3049 {
3050 switch (which_alternative)
3051 {
3052 case 0:
3053 case 1:
3054 return output_387_reg_move (insn, operands);
3055
3056 case 2:
3057 return standard_80387_constant_opcode (operands[1]);
3058
3059 case 3:
3060 case 4:
3061 return "#";
3062
3063 case 5:
3064 switch (get_attr_mode (insn))
3065 {
3066 case MODE_V4SF:
3067 return "xorps\t%0, %0";
3068 case MODE_V2DF:
3069 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3070 return "xorps\t%0, %0";
3071 else
3072 return "xorpd\t%0, %0";
3073 case MODE_TI:
3074 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3075 return "xorps\t%0, %0";
3076 else
3077 return "pxor\t%0, %0";
3078 default:
3079 gcc_unreachable ();
3080 }
3081 case 6:
3082 case 7:
3083 case 8:
3084 switch (get_attr_mode (insn))
3085 {
3086 case MODE_V4SF:
3087 return "movaps\t{%1, %0|%0, %1}";
3088 case MODE_V2DF:
3089 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3090 return "movaps\t{%1, %0|%0, %1}";
3091 else
3092 return "movapd\t{%1, %0|%0, %1}";
3093 case MODE_TI:
3094 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3095 return "movaps\t{%1, %0|%0, %1}";
3096 else
3097 return "movdqa\t{%1, %0|%0, %1}";
3098 case MODE_DI:
3099 return "movq\t{%1, %0|%0, %1}";
3100 case MODE_DF:
3101 return "movsd\t{%1, %0|%0, %1}";
3102 case MODE_V1DF:
3103 return "movlpd\t{%1, %0|%0, %1}";
3104 case MODE_V2SF:
3105 return "movlps\t{%1, %0|%0, %1}";
3106 default:
3107 gcc_unreachable ();
3108 }
3109
3110 default:
3111 gcc_unreachable();
3112 }
3113 }
3114 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3115 (set (attr "prefix_data16")
3116 (if_then_else (eq_attr "mode" "V1DF")
3117 (const_string "1")
3118 (const_string "*")))
3119 (set (attr "mode")
3120 (cond [(eq_attr "alternative" "0,1,2")
3121 (const_string "DF")
3122 (eq_attr "alternative" "3,4")
3123 (const_string "SI")
3124
3125 /* For SSE1, we have many fewer alternatives. */
3126 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3127 (cond [(eq_attr "alternative" "5,6")
3128 (const_string "V4SF")
3129 ]
3130 (const_string "V2SF"))
3131
3132 /* xorps is one byte shorter. */
3133 (eq_attr "alternative" "5")
3134 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3135 (const_int 0))
3136 (const_string "V4SF")
3137 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3138 (const_int 0))
3139 (const_string "TI")
3140 ]
3141 (const_string "V2DF"))
3142
3143 /* For architectures resolving dependencies on
3144 whole SSE registers use APD move to break dependency
3145 chains, otherwise use short move to avoid extra work.
3146
3147 movaps encodes one byte shorter. */
3148 (eq_attr "alternative" "6")
3149 (cond
3150 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3151 (const_int 0))
3152 (const_string "V4SF")
3153 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154 (const_int 0))
3155 (const_string "V2DF")
3156 ]
3157 (const_string "DF"))
3158 /* For architectures resolving dependencies on register
3159 parts we may avoid extra work to zero out upper part
3160 of register. */
3161 (eq_attr "alternative" "7")
3162 (if_then_else
3163 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3164 (const_int 0))
3165 (const_string "V1DF")
3166 (const_string "DF"))
3167 ]
3168 (const_string "DF")))])
3169
3170 ;; Moving is usually shorter when only FP registers are used. This separate
3171 ;; movdf pattern avoids the use of integer registers for FP operations
3172 ;; when optimizing for size.
3173
3174 (define_insn "*movdf_internal_nointeger"
3175 [(set (match_operand:DF 0 "nonimmediate_operand"
3176 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3177 (match_operand:DF 1 "general_operand"
3178 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3179 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3180 && ((optimize_function_for_size_p (cfun)
3181 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3182 && (reload_in_progress || reload_completed
3183 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3184 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3185 && optimize_function_for_size_p (cfun)
3186 && !memory_operand (operands[0], DFmode)
3187 && standard_80387_constant_p (operands[1]))
3188 || GET_CODE (operands[1]) != CONST_DOUBLE
3189 || ((optimize_function_for_size_p (cfun)
3190 || !TARGET_MEMORY_MISMATCH_STALL
3191 || reload_in_progress || reload_completed)
3192 && memory_operand (operands[0], DFmode)))"
3193 {
3194 switch (which_alternative)
3195 {
3196 case 0:
3197 case 1:
3198 return output_387_reg_move (insn, operands);
3199
3200 case 2:
3201 return standard_80387_constant_opcode (operands[1]);
3202
3203 case 3:
3204 case 4:
3205 return "#";
3206
3207 case 5:
3208 switch (get_attr_mode (insn))
3209 {
3210 case MODE_V4SF:
3211 return "%vxorps\t%0, %d0";
3212 case MODE_V2DF:
3213 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3214 return "%vxorps\t%0, %d0";
3215 else
3216 return "%vxorpd\t%0, %d0";
3217 case MODE_TI:
3218 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3219 return "%vxorps\t%0, %d0";
3220 else
3221 return "%vpxor\t%0, %d0";
3222 default:
3223 gcc_unreachable ();
3224 }
3225 case 6:
3226 case 7:
3227 case 8:
3228 switch (get_attr_mode (insn))
3229 {
3230 case MODE_V4SF:
3231 return "%vmovaps\t{%1, %0|%0, %1}";
3232 case MODE_V2DF:
3233 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3234 return "%vmovaps\t{%1, %0|%0, %1}";
3235 else
3236 return "%vmovapd\t{%1, %0|%0, %1}";
3237 case MODE_TI:
3238 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3239 return "%vmovaps\t{%1, %0|%0, %1}";
3240 else
3241 return "%vmovdqa\t{%1, %0|%0, %1}";
3242 case MODE_DI:
3243 return "%vmovq\t{%1, %0|%0, %1}";
3244 case MODE_DF:
3245 if (TARGET_AVX)
3246 {
3247 if (REG_P (operands[0]) && REG_P (operands[1]))
3248 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3249 else
3250 return "vmovsd\t{%1, %0|%0, %1}";
3251 }
3252 else
3253 return "movsd\t{%1, %0|%0, %1}";
3254 case MODE_V1DF:
3255 if (TARGET_AVX)
3256 {
3257 if (REG_P (operands[0]))
3258 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3259 else
3260 return "vmovlpd\t{%1, %0|%0, %1}";
3261 }
3262 else
3263 return "movlpd\t{%1, %0|%0, %1}";
3264 case MODE_V2SF:
3265 if (TARGET_AVX)
3266 {
3267 if (REG_P (operands[0]))
3268 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3269 else
3270 return "vmovlps\t{%1, %0|%0, %1}";
3271 }
3272 else
3273 return "movlps\t{%1, %0|%0, %1}";
3274 default:
3275 gcc_unreachable ();
3276 }
3277
3278 default:
3279 gcc_unreachable ();
3280 }
3281 }
3282 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3283 (set (attr "prefix")
3284 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3285 (const_string "orig")
3286 (const_string "maybe_vex")))
3287 (set (attr "prefix_data16")
3288 (if_then_else (eq_attr "mode" "V1DF")
3289 (const_string "1")
3290 (const_string "*")))
3291 (set (attr "mode")
3292 (cond [(eq_attr "alternative" "0,1,2")
3293 (const_string "DF")
3294 (eq_attr "alternative" "3,4")
3295 (const_string "SI")
3296
3297 /* For SSE1, we have many fewer alternatives. */
3298 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3299 (cond [(eq_attr "alternative" "5,6")
3300 (const_string "V4SF")
3301 ]
3302 (const_string "V2SF"))
3303
3304 /* xorps is one byte shorter. */
3305 (eq_attr "alternative" "5")
3306 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3307 (const_int 0))
3308 (const_string "V4SF")
3309 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3310 (const_int 0))
3311 (const_string "TI")
3312 ]
3313 (const_string "V2DF"))
3314
3315 /* For architectures resolving dependencies on
3316 whole SSE registers use APD move to break dependency
3317 chains, otherwise use short move to avoid extra work.
3318
3319 movaps encodes one byte shorter. */
3320 (eq_attr "alternative" "6")
3321 (cond
3322 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3323 (const_int 0))
3324 (const_string "V4SF")
3325 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3326 (const_int 0))
3327 (const_string "V2DF")
3328 ]
3329 (const_string "DF"))
3330 /* For architectures resolving dependencies on register
3331 parts we may avoid extra work to zero out upper part
3332 of register. */
3333 (eq_attr "alternative" "7")
3334 (if_then_else
3335 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3336 (const_int 0))
3337 (const_string "V1DF")
3338 (const_string "DF"))
3339 ]
3340 (const_string "DF")))])
3341
3342 (define_split
3343 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3344 (match_operand:DF 1 "general_operand" ""))]
3345 "reload_completed
3346 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3347 && ! (ANY_FP_REG_P (operands[0]) ||
3348 (GET_CODE (operands[0]) == SUBREG
3349 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3350 && ! (ANY_FP_REG_P (operands[1]) ||
3351 (GET_CODE (operands[1]) == SUBREG
3352 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3353 [(const_int 0)]
3354 "ix86_split_long_move (operands); DONE;")
3355
3356 (define_insn "*movsf_internal"
3357 [(set (match_operand:SF 0 "nonimmediate_operand"
3358 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3359 (match_operand:SF 1 "general_operand"
3360 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3361 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3362 && (reload_in_progress || reload_completed
3363 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3364 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3365 && standard_80387_constant_p (operands[1]))
3366 || GET_CODE (operands[1]) != CONST_DOUBLE
3367 || memory_operand (operands[0], SFmode))"
3368 {
3369 switch (which_alternative)
3370 {
3371 case 0:
3372 case 1:
3373 return output_387_reg_move (insn, operands);
3374
3375 case 2:
3376 return standard_80387_constant_opcode (operands[1]);
3377
3378 case 3:
3379 case 4:
3380 return "mov{l}\t{%1, %0|%0, %1}";
3381 case 5:
3382 if (get_attr_mode (insn) == MODE_TI)
3383 return "%vpxor\t%0, %d0";
3384 else
3385 return "%vxorps\t%0, %d0";
3386 case 6:
3387 if (get_attr_mode (insn) == MODE_V4SF)
3388 return "%vmovaps\t{%1, %0|%0, %1}";
3389 else
3390 return "%vmovss\t{%1, %d0|%d0, %1}";
3391 case 7:
3392 if (TARGET_AVX)
3393 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3394 : "vmovss\t{%1, %0|%0, %1}";
3395 else
3396 return "movss\t{%1, %0|%0, %1}";
3397 case 8:
3398 return "%vmovss\t{%1, %0|%0, %1}";
3399
3400 case 9: case 10: case 14: case 15:
3401 return "movd\t{%1, %0|%0, %1}";
3402 case 12: case 13:
3403 return "%vmovd\t{%1, %0|%0, %1}";
3404
3405 case 11:
3406 return "movq\t{%1, %0|%0, %1}";
3407
3408 default:
3409 gcc_unreachable ();
3410 }
3411 }
3412 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3413 (set (attr "prefix")
3414 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3415 (const_string "maybe_vex")
3416 (const_string "orig")))
3417 (set (attr "mode")
3418 (cond [(eq_attr "alternative" "3,4,9,10")
3419 (const_string "SI")
3420 (eq_attr "alternative" "5")
3421 (if_then_else
3422 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3423 (const_int 0))
3424 (ne (symbol_ref "TARGET_SSE2")
3425 (const_int 0)))
3426 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3427 (const_int 0)))
3428 (const_string "TI")
3429 (const_string "V4SF"))
3430 /* For architectures resolving dependencies on
3431 whole SSE registers use APS move to break dependency
3432 chains, otherwise use short move to avoid extra work.
3433
3434 Do the same for architectures resolving dependencies on
3435 the parts. While in DF mode it is better to always handle
3436 just register parts, the SF mode is different due to lack
3437 of instructions to load just part of the register. It is
3438 better to maintain the whole registers in single format
3439 to avoid problems on using packed logical operations. */
3440 (eq_attr "alternative" "6")
3441 (if_then_else
3442 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3443 (const_int 0))
3444 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3445 (const_int 0)))
3446 (const_string "V4SF")
3447 (const_string "SF"))
3448 (eq_attr "alternative" "11")
3449 (const_string "DI")]
3450 (const_string "SF")))])
3451
3452 (define_split
3453 [(set (match_operand 0 "register_operand" "")
3454 (match_operand 1 "memory_operand" ""))]
3455 "reload_completed
3456 && MEM_P (operands[1])
3457 && (GET_MODE (operands[0]) == TFmode
3458 || GET_MODE (operands[0]) == XFmode
3459 || GET_MODE (operands[0]) == DFmode
3460 || GET_MODE (operands[0]) == SFmode)
3461 && (operands[2] = find_constant_src (insn))"
3462 [(set (match_dup 0) (match_dup 2))]
3463 {
3464 rtx c = operands[2];
3465 rtx r = operands[0];
3466
3467 if (GET_CODE (r) == SUBREG)
3468 r = SUBREG_REG (r);
3469
3470 if (SSE_REG_P (r))
3471 {
3472 if (!standard_sse_constant_p (c))
3473 FAIL;
3474 }
3475 else if (FP_REG_P (r))
3476 {
3477 if (!standard_80387_constant_p (c))
3478 FAIL;
3479 }
3480 else if (MMX_REG_P (r))
3481 FAIL;
3482 })
3483
3484 (define_split
3485 [(set (match_operand 0 "register_operand" "")
3486 (float_extend (match_operand 1 "memory_operand" "")))]
3487 "reload_completed
3488 && MEM_P (operands[1])
3489 && (GET_MODE (operands[0]) == TFmode
3490 || GET_MODE (operands[0]) == XFmode
3491 || GET_MODE (operands[0]) == DFmode
3492 || GET_MODE (operands[0]) == SFmode)
3493 && (operands[2] = find_constant_src (insn))"
3494 [(set (match_dup 0) (match_dup 2))]
3495 {
3496 rtx c = operands[2];
3497 rtx r = operands[0];
3498
3499 if (GET_CODE (r) == SUBREG)
3500 r = SUBREG_REG (r);
3501
3502 if (SSE_REG_P (r))
3503 {
3504 if (!standard_sse_constant_p (c))
3505 FAIL;
3506 }
3507 else if (FP_REG_P (r))
3508 {
3509 if (!standard_80387_constant_p (c))
3510 FAIL;
3511 }
3512 else if (MMX_REG_P (r))
3513 FAIL;
3514 })
3515
3516 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3517 (define_split
3518 [(set (match_operand:X87MODEF 0 "register_operand" "")
3519 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3520 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3521 && (standard_80387_constant_p (operands[1]) == 8
3522 || standard_80387_constant_p (operands[1]) == 9)"
3523 [(set (match_dup 0)(match_dup 1))
3524 (set (match_dup 0)
3525 (neg:X87MODEF (match_dup 0)))]
3526 {
3527 REAL_VALUE_TYPE r;
3528
3529 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3530 if (real_isnegzero (&r))
3531 operands[1] = CONST0_RTX (<MODE>mode);
3532 else
3533 operands[1] = CONST1_RTX (<MODE>mode);
3534 })
3535
3536 (define_insn "swapxf"
3537 [(set (match_operand:XF 0 "register_operand" "+f")
3538 (match_operand:XF 1 "register_operand" "+f"))
3539 (set (match_dup 1)
3540 (match_dup 0))]
3541 "TARGET_80387"
3542 {
3543 if (STACK_TOP_P (operands[0]))
3544 return "fxch\t%1";
3545 else
3546 return "fxch\t%0";
3547 }
3548 [(set_attr "type" "fxch")
3549 (set_attr "mode" "XF")])
3550
3551 (define_insn "*swap<mode>"
3552 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3553 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3554 (set (match_dup 1)
3555 (match_dup 0))]
3556 "TARGET_80387 || reload_completed"
3557 {
3558 if (STACK_TOP_P (operands[0]))
3559 return "fxch\t%1";
3560 else
3561 return "fxch\t%0";
3562 }
3563 [(set_attr "type" "fxch")
3564 (set_attr "mode" "<MODE>")])
3565 \f
3566 ;; Zero extension instructions
3567
3568 (define_expand "zero_extendsidi2"
3569 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3570 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3571 ""
3572 {
3573 if (!TARGET_64BIT)
3574 {
3575 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3576 DONE;
3577 }
3578 })
3579
3580 (define_insn "*zero_extendsidi2_rex64"
3581 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3582 (zero_extend:DI
3583 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3584 "TARGET_64BIT"
3585 "@
3586 mov\t{%k1, %k0|%k0, %k1}
3587 #
3588 movd\t{%1, %0|%0, %1}
3589 movd\t{%1, %0|%0, %1}
3590 %vmovd\t{%1, %0|%0, %1}
3591 %vmovd\t{%1, %0|%0, %1}"
3592 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3593 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3594 (set_attr "prefix_0f" "0,*,*,*,*,*")
3595 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3596
3597 (define_split
3598 [(set (match_operand:DI 0 "memory_operand" "")
3599 (zero_extend:DI (match_dup 0)))]
3600 "TARGET_64BIT"
3601 [(set (match_dup 4) (const_int 0))]
3602 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3603
3604 ;; %%% Kill me once multi-word ops are sane.
3605 (define_insn "zero_extendsidi2_1"
3606 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3607 (zero_extend:DI
3608 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3609 (clobber (reg:CC FLAGS_REG))]
3610 "!TARGET_64BIT"
3611 "@
3612 #
3613 #
3614 #
3615 movd\t{%1, %0|%0, %1}
3616 movd\t{%1, %0|%0, %1}
3617 %vmovd\t{%1, %0|%0, %1}
3618 %vmovd\t{%1, %0|%0, %1}"
3619 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3620 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3621 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3622
3623 (define_split
3624 [(set (match_operand:DI 0 "register_operand" "")
3625 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3626 (clobber (reg:CC FLAGS_REG))]
3627 "!TARGET_64BIT && reload_completed
3628 && true_regnum (operands[0]) == true_regnum (operands[1])"
3629 [(set (match_dup 4) (const_int 0))]
3630 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3631
3632 (define_split
3633 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3634 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3635 (clobber (reg:CC FLAGS_REG))]
3636 "!TARGET_64BIT && reload_completed
3637 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3638 [(set (match_dup 3) (match_dup 1))
3639 (set (match_dup 4) (const_int 0))]
3640 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3641
3642 (define_insn "zero_extend<mode>di2"
3643 [(set (match_operand:DI 0 "register_operand" "=r")
3644 (zero_extend:DI
3645 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3646 "TARGET_64BIT"
3647 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3648 [(set_attr "type" "imovx")
3649 (set_attr "mode" "SI")])
3650
3651 (define_expand "zero_extendhisi2"
3652 [(set (match_operand:SI 0 "register_operand" "")
3653 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3654 ""
3655 {
3656 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3657 {
3658 operands[1] = force_reg (HImode, operands[1]);
3659 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3660 DONE;
3661 }
3662 })
3663
3664 (define_insn_and_split "zero_extendhisi2_and"
3665 [(set (match_operand:SI 0 "register_operand" "=r")
3666 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3667 (clobber (reg:CC FLAGS_REG))]
3668 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3669 "#"
3670 "&& reload_completed"
3671 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3672 (clobber (reg:CC FLAGS_REG))])]
3673 ""
3674 [(set_attr "type" "alu1")
3675 (set_attr "mode" "SI")])
3676
3677 (define_insn "*zero_extendhisi2_movzwl"
3678 [(set (match_operand:SI 0 "register_operand" "=r")
3679 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3680 "!TARGET_ZERO_EXTEND_WITH_AND
3681 || optimize_function_for_size_p (cfun)"
3682 "movz{wl|x}\t{%1, %0|%0, %1}"
3683 [(set_attr "type" "imovx")
3684 (set_attr "mode" "SI")])
3685
3686 (define_expand "zero_extendqi<mode>2"
3687 [(parallel
3688 [(set (match_operand:SWI24 0 "register_operand" "")
3689 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3690 (clobber (reg:CC FLAGS_REG))])])
3691
3692 (define_insn "*zero_extendqi<mode>2_and"
3693 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3694 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3695 (clobber (reg:CC FLAGS_REG))]
3696 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3697 "#"
3698 [(set_attr "type" "alu1")
3699 (set_attr "mode" "<MODE>")])
3700
3701 ;; When source and destination does not overlap, clear destination
3702 ;; first and then do the movb
3703 (define_split
3704 [(set (match_operand:SWI24 0 "register_operand" "")
3705 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3706 (clobber (reg:CC FLAGS_REG))]
3707 "reload_completed
3708 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3709 && ANY_QI_REG_P (operands[0])
3710 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3711 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3712 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3713 {
3714 operands[2] = gen_lowpart (QImode, operands[0]);
3715 ix86_expand_clear (operands[0]);
3716 })
3717
3718 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3719 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3720 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3721 (clobber (reg:CC FLAGS_REG))]
3722 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3723 "#"
3724 [(set_attr "type" "imovx,alu1")
3725 (set_attr "mode" "<MODE>")])
3726
3727 ;; For the movzbl case strip only the clobber
3728 (define_split
3729 [(set (match_operand:SWI24 0 "register_operand" "")
3730 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3731 (clobber (reg:CC FLAGS_REG))]
3732 "reload_completed
3733 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3734 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3735 [(set (match_dup 0)
3736 (zero_extend:SWI24 (match_dup 1)))])
3737
3738 ; zero extend to SImode to avoid partial register stalls
3739 (define_insn "*zero_extendqi<mode>2_movzbl"
3740 [(set (match_operand:SWI24 0 "register_operand" "=r")
3741 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3742 "reload_completed
3743 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3744 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3745 [(set_attr "type" "imovx")
3746 (set_attr "mode" "SI")])
3747
3748 ;; Rest is handled by single and.
3749 (define_split
3750 [(set (match_operand:SWI24 0 "register_operand" "")
3751 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3752 (clobber (reg:CC FLAGS_REG))]
3753 "reload_completed
3754 && true_regnum (operands[0]) == true_regnum (operands[1])"
3755 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3756 (clobber (reg:CC FLAGS_REG))])])
3757 \f
3758 ;; Sign extension instructions
3759
3760 (define_expand "extendsidi2"
3761 [(set (match_operand:DI 0 "register_operand" "")
3762 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3763 ""
3764 {
3765 if (!TARGET_64BIT)
3766 {
3767 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3768 DONE;
3769 }
3770 })
3771
3772 (define_insn "*extendsidi2_rex64"
3773 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3774 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3775 "TARGET_64BIT"
3776 "@
3777 {cltq|cdqe}
3778 movs{lq|x}\t{%1, %0|%0, %1}"
3779 [(set_attr "type" "imovx")
3780 (set_attr "mode" "DI")
3781 (set_attr "prefix_0f" "0")
3782 (set_attr "modrm" "0,1")])
3783
3784 (define_insn "extendsidi2_1"
3785 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3786 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3787 (clobber (reg:CC FLAGS_REG))
3788 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3789 "!TARGET_64BIT"
3790 "#")
3791
3792 ;; Extend to memory case when source register does die.
3793 (define_split
3794 [(set (match_operand:DI 0 "memory_operand" "")
3795 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3796 (clobber (reg:CC FLAGS_REG))
3797 (clobber (match_operand:SI 2 "register_operand" ""))]
3798 "(reload_completed
3799 && dead_or_set_p (insn, operands[1])
3800 && !reg_mentioned_p (operands[1], operands[0]))"
3801 [(set (match_dup 3) (match_dup 1))
3802 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3803 (clobber (reg:CC FLAGS_REG))])
3804 (set (match_dup 4) (match_dup 1))]
3805 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3806
3807 ;; Extend to memory case when source register does not die.
3808 (define_split
3809 [(set (match_operand:DI 0 "memory_operand" "")
3810 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3811 (clobber (reg:CC FLAGS_REG))
3812 (clobber (match_operand:SI 2 "register_operand" ""))]
3813 "reload_completed"
3814 [(const_int 0)]
3815 {
3816 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3817
3818 emit_move_insn (operands[3], operands[1]);
3819
3820 /* Generate a cltd if possible and doing so it profitable. */
3821 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3822 && true_regnum (operands[1]) == AX_REG
3823 && true_regnum (operands[2]) == DX_REG)
3824 {
3825 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3826 }
3827 else
3828 {
3829 emit_move_insn (operands[2], operands[1]);
3830 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3831 }
3832 emit_move_insn (operands[4], operands[2]);
3833 DONE;
3834 })
3835
3836 ;; Extend to register case. Optimize case where source and destination
3837 ;; registers match and cases where we can use cltd.
3838 (define_split
3839 [(set (match_operand:DI 0 "register_operand" "")
3840 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3841 (clobber (reg:CC FLAGS_REG))
3842 (clobber (match_scratch:SI 2 ""))]
3843 "reload_completed"
3844 [(const_int 0)]
3845 {
3846 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3847
3848 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3849 emit_move_insn (operands[3], operands[1]);
3850
3851 /* Generate a cltd if possible and doing so it profitable. */
3852 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3853 && true_regnum (operands[3]) == AX_REG
3854 && true_regnum (operands[4]) == DX_REG)
3855 {
3856 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3857 DONE;
3858 }
3859
3860 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3861 emit_move_insn (operands[4], operands[1]);
3862
3863 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3864 DONE;
3865 })
3866
3867 (define_insn "extend<mode>di2"
3868 [(set (match_operand:DI 0 "register_operand" "=r")
3869 (sign_extend:DI
3870 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3871 "TARGET_64BIT"
3872 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3873 [(set_attr "type" "imovx")
3874 (set_attr "mode" "DI")])
3875
3876 (define_insn "extendhisi2"
3877 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3878 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3879 ""
3880 {
3881 switch (get_attr_prefix_0f (insn))
3882 {
3883 case 0:
3884 return "{cwtl|cwde}";
3885 default:
3886 return "movs{wl|x}\t{%1, %0|%0, %1}";
3887 }
3888 }
3889 [(set_attr "type" "imovx")
3890 (set_attr "mode" "SI")
3891 (set (attr "prefix_0f")
3892 ;; movsx is short decodable while cwtl is vector decoded.
3893 (if_then_else (and (eq_attr "cpu" "!k6")
3894 (eq_attr "alternative" "0"))
3895 (const_string "0")
3896 (const_string "1")))
3897 (set (attr "modrm")
3898 (if_then_else (eq_attr "prefix_0f" "0")
3899 (const_string "0")
3900 (const_string "1")))])
3901
3902 (define_insn "*extendhisi2_zext"
3903 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3904 (zero_extend:DI
3905 (sign_extend:SI
3906 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3907 "TARGET_64BIT"
3908 {
3909 switch (get_attr_prefix_0f (insn))
3910 {
3911 case 0:
3912 return "{cwtl|cwde}";
3913 default:
3914 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3915 }
3916 }
3917 [(set_attr "type" "imovx")
3918 (set_attr "mode" "SI")
3919 (set (attr "prefix_0f")
3920 ;; movsx is short decodable while cwtl is vector decoded.
3921 (if_then_else (and (eq_attr "cpu" "!k6")
3922 (eq_attr "alternative" "0"))
3923 (const_string "0")
3924 (const_string "1")))
3925 (set (attr "modrm")
3926 (if_then_else (eq_attr "prefix_0f" "0")
3927 (const_string "0")
3928 (const_string "1")))])
3929
3930 (define_insn "extendqisi2"
3931 [(set (match_operand:SI 0 "register_operand" "=r")
3932 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3933 ""
3934 "movs{bl|x}\t{%1, %0|%0, %1}"
3935 [(set_attr "type" "imovx")
3936 (set_attr "mode" "SI")])
3937
3938 (define_insn "*extendqisi2_zext"
3939 [(set (match_operand:DI 0 "register_operand" "=r")
3940 (zero_extend:DI
3941 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3942 "TARGET_64BIT"
3943 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3944 [(set_attr "type" "imovx")
3945 (set_attr "mode" "SI")])
3946
3947 (define_insn "extendqihi2"
3948 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3949 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3950 ""
3951 {
3952 switch (get_attr_prefix_0f (insn))
3953 {
3954 case 0:
3955 return "{cbtw|cbw}";
3956 default:
3957 return "movs{bw|x}\t{%1, %0|%0, %1}";
3958 }
3959 }
3960 [(set_attr "type" "imovx")
3961 (set_attr "mode" "HI")
3962 (set (attr "prefix_0f")
3963 ;; movsx is short decodable while cwtl is vector decoded.
3964 (if_then_else (and (eq_attr "cpu" "!k6")
3965 (eq_attr "alternative" "0"))
3966 (const_string "0")
3967 (const_string "1")))
3968 (set (attr "modrm")
3969 (if_then_else (eq_attr "prefix_0f" "0")
3970 (const_string "0")
3971 (const_string "1")))])
3972 \f
3973 ;; Conversions between float and double.
3974
3975 ;; These are all no-ops in the model used for the 80387.
3976 ;; So just emit moves.
3977
3978 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3979 (define_split
3980 [(set (match_operand:DF 0 "push_operand" "")
3981 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3982 "reload_completed"
3983 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3984 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3985
3986 (define_split
3987 [(set (match_operand:XF 0 "push_operand" "")
3988 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3989 "reload_completed"
3990 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3991 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3992 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3993
3994 (define_expand "extendsfdf2"
3995 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3996 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3997 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3998 {
3999 /* ??? Needed for compress_float_constant since all fp constants
4000 are LEGITIMATE_CONSTANT_P. */
4001 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4002 {
4003 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4004 && standard_80387_constant_p (operands[1]) > 0)
4005 {
4006 operands[1] = simplify_const_unary_operation
4007 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4008 emit_move_insn_1 (operands[0], operands[1]);
4009 DONE;
4010 }
4011 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4012 }
4013 })
4014
4015 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4016 cvtss2sd:
4017 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4018 cvtps2pd xmm2,xmm1
4019 We do the conversion post reload to avoid producing of 128bit spills
4020 that might lead to ICE on 32bit target. The sequence unlikely combine
4021 anyway. */
4022 (define_split
4023 [(set (match_operand:DF 0 "register_operand" "")
4024 (float_extend:DF
4025 (match_operand:SF 1 "nonimmediate_operand" "")))]
4026 "TARGET_USE_VECTOR_FP_CONVERTS
4027 && optimize_insn_for_speed_p ()
4028 && reload_completed && SSE_REG_P (operands[0])"
4029 [(set (match_dup 2)
4030 (float_extend:V2DF
4031 (vec_select:V2SF
4032 (match_dup 3)
4033 (parallel [(const_int 0) (const_int 1)]))))]
4034 {
4035 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4036 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4037 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4038 Try to avoid move when unpacking can be done in source. */
4039 if (REG_P (operands[1]))
4040 {
4041 /* If it is unsafe to overwrite upper half of source, we need
4042 to move to destination and unpack there. */
4043 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4044 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4045 && true_regnum (operands[0]) != true_regnum (operands[1]))
4046 {
4047 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4048 emit_move_insn (tmp, operands[1]);
4049 }
4050 else
4051 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4052 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4053 operands[3]));
4054 }
4055 else
4056 emit_insn (gen_vec_setv4sf_0 (operands[3],
4057 CONST0_RTX (V4SFmode), operands[1]));
4058 })
4059
4060 (define_insn "*extendsfdf2_mixed"
4061 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4062 (float_extend:DF
4063 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4064 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4065 {
4066 switch (which_alternative)
4067 {
4068 case 0:
4069 case 1:
4070 return output_387_reg_move (insn, operands);
4071
4072 case 2:
4073 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4074
4075 default:
4076 gcc_unreachable ();
4077 }
4078 }
4079 [(set_attr "type" "fmov,fmov,ssecvt")
4080 (set_attr "prefix" "orig,orig,maybe_vex")
4081 (set_attr "mode" "SF,XF,DF")])
4082
4083 (define_insn "*extendsfdf2_sse"
4084 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4085 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4086 "TARGET_SSE2 && TARGET_SSE_MATH"
4087 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4088 [(set_attr "type" "ssecvt")
4089 (set_attr "prefix" "maybe_vex")
4090 (set_attr "mode" "DF")])
4091
4092 (define_insn "*extendsfdf2_i387"
4093 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4094 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4095 "TARGET_80387"
4096 "* return output_387_reg_move (insn, operands);"
4097 [(set_attr "type" "fmov")
4098 (set_attr "mode" "SF,XF")])
4099
4100 (define_expand "extend<mode>xf2"
4101 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4102 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4103 "TARGET_80387"
4104 {
4105 /* ??? Needed for compress_float_constant since all fp constants
4106 are LEGITIMATE_CONSTANT_P. */
4107 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4108 {
4109 if (standard_80387_constant_p (operands[1]) > 0)
4110 {
4111 operands[1] = simplify_const_unary_operation
4112 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4113 emit_move_insn_1 (operands[0], operands[1]);
4114 DONE;
4115 }
4116 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4117 }
4118 })
4119
4120 (define_insn "*extend<mode>xf2_i387"
4121 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4122 (float_extend:XF
4123 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4124 "TARGET_80387"
4125 "* return output_387_reg_move (insn, operands);"
4126 [(set_attr "type" "fmov")
4127 (set_attr "mode" "<MODE>,XF")])
4128
4129 ;; %%% This seems bad bad news.
4130 ;; This cannot output into an f-reg because there is no way to be sure
4131 ;; of truncating in that case. Otherwise this is just like a simple move
4132 ;; insn. So we pretend we can output to a reg in order to get better
4133 ;; register preferencing, but we really use a stack slot.
4134
4135 ;; Conversion from DFmode to SFmode.
4136
4137 (define_expand "truncdfsf2"
4138 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4139 (float_truncate:SF
4140 (match_operand:DF 1 "nonimmediate_operand" "")))]
4141 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4142 {
4143 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4144 ;
4145 else if (flag_unsafe_math_optimizations)
4146 ;
4147 else
4148 {
4149 enum ix86_stack_slot slot = (virtuals_instantiated
4150 ? SLOT_TEMP
4151 : SLOT_VIRTUAL);
4152 rtx temp = assign_386_stack_local (SFmode, slot);
4153 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4154 DONE;
4155 }
4156 })
4157
4158 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4159 cvtsd2ss:
4160 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4161 cvtpd2ps xmm2,xmm1
4162 We do the conversion post reload to avoid producing of 128bit spills
4163 that might lead to ICE on 32bit target. The sequence unlikely combine
4164 anyway. */
4165 (define_split
4166 [(set (match_operand:SF 0 "register_operand" "")
4167 (float_truncate:SF
4168 (match_operand:DF 1 "nonimmediate_operand" "")))]
4169 "TARGET_USE_VECTOR_FP_CONVERTS
4170 && optimize_insn_for_speed_p ()
4171 && reload_completed && SSE_REG_P (operands[0])"
4172 [(set (match_dup 2)
4173 (vec_concat:V4SF
4174 (float_truncate:V2SF
4175 (match_dup 4))
4176 (match_dup 3)))]
4177 {
4178 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4179 operands[3] = CONST0_RTX (V2SFmode);
4180 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4181 /* Use movsd for loading from memory, unpcklpd for registers.
4182 Try to avoid move when unpacking can be done in source, or SSE3
4183 movddup is available. */
4184 if (REG_P (operands[1]))
4185 {
4186 if (!TARGET_SSE3
4187 && true_regnum (operands[0]) != true_regnum (operands[1])
4188 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4189 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4190 {
4191 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4192 emit_move_insn (tmp, operands[1]);
4193 operands[1] = tmp;
4194 }
4195 else if (!TARGET_SSE3)
4196 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4197 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4198 }
4199 else
4200 emit_insn (gen_sse2_loadlpd (operands[4],
4201 CONST0_RTX (V2DFmode), operands[1]));
4202 })
4203
4204 (define_expand "truncdfsf2_with_temp"
4205 [(parallel [(set (match_operand:SF 0 "" "")
4206 (float_truncate:SF (match_operand:DF 1 "" "")))
4207 (clobber (match_operand:SF 2 "" ""))])])
4208
4209 (define_insn "*truncdfsf_fast_mixed"
4210 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4211 (float_truncate:SF
4212 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4213 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4214 {
4215 switch (which_alternative)
4216 {
4217 case 0:
4218 return output_387_reg_move (insn, operands);
4219 case 1:
4220 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4221 default:
4222 gcc_unreachable ();
4223 }
4224 }
4225 [(set_attr "type" "fmov,ssecvt")
4226 (set_attr "prefix" "orig,maybe_vex")
4227 (set_attr "mode" "SF")])
4228
4229 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4230 ;; because nothing we do here is unsafe.
4231 (define_insn "*truncdfsf_fast_sse"
4232 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4233 (float_truncate:SF
4234 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4235 "TARGET_SSE2 && TARGET_SSE_MATH"
4236 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4237 [(set_attr "type" "ssecvt")
4238 (set_attr "prefix" "maybe_vex")
4239 (set_attr "mode" "SF")])
4240
4241 (define_insn "*truncdfsf_fast_i387"
4242 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4243 (float_truncate:SF
4244 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4245 "TARGET_80387 && flag_unsafe_math_optimizations"
4246 "* return output_387_reg_move (insn, operands);"
4247 [(set_attr "type" "fmov")
4248 (set_attr "mode" "SF")])
4249
4250 (define_insn "*truncdfsf_mixed"
4251 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4252 (float_truncate:SF
4253 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4254 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4255 "TARGET_MIX_SSE_I387"
4256 {
4257 switch (which_alternative)
4258 {
4259 case 0:
4260 return output_387_reg_move (insn, operands);
4261 case 1:
4262 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4263
4264 default:
4265 return "#";
4266 }
4267 }
4268 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4269 (set_attr "unit" "*,*,i387,i387,i387")
4270 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4271 (set_attr "mode" "SF")])
4272
4273 (define_insn "*truncdfsf_i387"
4274 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4275 (float_truncate:SF
4276 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4277 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4278 "TARGET_80387"
4279 {
4280 switch (which_alternative)
4281 {
4282 case 0:
4283 return output_387_reg_move (insn, operands);
4284
4285 default:
4286 return "#";
4287 }
4288 }
4289 [(set_attr "type" "fmov,multi,multi,multi")
4290 (set_attr "unit" "*,i387,i387,i387")
4291 (set_attr "mode" "SF")])
4292
4293 (define_insn "*truncdfsf2_i387_1"
4294 [(set (match_operand:SF 0 "memory_operand" "=m")
4295 (float_truncate:SF
4296 (match_operand:DF 1 "register_operand" "f")))]
4297 "TARGET_80387
4298 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299 && !TARGET_MIX_SSE_I387"
4300 "* return output_387_reg_move (insn, operands);"
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "SF")])
4303
4304 (define_split
4305 [(set (match_operand:SF 0 "register_operand" "")
4306 (float_truncate:SF
4307 (match_operand:DF 1 "fp_register_operand" "")))
4308 (clobber (match_operand 2 "" ""))]
4309 "reload_completed"
4310 [(set (match_dup 2) (match_dup 1))
4311 (set (match_dup 0) (match_dup 2))]
4312 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4313
4314 ;; Conversion from XFmode to {SF,DF}mode
4315
4316 (define_expand "truncxf<mode>2"
4317 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4318 (float_truncate:MODEF
4319 (match_operand:XF 1 "register_operand" "")))
4320 (clobber (match_dup 2))])]
4321 "TARGET_80387"
4322 {
4323 if (flag_unsafe_math_optimizations)
4324 {
4325 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4326 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4327 if (reg != operands[0])
4328 emit_move_insn (operands[0], reg);
4329 DONE;
4330 }
4331 else
4332 {
4333 enum ix86_stack_slot slot = (virtuals_instantiated
4334 ? SLOT_TEMP
4335 : SLOT_VIRTUAL);
4336 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4337 }
4338 })
4339
4340 (define_insn "*truncxfsf2_mixed"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4342 (float_truncate:SF
4343 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4345 "TARGET_80387"
4346 {
4347 gcc_assert (!which_alternative);
4348 return output_387_reg_move (insn, operands);
4349 }
4350 [(set_attr "type" "fmov,multi,multi,multi")
4351 (set_attr "unit" "*,i387,i387,i387")
4352 (set_attr "mode" "SF")])
4353
4354 (define_insn "*truncxfdf2_mixed"
4355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4356 (float_truncate:DF
4357 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4358 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4359 "TARGET_80387"
4360 {
4361 gcc_assert (!which_alternative);
4362 return output_387_reg_move (insn, operands);
4363 }
4364 [(set_attr "type" "fmov,multi,multi,multi")
4365 (set_attr "unit" "*,i387,i387,i387")
4366 (set_attr "mode" "DF")])
4367
4368 (define_insn "truncxf<mode>2_i387_noop"
4369 [(set (match_operand:MODEF 0 "register_operand" "=f")
4370 (float_truncate:MODEF
4371 (match_operand:XF 1 "register_operand" "f")))]
4372 "TARGET_80387 && flag_unsafe_math_optimizations"
4373 "* return output_387_reg_move (insn, operands);"
4374 [(set_attr "type" "fmov")
4375 (set_attr "mode" "<MODE>")])
4376
4377 (define_insn "*truncxf<mode>2_i387"
4378 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379 (float_truncate:MODEF
4380 (match_operand:XF 1 "register_operand" "f")))]
4381 "TARGET_80387"
4382 "* return output_387_reg_move (insn, operands);"
4383 [(set_attr "type" "fmov")
4384 (set_attr "mode" "<MODE>")])
4385
4386 (define_split
4387 [(set (match_operand:MODEF 0 "register_operand" "")
4388 (float_truncate:MODEF
4389 (match_operand:XF 1 "register_operand" "")))
4390 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391 "TARGET_80387 && reload_completed"
4392 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393 (set (match_dup 0) (match_dup 2))])
4394
4395 (define_split
4396 [(set (match_operand:MODEF 0 "memory_operand" "")
4397 (float_truncate:MODEF
4398 (match_operand:XF 1 "register_operand" "")))
4399 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4400 "TARGET_80387"
4401 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4402 \f
4403 ;; Signed conversion to DImode.
4404
4405 (define_expand "fix_truncxfdi2"
4406 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4407 (fix:DI (match_operand:XF 1 "register_operand" "")))
4408 (clobber (reg:CC FLAGS_REG))])]
4409 "TARGET_80387"
4410 {
4411 if (TARGET_FISTTP)
4412 {
4413 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4414 DONE;
4415 }
4416 })
4417
4418 (define_expand "fix_trunc<mode>di2"
4419 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4420 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4421 (clobber (reg:CC FLAGS_REG))])]
4422 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4423 {
4424 if (TARGET_FISTTP
4425 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4426 {
4427 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4428 DONE;
4429 }
4430 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4431 {
4432 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4433 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4434 if (out != operands[0])
4435 emit_move_insn (operands[0], out);
4436 DONE;
4437 }
4438 })
4439
4440 ;; Signed conversion to SImode.
4441
4442 (define_expand "fix_truncxfsi2"
4443 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4444 (fix:SI (match_operand:XF 1 "register_operand" "")))
4445 (clobber (reg:CC FLAGS_REG))])]
4446 "TARGET_80387"
4447 {
4448 if (TARGET_FISTTP)
4449 {
4450 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4451 DONE;
4452 }
4453 })
4454
4455 (define_expand "fix_trunc<mode>si2"
4456 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4457 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4458 (clobber (reg:CC FLAGS_REG))])]
4459 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4460 {
4461 if (TARGET_FISTTP
4462 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4463 {
4464 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4465 DONE;
4466 }
4467 if (SSE_FLOAT_MODE_P (<MODE>mode))
4468 {
4469 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4470 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4471 if (out != operands[0])
4472 emit_move_insn (operands[0], out);
4473 DONE;
4474 }
4475 })
4476
4477 ;; Signed conversion to HImode.
4478
4479 (define_expand "fix_trunc<mode>hi2"
4480 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4481 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4482 (clobber (reg:CC FLAGS_REG))])]
4483 "TARGET_80387
4484 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4485 {
4486 if (TARGET_FISTTP)
4487 {
4488 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4489 DONE;
4490 }
4491 })
4492
4493 ;; Unsigned conversion to SImode.
4494
4495 (define_expand "fixuns_trunc<mode>si2"
4496 [(parallel
4497 [(set (match_operand:SI 0 "register_operand" "")
4498 (unsigned_fix:SI
4499 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4500 (use (match_dup 2))
4501 (clobber (match_scratch:<ssevecmode> 3 ""))
4502 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4503 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4504 {
4505 enum machine_mode mode = <MODE>mode;
4506 enum machine_mode vecmode = <ssevecmode>mode;
4507 REAL_VALUE_TYPE TWO31r;
4508 rtx two31;
4509
4510 if (optimize_insn_for_size_p ())
4511 FAIL;
4512
4513 real_ldexp (&TWO31r, &dconst1, 31);
4514 two31 = const_double_from_real_value (TWO31r, mode);
4515 two31 = ix86_build_const_vector (mode, true, two31);
4516 operands[2] = force_reg (vecmode, two31);
4517 })
4518
4519 (define_insn_and_split "*fixuns_trunc<mode>_1"
4520 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4521 (unsigned_fix:SI
4522 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4523 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4524 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4525 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4526 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4527 && optimize_function_for_speed_p (cfun)"
4528 "#"
4529 "&& reload_completed"
4530 [(const_int 0)]
4531 {
4532 ix86_split_convert_uns_si_sse (operands);
4533 DONE;
4534 })
4535
4536 ;; Unsigned conversion to HImode.
4537 ;; Without these patterns, we'll try the unsigned SI conversion which
4538 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4539
4540 (define_expand "fixuns_trunc<mode>hi2"
4541 [(set (match_dup 2)
4542 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4543 (set (match_operand:HI 0 "nonimmediate_operand" "")
4544 (subreg:HI (match_dup 2) 0))]
4545 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4546 "operands[2] = gen_reg_rtx (SImode);")
4547
4548 ;; When SSE is available, it is always faster to use it!
4549 (define_insn "fix_trunc<mode>di_sse"
4550 [(set (match_operand:DI 0 "register_operand" "=r,r")
4551 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4552 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4553 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4554 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4555 [(set_attr "type" "sseicvt")
4556 (set_attr "prefix" "maybe_vex")
4557 (set_attr "prefix_rex" "1")
4558 (set_attr "mode" "<MODE>")
4559 (set_attr "athlon_decode" "double,vector")
4560 (set_attr "amdfam10_decode" "double,double")])
4561
4562 (define_insn "fix_trunc<mode>si_sse"
4563 [(set (match_operand:SI 0 "register_operand" "=r,r")
4564 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4565 "SSE_FLOAT_MODE_P (<MODE>mode)
4566 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4567 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4568 [(set_attr "type" "sseicvt")
4569 (set_attr "prefix" "maybe_vex")
4570 (set_attr "mode" "<MODE>")
4571 (set_attr "athlon_decode" "double,vector")
4572 (set_attr "amdfam10_decode" "double,double")])
4573
4574 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4575 (define_peephole2
4576 [(set (match_operand:MODEF 0 "register_operand" "")
4577 (match_operand:MODEF 1 "memory_operand" ""))
4578 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4579 (fix:SSEMODEI24 (match_dup 0)))]
4580 "TARGET_SHORTEN_X87_SSE
4581 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4582 && peep2_reg_dead_p (2, operands[0])"
4583 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4584
4585 ;; Avoid vector decoded forms of the instruction.
4586 (define_peephole2
4587 [(match_scratch:DF 2 "Y2")
4588 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4589 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4590 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4591 [(set (match_dup 2) (match_dup 1))
4592 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4593
4594 (define_peephole2
4595 [(match_scratch:SF 2 "x")
4596 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4597 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4598 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4599 [(set (match_dup 2) (match_dup 1))
4600 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4601
4602 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4603 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4604 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4605 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4606 && TARGET_FISTTP
4607 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4608 && (TARGET_64BIT || <MODE>mode != DImode))
4609 && TARGET_SSE_MATH)
4610 && can_create_pseudo_p ()"
4611 "#"
4612 "&& 1"
4613 [(const_int 0)]
4614 {
4615 if (memory_operand (operands[0], VOIDmode))
4616 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4617 else
4618 {
4619 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4620 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4621 operands[1],
4622 operands[2]));
4623 }
4624 DONE;
4625 }
4626 [(set_attr "type" "fisttp")
4627 (set_attr "mode" "<MODE>")])
4628
4629 (define_insn "fix_trunc<mode>_i387_fisttp"
4630 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4631 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4632 (clobber (match_scratch:XF 2 "=&1f"))]
4633 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4634 && TARGET_FISTTP
4635 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4636 && (TARGET_64BIT || <MODE>mode != DImode))
4637 && TARGET_SSE_MATH)"
4638 "* return output_fix_trunc (insn, operands, 1);"
4639 [(set_attr "type" "fisttp")
4640 (set_attr "mode" "<MODE>")])
4641
4642 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4643 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4644 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4645 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4646 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4647 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648 && TARGET_FISTTP
4649 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4650 && (TARGET_64BIT || <MODE>mode != DImode))
4651 && TARGET_SSE_MATH)"
4652 "#"
4653 [(set_attr "type" "fisttp")
4654 (set_attr "mode" "<MODE>")])
4655
4656 (define_split
4657 [(set (match_operand:X87MODEI 0 "register_operand" "")
4658 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4659 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4660 (clobber (match_scratch 3 ""))]
4661 "reload_completed"
4662 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4663 (clobber (match_dup 3))])
4664 (set (match_dup 0) (match_dup 2))])
4665
4666 (define_split
4667 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4668 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4669 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4670 (clobber (match_scratch 3 ""))]
4671 "reload_completed"
4672 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4673 (clobber (match_dup 3))])])
4674
4675 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4676 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4677 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4678 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4679 ;; function in i386.c.
4680 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4681 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4682 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4683 (clobber (reg:CC FLAGS_REG))]
4684 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685 && !TARGET_FISTTP
4686 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4687 && (TARGET_64BIT || <MODE>mode != DImode))
4688 && can_create_pseudo_p ()"
4689 "#"
4690 "&& 1"
4691 [(const_int 0)]
4692 {
4693 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4694
4695 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4696 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4697 if (memory_operand (operands[0], VOIDmode))
4698 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4699 operands[2], operands[3]));
4700 else
4701 {
4702 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4703 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4704 operands[2], operands[3],
4705 operands[4]));
4706 }
4707 DONE;
4708 }
4709 [(set_attr "type" "fistp")
4710 (set_attr "i387_cw" "trunc")
4711 (set_attr "mode" "<MODE>")])
4712
4713 (define_insn "fix_truncdi_i387"
4714 [(set (match_operand:DI 0 "memory_operand" "=m")
4715 (fix:DI (match_operand 1 "register_operand" "f")))
4716 (use (match_operand:HI 2 "memory_operand" "m"))
4717 (use (match_operand:HI 3 "memory_operand" "m"))
4718 (clobber (match_scratch:XF 4 "=&1f"))]
4719 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4720 && !TARGET_FISTTP
4721 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4722 "* return output_fix_trunc (insn, operands, 0);"
4723 [(set_attr "type" "fistp")
4724 (set_attr "i387_cw" "trunc")
4725 (set_attr "mode" "DI")])
4726
4727 (define_insn "fix_truncdi_i387_with_temp"
4728 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4729 (fix:DI (match_operand 1 "register_operand" "f,f")))
4730 (use (match_operand:HI 2 "memory_operand" "m,m"))
4731 (use (match_operand:HI 3 "memory_operand" "m,m"))
4732 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4733 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4734 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && !TARGET_FISTTP
4736 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4737 "#"
4738 [(set_attr "type" "fistp")
4739 (set_attr "i387_cw" "trunc")
4740 (set_attr "mode" "DI")])
4741
4742 (define_split
4743 [(set (match_operand:DI 0 "register_operand" "")
4744 (fix:DI (match_operand 1 "register_operand" "")))
4745 (use (match_operand:HI 2 "memory_operand" ""))
4746 (use (match_operand:HI 3 "memory_operand" ""))
4747 (clobber (match_operand:DI 4 "memory_operand" ""))
4748 (clobber (match_scratch 5 ""))]
4749 "reload_completed"
4750 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4751 (use (match_dup 2))
4752 (use (match_dup 3))
4753 (clobber (match_dup 5))])
4754 (set (match_dup 0) (match_dup 4))])
4755
4756 (define_split
4757 [(set (match_operand:DI 0 "memory_operand" "")
4758 (fix:DI (match_operand 1 "register_operand" "")))
4759 (use (match_operand:HI 2 "memory_operand" ""))
4760 (use (match_operand:HI 3 "memory_operand" ""))
4761 (clobber (match_operand:DI 4 "memory_operand" ""))
4762 (clobber (match_scratch 5 ""))]
4763 "reload_completed"
4764 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4765 (use (match_dup 2))
4766 (use (match_dup 3))
4767 (clobber (match_dup 5))])])
4768
4769 (define_insn "fix_trunc<mode>_i387"
4770 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4771 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4772 (use (match_operand:HI 2 "memory_operand" "m"))
4773 (use (match_operand:HI 3 "memory_operand" "m"))]
4774 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4775 && !TARGET_FISTTP
4776 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4777 "* return output_fix_trunc (insn, operands, 0);"
4778 [(set_attr "type" "fistp")
4779 (set_attr "i387_cw" "trunc")
4780 (set_attr "mode" "<MODE>")])
4781
4782 (define_insn "fix_trunc<mode>_i387_with_temp"
4783 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4784 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4785 (use (match_operand:HI 2 "memory_operand" "m,m"))
4786 (use (match_operand:HI 3 "memory_operand" "m,m"))
4787 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4788 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4789 && !TARGET_FISTTP
4790 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4791 "#"
4792 [(set_attr "type" "fistp")
4793 (set_attr "i387_cw" "trunc")
4794 (set_attr "mode" "<MODE>")])
4795
4796 (define_split
4797 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4798 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4799 (use (match_operand:HI 2 "memory_operand" ""))
4800 (use (match_operand:HI 3 "memory_operand" ""))
4801 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4802 "reload_completed"
4803 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4804 (use (match_dup 2))
4805 (use (match_dup 3))])
4806 (set (match_dup 0) (match_dup 4))])
4807
4808 (define_split
4809 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4810 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4811 (use (match_operand:HI 2 "memory_operand" ""))
4812 (use (match_operand:HI 3 "memory_operand" ""))
4813 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4814 "reload_completed"
4815 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4816 (use (match_dup 2))
4817 (use (match_dup 3))])])
4818
4819 (define_insn "x86_fnstcw_1"
4820 [(set (match_operand:HI 0 "memory_operand" "=m")
4821 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4822 "TARGET_80387"
4823 "fnstcw\t%0"
4824 [(set (attr "length")
4825 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4826 (set_attr "mode" "HI")
4827 (set_attr "unit" "i387")])
4828
4829 (define_insn "x86_fldcw_1"
4830 [(set (reg:HI FPCR_REG)
4831 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4832 "TARGET_80387"
4833 "fldcw\t%0"
4834 [(set (attr "length")
4835 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4836 (set_attr "mode" "HI")
4837 (set_attr "unit" "i387")
4838 (set_attr "athlon_decode" "vector")
4839 (set_attr "amdfam10_decode" "vector")])
4840 \f
4841 ;; Conversion between fixed point and floating point.
4842
4843 ;; Even though we only accept memory inputs, the backend _really_
4844 ;; wants to be able to do this between registers.
4845
4846 (define_expand "floathi<mode>2"
4847 [(set (match_operand:X87MODEF 0 "register_operand" "")
4848 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4849 "TARGET_80387
4850 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4851 || TARGET_MIX_SSE_I387)")
4852
4853 ;; Pre-reload splitter to add memory clobber to the pattern.
4854 (define_insn_and_split "*floathi<mode>2_1"
4855 [(set (match_operand:X87MODEF 0 "register_operand" "")
4856 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4857 "TARGET_80387
4858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4859 || TARGET_MIX_SSE_I387)
4860 && can_create_pseudo_p ()"
4861 "#"
4862 "&& 1"
4863 [(parallel [(set (match_dup 0)
4864 (float:X87MODEF (match_dup 1)))
4865 (clobber (match_dup 2))])]
4866 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4867
4868 (define_insn "*floathi<mode>2_i387_with_temp"
4869 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4870 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4871 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4872 "TARGET_80387
4873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4874 || TARGET_MIX_SSE_I387)"
4875 "#"
4876 [(set_attr "type" "fmov,multi")
4877 (set_attr "mode" "<MODE>")
4878 (set_attr "unit" "*,i387")
4879 (set_attr "fp_int_src" "true")])
4880
4881 (define_insn "*floathi<mode>2_i387"
4882 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4883 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4884 "TARGET_80387
4885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4886 || TARGET_MIX_SSE_I387)"
4887 "fild%Z1\t%1"
4888 [(set_attr "type" "fmov")
4889 (set_attr "mode" "<MODE>")
4890 (set_attr "fp_int_src" "true")])
4891
4892 (define_split
4893 [(set (match_operand:X87MODEF 0 "register_operand" "")
4894 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4895 (clobber (match_operand:HI 2 "memory_operand" ""))]
4896 "TARGET_80387
4897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4898 || TARGET_MIX_SSE_I387)
4899 && reload_completed"
4900 [(set (match_dup 2) (match_dup 1))
4901 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4902
4903 (define_split
4904 [(set (match_operand:X87MODEF 0 "register_operand" "")
4905 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4906 (clobber (match_operand:HI 2 "memory_operand" ""))]
4907 "TARGET_80387
4908 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4909 || TARGET_MIX_SSE_I387)
4910 && reload_completed"
4911 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4912
4913 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4914 [(set (match_operand:X87MODEF 0 "register_operand" "")
4915 (float:X87MODEF
4916 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4917 "TARGET_80387
4918 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4920 {
4921 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4922 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4923 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4924 {
4925 rtx reg = gen_reg_rtx (XFmode);
4926 rtx insn;
4927
4928 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4929
4930 if (<X87MODEF:MODE>mode == SFmode)
4931 insn = gen_truncxfsf2 (operands[0], reg);
4932 else if (<X87MODEF:MODE>mode == DFmode)
4933 insn = gen_truncxfdf2 (operands[0], reg);
4934 else
4935 gcc_unreachable ();
4936
4937 emit_insn (insn);
4938 DONE;
4939 }
4940 })
4941
4942 ;; Pre-reload splitter to add memory clobber to the pattern.
4943 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4944 [(set (match_operand:X87MODEF 0 "register_operand" "")
4945 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4946 "((TARGET_80387
4947 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4948 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4950 || TARGET_MIX_SSE_I387))
4951 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4952 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4953 && ((<SSEMODEI24:MODE>mode == SImode
4954 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4955 && optimize_function_for_speed_p (cfun)
4956 && flag_trapping_math)
4957 || !(TARGET_INTER_UNIT_CONVERSIONS
4958 || optimize_function_for_size_p (cfun)))))
4959 && can_create_pseudo_p ()"
4960 "#"
4961 "&& 1"
4962 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4963 (clobber (match_dup 2))])]
4964 {
4965 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4966
4967 /* Avoid store forwarding (partial memory) stall penalty
4968 by passing DImode value through XMM registers. */
4969 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4970 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4971 && optimize_function_for_speed_p (cfun))
4972 {
4973 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4974 operands[1],
4975 operands[2]));
4976 DONE;
4977 }
4978 })
4979
4980 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4981 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4982 (float:MODEF
4983 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4984 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4985 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4986 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4987 "#"
4988 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4989 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4990 (set_attr "unit" "*,i387,*,*,*")
4991 (set_attr "athlon_decode" "*,*,double,direct,double")
4992 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4993 (set_attr "fp_int_src" "true")])
4994
4995 (define_insn "*floatsi<mode>2_vector_mixed"
4996 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4997 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4998 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4999 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5000 "@
5001 fild%Z1\t%1
5002 #"
5003 [(set_attr "type" "fmov,sseicvt")
5004 (set_attr "mode" "<MODE>,<ssevecmode>")
5005 (set_attr "unit" "i387,*")
5006 (set_attr "athlon_decode" "*,direct")
5007 (set_attr "amdfam10_decode" "*,double")
5008 (set_attr "fp_int_src" "true")])
5009
5010 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5011 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5012 (float:MODEF
5013 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5014 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5015 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5016 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5017 "#"
5018 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set_attr "unit" "*,i387,*,*")
5021 (set_attr "athlon_decode" "*,*,double,direct")
5022 (set_attr "amdfam10_decode" "*,*,vector,double")
5023 (set_attr "fp_int_src" "true")])
5024
5025 (define_split
5026 [(set (match_operand:MODEF 0 "register_operand" "")
5027 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5028 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5029 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5030 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5031 && TARGET_INTER_UNIT_CONVERSIONS
5032 && reload_completed
5033 && (SSE_REG_P (operands[0])
5034 || (GET_CODE (operands[0]) == SUBREG
5035 && SSE_REG_P (operands[0])))"
5036 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5037
5038 (define_split
5039 [(set (match_operand:MODEF 0 "register_operand" "")
5040 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5041 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5042 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5043 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5044 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5045 && reload_completed
5046 && (SSE_REG_P (operands[0])
5047 || (GET_CODE (operands[0]) == SUBREG
5048 && SSE_REG_P (operands[0])))"
5049 [(set (match_dup 2) (match_dup 1))
5050 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5051
5052 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5053 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5054 (float:MODEF
5055 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5056 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5057 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5058 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5059 "@
5060 fild%Z1\t%1
5061 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5062 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5063 [(set_attr "type" "fmov,sseicvt,sseicvt")
5064 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5065 (set_attr "mode" "<MODEF:MODE>")
5066 (set (attr "prefix_rex")
5067 (if_then_else
5068 (and (eq_attr "prefix" "maybe_vex")
5069 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5070 (const_string "1")
5071 (const_string "*")))
5072 (set_attr "unit" "i387,*,*")
5073 (set_attr "athlon_decode" "*,double,direct")
5074 (set_attr "amdfam10_decode" "*,vector,double")
5075 (set_attr "fp_int_src" "true")])
5076
5077 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5078 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5079 (float:MODEF
5080 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5081 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5083 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5084 "@
5085 fild%Z1\t%1
5086 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5087 [(set_attr "type" "fmov,sseicvt")
5088 (set_attr "prefix" "orig,maybe_vex")
5089 (set_attr "mode" "<MODEF:MODE>")
5090 (set (attr "prefix_rex")
5091 (if_then_else
5092 (and (eq_attr "prefix" "maybe_vex")
5093 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5094 (const_string "1")
5095 (const_string "*")))
5096 (set_attr "athlon_decode" "*,direct")
5097 (set_attr "amdfam10_decode" "*,double")
5098 (set_attr "fp_int_src" "true")])
5099
5100 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5101 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5102 (float:MODEF
5103 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5104 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5105 "TARGET_SSE2 && TARGET_SSE_MATH
5106 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5107 "#"
5108 [(set_attr "type" "sseicvt")
5109 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5110 (set_attr "athlon_decode" "double,direct,double")
5111 (set_attr "amdfam10_decode" "vector,double,double")
5112 (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "*floatsi<mode>2_vector_sse"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x")
5116 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5117 "TARGET_SSE2 && TARGET_SSE_MATH
5118 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5119 "#"
5120 [(set_attr "type" "sseicvt")
5121 (set_attr "mode" "<MODE>")
5122 (set_attr "athlon_decode" "direct")
5123 (set_attr "amdfam10_decode" "double")
5124 (set_attr "fp_int_src" "true")])
5125
5126 (define_split
5127 [(set (match_operand:MODEF 0 "register_operand" "")
5128 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5129 (clobber (match_operand:SI 2 "memory_operand" ""))]
5130 "TARGET_SSE2 && TARGET_SSE_MATH
5131 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5132 && reload_completed
5133 && (SSE_REG_P (operands[0])
5134 || (GET_CODE (operands[0]) == SUBREG
5135 && SSE_REG_P (operands[0])))"
5136 [(const_int 0)]
5137 {
5138 rtx op1 = operands[1];
5139
5140 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5141 <MODE>mode, 0);
5142 if (GET_CODE (op1) == SUBREG)
5143 op1 = SUBREG_REG (op1);
5144
5145 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5146 {
5147 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148 emit_insn (gen_sse2_loadld (operands[4],
5149 CONST0_RTX (V4SImode), operands[1]));
5150 }
5151 /* We can ignore possible trapping value in the
5152 high part of SSE register for non-trapping math. */
5153 else if (SSE_REG_P (op1) && !flag_trapping_math)
5154 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5155 else
5156 {
5157 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5158 emit_move_insn (operands[2], operands[1]);
5159 emit_insn (gen_sse2_loadld (operands[4],
5160 CONST0_RTX (V4SImode), operands[2]));
5161 }
5162 emit_insn
5163 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5164 DONE;
5165 })
5166
5167 (define_split
5168 [(set (match_operand:MODEF 0 "register_operand" "")
5169 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5170 (clobber (match_operand:SI 2 "memory_operand" ""))]
5171 "TARGET_SSE2 && TARGET_SSE_MATH
5172 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5173 && reload_completed
5174 && (SSE_REG_P (operands[0])
5175 || (GET_CODE (operands[0]) == SUBREG
5176 && SSE_REG_P (operands[0])))"
5177 [(const_int 0)]
5178 {
5179 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5180 <MODE>mode, 0);
5181 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5182
5183 emit_insn (gen_sse2_loadld (operands[4],
5184 CONST0_RTX (V4SImode), operands[1]));
5185 emit_insn
5186 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5187 DONE;
5188 })
5189
5190 (define_split
5191 [(set (match_operand:MODEF 0 "register_operand" "")
5192 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5193 "TARGET_SSE2 && TARGET_SSE_MATH
5194 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5195 && reload_completed
5196 && (SSE_REG_P (operands[0])
5197 || (GET_CODE (operands[0]) == SUBREG
5198 && SSE_REG_P (operands[0])))"
5199 [(const_int 0)]
5200 {
5201 rtx op1 = operands[1];
5202
5203 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5204 <MODE>mode, 0);
5205 if (GET_CODE (op1) == SUBREG)
5206 op1 = SUBREG_REG (op1);
5207
5208 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5209 {
5210 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5211 emit_insn (gen_sse2_loadld (operands[4],
5212 CONST0_RTX (V4SImode), operands[1]));
5213 }
5214 /* We can ignore possible trapping value in the
5215 high part of SSE register for non-trapping math. */
5216 else if (SSE_REG_P (op1) && !flag_trapping_math)
5217 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5218 else
5219 gcc_unreachable ();
5220 emit_insn
5221 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5222 DONE;
5223 })
5224
5225 (define_split
5226 [(set (match_operand:MODEF 0 "register_operand" "")
5227 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5228 "TARGET_SSE2 && TARGET_SSE_MATH
5229 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5230 && reload_completed
5231 && (SSE_REG_P (operands[0])
5232 || (GET_CODE (operands[0]) == SUBREG
5233 && SSE_REG_P (operands[0])))"
5234 [(const_int 0)]
5235 {
5236 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5237 <MODE>mode, 0);
5238 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5239
5240 emit_insn (gen_sse2_loadld (operands[4],
5241 CONST0_RTX (V4SImode), operands[1]));
5242 emit_insn
5243 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5244 DONE;
5245 })
5246
5247 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5248 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5249 (float:MODEF
5250 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5251 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5252 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5253 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5254 "#"
5255 [(set_attr "type" "sseicvt")
5256 (set_attr "mode" "<MODEF:MODE>")
5257 (set_attr "athlon_decode" "double,direct")
5258 (set_attr "amdfam10_decode" "vector,double")
5259 (set_attr "fp_int_src" "true")])
5260
5261 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5262 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5263 (float:MODEF
5264 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5265 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5266 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5267 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5268 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5269 [(set_attr "type" "sseicvt")
5270 (set_attr "prefix" "maybe_vex")
5271 (set_attr "mode" "<MODEF:MODE>")
5272 (set (attr "prefix_rex")
5273 (if_then_else
5274 (and (eq_attr "prefix" "maybe_vex")
5275 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5276 (const_string "1")
5277 (const_string "*")))
5278 (set_attr "athlon_decode" "double,direct")
5279 (set_attr "amdfam10_decode" "vector,double")
5280 (set_attr "fp_int_src" "true")])
5281
5282 (define_split
5283 [(set (match_operand:MODEF 0 "register_operand" "")
5284 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5285 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5286 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5288 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5289 && reload_completed
5290 && (SSE_REG_P (operands[0])
5291 || (GET_CODE (operands[0]) == SUBREG
5292 && SSE_REG_P (operands[0])))"
5293 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5294
5295 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5296 [(set (match_operand:MODEF 0 "register_operand" "=x")
5297 (float:MODEF
5298 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5299 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5301 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5302 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5303 [(set_attr "type" "sseicvt")
5304 (set_attr "prefix" "maybe_vex")
5305 (set_attr "mode" "<MODEF:MODE>")
5306 (set (attr "prefix_rex")
5307 (if_then_else
5308 (and (eq_attr "prefix" "maybe_vex")
5309 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5310 (const_string "1")
5311 (const_string "*")))
5312 (set_attr "athlon_decode" "direct")
5313 (set_attr "amdfam10_decode" "double")
5314 (set_attr "fp_int_src" "true")])
5315
5316 (define_split
5317 [(set (match_operand:MODEF 0 "register_operand" "")
5318 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5319 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5320 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5322 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5323 && reload_completed
5324 && (SSE_REG_P (operands[0])
5325 || (GET_CODE (operands[0]) == SUBREG
5326 && SSE_REG_P (operands[0])))"
5327 [(set (match_dup 2) (match_dup 1))
5328 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5329
5330 (define_split
5331 [(set (match_operand:MODEF 0 "register_operand" "")
5332 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5333 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5334 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5335 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5336 && reload_completed
5337 && (SSE_REG_P (operands[0])
5338 || (GET_CODE (operands[0]) == SUBREG
5339 && SSE_REG_P (operands[0])))"
5340 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5341
5342 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5343 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5344 (float:X87MODEF
5345 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5346 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5347 "TARGET_80387
5348 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5349 "@
5350 fild%Z1\t%1
5351 #"
5352 [(set_attr "type" "fmov,multi")
5353 (set_attr "mode" "<X87MODEF:MODE>")
5354 (set_attr "unit" "*,i387")
5355 (set_attr "fp_int_src" "true")])
5356
5357 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5358 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5359 (float:X87MODEF
5360 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5361 "TARGET_80387
5362 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5363 "fild%Z1\t%1"
5364 [(set_attr "type" "fmov")
5365 (set_attr "mode" "<X87MODEF:MODE>")
5366 (set_attr "fp_int_src" "true")])
5367
5368 (define_split
5369 [(set (match_operand:X87MODEF 0 "register_operand" "")
5370 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5371 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5372 "TARGET_80387
5373 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5374 && reload_completed
5375 && FP_REG_P (operands[0])"
5376 [(set (match_dup 2) (match_dup 1))
5377 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5378
5379 (define_split
5380 [(set (match_operand:X87MODEF 0 "register_operand" "")
5381 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5382 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5383 "TARGET_80387
5384 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5385 && reload_completed
5386 && FP_REG_P (operands[0])"
5387 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5388
5389 ;; Avoid store forwarding (partial memory) stall penalty
5390 ;; by passing DImode value through XMM registers. */
5391
5392 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5393 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5394 (float:X87MODEF
5395 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5396 (clobber (match_scratch:V4SI 3 "=X,x"))
5397 (clobber (match_scratch:V4SI 4 "=X,x"))
5398 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5399 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5401 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5402 "#"
5403 [(set_attr "type" "multi")
5404 (set_attr "mode" "<X87MODEF:MODE>")
5405 (set_attr "unit" "i387")
5406 (set_attr "fp_int_src" "true")])
5407
5408 (define_split
5409 [(set (match_operand:X87MODEF 0 "register_operand" "")
5410 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5411 (clobber (match_scratch:V4SI 3 ""))
5412 (clobber (match_scratch:V4SI 4 ""))
5413 (clobber (match_operand:DI 2 "memory_operand" ""))]
5414 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5415 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5416 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5417 && reload_completed
5418 && FP_REG_P (operands[0])"
5419 [(set (match_dup 2) (match_dup 3))
5420 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5421 {
5422 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5423 Assemble the 64-bit DImode value in an xmm register. */
5424 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5425 gen_rtx_SUBREG (SImode, operands[1], 0)));
5426 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5427 gen_rtx_SUBREG (SImode, operands[1], 4)));
5428 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5429 operands[4]));
5430
5431 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5432 })
5433
5434 (define_split
5435 [(set (match_operand:X87MODEF 0 "register_operand" "")
5436 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5437 (clobber (match_scratch:V4SI 3 ""))
5438 (clobber (match_scratch:V4SI 4 ""))
5439 (clobber (match_operand:DI 2 "memory_operand" ""))]
5440 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5441 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5442 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5443 && reload_completed
5444 && FP_REG_P (operands[0])"
5445 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5446
5447 ;; Avoid store forwarding (partial memory) stall penalty by extending
5448 ;; SImode value to DImode through XMM register instead of pushing two
5449 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5450 ;; targets benefit from this optimization. Also note that fild
5451 ;; loads from memory only.
5452
5453 (define_insn "*floatunssi<mode>2_1"
5454 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5455 (unsigned_float:X87MODEF
5456 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5457 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5458 (clobber (match_scratch:SI 3 "=X,x"))]
5459 "!TARGET_64BIT
5460 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5461 && TARGET_SSE"
5462 "#"
5463 [(set_attr "type" "multi")
5464 (set_attr "mode" "<MODE>")])
5465
5466 (define_split
5467 [(set (match_operand:X87MODEF 0 "register_operand" "")
5468 (unsigned_float:X87MODEF
5469 (match_operand:SI 1 "register_operand" "")))
5470 (clobber (match_operand:DI 2 "memory_operand" ""))
5471 (clobber (match_scratch:SI 3 ""))]
5472 "!TARGET_64BIT
5473 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5474 && TARGET_SSE
5475 && reload_completed"
5476 [(set (match_dup 2) (match_dup 1))
5477 (set (match_dup 0)
5478 (float:X87MODEF (match_dup 2)))]
5479 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5480
5481 (define_split
5482 [(set (match_operand:X87MODEF 0 "register_operand" "")
5483 (unsigned_float:X87MODEF
5484 (match_operand:SI 1 "memory_operand" "")))
5485 (clobber (match_operand:DI 2 "memory_operand" ""))
5486 (clobber (match_scratch:SI 3 ""))]
5487 "!TARGET_64BIT
5488 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5489 && TARGET_SSE
5490 && reload_completed"
5491 [(set (match_dup 2) (match_dup 3))
5492 (set (match_dup 0)
5493 (float:X87MODEF (match_dup 2)))]
5494 {
5495 emit_move_insn (operands[3], operands[1]);
5496 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5497 })
5498
5499 (define_expand "floatunssi<mode>2"
5500 [(parallel
5501 [(set (match_operand:X87MODEF 0 "register_operand" "")
5502 (unsigned_float:X87MODEF
5503 (match_operand:SI 1 "nonimmediate_operand" "")))
5504 (clobber (match_dup 2))
5505 (clobber (match_scratch:SI 3 ""))])]
5506 "!TARGET_64BIT
5507 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5508 && TARGET_SSE)
5509 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5510 {
5511 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5512 {
5513 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5514 DONE;
5515 }
5516 else
5517 {
5518 enum ix86_stack_slot slot = (virtuals_instantiated
5519 ? SLOT_TEMP
5520 : SLOT_VIRTUAL);
5521 operands[2] = assign_386_stack_local (DImode, slot);
5522 }
5523 })
5524
5525 (define_expand "floatunsdisf2"
5526 [(use (match_operand:SF 0 "register_operand" ""))
5527 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5528 "TARGET_64BIT && TARGET_SSE_MATH"
5529 "x86_emit_floatuns (operands); DONE;")
5530
5531 (define_expand "floatunsdidf2"
5532 [(use (match_operand:DF 0 "register_operand" ""))
5533 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5534 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5535 && TARGET_SSE2 && TARGET_SSE_MATH"
5536 {
5537 if (TARGET_64BIT)
5538 x86_emit_floatuns (operands);
5539 else
5540 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5541 DONE;
5542 })
5543 \f
5544 ;; Add instructions
5545
5546 (define_expand "add<mode>3"
5547 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5548 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5549 (match_operand:SDWIM 2 "<general_operand>" "")))]
5550 ""
5551 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5552
5553 (define_insn_and_split "*add<dwi>3_doubleword"
5554 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5555 (plus:<DWI>
5556 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5557 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5558 (clobber (reg:CC FLAGS_REG))]
5559 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5560 "#"
5561 "reload_completed"
5562 [(parallel [(set (reg:CC FLAGS_REG)
5563 (unspec:CC [(match_dup 1) (match_dup 2)]
5564 UNSPEC_ADD_CARRY))
5565 (set (match_dup 0)
5566 (plus:DWIH (match_dup 1) (match_dup 2)))])
5567 (parallel [(set (match_dup 3)
5568 (plus:DWIH
5569 (match_dup 4)
5570 (plus:DWIH
5571 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5572 (match_dup 5))))
5573 (clobber (reg:CC FLAGS_REG))])]
5574 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5575
5576 (define_insn "*add<mode>3_cc"
5577 [(set (reg:CC FLAGS_REG)
5578 (unspec:CC
5579 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5580 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5581 UNSPEC_ADD_CARRY))
5582 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5583 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5584 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5586 [(set_attr "type" "alu")
5587 (set_attr "mode" "<MODE>")])
5588
5589 (define_insn "addqi3_cc"
5590 [(set (reg:CC FLAGS_REG)
5591 (unspec:CC
5592 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5593 (match_operand:QI 2 "general_operand" "qn,qm")]
5594 UNSPEC_ADD_CARRY))
5595 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5596 (plus:QI (match_dup 1) (match_dup 2)))]
5597 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5598 "add{b}\t{%2, %0|%0, %2}"
5599 [(set_attr "type" "alu")
5600 (set_attr "mode" "QI")])
5601
5602 (define_insn "*lea_1"
5603 [(set (match_operand:P 0 "register_operand" "=r")
5604 (match_operand:P 1 "no_seg_address_operand" "p"))]
5605 ""
5606 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5607 [(set_attr "type" "lea")
5608 (set_attr "mode" "<MODE>")])
5609
5610 (define_insn "*lea_2"
5611 [(set (match_operand:SI 0 "register_operand" "=r")
5612 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5613 "TARGET_64BIT"
5614 "lea{l}\t{%a1, %0|%0, %a1}"
5615 [(set_attr "type" "lea")
5616 (set_attr "mode" "SI")])
5617
5618 (define_insn "*lea_2_zext"
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5620 (zero_extend:DI
5621 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5622 "TARGET_64BIT"
5623 "lea{l}\t{%a1, %k0|%k0, %a1}"
5624 [(set_attr "type" "lea")
5625 (set_attr "mode" "SI")])
5626
5627 (define_insn "*add<mode>_1"
5628 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5629 (plus:SWI48
5630 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5631 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5632 (clobber (reg:CC FLAGS_REG))]
5633 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5634 {
5635 switch (get_attr_type (insn))
5636 {
5637 case TYPE_LEA:
5638 return "#";
5639
5640 case TYPE_INCDEC:
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (operands[2] == const1_rtx)
5643 return "inc{<imodesuffix>}\t%0";
5644 else
5645 {
5646 gcc_assert (operands[2] == constm1_rtx);
5647 return "dec{<imodesuffix>}\t%0";
5648 }
5649
5650 default:
5651 /* For most processors, ADD is faster than LEA. This alternative
5652 was added to use ADD as much as possible. */
5653 if (which_alternative == 2)
5654 {
5655 rtx tmp;
5656 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5657 }
5658
5659 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5661 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5662
5663 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5664 }
5665 }
5666 [(set (attr "type")
5667 (cond [(eq_attr "alternative" "3")
5668 (const_string "lea")
5669 (match_operand:SWI48 2 "incdec_operand" "")
5670 (const_string "incdec")
5671 ]
5672 (const_string "alu")))
5673 (set (attr "length_immediate")
5674 (if_then_else
5675 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5676 (const_string "1")
5677 (const_string "*")))
5678 (set_attr "mode" "<MODE>")])
5679
5680 ;; It may seem that nonimmediate operand is proper one for operand 1.
5681 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5682 ;; we take care in ix86_binary_operator_ok to not allow two memory
5683 ;; operands so proper swapping will be done in reload. This allow
5684 ;; patterns constructed from addsi_1 to match.
5685
5686 (define_insn "*addsi_1_zext"
5687 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5688 (zero_extend:DI
5689 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5690 (match_operand:SI 2 "general_operand" "g,0,li"))))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5693 {
5694 switch (get_attr_type (insn))
5695 {
5696 case TYPE_LEA:
5697 return "#";
5698
5699 case TYPE_INCDEC:
5700 if (operands[2] == const1_rtx)
5701 return "inc{l}\t%k0";
5702 else
5703 {
5704 gcc_assert (operands[2] == constm1_rtx);
5705 return "dec{l}\t%k0";
5706 }
5707
5708 default:
5709 /* For most processors, ADD is faster than LEA. This alternative
5710 was added to use ADD as much as possible. */
5711 if (which_alternative == 1)
5712 {
5713 rtx tmp;
5714 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5715 }
5716
5717 if (x86_maybe_negate_const_int (&operands[2], SImode))
5718 return "sub{l}\t{%2, %k0|%k0, %2}";
5719
5720 return "add{l}\t{%2, %k0|%k0, %2}";
5721 }
5722 }
5723 [(set (attr "type")
5724 (cond [(eq_attr "alternative" "2")
5725 (const_string "lea")
5726 (match_operand:SI 2 "incdec_operand" "")
5727 (const_string "incdec")
5728 ]
5729 (const_string "alu")))
5730 (set (attr "length_immediate")
5731 (if_then_else
5732 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5733 (const_string "1")
5734 (const_string "*")))
5735 (set_attr "mode" "SI")])
5736
5737 (define_insn "*addhi_1"
5738 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5739 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5740 (match_operand:HI 2 "general_operand" "rn,rm")))
5741 (clobber (reg:CC FLAGS_REG))]
5742 "TARGET_PARTIAL_REG_STALL
5743 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5744 {
5745 switch (get_attr_type (insn))
5746 {
5747 case TYPE_INCDEC:
5748 if (operands[2] == const1_rtx)
5749 return "inc{w}\t%0";
5750 else
5751 {
5752 gcc_assert (operands[2] == constm1_rtx);
5753 return "dec{w}\t%0";
5754 }
5755
5756 default:
5757 if (x86_maybe_negate_const_int (&operands[2], HImode))
5758 return "sub{w}\t{%2, %0|%0, %2}";
5759
5760 return "add{w}\t{%2, %0|%0, %2}";
5761 }
5762 }
5763 [(set (attr "type")
5764 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5765 (const_string "incdec")
5766 (const_string "alu")))
5767 (set (attr "length_immediate")
5768 (if_then_else
5769 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5770 (const_string "1")
5771 (const_string "*")))
5772 (set_attr "mode" "HI")])
5773
5774 (define_insn "*addhi_1_lea"
5775 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5776 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5777 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "!TARGET_PARTIAL_REG_STALL
5780 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5781 {
5782 switch (get_attr_type (insn))
5783 {
5784 case TYPE_LEA:
5785 return "#";
5786
5787 case TYPE_INCDEC:
5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789 if (operands[2] == const1_rtx)
5790 return "inc{w}\t%0";
5791 else
5792 {
5793 gcc_assert (operands[2] == constm1_rtx);
5794 return "dec{w}\t%0";
5795 }
5796
5797 default:
5798 /* For most processors, ADD is faster than LEA. This alternative
5799 was added to use ADD as much as possible. */
5800 if (which_alternative == 2)
5801 {
5802 rtx tmp;
5803 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5804 }
5805
5806 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5807 if (x86_maybe_negate_const_int (&operands[2], HImode))
5808 return "sub{w}\t{%2, %0|%0, %2}";
5809
5810 return "add{w}\t{%2, %0|%0, %2}";
5811 }
5812 }
5813 [(set (attr "type")
5814 (cond [(eq_attr "alternative" "3")
5815 (const_string "lea")
5816 (match_operand:HI 2 "incdec_operand" "")
5817 (const_string "incdec")
5818 ]
5819 (const_string "alu")))
5820 (set (attr "length_immediate")
5821 (if_then_else
5822 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5823 (const_string "1")
5824 (const_string "*")))
5825 (set_attr "mode" "HI,HI,HI,SI")])
5826
5827 ;; %%% Potential partial reg stall on alternative 2. What to do?
5828 (define_insn "*addqi_1"
5829 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5830 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5831 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "TARGET_PARTIAL_REG_STALL
5834 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5835 {
5836 int widen = (which_alternative == 2);
5837 switch (get_attr_type (insn))
5838 {
5839 case TYPE_INCDEC:
5840 if (operands[2] == const1_rtx)
5841 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5842 else
5843 {
5844 gcc_assert (operands[2] == constm1_rtx);
5845 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5846 }
5847
5848 default:
5849 if (x86_maybe_negate_const_int (&operands[2], QImode))
5850 {
5851 if (widen)
5852 return "sub{l}\t{%2, %k0|%k0, %2}";
5853 else
5854 return "sub{b}\t{%2, %0|%0, %2}";
5855 }
5856 if (widen)
5857 return "add{l}\t{%k2, %k0|%k0, %k2}";
5858 else
5859 return "add{b}\t{%2, %0|%0, %2}";
5860 }
5861 }
5862 [(set (attr "type")
5863 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5864 (const_string "incdec")
5865 (const_string "alu")))
5866 (set (attr "length_immediate")
5867 (if_then_else
5868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5869 (const_string "1")
5870 (const_string "*")))
5871 (set_attr "mode" "QI,QI,SI")])
5872
5873 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5874 (define_insn "*addqi_1_lea"
5875 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5876 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5877 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5878 (clobber (reg:CC FLAGS_REG))]
5879 "!TARGET_PARTIAL_REG_STALL
5880 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5881 {
5882 int widen = (which_alternative == 3 || which_alternative == 4);
5883
5884 switch (get_attr_type (insn))
5885 {
5886 case TYPE_LEA:
5887 return "#";
5888
5889 case TYPE_INCDEC:
5890 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5891 if (operands[2] == const1_rtx)
5892 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5893 else
5894 {
5895 gcc_assert (operands[2] == constm1_rtx);
5896 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5897 }
5898
5899 default:
5900 /* For most processors, ADD is faster than LEA. These alternatives
5901 were added to use ADD as much as possible. */
5902 if (which_alternative == 2 || which_alternative == 4)
5903 {
5904 rtx tmp;
5905 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5906 }
5907
5908 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909 if (x86_maybe_negate_const_int (&operands[2], QImode))
5910 {
5911 if (widen)
5912 return "sub{l}\t{%2, %k0|%k0, %2}";
5913 else
5914 return "sub{b}\t{%2, %0|%0, %2}";
5915 }
5916 if (widen)
5917 return "add{l}\t{%k2, %k0|%k0, %k2}";
5918 else
5919 return "add{b}\t{%2, %0|%0, %2}";
5920 }
5921 }
5922 [(set (attr "type")
5923 (cond [(eq_attr "alternative" "5")
5924 (const_string "lea")
5925 (match_operand:QI 2 "incdec_operand" "")
5926 (const_string "incdec")
5927 ]
5928 (const_string "alu")))
5929 (set (attr "length_immediate")
5930 (if_then_else
5931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5932 (const_string "1")
5933 (const_string "*")))
5934 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5935
5936 (define_insn "*addqi_1_slp"
5937 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5938 (plus:QI (match_dup 0)
5939 (match_operand:QI 1 "general_operand" "qn,qnm")))
5940 (clobber (reg:CC FLAGS_REG))]
5941 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5942 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5943 {
5944 switch (get_attr_type (insn))
5945 {
5946 case TYPE_INCDEC:
5947 if (operands[1] == const1_rtx)
5948 return "inc{b}\t%0";
5949 else
5950 {
5951 gcc_assert (operands[1] == constm1_rtx);
5952 return "dec{b}\t%0";
5953 }
5954
5955 default:
5956 if (x86_maybe_negate_const_int (&operands[1], QImode))
5957 return "sub{b}\t{%1, %0|%0, %1}";
5958
5959 return "add{b}\t{%1, %0|%0, %1}";
5960 }
5961 }
5962 [(set (attr "type")
5963 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5964 (const_string "incdec")
5965 (const_string "alu1")))
5966 (set (attr "memory")
5967 (if_then_else (match_operand 1 "memory_operand" "")
5968 (const_string "load")
5969 (const_string "none")))
5970 (set_attr "mode" "QI")])
5971
5972 ;; Convert lea to the lea pattern to avoid flags dependency.
5973 (define_split
5974 [(set (match_operand 0 "register_operand" "")
5975 (plus (match_operand 1 "register_operand" "")
5976 (match_operand 2 "nonmemory_operand" "")))
5977 (clobber (reg:CC FLAGS_REG))]
5978 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5979 [(const_int 0)]
5980 {
5981 rtx pat;
5982 enum machine_mode mode = GET_MODE (operands[0]);
5983
5984 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5985 may confuse gen_lowpart. */
5986 if (mode != Pmode)
5987 {
5988 operands[1] = gen_lowpart (Pmode, operands[1]);
5989 operands[2] = gen_lowpart (Pmode, operands[2]);
5990 }
5991
5992 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5993
5994 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5995 operands[0] = gen_lowpart (SImode, operands[0]);
5996
5997 if (TARGET_64BIT && mode != Pmode)
5998 pat = gen_rtx_SUBREG (SImode, pat, 0);
5999
6000 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6001 DONE;
6002 })
6003
6004 ;; Convert lea to the lea pattern to avoid flags dependency.
6005 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6006 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6007 (define_split
6008 [(set (match_operand:DI 0 "register_operand" "")
6009 (plus:DI (match_operand:DI 1 "register_operand" "")
6010 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6011 (clobber (reg:CC FLAGS_REG))]
6012 "TARGET_64BIT && reload_completed
6013 && true_regnum (operands[0]) != true_regnum (operands[1])"
6014 [(set (match_dup 0)
6015 (plus:DI (match_dup 1) (match_dup 2)))])
6016
6017 ;; Convert lea to the lea pattern to avoid flags dependency.
6018 (define_split
6019 [(set (match_operand:DI 0 "register_operand" "")
6020 (zero_extend:DI
6021 (plus:SI (match_operand:SI 1 "register_operand" "")
6022 (match_operand:SI 2 "nonmemory_operand" ""))))
6023 (clobber (reg:CC FLAGS_REG))]
6024 "TARGET_64BIT && reload_completed
6025 && ix86_lea_for_add_ok (insn, operands)"
6026 [(set (match_dup 0)
6027 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6028 {
6029 operands[1] = gen_lowpart (DImode, operands[1]);
6030 operands[2] = gen_lowpart (DImode, operands[2]);
6031 })
6032
6033 (define_insn "*add<mode>_2"
6034 [(set (reg FLAGS_REG)
6035 (compare
6036 (plus:SWI
6037 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6038 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6039 (const_int 0)))
6040 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6041 (plus:SWI (match_dup 1) (match_dup 2)))]
6042 "ix86_match_ccmode (insn, CCGOCmode)
6043 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6044 {
6045 switch (get_attr_type (insn))
6046 {
6047 case TYPE_INCDEC:
6048 if (operands[2] == const1_rtx)
6049 return "inc{<imodesuffix>}\t%0";
6050 else
6051 {
6052 gcc_assert (operands[2] == constm1_rtx);
6053 return "dec{<imodesuffix>}\t%0";
6054 }
6055
6056 default:
6057 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6058 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6059
6060 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6061 }
6062 }
6063 [(set (attr "type")
6064 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6065 (const_string "incdec")
6066 (const_string "alu")))
6067 (set (attr "length_immediate")
6068 (if_then_else
6069 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6070 (const_string "1")
6071 (const_string "*")))
6072 (set_attr "mode" "<MODE>")])
6073
6074 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6075 (define_insn "*addsi_2_zext"
6076 [(set (reg FLAGS_REG)
6077 (compare
6078 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6079 (match_operand:SI 2 "general_operand" "g"))
6080 (const_int 0)))
6081 (set (match_operand:DI 0 "register_operand" "=r")
6082 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6083 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6084 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6085 {
6086 switch (get_attr_type (insn))
6087 {
6088 case TYPE_INCDEC:
6089 if (operands[2] == const1_rtx)
6090 return "inc{l}\t%k0";
6091 else
6092 {
6093 gcc_assert (operands[2] == constm1_rtx);
6094 return "dec{l}\t%k0";
6095 }
6096
6097 default:
6098 if (x86_maybe_negate_const_int (&operands[2], SImode))
6099 return "sub{l}\t{%2, %k0|%k0, %2}";
6100
6101 return "add{l}\t{%2, %k0|%k0, %2}";
6102 }
6103 }
6104 [(set (attr "type")
6105 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6106 (const_string "incdec")
6107 (const_string "alu")))
6108 (set (attr "length_immediate")
6109 (if_then_else
6110 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6111 (const_string "1")
6112 (const_string "*")))
6113 (set_attr "mode" "SI")])
6114
6115 (define_insn "*add<mode>_3"
6116 [(set (reg FLAGS_REG)
6117 (compare
6118 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6119 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6120 (clobber (match_scratch:SWI 0 "=<r>"))]
6121 "ix86_match_ccmode (insn, CCZmode)
6122 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6123 {
6124 switch (get_attr_type (insn))
6125 {
6126 case TYPE_INCDEC:
6127 if (operands[2] == const1_rtx)
6128 return "inc{<imodesuffix>}\t%0";
6129 else
6130 {
6131 gcc_assert (operands[2] == constm1_rtx);
6132 return "dec{<imodesuffix>}\t%0";
6133 }
6134
6135 default:
6136 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6137 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6138
6139 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6140 }
6141 }
6142 [(set (attr "type")
6143 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6144 (const_string "incdec")
6145 (const_string "alu")))
6146 (set (attr "length_immediate")
6147 (if_then_else
6148 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6149 (const_string "1")
6150 (const_string "*")))
6151 (set_attr "mode" "<MODE>")])
6152
6153 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6154 (define_insn "*addsi_3_zext"
6155 [(set (reg FLAGS_REG)
6156 (compare
6157 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6158 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6159 (set (match_operand:DI 0 "register_operand" "=r")
6160 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6161 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6162 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6163 {
6164 switch (get_attr_type (insn))
6165 {
6166 case TYPE_INCDEC:
6167 if (operands[2] == const1_rtx)
6168 return "inc{l}\t%k0";
6169 else
6170 {
6171 gcc_assert (operands[2] == constm1_rtx);
6172 return "dec{l}\t%k0";
6173 }
6174
6175 default:
6176 if (x86_maybe_negate_const_int (&operands[2], SImode))
6177 return "sub{l}\t{%2, %k0|%k0, %2}";
6178
6179 return "add{l}\t{%2, %k0|%k0, %2}";
6180 }
6181 }
6182 [(set (attr "type")
6183 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6184 (const_string "incdec")
6185 (const_string "alu")))
6186 (set (attr "length_immediate")
6187 (if_then_else
6188 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6189 (const_string "1")
6190 (const_string "*")))
6191 (set_attr "mode" "SI")])
6192
6193 ; For comparisons against 1, -1 and 128, we may generate better code
6194 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6195 ; is matched then. We can't accept general immediate, because for
6196 ; case of overflows, the result is messed up.
6197 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6198 ; only for comparisons not depending on it.
6199
6200 (define_insn "*adddi_4"
6201 [(set (reg FLAGS_REG)
6202 (compare
6203 (match_operand:DI 1 "nonimmediate_operand" "0")
6204 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6205 (clobber (match_scratch:DI 0 "=rm"))]
6206 "TARGET_64BIT
6207 && ix86_match_ccmode (insn, CCGCmode)"
6208 {
6209 switch (get_attr_type (insn))
6210 {
6211 case TYPE_INCDEC:
6212 if (operands[2] == constm1_rtx)
6213 return "inc{q}\t%0";
6214 else
6215 {
6216 gcc_assert (operands[2] == const1_rtx);
6217 return "dec{q}\t%0";
6218 }
6219
6220 default:
6221 if (x86_maybe_negate_const_int (&operands[2], DImode))
6222 return "add{q}\t{%2, %0|%0, %2}";
6223
6224 return "sub{q}\t{%2, %0|%0, %2}";
6225 }
6226 }
6227 [(set (attr "type")
6228 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6229 (const_string "incdec")
6230 (const_string "alu")))
6231 (set (attr "length_immediate")
6232 (if_then_else
6233 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6234 (const_string "1")
6235 (const_string "*")))
6236 (set_attr "mode" "DI")])
6237
6238 ; For comparisons against 1, -1 and 128, we may generate better code
6239 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6240 ; is matched then. We can't accept general immediate, because for
6241 ; case of overflows, the result is messed up.
6242 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6243 ; only for comparisons not depending on it.
6244
6245 (define_insn "*add<mode>_4"
6246 [(set (reg FLAGS_REG)
6247 (compare
6248 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6249 (match_operand:SWI124 2 "const_int_operand" "n")))
6250 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6251 "ix86_match_ccmode (insn, CCGCmode)"
6252 {
6253 switch (get_attr_type (insn))
6254 {
6255 case TYPE_INCDEC:
6256 if (operands[2] == constm1_rtx)
6257 return "inc{<imodesuffix>}\t%0";
6258 else
6259 {
6260 gcc_assert (operands[2] == const1_rtx);
6261 return "dec{<imodesuffix>}\t%0";
6262 }
6263
6264 default:
6265 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6266 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6267
6268 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6269 }
6270 }
6271 [(set (attr "type")
6272 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6273 (const_string "incdec")
6274 (const_string "alu")))
6275 (set (attr "length_immediate")
6276 (if_then_else
6277 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6278 (const_string "1")
6279 (const_string "*")))
6280 (set_attr "mode" "<MODE>")])
6281
6282 (define_insn "*add<mode>_5"
6283 [(set (reg FLAGS_REG)
6284 (compare
6285 (plus:SWI
6286 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6287 (match_operand:SWI 2 "<general_operand>" "<g>"))
6288 (const_int 0)))
6289 (clobber (match_scratch:SWI 0 "=<r>"))]
6290 "ix86_match_ccmode (insn, CCGOCmode)
6291 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6292 {
6293 switch (get_attr_type (insn))
6294 {
6295 case TYPE_INCDEC:
6296 if (operands[2] == const1_rtx)
6297 return "inc{<imodesuffix>}\t%0";
6298 else
6299 {
6300 gcc_assert (operands[2] == constm1_rtx);
6301 return "dec{<imodesuffix>}\t%0";
6302 }
6303
6304 default:
6305 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6306 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6307
6308 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6309 }
6310 }
6311 [(set (attr "type")
6312 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6313 (const_string "incdec")
6314 (const_string "alu")))
6315 (set (attr "length_immediate")
6316 (if_then_else
6317 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6318 (const_string "1")
6319 (const_string "*")))
6320 (set_attr "mode" "<MODE>")])
6321
6322 (define_insn "*addqi_ext_1_rex64"
6323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6324 (const_int 8)
6325 (const_int 8))
6326 (plus:SI
6327 (zero_extract:SI
6328 (match_operand 1 "ext_register_operand" "0")
6329 (const_int 8)
6330 (const_int 8))
6331 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6332 (clobber (reg:CC FLAGS_REG))]
6333 "TARGET_64BIT"
6334 {
6335 switch (get_attr_type (insn))
6336 {
6337 case TYPE_INCDEC:
6338 if (operands[2] == const1_rtx)
6339 return "inc{b}\t%h0";
6340 else
6341 {
6342 gcc_assert (operands[2] == constm1_rtx);
6343 return "dec{b}\t%h0";
6344 }
6345
6346 default:
6347 return "add{b}\t{%2, %h0|%h0, %2}";
6348 }
6349 }
6350 [(set (attr "type")
6351 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352 (const_string "incdec")
6353 (const_string "alu")))
6354 (set_attr "modrm" "1")
6355 (set_attr "mode" "QI")])
6356
6357 (define_insn "addqi_ext_1"
6358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359 (const_int 8)
6360 (const_int 8))
6361 (plus:SI
6362 (zero_extract:SI
6363 (match_operand 1 "ext_register_operand" "0")
6364 (const_int 8)
6365 (const_int 8))
6366 (match_operand:QI 2 "general_operand" "Qmn")))
6367 (clobber (reg:CC FLAGS_REG))]
6368 "!TARGET_64BIT"
6369 {
6370 switch (get_attr_type (insn))
6371 {
6372 case TYPE_INCDEC:
6373 if (operands[2] == const1_rtx)
6374 return "inc{b}\t%h0";
6375 else
6376 {
6377 gcc_assert (operands[2] == constm1_rtx);
6378 return "dec{b}\t%h0";
6379 }
6380
6381 default:
6382 return "add{b}\t{%2, %h0|%h0, %2}";
6383 }
6384 }
6385 [(set (attr "type")
6386 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6387 (const_string "incdec")
6388 (const_string "alu")))
6389 (set_attr "modrm" "1")
6390 (set_attr "mode" "QI")])
6391
6392 (define_insn "*addqi_ext_2"
6393 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6394 (const_int 8)
6395 (const_int 8))
6396 (plus:SI
6397 (zero_extract:SI
6398 (match_operand 1 "ext_register_operand" "%0")
6399 (const_int 8)
6400 (const_int 8))
6401 (zero_extract:SI
6402 (match_operand 2 "ext_register_operand" "Q")
6403 (const_int 8)
6404 (const_int 8))))
6405 (clobber (reg:CC FLAGS_REG))]
6406 ""
6407 "add{b}\t{%h2, %h0|%h0, %h2}"
6408 [(set_attr "type" "alu")
6409 (set_attr "mode" "QI")])
6410
6411 ;; The lea patterns for non-Pmodes needs to be matched by
6412 ;; several insns converted to real lea by splitters.
6413
6414 (define_insn_and_split "*lea_general_1"
6415 [(set (match_operand 0 "register_operand" "=r")
6416 (plus (plus (match_operand 1 "index_register_operand" "l")
6417 (match_operand 2 "register_operand" "r"))
6418 (match_operand 3 "immediate_operand" "i")))]
6419 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6420 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6421 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6423 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6424 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6425 || GET_MODE (operands[3]) == VOIDmode)"
6426 "#"
6427 "&& reload_completed"
6428 [(const_int 0)]
6429 {
6430 rtx pat;
6431 operands[0] = gen_lowpart (SImode, operands[0]);
6432 operands[1] = gen_lowpart (Pmode, operands[1]);
6433 operands[2] = gen_lowpart (Pmode, operands[2]);
6434 operands[3] = gen_lowpart (Pmode, operands[3]);
6435 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6436 operands[3]);
6437 if (Pmode != SImode)
6438 pat = gen_rtx_SUBREG (SImode, pat, 0);
6439 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6440 DONE;
6441 }
6442 [(set_attr "type" "lea")
6443 (set_attr "mode" "SI")])
6444
6445 (define_insn_and_split "*lea_general_1_zext"
6446 [(set (match_operand:DI 0 "register_operand" "=r")
6447 (zero_extend:DI
6448 (plus:SI (plus:SI
6449 (match_operand:SI 1 "index_register_operand" "l")
6450 (match_operand:SI 2 "register_operand" "r"))
6451 (match_operand:SI 3 "immediate_operand" "i"))))]
6452 "TARGET_64BIT"
6453 "#"
6454 "&& reload_completed"
6455 [(set (match_dup 0)
6456 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6457 (match_dup 2))
6458 (match_dup 3)) 0)))]
6459 {
6460 operands[1] = gen_lowpart (Pmode, operands[1]);
6461 operands[2] = gen_lowpart (Pmode, operands[2]);
6462 operands[3] = gen_lowpart (Pmode, operands[3]);
6463 }
6464 [(set_attr "type" "lea")
6465 (set_attr "mode" "SI")])
6466
6467 (define_insn_and_split "*lea_general_2"
6468 [(set (match_operand 0 "register_operand" "=r")
6469 (plus (mult (match_operand 1 "index_register_operand" "l")
6470 (match_operand 2 "const248_operand" "i"))
6471 (match_operand 3 "nonmemory_operand" "ri")))]
6472 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6473 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6474 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6475 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6476 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6477 || GET_MODE (operands[3]) == VOIDmode)"
6478 "#"
6479 "&& reload_completed"
6480 [(const_int 0)]
6481 {
6482 rtx pat;
6483 operands[0] = gen_lowpart (SImode, operands[0]);
6484 operands[1] = gen_lowpart (Pmode, operands[1]);
6485 operands[3] = gen_lowpart (Pmode, operands[3]);
6486 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6487 operands[3]);
6488 if (Pmode != SImode)
6489 pat = gen_rtx_SUBREG (SImode, pat, 0);
6490 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6491 DONE;
6492 }
6493 [(set_attr "type" "lea")
6494 (set_attr "mode" "SI")])
6495
6496 (define_insn_and_split "*lea_general_2_zext"
6497 [(set (match_operand:DI 0 "register_operand" "=r")
6498 (zero_extend:DI
6499 (plus:SI (mult:SI
6500 (match_operand:SI 1 "index_register_operand" "l")
6501 (match_operand:SI 2 "const248_operand" "n"))
6502 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6503 "TARGET_64BIT"
6504 "#"
6505 "&& reload_completed"
6506 [(set (match_dup 0)
6507 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6508 (match_dup 2))
6509 (match_dup 3)) 0)))]
6510 {
6511 operands[1] = gen_lowpart (Pmode, operands[1]);
6512 operands[3] = gen_lowpart (Pmode, operands[3]);
6513 }
6514 [(set_attr "type" "lea")
6515 (set_attr "mode" "SI")])
6516
6517 (define_insn_and_split "*lea_general_3"
6518 [(set (match_operand 0 "register_operand" "=r")
6519 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6520 (match_operand 2 "const248_operand" "i"))
6521 (match_operand 3 "register_operand" "r"))
6522 (match_operand 4 "immediate_operand" "i")))]
6523 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6524 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6525 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6526 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6527 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6528 "#"
6529 "&& reload_completed"
6530 [(const_int 0)]
6531 {
6532 rtx pat;
6533 operands[0] = gen_lowpart (SImode, operands[0]);
6534 operands[1] = gen_lowpart (Pmode, operands[1]);
6535 operands[3] = gen_lowpart (Pmode, operands[3]);
6536 operands[4] = gen_lowpart (Pmode, operands[4]);
6537 pat = gen_rtx_PLUS (Pmode,
6538 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6539 operands[2]),
6540 operands[3]),
6541 operands[4]);
6542 if (Pmode != SImode)
6543 pat = gen_rtx_SUBREG (SImode, pat, 0);
6544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6545 DONE;
6546 }
6547 [(set_attr "type" "lea")
6548 (set_attr "mode" "SI")])
6549
6550 (define_insn_and_split "*lea_general_3_zext"
6551 [(set (match_operand:DI 0 "register_operand" "=r")
6552 (zero_extend:DI
6553 (plus:SI (plus:SI
6554 (mult:SI
6555 (match_operand:SI 1 "index_register_operand" "l")
6556 (match_operand:SI 2 "const248_operand" "n"))
6557 (match_operand:SI 3 "register_operand" "r"))
6558 (match_operand:SI 4 "immediate_operand" "i"))))]
6559 "TARGET_64BIT"
6560 "#"
6561 "&& reload_completed"
6562 [(set (match_dup 0)
6563 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6564 (match_dup 2))
6565 (match_dup 3))
6566 (match_dup 4)) 0)))]
6567 {
6568 operands[1] = gen_lowpart (Pmode, operands[1]);
6569 operands[3] = gen_lowpart (Pmode, operands[3]);
6570 operands[4] = gen_lowpart (Pmode, operands[4]);
6571 }
6572 [(set_attr "type" "lea")
6573 (set_attr "mode" "SI")])
6574 \f
6575 ;; Subtract instructions
6576
6577 (define_expand "sub<mode>3"
6578 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6579 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6580 (match_operand:SDWIM 2 "<general_operand>" "")))]
6581 ""
6582 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6583
6584 (define_insn_and_split "*sub<dwi>3_doubleword"
6585 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6586 (minus:<DWI>
6587 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6588 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6589 (clobber (reg:CC FLAGS_REG))]
6590 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6591 "#"
6592 "reload_completed"
6593 [(parallel [(set (reg:CC FLAGS_REG)
6594 (compare:CC (match_dup 1) (match_dup 2)))
6595 (set (match_dup 0)
6596 (minus:DWIH (match_dup 1) (match_dup 2)))])
6597 (parallel [(set (match_dup 3)
6598 (minus:DWIH
6599 (match_dup 4)
6600 (plus:DWIH
6601 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6602 (match_dup 5))))
6603 (clobber (reg:CC FLAGS_REG))])]
6604 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6605
6606 (define_insn "*sub<mode>_1"
6607 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608 (minus:SWI
6609 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6610 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6613 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "mode" "<MODE>")])
6616
6617 (define_insn "*subsi_1_zext"
6618 [(set (match_operand:DI 0 "register_operand" "=r")
6619 (zero_extend:DI
6620 (minus:SI (match_operand:SI 1 "register_operand" "0")
6621 (match_operand:SI 2 "general_operand" "g"))))
6622 (clobber (reg:CC FLAGS_REG))]
6623 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624 "sub{l}\t{%2, %k0|%k0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "SI")])
6627
6628 (define_insn "*subqi_1_slp"
6629 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6630 (minus:QI (match_dup 0)
6631 (match_operand:QI 1 "general_operand" "qn,qm")))
6632 (clobber (reg:CC FLAGS_REG))]
6633 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6634 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6635 "sub{b}\t{%1, %0|%0, %1}"
6636 [(set_attr "type" "alu1")
6637 (set_attr "mode" "QI")])
6638
6639 (define_insn "*sub<mode>_2"
6640 [(set (reg FLAGS_REG)
6641 (compare
6642 (minus:SWI
6643 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6645 (const_int 0)))
6646 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6647 (minus:SWI (match_dup 1) (match_dup 2)))]
6648 "ix86_match_ccmode (insn, CCGOCmode)
6649 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "<MODE>")])
6653
6654 (define_insn "*subsi_2_zext"
6655 [(set (reg FLAGS_REG)
6656 (compare
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
6658 (match_operand:SI 2 "general_operand" "g"))
6659 (const_int 0)))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6661 (zero_extend:DI
6662 (minus:SI (match_dup 1)
6663 (match_dup 2))))]
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666 "sub{l}\t{%2, %k0|%k0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6669
6670 (define_insn "*sub<mode>_3"
6671 [(set (reg FLAGS_REG)
6672 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6674 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6675 (minus:SWI (match_dup 1) (match_dup 2)))]
6676 "ix86_match_ccmode (insn, CCmode)
6677 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6678 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "<MODE>")])
6681
6682 (define_insn "*subsi_3_zext"
6683 [(set (reg FLAGS_REG)
6684 (compare (match_operand:SI 1 "register_operand" "0")
6685 (match_operand:SI 2 "general_operand" "g")))
6686 (set (match_operand:DI 0 "register_operand" "=r")
6687 (zero_extend:DI
6688 (minus:SI (match_dup 1)
6689 (match_dup 2))))]
6690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692 "sub{l}\t{%2, %1|%1, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "mode" "SI")])
6695 \f
6696 ;; Add with carry and subtract with borrow
6697
6698 (define_expand "<plusminus_insn><mode>3_carry"
6699 [(parallel
6700 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6701 (plusminus:SWI
6702 (match_operand:SWI 1 "nonimmediate_operand" "")
6703 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6704 [(match_operand 3 "flags_reg_operand" "")
6705 (const_int 0)])
6706 (match_operand:SWI 2 "<general_operand>" ""))))
6707 (clobber (reg:CC FLAGS_REG))])]
6708 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6709
6710 (define_insn "*<plusminus_insn><mode>3_carry"
6711 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6712 (plusminus:SWI
6713 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6714 (plus:SWI
6715 (match_operator 3 "ix86_carry_flag_operator"
6716 [(reg FLAGS_REG) (const_int 0)])
6717 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6718 (clobber (reg:CC FLAGS_REG))]
6719 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6720 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6721 [(set_attr "type" "alu")
6722 (set_attr "use_carry" "1")
6723 (set_attr "pent_pair" "pu")
6724 (set_attr "mode" "<MODE>")])
6725
6726 (define_insn "*addsi3_carry_zext"
6727 [(set (match_operand:DI 0 "register_operand" "=r")
6728 (zero_extend:DI
6729 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6730 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6731 [(reg FLAGS_REG) (const_int 0)])
6732 (match_operand:SI 2 "general_operand" "g")))))
6733 (clobber (reg:CC FLAGS_REG))]
6734 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6735 "adc{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "use_carry" "1")
6738 (set_attr "pent_pair" "pu")
6739 (set_attr "mode" "SI")])
6740
6741 (define_insn "*subsi3_carry_zext"
6742 [(set (match_operand:DI 0 "register_operand" "=r")
6743 (zero_extend:DI
6744 (minus:SI (match_operand:SI 1 "register_operand" "0")
6745 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6746 [(reg FLAGS_REG) (const_int 0)])
6747 (match_operand:SI 2 "general_operand" "g")))))
6748 (clobber (reg:CC FLAGS_REG))]
6749 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750 "sbb{l}\t{%2, %k0|%k0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "pent_pair" "pu")
6753 (set_attr "mode" "SI")])
6754 \f
6755 ;; Overflow setting add and subtract instructions
6756
6757 (define_insn "*add<mode>3_cconly_overflow"
6758 [(set (reg:CCC FLAGS_REG)
6759 (compare:CCC
6760 (plus:SWI
6761 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6762 (match_operand:SWI 2 "<general_operand>" "<g>"))
6763 (match_dup 1)))
6764 (clobber (match_scratch:SWI 0 "=<r>"))]
6765 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6766 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6767 [(set_attr "type" "alu")
6768 (set_attr "mode" "<MODE>")])
6769
6770 (define_insn "*sub<mode>3_cconly_overflow"
6771 [(set (reg:CCC FLAGS_REG)
6772 (compare:CCC
6773 (minus:SWI
6774 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6775 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6776 (match_dup 0)))]
6777 ""
6778 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6779 [(set_attr "type" "icmp")
6780 (set_attr "mode" "<MODE>")])
6781
6782 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6783 [(set (reg:CCC FLAGS_REG)
6784 (compare:CCC
6785 (plusminus:SWI
6786 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6787 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6788 (match_dup 1)))
6789 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6790 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6791 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6792 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6793 [(set_attr "type" "alu")
6794 (set_attr "mode" "<MODE>")])
6795
6796 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6797 [(set (reg:CCC FLAGS_REG)
6798 (compare:CCC
6799 (plusminus:SI
6800 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6801 (match_operand:SI 2 "general_operand" "g"))
6802 (match_dup 1)))
6803 (set (match_operand:DI 0 "register_operand" "=r")
6804 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6805 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6806 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6807 [(set_attr "type" "alu")
6808 (set_attr "mode" "SI")])
6809
6810 ;; The patterns that match these are at the end of this file.
6811
6812 (define_expand "<plusminus_insn>xf3"
6813 [(set (match_operand:XF 0 "register_operand" "")
6814 (plusminus:XF
6815 (match_operand:XF 1 "register_operand" "")
6816 (match_operand:XF 2 "register_operand" "")))]
6817 "TARGET_80387")
6818
6819 (define_expand "<plusminus_insn><mode>3"
6820 [(set (match_operand:MODEF 0 "register_operand" "")
6821 (plusminus:MODEF
6822 (match_operand:MODEF 1 "register_operand" "")
6823 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6824 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6825 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6826 \f
6827 ;; Multiply instructions
6828
6829 (define_expand "mul<mode>3"
6830 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6831 (mult:SWIM248
6832 (match_operand:SWIM248 1 "register_operand" "")
6833 (match_operand:SWIM248 2 "<general_operand>" "")))
6834 (clobber (reg:CC FLAGS_REG))])])
6835
6836 (define_expand "mulqi3"
6837 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6838 (mult:QI
6839 (match_operand:QI 1 "register_operand" "")
6840 (match_operand:QI 2 "nonimmediate_operand" "")))
6841 (clobber (reg:CC FLAGS_REG))])]
6842 "TARGET_QIMODE_MATH")
6843
6844 ;; On AMDFAM10
6845 ;; IMUL reg32/64, reg32/64, imm8 Direct
6846 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6847 ;; IMUL reg32/64, reg32/64, imm32 Direct
6848 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6849 ;; IMUL reg32/64, reg32/64 Direct
6850 ;; IMUL reg32/64, mem32/64 Direct
6851
6852 (define_insn "*mul<mode>3_1"
6853 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6854 (mult:SWI48
6855 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6856 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6857 (clobber (reg:CC FLAGS_REG))]
6858 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6859 "@
6860 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6861 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6862 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6863 [(set_attr "type" "imul")
6864 (set_attr "prefix_0f" "0,0,1")
6865 (set (attr "athlon_decode")
6866 (cond [(eq_attr "cpu" "athlon")
6867 (const_string "vector")
6868 (eq_attr "alternative" "1")
6869 (const_string "vector")
6870 (and (eq_attr "alternative" "2")
6871 (match_operand 1 "memory_operand" ""))
6872 (const_string "vector")]
6873 (const_string "direct")))
6874 (set (attr "amdfam10_decode")
6875 (cond [(and (eq_attr "alternative" "0,1")
6876 (match_operand 1 "memory_operand" ""))
6877 (const_string "vector")]
6878 (const_string "direct")))
6879 (set_attr "mode" "<MODE>")])
6880
6881 (define_insn "*mulsi3_1_zext"
6882 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6883 (zero_extend:DI
6884 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6885 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6886 (clobber (reg:CC FLAGS_REG))]
6887 "TARGET_64BIT
6888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889 "@
6890 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6891 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6892 imul{l}\t{%2, %k0|%k0, %2}"
6893 [(set_attr "type" "imul")
6894 (set_attr "prefix_0f" "0,0,1")
6895 (set (attr "athlon_decode")
6896 (cond [(eq_attr "cpu" "athlon")
6897 (const_string "vector")
6898 (eq_attr "alternative" "1")
6899 (const_string "vector")
6900 (and (eq_attr "alternative" "2")
6901 (match_operand 1 "memory_operand" ""))
6902 (const_string "vector")]
6903 (const_string "direct")))
6904 (set (attr "amdfam10_decode")
6905 (cond [(and (eq_attr "alternative" "0,1")
6906 (match_operand 1 "memory_operand" ""))
6907 (const_string "vector")]
6908 (const_string "direct")))
6909 (set_attr "mode" "SI")])
6910
6911 ;; On AMDFAM10
6912 ;; IMUL reg16, reg16, imm8 VectorPath
6913 ;; IMUL reg16, mem16, imm8 VectorPath
6914 ;; IMUL reg16, reg16, imm16 VectorPath
6915 ;; IMUL reg16, mem16, imm16 VectorPath
6916 ;; IMUL reg16, reg16 Direct
6917 ;; IMUL reg16, mem16 Direct
6918
6919 (define_insn "*mulhi3_1"
6920 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6921 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6922 (match_operand:HI 2 "general_operand" "K,n,mr")))
6923 (clobber (reg:CC FLAGS_REG))]
6924 "TARGET_HIMODE_MATH
6925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6926 "@
6927 imul{w}\t{%2, %1, %0|%0, %1, %2}
6928 imul{w}\t{%2, %1, %0|%0, %1, %2}
6929 imul{w}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "imul")
6931 (set_attr "prefix_0f" "0,0,1")
6932 (set (attr "athlon_decode")
6933 (cond [(eq_attr "cpu" "athlon")
6934 (const_string "vector")
6935 (eq_attr "alternative" "1,2")
6936 (const_string "vector")]
6937 (const_string "direct")))
6938 (set (attr "amdfam10_decode")
6939 (cond [(eq_attr "alternative" "0,1")
6940 (const_string "vector")]
6941 (const_string "direct")))
6942 (set_attr "mode" "HI")])
6943
6944 ;;On AMDFAM10
6945 ;; MUL reg8 Direct
6946 ;; MUL mem8 Direct
6947
6948 (define_insn "*mulqi3_1"
6949 [(set (match_operand:QI 0 "register_operand" "=a")
6950 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6951 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6952 (clobber (reg:CC FLAGS_REG))]
6953 "TARGET_QIMODE_MATH
6954 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6955 "mul{b}\t%2"
6956 [(set_attr "type" "imul")
6957 (set_attr "length_immediate" "0")
6958 (set (attr "athlon_decode")
6959 (if_then_else (eq_attr "cpu" "athlon")
6960 (const_string "vector")
6961 (const_string "direct")))
6962 (set_attr "amdfam10_decode" "direct")
6963 (set_attr "mode" "QI")])
6964
6965 (define_expand "<u>mul<mode><dwi>3"
6966 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6967 (mult:<DWI>
6968 (any_extend:<DWI>
6969 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6970 (any_extend:<DWI>
6971 (match_operand:DWIH 2 "register_operand" ""))))
6972 (clobber (reg:CC FLAGS_REG))])])
6973
6974 (define_expand "<u>mulqihi3"
6975 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6976 (mult:HI
6977 (any_extend:HI
6978 (match_operand:QI 1 "nonimmediate_operand" ""))
6979 (any_extend:HI
6980 (match_operand:QI 2 "register_operand" ""))))
6981 (clobber (reg:CC FLAGS_REG))])]
6982 "TARGET_QIMODE_MATH")
6983
6984 (define_insn "*<u>mul<mode><dwi>3_1"
6985 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6986 (mult:<DWI>
6987 (any_extend:<DWI>
6988 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6989 (any_extend:<DWI>
6990 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6991 (clobber (reg:CC FLAGS_REG))]
6992 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6993 "<sgnprefix>mul{<imodesuffix>}\t%2"
6994 [(set_attr "type" "imul")
6995 (set_attr "length_immediate" "0")
6996 (set (attr "athlon_decode")
6997 (if_then_else (eq_attr "cpu" "athlon")
6998 (const_string "vector")
6999 (const_string "double")))
7000 (set_attr "amdfam10_decode" "double")
7001 (set_attr "mode" "<MODE>")])
7002
7003 (define_insn "*<u>mulqihi3_1"
7004 [(set (match_operand:HI 0 "register_operand" "=a")
7005 (mult:HI
7006 (any_extend:HI
7007 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7008 (any_extend:HI
7009 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7010 (clobber (reg:CC FLAGS_REG))]
7011 "TARGET_QIMODE_MATH
7012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7013 "<sgnprefix>mul{b}\t%2"
7014 [(set_attr "type" "imul")
7015 (set_attr "length_immediate" "0")
7016 (set (attr "athlon_decode")
7017 (if_then_else (eq_attr "cpu" "athlon")
7018 (const_string "vector")
7019 (const_string "direct")))
7020 (set_attr "amdfam10_decode" "direct")
7021 (set_attr "mode" "QI")])
7022
7023 (define_expand "<s>mul<mode>3_highpart"
7024 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7025 (truncate:SWI48
7026 (lshiftrt:<DWI>
7027 (mult:<DWI>
7028 (any_extend:<DWI>
7029 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7030 (any_extend:<DWI>
7031 (match_operand:SWI48 2 "register_operand" "")))
7032 (match_dup 4))))
7033 (clobber (match_scratch:SWI48 3 ""))
7034 (clobber (reg:CC FLAGS_REG))])]
7035 ""
7036 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7037
7038 (define_insn "*<s>muldi3_highpart_1"
7039 [(set (match_operand:DI 0 "register_operand" "=d")
7040 (truncate:DI
7041 (lshiftrt:TI
7042 (mult:TI
7043 (any_extend:TI
7044 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7045 (any_extend:TI
7046 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7047 (const_int 64))))
7048 (clobber (match_scratch:DI 3 "=1"))
7049 (clobber (reg:CC FLAGS_REG))]
7050 "TARGET_64BIT
7051 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7052 "<sgnprefix>mul{q}\t%2"
7053 [(set_attr "type" "imul")
7054 (set_attr "length_immediate" "0")
7055 (set (attr "athlon_decode")
7056 (if_then_else (eq_attr "cpu" "athlon")
7057 (const_string "vector")
7058 (const_string "double")))
7059 (set_attr "amdfam10_decode" "double")
7060 (set_attr "mode" "DI")])
7061
7062 (define_insn "*<s>mulsi3_highpart_1"
7063 [(set (match_operand:SI 0 "register_operand" "=d")
7064 (truncate:SI
7065 (lshiftrt:DI
7066 (mult:DI
7067 (any_extend:DI
7068 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7069 (any_extend:DI
7070 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7071 (const_int 32))))
7072 (clobber (match_scratch:SI 3 "=1"))
7073 (clobber (reg:CC FLAGS_REG))]
7074 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7075 "<sgnprefix>mul{l}\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 "double")))
7082 (set_attr "amdfam10_decode" "double")
7083 (set_attr "mode" "SI")])
7084
7085 (define_insn "*<s>mulsi3_highpart_zext"
7086 [(set (match_operand:DI 0 "register_operand" "=d")
7087 (zero_extend:DI (truncate:SI
7088 (lshiftrt:DI
7089 (mult:DI (any_extend:DI
7090 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7091 (any_extend:DI
7092 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7093 (const_int 32)))))
7094 (clobber (match_scratch:SI 3 "=1"))
7095 (clobber (reg:CC FLAGS_REG))]
7096 "TARGET_64BIT
7097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7098 "<sgnprefix>mul{l}\t%2"
7099 [(set_attr "type" "imul")
7100 (set_attr "length_immediate" "0")
7101 (set (attr "athlon_decode")
7102 (if_then_else (eq_attr "cpu" "athlon")
7103 (const_string "vector")
7104 (const_string "double")))
7105 (set_attr "amdfam10_decode" "double")
7106 (set_attr "mode" "SI")])
7107
7108 ;; The patterns that match these are at the end of this file.
7109
7110 (define_expand "mulxf3"
7111 [(set (match_operand:XF 0 "register_operand" "")
7112 (mult:XF (match_operand:XF 1 "register_operand" "")
7113 (match_operand:XF 2 "register_operand" "")))]
7114 "TARGET_80387")
7115
7116 (define_expand "mul<mode>3"
7117 [(set (match_operand:MODEF 0 "register_operand" "")
7118 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7119 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7120 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7121 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7122 \f
7123 ;; Divide instructions
7124
7125 ;; The patterns that match these are at the end of this file.
7126
7127 (define_expand "divxf3"
7128 [(set (match_operand:XF 0 "register_operand" "")
7129 (div:XF (match_operand:XF 1 "register_operand" "")
7130 (match_operand:XF 2 "register_operand" "")))]
7131 "TARGET_80387")
7132
7133 (define_expand "divdf3"
7134 [(set (match_operand:DF 0 "register_operand" "")
7135 (div:DF (match_operand:DF 1 "register_operand" "")
7136 (match_operand:DF 2 "nonimmediate_operand" "")))]
7137 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7138 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7139
7140 (define_expand "divsf3"
7141 [(set (match_operand:SF 0 "register_operand" "")
7142 (div:SF (match_operand:SF 1 "register_operand" "")
7143 (match_operand:SF 2 "nonimmediate_operand" "")))]
7144 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7145 || TARGET_SSE_MATH"
7146 {
7147 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7148 && flag_finite_math_only && !flag_trapping_math
7149 && flag_unsafe_math_optimizations)
7150 {
7151 ix86_emit_swdivsf (operands[0], operands[1],
7152 operands[2], SFmode);
7153 DONE;
7154 }
7155 })
7156 \f
7157 ;; Divmod instructions.
7158
7159 (define_expand "divmod<mode>4"
7160 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7161 (div:SWIM248
7162 (match_operand:SWIM248 1 "register_operand" "")
7163 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7164 (set (match_operand:SWIM248 3 "register_operand" "")
7165 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7166 (clobber (reg:CC FLAGS_REG))])])
7167
7168 ;; Split with 8bit unsigned divide:
7169 ;; if (dividend an divisor are in [0-255])
7170 ;; use 8bit unsigned integer divide
7171 ;; else
7172 ;; use original integer divide
7173 (define_split
7174 [(set (match_operand:SWI48 0 "register_operand" "")
7175 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7176 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7177 (set (match_operand:SWI48 1 "register_operand" "")
7178 (mod:SWI48 (match_dup 2) (match_dup 3)))
7179 (clobber (reg:CC FLAGS_REG))]
7180 "TARGET_USE_8BIT_IDIV
7181 && TARGET_QIMODE_MATH
7182 && can_create_pseudo_p ()
7183 && !optimize_insn_for_size_p ()"
7184 [(const_int 0)]
7185 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7186
7187 (define_insn_and_split "divmod<mode>4_1"
7188 [(set (match_operand:SWI48 0 "register_operand" "=a")
7189 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7190 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7191 (set (match_operand:SWI48 1 "register_operand" "=&d")
7192 (mod:SWI48 (match_dup 2) (match_dup 3)))
7193 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7194 (clobber (reg:CC FLAGS_REG))]
7195 ""
7196 "#"
7197 "reload_completed"
7198 [(parallel [(set (match_dup 1)
7199 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7200 (clobber (reg:CC FLAGS_REG))])
7201 (parallel [(set (match_dup 0)
7202 (div:SWI48 (match_dup 2) (match_dup 3)))
7203 (set (match_dup 1)
7204 (mod:SWI48 (match_dup 2) (match_dup 3)))
7205 (use (match_dup 1))
7206 (clobber (reg:CC FLAGS_REG))])]
7207 {
7208 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7209
7210 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7211 operands[4] = operands[2];
7212 else
7213 {
7214 /* Avoid use of cltd in favor of a mov+shift. */
7215 emit_move_insn (operands[1], operands[2]);
7216 operands[4] = operands[1];
7217 }
7218 }
7219 [(set_attr "type" "multi")
7220 (set_attr "mode" "<MODE>")])
7221
7222 (define_insn_and_split "*divmod<mode>4"
7223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7224 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7225 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7226 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7227 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7228 (clobber (reg:CC FLAGS_REG))]
7229 ""
7230 "#"
7231 "reload_completed"
7232 [(parallel [(set (match_dup 1)
7233 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7234 (clobber (reg:CC FLAGS_REG))])
7235 (parallel [(set (match_dup 0)
7236 (div:SWIM248 (match_dup 2) (match_dup 3)))
7237 (set (match_dup 1)
7238 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7239 (use (match_dup 1))
7240 (clobber (reg:CC FLAGS_REG))])]
7241 {
7242 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7243
7244 if (<MODE>mode != HImode
7245 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7246 operands[4] = operands[2];
7247 else
7248 {
7249 /* Avoid use of cltd in favor of a mov+shift. */
7250 emit_move_insn (operands[1], operands[2]);
7251 operands[4] = operands[1];
7252 }
7253 }
7254 [(set_attr "type" "multi")
7255 (set_attr "mode" "<MODE>")])
7256
7257 (define_insn "*divmod<mode>4_noext"
7258 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7259 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7260 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7261 (set (match_operand:SWIM248 1 "register_operand" "=d")
7262 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7263 (use (match_operand:SWIM248 4 "register_operand" "1"))
7264 (clobber (reg:CC FLAGS_REG))]
7265 ""
7266 "idiv{<imodesuffix>}\t%3"
7267 [(set_attr "type" "idiv")
7268 (set_attr "mode" "<MODE>")])
7269
7270 (define_expand "divmodqi4"
7271 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7272 (div:QI
7273 (match_operand:QI 1 "register_operand" "")
7274 (match_operand:QI 2 "nonimmediate_operand" "")))
7275 (set (match_operand:QI 3 "register_operand" "")
7276 (mod:QI (match_dup 1) (match_dup 2)))
7277 (clobber (reg:CC FLAGS_REG))])]
7278 "TARGET_QIMODE_MATH"
7279 {
7280 rtx div, mod, insn;
7281 rtx tmp0, tmp1;
7282
7283 tmp0 = gen_reg_rtx (HImode);
7284 tmp1 = gen_reg_rtx (HImode);
7285
7286 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7287 in AX. */
7288 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7289 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7290
7291 /* Extract remainder from AH. */
7292 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7293 insn = emit_move_insn (operands[3], tmp1);
7294
7295 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7296 set_unique_reg_note (insn, REG_EQUAL, mod);
7297
7298 /* Extract quotient from AL. */
7299 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7300
7301 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7302 set_unique_reg_note (insn, REG_EQUAL, div);
7303
7304 DONE;
7305 })
7306
7307 ;; Divide AX by r/m8, with result stored in
7308 ;; AL <- Quotient
7309 ;; AH <- Remainder
7310 ;; Change div/mod to HImode and extend the second argument to HImode
7311 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7312 ;; combine may fail.
7313 (define_insn "divmodhiqi3"
7314 [(set (match_operand:HI 0 "register_operand" "=a")
7315 (ior:HI
7316 (ashift:HI
7317 (zero_extend:HI
7318 (truncate:QI
7319 (mod:HI (match_operand:HI 1 "register_operand" "0")
7320 (sign_extend:HI
7321 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7322 (const_int 8))
7323 (zero_extend:HI
7324 (truncate:QI
7325 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7326 (clobber (reg:CC FLAGS_REG))]
7327 "TARGET_QIMODE_MATH"
7328 "idiv{b}\t%2"
7329 [(set_attr "type" "idiv")
7330 (set_attr "mode" "QI")])
7331
7332 (define_expand "udivmod<mode>4"
7333 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7334 (udiv:SWIM248
7335 (match_operand:SWIM248 1 "register_operand" "")
7336 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7337 (set (match_operand:SWIM248 3 "register_operand" "")
7338 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7339 (clobber (reg:CC FLAGS_REG))])])
7340
7341 ;; Split with 8bit unsigned divide:
7342 ;; if (dividend an divisor are in [0-255])
7343 ;; use 8bit unsigned integer divide
7344 ;; else
7345 ;; use original integer divide
7346 (define_split
7347 [(set (match_operand:SWI48 0 "register_operand" "")
7348 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7349 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7350 (set (match_operand:SWI48 1 "register_operand" "")
7351 (umod:SWI48 (match_dup 2) (match_dup 3)))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "TARGET_USE_8BIT_IDIV
7354 && TARGET_QIMODE_MATH
7355 && can_create_pseudo_p ()
7356 && !optimize_insn_for_size_p ()"
7357 [(const_int 0)]
7358 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7359
7360 (define_insn_and_split "udivmod<mode>4_1"
7361 [(set (match_operand:SWI48 0 "register_operand" "=a")
7362 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7363 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7364 (set (match_operand:SWI48 1 "register_operand" "=&d")
7365 (umod:SWI48 (match_dup 2) (match_dup 3)))
7366 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7367 (clobber (reg:CC FLAGS_REG))]
7368 ""
7369 "#"
7370 "reload_completed"
7371 [(set (match_dup 1) (const_int 0))
7372 (parallel [(set (match_dup 0)
7373 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7374 (set (match_dup 1)
7375 (umod:SWI48 (match_dup 2) (match_dup 3)))
7376 (use (match_dup 1))
7377 (clobber (reg:CC FLAGS_REG))])]
7378 ""
7379 [(set_attr "type" "multi")
7380 (set_attr "mode" "<MODE>")])
7381
7382 (define_insn_and_split "*udivmod<mode>4"
7383 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7384 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7385 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7386 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7387 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7388 (clobber (reg:CC FLAGS_REG))]
7389 ""
7390 "#"
7391 "reload_completed"
7392 [(set (match_dup 1) (const_int 0))
7393 (parallel [(set (match_dup 0)
7394 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7395 (set (match_dup 1)
7396 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7397 (use (match_dup 1))
7398 (clobber (reg:CC FLAGS_REG))])]
7399 ""
7400 [(set_attr "type" "multi")
7401 (set_attr "mode" "<MODE>")])
7402
7403 (define_insn "*udivmod<mode>4_noext"
7404 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7405 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7406 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7407 (set (match_operand:SWIM248 1 "register_operand" "=d")
7408 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7409 (use (match_operand:SWIM248 4 "register_operand" "1"))
7410 (clobber (reg:CC FLAGS_REG))]
7411 ""
7412 "div{<imodesuffix>}\t%3"
7413 [(set_attr "type" "idiv")
7414 (set_attr "mode" "<MODE>")])
7415
7416 (define_expand "udivmodqi4"
7417 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7418 (udiv:QI
7419 (match_operand:QI 1 "register_operand" "")
7420 (match_operand:QI 2 "nonimmediate_operand" "")))
7421 (set (match_operand:QI 3 "register_operand" "")
7422 (umod:QI (match_dup 1) (match_dup 2)))
7423 (clobber (reg:CC FLAGS_REG))])]
7424 "TARGET_QIMODE_MATH"
7425 {
7426 rtx div, mod, insn;
7427 rtx tmp0, tmp1;
7428
7429 tmp0 = gen_reg_rtx (HImode);
7430 tmp1 = gen_reg_rtx (HImode);
7431
7432 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7433 in AX. */
7434 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7435 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7436
7437 /* Extract remainder from AH. */
7438 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7439 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7440 insn = emit_move_insn (operands[3], tmp1);
7441
7442 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7443 set_unique_reg_note (insn, REG_EQUAL, mod);
7444
7445 /* Extract quotient from AL. */
7446 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7447
7448 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7449 set_unique_reg_note (insn, REG_EQUAL, div);
7450
7451 DONE;
7452 })
7453
7454 (define_insn "udivmodhiqi3"
7455 [(set (match_operand:HI 0 "register_operand" "=a")
7456 (ior:HI
7457 (ashift:HI
7458 (zero_extend:HI
7459 (truncate:QI
7460 (mod:HI (match_operand:HI 1 "register_operand" "0")
7461 (zero_extend:HI
7462 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7463 (const_int 8))
7464 (zero_extend:HI
7465 (truncate:QI
7466 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7467 (clobber (reg:CC FLAGS_REG))]
7468 "TARGET_QIMODE_MATH"
7469 "div{b}\t%2"
7470 [(set_attr "type" "idiv")
7471 (set_attr "mode" "QI")])
7472
7473 ;; We cannot use div/idiv for double division, because it causes
7474 ;; "division by zero" on the overflow and that's not what we expect
7475 ;; from truncate. Because true (non truncating) double division is
7476 ;; never generated, we can't create this insn anyway.
7477 ;
7478 ;(define_insn ""
7479 ; [(set (match_operand:SI 0 "register_operand" "=a")
7480 ; (truncate:SI
7481 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7482 ; (zero_extend:DI
7483 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7484 ; (set (match_operand:SI 3 "register_operand" "=d")
7485 ; (truncate:SI
7486 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7487 ; (clobber (reg:CC FLAGS_REG))]
7488 ; ""
7489 ; "div{l}\t{%2, %0|%0, %2}"
7490 ; [(set_attr "type" "idiv")])
7491 \f
7492 ;;- Logical AND instructions
7493
7494 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7495 ;; Note that this excludes ah.
7496
7497 (define_expand "testsi_ccno_1"
7498 [(set (reg:CCNO FLAGS_REG)
7499 (compare:CCNO
7500 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7501 (match_operand:SI 1 "nonmemory_operand" ""))
7502 (const_int 0)))])
7503
7504 (define_expand "testqi_ccz_1"
7505 [(set (reg:CCZ FLAGS_REG)
7506 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7507 (match_operand:QI 1 "nonmemory_operand" ""))
7508 (const_int 0)))])
7509
7510 (define_expand "testdi_ccno_1"
7511 [(set (reg:CCNO FLAGS_REG)
7512 (compare:CCNO
7513 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7514 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7515 (const_int 0)))]
7516 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7517
7518 (define_insn "*testdi_1"
7519 [(set (reg FLAGS_REG)
7520 (compare
7521 (and:DI
7522 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7523 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7524 (const_int 0)))]
7525 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7526 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7527 "@
7528 test{l}\t{%k1, %k0|%k0, %k1}
7529 test{l}\t{%k1, %k0|%k0, %k1}
7530 test{q}\t{%1, %0|%0, %1}
7531 test{q}\t{%1, %0|%0, %1}
7532 test{q}\t{%1, %0|%0, %1}"
7533 [(set_attr "type" "test")
7534 (set_attr "modrm" "0,1,0,1,1")
7535 (set_attr "mode" "SI,SI,DI,DI,DI")])
7536
7537 (define_insn "*testqi_1_maybe_si"
7538 [(set (reg FLAGS_REG)
7539 (compare
7540 (and:QI
7541 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7542 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7543 (const_int 0)))]
7544 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7545 && ix86_match_ccmode (insn,
7546 CONST_INT_P (operands[1])
7547 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7548 {
7549 if (which_alternative == 3)
7550 {
7551 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7552 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7553 return "test{l}\t{%1, %k0|%k0, %1}";
7554 }
7555 return "test{b}\t{%1, %0|%0, %1}";
7556 }
7557 [(set_attr "type" "test")
7558 (set_attr "modrm" "0,1,1,1")
7559 (set_attr "mode" "QI,QI,QI,SI")
7560 (set_attr "pent_pair" "uv,np,uv,np")])
7561
7562 (define_insn "*test<mode>_1"
7563 [(set (reg FLAGS_REG)
7564 (compare
7565 (and:SWI124
7566 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7567 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7568 (const_int 0)))]
7569 "ix86_match_ccmode (insn, CCNOmode)
7570 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7571 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7572 [(set_attr "type" "test")
7573 (set_attr "modrm" "0,1,1")
7574 (set_attr "mode" "<MODE>")
7575 (set_attr "pent_pair" "uv,np,uv")])
7576
7577 (define_expand "testqi_ext_ccno_0"
7578 [(set (reg:CCNO FLAGS_REG)
7579 (compare:CCNO
7580 (and:SI
7581 (zero_extract:SI
7582 (match_operand 0 "ext_register_operand" "")
7583 (const_int 8)
7584 (const_int 8))
7585 (match_operand 1 "const_int_operand" ""))
7586 (const_int 0)))])
7587
7588 (define_insn "*testqi_ext_0"
7589 [(set (reg FLAGS_REG)
7590 (compare
7591 (and:SI
7592 (zero_extract:SI
7593 (match_operand 0 "ext_register_operand" "Q")
7594 (const_int 8)
7595 (const_int 8))
7596 (match_operand 1 "const_int_operand" "n"))
7597 (const_int 0)))]
7598 "ix86_match_ccmode (insn, CCNOmode)"
7599 "test{b}\t{%1, %h0|%h0, %1}"
7600 [(set_attr "type" "test")
7601 (set_attr "mode" "QI")
7602 (set_attr "length_immediate" "1")
7603 (set_attr "modrm" "1")
7604 (set_attr "pent_pair" "np")])
7605
7606 (define_insn "*testqi_ext_1_rex64"
7607 [(set (reg FLAGS_REG)
7608 (compare
7609 (and:SI
7610 (zero_extract:SI
7611 (match_operand 0 "ext_register_operand" "Q")
7612 (const_int 8)
7613 (const_int 8))
7614 (zero_extend:SI
7615 (match_operand:QI 1 "register_operand" "Q")))
7616 (const_int 0)))]
7617 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7618 "test{b}\t{%1, %h0|%h0, %1}"
7619 [(set_attr "type" "test")
7620 (set_attr "mode" "QI")])
7621
7622 (define_insn "*testqi_ext_1"
7623 [(set (reg FLAGS_REG)
7624 (compare
7625 (and:SI
7626 (zero_extract:SI
7627 (match_operand 0 "ext_register_operand" "Q")
7628 (const_int 8)
7629 (const_int 8))
7630 (zero_extend:SI
7631 (match_operand:QI 1 "general_operand" "Qm")))
7632 (const_int 0)))]
7633 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7634 "test{b}\t{%1, %h0|%h0, %1}"
7635 [(set_attr "type" "test")
7636 (set_attr "mode" "QI")])
7637
7638 (define_insn "*testqi_ext_2"
7639 [(set (reg FLAGS_REG)
7640 (compare
7641 (and:SI
7642 (zero_extract:SI
7643 (match_operand 0 "ext_register_operand" "Q")
7644 (const_int 8)
7645 (const_int 8))
7646 (zero_extract:SI
7647 (match_operand 1 "ext_register_operand" "Q")
7648 (const_int 8)
7649 (const_int 8)))
7650 (const_int 0)))]
7651 "ix86_match_ccmode (insn, CCNOmode)"
7652 "test{b}\t{%h1, %h0|%h0, %h1}"
7653 [(set_attr "type" "test")
7654 (set_attr "mode" "QI")])
7655
7656 (define_insn "*testqi_ext_3_rex64"
7657 [(set (reg FLAGS_REG)
7658 (compare (zero_extract:DI
7659 (match_operand 0 "nonimmediate_operand" "rm")
7660 (match_operand:DI 1 "const_int_operand" "")
7661 (match_operand:DI 2 "const_int_operand" ""))
7662 (const_int 0)))]
7663 "TARGET_64BIT
7664 && ix86_match_ccmode (insn, CCNOmode)
7665 && INTVAL (operands[1]) > 0
7666 && INTVAL (operands[2]) >= 0
7667 /* Ensure that resulting mask is zero or sign extended operand. */
7668 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7669 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7670 && INTVAL (operands[1]) > 32))
7671 && (GET_MODE (operands[0]) == SImode
7672 || GET_MODE (operands[0]) == DImode
7673 || GET_MODE (operands[0]) == HImode
7674 || GET_MODE (operands[0]) == QImode)"
7675 "#")
7676
7677 ;; Combine likes to form bit extractions for some tests. Humor it.
7678 (define_insn "*testqi_ext_3"
7679 [(set (reg FLAGS_REG)
7680 (compare (zero_extract:SI
7681 (match_operand 0 "nonimmediate_operand" "rm")
7682 (match_operand:SI 1 "const_int_operand" "")
7683 (match_operand:SI 2 "const_int_operand" ""))
7684 (const_int 0)))]
7685 "ix86_match_ccmode (insn, CCNOmode)
7686 && INTVAL (operands[1]) > 0
7687 && INTVAL (operands[2]) >= 0
7688 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7689 && (GET_MODE (operands[0]) == SImode
7690 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7691 || GET_MODE (operands[0]) == HImode
7692 || GET_MODE (operands[0]) == QImode)"
7693 "#")
7694
7695 (define_split
7696 [(set (match_operand 0 "flags_reg_operand" "")
7697 (match_operator 1 "compare_operator"
7698 [(zero_extract
7699 (match_operand 2 "nonimmediate_operand" "")
7700 (match_operand 3 "const_int_operand" "")
7701 (match_operand 4 "const_int_operand" ""))
7702 (const_int 0)]))]
7703 "ix86_match_ccmode (insn, CCNOmode)"
7704 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7705 {
7706 rtx val = operands[2];
7707 HOST_WIDE_INT len = INTVAL (operands[3]);
7708 HOST_WIDE_INT pos = INTVAL (operands[4]);
7709 HOST_WIDE_INT mask;
7710 enum machine_mode mode, submode;
7711
7712 mode = GET_MODE (val);
7713 if (MEM_P (val))
7714 {
7715 /* ??? Combine likes to put non-volatile mem extractions in QImode
7716 no matter the size of the test. So find a mode that works. */
7717 if (! MEM_VOLATILE_P (val))
7718 {
7719 mode = smallest_mode_for_size (pos + len, MODE_INT);
7720 val = adjust_address (val, mode, 0);
7721 }
7722 }
7723 else if (GET_CODE (val) == SUBREG
7724 && (submode = GET_MODE (SUBREG_REG (val)),
7725 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7726 && pos + len <= GET_MODE_BITSIZE (submode)
7727 && GET_MODE_CLASS (submode) == MODE_INT)
7728 {
7729 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7730 mode = submode;
7731 val = SUBREG_REG (val);
7732 }
7733 else if (mode == HImode && pos + len <= 8)
7734 {
7735 /* Small HImode tests can be converted to QImode. */
7736 mode = QImode;
7737 val = gen_lowpart (QImode, val);
7738 }
7739
7740 if (len == HOST_BITS_PER_WIDE_INT)
7741 mask = -1;
7742 else
7743 mask = ((HOST_WIDE_INT)1 << len) - 1;
7744 mask <<= pos;
7745
7746 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7747 })
7748
7749 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7750 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7751 ;; this is relatively important trick.
7752 ;; Do the conversion only post-reload to avoid limiting of the register class
7753 ;; to QI regs.
7754 (define_split
7755 [(set (match_operand 0 "flags_reg_operand" "")
7756 (match_operator 1 "compare_operator"
7757 [(and (match_operand 2 "register_operand" "")
7758 (match_operand 3 "const_int_operand" ""))
7759 (const_int 0)]))]
7760 "reload_completed
7761 && QI_REG_P (operands[2])
7762 && GET_MODE (operands[2]) != QImode
7763 && ((ix86_match_ccmode (insn, CCZmode)
7764 && !(INTVAL (operands[3]) & ~(255 << 8)))
7765 || (ix86_match_ccmode (insn, CCNOmode)
7766 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7767 [(set (match_dup 0)
7768 (match_op_dup 1
7769 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7770 (match_dup 3))
7771 (const_int 0)]))]
7772 "operands[2] = gen_lowpart (SImode, operands[2]);
7773 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7774
7775 (define_split
7776 [(set (match_operand 0 "flags_reg_operand" "")
7777 (match_operator 1 "compare_operator"
7778 [(and (match_operand 2 "nonimmediate_operand" "")
7779 (match_operand 3 "const_int_operand" ""))
7780 (const_int 0)]))]
7781 "reload_completed
7782 && GET_MODE (operands[2]) != QImode
7783 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7784 && ((ix86_match_ccmode (insn, CCZmode)
7785 && !(INTVAL (operands[3]) & ~255))
7786 || (ix86_match_ccmode (insn, CCNOmode)
7787 && !(INTVAL (operands[3]) & ~127)))"
7788 [(set (match_dup 0)
7789 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7790 (const_int 0)]))]
7791 "operands[2] = gen_lowpart (QImode, operands[2]);
7792 operands[3] = gen_lowpart (QImode, operands[3]);")
7793
7794 ;; %%% This used to optimize known byte-wide and operations to memory,
7795 ;; and sometimes to QImode registers. If this is considered useful,
7796 ;; it should be done with splitters.
7797
7798 (define_expand "and<mode>3"
7799 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7800 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7801 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7802 ""
7803 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7804
7805 (define_insn "*anddi_1"
7806 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7807 (and:DI
7808 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7809 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7812 {
7813 switch (get_attr_type (insn))
7814 {
7815 case TYPE_IMOVX:
7816 {
7817 enum machine_mode mode;
7818
7819 gcc_assert (CONST_INT_P (operands[2]));
7820 if (INTVAL (operands[2]) == 0xff)
7821 mode = QImode;
7822 else
7823 {
7824 gcc_assert (INTVAL (operands[2]) == 0xffff);
7825 mode = HImode;
7826 }
7827
7828 operands[1] = gen_lowpart (mode, operands[1]);
7829 if (mode == QImode)
7830 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7831 else
7832 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7833 }
7834
7835 default:
7836 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7837 if (get_attr_mode (insn) == MODE_SI)
7838 return "and{l}\t{%k2, %k0|%k0, %k2}";
7839 else
7840 return "and{q}\t{%2, %0|%0, %2}";
7841 }
7842 }
7843 [(set_attr "type" "alu,alu,alu,imovx")
7844 (set_attr "length_immediate" "*,*,*,0")
7845 (set (attr "prefix_rex")
7846 (if_then_else
7847 (and (eq_attr "type" "imovx")
7848 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7849 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7850 (const_string "1")
7851 (const_string "*")))
7852 (set_attr "mode" "SI,DI,DI,SI")])
7853
7854 (define_insn "*andsi_1"
7855 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7856 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7857 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "ix86_binary_operator_ok (AND, SImode, operands)"
7860 {
7861 switch (get_attr_type (insn))
7862 {
7863 case TYPE_IMOVX:
7864 {
7865 enum machine_mode mode;
7866
7867 gcc_assert (CONST_INT_P (operands[2]));
7868 if (INTVAL (operands[2]) == 0xff)
7869 mode = QImode;
7870 else
7871 {
7872 gcc_assert (INTVAL (operands[2]) == 0xffff);
7873 mode = HImode;
7874 }
7875
7876 operands[1] = gen_lowpart (mode, operands[1]);
7877 if (mode == QImode)
7878 return "movz{bl|x}\t{%1, %0|%0, %1}";
7879 else
7880 return "movz{wl|x}\t{%1, %0|%0, %1}";
7881 }
7882
7883 default:
7884 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7885 return "and{l}\t{%2, %0|%0, %2}";
7886 }
7887 }
7888 [(set_attr "type" "alu,alu,imovx")
7889 (set (attr "prefix_rex")
7890 (if_then_else
7891 (and (eq_attr "type" "imovx")
7892 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7893 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7894 (const_string "1")
7895 (const_string "*")))
7896 (set_attr "length_immediate" "*,*,0")
7897 (set_attr "mode" "SI")])
7898
7899 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7900 (define_insn "*andsi_1_zext"
7901 [(set (match_operand:DI 0 "register_operand" "=r")
7902 (zero_extend:DI
7903 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7904 (match_operand:SI 2 "general_operand" "g"))))
7905 (clobber (reg:CC FLAGS_REG))]
7906 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7907 "and{l}\t{%2, %k0|%k0, %2}"
7908 [(set_attr "type" "alu")
7909 (set_attr "mode" "SI")])
7910
7911 (define_insn "*andhi_1"
7912 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7913 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7914 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7915 (clobber (reg:CC FLAGS_REG))]
7916 "ix86_binary_operator_ok (AND, HImode, operands)"
7917 {
7918 switch (get_attr_type (insn))
7919 {
7920 case TYPE_IMOVX:
7921 gcc_assert (CONST_INT_P (operands[2]));
7922 gcc_assert (INTVAL (operands[2]) == 0xff);
7923 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7924
7925 default:
7926 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7927
7928 return "and{w}\t{%2, %0|%0, %2}";
7929 }
7930 }
7931 [(set_attr "type" "alu,alu,imovx")
7932 (set_attr "length_immediate" "*,*,0")
7933 (set (attr "prefix_rex")
7934 (if_then_else
7935 (and (eq_attr "type" "imovx")
7936 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7937 (const_string "1")
7938 (const_string "*")))
7939 (set_attr "mode" "HI,HI,SI")])
7940
7941 ;; %%% Potential partial reg stall on alternative 2. What to do?
7942 (define_insn "*andqi_1"
7943 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7944 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7945 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7946 (clobber (reg:CC FLAGS_REG))]
7947 "ix86_binary_operator_ok (AND, QImode, operands)"
7948 "@
7949 and{b}\t{%2, %0|%0, %2}
7950 and{b}\t{%2, %0|%0, %2}
7951 and{l}\t{%k2, %k0|%k0, %k2}"
7952 [(set_attr "type" "alu")
7953 (set_attr "mode" "QI,QI,SI")])
7954
7955 (define_insn "*andqi_1_slp"
7956 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7957 (and:QI (match_dup 0)
7958 (match_operand:QI 1 "general_operand" "qn,qmn")))
7959 (clobber (reg:CC FLAGS_REG))]
7960 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7961 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7962 "and{b}\t{%1, %0|%0, %1}"
7963 [(set_attr "type" "alu1")
7964 (set_attr "mode" "QI")])
7965
7966 (define_split
7967 [(set (match_operand 0 "register_operand" "")
7968 (and (match_dup 0)
7969 (const_int -65536)))
7970 (clobber (reg:CC FLAGS_REG))]
7971 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7972 || optimize_function_for_size_p (cfun)"
7973 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7974 "operands[1] = gen_lowpart (HImode, operands[0]);")
7975
7976 (define_split
7977 [(set (match_operand 0 "ext_register_operand" "")
7978 (and (match_dup 0)
7979 (const_int -256)))
7980 (clobber (reg:CC FLAGS_REG))]
7981 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7982 && reload_completed"
7983 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7984 "operands[1] = gen_lowpart (QImode, operands[0]);")
7985
7986 (define_split
7987 [(set (match_operand 0 "ext_register_operand" "")
7988 (and (match_dup 0)
7989 (const_int -65281)))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7992 && reload_completed"
7993 [(parallel [(set (zero_extract:SI (match_dup 0)
7994 (const_int 8)
7995 (const_int 8))
7996 (xor:SI
7997 (zero_extract:SI (match_dup 0)
7998 (const_int 8)
7999 (const_int 8))
8000 (zero_extract:SI (match_dup 0)
8001 (const_int 8)
8002 (const_int 8))))
8003 (clobber (reg:CC FLAGS_REG))])]
8004 "operands[0] = gen_lowpart (SImode, operands[0]);")
8005
8006 (define_insn "*anddi_2"
8007 [(set (reg FLAGS_REG)
8008 (compare
8009 (and:DI
8010 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8011 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8012 (const_int 0)))
8013 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8014 (and:DI (match_dup 1) (match_dup 2)))]
8015 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8016 && ix86_binary_operator_ok (AND, DImode, operands)"
8017 "@
8018 and{l}\t{%k2, %k0|%k0, %k2}
8019 and{q}\t{%2, %0|%0, %2}
8020 and{q}\t{%2, %0|%0, %2}"
8021 [(set_attr "type" "alu")
8022 (set_attr "mode" "SI,DI,DI")])
8023
8024 (define_insn "*andqi_2_maybe_si"
8025 [(set (reg FLAGS_REG)
8026 (compare (and:QI
8027 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8028 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8029 (const_int 0)))
8030 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8031 (and:QI (match_dup 1) (match_dup 2)))]
8032 "ix86_binary_operator_ok (AND, QImode, operands)
8033 && ix86_match_ccmode (insn,
8034 CONST_INT_P (operands[2])
8035 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8036 {
8037 if (which_alternative == 2)
8038 {
8039 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8040 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8041 return "and{l}\t{%2, %k0|%k0, %2}";
8042 }
8043 return "and{b}\t{%2, %0|%0, %2}";
8044 }
8045 [(set_attr "type" "alu")
8046 (set_attr "mode" "QI,QI,SI")])
8047
8048 (define_insn "*and<mode>_2"
8049 [(set (reg FLAGS_REG)
8050 (compare (and:SWI124
8051 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8052 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8053 (const_int 0)))
8054 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8055 (and:SWI124 (match_dup 1) (match_dup 2)))]
8056 "ix86_match_ccmode (insn, CCNOmode)
8057 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8058 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8059 [(set_attr "type" "alu")
8060 (set_attr "mode" "<MODE>")])
8061
8062 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8063 (define_insn "*andsi_2_zext"
8064 [(set (reg FLAGS_REG)
8065 (compare (and:SI
8066 (match_operand:SI 1 "nonimmediate_operand" "%0")
8067 (match_operand:SI 2 "general_operand" "g"))
8068 (const_int 0)))
8069 (set (match_operand:DI 0 "register_operand" "=r")
8070 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8071 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8072 && ix86_binary_operator_ok (AND, SImode, operands)"
8073 "and{l}\t{%2, %k0|%k0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "mode" "SI")])
8076
8077 (define_insn "*andqi_2_slp"
8078 [(set (reg FLAGS_REG)
8079 (compare (and:QI
8080 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8081 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8082 (const_int 0)))
8083 (set (strict_low_part (match_dup 0))
8084 (and:QI (match_dup 0) (match_dup 1)))]
8085 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086 && ix86_match_ccmode (insn, CCNOmode)
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 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8093 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8094 ;; for a QImode operand, which of course failed.
8095 (define_insn "andqi_ext_0"
8096 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8097 (const_int 8)
8098 (const_int 8))
8099 (and:SI
8100 (zero_extract:SI
8101 (match_operand 1 "ext_register_operand" "0")
8102 (const_int 8)
8103 (const_int 8))
8104 (match_operand 2 "const_int_operand" "n")))
8105 (clobber (reg:CC FLAGS_REG))]
8106 ""
8107 "and{b}\t{%2, %h0|%h0, %2}"
8108 [(set_attr "type" "alu")
8109 (set_attr "length_immediate" "1")
8110 (set_attr "modrm" "1")
8111 (set_attr "mode" "QI")])
8112
8113 ;; Generated by peephole translating test to and. This shows up
8114 ;; often in fp comparisons.
8115 (define_insn "*andqi_ext_0_cc"
8116 [(set (reg FLAGS_REG)
8117 (compare
8118 (and:SI
8119 (zero_extract:SI
8120 (match_operand 1 "ext_register_operand" "0")
8121 (const_int 8)
8122 (const_int 8))
8123 (match_operand 2 "const_int_operand" "n"))
8124 (const_int 0)))
8125 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8126 (const_int 8)
8127 (const_int 8))
8128 (and:SI
8129 (zero_extract:SI
8130 (match_dup 1)
8131 (const_int 8)
8132 (const_int 8))
8133 (match_dup 2)))]
8134 "ix86_match_ccmode (insn, CCNOmode)"
8135 "and{b}\t{%2, %h0|%h0, %2}"
8136 [(set_attr "type" "alu")
8137 (set_attr "length_immediate" "1")
8138 (set_attr "modrm" "1")
8139 (set_attr "mode" "QI")])
8140
8141 (define_insn "*andqi_ext_1_rex64"
8142 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8143 (const_int 8)
8144 (const_int 8))
8145 (and:SI
8146 (zero_extract:SI
8147 (match_operand 1 "ext_register_operand" "0")
8148 (const_int 8)
8149 (const_int 8))
8150 (zero_extend:SI
8151 (match_operand 2 "ext_register_operand" "Q"))))
8152 (clobber (reg:CC FLAGS_REG))]
8153 "TARGET_64BIT"
8154 "and{b}\t{%2, %h0|%h0, %2}"
8155 [(set_attr "type" "alu")
8156 (set_attr "length_immediate" "0")
8157 (set_attr "mode" "QI")])
8158
8159 (define_insn "*andqi_ext_1"
8160 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8161 (const_int 8)
8162 (const_int 8))
8163 (and:SI
8164 (zero_extract:SI
8165 (match_operand 1 "ext_register_operand" "0")
8166 (const_int 8)
8167 (const_int 8))
8168 (zero_extend:SI
8169 (match_operand:QI 2 "general_operand" "Qm"))))
8170 (clobber (reg:CC FLAGS_REG))]
8171 "!TARGET_64BIT"
8172 "and{b}\t{%2, %h0|%h0, %2}"
8173 [(set_attr "type" "alu")
8174 (set_attr "length_immediate" "0")
8175 (set_attr "mode" "QI")])
8176
8177 (define_insn "*andqi_ext_2"
8178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8179 (const_int 8)
8180 (const_int 8))
8181 (and:SI
8182 (zero_extract:SI
8183 (match_operand 1 "ext_register_operand" "%0")
8184 (const_int 8)
8185 (const_int 8))
8186 (zero_extract:SI
8187 (match_operand 2 "ext_register_operand" "Q")
8188 (const_int 8)
8189 (const_int 8))))
8190 (clobber (reg:CC FLAGS_REG))]
8191 ""
8192 "and{b}\t{%h2, %h0|%h0, %h2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "length_immediate" "0")
8195 (set_attr "mode" "QI")])
8196
8197 ;; Convert wide AND instructions with immediate operand to shorter QImode
8198 ;; equivalents when possible.
8199 ;; Don't do the splitting with memory operands, since it introduces risk
8200 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8201 ;; for size, but that can (should?) be handled by generic code instead.
8202 (define_split
8203 [(set (match_operand 0 "register_operand" "")
8204 (and (match_operand 1 "register_operand" "")
8205 (match_operand 2 "const_int_operand" "")))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "reload_completed
8208 && QI_REG_P (operands[0])
8209 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8210 && !(~INTVAL (operands[2]) & ~(255 << 8))
8211 && GET_MODE (operands[0]) != QImode"
8212 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8213 (and:SI (zero_extract:SI (match_dup 1)
8214 (const_int 8) (const_int 8))
8215 (match_dup 2)))
8216 (clobber (reg:CC FLAGS_REG))])]
8217 "operands[0] = gen_lowpart (SImode, operands[0]);
8218 operands[1] = gen_lowpart (SImode, operands[1]);
8219 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8220
8221 ;; Since AND can be encoded with sign extended immediate, this is only
8222 ;; profitable when 7th bit is not set.
8223 (define_split
8224 [(set (match_operand 0 "register_operand" "")
8225 (and (match_operand 1 "general_operand" "")
8226 (match_operand 2 "const_int_operand" "")))
8227 (clobber (reg:CC FLAGS_REG))]
8228 "reload_completed
8229 && ANY_QI_REG_P (operands[0])
8230 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8231 && !(~INTVAL (operands[2]) & ~255)
8232 && !(INTVAL (operands[2]) & 128)
8233 && GET_MODE (operands[0]) != QImode"
8234 [(parallel [(set (strict_low_part (match_dup 0))
8235 (and:QI (match_dup 1)
8236 (match_dup 2)))
8237 (clobber (reg:CC FLAGS_REG))])]
8238 "operands[0] = gen_lowpart (QImode, operands[0]);
8239 operands[1] = gen_lowpart (QImode, operands[1]);
8240 operands[2] = gen_lowpart (QImode, operands[2]);")
8241 \f
8242 ;; Logical inclusive and exclusive OR instructions
8243
8244 ;; %%% This used to optimize known byte-wide and operations to memory.
8245 ;; If this is considered useful, it should be done with splitters.
8246
8247 (define_expand "<code><mode>3"
8248 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8249 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8250 (match_operand:SWIM 2 "<general_operand>" "")))]
8251 ""
8252 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8253
8254 (define_insn "*<code><mode>_1"
8255 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8256 (any_or:SWI248
8257 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8258 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8259 (clobber (reg:CC FLAGS_REG))]
8260 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8261 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8262 [(set_attr "type" "alu")
8263 (set_attr "mode" "<MODE>")])
8264
8265 ;; %%% Potential partial reg stall on alternative 2. What to do?
8266 (define_insn "*<code>qi_1"
8267 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8268 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8269 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8272 "@
8273 <logic>{b}\t{%2, %0|%0, %2}
8274 <logic>{b}\t{%2, %0|%0, %2}
8275 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8276 [(set_attr "type" "alu")
8277 (set_attr "mode" "QI,QI,SI")])
8278
8279 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8280 (define_insn "*<code>si_1_zext"
8281 [(set (match_operand:DI 0 "register_operand" "=r")
8282 (zero_extend:DI
8283 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8284 (match_operand:SI 2 "general_operand" "g"))))
8285 (clobber (reg:CC FLAGS_REG))]
8286 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8287 "<logic>{l}\t{%2, %k0|%k0, %2}"
8288 [(set_attr "type" "alu")
8289 (set_attr "mode" "SI")])
8290
8291 (define_insn "*<code>si_1_zext_imm"
8292 [(set (match_operand:DI 0 "register_operand" "=r")
8293 (any_or:DI
8294 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8295 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8296 (clobber (reg:CC FLAGS_REG))]
8297 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8298 "<logic>{l}\t{%2, %k0|%k0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "mode" "SI")])
8301
8302 (define_insn "*<code>qi_1_slp"
8303 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8304 (any_or:QI (match_dup 0)
8305 (match_operand:QI 1 "general_operand" "qmn,qn")))
8306 (clobber (reg:CC FLAGS_REG))]
8307 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8308 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8309 "<logic>{b}\t{%1, %0|%0, %1}"
8310 [(set_attr "type" "alu1")
8311 (set_attr "mode" "QI")])
8312
8313 (define_insn "*<code><mode>_2"
8314 [(set (reg FLAGS_REG)
8315 (compare (any_or:SWI
8316 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8317 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8318 (const_int 0)))
8319 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8320 (any_or:SWI (match_dup 1) (match_dup 2)))]
8321 "ix86_match_ccmode (insn, CCNOmode)
8322 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8323 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "mode" "<MODE>")])
8326
8327 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8328 ;; ??? Special case for immediate operand is missing - it is tricky.
8329 (define_insn "*<code>si_2_zext"
8330 [(set (reg FLAGS_REG)
8331 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8332 (match_operand:SI 2 "general_operand" "g"))
8333 (const_int 0)))
8334 (set (match_operand:DI 0 "register_operand" "=r")
8335 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8336 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8337 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8338 "<logic>{l}\t{%2, %k0|%k0, %2}"
8339 [(set_attr "type" "alu")
8340 (set_attr "mode" "SI")])
8341
8342 (define_insn "*<code>si_2_zext_imm"
8343 [(set (reg FLAGS_REG)
8344 (compare (any_or:SI
8345 (match_operand:SI 1 "nonimmediate_operand" "%0")
8346 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8347 (const_int 0)))
8348 (set (match_operand:DI 0 "register_operand" "=r")
8349 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8350 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8351 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8352 "<logic>{l}\t{%2, %k0|%k0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "SI")])
8355
8356 (define_insn "*<code>qi_2_slp"
8357 [(set (reg FLAGS_REG)
8358 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8359 (match_operand:QI 1 "general_operand" "qmn,qn"))
8360 (const_int 0)))
8361 (set (strict_low_part (match_dup 0))
8362 (any_or:QI (match_dup 0) (match_dup 1)))]
8363 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8364 && ix86_match_ccmode (insn, CCNOmode)
8365 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8366 "<logic>{b}\t{%1, %0|%0, %1}"
8367 [(set_attr "type" "alu1")
8368 (set_attr "mode" "QI")])
8369
8370 (define_insn "*<code><mode>_3"
8371 [(set (reg FLAGS_REG)
8372 (compare (any_or:SWI
8373 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8374 (match_operand:SWI 2 "<general_operand>" "<g>"))
8375 (const_int 0)))
8376 (clobber (match_scratch:SWI 0 "=<r>"))]
8377 "ix86_match_ccmode (insn, CCNOmode)
8378 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8379 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "<MODE>")])
8382
8383 (define_insn "*<code>qi_ext_0"
8384 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8385 (const_int 8)
8386 (const_int 8))
8387 (any_or:SI
8388 (zero_extract:SI
8389 (match_operand 1 "ext_register_operand" "0")
8390 (const_int 8)
8391 (const_int 8))
8392 (match_operand 2 "const_int_operand" "n")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8395 "<logic>{b}\t{%2, %h0|%h0, %2}"
8396 [(set_attr "type" "alu")
8397 (set_attr "length_immediate" "1")
8398 (set_attr "modrm" "1")
8399 (set_attr "mode" "QI")])
8400
8401 (define_insn "*<code>qi_ext_1_rex64"
8402 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8403 (const_int 8)
8404 (const_int 8))
8405 (any_or:SI
8406 (zero_extract:SI
8407 (match_operand 1 "ext_register_operand" "0")
8408 (const_int 8)
8409 (const_int 8))
8410 (zero_extend:SI
8411 (match_operand 2 "ext_register_operand" "Q"))))
8412 (clobber (reg:CC FLAGS_REG))]
8413 "TARGET_64BIT
8414 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8415 "<logic>{b}\t{%2, %h0|%h0, %2}"
8416 [(set_attr "type" "alu")
8417 (set_attr "length_immediate" "0")
8418 (set_attr "mode" "QI")])
8419
8420 (define_insn "*<code>qi_ext_1"
8421 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8422 (const_int 8)
8423 (const_int 8))
8424 (any_or:SI
8425 (zero_extract:SI
8426 (match_operand 1 "ext_register_operand" "0")
8427 (const_int 8)
8428 (const_int 8))
8429 (zero_extend:SI
8430 (match_operand:QI 2 "general_operand" "Qm"))))
8431 (clobber (reg:CC FLAGS_REG))]
8432 "!TARGET_64BIT
8433 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8434 "<logic>{b}\t{%2, %h0|%h0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "length_immediate" "0")
8437 (set_attr "mode" "QI")])
8438
8439 (define_insn "*<code>qi_ext_2"
8440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8441 (const_int 8)
8442 (const_int 8))
8443 (any_or:SI
8444 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8445 (const_int 8)
8446 (const_int 8))
8447 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8448 (const_int 8)
8449 (const_int 8))))
8450 (clobber (reg:CC FLAGS_REG))]
8451 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8452 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8453 [(set_attr "type" "alu")
8454 (set_attr "length_immediate" "0")
8455 (set_attr "mode" "QI")])
8456
8457 (define_split
8458 [(set (match_operand 0 "register_operand" "")
8459 (any_or (match_operand 1 "register_operand" "")
8460 (match_operand 2 "const_int_operand" "")))
8461 (clobber (reg:CC FLAGS_REG))]
8462 "reload_completed
8463 && QI_REG_P (operands[0])
8464 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8465 && !(INTVAL (operands[2]) & ~(255 << 8))
8466 && GET_MODE (operands[0]) != QImode"
8467 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8468 (any_or:SI (zero_extract:SI (match_dup 1)
8469 (const_int 8) (const_int 8))
8470 (match_dup 2)))
8471 (clobber (reg:CC FLAGS_REG))])]
8472 "operands[0] = gen_lowpart (SImode, operands[0]);
8473 operands[1] = gen_lowpart (SImode, operands[1]);
8474 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8475
8476 ;; Since OR can be encoded with sign extended immediate, this is only
8477 ;; profitable when 7th bit is set.
8478 (define_split
8479 [(set (match_operand 0 "register_operand" "")
8480 (any_or (match_operand 1 "general_operand" "")
8481 (match_operand 2 "const_int_operand" "")))
8482 (clobber (reg:CC FLAGS_REG))]
8483 "reload_completed
8484 && ANY_QI_REG_P (operands[0])
8485 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8486 && !(INTVAL (operands[2]) & ~255)
8487 && (INTVAL (operands[2]) & 128)
8488 && GET_MODE (operands[0]) != QImode"
8489 [(parallel [(set (strict_low_part (match_dup 0))
8490 (any_or:QI (match_dup 1)
8491 (match_dup 2)))
8492 (clobber (reg:CC FLAGS_REG))])]
8493 "operands[0] = gen_lowpart (QImode, operands[0]);
8494 operands[1] = gen_lowpart (QImode, operands[1]);
8495 operands[2] = gen_lowpart (QImode, operands[2]);")
8496
8497 (define_expand "xorqi_cc_ext_1"
8498 [(parallel [
8499 (set (reg:CCNO FLAGS_REG)
8500 (compare:CCNO
8501 (xor:SI
8502 (zero_extract:SI
8503 (match_operand 1 "ext_register_operand" "")
8504 (const_int 8)
8505 (const_int 8))
8506 (match_operand:QI 2 "general_operand" ""))
8507 (const_int 0)))
8508 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8509 (const_int 8)
8510 (const_int 8))
8511 (xor:SI
8512 (zero_extract:SI
8513 (match_dup 1)
8514 (const_int 8)
8515 (const_int 8))
8516 (match_dup 2)))])])
8517
8518 (define_insn "*xorqi_cc_ext_1_rex64"
8519 [(set (reg FLAGS_REG)
8520 (compare
8521 (xor:SI
8522 (zero_extract:SI
8523 (match_operand 1 "ext_register_operand" "0")
8524 (const_int 8)
8525 (const_int 8))
8526 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8527 (const_int 0)))
8528 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8529 (const_int 8)
8530 (const_int 8))
8531 (xor:SI
8532 (zero_extract:SI
8533 (match_dup 1)
8534 (const_int 8)
8535 (const_int 8))
8536 (match_dup 2)))]
8537 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8538 "xor{b}\t{%2, %h0|%h0, %2}"
8539 [(set_attr "type" "alu")
8540 (set_attr "modrm" "1")
8541 (set_attr "mode" "QI")])
8542
8543 (define_insn "*xorqi_cc_ext_1"
8544 [(set (reg FLAGS_REG)
8545 (compare
8546 (xor:SI
8547 (zero_extract:SI
8548 (match_operand 1 "ext_register_operand" "0")
8549 (const_int 8)
8550 (const_int 8))
8551 (match_operand:QI 2 "general_operand" "qmn"))
8552 (const_int 0)))
8553 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8554 (const_int 8)
8555 (const_int 8))
8556 (xor:SI
8557 (zero_extract:SI
8558 (match_dup 1)
8559 (const_int 8)
8560 (const_int 8))
8561 (match_dup 2)))]
8562 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8563 "xor{b}\t{%2, %h0|%h0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "modrm" "1")
8566 (set_attr "mode" "QI")])
8567 \f
8568 ;; Negation instructions
8569
8570 (define_expand "neg<mode>2"
8571 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8572 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8573 ""
8574 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8575
8576 (define_insn_and_split "*neg<dwi>2_doubleword"
8577 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8578 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8581 "#"
8582 "reload_completed"
8583 [(parallel
8584 [(set (reg:CCZ FLAGS_REG)
8585 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8586 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8587 (parallel
8588 [(set (match_dup 2)
8589 (plus:DWIH (match_dup 3)
8590 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8591 (const_int 0))))
8592 (clobber (reg:CC FLAGS_REG))])
8593 (parallel
8594 [(set (match_dup 2)
8595 (neg:DWIH (match_dup 2)))
8596 (clobber (reg:CC FLAGS_REG))])]
8597 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8598
8599 (define_insn "*neg<mode>2_1"
8600 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8601 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8604 "neg{<imodesuffix>}\t%0"
8605 [(set_attr "type" "negnot")
8606 (set_attr "mode" "<MODE>")])
8607
8608 ;; Combine is quite creative about this pattern.
8609 (define_insn "*negsi2_1_zext"
8610 [(set (match_operand:DI 0 "register_operand" "=r")
8611 (lshiftrt:DI
8612 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8613 (const_int 32)))
8614 (const_int 32)))
8615 (clobber (reg:CC FLAGS_REG))]
8616 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8617 "neg{l}\t%k0"
8618 [(set_attr "type" "negnot")
8619 (set_attr "mode" "SI")])
8620
8621 ;; The problem with neg is that it does not perform (compare x 0),
8622 ;; it really performs (compare 0 x), which leaves us with the zero
8623 ;; flag being the only useful item.
8624
8625 (define_insn "*neg<mode>2_cmpz"
8626 [(set (reg:CCZ FLAGS_REG)
8627 (compare:CCZ
8628 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8629 (const_int 0)))
8630 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8631 (neg:SWI (match_dup 1)))]
8632 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8633 "neg{<imodesuffix>}\t%0"
8634 [(set_attr "type" "negnot")
8635 (set_attr "mode" "<MODE>")])
8636
8637 (define_insn "*negsi2_cmpz_zext"
8638 [(set (reg:CCZ FLAGS_REG)
8639 (compare:CCZ
8640 (lshiftrt:DI
8641 (neg:DI (ashift:DI
8642 (match_operand:DI 1 "register_operand" "0")
8643 (const_int 32)))
8644 (const_int 32))
8645 (const_int 0)))
8646 (set (match_operand:DI 0 "register_operand" "=r")
8647 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8648 (const_int 32)))
8649 (const_int 32)))]
8650 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8651 "neg{l}\t%k0"
8652 [(set_attr "type" "negnot")
8653 (set_attr "mode" "SI")])
8654
8655 ;; Changing of sign for FP values is doable using integer unit too.
8656
8657 (define_expand "<code><mode>2"
8658 [(set (match_operand:X87MODEF 0 "register_operand" "")
8659 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8660 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8661 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8662
8663 (define_insn "*absneg<mode>2_mixed"
8664 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8665 (match_operator:MODEF 3 "absneg_operator"
8666 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8667 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8670 "#")
8671
8672 (define_insn "*absneg<mode>2_sse"
8673 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8674 (match_operator:MODEF 3 "absneg_operator"
8675 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8676 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8677 (clobber (reg:CC FLAGS_REG))]
8678 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8679 "#")
8680
8681 (define_insn "*absneg<mode>2_i387"
8682 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8683 (match_operator:X87MODEF 3 "absneg_operator"
8684 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8685 (use (match_operand 2 "" ""))
8686 (clobber (reg:CC FLAGS_REG))]
8687 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8688 "#")
8689
8690 (define_expand "<code>tf2"
8691 [(set (match_operand:TF 0 "register_operand" "")
8692 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8693 "TARGET_SSE2"
8694 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8695
8696 (define_insn "*absnegtf2_sse"
8697 [(set (match_operand:TF 0 "register_operand" "=x,x")
8698 (match_operator:TF 3 "absneg_operator"
8699 [(match_operand:TF 1 "register_operand" "0,x")]))
8700 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8701 (clobber (reg:CC FLAGS_REG))]
8702 "TARGET_SSE2"
8703 "#")
8704
8705 ;; Splitters for fp abs and neg.
8706
8707 (define_split
8708 [(set (match_operand 0 "fp_register_operand" "")
8709 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8710 (use (match_operand 2 "" ""))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "reload_completed"
8713 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8714
8715 (define_split
8716 [(set (match_operand 0 "register_operand" "")
8717 (match_operator 3 "absneg_operator"
8718 [(match_operand 1 "register_operand" "")]))
8719 (use (match_operand 2 "nonimmediate_operand" ""))
8720 (clobber (reg:CC FLAGS_REG))]
8721 "reload_completed && SSE_REG_P (operands[0])"
8722 [(set (match_dup 0) (match_dup 3))]
8723 {
8724 enum machine_mode mode = GET_MODE (operands[0]);
8725 enum machine_mode vmode = GET_MODE (operands[2]);
8726 rtx tmp;
8727
8728 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8729 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8730 if (operands_match_p (operands[0], operands[2]))
8731 {
8732 tmp = operands[1];
8733 operands[1] = operands[2];
8734 operands[2] = tmp;
8735 }
8736 if (GET_CODE (operands[3]) == ABS)
8737 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8738 else
8739 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8740 operands[3] = tmp;
8741 })
8742
8743 (define_split
8744 [(set (match_operand:SF 0 "register_operand" "")
8745 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8746 (use (match_operand:V4SF 2 "" ""))
8747 (clobber (reg:CC FLAGS_REG))]
8748 "reload_completed"
8749 [(parallel [(set (match_dup 0) (match_dup 1))
8750 (clobber (reg:CC FLAGS_REG))])]
8751 {
8752 rtx tmp;
8753 operands[0] = gen_lowpart (SImode, operands[0]);
8754 if (GET_CODE (operands[1]) == ABS)
8755 {
8756 tmp = gen_int_mode (0x7fffffff, SImode);
8757 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8758 }
8759 else
8760 {
8761 tmp = gen_int_mode (0x80000000, SImode);
8762 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8763 }
8764 operands[1] = tmp;
8765 })
8766
8767 (define_split
8768 [(set (match_operand:DF 0 "register_operand" "")
8769 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8770 (use (match_operand 2 "" ""))
8771 (clobber (reg:CC FLAGS_REG))]
8772 "reload_completed"
8773 [(parallel [(set (match_dup 0) (match_dup 1))
8774 (clobber (reg:CC FLAGS_REG))])]
8775 {
8776 rtx tmp;
8777 if (TARGET_64BIT)
8778 {
8779 tmp = gen_lowpart (DImode, operands[0]);
8780 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8781 operands[0] = tmp;
8782
8783 if (GET_CODE (operands[1]) == ABS)
8784 tmp = const0_rtx;
8785 else
8786 tmp = gen_rtx_NOT (DImode, tmp);
8787 }
8788 else
8789 {
8790 operands[0] = gen_highpart (SImode, operands[0]);
8791 if (GET_CODE (operands[1]) == ABS)
8792 {
8793 tmp = gen_int_mode (0x7fffffff, SImode);
8794 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8795 }
8796 else
8797 {
8798 tmp = gen_int_mode (0x80000000, SImode);
8799 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8800 }
8801 }
8802 operands[1] = tmp;
8803 })
8804
8805 (define_split
8806 [(set (match_operand:XF 0 "register_operand" "")
8807 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8808 (use (match_operand 2 "" ""))
8809 (clobber (reg:CC FLAGS_REG))]
8810 "reload_completed"
8811 [(parallel [(set (match_dup 0) (match_dup 1))
8812 (clobber (reg:CC FLAGS_REG))])]
8813 {
8814 rtx tmp;
8815 operands[0] = gen_rtx_REG (SImode,
8816 true_regnum (operands[0])
8817 + (TARGET_64BIT ? 1 : 2));
8818 if (GET_CODE (operands[1]) == ABS)
8819 {
8820 tmp = GEN_INT (0x7fff);
8821 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8822 }
8823 else
8824 {
8825 tmp = GEN_INT (0x8000);
8826 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8827 }
8828 operands[1] = tmp;
8829 })
8830
8831 ;; Conditionalize these after reload. If they match before reload, we
8832 ;; lose the clobber and ability to use integer instructions.
8833
8834 (define_insn "*<code><mode>2_1"
8835 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8836 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8837 "TARGET_80387
8838 && (reload_completed
8839 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8840 "f<absneg_mnemonic>"
8841 [(set_attr "type" "fsgn")
8842 (set_attr "mode" "<MODE>")])
8843
8844 (define_insn "*<code>extendsfdf2"
8845 [(set (match_operand:DF 0 "register_operand" "=f")
8846 (absneg:DF (float_extend:DF
8847 (match_operand:SF 1 "register_operand" "0"))))]
8848 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8849 "f<absneg_mnemonic>"
8850 [(set_attr "type" "fsgn")
8851 (set_attr "mode" "DF")])
8852
8853 (define_insn "*<code>extendsfxf2"
8854 [(set (match_operand:XF 0 "register_operand" "=f")
8855 (absneg:XF (float_extend:XF
8856 (match_operand:SF 1 "register_operand" "0"))))]
8857 "TARGET_80387"
8858 "f<absneg_mnemonic>"
8859 [(set_attr "type" "fsgn")
8860 (set_attr "mode" "XF")])
8861
8862 (define_insn "*<code>extenddfxf2"
8863 [(set (match_operand:XF 0 "register_operand" "=f")
8864 (absneg:XF (float_extend:XF
8865 (match_operand:DF 1 "register_operand" "0"))))]
8866 "TARGET_80387"
8867 "f<absneg_mnemonic>"
8868 [(set_attr "type" "fsgn")
8869 (set_attr "mode" "XF")])
8870
8871 ;; Copysign instructions
8872
8873 (define_mode_iterator CSGNMODE [SF DF TF])
8874 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8875
8876 (define_expand "copysign<mode>3"
8877 [(match_operand:CSGNMODE 0 "register_operand" "")
8878 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8879 (match_operand:CSGNMODE 2 "register_operand" "")]
8880 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8881 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8882 "ix86_expand_copysign (operands); DONE;")
8883
8884 (define_insn_and_split "copysign<mode>3_const"
8885 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8886 (unspec:CSGNMODE
8887 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8888 (match_operand:CSGNMODE 2 "register_operand" "0")
8889 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8890 UNSPEC_COPYSIGN))]
8891 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8892 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8893 "#"
8894 "&& reload_completed"
8895 [(const_int 0)]
8896 "ix86_split_copysign_const (operands); DONE;")
8897
8898 (define_insn "copysign<mode>3_var"
8899 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8900 (unspec:CSGNMODE
8901 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8902 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8903 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8904 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8905 UNSPEC_COPYSIGN))
8906 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8907 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8908 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8909 "#")
8910
8911 (define_split
8912 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8913 (unspec:CSGNMODE
8914 [(match_operand:CSGNMODE 2 "register_operand" "")
8915 (match_operand:CSGNMODE 3 "register_operand" "")
8916 (match_operand:<CSGNVMODE> 4 "" "")
8917 (match_operand:<CSGNVMODE> 5 "" "")]
8918 UNSPEC_COPYSIGN))
8919 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8920 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8921 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8922 && reload_completed"
8923 [(const_int 0)]
8924 "ix86_split_copysign_var (operands); DONE;")
8925 \f
8926 ;; One complement instructions
8927
8928 (define_expand "one_cmpl<mode>2"
8929 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8930 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8931 ""
8932 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8933
8934 (define_insn "*one_cmpl<mode>2_1"
8935 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8936 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8937 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8938 "not{<imodesuffix>}\t%0"
8939 [(set_attr "type" "negnot")
8940 (set_attr "mode" "<MODE>")])
8941
8942 ;; %%% Potential partial reg stall on alternative 1. What to do?
8943 (define_insn "*one_cmplqi2_1"
8944 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8945 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8946 "ix86_unary_operator_ok (NOT, QImode, operands)"
8947 "@
8948 not{b}\t%0
8949 not{l}\t%k0"
8950 [(set_attr "type" "negnot")
8951 (set_attr "mode" "QI,SI")])
8952
8953 ;; ??? Currently never generated - xor is used instead.
8954 (define_insn "*one_cmplsi2_1_zext"
8955 [(set (match_operand:DI 0 "register_operand" "=r")
8956 (zero_extend:DI
8957 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8958 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8959 "not{l}\t%k0"
8960 [(set_attr "type" "negnot")
8961 (set_attr "mode" "SI")])
8962
8963 (define_insn "*one_cmpl<mode>2_2"
8964 [(set (reg FLAGS_REG)
8965 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8966 (const_int 0)))
8967 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8968 (not:SWI (match_dup 1)))]
8969 "ix86_match_ccmode (insn, CCNOmode)
8970 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8971 "#"
8972 [(set_attr "type" "alu1")
8973 (set_attr "mode" "<MODE>")])
8974
8975 (define_split
8976 [(set (match_operand 0 "flags_reg_operand" "")
8977 (match_operator 2 "compare_operator"
8978 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8979 (const_int 0)]))
8980 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8981 (not:SWI (match_dup 3)))]
8982 "ix86_match_ccmode (insn, CCNOmode)"
8983 [(parallel [(set (match_dup 0)
8984 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8985 (const_int 0)]))
8986 (set (match_dup 1)
8987 (xor:SWI (match_dup 3) (const_int -1)))])])
8988
8989 ;; ??? Currently never generated - xor is used instead.
8990 (define_insn "*one_cmplsi2_2_zext"
8991 [(set (reg FLAGS_REG)
8992 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8993 (const_int 0)))
8994 (set (match_operand:DI 0 "register_operand" "=r")
8995 (zero_extend:DI (not:SI (match_dup 1))))]
8996 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8997 && ix86_unary_operator_ok (NOT, SImode, operands)"
8998 "#"
8999 [(set_attr "type" "alu1")
9000 (set_attr "mode" "SI")])
9001
9002 (define_split
9003 [(set (match_operand 0 "flags_reg_operand" "")
9004 (match_operator 2 "compare_operator"
9005 [(not:SI (match_operand:SI 3 "register_operand" ""))
9006 (const_int 0)]))
9007 (set (match_operand:DI 1 "register_operand" "")
9008 (zero_extend:DI (not:SI (match_dup 3))))]
9009 "ix86_match_ccmode (insn, CCNOmode)"
9010 [(parallel [(set (match_dup 0)
9011 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9012 (const_int 0)]))
9013 (set (match_dup 1)
9014 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9015 \f
9016 ;; Shift instructions
9017
9018 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9019 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9020 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9021 ;; from the assembler input.
9022 ;;
9023 ;; This instruction shifts the target reg/mem as usual, but instead of
9024 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9025 ;; is a left shift double, bits are taken from the high order bits of
9026 ;; reg, else if the insn is a shift right double, bits are taken from the
9027 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9028 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9029 ;;
9030 ;; Since sh[lr]d does not change the `reg' operand, that is done
9031 ;; separately, making all shifts emit pairs of shift double and normal
9032 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9033 ;; support a 63 bit shift, each shift where the count is in a reg expands
9034 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9035 ;;
9036 ;; If the shift count is a constant, we need never emit more than one
9037 ;; shift pair, instead using moves and sign extension for counts greater
9038 ;; than 31.
9039
9040 (define_expand "ashl<mode>3"
9041 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9042 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9043 (match_operand:QI 2 "nonmemory_operand" "")))]
9044 ""
9045 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9046
9047 (define_insn "*ashl<mode>3_doubleword"
9048 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9049 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9050 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9051 (clobber (reg:CC FLAGS_REG))]
9052 ""
9053 "#"
9054 [(set_attr "type" "multi")])
9055
9056 (define_split
9057 [(set (match_operand:DWI 0 "register_operand" "")
9058 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9059 (match_operand:QI 2 "nonmemory_operand" "")))
9060 (clobber (reg:CC FLAGS_REG))]
9061 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9062 [(const_int 0)]
9063 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9064
9065 ;; By default we don't ask for a scratch register, because when DWImode
9066 ;; values are manipulated, registers are already at a premium. But if
9067 ;; we have one handy, we won't turn it away.
9068
9069 (define_peephole2
9070 [(match_scratch:DWIH 3 "r")
9071 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9072 (ashift:<DWI>
9073 (match_operand:<DWI> 1 "nonmemory_operand" "")
9074 (match_operand:QI 2 "nonmemory_operand" "")))
9075 (clobber (reg:CC FLAGS_REG))])
9076 (match_dup 3)]
9077 "TARGET_CMOVE"
9078 [(const_int 0)]
9079 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9080
9081 (define_insn "x86_64_shld"
9082 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9083 (ior:DI (ashift:DI (match_dup 0)
9084 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9085 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9086 (minus:QI (const_int 64) (match_dup 2)))))
9087 (clobber (reg:CC FLAGS_REG))]
9088 "TARGET_64BIT"
9089 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9090 [(set_attr "type" "ishift")
9091 (set_attr "prefix_0f" "1")
9092 (set_attr "mode" "DI")
9093 (set_attr "athlon_decode" "vector")
9094 (set_attr "amdfam10_decode" "vector")])
9095
9096 (define_insn "x86_shld"
9097 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9098 (ior:SI (ashift:SI (match_dup 0)
9099 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9100 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9101 (minus:QI (const_int 32) (match_dup 2)))))
9102 (clobber (reg:CC FLAGS_REG))]
9103 ""
9104 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9105 [(set_attr "type" "ishift")
9106 (set_attr "prefix_0f" "1")
9107 (set_attr "mode" "SI")
9108 (set_attr "pent_pair" "np")
9109 (set_attr "athlon_decode" "vector")
9110 (set_attr "amdfam10_decode" "vector")])
9111
9112 (define_expand "x86_shift<mode>_adj_1"
9113 [(set (reg:CCZ FLAGS_REG)
9114 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9115 (match_dup 4))
9116 (const_int 0)))
9117 (set (match_operand:SWI48 0 "register_operand" "")
9118 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9119 (match_operand:SWI48 1 "register_operand" "")
9120 (match_dup 0)))
9121 (set (match_dup 1)
9122 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9123 (match_operand:SWI48 3 "register_operand" "r")
9124 (match_dup 1)))]
9125 "TARGET_CMOVE"
9126 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9127
9128 (define_expand "x86_shift<mode>_adj_2"
9129 [(use (match_operand:SWI48 0 "register_operand" ""))
9130 (use (match_operand:SWI48 1 "register_operand" ""))
9131 (use (match_operand:QI 2 "register_operand" ""))]
9132 ""
9133 {
9134 rtx label = gen_label_rtx ();
9135 rtx tmp;
9136
9137 emit_insn (gen_testqi_ccz_1 (operands[2],
9138 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9139
9140 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9141 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9142 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9143 gen_rtx_LABEL_REF (VOIDmode, label),
9144 pc_rtx);
9145 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9146 JUMP_LABEL (tmp) = label;
9147
9148 emit_move_insn (operands[0], operands[1]);
9149 ix86_expand_clear (operands[1]);
9150
9151 emit_label (label);
9152 LABEL_NUSES (label) = 1;
9153
9154 DONE;
9155 })
9156
9157 (define_insn "*ashl<mode>3_1"
9158 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9159 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9160 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9161 (clobber (reg:CC FLAGS_REG))]
9162 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9163 {
9164 switch (get_attr_type (insn))
9165 {
9166 case TYPE_LEA:
9167 return "#";
9168
9169 case TYPE_ALU:
9170 gcc_assert (operands[2] == const1_rtx);
9171 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9172 return "add{<imodesuffix>}\t%0, %0";
9173
9174 default:
9175 if (operands[2] == const1_rtx
9176 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9177 return "sal{<imodesuffix>}\t%0";
9178 else
9179 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9180 }
9181 }
9182 [(set (attr "type")
9183 (cond [(eq_attr "alternative" "1")
9184 (const_string "lea")
9185 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9186 (const_int 0))
9187 (match_operand 0 "register_operand" ""))
9188 (match_operand 2 "const1_operand" ""))
9189 (const_string "alu")
9190 ]
9191 (const_string "ishift")))
9192 (set (attr "length_immediate")
9193 (if_then_else
9194 (ior (eq_attr "type" "alu")
9195 (and (eq_attr "type" "ishift")
9196 (and (match_operand 2 "const1_operand" "")
9197 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9198 (const_int 0)))))
9199 (const_string "0")
9200 (const_string "*")))
9201 (set_attr "mode" "<MODE>")])
9202
9203 (define_insn "*ashlsi3_1_zext"
9204 [(set (match_operand:DI 0 "register_operand" "=r,r")
9205 (zero_extend:DI
9206 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9207 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9208 (clobber (reg:CC FLAGS_REG))]
9209 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9210 {
9211 switch (get_attr_type (insn))
9212 {
9213 case TYPE_LEA:
9214 return "#";
9215
9216 case TYPE_ALU:
9217 gcc_assert (operands[2] == const1_rtx);
9218 return "add{l}\t%k0, %k0";
9219
9220 default:
9221 if (operands[2] == const1_rtx
9222 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9223 return "sal{l}\t%k0";
9224 else
9225 return "sal{l}\t{%2, %k0|%k0, %2}";
9226 }
9227 }
9228 [(set (attr "type")
9229 (cond [(eq_attr "alternative" "1")
9230 (const_string "lea")
9231 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9232 (const_int 0))
9233 (match_operand 2 "const1_operand" ""))
9234 (const_string "alu")
9235 ]
9236 (const_string "ishift")))
9237 (set (attr "length_immediate")
9238 (if_then_else
9239 (ior (eq_attr "type" "alu")
9240 (and (eq_attr "type" "ishift")
9241 (and (match_operand 2 "const1_operand" "")
9242 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9243 (const_int 0)))))
9244 (const_string "0")
9245 (const_string "*")))
9246 (set_attr "mode" "SI")])
9247
9248 (define_insn "*ashlhi3_1"
9249 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9250 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9251 (match_operand:QI 2 "nonmemory_operand" "cI")))
9252 (clobber (reg:CC FLAGS_REG))]
9253 "TARGET_PARTIAL_REG_STALL
9254 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9255 {
9256 switch (get_attr_type (insn))
9257 {
9258 case TYPE_ALU:
9259 gcc_assert (operands[2] == const1_rtx);
9260 return "add{w}\t%0, %0";
9261
9262 default:
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{w}\t%0";
9266 else
9267 return "sal{w}\t{%2, %0|%0, %2}";
9268 }
9269 }
9270 [(set (attr "type")
9271 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9272 (const_int 0))
9273 (match_operand 0 "register_operand" ""))
9274 (match_operand 2 "const1_operand" ""))
9275 (const_string "alu")
9276 ]
9277 (const_string "ishift")))
9278 (set (attr "length_immediate")
9279 (if_then_else
9280 (ior (eq_attr "type" "alu")
9281 (and (eq_attr "type" "ishift")
9282 (and (match_operand 2 "const1_operand" "")
9283 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9284 (const_int 0)))))
9285 (const_string "0")
9286 (const_string "*")))
9287 (set_attr "mode" "HI")])
9288
9289 (define_insn "*ashlhi3_1_lea"
9290 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9291 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9292 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "!TARGET_PARTIAL_REG_STALL
9295 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9296 {
9297 switch (get_attr_type (insn))
9298 {
9299 case TYPE_LEA:
9300 return "#";
9301
9302 case TYPE_ALU:
9303 gcc_assert (operands[2] == const1_rtx);
9304 return "add{w}\t%0, %0";
9305
9306 default:
9307 if (operands[2] == const1_rtx
9308 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9309 return "sal{w}\t%0";
9310 else
9311 return "sal{w}\t{%2, %0|%0, %2}";
9312 }
9313 }
9314 [(set (attr "type")
9315 (cond [(eq_attr "alternative" "1")
9316 (const_string "lea")
9317 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9318 (const_int 0))
9319 (match_operand 0 "register_operand" ""))
9320 (match_operand 2 "const1_operand" ""))
9321 (const_string "alu")
9322 ]
9323 (const_string "ishift")))
9324 (set (attr "length_immediate")
9325 (if_then_else
9326 (ior (eq_attr "type" "alu")
9327 (and (eq_attr "type" "ishift")
9328 (and (match_operand 2 "const1_operand" "")
9329 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9330 (const_int 0)))))
9331 (const_string "0")
9332 (const_string "*")))
9333 (set_attr "mode" "HI,SI")])
9334
9335 (define_insn "*ashlqi3_1"
9336 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9337 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9338 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9339 (clobber (reg:CC FLAGS_REG))]
9340 "TARGET_PARTIAL_REG_STALL
9341 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9342 {
9343 switch (get_attr_type (insn))
9344 {
9345 case TYPE_ALU:
9346 gcc_assert (operands[2] == const1_rtx);
9347 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9348 return "add{l}\t%k0, %k0";
9349 else
9350 return "add{b}\t%0, %0";
9351
9352 default:
9353 if (operands[2] == const1_rtx
9354 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9355 {
9356 if (get_attr_mode (insn) == MODE_SI)
9357 return "sal{l}\t%k0";
9358 else
9359 return "sal{b}\t%0";
9360 }
9361 else
9362 {
9363 if (get_attr_mode (insn) == MODE_SI)
9364 return "sal{l}\t{%2, %k0|%k0, %2}";
9365 else
9366 return "sal{b}\t{%2, %0|%0, %2}";
9367 }
9368 }
9369 }
9370 [(set (attr "type")
9371 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9372 (const_int 0))
9373 (match_operand 0 "register_operand" ""))
9374 (match_operand 2 "const1_operand" ""))
9375 (const_string "alu")
9376 ]
9377 (const_string "ishift")))
9378 (set (attr "length_immediate")
9379 (if_then_else
9380 (ior (eq_attr "type" "alu")
9381 (and (eq_attr "type" "ishift")
9382 (and (match_operand 2 "const1_operand" "")
9383 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9384 (const_int 0)))))
9385 (const_string "0")
9386 (const_string "*")))
9387 (set_attr "mode" "QI,SI")])
9388
9389 ;; %%% Potential partial reg stall on alternative 2. What to do?
9390 (define_insn "*ashlqi3_1_lea"
9391 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9392 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9393 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "!TARGET_PARTIAL_REG_STALL
9396 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9397 {
9398 switch (get_attr_type (insn))
9399 {
9400 case TYPE_LEA:
9401 return "#";
9402
9403 case TYPE_ALU:
9404 gcc_assert (operands[2] == const1_rtx);
9405 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9406 return "add{l}\t%k0, %k0";
9407 else
9408 return "add{b}\t%0, %0";
9409
9410 default:
9411 if (operands[2] == const1_rtx
9412 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9413 {
9414 if (get_attr_mode (insn) == MODE_SI)
9415 return "sal{l}\t%k0";
9416 else
9417 return "sal{b}\t%0";
9418 }
9419 else
9420 {
9421 if (get_attr_mode (insn) == MODE_SI)
9422 return "sal{l}\t{%2, %k0|%k0, %2}";
9423 else
9424 return "sal{b}\t{%2, %0|%0, %2}";
9425 }
9426 }
9427 }
9428 [(set (attr "type")
9429 (cond [(eq_attr "alternative" "2")
9430 (const_string "lea")
9431 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9432 (const_int 0))
9433 (match_operand 0 "register_operand" ""))
9434 (match_operand 2 "const1_operand" ""))
9435 (const_string "alu")
9436 ]
9437 (const_string "ishift")))
9438 (set (attr "length_immediate")
9439 (if_then_else
9440 (ior (eq_attr "type" "alu")
9441 (and (eq_attr "type" "ishift")
9442 (and (match_operand 2 "const1_operand" "")
9443 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9444 (const_int 0)))))
9445 (const_string "0")
9446 (const_string "*")))
9447 (set_attr "mode" "QI,SI,SI")])
9448
9449 (define_insn "*ashlqi3_1_slp"
9450 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9451 (ashift:QI (match_dup 0)
9452 (match_operand:QI 1 "nonmemory_operand" "cI")))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "(optimize_function_for_size_p (cfun)
9455 || !TARGET_PARTIAL_FLAG_REG_STALL
9456 || (operands[1] == const1_rtx
9457 && (TARGET_SHIFT1
9458 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9459 {
9460 switch (get_attr_type (insn))
9461 {
9462 case TYPE_ALU:
9463 gcc_assert (operands[1] == const1_rtx);
9464 return "add{b}\t%0, %0";
9465
9466 default:
9467 if (operands[1] == const1_rtx
9468 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9469 return "sal{b}\t%0";
9470 else
9471 return "sal{b}\t{%1, %0|%0, %1}";
9472 }
9473 }
9474 [(set (attr "type")
9475 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9476 (const_int 0))
9477 (match_operand 0 "register_operand" ""))
9478 (match_operand 1 "const1_operand" ""))
9479 (const_string "alu")
9480 ]
9481 (const_string "ishift1")))
9482 (set (attr "length_immediate")
9483 (if_then_else
9484 (ior (eq_attr "type" "alu")
9485 (and (eq_attr "type" "ishift1")
9486 (and (match_operand 1 "const1_operand" "")
9487 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9488 (const_int 0)))))
9489 (const_string "0")
9490 (const_string "*")))
9491 (set_attr "mode" "QI")])
9492
9493 ;; Convert lea to the lea pattern to avoid flags dependency.
9494 (define_split
9495 [(set (match_operand 0 "register_operand" "")
9496 (ashift (match_operand 1 "index_register_operand" "")
9497 (match_operand:QI 2 "const_int_operand" "")))
9498 (clobber (reg:CC FLAGS_REG))]
9499 "reload_completed
9500 && true_regnum (operands[0]) != true_regnum (operands[1])"
9501 [(const_int 0)]
9502 {
9503 rtx pat;
9504 enum machine_mode mode = GET_MODE (operands[0]);
9505
9506 if (mode != Pmode)
9507 operands[1] = gen_lowpart (Pmode, operands[1]);
9508 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9509
9510 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9511
9512 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9513 operands[0] = gen_lowpart (SImode, operands[0]);
9514
9515 if (TARGET_64BIT && mode != Pmode)
9516 pat = gen_rtx_SUBREG (SImode, pat, 0);
9517
9518 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9519 DONE;
9520 })
9521
9522 ;; Convert lea to the lea pattern to avoid flags dependency.
9523 (define_split
9524 [(set (match_operand:DI 0 "register_operand" "")
9525 (zero_extend:DI
9526 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9527 (match_operand:QI 2 "const_int_operand" ""))))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "TARGET_64BIT && reload_completed
9530 && true_regnum (operands[0]) != true_regnum (operands[1])"
9531 [(set (match_dup 0)
9532 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9533 {
9534 operands[1] = gen_lowpart (DImode, operands[1]);
9535 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9536 })
9537
9538 ;; This pattern can't accept a variable shift count, since shifts by
9539 ;; zero don't affect the flags. We assume that shifts by constant
9540 ;; zero are optimized away.
9541 (define_insn "*ashl<mode>3_cmp"
9542 [(set (reg FLAGS_REG)
9543 (compare
9544 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9545 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9546 (const_int 0)))
9547 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9548 (ashift:SWI (match_dup 1) (match_dup 2)))]
9549 "(optimize_function_for_size_p (cfun)
9550 || !TARGET_PARTIAL_FLAG_REG_STALL
9551 || (operands[2] == const1_rtx
9552 && (TARGET_SHIFT1
9553 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9554 && ix86_match_ccmode (insn, CCGOCmode)
9555 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9556 {
9557 switch (get_attr_type (insn))
9558 {
9559 case TYPE_ALU:
9560 gcc_assert (operands[2] == const1_rtx);
9561 return "add{<imodesuffix>}\t%0, %0";
9562
9563 default:
9564 if (operands[2] == const1_rtx
9565 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566 return "sal{<imodesuffix>}\t%0";
9567 else
9568 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9569 }
9570 }
9571 [(set (attr "type")
9572 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9573 (const_int 0))
9574 (match_operand 0 "register_operand" ""))
9575 (match_operand 2 "const1_operand" ""))
9576 (const_string "alu")
9577 ]
9578 (const_string "ishift")))
9579 (set (attr "length_immediate")
9580 (if_then_else
9581 (ior (eq_attr "type" "alu")
9582 (and (eq_attr "type" "ishift")
9583 (and (match_operand 2 "const1_operand" "")
9584 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9585 (const_int 0)))))
9586 (const_string "0")
9587 (const_string "*")))
9588 (set_attr "mode" "<MODE>")])
9589
9590 (define_insn "*ashlsi3_cmp_zext"
9591 [(set (reg FLAGS_REG)
9592 (compare
9593 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9594 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9595 (const_int 0)))
9596 (set (match_operand:DI 0 "register_operand" "=r")
9597 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9598 "TARGET_64BIT
9599 && (optimize_function_for_size_p (cfun)
9600 || !TARGET_PARTIAL_FLAG_REG_STALL
9601 || (operands[2] == const1_rtx
9602 && (TARGET_SHIFT1
9603 || TARGET_DOUBLE_WITH_ADD)))
9604 && ix86_match_ccmode (insn, CCGOCmode)
9605 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9606 {
9607 switch (get_attr_type (insn))
9608 {
9609 case TYPE_ALU:
9610 gcc_assert (operands[2] == const1_rtx);
9611 return "add{l}\t%k0, %k0";
9612
9613 default:
9614 if (operands[2] == const1_rtx
9615 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9616 return "sal{l}\t%k0";
9617 else
9618 return "sal{l}\t{%2, %k0|%k0, %2}";
9619 }
9620 }
9621 [(set (attr "type")
9622 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9623 (const_int 0))
9624 (match_operand 2 "const1_operand" ""))
9625 (const_string "alu")
9626 ]
9627 (const_string "ishift")))
9628 (set (attr "length_immediate")
9629 (if_then_else
9630 (ior (eq_attr "type" "alu")
9631 (and (eq_attr "type" "ishift")
9632 (and (match_operand 2 "const1_operand" "")
9633 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9634 (const_int 0)))))
9635 (const_string "0")
9636 (const_string "*")))
9637 (set_attr "mode" "SI")])
9638
9639 (define_insn "*ashl<mode>3_cconly"
9640 [(set (reg FLAGS_REG)
9641 (compare
9642 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9643 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9644 (const_int 0)))
9645 (clobber (match_scratch:SWI 0 "=<r>"))]
9646 "(optimize_function_for_size_p (cfun)
9647 || !TARGET_PARTIAL_FLAG_REG_STALL
9648 || (operands[2] == const1_rtx
9649 && (TARGET_SHIFT1
9650 || TARGET_DOUBLE_WITH_ADD)))
9651 && ix86_match_ccmode (insn, CCGOCmode)
9652 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9653 {
9654 switch (get_attr_type (insn))
9655 {
9656 case TYPE_ALU:
9657 gcc_assert (operands[2] == const1_rtx);
9658 return "add{<imodesuffix>}\t%0, %0";
9659
9660 default:
9661 if (operands[2] == const1_rtx
9662 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9663 return "sal{<imodesuffix>}\t%0";
9664 else
9665 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9666 }
9667 }
9668 [(set (attr "type")
9669 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9670 (const_int 0))
9671 (match_operand 0 "register_operand" ""))
9672 (match_operand 2 "const1_operand" ""))
9673 (const_string "alu")
9674 ]
9675 (const_string "ishift")))
9676 (set (attr "length_immediate")
9677 (if_then_else
9678 (ior (eq_attr "type" "alu")
9679 (and (eq_attr "type" "ishift")
9680 (and (match_operand 2 "const1_operand" "")
9681 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9682 (const_int 0)))))
9683 (const_string "0")
9684 (const_string "*")))
9685 (set_attr "mode" "<MODE>")])
9686
9687 ;; See comment above `ashl<mode>3' about how this works.
9688
9689 (define_expand "<shiftrt_insn><mode>3"
9690 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9691 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9692 (match_operand:QI 2 "nonmemory_operand" "")))]
9693 ""
9694 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9695
9696 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9697 [(set (match_operand:DWI 0 "register_operand" "=r")
9698 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9699 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9700 (clobber (reg:CC FLAGS_REG))]
9701 ""
9702 "#"
9703 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9704 [(const_int 0)]
9705 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9706 [(set_attr "type" "multi")])
9707
9708 ;; By default we don't ask for a scratch register, because when DWImode
9709 ;; values are manipulated, registers are already at a premium. But if
9710 ;; we have one handy, we won't turn it away.
9711
9712 (define_peephole2
9713 [(match_scratch:DWIH 3 "r")
9714 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9715 (any_shiftrt:<DWI>
9716 (match_operand:<DWI> 1 "register_operand" "")
9717 (match_operand:QI 2 "nonmemory_operand" "")))
9718 (clobber (reg:CC FLAGS_REG))])
9719 (match_dup 3)]
9720 "TARGET_CMOVE"
9721 [(const_int 0)]
9722 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9723
9724 (define_insn "x86_64_shrd"
9725 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9726 (ior:DI (ashiftrt:DI (match_dup 0)
9727 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9728 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9729 (minus:QI (const_int 64) (match_dup 2)))))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "TARGET_64BIT"
9732 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9733 [(set_attr "type" "ishift")
9734 (set_attr "prefix_0f" "1")
9735 (set_attr "mode" "DI")
9736 (set_attr "athlon_decode" "vector")
9737 (set_attr "amdfam10_decode" "vector")])
9738
9739 (define_insn "x86_shrd"
9740 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9741 (ior:SI (ashiftrt:SI (match_dup 0)
9742 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9743 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9744 (minus:QI (const_int 32) (match_dup 2)))))
9745 (clobber (reg:CC FLAGS_REG))]
9746 ""
9747 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9748 [(set_attr "type" "ishift")
9749 (set_attr "prefix_0f" "1")
9750 (set_attr "mode" "SI")
9751 (set_attr "pent_pair" "np")
9752 (set_attr "athlon_decode" "vector")
9753 (set_attr "amdfam10_decode" "vector")])
9754
9755 (define_insn "ashrdi3_cvt"
9756 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9757 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9758 (match_operand:QI 2 "const_int_operand" "")))
9759 (clobber (reg:CC FLAGS_REG))]
9760 "TARGET_64BIT && INTVAL (operands[2]) == 63
9761 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9762 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9763 "@
9764 {cqto|cqo}
9765 sar{q}\t{%2, %0|%0, %2}"
9766 [(set_attr "type" "imovx,ishift")
9767 (set_attr "prefix_0f" "0,*")
9768 (set_attr "length_immediate" "0,*")
9769 (set_attr "modrm" "0,1")
9770 (set_attr "mode" "DI")])
9771
9772 (define_insn "ashrsi3_cvt"
9773 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9774 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9775 (match_operand:QI 2 "const_int_operand" "")))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "INTVAL (operands[2]) == 31
9778 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9779 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9780 "@
9781 {cltd|cdq}
9782 sar{l}\t{%2, %0|%0, %2}"
9783 [(set_attr "type" "imovx,ishift")
9784 (set_attr "prefix_0f" "0,*")
9785 (set_attr "length_immediate" "0,*")
9786 (set_attr "modrm" "0,1")
9787 (set_attr "mode" "SI")])
9788
9789 (define_insn "*ashrsi3_cvt_zext"
9790 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9791 (zero_extend:DI
9792 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9793 (match_operand:QI 2 "const_int_operand" ""))))
9794 (clobber (reg:CC FLAGS_REG))]
9795 "TARGET_64BIT && INTVAL (operands[2]) == 31
9796 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9797 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9798 "@
9799 {cltd|cdq}
9800 sar{l}\t{%2, %k0|%k0, %2}"
9801 [(set_attr "type" "imovx,ishift")
9802 (set_attr "prefix_0f" "0,*")
9803 (set_attr "length_immediate" "0,*")
9804 (set_attr "modrm" "0,1")
9805 (set_attr "mode" "SI")])
9806
9807 (define_expand "x86_shift<mode>_adj_3"
9808 [(use (match_operand:SWI48 0 "register_operand" ""))
9809 (use (match_operand:SWI48 1 "register_operand" ""))
9810 (use (match_operand:QI 2 "register_operand" ""))]
9811 ""
9812 {
9813 rtx label = gen_label_rtx ();
9814 rtx tmp;
9815
9816 emit_insn (gen_testqi_ccz_1 (operands[2],
9817 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9818
9819 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9820 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9821 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9822 gen_rtx_LABEL_REF (VOIDmode, label),
9823 pc_rtx);
9824 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9825 JUMP_LABEL (tmp) = label;
9826
9827 emit_move_insn (operands[0], operands[1]);
9828 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9829 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9830 emit_label (label);
9831 LABEL_NUSES (label) = 1;
9832
9833 DONE;
9834 })
9835
9836 (define_insn "*<shiftrt_insn><mode>3_1"
9837 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9838 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9839 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9842 {
9843 if (operands[2] == const1_rtx
9844 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9845 return "<shiftrt>{<imodesuffix>}\t%0";
9846 else
9847 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9848 }
9849 [(set_attr "type" "ishift")
9850 (set (attr "length_immediate")
9851 (if_then_else
9852 (and (match_operand 2 "const1_operand" "")
9853 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9854 (const_int 0)))
9855 (const_string "0")
9856 (const_string "*")))
9857 (set_attr "mode" "<MODE>")])
9858
9859 (define_insn "*<shiftrt_insn>si3_1_zext"
9860 [(set (match_operand:DI 0 "register_operand" "=r")
9861 (zero_extend:DI
9862 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9863 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9864 (clobber (reg:CC FLAGS_REG))]
9865 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9866 {
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869 return "<shiftrt>{l}\t%k0";
9870 else
9871 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9872 }
9873 [(set_attr "type" "ishift")
9874 (set (attr "length_immediate")
9875 (if_then_else
9876 (and (match_operand 2 "const1_operand" "")
9877 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9878 (const_int 0)))
9879 (const_string "0")
9880 (const_string "*")))
9881 (set_attr "mode" "SI")])
9882
9883 (define_insn "*<shiftrt_insn>qi3_1_slp"
9884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9885 (any_shiftrt:QI (match_dup 0)
9886 (match_operand:QI 1 "nonmemory_operand" "cI")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "(optimize_function_for_size_p (cfun)
9889 || !TARGET_PARTIAL_REG_STALL
9890 || (operands[1] == const1_rtx
9891 && TARGET_SHIFT1))"
9892 {
9893 if (operands[1] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 return "<shiftrt>{b}\t%0";
9896 else
9897 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9898 }
9899 [(set_attr "type" "ishift1")
9900 (set (attr "length_immediate")
9901 (if_then_else
9902 (and (match_operand 1 "const1_operand" "")
9903 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9904 (const_int 0)))
9905 (const_string "0")
9906 (const_string "*")))
9907 (set_attr "mode" "QI")])
9908
9909 ;; This pattern can't accept a variable shift count, since shifts by
9910 ;; zero don't affect the flags. We assume that shifts by constant
9911 ;; zero are optimized away.
9912 (define_insn "*<shiftrt_insn><mode>3_cmp"
9913 [(set (reg FLAGS_REG)
9914 (compare
9915 (any_shiftrt:SWI
9916 (match_operand:SWI 1 "nonimmediate_operand" "0")
9917 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9918 (const_int 0)))
9919 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9920 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9921 "(optimize_function_for_size_p (cfun)
9922 || !TARGET_PARTIAL_FLAG_REG_STALL
9923 || (operands[2] == const1_rtx
9924 && TARGET_SHIFT1))
9925 && ix86_match_ccmode (insn, CCGOCmode)
9926 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9927 {
9928 if (operands[2] == const1_rtx
9929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9930 return "<shiftrt>{<imodesuffix>}\t%0";
9931 else
9932 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9933 }
9934 [(set_attr "type" "ishift")
9935 (set (attr "length_immediate")
9936 (if_then_else
9937 (and (match_operand 2 "const1_operand" "")
9938 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9939 (const_int 0)))
9940 (const_string "0")
9941 (const_string "*")))
9942 (set_attr "mode" "<MODE>")])
9943
9944 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9945 [(set (reg FLAGS_REG)
9946 (compare
9947 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9949 (const_int 0)))
9950 (set (match_operand:DI 0 "register_operand" "=r")
9951 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9952 "TARGET_64BIT
9953 && (optimize_function_for_size_p (cfun)
9954 || !TARGET_PARTIAL_FLAG_REG_STALL
9955 || (operands[2] == const1_rtx
9956 && TARGET_SHIFT1))
9957 && ix86_match_ccmode (insn, CCGOCmode)
9958 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9959 {
9960 if (operands[2] == const1_rtx
9961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9962 return "<shiftrt>{l}\t%k0";
9963 else
9964 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9965 }
9966 [(set_attr "type" "ishift")
9967 (set (attr "length_immediate")
9968 (if_then_else
9969 (and (match_operand 2 "const1_operand" "")
9970 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9971 (const_int 0)))
9972 (const_string "0")
9973 (const_string "*")))
9974 (set_attr "mode" "SI")])
9975
9976 (define_insn "*<shiftrt_insn><mode>3_cconly"
9977 [(set (reg FLAGS_REG)
9978 (compare
9979 (any_shiftrt:SWI
9980 (match_operand:SWI 1 "nonimmediate_operand" "0")
9981 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9982 (const_int 0)))
9983 (clobber (match_scratch:SWI 0 "=<r>"))]
9984 "(optimize_function_for_size_p (cfun)
9985 || !TARGET_PARTIAL_FLAG_REG_STALL
9986 || (operands[2] == const1_rtx
9987 && TARGET_SHIFT1))
9988 && ix86_match_ccmode (insn, CCGOCmode)
9989 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9990 {
9991 if (operands[2] == const1_rtx
9992 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993 return "<shiftrt>{<imodesuffix>}\t%0";
9994 else
9995 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9996 }
9997 [(set_attr "type" "ishift")
9998 (set (attr "length_immediate")
9999 (if_then_else
10000 (and (match_operand 2 "const1_operand" "")
10001 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10002 (const_int 0)))
10003 (const_string "0")
10004 (const_string "*")))
10005 (set_attr "mode" "<MODE>")])
10006 \f
10007 ;; Rotate instructions
10008
10009 (define_expand "<rotate_insn>ti3"
10010 [(set (match_operand:TI 0 "register_operand" "")
10011 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10012 (match_operand:QI 2 "nonmemory_operand" "")))]
10013 "TARGET_64BIT"
10014 {
10015 if (const_1_to_63_operand (operands[2], VOIDmode))
10016 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10017 (operands[0], operands[1], operands[2]));
10018 else
10019 FAIL;
10020
10021 DONE;
10022 })
10023
10024 (define_expand "<rotate_insn>di3"
10025 [(set (match_operand:DI 0 "shiftdi_operand" "")
10026 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10027 (match_operand:QI 2 "nonmemory_operand" "")))]
10028 ""
10029 {
10030 if (TARGET_64BIT)
10031 ix86_expand_binary_operator (<CODE>, DImode, operands);
10032 else if (const_1_to_31_operand (operands[2], VOIDmode))
10033 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10034 (operands[0], operands[1], operands[2]));
10035 else
10036 FAIL;
10037
10038 DONE;
10039 })
10040
10041 (define_expand "<rotate_insn><mode>3"
10042 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10043 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10044 (match_operand:QI 2 "nonmemory_operand" "")))]
10045 ""
10046 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10047
10048 ;; Implement rotation using two double-precision
10049 ;; shift instructions and a scratch register.
10050
10051 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10052 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10053 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10054 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10055 (clobber (reg:CC FLAGS_REG))
10056 (clobber (match_scratch:DWIH 3 "=&r"))]
10057 ""
10058 "#"
10059 "reload_completed"
10060 [(set (match_dup 3) (match_dup 4))
10061 (parallel
10062 [(set (match_dup 4)
10063 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10064 (lshiftrt:DWIH (match_dup 5)
10065 (minus:QI (match_dup 6) (match_dup 2)))))
10066 (clobber (reg:CC FLAGS_REG))])
10067 (parallel
10068 [(set (match_dup 5)
10069 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10070 (lshiftrt:DWIH (match_dup 3)
10071 (minus:QI (match_dup 6) (match_dup 2)))))
10072 (clobber (reg:CC FLAGS_REG))])]
10073 {
10074 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10075
10076 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10077 })
10078
10079 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10080 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10081 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10082 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10083 (clobber (reg:CC FLAGS_REG))
10084 (clobber (match_scratch:DWIH 3 "=&r"))]
10085 ""
10086 "#"
10087 "reload_completed"
10088 [(set (match_dup 3) (match_dup 4))
10089 (parallel
10090 [(set (match_dup 4)
10091 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10092 (ashift:DWIH (match_dup 5)
10093 (minus:QI (match_dup 6) (match_dup 2)))))
10094 (clobber (reg:CC FLAGS_REG))])
10095 (parallel
10096 [(set (match_dup 5)
10097 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10098 (ashift:DWIH (match_dup 3)
10099 (minus:QI (match_dup 6) (match_dup 2)))))
10100 (clobber (reg:CC FLAGS_REG))])]
10101 {
10102 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10103
10104 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10105 })
10106
10107 (define_insn "*<rotate_insn><mode>3_1"
10108 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10109 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10110 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10111 (clobber (reg:CC FLAGS_REG))]
10112 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10113 {
10114 if (operands[2] == const1_rtx
10115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116 return "<rotate>{<imodesuffix>}\t%0";
10117 else
10118 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10119 }
10120 [(set_attr "type" "rotate")
10121 (set (attr "length_immediate")
10122 (if_then_else
10123 (and (match_operand 2 "const1_operand" "")
10124 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10125 (const_int 0)))
10126 (const_string "0")
10127 (const_string "*")))
10128 (set_attr "mode" "<MODE>")])
10129
10130 (define_insn "*<rotate_insn>si3_1_zext"
10131 [(set (match_operand:DI 0 "register_operand" "=r")
10132 (zero_extend:DI
10133 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10134 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10135 (clobber (reg:CC FLAGS_REG))]
10136 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10137 {
10138 if (operands[2] == const1_rtx
10139 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10140 return "<rotate>{l}\t%k0";
10141 else
10142 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10143 }
10144 [(set_attr "type" "rotate")
10145 (set (attr "length_immediate")
10146 (if_then_else
10147 (and (match_operand 2 "const1_operand" "")
10148 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10149 (const_int 0)))
10150 (const_string "0")
10151 (const_string "*")))
10152 (set_attr "mode" "SI")])
10153
10154 (define_insn "*<rotate_insn>qi3_1_slp"
10155 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10156 (any_rotate:QI (match_dup 0)
10157 (match_operand:QI 1 "nonmemory_operand" "cI")))
10158 (clobber (reg:CC FLAGS_REG))]
10159 "(optimize_function_for_size_p (cfun)
10160 || !TARGET_PARTIAL_REG_STALL
10161 || (operands[1] == const1_rtx
10162 && TARGET_SHIFT1))"
10163 {
10164 if (operands[1] == const1_rtx
10165 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10166 return "<rotate>{b}\t%0";
10167 else
10168 return "<rotate>{b}\t{%1, %0|%0, %1}";
10169 }
10170 [(set_attr "type" "rotate1")
10171 (set (attr "length_immediate")
10172 (if_then_else
10173 (and (match_operand 1 "const1_operand" "")
10174 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10175 (const_int 0)))
10176 (const_string "0")
10177 (const_string "*")))
10178 (set_attr "mode" "QI")])
10179
10180 (define_split
10181 [(set (match_operand:HI 0 "register_operand" "")
10182 (any_rotate:HI (match_dup 0) (const_int 8)))
10183 (clobber (reg:CC FLAGS_REG))]
10184 "reload_completed
10185 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10186 [(parallel [(set (strict_low_part (match_dup 0))
10187 (bswap:HI (match_dup 0)))
10188 (clobber (reg:CC FLAGS_REG))])])
10189 \f
10190 ;; Bit set / bit test instructions
10191
10192 (define_expand "extv"
10193 [(set (match_operand:SI 0 "register_operand" "")
10194 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10195 (match_operand:SI 2 "const8_operand" "")
10196 (match_operand:SI 3 "const8_operand" "")))]
10197 ""
10198 {
10199 /* Handle extractions from %ah et al. */
10200 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10201 FAIL;
10202
10203 /* From mips.md: extract_bit_field doesn't verify that our source
10204 matches the predicate, so check it again here. */
10205 if (! ext_register_operand (operands[1], VOIDmode))
10206 FAIL;
10207 })
10208
10209 (define_expand "extzv"
10210 [(set (match_operand:SI 0 "register_operand" "")
10211 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10212 (match_operand:SI 2 "const8_operand" "")
10213 (match_operand:SI 3 "const8_operand" "")))]
10214 ""
10215 {
10216 /* Handle extractions from %ah et al. */
10217 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10218 FAIL;
10219
10220 /* From mips.md: extract_bit_field doesn't verify that our source
10221 matches the predicate, so check it again here. */
10222 if (! ext_register_operand (operands[1], VOIDmode))
10223 FAIL;
10224 })
10225
10226 (define_expand "insv"
10227 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10228 (match_operand 1 "const8_operand" "")
10229 (match_operand 2 "const8_operand" ""))
10230 (match_operand 3 "register_operand" ""))]
10231 ""
10232 {
10233 rtx (*gen_mov_insv_1) (rtx, rtx);
10234
10235 /* Handle insertions to %ah et al. */
10236 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10237 FAIL;
10238
10239 /* From mips.md: insert_bit_field doesn't verify that our source
10240 matches the predicate, so check it again here. */
10241 if (! ext_register_operand (operands[0], VOIDmode))
10242 FAIL;
10243
10244 gen_mov_insv_1 = (TARGET_64BIT
10245 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10246
10247 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10248 DONE;
10249 })
10250
10251 ;; %%% bts, btr, btc, bt.
10252 ;; In general these instructions are *slow* when applied to memory,
10253 ;; since they enforce atomic operation. When applied to registers,
10254 ;; it depends on the cpu implementation. They're never faster than
10255 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10256 ;; no point. But in 64-bit, we can't hold the relevant immediates
10257 ;; within the instruction itself, so operating on bits in the high
10258 ;; 32-bits of a register becomes easier.
10259 ;;
10260 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10261 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10262 ;; negdf respectively, so they can never be disabled entirely.
10263
10264 (define_insn "*btsq"
10265 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10266 (const_int 1)
10267 (match_operand:DI 1 "const_0_to_63_operand" ""))
10268 (const_int 1))
10269 (clobber (reg:CC FLAGS_REG))]
10270 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10271 "bts{q}\t{%1, %0|%0, %1}"
10272 [(set_attr "type" "alu1")
10273 (set_attr "prefix_0f" "1")
10274 (set_attr "mode" "DI")])
10275
10276 (define_insn "*btrq"
10277 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10278 (const_int 1)
10279 (match_operand:DI 1 "const_0_to_63_operand" ""))
10280 (const_int 0))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10283 "btr{q}\t{%1, %0|%0, %1}"
10284 [(set_attr "type" "alu1")
10285 (set_attr "prefix_0f" "1")
10286 (set_attr "mode" "DI")])
10287
10288 (define_insn "*btcq"
10289 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10290 (const_int 1)
10291 (match_operand:DI 1 "const_0_to_63_operand" ""))
10292 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10295 "btc{q}\t{%1, %0|%0, %1}"
10296 [(set_attr "type" "alu1")
10297 (set_attr "prefix_0f" "1")
10298 (set_attr "mode" "DI")])
10299
10300 ;; Allow Nocona to avoid these instructions if a register is available.
10301
10302 (define_peephole2
10303 [(match_scratch:DI 2 "r")
10304 (parallel [(set (zero_extract:DI
10305 (match_operand:DI 0 "register_operand" "")
10306 (const_int 1)
10307 (match_operand:DI 1 "const_0_to_63_operand" ""))
10308 (const_int 1))
10309 (clobber (reg:CC FLAGS_REG))])]
10310 "TARGET_64BIT && !TARGET_USE_BT"
10311 [(const_int 0)]
10312 {
10313 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10314 rtx op1;
10315
10316 if (HOST_BITS_PER_WIDE_INT >= 64)
10317 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10318 else if (i < HOST_BITS_PER_WIDE_INT)
10319 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10320 else
10321 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10322
10323 op1 = immed_double_const (lo, hi, DImode);
10324 if (i >= 31)
10325 {
10326 emit_move_insn (operands[2], op1);
10327 op1 = operands[2];
10328 }
10329
10330 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10331 DONE;
10332 })
10333
10334 (define_peephole2
10335 [(match_scratch:DI 2 "r")
10336 (parallel [(set (zero_extract:DI
10337 (match_operand:DI 0 "register_operand" "")
10338 (const_int 1)
10339 (match_operand:DI 1 "const_0_to_63_operand" ""))
10340 (const_int 0))
10341 (clobber (reg:CC FLAGS_REG))])]
10342 "TARGET_64BIT && !TARGET_USE_BT"
10343 [(const_int 0)]
10344 {
10345 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10346 rtx op1;
10347
10348 if (HOST_BITS_PER_WIDE_INT >= 64)
10349 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10350 else if (i < HOST_BITS_PER_WIDE_INT)
10351 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10352 else
10353 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10354
10355 op1 = immed_double_const (~lo, ~hi, DImode);
10356 if (i >= 32)
10357 {
10358 emit_move_insn (operands[2], op1);
10359 op1 = operands[2];
10360 }
10361
10362 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10363 DONE;
10364 })
10365
10366 (define_peephole2
10367 [(match_scratch:DI 2 "r")
10368 (parallel [(set (zero_extract:DI
10369 (match_operand:DI 0 "register_operand" "")
10370 (const_int 1)
10371 (match_operand:DI 1 "const_0_to_63_operand" ""))
10372 (not:DI (zero_extract:DI
10373 (match_dup 0) (const_int 1) (match_dup 1))))
10374 (clobber (reg:CC FLAGS_REG))])]
10375 "TARGET_64BIT && !TARGET_USE_BT"
10376 [(const_int 0)]
10377 {
10378 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10379 rtx op1;
10380
10381 if (HOST_BITS_PER_WIDE_INT >= 64)
10382 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10383 else if (i < HOST_BITS_PER_WIDE_INT)
10384 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10385 else
10386 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10387
10388 op1 = immed_double_const (lo, hi, DImode);
10389 if (i >= 31)
10390 {
10391 emit_move_insn (operands[2], op1);
10392 op1 = operands[2];
10393 }
10394
10395 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10396 DONE;
10397 })
10398
10399 (define_insn "*bt<mode>"
10400 [(set (reg:CCC FLAGS_REG)
10401 (compare:CCC
10402 (zero_extract:SWI48
10403 (match_operand:SWI48 0 "register_operand" "r")
10404 (const_int 1)
10405 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10406 (const_int 0)))]
10407 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10408 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10409 [(set_attr "type" "alu1")
10410 (set_attr "prefix_0f" "1")
10411 (set_attr "mode" "<MODE>")])
10412 \f
10413 ;; Store-flag instructions.
10414
10415 ;; For all sCOND expanders, also expand the compare or test insn that
10416 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10417
10418 (define_insn_and_split "*setcc_di_1"
10419 [(set (match_operand:DI 0 "register_operand" "=q")
10420 (match_operator:DI 1 "ix86_comparison_operator"
10421 [(reg FLAGS_REG) (const_int 0)]))]
10422 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10423 "#"
10424 "&& reload_completed"
10425 [(set (match_dup 2) (match_dup 1))
10426 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10427 {
10428 PUT_MODE (operands[1], QImode);
10429 operands[2] = gen_lowpart (QImode, operands[0]);
10430 })
10431
10432 (define_insn_and_split "*setcc_si_1_and"
10433 [(set (match_operand:SI 0 "register_operand" "=q")
10434 (match_operator:SI 1 "ix86_comparison_operator"
10435 [(reg FLAGS_REG) (const_int 0)]))
10436 (clobber (reg:CC FLAGS_REG))]
10437 "!TARGET_PARTIAL_REG_STALL
10438 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10439 "#"
10440 "&& reload_completed"
10441 [(set (match_dup 2) (match_dup 1))
10442 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10443 (clobber (reg:CC FLAGS_REG))])]
10444 {
10445 PUT_MODE (operands[1], QImode);
10446 operands[2] = gen_lowpart (QImode, operands[0]);
10447 })
10448
10449 (define_insn_and_split "*setcc_si_1_movzbl"
10450 [(set (match_operand:SI 0 "register_operand" "=q")
10451 (match_operator:SI 1 "ix86_comparison_operator"
10452 [(reg FLAGS_REG) (const_int 0)]))]
10453 "!TARGET_PARTIAL_REG_STALL
10454 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10455 "#"
10456 "&& reload_completed"
10457 [(set (match_dup 2) (match_dup 1))
10458 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10459 {
10460 PUT_MODE (operands[1], QImode);
10461 operands[2] = gen_lowpart (QImode, operands[0]);
10462 })
10463
10464 (define_insn "*setcc_qi"
10465 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10466 (match_operator:QI 1 "ix86_comparison_operator"
10467 [(reg FLAGS_REG) (const_int 0)]))]
10468 ""
10469 "set%C1\t%0"
10470 [(set_attr "type" "setcc")
10471 (set_attr "mode" "QI")])
10472
10473 (define_insn "*setcc_qi_slp"
10474 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10475 (match_operator:QI 1 "ix86_comparison_operator"
10476 [(reg FLAGS_REG) (const_int 0)]))]
10477 ""
10478 "set%C1\t%0"
10479 [(set_attr "type" "setcc")
10480 (set_attr "mode" "QI")])
10481
10482 ;; In general it is not safe to assume too much about CCmode registers,
10483 ;; so simplify-rtx stops when it sees a second one. Under certain
10484 ;; conditions this is safe on x86, so help combine not create
10485 ;;
10486 ;; seta %al
10487 ;; testb %al, %al
10488 ;; sete %al
10489
10490 (define_split
10491 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10492 (ne:QI (match_operator 1 "ix86_comparison_operator"
10493 [(reg FLAGS_REG) (const_int 0)])
10494 (const_int 0)))]
10495 ""
10496 [(set (match_dup 0) (match_dup 1))]
10497 "PUT_MODE (operands[1], QImode);")
10498
10499 (define_split
10500 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10501 (ne:QI (match_operator 1 "ix86_comparison_operator"
10502 [(reg FLAGS_REG) (const_int 0)])
10503 (const_int 0)))]
10504 ""
10505 [(set (match_dup 0) (match_dup 1))]
10506 "PUT_MODE (operands[1], QImode);")
10507
10508 (define_split
10509 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10510 (eq:QI (match_operator 1 "ix86_comparison_operator"
10511 [(reg FLAGS_REG) (const_int 0)])
10512 (const_int 0)))]
10513 ""
10514 [(set (match_dup 0) (match_dup 1))]
10515 {
10516 rtx new_op1 = copy_rtx (operands[1]);
10517 operands[1] = new_op1;
10518 PUT_MODE (new_op1, QImode);
10519 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10520 GET_MODE (XEXP (new_op1, 0))));
10521
10522 /* Make sure that (a) the CCmode we have for the flags is strong
10523 enough for the reversed compare or (b) we have a valid FP compare. */
10524 if (! ix86_comparison_operator (new_op1, VOIDmode))
10525 FAIL;
10526 })
10527
10528 (define_split
10529 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10530 (eq:QI (match_operator 1 "ix86_comparison_operator"
10531 [(reg FLAGS_REG) (const_int 0)])
10532 (const_int 0)))]
10533 ""
10534 [(set (match_dup 0) (match_dup 1))]
10535 {
10536 rtx new_op1 = copy_rtx (operands[1]);
10537 operands[1] = new_op1;
10538 PUT_MODE (new_op1, QImode);
10539 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10540 GET_MODE (XEXP (new_op1, 0))));
10541
10542 /* Make sure that (a) the CCmode we have for the flags is strong
10543 enough for the reversed compare or (b) we have a valid FP compare. */
10544 if (! ix86_comparison_operator (new_op1, VOIDmode))
10545 FAIL;
10546 })
10547
10548 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10549 ;; subsequent logical operations are used to imitate conditional moves.
10550 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10551 ;; it directly.
10552
10553 (define_insn "*avx_setcc<mode>"
10554 [(set (match_operand:MODEF 0 "register_operand" "=x")
10555 (match_operator:MODEF 1 "avx_comparison_float_operator"
10556 [(match_operand:MODEF 2 "register_operand" "x")
10557 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10558 "TARGET_AVX"
10559 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10560 [(set_attr "type" "ssecmp")
10561 (set_attr "prefix" "vex")
10562 (set_attr "length_immediate" "1")
10563 (set_attr "mode" "<MODE>")])
10564
10565 (define_insn "*sse_setcc<mode>"
10566 [(set (match_operand:MODEF 0 "register_operand" "=x")
10567 (match_operator:MODEF 1 "sse_comparison_operator"
10568 [(match_operand:MODEF 2 "register_operand" "0")
10569 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10570 "SSE_FLOAT_MODE_P (<MODE>mode)"
10571 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10572 [(set_attr "type" "ssecmp")
10573 (set_attr "length_immediate" "1")
10574 (set_attr "mode" "<MODE>")])
10575 \f
10576 ;; Basic conditional jump instructions.
10577 ;; We ignore the overflow flag for signed branch instructions.
10578
10579 (define_insn "*jcc_1"
10580 [(set (pc)
10581 (if_then_else (match_operator 1 "ix86_comparison_operator"
10582 [(reg FLAGS_REG) (const_int 0)])
10583 (label_ref (match_operand 0 "" ""))
10584 (pc)))]
10585 ""
10586 "%+j%C1\t%l0"
10587 [(set_attr "type" "ibr")
10588 (set_attr "modrm" "0")
10589 (set (attr "length")
10590 (if_then_else (and (ge (minus (match_dup 0) (pc))
10591 (const_int -126))
10592 (lt (minus (match_dup 0) (pc))
10593 (const_int 128)))
10594 (const_int 2)
10595 (const_int 6)))])
10596
10597 (define_insn "*jcc_2"
10598 [(set (pc)
10599 (if_then_else (match_operator 1 "ix86_comparison_operator"
10600 [(reg FLAGS_REG) (const_int 0)])
10601 (pc)
10602 (label_ref (match_operand 0 "" ""))))]
10603 ""
10604 "%+j%c1\t%l0"
10605 [(set_attr "type" "ibr")
10606 (set_attr "modrm" "0")
10607 (set (attr "length")
10608 (if_then_else (and (ge (minus (match_dup 0) (pc))
10609 (const_int -126))
10610 (lt (minus (match_dup 0) (pc))
10611 (const_int 128)))
10612 (const_int 2)
10613 (const_int 6)))])
10614
10615 ;; In general it is not safe to assume too much about CCmode registers,
10616 ;; so simplify-rtx stops when it sees a second one. Under certain
10617 ;; conditions this is safe on x86, so help combine not create
10618 ;;
10619 ;; seta %al
10620 ;; testb %al, %al
10621 ;; je Lfoo
10622
10623 (define_split
10624 [(set (pc)
10625 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10626 [(reg FLAGS_REG) (const_int 0)])
10627 (const_int 0))
10628 (label_ref (match_operand 1 "" ""))
10629 (pc)))]
10630 ""
10631 [(set (pc)
10632 (if_then_else (match_dup 0)
10633 (label_ref (match_dup 1))
10634 (pc)))]
10635 "PUT_MODE (operands[0], VOIDmode);")
10636
10637 (define_split
10638 [(set (pc)
10639 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10640 [(reg FLAGS_REG) (const_int 0)])
10641 (const_int 0))
10642 (label_ref (match_operand 1 "" ""))
10643 (pc)))]
10644 ""
10645 [(set (pc)
10646 (if_then_else (match_dup 0)
10647 (label_ref (match_dup 1))
10648 (pc)))]
10649 {
10650 rtx new_op0 = copy_rtx (operands[0]);
10651 operands[0] = new_op0;
10652 PUT_MODE (new_op0, VOIDmode);
10653 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10654 GET_MODE (XEXP (new_op0, 0))));
10655
10656 /* Make sure that (a) the CCmode we have for the flags is strong
10657 enough for the reversed compare or (b) we have a valid FP compare. */
10658 if (! ix86_comparison_operator (new_op0, VOIDmode))
10659 FAIL;
10660 })
10661
10662 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10663 ;; pass generates from shift insn with QImode operand. Actually, the mode
10664 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10665 ;; appropriate modulo of the bit offset value.
10666
10667 (define_insn_and_split "*jcc_bt<mode>"
10668 [(set (pc)
10669 (if_then_else (match_operator 0 "bt_comparison_operator"
10670 [(zero_extract:SWI48
10671 (match_operand:SWI48 1 "register_operand" "r")
10672 (const_int 1)
10673 (zero_extend:SI
10674 (match_operand:QI 2 "register_operand" "r")))
10675 (const_int 0)])
10676 (label_ref (match_operand 3 "" ""))
10677 (pc)))
10678 (clobber (reg:CC FLAGS_REG))]
10679 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10680 "#"
10681 "&& 1"
10682 [(set (reg:CCC FLAGS_REG)
10683 (compare:CCC
10684 (zero_extract:SWI48
10685 (match_dup 1)
10686 (const_int 1)
10687 (match_dup 2))
10688 (const_int 0)))
10689 (set (pc)
10690 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10691 (label_ref (match_dup 3))
10692 (pc)))]
10693 {
10694 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10695
10696 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10697 })
10698
10699 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10700 ;; also for DImode, this is what combine produces.
10701 (define_insn_and_split "*jcc_bt<mode>_mask"
10702 [(set (pc)
10703 (if_then_else (match_operator 0 "bt_comparison_operator"
10704 [(zero_extract:SWI48
10705 (match_operand:SWI48 1 "register_operand" "r")
10706 (const_int 1)
10707 (and:SI
10708 (match_operand:SI 2 "register_operand" "r")
10709 (match_operand:SI 3 "const_int_operand" "n")))])
10710 (label_ref (match_operand 4 "" ""))
10711 (pc)))
10712 (clobber (reg:CC FLAGS_REG))]
10713 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10715 == GET_MODE_BITSIZE (<MODE>mode)-1"
10716 "#"
10717 "&& 1"
10718 [(set (reg:CCC FLAGS_REG)
10719 (compare:CCC
10720 (zero_extract:SWI48
10721 (match_dup 1)
10722 (const_int 1)
10723 (match_dup 2))
10724 (const_int 0)))
10725 (set (pc)
10726 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10727 (label_ref (match_dup 4))
10728 (pc)))]
10729 {
10730 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10731
10732 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10733 })
10734
10735 (define_insn_and_split "*jcc_btsi_1"
10736 [(set (pc)
10737 (if_then_else (match_operator 0 "bt_comparison_operator"
10738 [(and:SI
10739 (lshiftrt:SI
10740 (match_operand:SI 1 "register_operand" "r")
10741 (match_operand:QI 2 "register_operand" "r"))
10742 (const_int 1))
10743 (const_int 0)])
10744 (label_ref (match_operand 3 "" ""))
10745 (pc)))
10746 (clobber (reg:CC FLAGS_REG))]
10747 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10748 "#"
10749 "&& 1"
10750 [(set (reg:CCC FLAGS_REG)
10751 (compare:CCC
10752 (zero_extract:SI
10753 (match_dup 1)
10754 (const_int 1)
10755 (match_dup 2))
10756 (const_int 0)))
10757 (set (pc)
10758 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10759 (label_ref (match_dup 3))
10760 (pc)))]
10761 {
10762 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10763
10764 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10765 })
10766
10767 ;; avoid useless masking of bit offset operand
10768 (define_insn_and_split "*jcc_btsi_mask_1"
10769 [(set (pc)
10770 (if_then_else
10771 (match_operator 0 "bt_comparison_operator"
10772 [(and:SI
10773 (lshiftrt:SI
10774 (match_operand:SI 1 "register_operand" "r")
10775 (subreg:QI
10776 (and:SI
10777 (match_operand:SI 2 "register_operand" "r")
10778 (match_operand:SI 3 "const_int_operand" "n")) 0))
10779 (const_int 1))
10780 (const_int 0)])
10781 (label_ref (match_operand 4 "" ""))
10782 (pc)))
10783 (clobber (reg:CC FLAGS_REG))]
10784 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10785 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10786 "#"
10787 "&& 1"
10788 [(set (reg:CCC FLAGS_REG)
10789 (compare:CCC
10790 (zero_extract:SI
10791 (match_dup 1)
10792 (const_int 1)
10793 (match_dup 2))
10794 (const_int 0)))
10795 (set (pc)
10796 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10797 (label_ref (match_dup 4))
10798 (pc)))]
10799 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10800
10801 ;; Define combination compare-and-branch fp compare instructions to help
10802 ;; combine.
10803
10804 (define_insn "*fp_jcc_1_387"
10805 [(set (pc)
10806 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10807 [(match_operand 1 "register_operand" "f")
10808 (match_operand 2 "nonimmediate_operand" "fm")])
10809 (label_ref (match_operand 3 "" ""))
10810 (pc)))
10811 (clobber (reg:CCFP FPSR_REG))
10812 (clobber (reg:CCFP FLAGS_REG))
10813 (clobber (match_scratch:HI 4 "=a"))]
10814 "TARGET_80387
10815 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10816 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10817 && SELECT_CC_MODE (GET_CODE (operands[0]),
10818 operands[1], operands[2]) == CCFPmode
10819 && !TARGET_CMOVE"
10820 "#")
10821
10822 (define_insn "*fp_jcc_1r_387"
10823 [(set (pc)
10824 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10825 [(match_operand 1 "register_operand" "f")
10826 (match_operand 2 "nonimmediate_operand" "fm")])
10827 (pc)
10828 (label_ref (match_operand 3 "" ""))))
10829 (clobber (reg:CCFP FPSR_REG))
10830 (clobber (reg:CCFP FLAGS_REG))
10831 (clobber (match_scratch:HI 4 "=a"))]
10832 "TARGET_80387
10833 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10834 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10835 && SELECT_CC_MODE (GET_CODE (operands[0]),
10836 operands[1], operands[2]) == CCFPmode
10837 && !TARGET_CMOVE"
10838 "#")
10839
10840 (define_insn "*fp_jcc_2_387"
10841 [(set (pc)
10842 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10843 [(match_operand 1 "register_operand" "f")
10844 (match_operand 2 "register_operand" "f")])
10845 (label_ref (match_operand 3 "" ""))
10846 (pc)))
10847 (clobber (reg:CCFP FPSR_REG))
10848 (clobber (reg:CCFP FLAGS_REG))
10849 (clobber (match_scratch:HI 4 "=a"))]
10850 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10851 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10852 && !TARGET_CMOVE"
10853 "#")
10854
10855 (define_insn "*fp_jcc_2r_387"
10856 [(set (pc)
10857 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10858 [(match_operand 1 "register_operand" "f")
10859 (match_operand 2 "register_operand" "f")])
10860 (pc)
10861 (label_ref (match_operand 3 "" ""))))
10862 (clobber (reg:CCFP FPSR_REG))
10863 (clobber (reg:CCFP FLAGS_REG))
10864 (clobber (match_scratch:HI 4 "=a"))]
10865 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10866 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10867 && !TARGET_CMOVE"
10868 "#")
10869
10870 (define_insn "*fp_jcc_3_387"
10871 [(set (pc)
10872 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10873 [(match_operand 1 "register_operand" "f")
10874 (match_operand 2 "const0_operand" "")])
10875 (label_ref (match_operand 3 "" ""))
10876 (pc)))
10877 (clobber (reg:CCFP FPSR_REG))
10878 (clobber (reg:CCFP FLAGS_REG))
10879 (clobber (match_scratch:HI 4 "=a"))]
10880 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10881 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10882 && SELECT_CC_MODE (GET_CODE (operands[0]),
10883 operands[1], operands[2]) == CCFPmode
10884 && !TARGET_CMOVE"
10885 "#")
10886
10887 (define_split
10888 [(set (pc)
10889 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10890 [(match_operand 1 "register_operand" "")
10891 (match_operand 2 "nonimmediate_operand" "")])
10892 (match_operand 3 "" "")
10893 (match_operand 4 "" "")))
10894 (clobber (reg:CCFP FPSR_REG))
10895 (clobber (reg:CCFP FLAGS_REG))]
10896 "reload_completed"
10897 [(const_int 0)]
10898 {
10899 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10900 operands[3], operands[4], NULL_RTX, NULL_RTX);
10901 DONE;
10902 })
10903
10904 (define_split
10905 [(set (pc)
10906 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10907 [(match_operand 1 "register_operand" "")
10908 (match_operand 2 "general_operand" "")])
10909 (match_operand 3 "" "")
10910 (match_operand 4 "" "")))
10911 (clobber (reg:CCFP FPSR_REG))
10912 (clobber (reg:CCFP FLAGS_REG))
10913 (clobber (match_scratch:HI 5 "=a"))]
10914 "reload_completed"
10915 [(const_int 0)]
10916 {
10917 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10918 operands[3], operands[4], operands[5], NULL_RTX);
10919 DONE;
10920 })
10921
10922 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10923 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10924 ;; with a precedence over other operators and is always put in the first
10925 ;; place. Swap condition and operands to match ficom instruction.
10926
10927 (define_insn "*fp_jcc_4_<mode>_387"
10928 [(set (pc)
10929 (if_then_else
10930 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10931 [(match_operator 1 "float_operator"
10932 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10933 (match_operand 3 "register_operand" "f,f")])
10934 (label_ref (match_operand 4 "" ""))
10935 (pc)))
10936 (clobber (reg:CCFP FPSR_REG))
10937 (clobber (reg:CCFP FLAGS_REG))
10938 (clobber (match_scratch:HI 5 "=a,a"))]
10939 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10940 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10941 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10942 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10943 && !TARGET_CMOVE"
10944 "#")
10945
10946 (define_split
10947 [(set (pc)
10948 (if_then_else
10949 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10950 [(match_operator 1 "float_operator"
10951 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10952 (match_operand 3 "register_operand" "")])
10953 (match_operand 4 "" "")
10954 (match_operand 5 "" "")))
10955 (clobber (reg:CCFP FPSR_REG))
10956 (clobber (reg:CCFP FLAGS_REG))
10957 (clobber (match_scratch:HI 6 "=a"))]
10958 "reload_completed"
10959 [(const_int 0)]
10960 {
10961 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10962
10963 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10964 operands[3], operands[7],
10965 operands[4], operands[5], operands[6], NULL_RTX);
10966 DONE;
10967 })
10968
10969 ;; %%% Kill this when reload knows how to do it.
10970 (define_split
10971 [(set (pc)
10972 (if_then_else
10973 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10974 [(match_operator 1 "float_operator"
10975 [(match_operand:X87MODEI12 2 "register_operand" "")])
10976 (match_operand 3 "register_operand" "")])
10977 (match_operand 4 "" "")
10978 (match_operand 5 "" "")))
10979 (clobber (reg:CCFP FPSR_REG))
10980 (clobber (reg:CCFP FLAGS_REG))
10981 (clobber (match_scratch:HI 6 "=a"))]
10982 "reload_completed"
10983 [(const_int 0)]
10984 {
10985 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10986 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10987
10988 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10989 operands[3], operands[7],
10990 operands[4], operands[5], operands[6], operands[2]);
10991 DONE;
10992 })
10993 \f
10994 ;; Unconditional and other jump instructions
10995
10996 (define_insn "jump"
10997 [(set (pc)
10998 (label_ref (match_operand 0 "" "")))]
10999 ""
11000 "jmp\t%l0"
11001 [(set_attr "type" "ibr")
11002 (set (attr "length")
11003 (if_then_else (and (ge (minus (match_dup 0) (pc))
11004 (const_int -126))
11005 (lt (minus (match_dup 0) (pc))
11006 (const_int 128)))
11007 (const_int 2)
11008 (const_int 5)))
11009 (set_attr "modrm" "0")])
11010
11011 (define_expand "indirect_jump"
11012 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11013 ""
11014 "")
11015
11016 (define_insn "*indirect_jump"
11017 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11018 ""
11019 "jmp\t%A0"
11020 [(set_attr "type" "ibr")
11021 (set_attr "length_immediate" "0")])
11022
11023 (define_expand "tablejump"
11024 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11025 (use (label_ref (match_operand 1 "" "")))])]
11026 ""
11027 {
11028 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11029 relative. Convert the relative address to an absolute address. */
11030 if (flag_pic)
11031 {
11032 rtx op0, op1;
11033 enum rtx_code code;
11034
11035 /* We can't use @GOTOFF for text labels on VxWorks;
11036 see gotoff_operand. */
11037 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11038 {
11039 code = PLUS;
11040 op0 = operands[0];
11041 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11042 }
11043 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11044 {
11045 code = PLUS;
11046 op0 = operands[0];
11047 op1 = pic_offset_table_rtx;
11048 }
11049 else
11050 {
11051 code = MINUS;
11052 op0 = pic_offset_table_rtx;
11053 op1 = operands[0];
11054 }
11055
11056 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11057 OPTAB_DIRECT);
11058 }
11059 })
11060
11061 (define_insn "*tablejump_1"
11062 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11063 (use (label_ref (match_operand 1 "" "")))]
11064 ""
11065 "jmp\t%A0"
11066 [(set_attr "type" "ibr")
11067 (set_attr "length_immediate" "0")])
11068 \f
11069 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11070
11071 (define_peephole2
11072 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11073 (set (match_operand:QI 1 "register_operand" "")
11074 (match_operator:QI 2 "ix86_comparison_operator"
11075 [(reg FLAGS_REG) (const_int 0)]))
11076 (set (match_operand 3 "q_regs_operand" "")
11077 (zero_extend (match_dup 1)))]
11078 "(peep2_reg_dead_p (3, operands[1])
11079 || operands_match_p (operands[1], operands[3]))
11080 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11081 [(set (match_dup 4) (match_dup 0))
11082 (set (strict_low_part (match_dup 5))
11083 (match_dup 2))]
11084 {
11085 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11086 operands[5] = gen_lowpart (QImode, operands[3]);
11087 ix86_expand_clear (operands[3]);
11088 })
11089
11090 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11091
11092 (define_peephole2
11093 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11094 (set (match_operand:QI 1 "register_operand" "")
11095 (match_operator:QI 2 "ix86_comparison_operator"
11096 [(reg FLAGS_REG) (const_int 0)]))
11097 (parallel [(set (match_operand 3 "q_regs_operand" "")
11098 (zero_extend (match_dup 1)))
11099 (clobber (reg:CC FLAGS_REG))])]
11100 "(peep2_reg_dead_p (3, operands[1])
11101 || operands_match_p (operands[1], operands[3]))
11102 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11103 [(set (match_dup 4) (match_dup 0))
11104 (set (strict_low_part (match_dup 5))
11105 (match_dup 2))]
11106 {
11107 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11108 operands[5] = gen_lowpart (QImode, operands[3]);
11109 ix86_expand_clear (operands[3]);
11110 })
11111 \f
11112 ;; Call instructions.
11113
11114 ;; The predicates normally associated with named expanders are not properly
11115 ;; checked for calls. This is a bug in the generic code, but it isn't that
11116 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11117
11118 ;; P6 processors will jump to the address after the decrement when %esp
11119 ;; is used as a call operand, so they will execute return address as a code.
11120 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11121
11122 ;; Call subroutine returning no value.
11123
11124 (define_expand "call_pop"
11125 [(parallel [(call (match_operand:QI 0 "" "")
11126 (match_operand:SI 1 "" ""))
11127 (set (reg:SI SP_REG)
11128 (plus:SI (reg:SI SP_REG)
11129 (match_operand:SI 3 "" "")))])]
11130 "!TARGET_64BIT"
11131 {
11132 ix86_expand_call (NULL, operands[0], operands[1],
11133 operands[2], operands[3], 0);
11134 DONE;
11135 })
11136
11137 (define_insn "*call_pop_0"
11138 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11139 (match_operand:SI 1 "" ""))
11140 (set (reg:SI SP_REG)
11141 (plus:SI (reg:SI SP_REG)
11142 (match_operand:SI 2 "immediate_operand" "")))]
11143 "!TARGET_64BIT"
11144 {
11145 if (SIBLING_CALL_P (insn))
11146 return "jmp\t%P0";
11147 else
11148 return "call\t%P0";
11149 }
11150 [(set_attr "type" "call")])
11151
11152 (define_insn "*call_pop_1"
11153 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11154 (match_operand:SI 1 "" ""))
11155 (set (reg:SI SP_REG)
11156 (plus:SI (reg:SI SP_REG)
11157 (match_operand:SI 2 "immediate_operand" "i")))]
11158 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11159 {
11160 if (constant_call_address_operand (operands[0], Pmode))
11161 return "call\t%P0";
11162 return "call\t%A0";
11163 }
11164 [(set_attr "type" "call")])
11165
11166 (define_insn "*sibcall_pop_1"
11167 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11168 (match_operand:SI 1 "" ""))
11169 (set (reg:SI SP_REG)
11170 (plus:SI (reg:SI SP_REG)
11171 (match_operand:SI 2 "immediate_operand" "i,i")))]
11172 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11173 "@
11174 jmp\t%P0
11175 jmp\t%A0"
11176 [(set_attr "type" "call")])
11177
11178 (define_expand "call"
11179 [(call (match_operand:QI 0 "" "")
11180 (match_operand 1 "" ""))
11181 (use (match_operand 2 "" ""))]
11182 ""
11183 {
11184 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11185 DONE;
11186 })
11187
11188 (define_expand "sibcall"
11189 [(call (match_operand:QI 0 "" "")
11190 (match_operand 1 "" ""))
11191 (use (match_operand 2 "" ""))]
11192 ""
11193 {
11194 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11195 DONE;
11196 })
11197
11198 (define_insn "*call_0"
11199 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11200 (match_operand 1 "" ""))]
11201 ""
11202 {
11203 if (SIBLING_CALL_P (insn))
11204 return "jmp\t%P0";
11205 else
11206 return "call\t%P0";
11207 }
11208 [(set_attr "type" "call")])
11209
11210 (define_insn "*call_1"
11211 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11212 (match_operand 1 "" ""))]
11213 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11214 {
11215 if (constant_call_address_operand (operands[0], Pmode))
11216 return "call\t%P0";
11217 return "call\t%A0";
11218 }
11219 [(set_attr "type" "call")])
11220
11221 (define_insn "*sibcall_1"
11222 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11223 (match_operand 1 "" ""))]
11224 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11225 "@
11226 jmp\t%P0
11227 jmp\t%A0"
11228 [(set_attr "type" "call")])
11229
11230 (define_insn "*call_1_rex64"
11231 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11232 (match_operand 1 "" ""))]
11233 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11234 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11235 {
11236 if (constant_call_address_operand (operands[0], Pmode))
11237 return "call\t%P0";
11238 return "call\t%A0";
11239 }
11240 [(set_attr "type" "call")])
11241
11242 (define_insn "*call_1_rex64_ms_sysv"
11243 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11244 (match_operand 1 "" ""))
11245 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11246 (clobber (reg:TI XMM6_REG))
11247 (clobber (reg:TI XMM7_REG))
11248 (clobber (reg:TI XMM8_REG))
11249 (clobber (reg:TI XMM9_REG))
11250 (clobber (reg:TI XMM10_REG))
11251 (clobber (reg:TI XMM11_REG))
11252 (clobber (reg:TI XMM12_REG))
11253 (clobber (reg:TI XMM13_REG))
11254 (clobber (reg:TI XMM14_REG))
11255 (clobber (reg:TI XMM15_REG))
11256 (clobber (reg:DI SI_REG))
11257 (clobber (reg:DI DI_REG))]
11258 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11259 {
11260 if (constant_call_address_operand (operands[0], Pmode))
11261 return "call\t%P0";
11262 return "call\t%A0";
11263 }
11264 [(set_attr "type" "call")])
11265
11266 (define_insn "*call_1_rex64_large"
11267 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11268 (match_operand 1 "" ""))]
11269 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11270 "call\t%A0"
11271 [(set_attr "type" "call")])
11272
11273 (define_insn "*sibcall_1_rex64"
11274 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11275 (match_operand 1 "" ""))]
11276 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11277 "@
11278 jmp\t%P0
11279 jmp\t%A0"
11280 [(set_attr "type" "call")])
11281
11282 ;; Call subroutine, returning value in operand 0
11283 (define_expand "call_value_pop"
11284 [(parallel [(set (match_operand 0 "" "")
11285 (call (match_operand:QI 1 "" "")
11286 (match_operand:SI 2 "" "")))
11287 (set (reg:SI SP_REG)
11288 (plus:SI (reg:SI SP_REG)
11289 (match_operand:SI 4 "" "")))])]
11290 "!TARGET_64BIT"
11291 {
11292 ix86_expand_call (operands[0], operands[1], operands[2],
11293 operands[3], operands[4], 0);
11294 DONE;
11295 })
11296
11297 (define_expand "call_value"
11298 [(set (match_operand 0 "" "")
11299 (call (match_operand:QI 1 "" "")
11300 (match_operand:SI 2 "" "")))
11301 (use (match_operand:SI 3 "" ""))]
11302 ;; Operand 3 is not used on the i386.
11303 ""
11304 {
11305 ix86_expand_call (operands[0], operands[1], operands[2],
11306 operands[3], NULL, 0);
11307 DONE;
11308 })
11309
11310 (define_expand "sibcall_value"
11311 [(set (match_operand 0 "" "")
11312 (call (match_operand:QI 1 "" "")
11313 (match_operand:SI 2 "" "")))
11314 (use (match_operand:SI 3 "" ""))]
11315 ;; Operand 3 is not used on the i386.
11316 ""
11317 {
11318 ix86_expand_call (operands[0], operands[1], operands[2],
11319 operands[3], NULL, 1);
11320 DONE;
11321 })
11322
11323 ;; Call subroutine returning any type.
11324
11325 (define_expand "untyped_call"
11326 [(parallel [(call (match_operand 0 "" "")
11327 (const_int 0))
11328 (match_operand 1 "" "")
11329 (match_operand 2 "" "")])]
11330 ""
11331 {
11332 int i;
11333
11334 /* In order to give reg-stack an easier job in validating two
11335 coprocessor registers as containing a possible return value,
11336 simply pretend the untyped call returns a complex long double
11337 value.
11338
11339 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11340 and should have the default ABI. */
11341
11342 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11343 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11344 operands[0], const0_rtx,
11345 GEN_INT ((TARGET_64BIT
11346 ? (ix86_abi == SYSV_ABI
11347 ? X86_64_SSE_REGPARM_MAX
11348 : X86_64_MS_SSE_REGPARM_MAX)
11349 : X86_32_SSE_REGPARM_MAX)
11350 - 1),
11351 NULL, 0);
11352
11353 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11354 {
11355 rtx set = XVECEXP (operands[2], 0, i);
11356 emit_move_insn (SET_DEST (set), SET_SRC (set));
11357 }
11358
11359 /* The optimizer does not know that the call sets the function value
11360 registers we stored in the result block. We avoid problems by
11361 claiming that all hard registers are used and clobbered at this
11362 point. */
11363 emit_insn (gen_blockage ());
11364
11365 DONE;
11366 })
11367 \f
11368 ;; Prologue and epilogue instructions
11369
11370 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11371 ;; all of memory. This blocks insns from being moved across this point.
11372
11373 (define_insn "blockage"
11374 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11375 ""
11376 ""
11377 [(set_attr "length" "0")])
11378
11379 ;; Do not schedule instructions accessing memory across this point.
11380
11381 (define_expand "memory_blockage"
11382 [(set (match_dup 0)
11383 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11384 ""
11385 {
11386 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11387 MEM_VOLATILE_P (operands[0]) = 1;
11388 })
11389
11390 (define_insn "*memory_blockage"
11391 [(set (match_operand:BLK 0 "" "")
11392 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11393 ""
11394 ""
11395 [(set_attr "length" "0")])
11396
11397 ;; As USE insns aren't meaningful after reload, this is used instead
11398 ;; to prevent deleting instructions setting registers for PIC code
11399 (define_insn "prologue_use"
11400 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11401 ""
11402 ""
11403 [(set_attr "length" "0")])
11404
11405 ;; Insn emitted into the body of a function to return from a function.
11406 ;; This is only done if the function's epilogue is known to be simple.
11407 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11408
11409 (define_expand "return"
11410 [(return)]
11411 "ix86_can_use_return_insn_p ()"
11412 {
11413 if (crtl->args.pops_args)
11414 {
11415 rtx popc = GEN_INT (crtl->args.pops_args);
11416 emit_jump_insn (gen_return_pop_internal (popc));
11417 DONE;
11418 }
11419 })
11420
11421 (define_insn "return_internal"
11422 [(return)]
11423 "reload_completed"
11424 "ret"
11425 [(set_attr "length" "1")
11426 (set_attr "atom_unit" "jeu")
11427 (set_attr "length_immediate" "0")
11428 (set_attr "modrm" "0")])
11429
11430 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11431 ;; instruction Athlon and K8 have.
11432
11433 (define_insn "return_internal_long"
11434 [(return)
11435 (unspec [(const_int 0)] UNSPEC_REP)]
11436 "reload_completed"
11437 "rep\;ret"
11438 [(set_attr "length" "2")
11439 (set_attr "atom_unit" "jeu")
11440 (set_attr "length_immediate" "0")
11441 (set_attr "prefix_rep" "1")
11442 (set_attr "modrm" "0")])
11443
11444 (define_insn "return_pop_internal"
11445 [(return)
11446 (use (match_operand:SI 0 "const_int_operand" ""))]
11447 "reload_completed"
11448 "ret\t%0"
11449 [(set_attr "length" "3")
11450 (set_attr "atom_unit" "jeu")
11451 (set_attr "length_immediate" "2")
11452 (set_attr "modrm" "0")])
11453
11454 (define_insn "return_indirect_internal"
11455 [(return)
11456 (use (match_operand:SI 0 "register_operand" "r"))]
11457 "reload_completed"
11458 "jmp\t%A0"
11459 [(set_attr "type" "ibr")
11460 (set_attr "length_immediate" "0")])
11461
11462 (define_insn "nop"
11463 [(const_int 0)]
11464 ""
11465 "nop"
11466 [(set_attr "length" "1")
11467 (set_attr "length_immediate" "0")
11468 (set_attr "modrm" "0")])
11469
11470 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11471 (define_insn "nops"
11472 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11473 UNSPECV_NOPS)]
11474 "reload_completed"
11475 {
11476 int num = INTVAL (operands[0]);
11477
11478 gcc_assert (num >= 1 && num <= 8);
11479
11480 while (num--)
11481 fputs ("\tnop\n", asm_out_file);
11482
11483 return "";
11484 }
11485 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11486 (set_attr "length_immediate" "0")
11487 (set_attr "modrm" "0")])
11488
11489 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11490 ;; branch prediction penalty for the third jump in a 16-byte
11491 ;; block on K8.
11492
11493 (define_insn "pad"
11494 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11495 ""
11496 {
11497 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11498 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11499 #else
11500 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11501 The align insn is used to avoid 3 jump instructions in the row to improve
11502 branch prediction and the benefits hardly outweigh the cost of extra 8
11503 nops on the average inserted by full alignment pseudo operation. */
11504 #endif
11505 return "";
11506 }
11507 [(set_attr "length" "16")])
11508
11509 (define_expand "prologue"
11510 [(const_int 0)]
11511 ""
11512 "ix86_expand_prologue (); DONE;")
11513
11514 (define_insn "set_got"
11515 [(set (match_operand:SI 0 "register_operand" "=r")
11516 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11517 (clobber (reg:CC FLAGS_REG))]
11518 "!TARGET_64BIT"
11519 "* return output_set_got (operands[0], NULL_RTX);"
11520 [(set_attr "type" "multi")
11521 (set_attr "length" "12")])
11522
11523 (define_insn "set_got_labelled"
11524 [(set (match_operand:SI 0 "register_operand" "=r")
11525 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11526 UNSPEC_SET_GOT))
11527 (clobber (reg:CC FLAGS_REG))]
11528 "!TARGET_64BIT"
11529 "* return output_set_got (operands[0], operands[1]);"
11530 [(set_attr "type" "multi")
11531 (set_attr "length" "12")])
11532
11533 (define_insn "set_got_rex64"
11534 [(set (match_operand:DI 0 "register_operand" "=r")
11535 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11536 "TARGET_64BIT"
11537 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11538 [(set_attr "type" "lea")
11539 (set_attr "length_address" "4")
11540 (set_attr "mode" "DI")])
11541
11542 (define_insn "set_rip_rex64"
11543 [(set (match_operand:DI 0 "register_operand" "=r")
11544 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11545 "TARGET_64BIT"
11546 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11547 [(set_attr "type" "lea")
11548 (set_attr "length_address" "4")
11549 (set_attr "mode" "DI")])
11550
11551 (define_insn "set_got_offset_rex64"
11552 [(set (match_operand:DI 0 "register_operand" "=r")
11553 (unspec:DI
11554 [(label_ref (match_operand 1 "" ""))]
11555 UNSPEC_SET_GOT_OFFSET))]
11556 "TARGET_64BIT"
11557 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11558 [(set_attr "type" "imov")
11559 (set_attr "length_immediate" "0")
11560 (set_attr "length_address" "8")
11561 (set_attr "mode" "DI")])
11562
11563 (define_expand "epilogue"
11564 [(const_int 0)]
11565 ""
11566 "ix86_expand_epilogue (1); DONE;")
11567
11568 (define_expand "sibcall_epilogue"
11569 [(const_int 0)]
11570 ""
11571 "ix86_expand_epilogue (0); DONE;")
11572
11573 (define_expand "eh_return"
11574 [(use (match_operand 0 "register_operand" ""))]
11575 ""
11576 {
11577 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11578
11579 /* Tricky bit: we write the address of the handler to which we will
11580 be returning into someone else's stack frame, one word below the
11581 stack address we wish to restore. */
11582 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11583 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11584 tmp = gen_rtx_MEM (Pmode, tmp);
11585 emit_move_insn (tmp, ra);
11586
11587 emit_jump_insn (gen_eh_return_internal ());
11588 emit_barrier ();
11589 DONE;
11590 })
11591
11592 (define_insn_and_split "eh_return_internal"
11593 [(eh_return)]
11594 ""
11595 "#"
11596 "epilogue_completed"
11597 [(const_int 0)]
11598 "ix86_expand_epilogue (2); DONE;")
11599
11600 (define_insn "leave"
11601 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11602 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11603 (clobber (mem:BLK (scratch)))]
11604 "!TARGET_64BIT"
11605 "leave"
11606 [(set_attr "type" "leave")])
11607
11608 (define_insn "leave_rex64"
11609 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11610 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11611 (clobber (mem:BLK (scratch)))]
11612 "TARGET_64BIT"
11613 "leave"
11614 [(set_attr "type" "leave")])
11615 \f
11616 ;; Handle -fsplit-stack.
11617
11618 (define_expand "split_stack_prologue"
11619 [(const_int 0)]
11620 ""
11621 {
11622 ix86_expand_split_stack_prologue ();
11623 DONE;
11624 })
11625
11626 ;; In order to support the call/return predictor, we use a return
11627 ;; instruction which the middle-end doesn't see.
11628 (define_insn "split_stack_return"
11629 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11630 UNSPEC_STACK_CHECK)]
11631 ""
11632 {
11633 if (operands[0] == const0_rtx)
11634 return "ret";
11635 else
11636 return "ret\t%0";
11637 }
11638 [(set_attr "atom_unit" "jeu")
11639 (set_attr "modrm" "0")
11640 (set (attr "length")
11641 (if_then_else (match_operand:SI 0 "const0_operand" "")
11642 (const_int 1)
11643 (const_int 3)))
11644 (set (attr "length_immediate")
11645 (if_then_else (match_operand:SI 0 "const0_operand" "")
11646 (const_int 0)
11647 (const_int 2)))])
11648
11649 ;; If there are operand 0 bytes available on the stack, jump to
11650 ;; operand 1.
11651
11652 (define_expand "split_stack_space_check"
11653 [(set (pc) (if_then_else
11654 (ltu (minus (reg SP_REG)
11655 (match_operand 0 "register_operand" ""))
11656 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11657 (label_ref (match_operand 1 "" ""))
11658 (pc)))]
11659 ""
11660 {
11661 rtx reg, size, limit;
11662
11663 reg = gen_reg_rtx (Pmode);
11664 size = force_reg (Pmode, operands[0]);
11665 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11666 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11667 UNSPEC_STACK_CHECK);
11668 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11669 ix86_expand_branch (GEU, reg, limit, operands[1]);
11670
11671 DONE;
11672 })
11673 \f
11674 ;; Bit manipulation instructions.
11675
11676 (define_expand "ffs<mode>2"
11677 [(set (match_dup 2) (const_int -1))
11678 (parallel [(set (reg:CCZ FLAGS_REG)
11679 (compare:CCZ
11680 (match_operand:SWI48 1 "nonimmediate_operand" "")
11681 (const_int 0)))
11682 (set (match_operand:SWI48 0 "register_operand" "")
11683 (ctz:SWI48 (match_dup 1)))])
11684 (set (match_dup 0) (if_then_else:SWI48
11685 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11686 (match_dup 2)
11687 (match_dup 0)))
11688 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11689 (clobber (reg:CC FLAGS_REG))])]
11690 ""
11691 {
11692 if (<MODE>mode == SImode && !TARGET_CMOVE)
11693 {
11694 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11695 DONE;
11696 }
11697 operands[2] = gen_reg_rtx (<MODE>mode);
11698 })
11699
11700 (define_insn_and_split "ffssi2_no_cmove"
11701 [(set (match_operand:SI 0 "register_operand" "=r")
11702 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11703 (clobber (match_scratch:SI 2 "=&q"))
11704 (clobber (reg:CC FLAGS_REG))]
11705 "!TARGET_CMOVE"
11706 "#"
11707 "&& reload_completed"
11708 [(parallel [(set (reg:CCZ FLAGS_REG)
11709 (compare:CCZ (match_dup 1) (const_int 0)))
11710 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11711 (set (strict_low_part (match_dup 3))
11712 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11713 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11714 (clobber (reg:CC FLAGS_REG))])
11715 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11716 (clobber (reg:CC FLAGS_REG))])
11717 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11718 (clobber (reg:CC FLAGS_REG))])]
11719 {
11720 operands[3] = gen_lowpart (QImode, operands[2]);
11721 ix86_expand_clear (operands[2]);
11722 })
11723
11724 (define_insn "*ffs<mode>_1"
11725 [(set (reg:CCZ FLAGS_REG)
11726 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11727 (const_int 0)))
11728 (set (match_operand:SWI48 0 "register_operand" "=r")
11729 (ctz:SWI48 (match_dup 1)))]
11730 ""
11731 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11732 [(set_attr "type" "alu1")
11733 (set_attr "prefix_0f" "1")
11734 (set_attr "mode" "<MODE>")])
11735
11736 (define_insn "ctz<mode>2"
11737 [(set (match_operand:SWI48 0 "register_operand" "=r")
11738 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11739 (clobber (reg:CC FLAGS_REG))]
11740 ""
11741 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11742 [(set_attr "type" "alu1")
11743 (set_attr "prefix_0f" "1")
11744 (set_attr "mode" "<MODE>")])
11745
11746 (define_expand "clz<mode>2"
11747 [(parallel
11748 [(set (match_operand:SWI248 0 "register_operand" "")
11749 (minus:SWI248
11750 (match_dup 2)
11751 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11752 (clobber (reg:CC FLAGS_REG))])
11753 (parallel
11754 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11755 (clobber (reg:CC FLAGS_REG))])]
11756 ""
11757 {
11758 if (TARGET_ABM)
11759 {
11760 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11761 DONE;
11762 }
11763 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11764 })
11765
11766 (define_insn "clz<mode>2_abm"
11767 [(set (match_operand:SWI248 0 "register_operand" "=r")
11768 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11769 (clobber (reg:CC FLAGS_REG))]
11770 "TARGET_ABM"
11771 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11772 [(set_attr "prefix_rep" "1")
11773 (set_attr "type" "bitmanip")
11774 (set_attr "mode" "<MODE>")])
11775
11776 (define_insn "bsr_rex64"
11777 [(set (match_operand:DI 0 "register_operand" "=r")
11778 (minus:DI (const_int 63)
11779 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11780 (clobber (reg:CC FLAGS_REG))]
11781 "TARGET_64BIT"
11782 "bsr{q}\t{%1, %0|%0, %1}"
11783 [(set_attr "type" "alu1")
11784 (set_attr "prefix_0f" "1")
11785 (set_attr "mode" "DI")])
11786
11787 (define_insn "bsr"
11788 [(set (match_operand:SI 0 "register_operand" "=r")
11789 (minus:SI (const_int 31)
11790 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11791 (clobber (reg:CC FLAGS_REG))]
11792 ""
11793 "bsr{l}\t{%1, %0|%0, %1}"
11794 [(set_attr "type" "alu1")
11795 (set_attr "prefix_0f" "1")
11796 (set_attr "mode" "SI")])
11797
11798 (define_insn "*bsrhi"
11799 [(set (match_operand:HI 0 "register_operand" "=r")
11800 (minus:HI (const_int 15)
11801 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11802 (clobber (reg:CC FLAGS_REG))]
11803 ""
11804 "bsr{w}\t{%1, %0|%0, %1}"
11805 [(set_attr "type" "alu1")
11806 (set_attr "prefix_0f" "1")
11807 (set_attr "mode" "HI")])
11808
11809 (define_insn "popcount<mode>2"
11810 [(set (match_operand:SWI248 0 "register_operand" "=r")
11811 (popcount:SWI248
11812 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11813 (clobber (reg:CC FLAGS_REG))]
11814 "TARGET_POPCNT"
11815 {
11816 #if TARGET_MACHO
11817 return "popcnt\t{%1, %0|%0, %1}";
11818 #else
11819 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11820 #endif
11821 }
11822 [(set_attr "prefix_rep" "1")
11823 (set_attr "type" "bitmanip")
11824 (set_attr "mode" "<MODE>")])
11825
11826 (define_insn "*popcount<mode>2_cmp"
11827 [(set (reg FLAGS_REG)
11828 (compare
11829 (popcount:SWI248
11830 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11831 (const_int 0)))
11832 (set (match_operand:SWI248 0 "register_operand" "=r")
11833 (popcount:SWI248 (match_dup 1)))]
11834 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11835 {
11836 #if TARGET_MACHO
11837 return "popcnt\t{%1, %0|%0, %1}";
11838 #else
11839 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11840 #endif
11841 }
11842 [(set_attr "prefix_rep" "1")
11843 (set_attr "type" "bitmanip")
11844 (set_attr "mode" "<MODE>")])
11845
11846 (define_insn "*popcountsi2_cmp_zext"
11847 [(set (reg FLAGS_REG)
11848 (compare
11849 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11850 (const_int 0)))
11851 (set (match_operand:DI 0 "register_operand" "=r")
11852 (zero_extend:DI(popcount:SI (match_dup 1))))]
11853 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11854 {
11855 #if TARGET_MACHO
11856 return "popcnt\t{%1, %0|%0, %1}";
11857 #else
11858 return "popcnt{l}\t{%1, %0|%0, %1}";
11859 #endif
11860 }
11861 [(set_attr "prefix_rep" "1")
11862 (set_attr "type" "bitmanip")
11863 (set_attr "mode" "SI")])
11864
11865 (define_expand "bswap<mode>2"
11866 [(set (match_operand:SWI48 0 "register_operand" "")
11867 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11868 ""
11869 {
11870 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11871 {
11872 rtx x = operands[0];
11873
11874 emit_move_insn (x, operands[1]);
11875 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11876 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11877 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11878 DONE;
11879 }
11880 })
11881
11882 (define_insn "*bswap<mode>2_movbe"
11883 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11884 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11885 "TARGET_MOVBE
11886 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11887 "@
11888 bswap\t%0
11889 movbe\t{%1, %0|%0, %1}
11890 movbe\t{%1, %0|%0, %1}"
11891 [(set_attr "type" "bitmanip,imov,imov")
11892 (set_attr "modrm" "0,1,1")
11893 (set_attr "prefix_0f" "*,1,1")
11894 (set_attr "prefix_extra" "*,1,1")
11895 (set_attr "mode" "<MODE>")])
11896
11897 (define_insn "*bswap<mode>2_1"
11898 [(set (match_operand:SWI48 0 "register_operand" "=r")
11899 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11900 "TARGET_BSWAP"
11901 "bswap\t%0"
11902 [(set_attr "type" "bitmanip")
11903 (set_attr "modrm" "0")
11904 (set_attr "mode" "<MODE>")])
11905
11906 (define_insn "*bswaphi_lowpart_1"
11907 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11908 (bswap:HI (match_dup 0)))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11911 "@
11912 xchg{b}\t{%h0, %b0|%b0, %h0}
11913 rol{w}\t{$8, %0|%0, 8}"
11914 [(set_attr "length" "2,4")
11915 (set_attr "mode" "QI,HI")])
11916
11917 (define_insn "bswaphi_lowpart"
11918 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11919 (bswap:HI (match_dup 0)))
11920 (clobber (reg:CC FLAGS_REG))]
11921 ""
11922 "rol{w}\t{$8, %0|%0, 8}"
11923 [(set_attr "length" "4")
11924 (set_attr "mode" "HI")])
11925
11926 (define_expand "paritydi2"
11927 [(set (match_operand:DI 0 "register_operand" "")
11928 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11929 "! TARGET_POPCNT"
11930 {
11931 rtx scratch = gen_reg_rtx (QImode);
11932 rtx cond;
11933
11934 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11935 NULL_RTX, operands[1]));
11936
11937 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11938 gen_rtx_REG (CCmode, FLAGS_REG),
11939 const0_rtx);
11940 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11941
11942 if (TARGET_64BIT)
11943 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11944 else
11945 {
11946 rtx tmp = gen_reg_rtx (SImode);
11947
11948 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11949 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11950 }
11951 DONE;
11952 })
11953
11954 (define_expand "paritysi2"
11955 [(set (match_operand:SI 0 "register_operand" "")
11956 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11957 "! TARGET_POPCNT"
11958 {
11959 rtx scratch = gen_reg_rtx (QImode);
11960 rtx cond;
11961
11962 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11963
11964 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11965 gen_rtx_REG (CCmode, FLAGS_REG),
11966 const0_rtx);
11967 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11968
11969 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11970 DONE;
11971 })
11972
11973 (define_insn_and_split "paritydi2_cmp"
11974 [(set (reg:CC FLAGS_REG)
11975 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11976 UNSPEC_PARITY))
11977 (clobber (match_scratch:DI 0 "=r"))
11978 (clobber (match_scratch:SI 1 "=&r"))
11979 (clobber (match_scratch:HI 2 "=Q"))]
11980 "! TARGET_POPCNT"
11981 "#"
11982 "&& reload_completed"
11983 [(parallel
11984 [(set (match_dup 1)
11985 (xor:SI (match_dup 1) (match_dup 4)))
11986 (clobber (reg:CC FLAGS_REG))])
11987 (parallel
11988 [(set (reg:CC FLAGS_REG)
11989 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11990 (clobber (match_dup 1))
11991 (clobber (match_dup 2))])]
11992 {
11993 operands[4] = gen_lowpart (SImode, operands[3]);
11994
11995 if (TARGET_64BIT)
11996 {
11997 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11998 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11999 }
12000 else
12001 operands[1] = gen_highpart (SImode, operands[3]);
12002 })
12003
12004 (define_insn_and_split "paritysi2_cmp"
12005 [(set (reg:CC FLAGS_REG)
12006 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12007 UNSPEC_PARITY))
12008 (clobber (match_scratch:SI 0 "=r"))
12009 (clobber (match_scratch:HI 1 "=&Q"))]
12010 "! TARGET_POPCNT"
12011 "#"
12012 "&& reload_completed"
12013 [(parallel
12014 [(set (match_dup 1)
12015 (xor:HI (match_dup 1) (match_dup 3)))
12016 (clobber (reg:CC FLAGS_REG))])
12017 (parallel
12018 [(set (reg:CC FLAGS_REG)
12019 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12020 (clobber (match_dup 1))])]
12021 {
12022 operands[3] = gen_lowpart (HImode, operands[2]);
12023
12024 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12025 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12026 })
12027
12028 (define_insn "*parityhi2_cmp"
12029 [(set (reg:CC FLAGS_REG)
12030 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12031 UNSPEC_PARITY))
12032 (clobber (match_scratch:HI 0 "=Q"))]
12033 "! TARGET_POPCNT"
12034 "xor{b}\t{%h0, %b0|%b0, %h0}"
12035 [(set_attr "length" "2")
12036 (set_attr "mode" "HI")])
12037 \f
12038 ;; Thread-local storage patterns for ELF.
12039 ;;
12040 ;; Note that these code sequences must appear exactly as shown
12041 ;; in order to allow linker relaxation.
12042
12043 (define_insn "*tls_global_dynamic_32_gnu"
12044 [(set (match_operand:SI 0 "register_operand" "=a")
12045 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12046 (match_operand:SI 2 "tls_symbolic_operand" "")
12047 (match_operand:SI 3 "call_insn_operand" "")]
12048 UNSPEC_TLS_GD))
12049 (clobber (match_scratch:SI 4 "=d"))
12050 (clobber (match_scratch:SI 5 "=c"))
12051 (clobber (reg:CC FLAGS_REG))]
12052 "!TARGET_64BIT && TARGET_GNU_TLS"
12053 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12054 [(set_attr "type" "multi")
12055 (set_attr "length" "12")])
12056
12057 (define_expand "tls_global_dynamic_32"
12058 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12059 (unspec:SI
12060 [(match_dup 2)
12061 (match_operand:SI 1 "tls_symbolic_operand" "")
12062 (match_dup 3)]
12063 UNSPEC_TLS_GD))
12064 (clobber (match_scratch:SI 4 ""))
12065 (clobber (match_scratch:SI 5 ""))
12066 (clobber (reg:CC FLAGS_REG))])]
12067 ""
12068 {
12069 if (flag_pic)
12070 operands[2] = pic_offset_table_rtx;
12071 else
12072 {
12073 operands[2] = gen_reg_rtx (Pmode);
12074 emit_insn (gen_set_got (operands[2]));
12075 }
12076 if (TARGET_GNU2_TLS)
12077 {
12078 emit_insn (gen_tls_dynamic_gnu2_32
12079 (operands[0], operands[1], operands[2]));
12080 DONE;
12081 }
12082 operands[3] = ix86_tls_get_addr ();
12083 })
12084
12085 (define_insn "*tls_global_dynamic_64"
12086 [(set (match_operand:DI 0 "register_operand" "=a")
12087 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12088 (match_operand:DI 3 "" "")))
12089 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12090 UNSPEC_TLS_GD)]
12091 "TARGET_64BIT"
12092 { 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"; }
12093 [(set_attr "type" "multi")
12094 (set_attr "length" "16")])
12095
12096 (define_expand "tls_global_dynamic_64"
12097 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12098 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12099 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12100 UNSPEC_TLS_GD)])]
12101 ""
12102 {
12103 if (TARGET_GNU2_TLS)
12104 {
12105 emit_insn (gen_tls_dynamic_gnu2_64
12106 (operands[0], operands[1]));
12107 DONE;
12108 }
12109 operands[2] = ix86_tls_get_addr ();
12110 })
12111
12112 (define_insn "*tls_local_dynamic_base_32_gnu"
12113 [(set (match_operand:SI 0 "register_operand" "=a")
12114 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12115 (match_operand:SI 2 "call_insn_operand" "")]
12116 UNSPEC_TLS_LD_BASE))
12117 (clobber (match_scratch:SI 3 "=d"))
12118 (clobber (match_scratch:SI 4 "=c"))
12119 (clobber (reg:CC FLAGS_REG))]
12120 "!TARGET_64BIT && TARGET_GNU_TLS"
12121 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12122 [(set_attr "type" "multi")
12123 (set_attr "length" "11")])
12124
12125 (define_expand "tls_local_dynamic_base_32"
12126 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12127 (unspec:SI [(match_dup 1) (match_dup 2)]
12128 UNSPEC_TLS_LD_BASE))
12129 (clobber (match_scratch:SI 3 ""))
12130 (clobber (match_scratch:SI 4 ""))
12131 (clobber (reg:CC FLAGS_REG))])]
12132 ""
12133 {
12134 if (flag_pic)
12135 operands[1] = pic_offset_table_rtx;
12136 else
12137 {
12138 operands[1] = gen_reg_rtx (Pmode);
12139 emit_insn (gen_set_got (operands[1]));
12140 }
12141 if (TARGET_GNU2_TLS)
12142 {
12143 emit_insn (gen_tls_dynamic_gnu2_32
12144 (operands[0], ix86_tls_module_base (), operands[1]));
12145 DONE;
12146 }
12147 operands[2] = ix86_tls_get_addr ();
12148 })
12149
12150 (define_insn "*tls_local_dynamic_base_64"
12151 [(set (match_operand:DI 0 "register_operand" "=a")
12152 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12153 (match_operand:DI 2 "" "")))
12154 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12155 "TARGET_64BIT"
12156 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12157 [(set_attr "type" "multi")
12158 (set_attr "length" "12")])
12159
12160 (define_expand "tls_local_dynamic_base_64"
12161 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12162 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12163 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12164 ""
12165 {
12166 if (TARGET_GNU2_TLS)
12167 {
12168 emit_insn (gen_tls_dynamic_gnu2_64
12169 (operands[0], ix86_tls_module_base ()));
12170 DONE;
12171 }
12172 operands[1] = ix86_tls_get_addr ();
12173 })
12174
12175 ;; Local dynamic of a single variable is a lose. Show combine how
12176 ;; to convert that back to global dynamic.
12177
12178 (define_insn_and_split "*tls_local_dynamic_32_once"
12179 [(set (match_operand:SI 0 "register_operand" "=a")
12180 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12181 (match_operand:SI 2 "call_insn_operand" "")]
12182 UNSPEC_TLS_LD_BASE)
12183 (const:SI (unspec:SI
12184 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12185 UNSPEC_DTPOFF))))
12186 (clobber (match_scratch:SI 4 "=d"))
12187 (clobber (match_scratch:SI 5 "=c"))
12188 (clobber (reg:CC FLAGS_REG))]
12189 ""
12190 "#"
12191 ""
12192 [(parallel [(set (match_dup 0)
12193 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12194 UNSPEC_TLS_GD))
12195 (clobber (match_dup 4))
12196 (clobber (match_dup 5))
12197 (clobber (reg:CC FLAGS_REG))])])
12198
12199 ;; Segment register for the thread base ptr load
12200 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12201
12202 ;; Load and add the thread base pointer from %gs:0.
12203 (define_insn "*load_tp_<mode>"
12204 [(set (match_operand:P 0 "register_operand" "=r")
12205 (unspec:P [(const_int 0)] UNSPEC_TP))]
12206 ""
12207 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12208 [(set_attr "type" "imov")
12209 (set_attr "modrm" "0")
12210 (set_attr "length" "7")
12211 (set_attr "memory" "load")
12212 (set_attr "imm_disp" "false")])
12213
12214 (define_insn "*add_tp_<mode>"
12215 [(set (match_operand:P 0 "register_operand" "=r")
12216 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12217 (match_operand:P 1 "register_operand" "0")))
12218 (clobber (reg:CC FLAGS_REG))]
12219 ""
12220 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12221 [(set_attr "type" "alu")
12222 (set_attr "modrm" "0")
12223 (set_attr "length" "7")
12224 (set_attr "memory" "load")
12225 (set_attr "imm_disp" "false")])
12226
12227 ;; GNU2 TLS patterns can be split.
12228
12229 (define_expand "tls_dynamic_gnu2_32"
12230 [(set (match_dup 3)
12231 (plus:SI (match_operand:SI 2 "register_operand" "")
12232 (const:SI
12233 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12234 UNSPEC_TLSDESC))))
12235 (parallel
12236 [(set (match_operand:SI 0 "register_operand" "")
12237 (unspec:SI [(match_dup 1) (match_dup 3)
12238 (match_dup 2) (reg:SI SP_REG)]
12239 UNSPEC_TLSDESC))
12240 (clobber (reg:CC FLAGS_REG))])]
12241 "!TARGET_64BIT && TARGET_GNU2_TLS"
12242 {
12243 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12244 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12245 })
12246
12247 (define_insn "*tls_dynamic_lea_32"
12248 [(set (match_operand:SI 0 "register_operand" "=r")
12249 (plus:SI (match_operand:SI 1 "register_operand" "b")
12250 (const:SI
12251 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12252 UNSPEC_TLSDESC))))]
12253 "!TARGET_64BIT && TARGET_GNU2_TLS"
12254 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12255 [(set_attr "type" "lea")
12256 (set_attr "mode" "SI")
12257 (set_attr "length" "6")
12258 (set_attr "length_address" "4")])
12259
12260 (define_insn "*tls_dynamic_call_32"
12261 [(set (match_operand:SI 0 "register_operand" "=a")
12262 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12263 (match_operand:SI 2 "register_operand" "0")
12264 ;; we have to make sure %ebx still points to the GOT
12265 (match_operand:SI 3 "register_operand" "b")
12266 (reg:SI SP_REG)]
12267 UNSPEC_TLSDESC))
12268 (clobber (reg:CC FLAGS_REG))]
12269 "!TARGET_64BIT && TARGET_GNU2_TLS"
12270 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12271 [(set_attr "type" "call")
12272 (set_attr "length" "2")
12273 (set_attr "length_address" "0")])
12274
12275 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12276 [(set (match_operand:SI 0 "register_operand" "=&a")
12277 (plus:SI
12278 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12279 (match_operand:SI 4 "" "")
12280 (match_operand:SI 2 "register_operand" "b")
12281 (reg:SI SP_REG)]
12282 UNSPEC_TLSDESC)
12283 (const:SI (unspec:SI
12284 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12285 UNSPEC_DTPOFF))))
12286 (clobber (reg:CC FLAGS_REG))]
12287 "!TARGET_64BIT && TARGET_GNU2_TLS"
12288 "#"
12289 ""
12290 [(set (match_dup 0) (match_dup 5))]
12291 {
12292 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12293 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12294 })
12295
12296 (define_expand "tls_dynamic_gnu2_64"
12297 [(set (match_dup 2)
12298 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12299 UNSPEC_TLSDESC))
12300 (parallel
12301 [(set (match_operand:DI 0 "register_operand" "")
12302 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12303 UNSPEC_TLSDESC))
12304 (clobber (reg:CC FLAGS_REG))])]
12305 "TARGET_64BIT && TARGET_GNU2_TLS"
12306 {
12307 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12308 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12309 })
12310
12311 (define_insn "*tls_dynamic_lea_64"
12312 [(set (match_operand:DI 0 "register_operand" "=r")
12313 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12314 UNSPEC_TLSDESC))]
12315 "TARGET_64BIT && TARGET_GNU2_TLS"
12316 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12317 [(set_attr "type" "lea")
12318 (set_attr "mode" "DI")
12319 (set_attr "length" "7")
12320 (set_attr "length_address" "4")])
12321
12322 (define_insn "*tls_dynamic_call_64"
12323 [(set (match_operand:DI 0 "register_operand" "=a")
12324 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12325 (match_operand:DI 2 "register_operand" "0")
12326 (reg:DI SP_REG)]
12327 UNSPEC_TLSDESC))
12328 (clobber (reg:CC FLAGS_REG))]
12329 "TARGET_64BIT && TARGET_GNU2_TLS"
12330 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12331 [(set_attr "type" "call")
12332 (set_attr "length" "2")
12333 (set_attr "length_address" "0")])
12334
12335 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12336 [(set (match_operand:DI 0 "register_operand" "=&a")
12337 (plus:DI
12338 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12339 (match_operand:DI 3 "" "")
12340 (reg:DI SP_REG)]
12341 UNSPEC_TLSDESC)
12342 (const:DI (unspec:DI
12343 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12344 UNSPEC_DTPOFF))))
12345 (clobber (reg:CC FLAGS_REG))]
12346 "TARGET_64BIT && TARGET_GNU2_TLS"
12347 "#"
12348 ""
12349 [(set (match_dup 0) (match_dup 4))]
12350 {
12351 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12352 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12353 })
12354 \f
12355 ;; These patterns match the binary 387 instructions for addM3, subM3,
12356 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12357 ;; SFmode. The first is the normal insn, the second the same insn but
12358 ;; with one operand a conversion, and the third the same insn but with
12359 ;; the other operand a conversion. The conversion may be SFmode or
12360 ;; SImode if the target mode DFmode, but only SImode if the target mode
12361 ;; is SFmode.
12362
12363 ;; Gcc is slightly more smart about handling normal two address instructions
12364 ;; so use special patterns for add and mull.
12365
12366 (define_insn "*fop_<mode>_comm_mixed_avx"
12367 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12368 (match_operator:MODEF 3 "binary_fp_operator"
12369 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12370 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12371 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12372 && COMMUTATIVE_ARITH_P (operands[3])
12373 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12374 "* return output_387_binary_op (insn, operands);"
12375 [(set (attr "type")
12376 (if_then_else (eq_attr "alternative" "1")
12377 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12378 (const_string "ssemul")
12379 (const_string "sseadd"))
12380 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12381 (const_string "fmul")
12382 (const_string "fop"))))
12383 (set_attr "prefix" "orig,maybe_vex")
12384 (set_attr "mode" "<MODE>")])
12385
12386 (define_insn "*fop_<mode>_comm_mixed"
12387 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12388 (match_operator:MODEF 3 "binary_fp_operator"
12389 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12390 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12392 && COMMUTATIVE_ARITH_P (operands[3])
12393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12394 "* return output_387_binary_op (insn, operands);"
12395 [(set (attr "type")
12396 (if_then_else (eq_attr "alternative" "1")
12397 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12398 (const_string "ssemul")
12399 (const_string "sseadd"))
12400 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12401 (const_string "fmul")
12402 (const_string "fop"))))
12403 (set_attr "mode" "<MODE>")])
12404
12405 (define_insn "*fop_<mode>_comm_avx"
12406 [(set (match_operand:MODEF 0 "register_operand" "=x")
12407 (match_operator:MODEF 3 "binary_fp_operator"
12408 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12409 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12410 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12411 && COMMUTATIVE_ARITH_P (operands[3])
12412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12413 "* return output_387_binary_op (insn, operands);"
12414 [(set (attr "type")
12415 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12416 (const_string "ssemul")
12417 (const_string "sseadd")))
12418 (set_attr "prefix" "vex")
12419 (set_attr "mode" "<MODE>")])
12420
12421 (define_insn "*fop_<mode>_comm_sse"
12422 [(set (match_operand:MODEF 0 "register_operand" "=x")
12423 (match_operator:MODEF 3 "binary_fp_operator"
12424 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12425 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12427 && COMMUTATIVE_ARITH_P (operands[3])
12428 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12429 "* return output_387_binary_op (insn, operands);"
12430 [(set (attr "type")
12431 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12432 (const_string "ssemul")
12433 (const_string "sseadd")))
12434 (set_attr "mode" "<MODE>")])
12435
12436 (define_insn "*fop_<mode>_comm_i387"
12437 [(set (match_operand:MODEF 0 "register_operand" "=f")
12438 (match_operator:MODEF 3 "binary_fp_operator"
12439 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12440 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12441 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12442 && COMMUTATIVE_ARITH_P (operands[3])
12443 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12444 "* return output_387_binary_op (insn, operands);"
12445 [(set (attr "type")
12446 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12447 (const_string "fmul")
12448 (const_string "fop")))
12449 (set_attr "mode" "<MODE>")])
12450
12451 (define_insn "*fop_<mode>_1_mixed_avx"
12452 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12453 (match_operator:MODEF 3 "binary_fp_operator"
12454 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12455 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12456 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12457 && !COMMUTATIVE_ARITH_P (operands[3])
12458 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12459 "* return output_387_binary_op (insn, operands);"
12460 [(set (attr "type")
12461 (cond [(and (eq_attr "alternative" "2")
12462 (match_operand:MODEF 3 "mult_operator" ""))
12463 (const_string "ssemul")
12464 (and (eq_attr "alternative" "2")
12465 (match_operand:MODEF 3 "div_operator" ""))
12466 (const_string "ssediv")
12467 (eq_attr "alternative" "2")
12468 (const_string "sseadd")
12469 (match_operand:MODEF 3 "mult_operator" "")
12470 (const_string "fmul")
12471 (match_operand:MODEF 3 "div_operator" "")
12472 (const_string "fdiv")
12473 ]
12474 (const_string "fop")))
12475 (set_attr "prefix" "orig,orig,maybe_vex")
12476 (set_attr "mode" "<MODE>")])
12477
12478 (define_insn "*fop_<mode>_1_mixed"
12479 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12480 (match_operator:MODEF 3 "binary_fp_operator"
12481 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12482 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12483 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12484 && !COMMUTATIVE_ARITH_P (operands[3])
12485 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12486 "* return output_387_binary_op (insn, operands);"
12487 [(set (attr "type")
12488 (cond [(and (eq_attr "alternative" "2")
12489 (match_operand:MODEF 3 "mult_operator" ""))
12490 (const_string "ssemul")
12491 (and (eq_attr "alternative" "2")
12492 (match_operand:MODEF 3 "div_operator" ""))
12493 (const_string "ssediv")
12494 (eq_attr "alternative" "2")
12495 (const_string "sseadd")
12496 (match_operand:MODEF 3 "mult_operator" "")
12497 (const_string "fmul")
12498 (match_operand:MODEF 3 "div_operator" "")
12499 (const_string "fdiv")
12500 ]
12501 (const_string "fop")))
12502 (set_attr "mode" "<MODE>")])
12503
12504 (define_insn "*rcpsf2_sse"
12505 [(set (match_operand:SF 0 "register_operand" "=x")
12506 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12507 UNSPEC_RCP))]
12508 "TARGET_SSE_MATH"
12509 "%vrcpss\t{%1, %d0|%d0, %1}"
12510 [(set_attr "type" "sse")
12511 (set_attr "atom_sse_attr" "rcp")
12512 (set_attr "prefix" "maybe_vex")
12513 (set_attr "mode" "SF")])
12514
12515 (define_insn "*fop_<mode>_1_avx"
12516 [(set (match_operand:MODEF 0 "register_operand" "=x")
12517 (match_operator:MODEF 3 "binary_fp_operator"
12518 [(match_operand:MODEF 1 "register_operand" "x")
12519 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12520 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12521 && !COMMUTATIVE_ARITH_P (operands[3])"
12522 "* return output_387_binary_op (insn, operands);"
12523 [(set (attr "type")
12524 (cond [(match_operand:MODEF 3 "mult_operator" "")
12525 (const_string "ssemul")
12526 (match_operand:MODEF 3 "div_operator" "")
12527 (const_string "ssediv")
12528 ]
12529 (const_string "sseadd")))
12530 (set_attr "prefix" "vex")
12531 (set_attr "mode" "<MODE>")])
12532
12533 (define_insn "*fop_<mode>_1_sse"
12534 [(set (match_operand:MODEF 0 "register_operand" "=x")
12535 (match_operator:MODEF 3 "binary_fp_operator"
12536 [(match_operand:MODEF 1 "register_operand" "0")
12537 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12538 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12539 && !COMMUTATIVE_ARITH_P (operands[3])"
12540 "* return output_387_binary_op (insn, operands);"
12541 [(set (attr "type")
12542 (cond [(match_operand:MODEF 3 "mult_operator" "")
12543 (const_string "ssemul")
12544 (match_operand:MODEF 3 "div_operator" "")
12545 (const_string "ssediv")
12546 ]
12547 (const_string "sseadd")))
12548 (set_attr "mode" "<MODE>")])
12549
12550 ;; This pattern is not fully shadowed by the pattern above.
12551 (define_insn "*fop_<mode>_1_i387"
12552 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12553 (match_operator:MODEF 3 "binary_fp_operator"
12554 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12555 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12556 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12557 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12558 && !COMMUTATIVE_ARITH_P (operands[3])
12559 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12560 "* return output_387_binary_op (insn, operands);"
12561 [(set (attr "type")
12562 (cond [(match_operand:MODEF 3 "mult_operator" "")
12563 (const_string "fmul")
12564 (match_operand:MODEF 3 "div_operator" "")
12565 (const_string "fdiv")
12566 ]
12567 (const_string "fop")))
12568 (set_attr "mode" "<MODE>")])
12569
12570 ;; ??? Add SSE splitters for these!
12571 (define_insn "*fop_<MODEF:mode>_2_i387"
12572 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12573 (match_operator:MODEF 3 "binary_fp_operator"
12574 [(float:MODEF
12575 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12576 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12577 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12578 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12579 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12580 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12581 [(set (attr "type")
12582 (cond [(match_operand:MODEF 3 "mult_operator" "")
12583 (const_string "fmul")
12584 (match_operand:MODEF 3 "div_operator" "")
12585 (const_string "fdiv")
12586 ]
12587 (const_string "fop")))
12588 (set_attr "fp_int_src" "true")
12589 (set_attr "mode" "<X87MODEI12:MODE>")])
12590
12591 (define_insn "*fop_<MODEF:mode>_3_i387"
12592 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12593 (match_operator:MODEF 3 "binary_fp_operator"
12594 [(match_operand:MODEF 1 "register_operand" "0,0")
12595 (float:MODEF
12596 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12597 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12598 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12599 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12600 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12601 [(set (attr "type")
12602 (cond [(match_operand:MODEF 3 "mult_operator" "")
12603 (const_string "fmul")
12604 (match_operand:MODEF 3 "div_operator" "")
12605 (const_string "fdiv")
12606 ]
12607 (const_string "fop")))
12608 (set_attr "fp_int_src" "true")
12609 (set_attr "mode" "<MODE>")])
12610
12611 (define_insn "*fop_df_4_i387"
12612 [(set (match_operand:DF 0 "register_operand" "=f,f")
12613 (match_operator:DF 3 "binary_fp_operator"
12614 [(float_extend:DF
12615 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12616 (match_operand:DF 2 "register_operand" "0,f")]))]
12617 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12618 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12620 "* return output_387_binary_op (insn, operands);"
12621 [(set (attr "type")
12622 (cond [(match_operand:DF 3 "mult_operator" "")
12623 (const_string "fmul")
12624 (match_operand:DF 3 "div_operator" "")
12625 (const_string "fdiv")
12626 ]
12627 (const_string "fop")))
12628 (set_attr "mode" "SF")])
12629
12630 (define_insn "*fop_df_5_i387"
12631 [(set (match_operand:DF 0 "register_operand" "=f,f")
12632 (match_operator:DF 3 "binary_fp_operator"
12633 [(match_operand:DF 1 "register_operand" "0,f")
12634 (float_extend:DF
12635 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12636 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12637 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12638 "* return output_387_binary_op (insn, operands);"
12639 [(set (attr "type")
12640 (cond [(match_operand:DF 3 "mult_operator" "")
12641 (const_string "fmul")
12642 (match_operand:DF 3 "div_operator" "")
12643 (const_string "fdiv")
12644 ]
12645 (const_string "fop")))
12646 (set_attr "mode" "SF")])
12647
12648 (define_insn "*fop_df_6_i387"
12649 [(set (match_operand:DF 0 "register_operand" "=f,f")
12650 (match_operator:DF 3 "binary_fp_operator"
12651 [(float_extend:DF
12652 (match_operand:SF 1 "register_operand" "0,f"))
12653 (float_extend:DF
12654 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12655 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12656 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12657 "* return output_387_binary_op (insn, operands);"
12658 [(set (attr "type")
12659 (cond [(match_operand:DF 3 "mult_operator" "")
12660 (const_string "fmul")
12661 (match_operand:DF 3 "div_operator" "")
12662 (const_string "fdiv")
12663 ]
12664 (const_string "fop")))
12665 (set_attr "mode" "SF")])
12666
12667 (define_insn "*fop_xf_comm_i387"
12668 [(set (match_operand:XF 0 "register_operand" "=f")
12669 (match_operator:XF 3 "binary_fp_operator"
12670 [(match_operand:XF 1 "register_operand" "%0")
12671 (match_operand:XF 2 "register_operand" "f")]))]
12672 "TARGET_80387
12673 && COMMUTATIVE_ARITH_P (operands[3])"
12674 "* return output_387_binary_op (insn, operands);"
12675 [(set (attr "type")
12676 (if_then_else (match_operand:XF 3 "mult_operator" "")
12677 (const_string "fmul")
12678 (const_string "fop")))
12679 (set_attr "mode" "XF")])
12680
12681 (define_insn "*fop_xf_1_i387"
12682 [(set (match_operand:XF 0 "register_operand" "=f,f")
12683 (match_operator:XF 3 "binary_fp_operator"
12684 [(match_operand:XF 1 "register_operand" "0,f")
12685 (match_operand:XF 2 "register_operand" "f,0")]))]
12686 "TARGET_80387
12687 && !COMMUTATIVE_ARITH_P (operands[3])"
12688 "* return output_387_binary_op (insn, operands);"
12689 [(set (attr "type")
12690 (cond [(match_operand:XF 3 "mult_operator" "")
12691 (const_string "fmul")
12692 (match_operand:XF 3 "div_operator" "")
12693 (const_string "fdiv")
12694 ]
12695 (const_string "fop")))
12696 (set_attr "mode" "XF")])
12697
12698 (define_insn "*fop_xf_2_i387"
12699 [(set (match_operand:XF 0 "register_operand" "=f,f")
12700 (match_operator:XF 3 "binary_fp_operator"
12701 [(float:XF
12702 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12703 (match_operand:XF 2 "register_operand" "0,0")]))]
12704 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12705 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12706 [(set (attr "type")
12707 (cond [(match_operand:XF 3 "mult_operator" "")
12708 (const_string "fmul")
12709 (match_operand:XF 3 "div_operator" "")
12710 (const_string "fdiv")
12711 ]
12712 (const_string "fop")))
12713 (set_attr "fp_int_src" "true")
12714 (set_attr "mode" "<MODE>")])
12715
12716 (define_insn "*fop_xf_3_i387"
12717 [(set (match_operand:XF 0 "register_operand" "=f,f")
12718 (match_operator:XF 3 "binary_fp_operator"
12719 [(match_operand:XF 1 "register_operand" "0,0")
12720 (float:XF
12721 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12722 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12723 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12724 [(set (attr "type")
12725 (cond [(match_operand:XF 3 "mult_operator" "")
12726 (const_string "fmul")
12727 (match_operand:XF 3 "div_operator" "")
12728 (const_string "fdiv")
12729 ]
12730 (const_string "fop")))
12731 (set_attr "fp_int_src" "true")
12732 (set_attr "mode" "<MODE>")])
12733
12734 (define_insn "*fop_xf_4_i387"
12735 [(set (match_operand:XF 0 "register_operand" "=f,f")
12736 (match_operator:XF 3 "binary_fp_operator"
12737 [(float_extend:XF
12738 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12739 (match_operand:XF 2 "register_operand" "0,f")]))]
12740 "TARGET_80387"
12741 "* return output_387_binary_op (insn, operands);"
12742 [(set (attr "type")
12743 (cond [(match_operand:XF 3 "mult_operator" "")
12744 (const_string "fmul")
12745 (match_operand:XF 3 "div_operator" "")
12746 (const_string "fdiv")
12747 ]
12748 (const_string "fop")))
12749 (set_attr "mode" "<MODE>")])
12750
12751 (define_insn "*fop_xf_5_i387"
12752 [(set (match_operand:XF 0 "register_operand" "=f,f")
12753 (match_operator:XF 3 "binary_fp_operator"
12754 [(match_operand:XF 1 "register_operand" "0,f")
12755 (float_extend:XF
12756 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12757 "TARGET_80387"
12758 "* return output_387_binary_op (insn, operands);"
12759 [(set (attr "type")
12760 (cond [(match_operand:XF 3 "mult_operator" "")
12761 (const_string "fmul")
12762 (match_operand:XF 3 "div_operator" "")
12763 (const_string "fdiv")
12764 ]
12765 (const_string "fop")))
12766 (set_attr "mode" "<MODE>")])
12767
12768 (define_insn "*fop_xf_6_i387"
12769 [(set (match_operand:XF 0 "register_operand" "=f,f")
12770 (match_operator:XF 3 "binary_fp_operator"
12771 [(float_extend:XF
12772 (match_operand:MODEF 1 "register_operand" "0,f"))
12773 (float_extend:XF
12774 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12775 "TARGET_80387"
12776 "* return output_387_binary_op (insn, operands);"
12777 [(set (attr "type")
12778 (cond [(match_operand:XF 3 "mult_operator" "")
12779 (const_string "fmul")
12780 (match_operand:XF 3 "div_operator" "")
12781 (const_string "fdiv")
12782 ]
12783 (const_string "fop")))
12784 (set_attr "mode" "<MODE>")])
12785
12786 (define_split
12787 [(set (match_operand 0 "register_operand" "")
12788 (match_operator 3 "binary_fp_operator"
12789 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12790 (match_operand 2 "register_operand" "")]))]
12791 "reload_completed
12792 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12793 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12794 [(const_int 0)]
12795 {
12796 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12797 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12798 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12799 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12800 GET_MODE (operands[3]),
12801 operands[4],
12802 operands[2])));
12803 ix86_free_from_memory (GET_MODE (operands[1]));
12804 DONE;
12805 })
12806
12807 (define_split
12808 [(set (match_operand 0 "register_operand" "")
12809 (match_operator 3 "binary_fp_operator"
12810 [(match_operand 1 "register_operand" "")
12811 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12812 "reload_completed
12813 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12814 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12815 [(const_int 0)]
12816 {
12817 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12818 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12819 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12820 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12821 GET_MODE (operands[3]),
12822 operands[1],
12823 operands[4])));
12824 ix86_free_from_memory (GET_MODE (operands[2]));
12825 DONE;
12826 })
12827 \f
12828 ;; FPU special functions.
12829
12830 ;; This pattern implements a no-op XFmode truncation for
12831 ;; all fancy i386 XFmode math functions.
12832
12833 (define_insn "truncxf<mode>2_i387_noop_unspec"
12834 [(set (match_operand:MODEF 0 "register_operand" "=f")
12835 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12836 UNSPEC_TRUNC_NOOP))]
12837 "TARGET_USE_FANCY_MATH_387"
12838 "* return output_387_reg_move (insn, operands);"
12839 [(set_attr "type" "fmov")
12840 (set_attr "mode" "<MODE>")])
12841
12842 (define_insn "sqrtxf2"
12843 [(set (match_operand:XF 0 "register_operand" "=f")
12844 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12845 "TARGET_USE_FANCY_MATH_387"
12846 "fsqrt"
12847 [(set_attr "type" "fpspc")
12848 (set_attr "mode" "XF")
12849 (set_attr "athlon_decode" "direct")
12850 (set_attr "amdfam10_decode" "direct")])
12851
12852 (define_insn "sqrt_extend<mode>xf2_i387"
12853 [(set (match_operand:XF 0 "register_operand" "=f")
12854 (sqrt:XF
12855 (float_extend:XF
12856 (match_operand:MODEF 1 "register_operand" "0"))))]
12857 "TARGET_USE_FANCY_MATH_387"
12858 "fsqrt"
12859 [(set_attr "type" "fpspc")
12860 (set_attr "mode" "XF")
12861 (set_attr "athlon_decode" "direct")
12862 (set_attr "amdfam10_decode" "direct")])
12863
12864 (define_insn "*rsqrtsf2_sse"
12865 [(set (match_operand:SF 0 "register_operand" "=x")
12866 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12867 UNSPEC_RSQRT))]
12868 "TARGET_SSE_MATH"
12869 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12870 [(set_attr "type" "sse")
12871 (set_attr "atom_sse_attr" "rcp")
12872 (set_attr "prefix" "maybe_vex")
12873 (set_attr "mode" "SF")])
12874
12875 (define_expand "rsqrtsf2"
12876 [(set (match_operand:SF 0 "register_operand" "")
12877 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12878 UNSPEC_RSQRT))]
12879 "TARGET_SSE_MATH"
12880 {
12881 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12882 DONE;
12883 })
12884
12885 (define_insn "*sqrt<mode>2_sse"
12886 [(set (match_operand:MODEF 0 "register_operand" "=x")
12887 (sqrt:MODEF
12888 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12889 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12890 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12891 [(set_attr "type" "sse")
12892 (set_attr "atom_sse_attr" "sqrt")
12893 (set_attr "prefix" "maybe_vex")
12894 (set_attr "mode" "<MODE>")
12895 (set_attr "athlon_decode" "*")
12896 (set_attr "amdfam10_decode" "*")])
12897
12898 (define_expand "sqrt<mode>2"
12899 [(set (match_operand:MODEF 0 "register_operand" "")
12900 (sqrt:MODEF
12901 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12902 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12903 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12904 {
12905 if (<MODE>mode == SFmode
12906 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12907 && flag_finite_math_only && !flag_trapping_math
12908 && flag_unsafe_math_optimizations)
12909 {
12910 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12911 DONE;
12912 }
12913
12914 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12915 {
12916 rtx op0 = gen_reg_rtx (XFmode);
12917 rtx op1 = force_reg (<MODE>mode, operands[1]);
12918
12919 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12920 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12921 DONE;
12922 }
12923 })
12924
12925 (define_insn "fpremxf4_i387"
12926 [(set (match_operand:XF 0 "register_operand" "=f")
12927 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12928 (match_operand:XF 3 "register_operand" "1")]
12929 UNSPEC_FPREM_F))
12930 (set (match_operand:XF 1 "register_operand" "=u")
12931 (unspec:XF [(match_dup 2) (match_dup 3)]
12932 UNSPEC_FPREM_U))
12933 (set (reg:CCFP FPSR_REG)
12934 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12935 UNSPEC_C2_FLAG))]
12936 "TARGET_USE_FANCY_MATH_387"
12937 "fprem"
12938 [(set_attr "type" "fpspc")
12939 (set_attr "mode" "XF")])
12940
12941 (define_expand "fmodxf3"
12942 [(use (match_operand:XF 0 "register_operand" ""))
12943 (use (match_operand:XF 1 "general_operand" ""))
12944 (use (match_operand:XF 2 "general_operand" ""))]
12945 "TARGET_USE_FANCY_MATH_387"
12946 {
12947 rtx label = gen_label_rtx ();
12948
12949 rtx op1 = gen_reg_rtx (XFmode);
12950 rtx op2 = gen_reg_rtx (XFmode);
12951
12952 emit_move_insn (op2, operands[2]);
12953 emit_move_insn (op1, operands[1]);
12954
12955 emit_label (label);
12956 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12957 ix86_emit_fp_unordered_jump (label);
12958 LABEL_NUSES (label) = 1;
12959
12960 emit_move_insn (operands[0], op1);
12961 DONE;
12962 })
12963
12964 (define_expand "fmod<mode>3"
12965 [(use (match_operand:MODEF 0 "register_operand" ""))
12966 (use (match_operand:MODEF 1 "general_operand" ""))
12967 (use (match_operand:MODEF 2 "general_operand" ""))]
12968 "TARGET_USE_FANCY_MATH_387"
12969 {
12970 rtx (*gen_truncxf) (rtx, rtx);
12971
12972 rtx label = gen_label_rtx ();
12973
12974 rtx op1 = gen_reg_rtx (XFmode);
12975 rtx op2 = gen_reg_rtx (XFmode);
12976
12977 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12979
12980 emit_label (label);
12981 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12982 ix86_emit_fp_unordered_jump (label);
12983 LABEL_NUSES (label) = 1;
12984
12985 /* Truncate the result properly for strict SSE math. */
12986 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12987 && !TARGET_MIX_SSE_I387)
12988 gen_truncxf = gen_truncxf<mode>2;
12989 else
12990 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12991
12992 emit_insn (gen_truncxf (operands[0], op1));
12993 DONE;
12994 })
12995
12996 (define_insn "fprem1xf4_i387"
12997 [(set (match_operand:XF 0 "register_operand" "=f")
12998 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12999 (match_operand:XF 3 "register_operand" "1")]
13000 UNSPEC_FPREM1_F))
13001 (set (match_operand:XF 1 "register_operand" "=u")
13002 (unspec:XF [(match_dup 2) (match_dup 3)]
13003 UNSPEC_FPREM1_U))
13004 (set (reg:CCFP FPSR_REG)
13005 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13006 UNSPEC_C2_FLAG))]
13007 "TARGET_USE_FANCY_MATH_387"
13008 "fprem1"
13009 [(set_attr "type" "fpspc")
13010 (set_attr "mode" "XF")])
13011
13012 (define_expand "remainderxf3"
13013 [(use (match_operand:XF 0 "register_operand" ""))
13014 (use (match_operand:XF 1 "general_operand" ""))
13015 (use (match_operand:XF 2 "general_operand" ""))]
13016 "TARGET_USE_FANCY_MATH_387"
13017 {
13018 rtx label = gen_label_rtx ();
13019
13020 rtx op1 = gen_reg_rtx (XFmode);
13021 rtx op2 = gen_reg_rtx (XFmode);
13022
13023 emit_move_insn (op2, operands[2]);
13024 emit_move_insn (op1, operands[1]);
13025
13026 emit_label (label);
13027 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13028 ix86_emit_fp_unordered_jump (label);
13029 LABEL_NUSES (label) = 1;
13030
13031 emit_move_insn (operands[0], op1);
13032 DONE;
13033 })
13034
13035 (define_expand "remainder<mode>3"
13036 [(use (match_operand:MODEF 0 "register_operand" ""))
13037 (use (match_operand:MODEF 1 "general_operand" ""))
13038 (use (match_operand:MODEF 2 "general_operand" ""))]
13039 "TARGET_USE_FANCY_MATH_387"
13040 {
13041 rtx (*gen_truncxf) (rtx, rtx);
13042
13043 rtx label = gen_label_rtx ();
13044
13045 rtx op1 = gen_reg_rtx (XFmode);
13046 rtx op2 = gen_reg_rtx (XFmode);
13047
13048 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13049 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13050
13051 emit_label (label);
13052
13053 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13054 ix86_emit_fp_unordered_jump (label);
13055 LABEL_NUSES (label) = 1;
13056
13057 /* Truncate the result properly for strict SSE math. */
13058 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13059 && !TARGET_MIX_SSE_I387)
13060 gen_truncxf = gen_truncxf<mode>2;
13061 else
13062 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13063
13064 emit_insn (gen_truncxf (operands[0], op1));
13065 DONE;
13066 })
13067
13068 (define_insn "*sinxf2_i387"
13069 [(set (match_operand:XF 0 "register_operand" "=f")
13070 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13071 "TARGET_USE_FANCY_MATH_387
13072 && flag_unsafe_math_optimizations"
13073 "fsin"
13074 [(set_attr "type" "fpspc")
13075 (set_attr "mode" "XF")])
13076
13077 (define_insn "*sin_extend<mode>xf2_i387"
13078 [(set (match_operand:XF 0 "register_operand" "=f")
13079 (unspec:XF [(float_extend:XF
13080 (match_operand:MODEF 1 "register_operand" "0"))]
13081 UNSPEC_SIN))]
13082 "TARGET_USE_FANCY_MATH_387
13083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13084 || TARGET_MIX_SSE_I387)
13085 && flag_unsafe_math_optimizations"
13086 "fsin"
13087 [(set_attr "type" "fpspc")
13088 (set_attr "mode" "XF")])
13089
13090 (define_insn "*cosxf2_i387"
13091 [(set (match_operand:XF 0 "register_operand" "=f")
13092 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13093 "TARGET_USE_FANCY_MATH_387
13094 && flag_unsafe_math_optimizations"
13095 "fcos"
13096 [(set_attr "type" "fpspc")
13097 (set_attr "mode" "XF")])
13098
13099 (define_insn "*cos_extend<mode>xf2_i387"
13100 [(set (match_operand:XF 0 "register_operand" "=f")
13101 (unspec:XF [(float_extend:XF
13102 (match_operand:MODEF 1 "register_operand" "0"))]
13103 UNSPEC_COS))]
13104 "TARGET_USE_FANCY_MATH_387
13105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13106 || TARGET_MIX_SSE_I387)
13107 && flag_unsafe_math_optimizations"
13108 "fcos"
13109 [(set_attr "type" "fpspc")
13110 (set_attr "mode" "XF")])
13111
13112 ;; When sincos pattern is defined, sin and cos builtin functions will be
13113 ;; expanded to sincos pattern with one of its outputs left unused.
13114 ;; CSE pass will figure out if two sincos patterns can be combined,
13115 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13116 ;; depending on the unused output.
13117
13118 (define_insn "sincosxf3"
13119 [(set (match_operand:XF 0 "register_operand" "=f")
13120 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13121 UNSPEC_SINCOS_COS))
13122 (set (match_operand:XF 1 "register_operand" "=u")
13123 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13124 "TARGET_USE_FANCY_MATH_387
13125 && flag_unsafe_math_optimizations"
13126 "fsincos"
13127 [(set_attr "type" "fpspc")
13128 (set_attr "mode" "XF")])
13129
13130 (define_split
13131 [(set (match_operand:XF 0 "register_operand" "")
13132 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13133 UNSPEC_SINCOS_COS))
13134 (set (match_operand:XF 1 "register_operand" "")
13135 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13136 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13137 && !(reload_completed || reload_in_progress)"
13138 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13139
13140 (define_split
13141 [(set (match_operand:XF 0 "register_operand" "")
13142 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13143 UNSPEC_SINCOS_COS))
13144 (set (match_operand:XF 1 "register_operand" "")
13145 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13146 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13147 && !(reload_completed || reload_in_progress)"
13148 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13149
13150 (define_insn "sincos_extend<mode>xf3_i387"
13151 [(set (match_operand:XF 0 "register_operand" "=f")
13152 (unspec:XF [(float_extend:XF
13153 (match_operand:MODEF 2 "register_operand" "0"))]
13154 UNSPEC_SINCOS_COS))
13155 (set (match_operand:XF 1 "register_operand" "=u")
13156 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13157 "TARGET_USE_FANCY_MATH_387
13158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13159 || TARGET_MIX_SSE_I387)
13160 && flag_unsafe_math_optimizations"
13161 "fsincos"
13162 [(set_attr "type" "fpspc")
13163 (set_attr "mode" "XF")])
13164
13165 (define_split
13166 [(set (match_operand:XF 0 "register_operand" "")
13167 (unspec:XF [(float_extend:XF
13168 (match_operand:MODEF 2 "register_operand" ""))]
13169 UNSPEC_SINCOS_COS))
13170 (set (match_operand:XF 1 "register_operand" "")
13171 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13172 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13173 && !(reload_completed || reload_in_progress)"
13174 [(set (match_dup 1)
13175 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13176
13177 (define_split
13178 [(set (match_operand:XF 0 "register_operand" "")
13179 (unspec:XF [(float_extend:XF
13180 (match_operand:MODEF 2 "register_operand" ""))]
13181 UNSPEC_SINCOS_COS))
13182 (set (match_operand:XF 1 "register_operand" "")
13183 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13184 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13185 && !(reload_completed || reload_in_progress)"
13186 [(set (match_dup 0)
13187 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13188
13189 (define_expand "sincos<mode>3"
13190 [(use (match_operand:MODEF 0 "register_operand" ""))
13191 (use (match_operand:MODEF 1 "register_operand" ""))
13192 (use (match_operand:MODEF 2 "register_operand" ""))]
13193 "TARGET_USE_FANCY_MATH_387
13194 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13195 || TARGET_MIX_SSE_I387)
13196 && flag_unsafe_math_optimizations"
13197 {
13198 rtx op0 = gen_reg_rtx (XFmode);
13199 rtx op1 = gen_reg_rtx (XFmode);
13200
13201 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13202 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13203 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13204 DONE;
13205 })
13206
13207 (define_insn "fptanxf4_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f")
13209 (match_operand:XF 3 "const_double_operand" "F"))
13210 (set (match_operand:XF 1 "register_operand" "=u")
13211 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13212 UNSPEC_TAN))]
13213 "TARGET_USE_FANCY_MATH_387
13214 && flag_unsafe_math_optimizations
13215 && standard_80387_constant_p (operands[3]) == 2"
13216 "fptan"
13217 [(set_attr "type" "fpspc")
13218 (set_attr "mode" "XF")])
13219
13220 (define_insn "fptan_extend<mode>xf4_i387"
13221 [(set (match_operand:MODEF 0 "register_operand" "=f")
13222 (match_operand:MODEF 3 "const_double_operand" "F"))
13223 (set (match_operand:XF 1 "register_operand" "=u")
13224 (unspec:XF [(float_extend:XF
13225 (match_operand:MODEF 2 "register_operand" "0"))]
13226 UNSPEC_TAN))]
13227 "TARGET_USE_FANCY_MATH_387
13228 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13229 || TARGET_MIX_SSE_I387)
13230 && flag_unsafe_math_optimizations
13231 && standard_80387_constant_p (operands[3]) == 2"
13232 "fptan"
13233 [(set_attr "type" "fpspc")
13234 (set_attr "mode" "XF")])
13235
13236 (define_expand "tanxf2"
13237 [(use (match_operand:XF 0 "register_operand" ""))
13238 (use (match_operand:XF 1 "register_operand" ""))]
13239 "TARGET_USE_FANCY_MATH_387
13240 && flag_unsafe_math_optimizations"
13241 {
13242 rtx one = gen_reg_rtx (XFmode);
13243 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13244
13245 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13246 DONE;
13247 })
13248
13249 (define_expand "tan<mode>2"
13250 [(use (match_operand:MODEF 0 "register_operand" ""))
13251 (use (match_operand:MODEF 1 "register_operand" ""))]
13252 "TARGET_USE_FANCY_MATH_387
13253 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13254 || TARGET_MIX_SSE_I387)
13255 && flag_unsafe_math_optimizations"
13256 {
13257 rtx op0 = gen_reg_rtx (XFmode);
13258
13259 rtx one = gen_reg_rtx (<MODE>mode);
13260 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13261
13262 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13263 operands[1], op2));
13264 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13265 DONE;
13266 })
13267
13268 (define_insn "*fpatanxf3_i387"
13269 [(set (match_operand:XF 0 "register_operand" "=f")
13270 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13271 (match_operand:XF 2 "register_operand" "u")]
13272 UNSPEC_FPATAN))
13273 (clobber (match_scratch:XF 3 "=2"))]
13274 "TARGET_USE_FANCY_MATH_387
13275 && flag_unsafe_math_optimizations"
13276 "fpatan"
13277 [(set_attr "type" "fpspc")
13278 (set_attr "mode" "XF")])
13279
13280 (define_insn "fpatan_extend<mode>xf3_i387"
13281 [(set (match_operand:XF 0 "register_operand" "=f")
13282 (unspec:XF [(float_extend:XF
13283 (match_operand:MODEF 1 "register_operand" "0"))
13284 (float_extend:XF
13285 (match_operand:MODEF 2 "register_operand" "u"))]
13286 UNSPEC_FPATAN))
13287 (clobber (match_scratch:XF 3 "=2"))]
13288 "TARGET_USE_FANCY_MATH_387
13289 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13290 || TARGET_MIX_SSE_I387)
13291 && flag_unsafe_math_optimizations"
13292 "fpatan"
13293 [(set_attr "type" "fpspc")
13294 (set_attr "mode" "XF")])
13295
13296 (define_expand "atan2xf3"
13297 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13298 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13299 (match_operand:XF 1 "register_operand" "")]
13300 UNSPEC_FPATAN))
13301 (clobber (match_scratch:XF 3 ""))])]
13302 "TARGET_USE_FANCY_MATH_387
13303 && flag_unsafe_math_optimizations")
13304
13305 (define_expand "atan2<mode>3"
13306 [(use (match_operand:MODEF 0 "register_operand" ""))
13307 (use (match_operand:MODEF 1 "register_operand" ""))
13308 (use (match_operand:MODEF 2 "register_operand" ""))]
13309 "TARGET_USE_FANCY_MATH_387
13310 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13311 || TARGET_MIX_SSE_I387)
13312 && flag_unsafe_math_optimizations"
13313 {
13314 rtx op0 = gen_reg_rtx (XFmode);
13315
13316 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13318 DONE;
13319 })
13320
13321 (define_expand "atanxf2"
13322 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13323 (unspec:XF [(match_dup 2)
13324 (match_operand:XF 1 "register_operand" "")]
13325 UNSPEC_FPATAN))
13326 (clobber (match_scratch:XF 3 ""))])]
13327 "TARGET_USE_FANCY_MATH_387
13328 && flag_unsafe_math_optimizations"
13329 {
13330 operands[2] = gen_reg_rtx (XFmode);
13331 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13332 })
13333
13334 (define_expand "atan<mode>2"
13335 [(use (match_operand:MODEF 0 "register_operand" ""))
13336 (use (match_operand:MODEF 1 "register_operand" ""))]
13337 "TARGET_USE_FANCY_MATH_387
13338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13339 || TARGET_MIX_SSE_I387)
13340 && flag_unsafe_math_optimizations"
13341 {
13342 rtx op0 = gen_reg_rtx (XFmode);
13343
13344 rtx op2 = gen_reg_rtx (<MODE>mode);
13345 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13346
13347 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13348 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13349 DONE;
13350 })
13351
13352 (define_expand "asinxf2"
13353 [(set (match_dup 2)
13354 (mult:XF (match_operand:XF 1 "register_operand" "")
13355 (match_dup 1)))
13356 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13357 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13358 (parallel [(set (match_operand:XF 0 "register_operand" "")
13359 (unspec:XF [(match_dup 5) (match_dup 1)]
13360 UNSPEC_FPATAN))
13361 (clobber (match_scratch:XF 6 ""))])]
13362 "TARGET_USE_FANCY_MATH_387
13363 && flag_unsafe_math_optimizations"
13364 {
13365 int i;
13366
13367 if (optimize_insn_for_size_p ())
13368 FAIL;
13369
13370 for (i = 2; i < 6; i++)
13371 operands[i] = gen_reg_rtx (XFmode);
13372
13373 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13374 })
13375
13376 (define_expand "asin<mode>2"
13377 [(use (match_operand:MODEF 0 "register_operand" ""))
13378 (use (match_operand:MODEF 1 "general_operand" ""))]
13379 "TARGET_USE_FANCY_MATH_387
13380 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13381 || TARGET_MIX_SSE_I387)
13382 && flag_unsafe_math_optimizations"
13383 {
13384 rtx op0 = gen_reg_rtx (XFmode);
13385 rtx op1 = gen_reg_rtx (XFmode);
13386
13387 if (optimize_insn_for_size_p ())
13388 FAIL;
13389
13390 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13391 emit_insn (gen_asinxf2 (op0, op1));
13392 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13393 DONE;
13394 })
13395
13396 (define_expand "acosxf2"
13397 [(set (match_dup 2)
13398 (mult:XF (match_operand:XF 1 "register_operand" "")
13399 (match_dup 1)))
13400 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13401 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13402 (parallel [(set (match_operand:XF 0 "register_operand" "")
13403 (unspec:XF [(match_dup 1) (match_dup 5)]
13404 UNSPEC_FPATAN))
13405 (clobber (match_scratch:XF 6 ""))])]
13406 "TARGET_USE_FANCY_MATH_387
13407 && flag_unsafe_math_optimizations"
13408 {
13409 int i;
13410
13411 if (optimize_insn_for_size_p ())
13412 FAIL;
13413
13414 for (i = 2; i < 6; i++)
13415 operands[i] = gen_reg_rtx (XFmode);
13416
13417 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13418 })
13419
13420 (define_expand "acos<mode>2"
13421 [(use (match_operand:MODEF 0 "register_operand" ""))
13422 (use (match_operand:MODEF 1 "general_operand" ""))]
13423 "TARGET_USE_FANCY_MATH_387
13424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13425 || TARGET_MIX_SSE_I387)
13426 && flag_unsafe_math_optimizations"
13427 {
13428 rtx op0 = gen_reg_rtx (XFmode);
13429 rtx op1 = gen_reg_rtx (XFmode);
13430
13431 if (optimize_insn_for_size_p ())
13432 FAIL;
13433
13434 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13435 emit_insn (gen_acosxf2 (op0, op1));
13436 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13437 DONE;
13438 })
13439
13440 (define_insn "fyl2xxf3_i387"
13441 [(set (match_operand:XF 0 "register_operand" "=f")
13442 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13443 (match_operand:XF 2 "register_operand" "u")]
13444 UNSPEC_FYL2X))
13445 (clobber (match_scratch:XF 3 "=2"))]
13446 "TARGET_USE_FANCY_MATH_387
13447 && flag_unsafe_math_optimizations"
13448 "fyl2x"
13449 [(set_attr "type" "fpspc")
13450 (set_attr "mode" "XF")])
13451
13452 (define_insn "fyl2x_extend<mode>xf3_i387"
13453 [(set (match_operand:XF 0 "register_operand" "=f")
13454 (unspec:XF [(float_extend:XF
13455 (match_operand:MODEF 1 "register_operand" "0"))
13456 (match_operand:XF 2 "register_operand" "u")]
13457 UNSPEC_FYL2X))
13458 (clobber (match_scratch:XF 3 "=2"))]
13459 "TARGET_USE_FANCY_MATH_387
13460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461 || TARGET_MIX_SSE_I387)
13462 && flag_unsafe_math_optimizations"
13463 "fyl2x"
13464 [(set_attr "type" "fpspc")
13465 (set_attr "mode" "XF")])
13466
13467 (define_expand "logxf2"
13468 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13469 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13470 (match_dup 2)] UNSPEC_FYL2X))
13471 (clobber (match_scratch:XF 3 ""))])]
13472 "TARGET_USE_FANCY_MATH_387
13473 && flag_unsafe_math_optimizations"
13474 {
13475 operands[2] = gen_reg_rtx (XFmode);
13476 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13477 })
13478
13479 (define_expand "log<mode>2"
13480 [(use (match_operand:MODEF 0 "register_operand" ""))
13481 (use (match_operand:MODEF 1 "register_operand" ""))]
13482 "TARGET_USE_FANCY_MATH_387
13483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13484 || TARGET_MIX_SSE_I387)
13485 && flag_unsafe_math_optimizations"
13486 {
13487 rtx op0 = gen_reg_rtx (XFmode);
13488
13489 rtx op2 = gen_reg_rtx (XFmode);
13490 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13491
13492 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13493 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13494 DONE;
13495 })
13496
13497 (define_expand "log10xf2"
13498 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13499 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13500 (match_dup 2)] UNSPEC_FYL2X))
13501 (clobber (match_scratch:XF 3 ""))])]
13502 "TARGET_USE_FANCY_MATH_387
13503 && flag_unsafe_math_optimizations"
13504 {
13505 operands[2] = gen_reg_rtx (XFmode);
13506 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13507 })
13508
13509 (define_expand "log10<mode>2"
13510 [(use (match_operand:MODEF 0 "register_operand" ""))
13511 (use (match_operand:MODEF 1 "register_operand" ""))]
13512 "TARGET_USE_FANCY_MATH_387
13513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13514 || TARGET_MIX_SSE_I387)
13515 && flag_unsafe_math_optimizations"
13516 {
13517 rtx op0 = gen_reg_rtx (XFmode);
13518
13519 rtx op2 = gen_reg_rtx (XFmode);
13520 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13521
13522 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13524 DONE;
13525 })
13526
13527 (define_expand "log2xf2"
13528 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13530 (match_dup 2)] UNSPEC_FYL2X))
13531 (clobber (match_scratch:XF 3 ""))])]
13532 "TARGET_USE_FANCY_MATH_387
13533 && flag_unsafe_math_optimizations"
13534 {
13535 operands[2] = gen_reg_rtx (XFmode);
13536 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13537 })
13538
13539 (define_expand "log2<mode>2"
13540 [(use (match_operand:MODEF 0 "register_operand" ""))
13541 (use (match_operand:MODEF 1 "register_operand" ""))]
13542 "TARGET_USE_FANCY_MATH_387
13543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544 || TARGET_MIX_SSE_I387)
13545 && flag_unsafe_math_optimizations"
13546 {
13547 rtx op0 = gen_reg_rtx (XFmode);
13548
13549 rtx op2 = gen_reg_rtx (XFmode);
13550 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13551
13552 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13554 DONE;
13555 })
13556
13557 (define_insn "fyl2xp1xf3_i387"
13558 [(set (match_operand:XF 0 "register_operand" "=f")
13559 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13560 (match_operand:XF 2 "register_operand" "u")]
13561 UNSPEC_FYL2XP1))
13562 (clobber (match_scratch:XF 3 "=2"))]
13563 "TARGET_USE_FANCY_MATH_387
13564 && flag_unsafe_math_optimizations"
13565 "fyl2xp1"
13566 [(set_attr "type" "fpspc")
13567 (set_attr "mode" "XF")])
13568
13569 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13570 [(set (match_operand:XF 0 "register_operand" "=f")
13571 (unspec:XF [(float_extend:XF
13572 (match_operand:MODEF 1 "register_operand" "0"))
13573 (match_operand:XF 2 "register_operand" "u")]
13574 UNSPEC_FYL2XP1))
13575 (clobber (match_scratch:XF 3 "=2"))]
13576 "TARGET_USE_FANCY_MATH_387
13577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578 || TARGET_MIX_SSE_I387)
13579 && flag_unsafe_math_optimizations"
13580 "fyl2xp1"
13581 [(set_attr "type" "fpspc")
13582 (set_attr "mode" "XF")])
13583
13584 (define_expand "log1pxf2"
13585 [(use (match_operand:XF 0 "register_operand" ""))
13586 (use (match_operand:XF 1 "register_operand" ""))]
13587 "TARGET_USE_FANCY_MATH_387
13588 && flag_unsafe_math_optimizations"
13589 {
13590 if (optimize_insn_for_size_p ())
13591 FAIL;
13592
13593 ix86_emit_i387_log1p (operands[0], operands[1]);
13594 DONE;
13595 })
13596
13597 (define_expand "log1p<mode>2"
13598 [(use (match_operand:MODEF 0 "register_operand" ""))
13599 (use (match_operand:MODEF 1 "register_operand" ""))]
13600 "TARGET_USE_FANCY_MATH_387
13601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13602 || TARGET_MIX_SSE_I387)
13603 && flag_unsafe_math_optimizations"
13604 {
13605 rtx op0;
13606
13607 if (optimize_insn_for_size_p ())
13608 FAIL;
13609
13610 op0 = gen_reg_rtx (XFmode);
13611
13612 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13613
13614 ix86_emit_i387_log1p (op0, operands[1]);
13615 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13616 DONE;
13617 })
13618
13619 (define_insn "fxtractxf3_i387"
13620 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13622 UNSPEC_XTRACT_FRACT))
13623 (set (match_operand:XF 1 "register_operand" "=u")
13624 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13625 "TARGET_USE_FANCY_MATH_387
13626 && flag_unsafe_math_optimizations"
13627 "fxtract"
13628 [(set_attr "type" "fpspc")
13629 (set_attr "mode" "XF")])
13630
13631 (define_insn "fxtract_extend<mode>xf3_i387"
13632 [(set (match_operand:XF 0 "register_operand" "=f")
13633 (unspec:XF [(float_extend:XF
13634 (match_operand:MODEF 2 "register_operand" "0"))]
13635 UNSPEC_XTRACT_FRACT))
13636 (set (match_operand:XF 1 "register_operand" "=u")
13637 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13638 "TARGET_USE_FANCY_MATH_387
13639 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13640 || TARGET_MIX_SSE_I387)
13641 && flag_unsafe_math_optimizations"
13642 "fxtract"
13643 [(set_attr "type" "fpspc")
13644 (set_attr "mode" "XF")])
13645
13646 (define_expand "logbxf2"
13647 [(parallel [(set (match_dup 2)
13648 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13649 UNSPEC_XTRACT_FRACT))
13650 (set (match_operand:XF 0 "register_operand" "")
13651 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13652 "TARGET_USE_FANCY_MATH_387
13653 && flag_unsafe_math_optimizations"
13654 "operands[2] = gen_reg_rtx (XFmode);")
13655
13656 (define_expand "logb<mode>2"
13657 [(use (match_operand:MODEF 0 "register_operand" ""))
13658 (use (match_operand:MODEF 1 "register_operand" ""))]
13659 "TARGET_USE_FANCY_MATH_387
13660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13661 || TARGET_MIX_SSE_I387)
13662 && flag_unsafe_math_optimizations"
13663 {
13664 rtx op0 = gen_reg_rtx (XFmode);
13665 rtx op1 = gen_reg_rtx (XFmode);
13666
13667 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13668 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13669 DONE;
13670 })
13671
13672 (define_expand "ilogbxf2"
13673 [(use (match_operand:SI 0 "register_operand" ""))
13674 (use (match_operand:XF 1 "register_operand" ""))]
13675 "TARGET_USE_FANCY_MATH_387
13676 && flag_unsafe_math_optimizations"
13677 {
13678 rtx op0, op1;
13679
13680 if (optimize_insn_for_size_p ())
13681 FAIL;
13682
13683 op0 = gen_reg_rtx (XFmode);
13684 op1 = gen_reg_rtx (XFmode);
13685
13686 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13687 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13688 DONE;
13689 })
13690
13691 (define_expand "ilogb<mode>2"
13692 [(use (match_operand:SI 0 "register_operand" ""))
13693 (use (match_operand:MODEF 1 "register_operand" ""))]
13694 "TARGET_USE_FANCY_MATH_387
13695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13696 || TARGET_MIX_SSE_I387)
13697 && flag_unsafe_math_optimizations"
13698 {
13699 rtx op0, op1;
13700
13701 if (optimize_insn_for_size_p ())
13702 FAIL;
13703
13704 op0 = gen_reg_rtx (XFmode);
13705 op1 = gen_reg_rtx (XFmode);
13706
13707 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13708 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13709 DONE;
13710 })
13711
13712 (define_insn "*f2xm1xf2_i387"
13713 [(set (match_operand:XF 0 "register_operand" "=f")
13714 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13715 UNSPEC_F2XM1))]
13716 "TARGET_USE_FANCY_MATH_387
13717 && flag_unsafe_math_optimizations"
13718 "f2xm1"
13719 [(set_attr "type" "fpspc")
13720 (set_attr "mode" "XF")])
13721
13722 (define_insn "*fscalexf4_i387"
13723 [(set (match_operand:XF 0 "register_operand" "=f")
13724 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13725 (match_operand:XF 3 "register_operand" "1")]
13726 UNSPEC_FSCALE_FRACT))
13727 (set (match_operand:XF 1 "register_operand" "=u")
13728 (unspec:XF [(match_dup 2) (match_dup 3)]
13729 UNSPEC_FSCALE_EXP))]
13730 "TARGET_USE_FANCY_MATH_387
13731 && flag_unsafe_math_optimizations"
13732 "fscale"
13733 [(set_attr "type" "fpspc")
13734 (set_attr "mode" "XF")])
13735
13736 (define_expand "expNcorexf3"
13737 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13738 (match_operand:XF 2 "register_operand" "")))
13739 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13740 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13741 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13742 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13743 (parallel [(set (match_operand:XF 0 "register_operand" "")
13744 (unspec:XF [(match_dup 8) (match_dup 4)]
13745 UNSPEC_FSCALE_FRACT))
13746 (set (match_dup 9)
13747 (unspec:XF [(match_dup 8) (match_dup 4)]
13748 UNSPEC_FSCALE_EXP))])]
13749 "TARGET_USE_FANCY_MATH_387
13750 && flag_unsafe_math_optimizations"
13751 {
13752 int i;
13753
13754 if (optimize_insn_for_size_p ())
13755 FAIL;
13756
13757 for (i = 3; i < 10; i++)
13758 operands[i] = gen_reg_rtx (XFmode);
13759
13760 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13761 })
13762
13763 (define_expand "expxf2"
13764 [(use (match_operand:XF 0 "register_operand" ""))
13765 (use (match_operand:XF 1 "register_operand" ""))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && flag_unsafe_math_optimizations"
13768 {
13769 rtx op2;
13770
13771 if (optimize_insn_for_size_p ())
13772 FAIL;
13773
13774 op2 = gen_reg_rtx (XFmode);
13775 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13776
13777 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13778 DONE;
13779 })
13780
13781 (define_expand "exp<mode>2"
13782 [(use (match_operand:MODEF 0 "register_operand" ""))
13783 (use (match_operand:MODEF 1 "general_operand" ""))]
13784 "TARGET_USE_FANCY_MATH_387
13785 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13786 || TARGET_MIX_SSE_I387)
13787 && flag_unsafe_math_optimizations"
13788 {
13789 rtx op0, op1;
13790
13791 if (optimize_insn_for_size_p ())
13792 FAIL;
13793
13794 op0 = gen_reg_rtx (XFmode);
13795 op1 = gen_reg_rtx (XFmode);
13796
13797 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13798 emit_insn (gen_expxf2 (op0, op1));
13799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13800 DONE;
13801 })
13802
13803 (define_expand "exp10xf2"
13804 [(use (match_operand:XF 0 "register_operand" ""))
13805 (use (match_operand:XF 1 "register_operand" ""))]
13806 "TARGET_USE_FANCY_MATH_387
13807 && flag_unsafe_math_optimizations"
13808 {
13809 rtx op2;
13810
13811 if (optimize_insn_for_size_p ())
13812 FAIL;
13813
13814 op2 = gen_reg_rtx (XFmode);
13815 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13816
13817 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13818 DONE;
13819 })
13820
13821 (define_expand "exp10<mode>2"
13822 [(use (match_operand:MODEF 0 "register_operand" ""))
13823 (use (match_operand:MODEF 1 "general_operand" ""))]
13824 "TARGET_USE_FANCY_MATH_387
13825 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13826 || TARGET_MIX_SSE_I387)
13827 && flag_unsafe_math_optimizations"
13828 {
13829 rtx op0, op1;
13830
13831 if (optimize_insn_for_size_p ())
13832 FAIL;
13833
13834 op0 = gen_reg_rtx (XFmode);
13835 op1 = gen_reg_rtx (XFmode);
13836
13837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13838 emit_insn (gen_exp10xf2 (op0, op1));
13839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13840 DONE;
13841 })
13842
13843 (define_expand "exp2xf2"
13844 [(use (match_operand:XF 0 "register_operand" ""))
13845 (use (match_operand:XF 1 "register_operand" ""))]
13846 "TARGET_USE_FANCY_MATH_387
13847 && flag_unsafe_math_optimizations"
13848 {
13849 rtx op2;
13850
13851 if (optimize_insn_for_size_p ())
13852 FAIL;
13853
13854 op2 = gen_reg_rtx (XFmode);
13855 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13856
13857 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13858 DONE;
13859 })
13860
13861 (define_expand "exp2<mode>2"
13862 [(use (match_operand:MODEF 0 "register_operand" ""))
13863 (use (match_operand:MODEF 1 "general_operand" ""))]
13864 "TARGET_USE_FANCY_MATH_387
13865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13866 || TARGET_MIX_SSE_I387)
13867 && flag_unsafe_math_optimizations"
13868 {
13869 rtx op0, op1;
13870
13871 if (optimize_insn_for_size_p ())
13872 FAIL;
13873
13874 op0 = gen_reg_rtx (XFmode);
13875 op1 = gen_reg_rtx (XFmode);
13876
13877 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13878 emit_insn (gen_exp2xf2 (op0, op1));
13879 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13880 DONE;
13881 })
13882
13883 (define_expand "expm1xf2"
13884 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13885 (match_dup 2)))
13886 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13887 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13888 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13889 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13890 (parallel [(set (match_dup 7)
13891 (unspec:XF [(match_dup 6) (match_dup 4)]
13892 UNSPEC_FSCALE_FRACT))
13893 (set (match_dup 8)
13894 (unspec:XF [(match_dup 6) (match_dup 4)]
13895 UNSPEC_FSCALE_EXP))])
13896 (parallel [(set (match_dup 10)
13897 (unspec:XF [(match_dup 9) (match_dup 8)]
13898 UNSPEC_FSCALE_FRACT))
13899 (set (match_dup 11)
13900 (unspec:XF [(match_dup 9) (match_dup 8)]
13901 UNSPEC_FSCALE_EXP))])
13902 (set (match_dup 12) (minus:XF (match_dup 10)
13903 (float_extend:XF (match_dup 13))))
13904 (set (match_operand:XF 0 "register_operand" "")
13905 (plus:XF (match_dup 12) (match_dup 7)))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && flag_unsafe_math_optimizations"
13908 {
13909 int i;
13910
13911 if (optimize_insn_for_size_p ())
13912 FAIL;
13913
13914 for (i = 2; i < 13; i++)
13915 operands[i] = gen_reg_rtx (XFmode);
13916
13917 operands[13]
13918 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13919
13920 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13921 })
13922
13923 (define_expand "expm1<mode>2"
13924 [(use (match_operand:MODEF 0 "register_operand" ""))
13925 (use (match_operand:MODEF 1 "general_operand" ""))]
13926 "TARGET_USE_FANCY_MATH_387
13927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13928 || TARGET_MIX_SSE_I387)
13929 && flag_unsafe_math_optimizations"
13930 {
13931 rtx op0, op1;
13932
13933 if (optimize_insn_for_size_p ())
13934 FAIL;
13935
13936 op0 = gen_reg_rtx (XFmode);
13937 op1 = gen_reg_rtx (XFmode);
13938
13939 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13940 emit_insn (gen_expm1xf2 (op0, op1));
13941 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13942 DONE;
13943 })
13944
13945 (define_expand "ldexpxf3"
13946 [(set (match_dup 3)
13947 (float:XF (match_operand:SI 2 "register_operand" "")))
13948 (parallel [(set (match_operand:XF 0 " register_operand" "")
13949 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13950 (match_dup 3)]
13951 UNSPEC_FSCALE_FRACT))
13952 (set (match_dup 4)
13953 (unspec:XF [(match_dup 1) (match_dup 3)]
13954 UNSPEC_FSCALE_EXP))])]
13955 "TARGET_USE_FANCY_MATH_387
13956 && flag_unsafe_math_optimizations"
13957 {
13958 if (optimize_insn_for_size_p ())
13959 FAIL;
13960
13961 operands[3] = gen_reg_rtx (XFmode);
13962 operands[4] = gen_reg_rtx (XFmode);
13963 })
13964
13965 (define_expand "ldexp<mode>3"
13966 [(use (match_operand:MODEF 0 "register_operand" ""))
13967 (use (match_operand:MODEF 1 "general_operand" ""))
13968 (use (match_operand:SI 2 "register_operand" ""))]
13969 "TARGET_USE_FANCY_MATH_387
13970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13971 || TARGET_MIX_SSE_I387)
13972 && flag_unsafe_math_optimizations"
13973 {
13974 rtx op0, op1;
13975
13976 if (optimize_insn_for_size_p ())
13977 FAIL;
13978
13979 op0 = gen_reg_rtx (XFmode);
13980 op1 = gen_reg_rtx (XFmode);
13981
13982 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13983 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13985 DONE;
13986 })
13987
13988 (define_expand "scalbxf3"
13989 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13990 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13991 (match_operand:XF 2 "register_operand" "")]
13992 UNSPEC_FSCALE_FRACT))
13993 (set (match_dup 3)
13994 (unspec:XF [(match_dup 1) (match_dup 2)]
13995 UNSPEC_FSCALE_EXP))])]
13996 "TARGET_USE_FANCY_MATH_387
13997 && flag_unsafe_math_optimizations"
13998 {
13999 if (optimize_insn_for_size_p ())
14000 FAIL;
14001
14002 operands[3] = gen_reg_rtx (XFmode);
14003 })
14004
14005 (define_expand "scalb<mode>3"
14006 [(use (match_operand:MODEF 0 "register_operand" ""))
14007 (use (match_operand:MODEF 1 "general_operand" ""))
14008 (use (match_operand:MODEF 2 "general_operand" ""))]
14009 "TARGET_USE_FANCY_MATH_387
14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011 || TARGET_MIX_SSE_I387)
14012 && flag_unsafe_math_optimizations"
14013 {
14014 rtx op0, op1, op2;
14015
14016 if (optimize_insn_for_size_p ())
14017 FAIL;
14018
14019 op0 = gen_reg_rtx (XFmode);
14020 op1 = gen_reg_rtx (XFmode);
14021 op2 = gen_reg_rtx (XFmode);
14022
14023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14024 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14025 emit_insn (gen_scalbxf3 (op0, op1, op2));
14026 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14027 DONE;
14028 })
14029
14030 (define_expand "significandxf2"
14031 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14032 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14033 UNSPEC_XTRACT_FRACT))
14034 (set (match_dup 2)
14035 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14036 "TARGET_USE_FANCY_MATH_387
14037 && flag_unsafe_math_optimizations"
14038 "operands[2] = gen_reg_rtx (XFmode);")
14039
14040 (define_expand "significand<mode>2"
14041 [(use (match_operand:MODEF 0 "register_operand" ""))
14042 (use (match_operand:MODEF 1 "register_operand" ""))]
14043 "TARGET_USE_FANCY_MATH_387
14044 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045 || TARGET_MIX_SSE_I387)
14046 && flag_unsafe_math_optimizations"
14047 {
14048 rtx op0 = gen_reg_rtx (XFmode);
14049 rtx op1 = gen_reg_rtx (XFmode);
14050
14051 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053 DONE;
14054 })
14055 \f
14056
14057 (define_insn "sse4_1_round<mode>2"
14058 [(set (match_operand:MODEF 0 "register_operand" "=x")
14059 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14060 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14061 UNSPEC_ROUND))]
14062 "TARGET_ROUND"
14063 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14064 [(set_attr "type" "ssecvt")
14065 (set_attr "prefix_extra" "1")
14066 (set_attr "prefix" "maybe_vex")
14067 (set_attr "mode" "<MODE>")])
14068
14069 (define_insn "rintxf2"
14070 [(set (match_operand:XF 0 "register_operand" "=f")
14071 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14072 UNSPEC_FRNDINT))]
14073 "TARGET_USE_FANCY_MATH_387
14074 && flag_unsafe_math_optimizations"
14075 "frndint"
14076 [(set_attr "type" "fpspc")
14077 (set_attr "mode" "XF")])
14078
14079 (define_expand "rint<mode>2"
14080 [(use (match_operand:MODEF 0 "register_operand" ""))
14081 (use (match_operand:MODEF 1 "register_operand" ""))]
14082 "(TARGET_USE_FANCY_MATH_387
14083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14084 || TARGET_MIX_SSE_I387)
14085 && flag_unsafe_math_optimizations)
14086 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14087 && !flag_trapping_math)"
14088 {
14089 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14090 && !flag_trapping_math)
14091 {
14092 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14093 FAIL;
14094 if (TARGET_ROUND)
14095 emit_insn (gen_sse4_1_round<mode>2
14096 (operands[0], operands[1], GEN_INT (0x04)));
14097 else
14098 ix86_expand_rint (operand0, operand1);
14099 }
14100 else
14101 {
14102 rtx op0 = gen_reg_rtx (XFmode);
14103 rtx op1 = gen_reg_rtx (XFmode);
14104
14105 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14106 emit_insn (gen_rintxf2 (op0, op1));
14107
14108 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14109 }
14110 DONE;
14111 })
14112
14113 (define_expand "round<mode>2"
14114 [(match_operand:MODEF 0 "register_operand" "")
14115 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14116 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14117 && !flag_trapping_math && !flag_rounding_math"
14118 {
14119 if (optimize_insn_for_size_p ())
14120 FAIL;
14121 if (TARGET_64BIT || (<MODE>mode != DFmode))
14122 ix86_expand_round (operand0, operand1);
14123 else
14124 ix86_expand_rounddf_32 (operand0, operand1);
14125 DONE;
14126 })
14127
14128 (define_insn_and_split "*fistdi2_1"
14129 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14130 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14131 UNSPEC_FIST))]
14132 "TARGET_USE_FANCY_MATH_387
14133 && can_create_pseudo_p ()"
14134 "#"
14135 "&& 1"
14136 [(const_int 0)]
14137 {
14138 if (memory_operand (operands[0], VOIDmode))
14139 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14140 else
14141 {
14142 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14143 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14144 operands[2]));
14145 }
14146 DONE;
14147 }
14148 [(set_attr "type" "fpspc")
14149 (set_attr "mode" "DI")])
14150
14151 (define_insn "fistdi2"
14152 [(set (match_operand:DI 0 "memory_operand" "=m")
14153 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14154 UNSPEC_FIST))
14155 (clobber (match_scratch:XF 2 "=&1f"))]
14156 "TARGET_USE_FANCY_MATH_387"
14157 "* return output_fix_trunc (insn, operands, 0);"
14158 [(set_attr "type" "fpspc")
14159 (set_attr "mode" "DI")])
14160
14161 (define_insn "fistdi2_with_temp"
14162 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14163 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14164 UNSPEC_FIST))
14165 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14166 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14167 "TARGET_USE_FANCY_MATH_387"
14168 "#"
14169 [(set_attr "type" "fpspc")
14170 (set_attr "mode" "DI")])
14171
14172 (define_split
14173 [(set (match_operand:DI 0 "register_operand" "")
14174 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14175 UNSPEC_FIST))
14176 (clobber (match_operand:DI 2 "memory_operand" ""))
14177 (clobber (match_scratch 3 ""))]
14178 "reload_completed"
14179 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14180 (clobber (match_dup 3))])
14181 (set (match_dup 0) (match_dup 2))])
14182
14183 (define_split
14184 [(set (match_operand:DI 0 "memory_operand" "")
14185 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14186 UNSPEC_FIST))
14187 (clobber (match_operand:DI 2 "memory_operand" ""))
14188 (clobber (match_scratch 3 ""))]
14189 "reload_completed"
14190 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14191 (clobber (match_dup 3))])])
14192
14193 (define_insn_and_split "*fist<mode>2_1"
14194 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14195 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14196 UNSPEC_FIST))]
14197 "TARGET_USE_FANCY_MATH_387
14198 && can_create_pseudo_p ()"
14199 "#"
14200 "&& 1"
14201 [(const_int 0)]
14202 {
14203 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14204 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14205 operands[2]));
14206 DONE;
14207 }
14208 [(set_attr "type" "fpspc")
14209 (set_attr "mode" "<MODE>")])
14210
14211 (define_insn "fist<mode>2"
14212 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14213 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14214 UNSPEC_FIST))]
14215 "TARGET_USE_FANCY_MATH_387"
14216 "* return output_fix_trunc (insn, operands, 0);"
14217 [(set_attr "type" "fpspc")
14218 (set_attr "mode" "<MODE>")])
14219
14220 (define_insn "fist<mode>2_with_temp"
14221 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14222 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14223 UNSPEC_FIST))
14224 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14225 "TARGET_USE_FANCY_MATH_387"
14226 "#"
14227 [(set_attr "type" "fpspc")
14228 (set_attr "mode" "<MODE>")])
14229
14230 (define_split
14231 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14232 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14233 UNSPEC_FIST))
14234 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14235 "reload_completed"
14236 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14237 (set (match_dup 0) (match_dup 2))])
14238
14239 (define_split
14240 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14241 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14242 UNSPEC_FIST))
14243 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14244 "reload_completed"
14245 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14246
14247 (define_expand "lrintxf<mode>2"
14248 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14249 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14250 UNSPEC_FIST))]
14251 "TARGET_USE_FANCY_MATH_387")
14252
14253 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14254 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14255 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14256 UNSPEC_FIX_NOTRUNC))]
14257 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14258 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14259
14260 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14261 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14262 (match_operand:MODEF 1 "register_operand" "")]
14263 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14264 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14265 && !flag_trapping_math && !flag_rounding_math"
14266 {
14267 if (optimize_insn_for_size_p ())
14268 FAIL;
14269 ix86_expand_lround (operand0, operand1);
14270 DONE;
14271 })
14272
14273 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14274 (define_insn_and_split "frndintxf2_floor"
14275 [(set (match_operand:XF 0 "register_operand" "")
14276 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14277 UNSPEC_FRNDINT_FLOOR))
14278 (clobber (reg:CC FLAGS_REG))]
14279 "TARGET_USE_FANCY_MATH_387
14280 && flag_unsafe_math_optimizations
14281 && can_create_pseudo_p ()"
14282 "#"
14283 "&& 1"
14284 [(const_int 0)]
14285 {
14286 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14287
14288 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14289 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14290
14291 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14292 operands[2], operands[3]));
14293 DONE;
14294 }
14295 [(set_attr "type" "frndint")
14296 (set_attr "i387_cw" "floor")
14297 (set_attr "mode" "XF")])
14298
14299 (define_insn "frndintxf2_floor_i387"
14300 [(set (match_operand:XF 0 "register_operand" "=f")
14301 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14302 UNSPEC_FRNDINT_FLOOR))
14303 (use (match_operand:HI 2 "memory_operand" "m"))
14304 (use (match_operand:HI 3 "memory_operand" "m"))]
14305 "TARGET_USE_FANCY_MATH_387
14306 && flag_unsafe_math_optimizations"
14307 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14308 [(set_attr "type" "frndint")
14309 (set_attr "i387_cw" "floor")
14310 (set_attr "mode" "XF")])
14311
14312 (define_expand "floorxf2"
14313 [(use (match_operand:XF 0 "register_operand" ""))
14314 (use (match_operand:XF 1 "register_operand" ""))]
14315 "TARGET_USE_FANCY_MATH_387
14316 && flag_unsafe_math_optimizations"
14317 {
14318 if (optimize_insn_for_size_p ())
14319 FAIL;
14320 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14321 DONE;
14322 })
14323
14324 (define_expand "floor<mode>2"
14325 [(use (match_operand:MODEF 0 "register_operand" ""))
14326 (use (match_operand:MODEF 1 "register_operand" ""))]
14327 "(TARGET_USE_FANCY_MATH_387
14328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14329 || TARGET_MIX_SSE_I387)
14330 && flag_unsafe_math_optimizations)
14331 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14332 && !flag_trapping_math)"
14333 {
14334 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14335 && !flag_trapping_math
14336 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14337 {
14338 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14339 FAIL;
14340 if (TARGET_ROUND)
14341 emit_insn (gen_sse4_1_round<mode>2
14342 (operands[0], operands[1], GEN_INT (0x01)));
14343 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14344 ix86_expand_floorceil (operand0, operand1, true);
14345 else
14346 ix86_expand_floorceildf_32 (operand0, operand1, true);
14347 }
14348 else
14349 {
14350 rtx op0, op1;
14351
14352 if (optimize_insn_for_size_p ())
14353 FAIL;
14354
14355 op0 = gen_reg_rtx (XFmode);
14356 op1 = gen_reg_rtx (XFmode);
14357 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14358 emit_insn (gen_frndintxf2_floor (op0, op1));
14359
14360 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14361 }
14362 DONE;
14363 })
14364
14365 (define_insn_and_split "*fist<mode>2_floor_1"
14366 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14367 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14368 UNSPEC_FIST_FLOOR))
14369 (clobber (reg:CC FLAGS_REG))]
14370 "TARGET_USE_FANCY_MATH_387
14371 && flag_unsafe_math_optimizations
14372 && can_create_pseudo_p ()"
14373 "#"
14374 "&& 1"
14375 [(const_int 0)]
14376 {
14377 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14378
14379 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14380 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14381 if (memory_operand (operands[0], VOIDmode))
14382 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14383 operands[2], operands[3]));
14384 else
14385 {
14386 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14387 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14388 operands[2], operands[3],
14389 operands[4]));
14390 }
14391 DONE;
14392 }
14393 [(set_attr "type" "fistp")
14394 (set_attr "i387_cw" "floor")
14395 (set_attr "mode" "<MODE>")])
14396
14397 (define_insn "fistdi2_floor"
14398 [(set (match_operand:DI 0 "memory_operand" "=m")
14399 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14400 UNSPEC_FIST_FLOOR))
14401 (use (match_operand:HI 2 "memory_operand" "m"))
14402 (use (match_operand:HI 3 "memory_operand" "m"))
14403 (clobber (match_scratch:XF 4 "=&1f"))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && flag_unsafe_math_optimizations"
14406 "* return output_fix_trunc (insn, operands, 0);"
14407 [(set_attr "type" "fistp")
14408 (set_attr "i387_cw" "floor")
14409 (set_attr "mode" "DI")])
14410
14411 (define_insn "fistdi2_floor_with_temp"
14412 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14413 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14414 UNSPEC_FIST_FLOOR))
14415 (use (match_operand:HI 2 "memory_operand" "m,m"))
14416 (use (match_operand:HI 3 "memory_operand" "m,m"))
14417 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14418 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14419 "TARGET_USE_FANCY_MATH_387
14420 && flag_unsafe_math_optimizations"
14421 "#"
14422 [(set_attr "type" "fistp")
14423 (set_attr "i387_cw" "floor")
14424 (set_attr "mode" "DI")])
14425
14426 (define_split
14427 [(set (match_operand:DI 0 "register_operand" "")
14428 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14429 UNSPEC_FIST_FLOOR))
14430 (use (match_operand:HI 2 "memory_operand" ""))
14431 (use (match_operand:HI 3 "memory_operand" ""))
14432 (clobber (match_operand:DI 4 "memory_operand" ""))
14433 (clobber (match_scratch 5 ""))]
14434 "reload_completed"
14435 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14436 (use (match_dup 2))
14437 (use (match_dup 3))
14438 (clobber (match_dup 5))])
14439 (set (match_dup 0) (match_dup 4))])
14440
14441 (define_split
14442 [(set (match_operand:DI 0 "memory_operand" "")
14443 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14444 UNSPEC_FIST_FLOOR))
14445 (use (match_operand:HI 2 "memory_operand" ""))
14446 (use (match_operand:HI 3 "memory_operand" ""))
14447 (clobber (match_operand:DI 4 "memory_operand" ""))
14448 (clobber (match_scratch 5 ""))]
14449 "reload_completed"
14450 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14451 (use (match_dup 2))
14452 (use (match_dup 3))
14453 (clobber (match_dup 5))])])
14454
14455 (define_insn "fist<mode>2_floor"
14456 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14457 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14458 UNSPEC_FIST_FLOOR))
14459 (use (match_operand:HI 2 "memory_operand" "m"))
14460 (use (match_operand:HI 3 "memory_operand" "m"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && flag_unsafe_math_optimizations"
14463 "* return output_fix_trunc (insn, operands, 0);"
14464 [(set_attr "type" "fistp")
14465 (set_attr "i387_cw" "floor")
14466 (set_attr "mode" "<MODE>")])
14467
14468 (define_insn "fist<mode>2_floor_with_temp"
14469 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14470 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14471 UNSPEC_FIST_FLOOR))
14472 (use (match_operand:HI 2 "memory_operand" "m,m"))
14473 (use (match_operand:HI 3 "memory_operand" "m,m"))
14474 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14475 "TARGET_USE_FANCY_MATH_387
14476 && flag_unsafe_math_optimizations"
14477 "#"
14478 [(set_attr "type" "fistp")
14479 (set_attr "i387_cw" "floor")
14480 (set_attr "mode" "<MODE>")])
14481
14482 (define_split
14483 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14484 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14485 UNSPEC_FIST_FLOOR))
14486 (use (match_operand:HI 2 "memory_operand" ""))
14487 (use (match_operand:HI 3 "memory_operand" ""))
14488 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14489 "reload_completed"
14490 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14491 UNSPEC_FIST_FLOOR))
14492 (use (match_dup 2))
14493 (use (match_dup 3))])
14494 (set (match_dup 0) (match_dup 4))])
14495
14496 (define_split
14497 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14498 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14499 UNSPEC_FIST_FLOOR))
14500 (use (match_operand:HI 2 "memory_operand" ""))
14501 (use (match_operand:HI 3 "memory_operand" ""))
14502 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14503 "reload_completed"
14504 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14505 UNSPEC_FIST_FLOOR))
14506 (use (match_dup 2))
14507 (use (match_dup 3))])])
14508
14509 (define_expand "lfloorxf<mode>2"
14510 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14511 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14512 UNSPEC_FIST_FLOOR))
14513 (clobber (reg:CC FLAGS_REG))])]
14514 "TARGET_USE_FANCY_MATH_387
14515 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14516 && flag_unsafe_math_optimizations")
14517
14518 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14519 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14520 (match_operand:MODEF 1 "register_operand" "")]
14521 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14522 && !flag_trapping_math"
14523 {
14524 if (TARGET_64BIT && optimize_insn_for_size_p ())
14525 FAIL;
14526 ix86_expand_lfloorceil (operand0, operand1, true);
14527 DONE;
14528 })
14529
14530 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14531 (define_insn_and_split "frndintxf2_ceil"
14532 [(set (match_operand:XF 0 "register_operand" "")
14533 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14534 UNSPEC_FRNDINT_CEIL))
14535 (clobber (reg:CC FLAGS_REG))]
14536 "TARGET_USE_FANCY_MATH_387
14537 && flag_unsafe_math_optimizations
14538 && can_create_pseudo_p ()"
14539 "#"
14540 "&& 1"
14541 [(const_int 0)]
14542 {
14543 ix86_optimize_mode_switching[I387_CEIL] = 1;
14544
14545 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14546 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14547
14548 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14549 operands[2], operands[3]));
14550 DONE;
14551 }
14552 [(set_attr "type" "frndint")
14553 (set_attr "i387_cw" "ceil")
14554 (set_attr "mode" "XF")])
14555
14556 (define_insn "frndintxf2_ceil_i387"
14557 [(set (match_operand:XF 0 "register_operand" "=f")
14558 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14559 UNSPEC_FRNDINT_CEIL))
14560 (use (match_operand:HI 2 "memory_operand" "m"))
14561 (use (match_operand:HI 3 "memory_operand" "m"))]
14562 "TARGET_USE_FANCY_MATH_387
14563 && flag_unsafe_math_optimizations"
14564 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14565 [(set_attr "type" "frndint")
14566 (set_attr "i387_cw" "ceil")
14567 (set_attr "mode" "XF")])
14568
14569 (define_expand "ceilxf2"
14570 [(use (match_operand:XF 0 "register_operand" ""))
14571 (use (match_operand:XF 1 "register_operand" ""))]
14572 "TARGET_USE_FANCY_MATH_387
14573 && flag_unsafe_math_optimizations"
14574 {
14575 if (optimize_insn_for_size_p ())
14576 FAIL;
14577 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14578 DONE;
14579 })
14580
14581 (define_expand "ceil<mode>2"
14582 [(use (match_operand:MODEF 0 "register_operand" ""))
14583 (use (match_operand:MODEF 1 "register_operand" ""))]
14584 "(TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
14587 && flag_unsafe_math_optimizations)
14588 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589 && !flag_trapping_math)"
14590 {
14591 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14592 && !flag_trapping_math
14593 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14594 {
14595 if (TARGET_ROUND)
14596 emit_insn (gen_sse4_1_round<mode>2
14597 (operands[0], operands[1], GEN_INT (0x02)));
14598 else if (optimize_insn_for_size_p ())
14599 FAIL;
14600 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14601 ix86_expand_floorceil (operand0, operand1, false);
14602 else
14603 ix86_expand_floorceildf_32 (operand0, operand1, false);
14604 }
14605 else
14606 {
14607 rtx op0, op1;
14608
14609 if (optimize_insn_for_size_p ())
14610 FAIL;
14611
14612 op0 = gen_reg_rtx (XFmode);
14613 op1 = gen_reg_rtx (XFmode);
14614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14615 emit_insn (gen_frndintxf2_ceil (op0, op1));
14616
14617 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14618 }
14619 DONE;
14620 })
14621
14622 (define_insn_and_split "*fist<mode>2_ceil_1"
14623 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14624 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14625 UNSPEC_FIST_CEIL))
14626 (clobber (reg:CC FLAGS_REG))]
14627 "TARGET_USE_FANCY_MATH_387
14628 && flag_unsafe_math_optimizations
14629 && can_create_pseudo_p ()"
14630 "#"
14631 "&& 1"
14632 [(const_int 0)]
14633 {
14634 ix86_optimize_mode_switching[I387_CEIL] = 1;
14635
14636 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14638 if (memory_operand (operands[0], VOIDmode))
14639 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14640 operands[2], operands[3]));
14641 else
14642 {
14643 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14644 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14645 operands[2], operands[3],
14646 operands[4]));
14647 }
14648 DONE;
14649 }
14650 [(set_attr "type" "fistp")
14651 (set_attr "i387_cw" "ceil")
14652 (set_attr "mode" "<MODE>")])
14653
14654 (define_insn "fistdi2_ceil"
14655 [(set (match_operand:DI 0 "memory_operand" "=m")
14656 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14657 UNSPEC_FIST_CEIL))
14658 (use (match_operand:HI 2 "memory_operand" "m"))
14659 (use (match_operand:HI 3 "memory_operand" "m"))
14660 (clobber (match_scratch:XF 4 "=&1f"))]
14661 "TARGET_USE_FANCY_MATH_387
14662 && flag_unsafe_math_optimizations"
14663 "* return output_fix_trunc (insn, operands, 0);"
14664 [(set_attr "type" "fistp")
14665 (set_attr "i387_cw" "ceil")
14666 (set_attr "mode" "DI")])
14667
14668 (define_insn "fistdi2_ceil_with_temp"
14669 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14670 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14671 UNSPEC_FIST_CEIL))
14672 (use (match_operand:HI 2 "memory_operand" "m,m"))
14673 (use (match_operand:HI 3 "memory_operand" "m,m"))
14674 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14675 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14676 "TARGET_USE_FANCY_MATH_387
14677 && flag_unsafe_math_optimizations"
14678 "#"
14679 [(set_attr "type" "fistp")
14680 (set_attr "i387_cw" "ceil")
14681 (set_attr "mode" "DI")])
14682
14683 (define_split
14684 [(set (match_operand:DI 0 "register_operand" "")
14685 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14686 UNSPEC_FIST_CEIL))
14687 (use (match_operand:HI 2 "memory_operand" ""))
14688 (use (match_operand:HI 3 "memory_operand" ""))
14689 (clobber (match_operand:DI 4 "memory_operand" ""))
14690 (clobber (match_scratch 5 ""))]
14691 "reload_completed"
14692 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14693 (use (match_dup 2))
14694 (use (match_dup 3))
14695 (clobber (match_dup 5))])
14696 (set (match_dup 0) (match_dup 4))])
14697
14698 (define_split
14699 [(set (match_operand:DI 0 "memory_operand" "")
14700 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14701 UNSPEC_FIST_CEIL))
14702 (use (match_operand:HI 2 "memory_operand" ""))
14703 (use (match_operand:HI 3 "memory_operand" ""))
14704 (clobber (match_operand:DI 4 "memory_operand" ""))
14705 (clobber (match_scratch 5 ""))]
14706 "reload_completed"
14707 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14708 (use (match_dup 2))
14709 (use (match_dup 3))
14710 (clobber (match_dup 5))])])
14711
14712 (define_insn "fist<mode>2_ceil"
14713 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14714 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14715 UNSPEC_FIST_CEIL))
14716 (use (match_operand:HI 2 "memory_operand" "m"))
14717 (use (match_operand:HI 3 "memory_operand" "m"))]
14718 "TARGET_USE_FANCY_MATH_387
14719 && flag_unsafe_math_optimizations"
14720 "* return output_fix_trunc (insn, operands, 0);"
14721 [(set_attr "type" "fistp")
14722 (set_attr "i387_cw" "ceil")
14723 (set_attr "mode" "<MODE>")])
14724
14725 (define_insn "fist<mode>2_ceil_with_temp"
14726 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14727 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14728 UNSPEC_FIST_CEIL))
14729 (use (match_operand:HI 2 "memory_operand" "m,m"))
14730 (use (match_operand:HI 3 "memory_operand" "m,m"))
14731 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14732 "TARGET_USE_FANCY_MATH_387
14733 && flag_unsafe_math_optimizations"
14734 "#"
14735 [(set_attr "type" "fistp")
14736 (set_attr "i387_cw" "ceil")
14737 (set_attr "mode" "<MODE>")])
14738
14739 (define_split
14740 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14741 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14742 UNSPEC_FIST_CEIL))
14743 (use (match_operand:HI 2 "memory_operand" ""))
14744 (use (match_operand:HI 3 "memory_operand" ""))
14745 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14746 "reload_completed"
14747 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14748 UNSPEC_FIST_CEIL))
14749 (use (match_dup 2))
14750 (use (match_dup 3))])
14751 (set (match_dup 0) (match_dup 4))])
14752
14753 (define_split
14754 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14755 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14756 UNSPEC_FIST_CEIL))
14757 (use (match_operand:HI 2 "memory_operand" ""))
14758 (use (match_operand:HI 3 "memory_operand" ""))
14759 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14760 "reload_completed"
14761 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14762 UNSPEC_FIST_CEIL))
14763 (use (match_dup 2))
14764 (use (match_dup 3))])])
14765
14766 (define_expand "lceilxf<mode>2"
14767 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14768 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14769 UNSPEC_FIST_CEIL))
14770 (clobber (reg:CC FLAGS_REG))])]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14773 && flag_unsafe_math_optimizations")
14774
14775 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14776 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14777 (match_operand:MODEF 1 "register_operand" "")]
14778 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14779 && !flag_trapping_math"
14780 {
14781 ix86_expand_lfloorceil (operand0, operand1, false);
14782 DONE;
14783 })
14784
14785 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14786 (define_insn_and_split "frndintxf2_trunc"
14787 [(set (match_operand:XF 0 "register_operand" "")
14788 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14789 UNSPEC_FRNDINT_TRUNC))
14790 (clobber (reg:CC FLAGS_REG))]
14791 "TARGET_USE_FANCY_MATH_387
14792 && flag_unsafe_math_optimizations
14793 && can_create_pseudo_p ()"
14794 "#"
14795 "&& 1"
14796 [(const_int 0)]
14797 {
14798 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14799
14800 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14801 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14802
14803 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14804 operands[2], operands[3]));
14805 DONE;
14806 }
14807 [(set_attr "type" "frndint")
14808 (set_attr "i387_cw" "trunc")
14809 (set_attr "mode" "XF")])
14810
14811 (define_insn "frndintxf2_trunc_i387"
14812 [(set (match_operand:XF 0 "register_operand" "=f")
14813 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14814 UNSPEC_FRNDINT_TRUNC))
14815 (use (match_operand:HI 2 "memory_operand" "m"))
14816 (use (match_operand:HI 3 "memory_operand" "m"))]
14817 "TARGET_USE_FANCY_MATH_387
14818 && flag_unsafe_math_optimizations"
14819 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14820 [(set_attr "type" "frndint")
14821 (set_attr "i387_cw" "trunc")
14822 (set_attr "mode" "XF")])
14823
14824 (define_expand "btruncxf2"
14825 [(use (match_operand:XF 0 "register_operand" ""))
14826 (use (match_operand:XF 1 "register_operand" ""))]
14827 "TARGET_USE_FANCY_MATH_387
14828 && flag_unsafe_math_optimizations"
14829 {
14830 if (optimize_insn_for_size_p ())
14831 FAIL;
14832 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14833 DONE;
14834 })
14835
14836 (define_expand "btrunc<mode>2"
14837 [(use (match_operand:MODEF 0 "register_operand" ""))
14838 (use (match_operand:MODEF 1 "register_operand" ""))]
14839 "(TARGET_USE_FANCY_MATH_387
14840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14841 || TARGET_MIX_SSE_I387)
14842 && flag_unsafe_math_optimizations)
14843 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844 && !flag_trapping_math)"
14845 {
14846 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14847 && !flag_trapping_math
14848 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14849 {
14850 if (TARGET_ROUND)
14851 emit_insn (gen_sse4_1_round<mode>2
14852 (operands[0], operands[1], GEN_INT (0x03)));
14853 else if (optimize_insn_for_size_p ())
14854 FAIL;
14855 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14856 ix86_expand_trunc (operand0, operand1);
14857 else
14858 ix86_expand_truncdf_32 (operand0, operand1);
14859 }
14860 else
14861 {
14862 rtx op0, op1;
14863
14864 if (optimize_insn_for_size_p ())
14865 FAIL;
14866
14867 op0 = gen_reg_rtx (XFmode);
14868 op1 = gen_reg_rtx (XFmode);
14869 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14870 emit_insn (gen_frndintxf2_trunc (op0, op1));
14871
14872 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14873 }
14874 DONE;
14875 })
14876
14877 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14878 (define_insn_and_split "frndintxf2_mask_pm"
14879 [(set (match_operand:XF 0 "register_operand" "")
14880 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14881 UNSPEC_FRNDINT_MASK_PM))
14882 (clobber (reg:CC FLAGS_REG))]
14883 "TARGET_USE_FANCY_MATH_387
14884 && flag_unsafe_math_optimizations
14885 && can_create_pseudo_p ()"
14886 "#"
14887 "&& 1"
14888 [(const_int 0)]
14889 {
14890 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14891
14892 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14893 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14894
14895 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14896 operands[2], operands[3]));
14897 DONE;
14898 }
14899 [(set_attr "type" "frndint")
14900 (set_attr "i387_cw" "mask_pm")
14901 (set_attr "mode" "XF")])
14902
14903 (define_insn "frndintxf2_mask_pm_i387"
14904 [(set (match_operand:XF 0 "register_operand" "=f")
14905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14906 UNSPEC_FRNDINT_MASK_PM))
14907 (use (match_operand:HI 2 "memory_operand" "m"))
14908 (use (match_operand:HI 3 "memory_operand" "m"))]
14909 "TARGET_USE_FANCY_MATH_387
14910 && flag_unsafe_math_optimizations"
14911 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14912 [(set_attr "type" "frndint")
14913 (set_attr "i387_cw" "mask_pm")
14914 (set_attr "mode" "XF")])
14915
14916 (define_expand "nearbyintxf2"
14917 [(use (match_operand:XF 0 "register_operand" ""))
14918 (use (match_operand:XF 1 "register_operand" ""))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations"
14921 {
14922 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14923 DONE;
14924 })
14925
14926 (define_expand "nearbyint<mode>2"
14927 [(use (match_operand:MODEF 0 "register_operand" ""))
14928 (use (match_operand:MODEF 1 "register_operand" ""))]
14929 "TARGET_USE_FANCY_MATH_387
14930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14931 || TARGET_MIX_SSE_I387)
14932 && flag_unsafe_math_optimizations"
14933 {
14934 rtx op0 = gen_reg_rtx (XFmode);
14935 rtx op1 = gen_reg_rtx (XFmode);
14936
14937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14938 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14939
14940 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14941 DONE;
14942 })
14943
14944 (define_insn "fxam<mode>2_i387"
14945 [(set (match_operand:HI 0 "register_operand" "=a")
14946 (unspec:HI
14947 [(match_operand:X87MODEF 1 "register_operand" "f")]
14948 UNSPEC_FXAM))]
14949 "TARGET_USE_FANCY_MATH_387"
14950 "fxam\n\tfnstsw\t%0"
14951 [(set_attr "type" "multi")
14952 (set_attr "length" "4")
14953 (set_attr "unit" "i387")
14954 (set_attr "mode" "<MODE>")])
14955
14956 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14957 [(set (match_operand:HI 0 "register_operand" "")
14958 (unspec:HI
14959 [(match_operand:MODEF 1 "memory_operand" "")]
14960 UNSPEC_FXAM_MEM))]
14961 "TARGET_USE_FANCY_MATH_387
14962 && can_create_pseudo_p ()"
14963 "#"
14964 "&& 1"
14965 [(set (match_dup 2)(match_dup 1))
14966 (set (match_dup 0)
14967 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14968 {
14969 operands[2] = gen_reg_rtx (<MODE>mode);
14970
14971 MEM_VOLATILE_P (operands[1]) = 1;
14972 }
14973 [(set_attr "type" "multi")
14974 (set_attr "unit" "i387")
14975 (set_attr "mode" "<MODE>")])
14976
14977 (define_expand "isinfxf2"
14978 [(use (match_operand:SI 0 "register_operand" ""))
14979 (use (match_operand:XF 1 "register_operand" ""))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && TARGET_C99_FUNCTIONS"
14982 {
14983 rtx mask = GEN_INT (0x45);
14984 rtx val = GEN_INT (0x05);
14985
14986 rtx cond;
14987
14988 rtx scratch = gen_reg_rtx (HImode);
14989 rtx res = gen_reg_rtx (QImode);
14990
14991 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14992
14993 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14994 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14995 cond = gen_rtx_fmt_ee (EQ, QImode,
14996 gen_rtx_REG (CCmode, FLAGS_REG),
14997 const0_rtx);
14998 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14999 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15000 DONE;
15001 })
15002
15003 (define_expand "isinf<mode>2"
15004 [(use (match_operand:SI 0 "register_operand" ""))
15005 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15006 "TARGET_USE_FANCY_MATH_387
15007 && TARGET_C99_FUNCTIONS
15008 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15009 {
15010 rtx mask = GEN_INT (0x45);
15011 rtx val = GEN_INT (0x05);
15012
15013 rtx cond;
15014
15015 rtx scratch = gen_reg_rtx (HImode);
15016 rtx res = gen_reg_rtx (QImode);
15017
15018 /* Remove excess precision by forcing value through memory. */
15019 if (memory_operand (operands[1], VOIDmode))
15020 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15021 else
15022 {
15023 enum ix86_stack_slot slot = (virtuals_instantiated
15024 ? SLOT_TEMP
15025 : SLOT_VIRTUAL);
15026 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15027
15028 emit_move_insn (temp, operands[1]);
15029 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15030 }
15031
15032 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15033 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15034 cond = gen_rtx_fmt_ee (EQ, QImode,
15035 gen_rtx_REG (CCmode, FLAGS_REG),
15036 const0_rtx);
15037 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15038 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15039 DONE;
15040 })
15041
15042 (define_expand "signbitxf2"
15043 [(use (match_operand:SI 0 "register_operand" ""))
15044 (use (match_operand:XF 1 "register_operand" ""))]
15045 "TARGET_USE_FANCY_MATH_387"
15046 {
15047 rtx scratch = gen_reg_rtx (HImode);
15048
15049 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15050 emit_insn (gen_andsi3 (operands[0],
15051 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15052 DONE;
15053 })
15054
15055 (define_insn "movmsk_df"
15056 [(set (match_operand:SI 0 "register_operand" "=r")
15057 (unspec:SI
15058 [(match_operand:DF 1 "register_operand" "x")]
15059 UNSPEC_MOVMSK))]
15060 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15061 "%vmovmskpd\t{%1, %0|%0, %1}"
15062 [(set_attr "type" "ssemov")
15063 (set_attr "prefix" "maybe_vex")
15064 (set_attr "mode" "DF")])
15065
15066 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15067 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15068 (define_expand "signbitdf2"
15069 [(use (match_operand:SI 0 "register_operand" ""))
15070 (use (match_operand:DF 1 "register_operand" ""))]
15071 "TARGET_USE_FANCY_MATH_387
15072 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15073 {
15074 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15075 {
15076 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15077 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15078 }
15079 else
15080 {
15081 rtx scratch = gen_reg_rtx (HImode);
15082
15083 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15084 emit_insn (gen_andsi3 (operands[0],
15085 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15086 }
15087 DONE;
15088 })
15089
15090 (define_expand "signbitsf2"
15091 [(use (match_operand:SI 0 "register_operand" ""))
15092 (use (match_operand:SF 1 "register_operand" ""))]
15093 "TARGET_USE_FANCY_MATH_387
15094 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15095 {
15096 rtx scratch = gen_reg_rtx (HImode);
15097
15098 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15099 emit_insn (gen_andsi3 (operands[0],
15100 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15101 DONE;
15102 })
15103 \f
15104 ;; Block operation instructions
15105
15106 (define_insn "cld"
15107 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15108 ""
15109 "cld"
15110 [(set_attr "length" "1")
15111 (set_attr "length_immediate" "0")
15112 (set_attr "modrm" "0")])
15113
15114 (define_expand "movmemsi"
15115 [(use (match_operand:BLK 0 "memory_operand" ""))
15116 (use (match_operand:BLK 1 "memory_operand" ""))
15117 (use (match_operand:SI 2 "nonmemory_operand" ""))
15118 (use (match_operand:SI 3 "const_int_operand" ""))
15119 (use (match_operand:SI 4 "const_int_operand" ""))
15120 (use (match_operand:SI 5 "const_int_operand" ""))]
15121 ""
15122 {
15123 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15124 operands[4], operands[5]))
15125 DONE;
15126 else
15127 FAIL;
15128 })
15129
15130 (define_expand "movmemdi"
15131 [(use (match_operand:BLK 0 "memory_operand" ""))
15132 (use (match_operand:BLK 1 "memory_operand" ""))
15133 (use (match_operand:DI 2 "nonmemory_operand" ""))
15134 (use (match_operand:DI 3 "const_int_operand" ""))
15135 (use (match_operand:SI 4 "const_int_operand" ""))
15136 (use (match_operand:SI 5 "const_int_operand" ""))]
15137 "TARGET_64BIT"
15138 {
15139 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15140 operands[4], operands[5]))
15141 DONE;
15142 else
15143 FAIL;
15144 })
15145
15146 ;; Most CPUs don't like single string operations
15147 ;; Handle this case here to simplify previous expander.
15148
15149 (define_expand "strmov"
15150 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15151 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15152 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15153 (clobber (reg:CC FLAGS_REG))])
15154 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15155 (clobber (reg:CC FLAGS_REG))])]
15156 ""
15157 {
15158 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15159
15160 /* If .md ever supports :P for Pmode, these can be directly
15161 in the pattern above. */
15162 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15163 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15164
15165 /* Can't use this if the user has appropriated esi or edi. */
15166 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15167 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15168 {
15169 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15170 operands[2], operands[3],
15171 operands[5], operands[6]));
15172 DONE;
15173 }
15174
15175 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15176 })
15177
15178 (define_expand "strmov_singleop"
15179 [(parallel [(set (match_operand 1 "memory_operand" "")
15180 (match_operand 3 "memory_operand" ""))
15181 (set (match_operand 0 "register_operand" "")
15182 (match_operand 4 "" ""))
15183 (set (match_operand 2 "register_operand" "")
15184 (match_operand 5 "" ""))])]
15185 ""
15186 "ix86_current_function_needs_cld = 1;")
15187
15188 (define_insn "*strmovdi_rex_1"
15189 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15190 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15191 (set (match_operand:DI 0 "register_operand" "=D")
15192 (plus:DI (match_dup 2)
15193 (const_int 8)))
15194 (set (match_operand:DI 1 "register_operand" "=S")
15195 (plus:DI (match_dup 3)
15196 (const_int 8)))]
15197 "TARGET_64BIT"
15198 "movsq"
15199 [(set_attr "type" "str")
15200 (set_attr "mode" "DI")
15201 (set_attr "memory" "both")])
15202
15203 (define_insn "*strmovsi_1"
15204 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15205 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15206 (set (match_operand:SI 0 "register_operand" "=D")
15207 (plus:SI (match_dup 2)
15208 (const_int 4)))
15209 (set (match_operand:SI 1 "register_operand" "=S")
15210 (plus:SI (match_dup 3)
15211 (const_int 4)))]
15212 "!TARGET_64BIT"
15213 "movs{l|d}"
15214 [(set_attr "type" "str")
15215 (set_attr "mode" "SI")
15216 (set_attr "memory" "both")])
15217
15218 (define_insn "*strmovsi_rex_1"
15219 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15220 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15221 (set (match_operand:DI 0 "register_operand" "=D")
15222 (plus:DI (match_dup 2)
15223 (const_int 4)))
15224 (set (match_operand:DI 1 "register_operand" "=S")
15225 (plus:DI (match_dup 3)
15226 (const_int 4)))]
15227 "TARGET_64BIT"
15228 "movs{l|d}"
15229 [(set_attr "type" "str")
15230 (set_attr "mode" "SI")
15231 (set_attr "memory" "both")])
15232
15233 (define_insn "*strmovhi_1"
15234 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15235 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15236 (set (match_operand:SI 0 "register_operand" "=D")
15237 (plus:SI (match_dup 2)
15238 (const_int 2)))
15239 (set (match_operand:SI 1 "register_operand" "=S")
15240 (plus:SI (match_dup 3)
15241 (const_int 2)))]
15242 "!TARGET_64BIT"
15243 "movsw"
15244 [(set_attr "type" "str")
15245 (set_attr "memory" "both")
15246 (set_attr "mode" "HI")])
15247
15248 (define_insn "*strmovhi_rex_1"
15249 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15250 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15251 (set (match_operand:DI 0 "register_operand" "=D")
15252 (plus:DI (match_dup 2)
15253 (const_int 2)))
15254 (set (match_operand:DI 1 "register_operand" "=S")
15255 (plus:DI (match_dup 3)
15256 (const_int 2)))]
15257 "TARGET_64BIT"
15258 "movsw"
15259 [(set_attr "type" "str")
15260 (set_attr "memory" "both")
15261 (set_attr "mode" "HI")])
15262
15263 (define_insn "*strmovqi_1"
15264 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15265 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15266 (set (match_operand:SI 0 "register_operand" "=D")
15267 (plus:SI (match_dup 2)
15268 (const_int 1)))
15269 (set (match_operand:SI 1 "register_operand" "=S")
15270 (plus:SI (match_dup 3)
15271 (const_int 1)))]
15272 "!TARGET_64BIT"
15273 "movsb"
15274 [(set_attr "type" "str")
15275 (set_attr "memory" "both")
15276 (set_attr "mode" "QI")])
15277
15278 (define_insn "*strmovqi_rex_1"
15279 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15280 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15281 (set (match_operand:DI 0 "register_operand" "=D")
15282 (plus:DI (match_dup 2)
15283 (const_int 1)))
15284 (set (match_operand:DI 1 "register_operand" "=S")
15285 (plus:DI (match_dup 3)
15286 (const_int 1)))]
15287 "TARGET_64BIT"
15288 "movsb"
15289 [(set_attr "type" "str")
15290 (set_attr "memory" "both")
15291 (set_attr "prefix_rex" "0")
15292 (set_attr "mode" "QI")])
15293
15294 (define_expand "rep_mov"
15295 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15296 (set (match_operand 0 "register_operand" "")
15297 (match_operand 5 "" ""))
15298 (set (match_operand 2 "register_operand" "")
15299 (match_operand 6 "" ""))
15300 (set (match_operand 1 "memory_operand" "")
15301 (match_operand 3 "memory_operand" ""))
15302 (use (match_dup 4))])]
15303 ""
15304 "ix86_current_function_needs_cld = 1;")
15305
15306 (define_insn "*rep_movdi_rex64"
15307 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15308 (set (match_operand:DI 0 "register_operand" "=D")
15309 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15310 (const_int 3))
15311 (match_operand:DI 3 "register_operand" "0")))
15312 (set (match_operand:DI 1 "register_operand" "=S")
15313 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15314 (match_operand:DI 4 "register_operand" "1")))
15315 (set (mem:BLK (match_dup 3))
15316 (mem:BLK (match_dup 4)))
15317 (use (match_dup 5))]
15318 "TARGET_64BIT"
15319 "rep{%;} movsq"
15320 [(set_attr "type" "str")
15321 (set_attr "prefix_rep" "1")
15322 (set_attr "memory" "both")
15323 (set_attr "mode" "DI")])
15324
15325 (define_insn "*rep_movsi"
15326 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15327 (set (match_operand:SI 0 "register_operand" "=D")
15328 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15329 (const_int 2))
15330 (match_operand:SI 3 "register_operand" "0")))
15331 (set (match_operand:SI 1 "register_operand" "=S")
15332 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15333 (match_operand:SI 4 "register_operand" "1")))
15334 (set (mem:BLK (match_dup 3))
15335 (mem:BLK (match_dup 4)))
15336 (use (match_dup 5))]
15337 "!TARGET_64BIT"
15338 "rep{%;} movs{l|d}"
15339 [(set_attr "type" "str")
15340 (set_attr "prefix_rep" "1")
15341 (set_attr "memory" "both")
15342 (set_attr "mode" "SI")])
15343
15344 (define_insn "*rep_movsi_rex64"
15345 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15346 (set (match_operand:DI 0 "register_operand" "=D")
15347 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15348 (const_int 2))
15349 (match_operand:DI 3 "register_operand" "0")))
15350 (set (match_operand:DI 1 "register_operand" "=S")
15351 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15352 (match_operand:DI 4 "register_operand" "1")))
15353 (set (mem:BLK (match_dup 3))
15354 (mem:BLK (match_dup 4)))
15355 (use (match_dup 5))]
15356 "TARGET_64BIT"
15357 "rep{%;} movs{l|d}"
15358 [(set_attr "type" "str")
15359 (set_attr "prefix_rep" "1")
15360 (set_attr "memory" "both")
15361 (set_attr "mode" "SI")])
15362
15363 (define_insn "*rep_movqi"
15364 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15365 (set (match_operand:SI 0 "register_operand" "=D")
15366 (plus:SI (match_operand:SI 3 "register_operand" "0")
15367 (match_operand:SI 5 "register_operand" "2")))
15368 (set (match_operand:SI 1 "register_operand" "=S")
15369 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15370 (set (mem:BLK (match_dup 3))
15371 (mem:BLK (match_dup 4)))
15372 (use (match_dup 5))]
15373 "!TARGET_64BIT"
15374 "rep{%;} movsb"
15375 [(set_attr "type" "str")
15376 (set_attr "prefix_rep" "1")
15377 (set_attr "memory" "both")
15378 (set_attr "mode" "SI")])
15379
15380 (define_insn "*rep_movqi_rex64"
15381 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15382 (set (match_operand:DI 0 "register_operand" "=D")
15383 (plus:DI (match_operand:DI 3 "register_operand" "0")
15384 (match_operand:DI 5 "register_operand" "2")))
15385 (set (match_operand:DI 1 "register_operand" "=S")
15386 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15387 (set (mem:BLK (match_dup 3))
15388 (mem:BLK (match_dup 4)))
15389 (use (match_dup 5))]
15390 "TARGET_64BIT"
15391 "rep{%;} movsb"
15392 [(set_attr "type" "str")
15393 (set_attr "prefix_rep" "1")
15394 (set_attr "memory" "both")
15395 (set_attr "mode" "SI")])
15396
15397 (define_expand "setmemsi"
15398 [(use (match_operand:BLK 0 "memory_operand" ""))
15399 (use (match_operand:SI 1 "nonmemory_operand" ""))
15400 (use (match_operand 2 "const_int_operand" ""))
15401 (use (match_operand 3 "const_int_operand" ""))
15402 (use (match_operand:SI 4 "const_int_operand" ""))
15403 (use (match_operand:SI 5 "const_int_operand" ""))]
15404 ""
15405 {
15406 if (ix86_expand_setmem (operands[0], operands[1],
15407 operands[2], operands[3],
15408 operands[4], operands[5]))
15409 DONE;
15410 else
15411 FAIL;
15412 })
15413
15414 (define_expand "setmemdi"
15415 [(use (match_operand:BLK 0 "memory_operand" ""))
15416 (use (match_operand:DI 1 "nonmemory_operand" ""))
15417 (use (match_operand 2 "const_int_operand" ""))
15418 (use (match_operand 3 "const_int_operand" ""))
15419 (use (match_operand 4 "const_int_operand" ""))
15420 (use (match_operand 5 "const_int_operand" ""))]
15421 "TARGET_64BIT"
15422 {
15423 if (ix86_expand_setmem (operands[0], operands[1],
15424 operands[2], operands[3],
15425 operands[4], operands[5]))
15426 DONE;
15427 else
15428 FAIL;
15429 })
15430
15431 ;; Most CPUs don't like single string operations
15432 ;; Handle this case here to simplify previous expander.
15433
15434 (define_expand "strset"
15435 [(set (match_operand 1 "memory_operand" "")
15436 (match_operand 2 "register_operand" ""))
15437 (parallel [(set (match_operand 0 "register_operand" "")
15438 (match_dup 3))
15439 (clobber (reg:CC FLAGS_REG))])]
15440 ""
15441 {
15442 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15443 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15444
15445 /* If .md ever supports :P for Pmode, this can be directly
15446 in the pattern above. */
15447 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15448 GEN_INT (GET_MODE_SIZE (GET_MODE
15449 (operands[2]))));
15450 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15451 {
15452 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15453 operands[3]));
15454 DONE;
15455 }
15456 })
15457
15458 (define_expand "strset_singleop"
15459 [(parallel [(set (match_operand 1 "memory_operand" "")
15460 (match_operand 2 "register_operand" ""))
15461 (set (match_operand 0 "register_operand" "")
15462 (match_operand 3 "" ""))])]
15463 ""
15464 "ix86_current_function_needs_cld = 1;")
15465
15466 (define_insn "*strsetdi_rex_1"
15467 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15468 (match_operand:DI 2 "register_operand" "a"))
15469 (set (match_operand:DI 0 "register_operand" "=D")
15470 (plus:DI (match_dup 1)
15471 (const_int 8)))]
15472 "TARGET_64BIT"
15473 "stosq"
15474 [(set_attr "type" "str")
15475 (set_attr "memory" "store")
15476 (set_attr "mode" "DI")])
15477
15478 (define_insn "*strsetsi_1"
15479 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15480 (match_operand:SI 2 "register_operand" "a"))
15481 (set (match_operand:SI 0 "register_operand" "=D")
15482 (plus:SI (match_dup 1)
15483 (const_int 4)))]
15484 "!TARGET_64BIT"
15485 "stos{l|d}"
15486 [(set_attr "type" "str")
15487 (set_attr "memory" "store")
15488 (set_attr "mode" "SI")])
15489
15490 (define_insn "*strsetsi_rex_1"
15491 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15492 (match_operand:SI 2 "register_operand" "a"))
15493 (set (match_operand:DI 0 "register_operand" "=D")
15494 (plus:DI (match_dup 1)
15495 (const_int 4)))]
15496 "TARGET_64BIT"
15497 "stos{l|d}"
15498 [(set_attr "type" "str")
15499 (set_attr "memory" "store")
15500 (set_attr "mode" "SI")])
15501
15502 (define_insn "*strsethi_1"
15503 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15504 (match_operand:HI 2 "register_operand" "a"))
15505 (set (match_operand:SI 0 "register_operand" "=D")
15506 (plus:SI (match_dup 1)
15507 (const_int 2)))]
15508 "!TARGET_64BIT"
15509 "stosw"
15510 [(set_attr "type" "str")
15511 (set_attr "memory" "store")
15512 (set_attr "mode" "HI")])
15513
15514 (define_insn "*strsethi_rex_1"
15515 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15516 (match_operand:HI 2 "register_operand" "a"))
15517 (set (match_operand:DI 0 "register_operand" "=D")
15518 (plus:DI (match_dup 1)
15519 (const_int 2)))]
15520 "TARGET_64BIT"
15521 "stosw"
15522 [(set_attr "type" "str")
15523 (set_attr "memory" "store")
15524 (set_attr "mode" "HI")])
15525
15526 (define_insn "*strsetqi_1"
15527 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15528 (match_operand:QI 2 "register_operand" "a"))
15529 (set (match_operand:SI 0 "register_operand" "=D")
15530 (plus:SI (match_dup 1)
15531 (const_int 1)))]
15532 "!TARGET_64BIT"
15533 "stosb"
15534 [(set_attr "type" "str")
15535 (set_attr "memory" "store")
15536 (set_attr "mode" "QI")])
15537
15538 (define_insn "*strsetqi_rex_1"
15539 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15540 (match_operand:QI 2 "register_operand" "a"))
15541 (set (match_operand:DI 0 "register_operand" "=D")
15542 (plus:DI (match_dup 1)
15543 (const_int 1)))]
15544 "TARGET_64BIT"
15545 "stosb"
15546 [(set_attr "type" "str")
15547 (set_attr "memory" "store")
15548 (set_attr "prefix_rex" "0")
15549 (set_attr "mode" "QI")])
15550
15551 (define_expand "rep_stos"
15552 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15553 (set (match_operand 0 "register_operand" "")
15554 (match_operand 4 "" ""))
15555 (set (match_operand 2 "memory_operand" "") (const_int 0))
15556 (use (match_operand 3 "register_operand" ""))
15557 (use (match_dup 1))])]
15558 ""
15559 "ix86_current_function_needs_cld = 1;")
15560
15561 (define_insn "*rep_stosdi_rex64"
15562 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15563 (set (match_operand:DI 0 "register_operand" "=D")
15564 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15565 (const_int 3))
15566 (match_operand:DI 3 "register_operand" "0")))
15567 (set (mem:BLK (match_dup 3))
15568 (const_int 0))
15569 (use (match_operand:DI 2 "register_operand" "a"))
15570 (use (match_dup 4))]
15571 "TARGET_64BIT"
15572 "rep{%;} stosq"
15573 [(set_attr "type" "str")
15574 (set_attr "prefix_rep" "1")
15575 (set_attr "memory" "store")
15576 (set_attr "mode" "DI")])
15577
15578 (define_insn "*rep_stossi"
15579 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15580 (set (match_operand:SI 0 "register_operand" "=D")
15581 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15582 (const_int 2))
15583 (match_operand:SI 3 "register_operand" "0")))
15584 (set (mem:BLK (match_dup 3))
15585 (const_int 0))
15586 (use (match_operand:SI 2 "register_operand" "a"))
15587 (use (match_dup 4))]
15588 "!TARGET_64BIT"
15589 "rep{%;} stos{l|d}"
15590 [(set_attr "type" "str")
15591 (set_attr "prefix_rep" "1")
15592 (set_attr "memory" "store")
15593 (set_attr "mode" "SI")])
15594
15595 (define_insn "*rep_stossi_rex64"
15596 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15597 (set (match_operand:DI 0 "register_operand" "=D")
15598 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15599 (const_int 2))
15600 (match_operand:DI 3 "register_operand" "0")))
15601 (set (mem:BLK (match_dup 3))
15602 (const_int 0))
15603 (use (match_operand:SI 2 "register_operand" "a"))
15604 (use (match_dup 4))]
15605 "TARGET_64BIT"
15606 "rep{%;} stos{l|d}"
15607 [(set_attr "type" "str")
15608 (set_attr "prefix_rep" "1")
15609 (set_attr "memory" "store")
15610 (set_attr "mode" "SI")])
15611
15612 (define_insn "*rep_stosqi"
15613 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15614 (set (match_operand:SI 0 "register_operand" "=D")
15615 (plus:SI (match_operand:SI 3 "register_operand" "0")
15616 (match_operand:SI 4 "register_operand" "1")))
15617 (set (mem:BLK (match_dup 3))
15618 (const_int 0))
15619 (use (match_operand:QI 2 "register_operand" "a"))
15620 (use (match_dup 4))]
15621 "!TARGET_64BIT"
15622 "rep{%;} stosb"
15623 [(set_attr "type" "str")
15624 (set_attr "prefix_rep" "1")
15625 (set_attr "memory" "store")
15626 (set_attr "mode" "QI")])
15627
15628 (define_insn "*rep_stosqi_rex64"
15629 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15630 (set (match_operand:DI 0 "register_operand" "=D")
15631 (plus:DI (match_operand:DI 3 "register_operand" "0")
15632 (match_operand:DI 4 "register_operand" "1")))
15633 (set (mem:BLK (match_dup 3))
15634 (const_int 0))
15635 (use (match_operand:QI 2 "register_operand" "a"))
15636 (use (match_dup 4))]
15637 "TARGET_64BIT"
15638 "rep{%;} stosb"
15639 [(set_attr "type" "str")
15640 (set_attr "prefix_rep" "1")
15641 (set_attr "memory" "store")
15642 (set_attr "prefix_rex" "0")
15643 (set_attr "mode" "QI")])
15644
15645 (define_expand "cmpstrnsi"
15646 [(set (match_operand:SI 0 "register_operand" "")
15647 (compare:SI (match_operand:BLK 1 "general_operand" "")
15648 (match_operand:BLK 2 "general_operand" "")))
15649 (use (match_operand 3 "general_operand" ""))
15650 (use (match_operand 4 "immediate_operand" ""))]
15651 ""
15652 {
15653 rtx addr1, addr2, out, outlow, count, countreg, align;
15654
15655 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15656 FAIL;
15657
15658 /* Can't use this if the user has appropriated esi or edi. */
15659 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15660 FAIL;
15661
15662 out = operands[0];
15663 if (!REG_P (out))
15664 out = gen_reg_rtx (SImode);
15665
15666 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15667 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15668 if (addr1 != XEXP (operands[1], 0))
15669 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15670 if (addr2 != XEXP (operands[2], 0))
15671 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15672
15673 count = operands[3];
15674 countreg = ix86_zero_extend_to_Pmode (count);
15675
15676 /* %%% Iff we are testing strict equality, we can use known alignment
15677 to good advantage. This may be possible with combine, particularly
15678 once cc0 is dead. */
15679 align = operands[4];
15680
15681 if (CONST_INT_P (count))
15682 {
15683 if (INTVAL (count) == 0)
15684 {
15685 emit_move_insn (operands[0], const0_rtx);
15686 DONE;
15687 }
15688 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15689 operands[1], operands[2]));
15690 }
15691 else
15692 {
15693 rtx (*gen_cmp) (rtx, rtx);
15694
15695 gen_cmp = (TARGET_64BIT
15696 ? gen_cmpdi_1 : gen_cmpsi_1);
15697
15698 emit_insn (gen_cmp (countreg, countreg));
15699 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15700 operands[1], operands[2]));
15701 }
15702
15703 outlow = gen_lowpart (QImode, out);
15704 emit_insn (gen_cmpintqi (outlow));
15705 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15706
15707 if (operands[0] != out)
15708 emit_move_insn (operands[0], out);
15709
15710 DONE;
15711 })
15712
15713 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15714
15715 (define_expand "cmpintqi"
15716 [(set (match_dup 1)
15717 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15718 (set (match_dup 2)
15719 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15720 (parallel [(set (match_operand:QI 0 "register_operand" "")
15721 (minus:QI (match_dup 1)
15722 (match_dup 2)))
15723 (clobber (reg:CC FLAGS_REG))])]
15724 ""
15725 "operands[1] = gen_reg_rtx (QImode);
15726 operands[2] = gen_reg_rtx (QImode);")
15727
15728 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15729 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15730
15731 (define_expand "cmpstrnqi_nz_1"
15732 [(parallel [(set (reg:CC FLAGS_REG)
15733 (compare:CC (match_operand 4 "memory_operand" "")
15734 (match_operand 5 "memory_operand" "")))
15735 (use (match_operand 2 "register_operand" ""))
15736 (use (match_operand:SI 3 "immediate_operand" ""))
15737 (clobber (match_operand 0 "register_operand" ""))
15738 (clobber (match_operand 1 "register_operand" ""))
15739 (clobber (match_dup 2))])]
15740 ""
15741 "ix86_current_function_needs_cld = 1;")
15742
15743 (define_insn "*cmpstrnqi_nz_1"
15744 [(set (reg:CC FLAGS_REG)
15745 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15746 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15747 (use (match_operand:SI 6 "register_operand" "2"))
15748 (use (match_operand:SI 3 "immediate_operand" "i"))
15749 (clobber (match_operand:SI 0 "register_operand" "=S"))
15750 (clobber (match_operand:SI 1 "register_operand" "=D"))
15751 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15752 "!TARGET_64BIT"
15753 "repz{%;} cmpsb"
15754 [(set_attr "type" "str")
15755 (set_attr "mode" "QI")
15756 (set_attr "prefix_rep" "1")])
15757
15758 (define_insn "*cmpstrnqi_nz_rex_1"
15759 [(set (reg:CC FLAGS_REG)
15760 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15761 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15762 (use (match_operand:DI 6 "register_operand" "2"))
15763 (use (match_operand:SI 3 "immediate_operand" "i"))
15764 (clobber (match_operand:DI 0 "register_operand" "=S"))
15765 (clobber (match_operand:DI 1 "register_operand" "=D"))
15766 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15767 "TARGET_64BIT"
15768 "repz{%;} cmpsb"
15769 [(set_attr "type" "str")
15770 (set_attr "mode" "QI")
15771 (set_attr "prefix_rex" "0")
15772 (set_attr "prefix_rep" "1")])
15773
15774 ;; The same, but the count is not known to not be zero.
15775
15776 (define_expand "cmpstrnqi_1"
15777 [(parallel [(set (reg:CC FLAGS_REG)
15778 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15779 (const_int 0))
15780 (compare:CC (match_operand 4 "memory_operand" "")
15781 (match_operand 5 "memory_operand" ""))
15782 (const_int 0)))
15783 (use (match_operand:SI 3 "immediate_operand" ""))
15784 (use (reg:CC FLAGS_REG))
15785 (clobber (match_operand 0 "register_operand" ""))
15786 (clobber (match_operand 1 "register_operand" ""))
15787 (clobber (match_dup 2))])]
15788 ""
15789 "ix86_current_function_needs_cld = 1;")
15790
15791 (define_insn "*cmpstrnqi_1"
15792 [(set (reg:CC FLAGS_REG)
15793 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15794 (const_int 0))
15795 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15796 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15797 (const_int 0)))
15798 (use (match_operand:SI 3 "immediate_operand" "i"))
15799 (use (reg:CC FLAGS_REG))
15800 (clobber (match_operand:SI 0 "register_operand" "=S"))
15801 (clobber (match_operand:SI 1 "register_operand" "=D"))
15802 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15803 "!TARGET_64BIT"
15804 "repz{%;} cmpsb"
15805 [(set_attr "type" "str")
15806 (set_attr "mode" "QI")
15807 (set_attr "prefix_rep" "1")])
15808
15809 (define_insn "*cmpstrnqi_rex_1"
15810 [(set (reg:CC FLAGS_REG)
15811 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15812 (const_int 0))
15813 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15814 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15815 (const_int 0)))
15816 (use (match_operand:SI 3 "immediate_operand" "i"))
15817 (use (reg:CC FLAGS_REG))
15818 (clobber (match_operand:DI 0 "register_operand" "=S"))
15819 (clobber (match_operand:DI 1 "register_operand" "=D"))
15820 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15821 "TARGET_64BIT"
15822 "repz{%;} cmpsb"
15823 [(set_attr "type" "str")
15824 (set_attr "mode" "QI")
15825 (set_attr "prefix_rex" "0")
15826 (set_attr "prefix_rep" "1")])
15827
15828 (define_expand "strlensi"
15829 [(set (match_operand:SI 0 "register_operand" "")
15830 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15831 (match_operand:QI 2 "immediate_operand" "")
15832 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15833 ""
15834 {
15835 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15836 DONE;
15837 else
15838 FAIL;
15839 })
15840
15841 (define_expand "strlendi"
15842 [(set (match_operand:DI 0 "register_operand" "")
15843 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15844 (match_operand:QI 2 "immediate_operand" "")
15845 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15846 ""
15847 {
15848 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15849 DONE;
15850 else
15851 FAIL;
15852 })
15853
15854 (define_expand "strlenqi_1"
15855 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15856 (clobber (match_operand 1 "register_operand" ""))
15857 (clobber (reg:CC FLAGS_REG))])]
15858 ""
15859 "ix86_current_function_needs_cld = 1;")
15860
15861 (define_insn "*strlenqi_1"
15862 [(set (match_operand:SI 0 "register_operand" "=&c")
15863 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15864 (match_operand:QI 2 "register_operand" "a")
15865 (match_operand:SI 3 "immediate_operand" "i")
15866 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15867 (clobber (match_operand:SI 1 "register_operand" "=D"))
15868 (clobber (reg:CC FLAGS_REG))]
15869 "!TARGET_64BIT"
15870 "repnz{%;} scasb"
15871 [(set_attr "type" "str")
15872 (set_attr "mode" "QI")
15873 (set_attr "prefix_rep" "1")])
15874
15875 (define_insn "*strlenqi_rex_1"
15876 [(set (match_operand:DI 0 "register_operand" "=&c")
15877 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15878 (match_operand:QI 2 "register_operand" "a")
15879 (match_operand:DI 3 "immediate_operand" "i")
15880 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15881 (clobber (match_operand:DI 1 "register_operand" "=D"))
15882 (clobber (reg:CC FLAGS_REG))]
15883 "TARGET_64BIT"
15884 "repnz{%;} scasb"
15885 [(set_attr "type" "str")
15886 (set_attr "mode" "QI")
15887 (set_attr "prefix_rex" "0")
15888 (set_attr "prefix_rep" "1")])
15889
15890 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15891 ;; handled in combine, but it is not currently up to the task.
15892 ;; When used for their truth value, the cmpstrn* expanders generate
15893 ;; code like this:
15894 ;;
15895 ;; repz cmpsb
15896 ;; seta %al
15897 ;; setb %dl
15898 ;; cmpb %al, %dl
15899 ;; jcc label
15900 ;;
15901 ;; The intermediate three instructions are unnecessary.
15902
15903 ;; This one handles cmpstrn*_nz_1...
15904 (define_peephole2
15905 [(parallel[
15906 (set (reg:CC FLAGS_REG)
15907 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15908 (mem:BLK (match_operand 5 "register_operand" ""))))
15909 (use (match_operand 6 "register_operand" ""))
15910 (use (match_operand:SI 3 "immediate_operand" ""))
15911 (clobber (match_operand 0 "register_operand" ""))
15912 (clobber (match_operand 1 "register_operand" ""))
15913 (clobber (match_operand 2 "register_operand" ""))])
15914 (set (match_operand:QI 7 "register_operand" "")
15915 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15916 (set (match_operand:QI 8 "register_operand" "")
15917 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15918 (set (reg FLAGS_REG)
15919 (compare (match_dup 7) (match_dup 8)))
15920 ]
15921 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15922 [(parallel[
15923 (set (reg:CC FLAGS_REG)
15924 (compare:CC (mem:BLK (match_dup 4))
15925 (mem:BLK (match_dup 5))))
15926 (use (match_dup 6))
15927 (use (match_dup 3))
15928 (clobber (match_dup 0))
15929 (clobber (match_dup 1))
15930 (clobber (match_dup 2))])])
15931
15932 ;; ...and this one handles cmpstrn*_1.
15933 (define_peephole2
15934 [(parallel[
15935 (set (reg:CC FLAGS_REG)
15936 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15937 (const_int 0))
15938 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15939 (mem:BLK (match_operand 5 "register_operand" "")))
15940 (const_int 0)))
15941 (use (match_operand:SI 3 "immediate_operand" ""))
15942 (use (reg:CC FLAGS_REG))
15943 (clobber (match_operand 0 "register_operand" ""))
15944 (clobber (match_operand 1 "register_operand" ""))
15945 (clobber (match_operand 2 "register_operand" ""))])
15946 (set (match_operand:QI 7 "register_operand" "")
15947 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15948 (set (match_operand:QI 8 "register_operand" "")
15949 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15950 (set (reg FLAGS_REG)
15951 (compare (match_dup 7) (match_dup 8)))
15952 ]
15953 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15954 [(parallel[
15955 (set (reg:CC FLAGS_REG)
15956 (if_then_else:CC (ne (match_dup 6)
15957 (const_int 0))
15958 (compare:CC (mem:BLK (match_dup 4))
15959 (mem:BLK (match_dup 5)))
15960 (const_int 0)))
15961 (use (match_dup 3))
15962 (use (reg:CC FLAGS_REG))
15963 (clobber (match_dup 0))
15964 (clobber (match_dup 1))
15965 (clobber (match_dup 2))])])
15966 \f
15967 ;; Conditional move instructions.
15968
15969 (define_expand "mov<mode>cc"
15970 [(set (match_operand:SWIM 0 "register_operand" "")
15971 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15972 (match_operand:SWIM 2 "general_operand" "")
15973 (match_operand:SWIM 3 "general_operand" "")))]
15974 ""
15975 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15976
15977 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15978 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15979 ;; So just document what we're doing explicitly.
15980
15981 (define_expand "x86_mov<mode>cc_0_m1"
15982 [(parallel
15983 [(set (match_operand:SWI48 0 "register_operand" "")
15984 (if_then_else:SWI48
15985 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15986 [(match_operand 1 "flags_reg_operand" "")
15987 (const_int 0)])
15988 (const_int -1)
15989 (const_int 0)))
15990 (clobber (reg:CC FLAGS_REG))])])
15991
15992 (define_insn "*x86_mov<mode>cc_0_m1"
15993 [(set (match_operand:SWI48 0 "register_operand" "=r")
15994 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15995 [(reg FLAGS_REG) (const_int 0)])
15996 (const_int -1)
15997 (const_int 0)))
15998 (clobber (reg:CC FLAGS_REG))]
15999 ""
16000 "sbb{<imodesuffix>}\t%0, %0"
16001 ; Since we don't have the proper number of operands for an alu insn,
16002 ; fill in all the blanks.
16003 [(set_attr "type" "alu")
16004 (set_attr "use_carry" "1")
16005 (set_attr "pent_pair" "pu")
16006 (set_attr "memory" "none")
16007 (set_attr "imm_disp" "false")
16008 (set_attr "mode" "<MODE>")
16009 (set_attr "length_immediate" "0")])
16010
16011 (define_insn "*x86_mov<mode>cc_0_m1_se"
16012 [(set (match_operand:SWI48 0 "register_operand" "=r")
16013 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16014 [(reg FLAGS_REG) (const_int 0)])
16015 (const_int 1)
16016 (const_int 0)))
16017 (clobber (reg:CC FLAGS_REG))]
16018 ""
16019 "sbb{<imodesuffix>}\t%0, %0"
16020 [(set_attr "type" "alu")
16021 (set_attr "use_carry" "1")
16022 (set_attr "pent_pair" "pu")
16023 (set_attr "memory" "none")
16024 (set_attr "imm_disp" "false")
16025 (set_attr "mode" "<MODE>")
16026 (set_attr "length_immediate" "0")])
16027
16028 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16029 [(set (match_operand:SWI48 0 "register_operand" "=r")
16030 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16031 [(reg FLAGS_REG) (const_int 0)])))]
16032 ""
16033 "sbb{<imodesuffix>}\t%0, %0"
16034 [(set_attr "type" "alu")
16035 (set_attr "use_carry" "1")
16036 (set_attr "pent_pair" "pu")
16037 (set_attr "memory" "none")
16038 (set_attr "imm_disp" "false")
16039 (set_attr "mode" "<MODE>")
16040 (set_attr "length_immediate" "0")])
16041
16042 (define_insn "*mov<mode>cc_noc"
16043 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16044 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16045 [(reg FLAGS_REG) (const_int 0)])
16046 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16047 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16048 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16049 "@
16050 cmov%O2%C1\t{%2, %0|%0, %2}
16051 cmov%O2%c1\t{%3, %0|%0, %3}"
16052 [(set_attr "type" "icmov")
16053 (set_attr "mode" "<MODE>")])
16054
16055 (define_insn_and_split "*movqicc_noc"
16056 [(set (match_operand:QI 0 "register_operand" "=r,r")
16057 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16058 [(match_operand 4 "flags_reg_operand" "")
16059 (const_int 0)])
16060 (match_operand:QI 2 "register_operand" "r,0")
16061 (match_operand:QI 3 "register_operand" "0,r")))]
16062 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16063 "#"
16064 "&& reload_completed"
16065 [(set (match_dup 0)
16066 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16067 (match_dup 2)
16068 (match_dup 3)))]
16069 "operands[0] = gen_lowpart (SImode, operands[0]);
16070 operands[2] = gen_lowpart (SImode, operands[2]);
16071 operands[3] = gen_lowpart (SImode, operands[3]);"
16072 [(set_attr "type" "icmov")
16073 (set_attr "mode" "SI")])
16074
16075 (define_expand "mov<mode>cc"
16076 [(set (match_operand:X87MODEF 0 "register_operand" "")
16077 (if_then_else:X87MODEF
16078 (match_operand 1 "ix86_fp_comparison_operator" "")
16079 (match_operand:X87MODEF 2 "register_operand" "")
16080 (match_operand:X87MODEF 3 "register_operand" "")))]
16081 "(TARGET_80387 && TARGET_CMOVE)
16082 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16083 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16084
16085 (define_insn "*movsfcc_1_387"
16086 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16087 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16088 [(reg FLAGS_REG) (const_int 0)])
16089 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16090 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16091 "TARGET_80387 && TARGET_CMOVE
16092 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16093 "@
16094 fcmov%F1\t{%2, %0|%0, %2}
16095 fcmov%f1\t{%3, %0|%0, %3}
16096 cmov%O2%C1\t{%2, %0|%0, %2}
16097 cmov%O2%c1\t{%3, %0|%0, %3}"
16098 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16099 (set_attr "mode" "SF,SF,SI,SI")])
16100
16101 (define_insn "*movdfcc_1"
16102 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16103 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16104 [(reg FLAGS_REG) (const_int 0)])
16105 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16106 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16107 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16108 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16109 "@
16110 fcmov%F1\t{%2, %0|%0, %2}
16111 fcmov%f1\t{%3, %0|%0, %3}
16112 #
16113 #"
16114 [(set_attr "type" "fcmov,fcmov,multi,multi")
16115 (set_attr "mode" "DF")])
16116
16117 (define_insn "*movdfcc_1_rex64"
16118 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16119 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16120 [(reg FLAGS_REG) (const_int 0)])
16121 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16122 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16123 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16124 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16125 "@
16126 fcmov%F1\t{%2, %0|%0, %2}
16127 fcmov%f1\t{%3, %0|%0, %3}
16128 cmov%O2%C1\t{%2, %0|%0, %2}
16129 cmov%O2%c1\t{%3, %0|%0, %3}"
16130 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16131 (set_attr "mode" "DF")])
16132
16133 (define_split
16134 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16135 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16136 [(match_operand 4 "flags_reg_operand" "")
16137 (const_int 0)])
16138 (match_operand:DF 2 "nonimmediate_operand" "")
16139 (match_operand:DF 3 "nonimmediate_operand" "")))]
16140 "!TARGET_64BIT && reload_completed"
16141 [(set (match_dup 2)
16142 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16143 (match_dup 5)
16144 (match_dup 6)))
16145 (set (match_dup 3)
16146 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16147 (match_dup 7)
16148 (match_dup 8)))]
16149 {
16150 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16151 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16152 })
16153
16154 (define_insn "*movxfcc_1"
16155 [(set (match_operand:XF 0 "register_operand" "=f,f")
16156 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16157 [(reg FLAGS_REG) (const_int 0)])
16158 (match_operand:XF 2 "register_operand" "f,0")
16159 (match_operand:XF 3 "register_operand" "0,f")))]
16160 "TARGET_80387 && TARGET_CMOVE"
16161 "@
16162 fcmov%F1\t{%2, %0|%0, %2}
16163 fcmov%f1\t{%3, %0|%0, %3}"
16164 [(set_attr "type" "fcmov")
16165 (set_attr "mode" "XF")])
16166
16167 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16168 ;; the scalar versions to have only XMM registers as operands.
16169
16170 ;; XOP conditional move
16171 (define_insn "*xop_pcmov_<mode>"
16172 [(set (match_operand:MODEF 0 "register_operand" "=x")
16173 (if_then_else:MODEF
16174 (match_operand:MODEF 1 "register_operand" "x")
16175 (match_operand:MODEF 2 "register_operand" "x")
16176 (match_operand:MODEF 3 "register_operand" "x")))]
16177 "TARGET_XOP"
16178 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16179 [(set_attr "type" "sse4arg")])
16180
16181 ;; These versions of the min/max patterns are intentionally ignorant of
16182 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16183 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16184 ;; are undefined in this condition, we're certain this is correct.
16185
16186 (define_insn "*avx_<code><mode>3"
16187 [(set (match_operand:MODEF 0 "register_operand" "=x")
16188 (smaxmin:MODEF
16189 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16190 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16191 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16192 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16193 [(set_attr "type" "sseadd")
16194 (set_attr "prefix" "vex")
16195 (set_attr "mode" "<MODE>")])
16196
16197 (define_insn "<code><mode>3"
16198 [(set (match_operand:MODEF 0 "register_operand" "=x")
16199 (smaxmin:MODEF
16200 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16201 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16202 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16203 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16204 [(set_attr "type" "sseadd")
16205 (set_attr "mode" "<MODE>")])
16206
16207 ;; These versions of the min/max patterns implement exactly the operations
16208 ;; min = (op1 < op2 ? op1 : op2)
16209 ;; max = (!(op1 < op2) ? op1 : op2)
16210 ;; Their operands are not commutative, and thus they may be used in the
16211 ;; presence of -0.0 and NaN.
16212
16213 (define_insn "*avx_ieee_smin<mode>3"
16214 [(set (match_operand:MODEF 0 "register_operand" "=x")
16215 (unspec:MODEF
16216 [(match_operand:MODEF 1 "register_operand" "x")
16217 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16218 UNSPEC_IEEE_MIN))]
16219 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16220 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16221 [(set_attr "type" "sseadd")
16222 (set_attr "prefix" "vex")
16223 (set_attr "mode" "<MODE>")])
16224
16225 (define_insn "*ieee_smin<mode>3"
16226 [(set (match_operand:MODEF 0 "register_operand" "=x")
16227 (unspec:MODEF
16228 [(match_operand:MODEF 1 "register_operand" "0")
16229 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16230 UNSPEC_IEEE_MIN))]
16231 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16232 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16233 [(set_attr "type" "sseadd")
16234 (set_attr "mode" "<MODE>")])
16235
16236 (define_insn "*avx_ieee_smax<mode>3"
16237 [(set (match_operand:MODEF 0 "register_operand" "=x")
16238 (unspec:MODEF
16239 [(match_operand:MODEF 1 "register_operand" "0")
16240 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16241 UNSPEC_IEEE_MAX))]
16242 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16243 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16244 [(set_attr "type" "sseadd")
16245 (set_attr "prefix" "vex")
16246 (set_attr "mode" "<MODE>")])
16247
16248 (define_insn "*ieee_smax<mode>3"
16249 [(set (match_operand:MODEF 0 "register_operand" "=x")
16250 (unspec:MODEF
16251 [(match_operand:MODEF 1 "register_operand" "0")
16252 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16253 UNSPEC_IEEE_MAX))]
16254 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16255 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16256 [(set_attr "type" "sseadd")
16257 (set_attr "mode" "<MODE>")])
16258
16259 ;; Make two stack loads independent:
16260 ;; fld aa fld aa
16261 ;; fld %st(0) -> fld bb
16262 ;; fmul bb fmul %st(1), %st
16263 ;;
16264 ;; Actually we only match the last two instructions for simplicity.
16265 (define_peephole2
16266 [(set (match_operand 0 "fp_register_operand" "")
16267 (match_operand 1 "fp_register_operand" ""))
16268 (set (match_dup 0)
16269 (match_operator 2 "binary_fp_operator"
16270 [(match_dup 0)
16271 (match_operand 3 "memory_operand" "")]))]
16272 "REGNO (operands[0]) != REGNO (operands[1])"
16273 [(set (match_dup 0) (match_dup 3))
16274 (set (match_dup 0) (match_dup 4))]
16275
16276 ;; The % modifier is not operational anymore in peephole2's, so we have to
16277 ;; swap the operands manually in the case of addition and multiplication.
16278 "if (COMMUTATIVE_ARITH_P (operands[2]))
16279 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16280 GET_MODE (operands[2]),
16281 operands[0], operands[1]);
16282 else
16283 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16284 GET_MODE (operands[2]),
16285 operands[1], operands[0]);")
16286
16287 ;; Conditional addition patterns
16288 (define_expand "add<mode>cc"
16289 [(match_operand:SWI 0 "register_operand" "")
16290 (match_operand 1 "ordered_comparison_operator" "")
16291 (match_operand:SWI 2 "register_operand" "")
16292 (match_operand:SWI 3 "const_int_operand" "")]
16293 ""
16294 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16295 \f
16296 ;; Misc patterns (?)
16297
16298 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16299 ;; Otherwise there will be nothing to keep
16300 ;;
16301 ;; [(set (reg ebp) (reg esp))]
16302 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16303 ;; (clobber (eflags)]
16304 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16305 ;;
16306 ;; in proper program order.
16307
16308 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16309 [(set (match_operand:P 0 "register_operand" "=r,r")
16310 (plus:P (match_operand:P 1 "register_operand" "0,r")
16311 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16312 (clobber (reg:CC FLAGS_REG))
16313 (clobber (mem:BLK (scratch)))]
16314 ""
16315 {
16316 switch (get_attr_type (insn))
16317 {
16318 case TYPE_IMOV:
16319 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16320
16321 case TYPE_ALU:
16322 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16323 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16324 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16325
16326 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16327
16328 default:
16329 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16330 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16331 }
16332 }
16333 [(set (attr "type")
16334 (cond [(and (eq_attr "alternative" "0")
16335 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16336 (const_string "alu")
16337 (match_operand:<MODE> 2 "const0_operand" "")
16338 (const_string "imov")
16339 ]
16340 (const_string "lea")))
16341 (set (attr "length_immediate")
16342 (cond [(eq_attr "type" "imov")
16343 (const_string "0")
16344 (and (eq_attr "type" "alu")
16345 (match_operand 2 "const128_operand" ""))
16346 (const_string "1")
16347 ]
16348 (const_string "*")))
16349 (set_attr "mode" "<MODE>")])
16350
16351 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16352 [(set (match_operand:P 0 "register_operand" "=r")
16353 (minus:P (match_operand:P 1 "register_operand" "0")
16354 (match_operand:P 2 "register_operand" "r")))
16355 (clobber (reg:CC FLAGS_REG))
16356 (clobber (mem:BLK (scratch)))]
16357 ""
16358 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16359 [(set_attr "type" "alu")
16360 (set_attr "mode" "<MODE>")])
16361
16362 (define_insn "allocate_stack_worker_probe_<mode>"
16363 [(set (match_operand:P 0 "register_operand" "=a")
16364 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16365 UNSPECV_STACK_PROBE))
16366 (clobber (reg:CC FLAGS_REG))]
16367 "ix86_target_stack_probe ()"
16368 "call\t___chkstk_ms"
16369 [(set_attr "type" "multi")
16370 (set_attr "length" "5")])
16371
16372 (define_expand "allocate_stack"
16373 [(match_operand 0 "register_operand" "")
16374 (match_operand 1 "general_operand" "")]
16375 "ix86_target_stack_probe ()"
16376 {
16377 rtx x;
16378
16379 #ifndef CHECK_STACK_LIMIT
16380 #define CHECK_STACK_LIMIT 0
16381 #endif
16382
16383 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16384 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16385 {
16386 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16387 stack_pointer_rtx, 0, OPTAB_DIRECT);
16388 if (x != stack_pointer_rtx)
16389 emit_move_insn (stack_pointer_rtx, x);
16390 }
16391 else
16392 {
16393 x = copy_to_mode_reg (Pmode, operands[1]);
16394 if (TARGET_64BIT)
16395 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16396 else
16397 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16398 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16399 stack_pointer_rtx, 0, OPTAB_DIRECT);
16400 if (x != stack_pointer_rtx)
16401 emit_move_insn (stack_pointer_rtx, x);
16402 }
16403
16404 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16405 DONE;
16406 })
16407
16408 ;; Use IOR for stack probes, this is shorter.
16409 (define_expand "probe_stack"
16410 [(match_operand 0 "memory_operand" "")]
16411 ""
16412 {
16413 rtx (*gen_ior3) (rtx, rtx, rtx);
16414
16415 gen_ior3 = (GET_MODE (operands[0]) == DImode
16416 ? gen_iordi3 : gen_iorsi3);
16417
16418 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16419 DONE;
16420 })
16421
16422 (define_insn "adjust_stack_and_probe<mode>"
16423 [(set (match_operand:P 0 "register_operand" "=r")
16424 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16425 UNSPECV_PROBE_STACK_RANGE))
16426 (set (reg:P SP_REG)
16427 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16428 (clobber (reg:CC FLAGS_REG))
16429 (clobber (mem:BLK (scratch)))]
16430 ""
16431 "* return output_adjust_stack_and_probe (operands[0]);"
16432 [(set_attr "type" "multi")])
16433
16434 (define_insn "probe_stack_range<mode>"
16435 [(set (match_operand:P 0 "register_operand" "=r")
16436 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16437 (match_operand:P 2 "const_int_operand" "n")]
16438 UNSPECV_PROBE_STACK_RANGE))
16439 (clobber (reg:CC FLAGS_REG))]
16440 ""
16441 "* return output_probe_stack_range (operands[0], operands[2]);"
16442 [(set_attr "type" "multi")])
16443
16444 (define_expand "builtin_setjmp_receiver"
16445 [(label_ref (match_operand 0 "" ""))]
16446 "!TARGET_64BIT && flag_pic"
16447 {
16448 #if TARGET_MACHO
16449 if (TARGET_MACHO)
16450 {
16451 rtx xops[3];
16452 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16453 rtx label_rtx = gen_label_rtx ();
16454 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16455 xops[0] = xops[1] = picreg;
16456 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16457 ix86_expand_binary_operator (MINUS, SImode, xops);
16458 }
16459 else
16460 #endif
16461 emit_insn (gen_set_got (pic_offset_table_rtx));
16462 DONE;
16463 })
16464 \f
16465 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16466
16467 (define_split
16468 [(set (match_operand 0 "register_operand" "")
16469 (match_operator 3 "promotable_binary_operator"
16470 [(match_operand 1 "register_operand" "")
16471 (match_operand 2 "aligned_operand" "")]))
16472 (clobber (reg:CC FLAGS_REG))]
16473 "! TARGET_PARTIAL_REG_STALL && reload_completed
16474 && ((GET_MODE (operands[0]) == HImode
16475 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16476 /* ??? next two lines just !satisfies_constraint_K (...) */
16477 || !CONST_INT_P (operands[2])
16478 || satisfies_constraint_K (operands[2])))
16479 || (GET_MODE (operands[0]) == QImode
16480 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16481 [(parallel [(set (match_dup 0)
16482 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16483 (clobber (reg:CC FLAGS_REG))])]
16484 "operands[0] = gen_lowpart (SImode, operands[0]);
16485 operands[1] = gen_lowpart (SImode, operands[1]);
16486 if (GET_CODE (operands[3]) != ASHIFT)
16487 operands[2] = gen_lowpart (SImode, operands[2]);
16488 PUT_MODE (operands[3], SImode);")
16489
16490 ; Promote the QImode tests, as i386 has encoding of the AND
16491 ; instruction with 32-bit sign-extended immediate and thus the
16492 ; instruction size is unchanged, except in the %eax case for
16493 ; which it is increased by one byte, hence the ! optimize_size.
16494 (define_split
16495 [(set (match_operand 0 "flags_reg_operand" "")
16496 (match_operator 2 "compare_operator"
16497 [(and (match_operand 3 "aligned_operand" "")
16498 (match_operand 4 "const_int_operand" ""))
16499 (const_int 0)]))
16500 (set (match_operand 1 "register_operand" "")
16501 (and (match_dup 3) (match_dup 4)))]
16502 "! TARGET_PARTIAL_REG_STALL && reload_completed
16503 && optimize_insn_for_speed_p ()
16504 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16505 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16506 /* Ensure that the operand will remain sign-extended immediate. */
16507 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16508 [(parallel [(set (match_dup 0)
16509 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16510 (const_int 0)]))
16511 (set (match_dup 1)
16512 (and:SI (match_dup 3) (match_dup 4)))])]
16513 {
16514 operands[4]
16515 = gen_int_mode (INTVAL (operands[4])
16516 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16517 operands[1] = gen_lowpart (SImode, operands[1]);
16518 operands[3] = gen_lowpart (SImode, operands[3]);
16519 })
16520
16521 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16522 ; the TEST instruction with 32-bit sign-extended immediate and thus
16523 ; the instruction size would at least double, which is not what we
16524 ; want even with ! optimize_size.
16525 (define_split
16526 [(set (match_operand 0 "flags_reg_operand" "")
16527 (match_operator 1 "compare_operator"
16528 [(and (match_operand:HI 2 "aligned_operand" "")
16529 (match_operand:HI 3 "const_int_operand" ""))
16530 (const_int 0)]))]
16531 "! TARGET_PARTIAL_REG_STALL && reload_completed
16532 && ! TARGET_FAST_PREFIX
16533 && optimize_insn_for_speed_p ()
16534 /* Ensure that the operand will remain sign-extended immediate. */
16535 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16536 [(set (match_dup 0)
16537 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16538 (const_int 0)]))]
16539 {
16540 operands[3]
16541 = gen_int_mode (INTVAL (operands[3])
16542 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16543 operands[2] = gen_lowpart (SImode, operands[2]);
16544 })
16545
16546 (define_split
16547 [(set (match_operand 0 "register_operand" "")
16548 (neg (match_operand 1 "register_operand" "")))
16549 (clobber (reg:CC FLAGS_REG))]
16550 "! TARGET_PARTIAL_REG_STALL && reload_completed
16551 && (GET_MODE (operands[0]) == HImode
16552 || (GET_MODE (operands[0]) == QImode
16553 && (TARGET_PROMOTE_QImode
16554 || optimize_insn_for_size_p ())))"
16555 [(parallel [(set (match_dup 0)
16556 (neg:SI (match_dup 1)))
16557 (clobber (reg:CC FLAGS_REG))])]
16558 "operands[0] = gen_lowpart (SImode, operands[0]);
16559 operands[1] = gen_lowpart (SImode, operands[1]);")
16560
16561 (define_split
16562 [(set (match_operand 0 "register_operand" "")
16563 (not (match_operand 1 "register_operand" "")))]
16564 "! TARGET_PARTIAL_REG_STALL && reload_completed
16565 && (GET_MODE (operands[0]) == HImode
16566 || (GET_MODE (operands[0]) == QImode
16567 && (TARGET_PROMOTE_QImode
16568 || optimize_insn_for_size_p ())))"
16569 [(set (match_dup 0)
16570 (not:SI (match_dup 1)))]
16571 "operands[0] = gen_lowpart (SImode, operands[0]);
16572 operands[1] = gen_lowpart (SImode, operands[1]);")
16573
16574 (define_split
16575 [(set (match_operand 0 "register_operand" "")
16576 (if_then_else (match_operator 1 "ordered_comparison_operator"
16577 [(reg FLAGS_REG) (const_int 0)])
16578 (match_operand 2 "register_operand" "")
16579 (match_operand 3 "register_operand" "")))]
16580 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16581 && (GET_MODE (operands[0]) == HImode
16582 || (GET_MODE (operands[0]) == QImode
16583 && (TARGET_PROMOTE_QImode
16584 || optimize_insn_for_size_p ())))"
16585 [(set (match_dup 0)
16586 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16587 "operands[0] = gen_lowpart (SImode, operands[0]);
16588 operands[2] = gen_lowpart (SImode, operands[2]);
16589 operands[3] = gen_lowpart (SImode, operands[3]);")
16590 \f
16591 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16592 ;; transform a complex memory operation into two memory to register operations.
16593
16594 ;; Don't push memory operands
16595 (define_peephole2
16596 [(set (match_operand:SWI 0 "push_operand" "")
16597 (match_operand:SWI 1 "memory_operand" ""))
16598 (match_scratch:SWI 2 "<r>")]
16599 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16600 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16601 [(set (match_dup 2) (match_dup 1))
16602 (set (match_dup 0) (match_dup 2))])
16603
16604 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16605 ;; SImode pushes.
16606 (define_peephole2
16607 [(set (match_operand:SF 0 "push_operand" "")
16608 (match_operand:SF 1 "memory_operand" ""))
16609 (match_scratch:SF 2 "r")]
16610 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16611 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16612 [(set (match_dup 2) (match_dup 1))
16613 (set (match_dup 0) (match_dup 2))])
16614
16615 ;; Don't move an immediate directly to memory when the instruction
16616 ;; gets too big.
16617 (define_peephole2
16618 [(match_scratch:SWI124 1 "<r>")
16619 (set (match_operand:SWI124 0 "memory_operand" "")
16620 (const_int 0))]
16621 "optimize_insn_for_speed_p ()
16622 && !TARGET_USE_MOV0
16623 && TARGET_SPLIT_LONG_MOVES
16624 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16625 && peep2_regno_dead_p (0, FLAGS_REG)"
16626 [(parallel [(set (match_dup 2) (const_int 0))
16627 (clobber (reg:CC FLAGS_REG))])
16628 (set (match_dup 0) (match_dup 1))]
16629 "operands[2] = gen_lowpart (SImode, operands[1]);")
16630
16631 (define_peephole2
16632 [(match_scratch:SWI124 2 "<r>")
16633 (set (match_operand:SWI124 0 "memory_operand" "")
16634 (match_operand:SWI124 1 "immediate_operand" ""))]
16635 "optimize_insn_for_speed_p ()
16636 && TARGET_SPLIT_LONG_MOVES
16637 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16638 [(set (match_dup 2) (match_dup 1))
16639 (set (match_dup 0) (match_dup 2))])
16640
16641 ;; Don't compare memory with zero, load and use a test instead.
16642 (define_peephole2
16643 [(set (match_operand 0 "flags_reg_operand" "")
16644 (match_operator 1 "compare_operator"
16645 [(match_operand:SI 2 "memory_operand" "")
16646 (const_int 0)]))
16647 (match_scratch:SI 3 "r")]
16648 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16649 [(set (match_dup 3) (match_dup 2))
16650 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16651
16652 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16653 ;; Don't split NOTs with a displacement operand, because resulting XOR
16654 ;; will not be pairable anyway.
16655 ;;
16656 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16657 ;; represented using a modRM byte. The XOR replacement is long decoded,
16658 ;; so this split helps here as well.
16659 ;;
16660 ;; Note: Can't do this as a regular split because we can't get proper
16661 ;; lifetime information then.
16662
16663 (define_peephole2
16664 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16665 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16666 "optimize_insn_for_speed_p ()
16667 && ((TARGET_NOT_UNPAIRABLE
16668 && (!MEM_P (operands[0])
16669 || !memory_displacement_operand (operands[0], <MODE>mode)))
16670 || (TARGET_NOT_VECTORMODE
16671 && long_memory_operand (operands[0], <MODE>mode)))
16672 && peep2_regno_dead_p (0, FLAGS_REG)"
16673 [(parallel [(set (match_dup 0)
16674 (xor:SWI124 (match_dup 1) (const_int -1)))
16675 (clobber (reg:CC FLAGS_REG))])])
16676
16677 ;; Non pairable "test imm, reg" instructions can be translated to
16678 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16679 ;; byte opcode instead of two, have a short form for byte operands),
16680 ;; so do it for other CPUs as well. Given that the value was dead,
16681 ;; this should not create any new dependencies. Pass on the sub-word
16682 ;; versions if we're concerned about partial register stalls.
16683
16684 (define_peephole2
16685 [(set (match_operand 0 "flags_reg_operand" "")
16686 (match_operator 1 "compare_operator"
16687 [(and:SI (match_operand:SI 2 "register_operand" "")
16688 (match_operand:SI 3 "immediate_operand" ""))
16689 (const_int 0)]))]
16690 "ix86_match_ccmode (insn, CCNOmode)
16691 && (true_regnum (operands[2]) != AX_REG
16692 || satisfies_constraint_K (operands[3]))
16693 && peep2_reg_dead_p (1, operands[2])"
16694 [(parallel
16695 [(set (match_dup 0)
16696 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16697 (const_int 0)]))
16698 (set (match_dup 2)
16699 (and:SI (match_dup 2) (match_dup 3)))])])
16700
16701 ;; We don't need to handle HImode case, because it will be promoted to SImode
16702 ;; on ! TARGET_PARTIAL_REG_STALL
16703
16704 (define_peephole2
16705 [(set (match_operand 0 "flags_reg_operand" "")
16706 (match_operator 1 "compare_operator"
16707 [(and:QI (match_operand:QI 2 "register_operand" "")
16708 (match_operand:QI 3 "immediate_operand" ""))
16709 (const_int 0)]))]
16710 "! TARGET_PARTIAL_REG_STALL
16711 && ix86_match_ccmode (insn, CCNOmode)
16712 && true_regnum (operands[2]) != AX_REG
16713 && peep2_reg_dead_p (1, operands[2])"
16714 [(parallel
16715 [(set (match_dup 0)
16716 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16717 (const_int 0)]))
16718 (set (match_dup 2)
16719 (and:QI (match_dup 2) (match_dup 3)))])])
16720
16721 (define_peephole2
16722 [(set (match_operand 0 "flags_reg_operand" "")
16723 (match_operator 1 "compare_operator"
16724 [(and:SI
16725 (zero_extract:SI
16726 (match_operand 2 "ext_register_operand" "")
16727 (const_int 8)
16728 (const_int 8))
16729 (match_operand 3 "const_int_operand" ""))
16730 (const_int 0)]))]
16731 "! TARGET_PARTIAL_REG_STALL
16732 && ix86_match_ccmode (insn, CCNOmode)
16733 && true_regnum (operands[2]) != AX_REG
16734 && peep2_reg_dead_p (1, operands[2])"
16735 [(parallel [(set (match_dup 0)
16736 (match_op_dup 1
16737 [(and:SI
16738 (zero_extract:SI
16739 (match_dup 2)
16740 (const_int 8)
16741 (const_int 8))
16742 (match_dup 3))
16743 (const_int 0)]))
16744 (set (zero_extract:SI (match_dup 2)
16745 (const_int 8)
16746 (const_int 8))
16747 (and:SI
16748 (zero_extract:SI
16749 (match_dup 2)
16750 (const_int 8)
16751 (const_int 8))
16752 (match_dup 3)))])])
16753
16754 ;; Don't do logical operations with memory inputs.
16755 (define_peephole2
16756 [(match_scratch:SI 2 "r")
16757 (parallel [(set (match_operand:SI 0 "register_operand" "")
16758 (match_operator:SI 3 "arith_or_logical_operator"
16759 [(match_dup 0)
16760 (match_operand:SI 1 "memory_operand" "")]))
16761 (clobber (reg:CC FLAGS_REG))])]
16762 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16763 [(set (match_dup 2) (match_dup 1))
16764 (parallel [(set (match_dup 0)
16765 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16766 (clobber (reg:CC FLAGS_REG))])])
16767
16768 (define_peephole2
16769 [(match_scratch:SI 2 "r")
16770 (parallel [(set (match_operand:SI 0 "register_operand" "")
16771 (match_operator:SI 3 "arith_or_logical_operator"
16772 [(match_operand:SI 1 "memory_operand" "")
16773 (match_dup 0)]))
16774 (clobber (reg:CC FLAGS_REG))])]
16775 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16776 [(set (match_dup 2) (match_dup 1))
16777 (parallel [(set (match_dup 0)
16778 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16779 (clobber (reg:CC FLAGS_REG))])])
16780
16781 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16782 ;; refers to the destination of the load!
16783
16784 (define_peephole2
16785 [(set (match_operand:SI 0 "register_operand" "")
16786 (match_operand:SI 1 "register_operand" ""))
16787 (parallel [(set (match_dup 0)
16788 (match_operator:SI 3 "commutative_operator"
16789 [(match_dup 0)
16790 (match_operand:SI 2 "memory_operand" "")]))
16791 (clobber (reg:CC FLAGS_REG))])]
16792 "REGNO (operands[0]) != REGNO (operands[1])
16793 && GENERAL_REGNO_P (REGNO (operands[0]))
16794 && GENERAL_REGNO_P (REGNO (operands[1]))"
16795 [(set (match_dup 0) (match_dup 4))
16796 (parallel [(set (match_dup 0)
16797 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16798 (clobber (reg:CC FLAGS_REG))])]
16799 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16800
16801 (define_peephole2
16802 [(set (match_operand 0 "register_operand" "")
16803 (match_operand 1 "register_operand" ""))
16804 (set (match_dup 0)
16805 (match_operator 3 "commutative_operator"
16806 [(match_dup 0)
16807 (match_operand 2 "memory_operand" "")]))]
16808 "REGNO (operands[0]) != REGNO (operands[1])
16809 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16810 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16811 [(set (match_dup 0) (match_dup 2))
16812 (set (match_dup 0)
16813 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16814
16815 ; Don't do logical operations with memory outputs
16816 ;
16817 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16818 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16819 ; the same decoder scheduling characteristics as the original.
16820
16821 (define_peephole2
16822 [(match_scratch:SI 2 "r")
16823 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16824 (match_operator:SI 3 "arith_or_logical_operator"
16825 [(match_dup 0)
16826 (match_operand:SI 1 "nonmemory_operand" "")]))
16827 (clobber (reg:CC FLAGS_REG))])]
16828 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16829 /* Do not split stack checking probes. */
16830 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16831 [(set (match_dup 2) (match_dup 0))
16832 (parallel [(set (match_dup 2)
16833 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16834 (clobber (reg:CC FLAGS_REG))])
16835 (set (match_dup 0) (match_dup 2))])
16836
16837 (define_peephole2
16838 [(match_scratch:SI 2 "r")
16839 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16840 (match_operator:SI 3 "arith_or_logical_operator"
16841 [(match_operand:SI 1 "nonmemory_operand" "")
16842 (match_dup 0)]))
16843 (clobber (reg:CC FLAGS_REG))])]
16844 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16845 /* Do not split stack checking probes. */
16846 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16847 [(set (match_dup 2) (match_dup 0))
16848 (parallel [(set (match_dup 2)
16849 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16850 (clobber (reg:CC FLAGS_REG))])
16851 (set (match_dup 0) (match_dup 2))])
16852
16853 ;; Attempt to always use XOR for zeroing registers.
16854 (define_peephole2
16855 [(set (match_operand 0 "register_operand" "")
16856 (match_operand 1 "const0_operand" ""))]
16857 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16858 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16859 && GENERAL_REG_P (operands[0])
16860 && peep2_regno_dead_p (0, FLAGS_REG)"
16861 [(parallel [(set (match_dup 0) (const_int 0))
16862 (clobber (reg:CC FLAGS_REG))])]
16863 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16864
16865 (define_peephole2
16866 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16867 (const_int 0))]
16868 "(GET_MODE (operands[0]) == QImode
16869 || GET_MODE (operands[0]) == HImode)
16870 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16871 && peep2_regno_dead_p (0, FLAGS_REG)"
16872 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16873 (clobber (reg:CC FLAGS_REG))])])
16874
16875 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16876 (define_peephole2
16877 [(set (match_operand:SWI248 0 "register_operand" "")
16878 (const_int -1))]
16879 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16880 && peep2_regno_dead_p (0, FLAGS_REG)"
16881 [(parallel [(set (match_dup 0) (const_int -1))
16882 (clobber (reg:CC FLAGS_REG))])]
16883 {
16884 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16885 operands[0] = gen_lowpart (SImode, operands[0]);
16886 })
16887
16888 ;; Attempt to convert simple lea to add/shift.
16889 ;; These can be created by move expanders.
16890
16891 (define_peephole2
16892 [(set (match_operand:SWI48 0 "register_operand" "")
16893 (plus:SWI48 (match_dup 0)
16894 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16895 "peep2_regno_dead_p (0, FLAGS_REG)"
16896 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16897 (clobber (reg:CC FLAGS_REG))])])
16898
16899 (define_peephole2
16900 [(set (match_operand:SI 0 "register_operand" "")
16901 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16902 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16903 "TARGET_64BIT
16904 && peep2_regno_dead_p (0, FLAGS_REG)
16905 && REGNO (operands[0]) == REGNO (operands[1])"
16906 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16907 (clobber (reg:CC FLAGS_REG))])]
16908 "operands[2] = gen_lowpart (SImode, operands[2]);")
16909
16910 (define_peephole2
16911 [(set (match_operand:SWI48 0 "register_operand" "")
16912 (mult:SWI48 (match_dup 0)
16913 (match_operand:SWI48 1 "const_int_operand" "")))]
16914 "exact_log2 (INTVAL (operands[1])) >= 0
16915 && peep2_regno_dead_p (0, FLAGS_REG)"
16916 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16917 (clobber (reg:CC FLAGS_REG))])]
16918 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16919
16920 (define_peephole2
16921 [(set (match_operand:SI 0 "register_operand" "")
16922 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16923 (match_operand:DI 2 "const_int_operand" "")) 0))]
16924 "TARGET_64BIT
16925 && exact_log2 (INTVAL (operands[2])) >= 0
16926 && REGNO (operands[0]) == REGNO (operands[1])
16927 && peep2_regno_dead_p (0, FLAGS_REG)"
16928 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16929 (clobber (reg:CC FLAGS_REG))])]
16930 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16931
16932 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16933 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16934 ;; On many CPUs it is also faster, since special hardware to avoid esp
16935 ;; dependencies is present.
16936
16937 ;; While some of these conversions may be done using splitters, we use
16938 ;; peepholes in order to allow combine_stack_adjustments pass to see
16939 ;; nonobfuscated RTL.
16940
16941 ;; Convert prologue esp subtractions to push.
16942 ;; We need register to push. In order to keep verify_flow_info happy we have
16943 ;; two choices
16944 ;; - use scratch and clobber it in order to avoid dependencies
16945 ;; - use already live register
16946 ;; We can't use the second way right now, since there is no reliable way how to
16947 ;; verify that given register is live. First choice will also most likely in
16948 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16949 ;; call clobbered registers are dead. We may want to use base pointer as an
16950 ;; alternative when no register is available later.
16951
16952 (define_peephole2
16953 [(match_scratch:P 1 "r")
16954 (parallel [(set (reg:P SP_REG)
16955 (plus:P (reg:P SP_REG)
16956 (match_operand:P 0 "const_int_operand" "")))
16957 (clobber (reg:CC FLAGS_REG))
16958 (clobber (mem:BLK (scratch)))])]
16959 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16960 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16961 [(clobber (match_dup 1))
16962 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16963 (clobber (mem:BLK (scratch)))])])
16964
16965 (define_peephole2
16966 [(match_scratch:P 1 "r")
16967 (parallel [(set (reg:P SP_REG)
16968 (plus:P (reg:P SP_REG)
16969 (match_operand:P 0 "const_int_operand" "")))
16970 (clobber (reg:CC FLAGS_REG))
16971 (clobber (mem:BLK (scratch)))])]
16972 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16973 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16974 [(clobber (match_dup 1))
16975 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16976 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16977 (clobber (mem:BLK (scratch)))])])
16978
16979 ;; Convert esp subtractions to push.
16980 (define_peephole2
16981 [(match_scratch:P 1 "r")
16982 (parallel [(set (reg:P SP_REG)
16983 (plus:P (reg:P SP_REG)
16984 (match_operand:P 0 "const_int_operand" "")))
16985 (clobber (reg:CC FLAGS_REG))])]
16986 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16987 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16988 [(clobber (match_dup 1))
16989 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16990
16991 (define_peephole2
16992 [(match_scratch:P 1 "r")
16993 (parallel [(set (reg:P SP_REG)
16994 (plus:P (reg:P SP_REG)
16995 (match_operand:P 0 "const_int_operand" "")))
16996 (clobber (reg:CC FLAGS_REG))])]
16997 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16998 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16999 [(clobber (match_dup 1))
17000 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17001 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17002
17003 ;; Convert epilogue deallocator to pop.
17004 (define_peephole2
17005 [(match_scratch:P 1 "r")
17006 (parallel [(set (reg:P SP_REG)
17007 (plus:P (reg:P SP_REG)
17008 (match_operand:P 0 "const_int_operand" "")))
17009 (clobber (reg:CC FLAGS_REG))
17010 (clobber (mem:BLK (scratch)))])]
17011 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17012 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17013 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17014 (clobber (mem:BLK (scratch)))])])
17015
17016 ;; Two pops case is tricky, since pop causes dependency
17017 ;; on destination register. We use two registers if available.
17018 (define_peephole2
17019 [(match_scratch:P 1 "r")
17020 (match_scratch:P 2 "r")
17021 (parallel [(set (reg:P SP_REG)
17022 (plus:P (reg:P SP_REG)
17023 (match_operand:P 0 "const_int_operand" "")))
17024 (clobber (reg:CC FLAGS_REG))
17025 (clobber (mem:BLK (scratch)))])]
17026 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17027 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17028 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17029 (clobber (mem:BLK (scratch)))])
17030 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17031
17032 (define_peephole2
17033 [(match_scratch:P 1 "r")
17034 (parallel [(set (reg:P SP_REG)
17035 (plus:P (reg:P SP_REG)
17036 (match_operand:P 0 "const_int_operand" "")))
17037 (clobber (reg:CC FLAGS_REG))
17038 (clobber (mem:BLK (scratch)))])]
17039 "optimize_insn_for_size_p ()
17040 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17041 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17042 (clobber (mem:BLK (scratch)))])
17043 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17044
17045 ;; Convert esp additions to pop.
17046 (define_peephole2
17047 [(match_scratch:P 1 "r")
17048 (parallel [(set (reg:P SP_REG)
17049 (plus:P (reg:P SP_REG)
17050 (match_operand:P 0 "const_int_operand" "")))
17051 (clobber (reg:CC FLAGS_REG))])]
17052 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17053 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17054
17055 ;; Two pops case is tricky, since pop causes dependency
17056 ;; on destination register. We use two registers if available.
17057 (define_peephole2
17058 [(match_scratch:P 1 "r")
17059 (match_scratch:P 2 "r")
17060 (parallel [(set (reg:P SP_REG)
17061 (plus:P (reg:P SP_REG)
17062 (match_operand:P 0 "const_int_operand" "")))
17063 (clobber (reg:CC FLAGS_REG))])]
17064 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17065 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17066 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17067
17068 (define_peephole2
17069 [(match_scratch:P 1 "r")
17070 (parallel [(set (reg:P SP_REG)
17071 (plus:P (reg:P SP_REG)
17072 (match_operand:P 0 "const_int_operand" "")))
17073 (clobber (reg:CC FLAGS_REG))])]
17074 "optimize_insn_for_size_p ()
17075 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17076 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17077 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17078 \f
17079 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17080 ;; required and register dies. Similarly for 128 to -128.
17081 (define_peephole2
17082 [(set (match_operand 0 "flags_reg_operand" "")
17083 (match_operator 1 "compare_operator"
17084 [(match_operand 2 "register_operand" "")
17085 (match_operand 3 "const_int_operand" "")]))]
17086 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17087 && incdec_operand (operands[3], GET_MODE (operands[3])))
17088 || (!TARGET_FUSE_CMP_AND_BRANCH
17089 && INTVAL (operands[3]) == 128))
17090 && ix86_match_ccmode (insn, CCGCmode)
17091 && peep2_reg_dead_p (1, operands[2])"
17092 [(parallel [(set (match_dup 0)
17093 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17094 (clobber (match_dup 2))])])
17095 \f
17096 ;; Convert imul by three, five and nine into lea
17097 (define_peephole2
17098 [(parallel
17099 [(set (match_operand:SWI48 0 "register_operand" "")
17100 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17101 (match_operand:SWI48 2 "const_int_operand" "")))
17102 (clobber (reg:CC FLAGS_REG))])]
17103 "INTVAL (operands[2]) == 3
17104 || INTVAL (operands[2]) == 5
17105 || INTVAL (operands[2]) == 9"
17106 [(set (match_dup 0)
17107 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17108 (match_dup 1)))]
17109 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17110
17111 (define_peephole2
17112 [(parallel
17113 [(set (match_operand:SWI48 0 "register_operand" "")
17114 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17115 (match_operand:SWI48 2 "const_int_operand" "")))
17116 (clobber (reg:CC FLAGS_REG))])]
17117 "optimize_insn_for_speed_p ()
17118 && (INTVAL (operands[2]) == 3
17119 || INTVAL (operands[2]) == 5
17120 || INTVAL (operands[2]) == 9)"
17121 [(set (match_dup 0) (match_dup 1))
17122 (set (match_dup 0)
17123 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17124 (match_dup 0)))]
17125 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17126
17127 ;; imul $32bit_imm, mem, reg is vector decoded, while
17128 ;; imul $32bit_imm, reg, reg is direct decoded.
17129 (define_peephole2
17130 [(match_scratch:SWI48 3 "r")
17131 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17132 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17133 (match_operand:SWI48 2 "immediate_operand" "")))
17134 (clobber (reg:CC FLAGS_REG))])]
17135 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17136 && !satisfies_constraint_K (operands[2])"
17137 [(set (match_dup 3) (match_dup 1))
17138 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17139 (clobber (reg:CC FLAGS_REG))])])
17140
17141 (define_peephole2
17142 [(match_scratch:SI 3 "r")
17143 (parallel [(set (match_operand:DI 0 "register_operand" "")
17144 (zero_extend:DI
17145 (mult:SI (match_operand:SI 1 "memory_operand" "")
17146 (match_operand:SI 2 "immediate_operand" ""))))
17147 (clobber (reg:CC FLAGS_REG))])]
17148 "TARGET_64BIT
17149 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17150 && !satisfies_constraint_K (operands[2])"
17151 [(set (match_dup 3) (match_dup 1))
17152 (parallel [(set (match_dup 0)
17153 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17154 (clobber (reg:CC FLAGS_REG))])])
17155
17156 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17157 ;; Convert it into imul reg, reg
17158 ;; It would be better to force assembler to encode instruction using long
17159 ;; immediate, but there is apparently no way to do so.
17160 (define_peephole2
17161 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17162 (mult:SWI248
17163 (match_operand:SWI248 1 "nonimmediate_operand" "")
17164 (match_operand:SWI248 2 "const_int_operand" "")))
17165 (clobber (reg:CC FLAGS_REG))])
17166 (match_scratch:SWI248 3 "r")]
17167 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17168 && satisfies_constraint_K (operands[2])"
17169 [(set (match_dup 3) (match_dup 2))
17170 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17171 (clobber (reg:CC FLAGS_REG))])]
17172 {
17173 if (!rtx_equal_p (operands[0], operands[1]))
17174 emit_move_insn (operands[0], operands[1]);
17175 })
17176
17177 ;; After splitting up read-modify operations, array accesses with memory
17178 ;; operands might end up in form:
17179 ;; sall $2, %eax
17180 ;; movl 4(%esp), %edx
17181 ;; addl %edx, %eax
17182 ;; instead of pre-splitting:
17183 ;; sall $2, %eax
17184 ;; addl 4(%esp), %eax
17185 ;; Turn it into:
17186 ;; movl 4(%esp), %edx
17187 ;; leal (%edx,%eax,4), %eax
17188
17189 (define_peephole2
17190 [(match_scratch:P 5 "r")
17191 (parallel [(set (match_operand 0 "register_operand" "")
17192 (ashift (match_operand 1 "register_operand" "")
17193 (match_operand 2 "const_int_operand" "")))
17194 (clobber (reg:CC FLAGS_REG))])
17195 (parallel [(set (match_operand 3 "register_operand" "")
17196 (plus (match_dup 0)
17197 (match_operand 4 "x86_64_general_operand" "")))
17198 (clobber (reg:CC FLAGS_REG))])]
17199 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17200 /* Validate MODE for lea. */
17201 && ((!TARGET_PARTIAL_REG_STALL
17202 && (GET_MODE (operands[0]) == QImode
17203 || GET_MODE (operands[0]) == HImode))
17204 || GET_MODE (operands[0]) == SImode
17205 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17206 && (rtx_equal_p (operands[0], operands[3])
17207 || peep2_reg_dead_p (2, operands[0]))
17208 /* We reorder load and the shift. */
17209 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17210 [(set (match_dup 5) (match_dup 4))
17211 (set (match_dup 0) (match_dup 1))]
17212 {
17213 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17214 int scale = 1 << INTVAL (operands[2]);
17215 rtx index = gen_lowpart (Pmode, operands[1]);
17216 rtx base = gen_lowpart (Pmode, operands[5]);
17217 rtx dest = gen_lowpart (mode, operands[3]);
17218
17219 operands[1] = gen_rtx_PLUS (Pmode, base,
17220 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17221 operands[5] = base;
17222 if (mode != Pmode)
17223 {
17224 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17225 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17226 }
17227 operands[0] = dest;
17228 })
17229 \f
17230 ;; Call-value patterns last so that the wildcard operand does not
17231 ;; disrupt insn-recog's switch tables.
17232
17233 (define_insn "*call_value_pop_0"
17234 [(set (match_operand 0 "" "")
17235 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17236 (match_operand:SI 2 "" "")))
17237 (set (reg:SI SP_REG)
17238 (plus:SI (reg:SI SP_REG)
17239 (match_operand:SI 3 "immediate_operand" "")))]
17240 "!TARGET_64BIT"
17241 {
17242 if (SIBLING_CALL_P (insn))
17243 return "jmp\t%P1";
17244 else
17245 return "call\t%P1";
17246 }
17247 [(set_attr "type" "callv")])
17248
17249 (define_insn "*call_value_pop_1"
17250 [(set (match_operand 0 "" "")
17251 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17252 (match_operand:SI 2 "" "")))
17253 (set (reg:SI SP_REG)
17254 (plus:SI (reg:SI SP_REG)
17255 (match_operand:SI 3 "immediate_operand" "i")))]
17256 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17257 {
17258 if (constant_call_address_operand (operands[1], Pmode))
17259 return "call\t%P1";
17260 return "call\t%A1";
17261 }
17262 [(set_attr "type" "callv")])
17263
17264 (define_insn "*sibcall_value_pop_1"
17265 [(set (match_operand 0 "" "")
17266 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17267 (match_operand:SI 2 "" "")))
17268 (set (reg:SI SP_REG)
17269 (plus:SI (reg:SI SP_REG)
17270 (match_operand:SI 3 "immediate_operand" "i,i")))]
17271 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17272 "@
17273 jmp\t%P1
17274 jmp\t%A1"
17275 [(set_attr "type" "callv")])
17276
17277 (define_insn "*call_value_0"
17278 [(set (match_operand 0 "" "")
17279 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17280 (match_operand:SI 2 "" "")))]
17281 "!TARGET_64BIT"
17282 {
17283 if (SIBLING_CALL_P (insn))
17284 return "jmp\t%P1";
17285 else
17286 return "call\t%P1";
17287 }
17288 [(set_attr "type" "callv")])
17289
17290 (define_insn "*call_value_0_rex64"
17291 [(set (match_operand 0 "" "")
17292 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17293 (match_operand:DI 2 "const_int_operand" "")))]
17294 "TARGET_64BIT"
17295 {
17296 if (SIBLING_CALL_P (insn))
17297 return "jmp\t%P1";
17298 else
17299 return "call\t%P1";
17300 }
17301 [(set_attr "type" "callv")])
17302
17303 (define_insn "*call_value_0_rex64_ms_sysv"
17304 [(set (match_operand 0 "" "")
17305 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17306 (match_operand:DI 2 "const_int_operand" "")))
17307 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17308 (clobber (reg:TI XMM6_REG))
17309 (clobber (reg:TI XMM7_REG))
17310 (clobber (reg:TI XMM8_REG))
17311 (clobber (reg:TI XMM9_REG))
17312 (clobber (reg:TI XMM10_REG))
17313 (clobber (reg:TI XMM11_REG))
17314 (clobber (reg:TI XMM12_REG))
17315 (clobber (reg:TI XMM13_REG))
17316 (clobber (reg:TI XMM14_REG))
17317 (clobber (reg:TI XMM15_REG))
17318 (clobber (reg:DI SI_REG))
17319 (clobber (reg:DI DI_REG))]
17320 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17321 {
17322 if (SIBLING_CALL_P (insn))
17323 return "jmp\t%P1";
17324 else
17325 return "call\t%P1";
17326 }
17327 [(set_attr "type" "callv")])
17328
17329 (define_insn "*call_value_1"
17330 [(set (match_operand 0 "" "")
17331 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17332 (match_operand:SI 2 "" "")))]
17333 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17334 {
17335 if (constant_call_address_operand (operands[1], Pmode))
17336 return "call\t%P1";
17337 return "call\t%A1";
17338 }
17339 [(set_attr "type" "callv")])
17340
17341 (define_insn "*sibcall_value_1"
17342 [(set (match_operand 0 "" "")
17343 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17344 (match_operand:SI 2 "" "")))]
17345 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17346 "@
17347 jmp\t%P1
17348 jmp\t%A1"
17349 [(set_attr "type" "callv")])
17350
17351 (define_insn "*call_value_1_rex64"
17352 [(set (match_operand 0 "" "")
17353 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17354 (match_operand:DI 2 "" "")))]
17355 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17356 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17357 {
17358 if (constant_call_address_operand (operands[1], Pmode))
17359 return "call\t%P1";
17360 return "call\t%A1";
17361 }
17362 [(set_attr "type" "callv")])
17363
17364 (define_insn "*call_value_1_rex64_ms_sysv"
17365 [(set (match_operand 0 "" "")
17366 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17367 (match_operand:DI 2 "" "")))
17368 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17369 (clobber (reg:TI XMM6_REG))
17370 (clobber (reg:TI XMM7_REG))
17371 (clobber (reg:TI XMM8_REG))
17372 (clobber (reg:TI XMM9_REG))
17373 (clobber (reg:TI XMM10_REG))
17374 (clobber (reg:TI XMM11_REG))
17375 (clobber (reg:TI XMM12_REG))
17376 (clobber (reg:TI XMM13_REG))
17377 (clobber (reg:TI XMM14_REG))
17378 (clobber (reg:TI XMM15_REG))
17379 (clobber (reg:DI SI_REG))
17380 (clobber (reg:DI DI_REG))]
17381 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17382 {
17383 if (constant_call_address_operand (operands[1], Pmode))
17384 return "call\t%P1";
17385 return "call\t%A1";
17386 }
17387 [(set_attr "type" "callv")])
17388
17389 (define_insn "*call_value_1_rex64_large"
17390 [(set (match_operand 0 "" "")
17391 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17392 (match_operand:DI 2 "" "")))]
17393 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17394 "call\t%A1"
17395 [(set_attr "type" "callv")])
17396
17397 (define_insn "*sibcall_value_1_rex64"
17398 [(set (match_operand 0 "" "")
17399 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17400 (match_operand:DI 2 "" "")))]
17401 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17402 "@
17403 jmp\t%P1
17404 jmp\t%A1"
17405 [(set_attr "type" "callv")])
17406 \f
17407 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17408 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17409 ;; caught for use by garbage collectors and the like. Using an insn that
17410 ;; maps to SIGILL makes it more likely the program will rightfully die.
17411 ;; Keeping with tradition, "6" is in honor of #UD.
17412 (define_insn "trap"
17413 [(trap_if (const_int 1) (const_int 6))]
17414 ""
17415 { return ASM_SHORT "0x0b0f"; }
17416 [(set_attr "length" "2")])
17417
17418 (define_expand "prefetch"
17419 [(prefetch (match_operand 0 "address_operand" "")
17420 (match_operand:SI 1 "const_int_operand" "")
17421 (match_operand:SI 2 "const_int_operand" ""))]
17422 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17423 {
17424 int rw = INTVAL (operands[1]);
17425 int locality = INTVAL (operands[2]);
17426
17427 gcc_assert (rw == 0 || rw == 1);
17428 gcc_assert (locality >= 0 && locality <= 3);
17429 gcc_assert (GET_MODE (operands[0]) == Pmode
17430 || GET_MODE (operands[0]) == VOIDmode);
17431
17432 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17433 supported by SSE counterpart or the SSE prefetch is not available
17434 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17435 of locality. */
17436 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17437 operands[2] = GEN_INT (3);
17438 else
17439 operands[1] = const0_rtx;
17440 })
17441
17442 (define_insn "*prefetch_sse_<mode>"
17443 [(prefetch (match_operand:P 0 "address_operand" "p")
17444 (const_int 0)
17445 (match_operand:SI 1 "const_int_operand" ""))]
17446 "TARGET_PREFETCH_SSE"
17447 {
17448 static const char * const patterns[4] = {
17449 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17450 };
17451
17452 int locality = INTVAL (operands[1]);
17453 gcc_assert (locality >= 0 && locality <= 3);
17454
17455 return patterns[locality];
17456 }
17457 [(set_attr "type" "sse")
17458 (set_attr "atom_sse_attr" "prefetch")
17459 (set (attr "length_address")
17460 (symbol_ref "memory_address_length (operands[0])"))
17461 (set_attr "memory" "none")])
17462
17463 (define_insn "*prefetch_3dnow_<mode>"
17464 [(prefetch (match_operand:P 0 "address_operand" "p")
17465 (match_operand:SI 1 "const_int_operand" "n")
17466 (const_int 3))]
17467 "TARGET_3DNOW"
17468 {
17469 if (INTVAL (operands[1]) == 0)
17470 return "prefetch\t%a0";
17471 else
17472 return "prefetchw\t%a0";
17473 }
17474 [(set_attr "type" "mmx")
17475 (set (attr "length_address")
17476 (symbol_ref "memory_address_length (operands[0])"))
17477 (set_attr "memory" "none")])
17478
17479 (define_expand "stack_protect_set"
17480 [(match_operand 0 "memory_operand" "")
17481 (match_operand 1 "memory_operand" "")]
17482 ""
17483 {
17484 rtx (*insn)(rtx, rtx);
17485
17486 #ifdef TARGET_THREAD_SSP_OFFSET
17487 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17488 insn = (TARGET_64BIT
17489 ? gen_stack_tls_protect_set_di
17490 : gen_stack_tls_protect_set_si);
17491 #else
17492 insn = (TARGET_64BIT
17493 ? gen_stack_protect_set_di
17494 : gen_stack_protect_set_si);
17495 #endif
17496
17497 emit_insn (insn (operands[0], operands[1]));
17498 DONE;
17499 })
17500
17501 (define_insn "stack_protect_set_<mode>"
17502 [(set (match_operand:P 0 "memory_operand" "=m")
17503 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17504 (set (match_scratch:P 2 "=&r") (const_int 0))
17505 (clobber (reg:CC FLAGS_REG))]
17506 ""
17507 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17508 [(set_attr "type" "multi")])
17509
17510 (define_insn "stack_tls_protect_set_<mode>"
17511 [(set (match_operand:P 0 "memory_operand" "=m")
17512 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17513 UNSPEC_SP_TLS_SET))
17514 (set (match_scratch:P 2 "=&r") (const_int 0))
17515 (clobber (reg:CC FLAGS_REG))]
17516 ""
17517 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17518 [(set_attr "type" "multi")])
17519
17520 (define_expand "stack_protect_test"
17521 [(match_operand 0 "memory_operand" "")
17522 (match_operand 1 "memory_operand" "")
17523 (match_operand 2 "" "")]
17524 ""
17525 {
17526 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17527
17528 rtx (*insn)(rtx, rtx, rtx);
17529
17530 #ifdef TARGET_THREAD_SSP_OFFSET
17531 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17532 insn = (TARGET_64BIT
17533 ? gen_stack_tls_protect_test_di
17534 : gen_stack_tls_protect_test_si);
17535 #else
17536 insn = (TARGET_64BIT
17537 ? gen_stack_protect_test_di
17538 : gen_stack_protect_test_si);
17539 #endif
17540
17541 emit_insn (insn (flags, operands[0], operands[1]));
17542
17543 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17544 flags, const0_rtx, operands[2]));
17545 DONE;
17546 })
17547
17548 (define_insn "stack_protect_test_<mode>"
17549 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17550 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17551 (match_operand:P 2 "memory_operand" "m")]
17552 UNSPEC_SP_TEST))
17553 (clobber (match_scratch:P 3 "=&r"))]
17554 ""
17555 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17556 [(set_attr "type" "multi")])
17557
17558 (define_insn "stack_tls_protect_test_<mode>"
17559 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17560 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17561 (match_operand:P 2 "const_int_operand" "i")]
17562 UNSPEC_SP_TLS_TEST))
17563 (clobber (match_scratch:P 3 "=r"))]
17564 ""
17565 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17566 [(set_attr "type" "multi")])
17567
17568 (define_insn "sse4_2_crc32<mode>"
17569 [(set (match_operand:SI 0 "register_operand" "=r")
17570 (unspec:SI
17571 [(match_operand:SI 1 "register_operand" "0")
17572 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17573 UNSPEC_CRC32))]
17574 "TARGET_SSE4_2 || TARGET_CRC32"
17575 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17576 [(set_attr "type" "sselog1")
17577 (set_attr "prefix_rep" "1")
17578 (set_attr "prefix_extra" "1")
17579 (set (attr "prefix_data16")
17580 (if_then_else (match_operand:HI 2 "" "")
17581 (const_string "1")
17582 (const_string "*")))
17583 (set (attr "prefix_rex")
17584 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17585 (const_string "1")
17586 (const_string "*")))
17587 (set_attr "mode" "SI")])
17588
17589 (define_insn "sse4_2_crc32di"
17590 [(set (match_operand:DI 0 "register_operand" "=r")
17591 (unspec:DI
17592 [(match_operand:DI 1 "register_operand" "0")
17593 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17594 UNSPEC_CRC32))]
17595 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17596 "crc32{q}\t{%2, %0|%0, %2}"
17597 [(set_attr "type" "sselog1")
17598 (set_attr "prefix_rep" "1")
17599 (set_attr "prefix_extra" "1")
17600 (set_attr "mode" "DI")])
17601
17602 (define_expand "rdpmc"
17603 [(match_operand:DI 0 "register_operand" "")
17604 (match_operand:SI 1 "register_operand" "")]
17605 ""
17606 {
17607 rtx reg = gen_reg_rtx (DImode);
17608 rtx si;
17609
17610 /* Force operand 1 into ECX. */
17611 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17612 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17613 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17614 UNSPECV_RDPMC);
17615
17616 if (TARGET_64BIT)
17617 {
17618 rtvec vec = rtvec_alloc (2);
17619 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17620 rtx upper = gen_reg_rtx (DImode);
17621 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17622 gen_rtvec (1, const0_rtx),
17623 UNSPECV_RDPMC);
17624 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17625 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17626 emit_insn (load);
17627 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17628 NULL, 1, OPTAB_DIRECT);
17629 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17630 OPTAB_DIRECT);
17631 }
17632 else
17633 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17634 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17635 DONE;
17636 })
17637
17638 (define_insn "*rdpmc"
17639 [(set (match_operand:DI 0 "register_operand" "=A")
17640 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17641 UNSPECV_RDPMC))]
17642 "!TARGET_64BIT"
17643 "rdpmc"
17644 [(set_attr "type" "other")
17645 (set_attr "length" "2")])
17646
17647 (define_insn "*rdpmc_rex64"
17648 [(set (match_operand:DI 0 "register_operand" "=a")
17649 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17650 UNSPECV_RDPMC))
17651 (set (match_operand:DI 1 "register_operand" "=d")
17652 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17653 "TARGET_64BIT"
17654 "rdpmc"
17655 [(set_attr "type" "other")
17656 (set_attr "length" "2")])
17657
17658 (define_expand "rdtsc"
17659 [(set (match_operand:DI 0 "register_operand" "")
17660 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17661 ""
17662 {
17663 if (TARGET_64BIT)
17664 {
17665 rtvec vec = rtvec_alloc (2);
17666 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17667 rtx upper = gen_reg_rtx (DImode);
17668 rtx lower = gen_reg_rtx (DImode);
17669 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17670 gen_rtvec (1, const0_rtx),
17671 UNSPECV_RDTSC);
17672 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17673 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17674 emit_insn (load);
17675 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17676 NULL, 1, OPTAB_DIRECT);
17677 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17678 OPTAB_DIRECT);
17679 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17680 DONE;
17681 }
17682 })
17683
17684 (define_insn "*rdtsc"
17685 [(set (match_operand:DI 0 "register_operand" "=A")
17686 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17687 "!TARGET_64BIT"
17688 "rdtsc"
17689 [(set_attr "type" "other")
17690 (set_attr "length" "2")])
17691
17692 (define_insn "*rdtsc_rex64"
17693 [(set (match_operand:DI 0 "register_operand" "=a")
17694 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17695 (set (match_operand:DI 1 "register_operand" "=d")
17696 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17697 "TARGET_64BIT"
17698 "rdtsc"
17699 [(set_attr "type" "other")
17700 (set_attr "length" "2")])
17701
17702 (define_expand "rdtscp"
17703 [(match_operand:DI 0 "register_operand" "")
17704 (match_operand:SI 1 "memory_operand" "")]
17705 ""
17706 {
17707 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17708 gen_rtvec (1, const0_rtx),
17709 UNSPECV_RDTSCP);
17710 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17711 gen_rtvec (1, const0_rtx),
17712 UNSPECV_RDTSCP);
17713 rtx reg = gen_reg_rtx (DImode);
17714 rtx tmp = gen_reg_rtx (SImode);
17715
17716 if (TARGET_64BIT)
17717 {
17718 rtvec vec = rtvec_alloc (3);
17719 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17720 rtx upper = gen_reg_rtx (DImode);
17721 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17722 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17723 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17724 emit_insn (load);
17725 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17726 NULL, 1, OPTAB_DIRECT);
17727 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17728 OPTAB_DIRECT);
17729 }
17730 else
17731 {
17732 rtvec vec = rtvec_alloc (2);
17733 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17734 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17735 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17736 emit_insn (load);
17737 }
17738 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17739 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17740 DONE;
17741 })
17742
17743 (define_insn "*rdtscp"
17744 [(set (match_operand:DI 0 "register_operand" "=A")
17745 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17746 (set (match_operand:SI 1 "register_operand" "=c")
17747 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17748 "!TARGET_64BIT"
17749 "rdtscp"
17750 [(set_attr "type" "other")
17751 (set_attr "length" "3")])
17752
17753 (define_insn "*rdtscp_rex64"
17754 [(set (match_operand:DI 0 "register_operand" "=a")
17755 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17756 (set (match_operand:DI 1 "register_operand" "=d")
17757 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17758 (set (match_operand:SI 2 "register_operand" "=c")
17759 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17760 "TARGET_64BIT"
17761 "rdtscp"
17762 [(set_attr "type" "other")
17763 (set_attr "length" "3")])
17764
17765 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17766 ;;
17767 ;; LWP instructions
17768 ;;
17769 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17770
17771 (define_expand "lwp_llwpcb"
17772 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17773 UNSPECV_LLWP_INTRINSIC)]
17774 "TARGET_LWP")
17775
17776 (define_insn "*lwp_llwpcb<mode>1"
17777 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17778 UNSPECV_LLWP_INTRINSIC)]
17779 "TARGET_LWP"
17780 "llwpcb\t%0"
17781 [(set_attr "type" "lwp")
17782 (set_attr "mode" "<MODE>")
17783 (set_attr "length" "5")])
17784
17785 (define_expand "lwp_slwpcb"
17786 [(set (match_operand 0 "register_operand" "=r")
17787 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17788 "TARGET_LWP"
17789 {
17790 if (TARGET_64BIT)
17791 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17792 else
17793 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17794 DONE;
17795 })
17796
17797 (define_insn "lwp_slwpcb<mode>"
17798 [(set (match_operand:P 0 "register_operand" "=r")
17799 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17800 "TARGET_LWP"
17801 "slwpcb\t%0"
17802 [(set_attr "type" "lwp")
17803 (set_attr "mode" "<MODE>")
17804 (set_attr "length" "5")])
17805
17806 (define_expand "lwp_lwpval<mode>3"
17807 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17808 (match_operand:SI 2 "nonimmediate_operand" "rm")
17809 (match_operand:SI 3 "const_int_operand" "i")]
17810 UNSPECV_LWPVAL_INTRINSIC)]
17811 "TARGET_LWP"
17812 "/* Avoid unused variable warning. */
17813 (void) operand0;")
17814
17815 (define_insn "*lwp_lwpval<mode>3_1"
17816 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17817 (match_operand:SI 1 "nonimmediate_operand" "rm")
17818 (match_operand:SI 2 "const_int_operand" "i")]
17819 UNSPECV_LWPVAL_INTRINSIC)]
17820 "TARGET_LWP"
17821 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17822 [(set_attr "type" "lwp")
17823 (set_attr "mode" "<MODE>")
17824 (set (attr "length")
17825 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17826
17827 (define_expand "lwp_lwpins<mode>3"
17828 [(set (reg:CCC FLAGS_REG)
17829 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17830 (match_operand:SI 2 "nonimmediate_operand" "rm")
17831 (match_operand:SI 3 "const_int_operand" "i")]
17832 UNSPECV_LWPINS_INTRINSIC))
17833 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17834 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17835 "TARGET_LWP")
17836
17837 (define_insn "*lwp_lwpins<mode>3_1"
17838 [(set (reg:CCC FLAGS_REG)
17839 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17840 (match_operand:SI 1 "nonimmediate_operand" "rm")
17841 (match_operand:SI 2 "const_int_operand" "i")]
17842 UNSPECV_LWPINS_INTRINSIC))]
17843 "TARGET_LWP"
17844 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17845 [(set_attr "type" "lwp")
17846 (set_attr "mode" "<MODE>")
17847 (set (attr "length")
17848 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17849
17850 (define_insn "rdfsbase<mode>"
17851 [(set (match_operand:SWI48 0 "register_operand" "=r")
17852 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17853 "TARGET_64BIT && TARGET_FSGSBASE"
17854 "rdfsbase %0"
17855 [(set_attr "type" "other")
17856 (set_attr "prefix_extra" "2")])
17857
17858 (define_insn "rdgsbase<mode>"
17859 [(set (match_operand:SWI48 0 "register_operand" "=r")
17860 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17861 "TARGET_64BIT && TARGET_FSGSBASE"
17862 "rdgsbase %0"
17863 [(set_attr "type" "other")
17864 (set_attr "prefix_extra" "2")])
17865
17866 (define_insn "wrfsbase<mode>"
17867 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17868 UNSPECV_WRFSBASE)]
17869 "TARGET_64BIT && TARGET_FSGSBASE"
17870 "wrfsbase %0"
17871 [(set_attr "type" "other")
17872 (set_attr "prefix_extra" "2")])
17873
17874 (define_insn "wrgsbase<mode>"
17875 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17876 UNSPECV_WRGSBASE)]
17877 "TARGET_64BIT && TARGET_FSGSBASE"
17878 "wrgsbase %0"
17879 [(set_attr "type" "other")
17880 (set_attr "prefix_extra" "2")])
17881
17882 (define_expand "rdrand<mode>"
17883 [(set (match_operand:SWI248 0 "register_operand" "=r")
17884 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17885 "TARGET_RDRND"
17886 {
17887 rtx retry_label, insn, ccc;
17888
17889 retry_label = gen_label_rtx ();
17890
17891 emit_label (retry_label);
17892
17893 /* Generate rdrand. */
17894 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17895
17896 /* Retry if the carry flag isn't valid. */
17897 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17898 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17899 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17900 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17901 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17902 JUMP_LABEL (insn) = retry_label;
17903
17904 DONE;
17905 })
17906
17907 (define_insn "rdrand<mode>_1"
17908 [(set (match_operand:SWI248 0 "register_operand" "=r")
17909 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17910 "TARGET_RDRND"
17911 "rdrand %0"
17912 [(set_attr "type" "other")
17913 (set_attr "prefix_extra" "1")])
17914
17915 (include "mmx.md")
17916 (include "sse.md")
17917 (include "sync.md")