]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
i386.md (unnamed peephole2): Do not force memory operands of arith or logical instruc...
[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
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 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;; operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50 [; Relocation specifiers
51 (UNSPEC_GOT 0)
52 (UNSPEC_GOTOFF 1)
53 (UNSPEC_GOTPCREL 2)
54 (UNSPEC_GOTTPOFF 3)
55 (UNSPEC_TPOFF 4)
56 (UNSPEC_NTPOFF 5)
57 (UNSPEC_DTPOFF 6)
58 (UNSPEC_GOTNTPOFF 7)
59 (UNSPEC_INDNTPOFF 8)
60 (UNSPEC_PLTOFF 9)
61 (UNSPEC_MACHOPIC_OFFSET 10)
62
63 ; Prologue support
64 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SET_GOT 12)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
67 (UNSPEC_REG_SAVE 14)
68 (UNSPEC_DEF_CFA 15)
69 (UNSPEC_SET_RIP 16)
70 (UNSPEC_SET_GOT_OFFSET 17)
71
72 ; TLS support
73 (UNSPEC_TP 18)
74 (UNSPEC_TLS_GD 19)
75 (UNSPEC_TLS_LD_BASE 20)
76 (UNSPEC_TLSDESC 21)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 30)
80 (UNSPEC_FNSTSW 31)
81 (UNSPEC_SAHF 32)
82 (UNSPEC_FSTCW 33)
83 (UNSPEC_ADD_CARRY 34)
84 (UNSPEC_FLDCW 35)
85 (UNSPEC_REP 36)
86 (UNSPEC_EH_RETURN 37)
87 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 39)
89
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 40)
92 (UNSPEC_MASKMOV 41)
93 (UNSPEC_MOVMSK 42)
94 (UNSPEC_MOVNT 43)
95 (UNSPEC_MOVU 44)
96 (UNSPEC_RCP 45)
97 (UNSPEC_RSQRT 46)
98 (UNSPEC_SFENCE 47)
99 (UNSPEC_PFRCP 49)
100 (UNSPEC_PFRCPIT1 40)
101 (UNSPEC_PFRCPIT2 41)
102 (UNSPEC_PFRSQRT 42)
103 (UNSPEC_PFRSQIT1 43)
104 (UNSPEC_MFENCE 44)
105 (UNSPEC_LFENCE 45)
106 (UNSPEC_PSADBW 46)
107 (UNSPEC_LDDQU 47)
108
109 ; Generic math support
110 (UNSPEC_COPYSIGN 50)
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
113
114 ; x87 Floating point
115 (UNSPEC_SIN 60)
116 (UNSPEC_COS 61)
117 (UNSPEC_FPATAN 62)
118 (UNSPEC_FYL2X 63)
119 (UNSPEC_FYL2XP1 64)
120 (UNSPEC_FRNDINT 65)
121 (UNSPEC_FIST 66)
122 (UNSPEC_F2XM1 67)
123 (UNSPEC_TAN 68)
124 (UNSPEC_FXAM 69)
125
126 ; x87 Rounding
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
133
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
141 (UNSPEC_FPREM_F 88)
142 (UNSPEC_FPREM_U 89)
143 (UNSPEC_FPREM1_F 90)
144 (UNSPEC_FPREM1_U 91)
145
146 (UNSPEC_C2_FLAG 95)
147
148 ; SSP patterns
149 (UNSPEC_SP_SET 100)
150 (UNSPEC_SP_TEST 101)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
153
154 ; SSSE3
155 (UNSPEC_PSHUFB 120)
156 (UNSPEC_PSIGN 121)
157 (UNSPEC_PALIGNR 122)
158
159 ; For SSE4A support
160 (UNSPEC_EXTRQI 130)
161 (UNSPEC_EXTRQ 131)
162 (UNSPEC_INSERTQI 132)
163 (UNSPEC_INSERTQ 133)
164
165 ; For SSE4.1 support
166 (UNSPEC_BLENDV 134)
167 (UNSPEC_INSERTPS 135)
168 (UNSPEC_DP 136)
169 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_MPSADBW 138)
171 (UNSPEC_PHMINPOSUW 139)
172 (UNSPEC_PTEST 140)
173 (UNSPEC_ROUND 141)
174
175 ; For SSE4.2 support
176 (UNSPEC_CRC32 143)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
179
180 ;; For SSE5
181 (UNSPEC_SSE5_INTRINSIC 150)
182 (UNSPEC_SSE5_UNSIGNED_CMP 151)
183 (UNSPEC_SSE5_TRUEFALSE 152)
184 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_FRCZ 154)
186 (UNSPEC_CVTPH2PS 155)
187 (UNSPEC_CVTPS2PH 156)
188
189 ; For AES support
190 (UNSPEC_AESENC 159)
191 (UNSPEC_AESENCLAST 160)
192 (UNSPEC_AESDEC 161)
193 (UNSPEC_AESDECLAST 162)
194 (UNSPEC_AESIMC 163)
195 (UNSPEC_AESKEYGENASSIST 164)
196
197 ; For PCLMUL support
198 (UNSPEC_PCLMUL 165)
199
200 ; For AVX support
201 (UNSPEC_PCMP 166)
202 (UNSPEC_VPERMIL 167)
203 (UNSPEC_VPERMIL2 168)
204 (UNSPEC_VPERMIL2F128 169)
205 (UNSPEC_MASKLOAD 170)
206 (UNSPEC_MASKSTORE 171)
207 (UNSPEC_CAST 172)
208 (UNSPEC_VTESTP 173)
209 ])
210
211 (define_constants
212 [(UNSPECV_BLOCKAGE 0)
213 (UNSPECV_STACK_PROBE 1)
214 (UNSPECV_EMMS 2)
215 (UNSPECV_LDMXCSR 3)
216 (UNSPECV_STMXCSR 4)
217 (UNSPECV_FEMMS 5)
218 (UNSPECV_CLFLUSH 6)
219 (UNSPECV_ALIGN 7)
220 (UNSPECV_MONITOR 8)
221 (UNSPECV_MWAIT 9)
222 (UNSPECV_CMPXCHG_1 10)
223 (UNSPECV_CMPXCHG_2 11)
224 (UNSPECV_XCHG 12)
225 (UNSPECV_LOCK 13)
226 (UNSPECV_PROLOGUE_USE 14)
227 (UNSPECV_CLD 15)
228 (UNSPECV_VZEROALL 16)
229 (UNSPECV_VZEROUPPER 17)
230 ])
231
232 ;; Constants to represent pcomtrue/pcomfalse variants
233 (define_constants
234 [(PCOM_FALSE 0)
235 (PCOM_TRUE 1)
236 (COM_FALSE_S 2)
237 (COM_FALSE_P 3)
238 (COM_TRUE_S 4)
239 (COM_TRUE_P 5)
240 ])
241
242 ;; Constants used in the SSE5 pperm instruction
243 (define_constants
244 [(PPERM_SRC 0x00) /* copy source */
245 (PPERM_INVERT 0x20) /* invert source */
246 (PPERM_REVERSE 0x40) /* bit reverse source */
247 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
248 (PPERM_ZERO 0x80) /* all 0's */
249 (PPERM_ONES 0xa0) /* all 1's */
250 (PPERM_SIGN 0xc0) /* propagate sign bit */
251 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
252 (PPERM_SRC1 0x00) /* use first source byte */
253 (PPERM_SRC2 0x10) /* use second source byte */
254 ])
255
256 ;; Registers by name.
257 (define_constants
258 [(AX_REG 0)
259 (DX_REG 1)
260 (CX_REG 2)
261 (BX_REG 3)
262 (SI_REG 4)
263 (DI_REG 5)
264 (BP_REG 6)
265 (SP_REG 7)
266 (FLAGS_REG 17)
267 (FPSR_REG 18)
268 (FPCR_REG 19)
269 (XMM0_REG 21)
270 (XMM1_REG 22)
271 (XMM2_REG 23)
272 (XMM3_REG 24)
273 (XMM4_REG 25)
274 (XMM5_REG 26)
275 (XMM6_REG 27)
276 (XMM7_REG 28)
277 (R10_REG 39)
278 (R11_REG 40)
279 (R13_REG 42)
280 (XMM8_REG 45)
281 (XMM9_REG 46)
282 (XMM10_REG 47)
283 (XMM11_REG 48)
284 (XMM12_REG 49)
285 (XMM13_REG 50)
286 (XMM14_REG 51)
287 (XMM15_REG 52)
288 ])
289
290 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
291 ;; from i386.c.
292
293 ;; In C guard expressions, put expressions which may be compile-time
294 ;; constants first. This allows for better optimization. For
295 ;; example, write "TARGET_64BIT && reload_completed", not
296 ;; "reload_completed && TARGET_64BIT".
297
298 \f
299 ;; Processor type.
300 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
301 generic64,amdfam10"
302 (const (symbol_ref "ix86_schedule")))
303
304 ;; A basic instruction type. Refinements due to arguments to be
305 ;; provided in other attributes.
306 (define_attr "type"
307 "other,multi,
308 alu,alu1,negnot,imov,imovx,lea,
309 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
310 icmp,test,ibr,setcc,icmov,
311 push,pop,call,callv,leave,
312 str,bitmanip,
313 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
314 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
315 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
316 ssemuladd,sse4arg,
317 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
318 (const_string "other"))
319
320 ;; Main data type used by the insn
321 (define_attr "mode"
322 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
323 (const_string "unknown"))
324
325 ;; The CPU unit operations uses.
326 (define_attr "unit" "integer,i387,sse,mmx,unknown"
327 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
328 (const_string "i387")
329 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
330 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
331 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
332 (const_string "sse")
333 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
334 (const_string "mmx")
335 (eq_attr "type" "other")
336 (const_string "unknown")]
337 (const_string "integer")))
338
339 ;; The (bounding maximum) length of an instruction immediate.
340 (define_attr "length_immediate" ""
341 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
342 bitmanip")
343 (const_int 0)
344 (eq_attr "unit" "i387,sse,mmx")
345 (const_int 0)
346 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
347 imul,icmp,push,pop")
348 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
349 (eq_attr "type" "imov,test")
350 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
351 (eq_attr "type" "call")
352 (if_then_else (match_operand 0 "constant_call_address_operand" "")
353 (const_int 4)
354 (const_int 0))
355 (eq_attr "type" "callv")
356 (if_then_else (match_operand 1 "constant_call_address_operand" "")
357 (const_int 4)
358 (const_int 0))
359 ;; We don't know the size before shorten_branches. Expect
360 ;; the instruction to fit for better scheduling.
361 (eq_attr "type" "ibr")
362 (const_int 1)
363 ]
364 (symbol_ref "/* Update immediate_length and other attributes! */
365 gcc_unreachable (),1")))
366
367 ;; The (bounding maximum) length of an instruction address.
368 (define_attr "length_address" ""
369 (cond [(eq_attr "type" "str,other,multi,fxch")
370 (const_int 0)
371 (and (eq_attr "type" "call")
372 (match_operand 0 "constant_call_address_operand" ""))
373 (const_int 0)
374 (and (eq_attr "type" "callv")
375 (match_operand 1 "constant_call_address_operand" ""))
376 (const_int 0)
377 ]
378 (symbol_ref "ix86_attr_length_address_default (insn)")))
379
380 ;; Set when length prefix is used.
381 (define_attr "prefix_data16" ""
382 (if_then_else (ior (eq_attr "mode" "HI")
383 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
384 (const_int 1)
385 (const_int 0)))
386
387 ;; Set when string REP prefix is used.
388 (define_attr "prefix_rep" ""
389 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
390 (const_int 1)
391 (const_int 0)))
392
393 ;; Set when 0f opcode prefix is used.
394 (define_attr "prefix_0f" ""
395 (if_then_else
396 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
397 (eq_attr "unit" "sse,mmx"))
398 (const_int 1)
399 (const_int 0)))
400
401 ;; Set when REX opcode prefix is used.
402 (define_attr "prefix_rex" ""
403 (cond [(and (eq_attr "mode" "DI")
404 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
405 (const_int 1)
406 (and (eq_attr "mode" "QI")
407 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
408 (const_int 0)))
409 (const_int 1)
410 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
411 (const_int 0))
412 (const_int 1)
413 ]
414 (const_int 0)))
415
416 ;; There are also additional prefixes in SSSE3.
417 (define_attr "prefix_extra" "" (const_int 0))
418
419 ;; Prefix used: original, VEX or maybe VEX.
420 (define_attr "prefix" "orig,vex,maybe_vex"
421 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
422 (const_string "vex")
423 (const_string "orig")))
424
425 ;; There is a 8bit immediate for VEX.
426 (define_attr "prefix_vex_imm8" "" (const_int 0))
427
428 ;; VEX W bit is used.
429 (define_attr "prefix_vex_w" "" (const_int 0))
430
431 ;; The length of VEX prefix
432 (define_attr "length_vex" ""
433 (if_then_else (eq_attr "prefix_0f" "1")
434 (if_then_else (eq_attr "prefix_vex_w" "1")
435 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
436 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
437 (if_then_else (eq_attr "prefix_vex_w" "1")
438 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
439 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
440
441 ;; Set when modrm byte is used.
442 (define_attr "modrm" ""
443 (cond [(eq_attr "type" "str,leave")
444 (const_int 0)
445 (eq_attr "unit" "i387")
446 (const_int 0)
447 (and (eq_attr "type" "incdec")
448 (ior (match_operand:SI 1 "register_operand" "")
449 (match_operand:HI 1 "register_operand" "")))
450 (const_int 0)
451 (and (eq_attr "type" "push")
452 (not (match_operand 1 "memory_operand" "")))
453 (const_int 0)
454 (and (eq_attr "type" "pop")
455 (not (match_operand 0 "memory_operand" "")))
456 (const_int 0)
457 (and (eq_attr "type" "imov")
458 (ior (and (match_operand 0 "register_operand" "")
459 (match_operand 1 "immediate_operand" ""))
460 (ior (and (match_operand 0 "ax_reg_operand" "")
461 (match_operand 1 "memory_displacement_only_operand" ""))
462 (and (match_operand 0 "memory_displacement_only_operand" "")
463 (match_operand 1 "ax_reg_operand" "")))))
464 (const_int 0)
465 (and (eq_attr "type" "call")
466 (match_operand 0 "constant_call_address_operand" ""))
467 (const_int 0)
468 (and (eq_attr "type" "callv")
469 (match_operand 1 "constant_call_address_operand" ""))
470 (const_int 0)
471 ]
472 (const_int 1)))
473
474 ;; The (bounding maximum) length of an instruction in bytes.
475 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
476 ;; Later we may want to split them and compute proper length as for
477 ;; other insns.
478 (define_attr "length" ""
479 (cond [(eq_attr "type" "other,multi,fistp,frndint")
480 (const_int 16)
481 (eq_attr "type" "fcmp")
482 (const_int 4)
483 (eq_attr "unit" "i387")
484 (plus (const_int 2)
485 (plus (attr "prefix_data16")
486 (attr "length_address")))
487 (ior (eq_attr "prefix" "vex")
488 (and (eq_attr "prefix" "maybe_vex")
489 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
490 (plus (attr "length_vex")
491 (plus (attr "prefix_vex_imm8")
492 (plus (attr "modrm")
493 (attr "length_address"))))]
494 (plus (plus (attr "modrm")
495 (plus (attr "prefix_0f")
496 (plus (attr "prefix_rex")
497 (plus (attr "prefix_extra")
498 (const_int 1)))))
499 (plus (attr "prefix_rep")
500 (plus (attr "prefix_data16")
501 (plus (attr "length_immediate")
502 (attr "length_address")))))))
503
504 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
505 ;; `store' if there is a simple memory reference therein, or `unknown'
506 ;; if the instruction is complex.
507
508 (define_attr "memory" "none,load,store,both,unknown"
509 (cond [(eq_attr "type" "other,multi,str")
510 (const_string "unknown")
511 (eq_attr "type" "lea,fcmov,fpspc")
512 (const_string "none")
513 (eq_attr "type" "fistp,leave")
514 (const_string "both")
515 (eq_attr "type" "frndint")
516 (const_string "load")
517 (eq_attr "type" "push")
518 (if_then_else (match_operand 1 "memory_operand" "")
519 (const_string "both")
520 (const_string "store"))
521 (eq_attr "type" "pop")
522 (if_then_else (match_operand 0 "memory_operand" "")
523 (const_string "both")
524 (const_string "load"))
525 (eq_attr "type" "setcc")
526 (if_then_else (match_operand 0 "memory_operand" "")
527 (const_string "store")
528 (const_string "none"))
529 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
530 (if_then_else (ior (match_operand 0 "memory_operand" "")
531 (match_operand 1 "memory_operand" ""))
532 (const_string "load")
533 (const_string "none"))
534 (eq_attr "type" "ibr")
535 (if_then_else (match_operand 0 "memory_operand" "")
536 (const_string "load")
537 (const_string "none"))
538 (eq_attr "type" "call")
539 (if_then_else (match_operand 0 "constant_call_address_operand" "")
540 (const_string "none")
541 (const_string "load"))
542 (eq_attr "type" "callv")
543 (if_then_else (match_operand 1 "constant_call_address_operand" "")
544 (const_string "none")
545 (const_string "load"))
546 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
547 (match_operand 1 "memory_operand" ""))
548 (const_string "both")
549 (and (match_operand 0 "memory_operand" "")
550 (match_operand 1 "memory_operand" ""))
551 (const_string "both")
552 (match_operand 0 "memory_operand" "")
553 (const_string "store")
554 (match_operand 1 "memory_operand" "")
555 (const_string "load")
556 (and (eq_attr "type"
557 "!alu1,negnot,ishift1,
558 imov,imovx,icmp,test,bitmanip,
559 fmov,fcmp,fsgn,
560 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
561 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
562 (match_operand 2 "memory_operand" ""))
563 (const_string "load")
564 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
565 (match_operand 3 "memory_operand" ""))
566 (const_string "load")
567 ]
568 (const_string "none")))
569
570 ;; Indicates if an instruction has both an immediate and a displacement.
571
572 (define_attr "imm_disp" "false,true,unknown"
573 (cond [(eq_attr "type" "other,multi")
574 (const_string "unknown")
575 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
576 (and (match_operand 0 "memory_displacement_operand" "")
577 (match_operand 1 "immediate_operand" "")))
578 (const_string "true")
579 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
580 (and (match_operand 0 "memory_displacement_operand" "")
581 (match_operand 2 "immediate_operand" "")))
582 (const_string "true")
583 ]
584 (const_string "false")))
585
586 ;; Indicates if an FP operation has an integer source.
587
588 (define_attr "fp_int_src" "false,true"
589 (const_string "false"))
590
591 ;; Defines rounding mode of an FP operation.
592
593 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
594 (const_string "any"))
595
596 ;; Describe a user's asm statement.
597 (define_asm_attributes
598 [(set_attr "length" "128")
599 (set_attr "type" "multi")])
600
601 ;; All integer comparison codes.
602 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
603
604 ;; All floating-point comparison codes.
605 (define_code_iterator fp_cond [unordered ordered
606 uneq unge ungt unle unlt ltgt ])
607
608 (define_code_iterator plusminus [plus minus])
609
610 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
611
612 ;; Base name for define_insn
613 (define_code_attr plusminus_insn
614 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
615 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
616
617 ;; Base name for insn mnemonic.
618 (define_code_attr plusminus_mnemonic
619 [(plus "add") (ss_plus "adds") (us_plus "addus")
620 (minus "sub") (ss_minus "subs") (us_minus "subus")])
621
622 ;; Mark commutative operators as such in constraints.
623 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
624 (minus "") (ss_minus "") (us_minus "")])
625
626 ;; Mapping of signed max and min
627 (define_code_iterator smaxmin [smax smin])
628
629 ;; Mapping of unsigned max and min
630 (define_code_iterator umaxmin [umax umin])
631
632 ;; Mapping of signed/unsigned max and min
633 (define_code_iterator maxmin [smax smin umax umin])
634
635 ;; Base name for integer and FP insn mnemonic
636 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
637 (umax "maxu") (umin "minu")])
638 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
639
640 ;; Mapping of parallel logic operators
641 (define_code_iterator plogic [and ior xor])
642
643 ;; Base name for insn mnemonic.
644 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
645
646 ;; Mapping of abs neg operators
647 (define_code_iterator absneg [abs neg])
648
649 ;; Base name for x87 insn mnemonic.
650 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
651
652 ;; All single word integer modes.
653 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
654
655 ;; Single word integer modes up to SImode.
656 (define_mode_iterator SWI32 [QI HI SI])
657
658 ;; Instruction suffix for integer modes.
659 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
660
661 ;; Register class for integer modes.
662 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
663
664 ;; Immediate operand constraint for integer modes.
665 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
666
667 ;; General operand predicate for integer modes.
668 (define_mode_attr general_operand
669 [(QI "general_operand")
670 (HI "general_operand")
671 (SI "general_operand")
672 (DI "x86_64_general_operand")])
673
674 ;; SSE and x87 SFmode and DFmode floating point modes
675 (define_mode_iterator MODEF [SF DF])
676
677 ;; All x87 floating point modes
678 (define_mode_iterator X87MODEF [SF DF XF])
679
680 ;; All integer modes handled by x87 fisttp operator.
681 (define_mode_iterator X87MODEI [HI SI DI])
682
683 ;; All integer modes handled by integer x87 operators.
684 (define_mode_iterator X87MODEI12 [HI SI])
685
686 ;; All integer modes handled by SSE cvtts?2si* operators.
687 (define_mode_iterator SSEMODEI24 [SI DI])
688
689 ;; SSE asm suffix for floating point modes
690 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
691
692 ;; SSE vector mode corresponding to a scalar mode
693 (define_mode_attr ssevecmode
694 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
695
696 ;; Instruction suffix for REX 64bit operators.
697 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
698
699 ;; This mode iterator allows :P to be used for patterns that operate on
700 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
701 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
702
703 \f
704 ;; Scheduling descriptions
705
706 (include "pentium.md")
707 (include "ppro.md")
708 (include "k6.md")
709 (include "athlon.md")
710 (include "geode.md")
711
712 \f
713 ;; Operand and operator predicates and constraints
714
715 (include "predicates.md")
716 (include "constraints.md")
717
718 \f
719 ;; Compare instructions.
720
721 ;; All compare insns have expanders that save the operands away without
722 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
723 ;; after the cmp) will actually emit the cmpM.
724
725 (define_expand "cmpti"
726 [(set (reg:CC FLAGS_REG)
727 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
728 (match_operand:TI 1 "x86_64_general_operand" "")))]
729 "TARGET_64BIT"
730 {
731 if (MEM_P (operands[0]) && MEM_P (operands[1]))
732 operands[0] = force_reg (TImode, operands[0]);
733 ix86_compare_op0 = operands[0];
734 ix86_compare_op1 = operands[1];
735 DONE;
736 })
737
738 (define_expand "cmpdi"
739 [(set (reg:CC FLAGS_REG)
740 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
741 (match_operand:DI 1 "x86_64_general_operand" "")))]
742 ""
743 {
744 if (MEM_P (operands[0]) && MEM_P (operands[1]))
745 operands[0] = force_reg (DImode, operands[0]);
746 ix86_compare_op0 = operands[0];
747 ix86_compare_op1 = operands[1];
748 DONE;
749 })
750
751 (define_expand "cmpsi"
752 [(set (reg:CC FLAGS_REG)
753 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
754 (match_operand:SI 1 "general_operand" "")))]
755 ""
756 {
757 if (MEM_P (operands[0]) && MEM_P (operands[1]))
758 operands[0] = force_reg (SImode, operands[0]);
759 ix86_compare_op0 = operands[0];
760 ix86_compare_op1 = operands[1];
761 DONE;
762 })
763
764 (define_expand "cmphi"
765 [(set (reg:CC FLAGS_REG)
766 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
767 (match_operand:HI 1 "general_operand" "")))]
768 ""
769 {
770 if (MEM_P (operands[0]) && MEM_P (operands[1]))
771 operands[0] = force_reg (HImode, operands[0]);
772 ix86_compare_op0 = operands[0];
773 ix86_compare_op1 = operands[1];
774 DONE;
775 })
776
777 (define_expand "cmpqi"
778 [(set (reg:CC FLAGS_REG)
779 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
780 (match_operand:QI 1 "general_operand" "")))]
781 "TARGET_QIMODE_MATH"
782 {
783 if (MEM_P (operands[0]) && MEM_P (operands[1]))
784 operands[0] = force_reg (QImode, operands[0]);
785 ix86_compare_op0 = operands[0];
786 ix86_compare_op1 = operands[1];
787 DONE;
788 })
789
790 (define_insn "cmpdi_ccno_1_rex64"
791 [(set (reg FLAGS_REG)
792 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
793 (match_operand:DI 1 "const0_operand" "")))]
794 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
795 "@
796 test{q}\t%0, %0
797 cmp{q}\t{%1, %0|%0, %1}"
798 [(set_attr "type" "test,icmp")
799 (set_attr "length_immediate" "0,1")
800 (set_attr "mode" "DI")])
801
802 (define_insn "*cmpdi_minus_1_rex64"
803 [(set (reg FLAGS_REG)
804 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
805 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
806 (const_int 0)))]
807 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
808 "cmp{q}\t{%1, %0|%0, %1}"
809 [(set_attr "type" "icmp")
810 (set_attr "mode" "DI")])
811
812 (define_expand "cmpdi_1_rex64"
813 [(set (reg:CC FLAGS_REG)
814 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
815 (match_operand:DI 1 "general_operand" "")))]
816 "TARGET_64BIT"
817 "")
818
819 (define_insn "cmpdi_1_insn_rex64"
820 [(set (reg FLAGS_REG)
821 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
822 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
823 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
824 "cmp{q}\t{%1, %0|%0, %1}"
825 [(set_attr "type" "icmp")
826 (set_attr "mode" "DI")])
827
828
829 (define_insn "*cmpsi_ccno_1"
830 [(set (reg FLAGS_REG)
831 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
832 (match_operand:SI 1 "const0_operand" "")))]
833 "ix86_match_ccmode (insn, CCNOmode)"
834 "@
835 test{l}\t%0, %0
836 cmp{l}\t{%1, %0|%0, %1}"
837 [(set_attr "type" "test,icmp")
838 (set_attr "length_immediate" "0,1")
839 (set_attr "mode" "SI")])
840
841 (define_insn "*cmpsi_minus_1"
842 [(set (reg FLAGS_REG)
843 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
844 (match_operand:SI 1 "general_operand" "ri,mr"))
845 (const_int 0)))]
846 "ix86_match_ccmode (insn, CCGOCmode)"
847 "cmp{l}\t{%1, %0|%0, %1}"
848 [(set_attr "type" "icmp")
849 (set_attr "mode" "SI")])
850
851 (define_expand "cmpsi_1"
852 [(set (reg:CC FLAGS_REG)
853 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
854 (match_operand:SI 1 "general_operand" "")))]
855 ""
856 "")
857
858 (define_insn "*cmpsi_1_insn"
859 [(set (reg FLAGS_REG)
860 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
861 (match_operand:SI 1 "general_operand" "ri,mr")))]
862 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
863 && ix86_match_ccmode (insn, CCmode)"
864 "cmp{l}\t{%1, %0|%0, %1}"
865 [(set_attr "type" "icmp")
866 (set_attr "mode" "SI")])
867
868 (define_insn "*cmphi_ccno_1"
869 [(set (reg FLAGS_REG)
870 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
871 (match_operand:HI 1 "const0_operand" "")))]
872 "ix86_match_ccmode (insn, CCNOmode)"
873 "@
874 test{w}\t%0, %0
875 cmp{w}\t{%1, %0|%0, %1}"
876 [(set_attr "type" "test,icmp")
877 (set_attr "length_immediate" "0,1")
878 (set_attr "mode" "HI")])
879
880 (define_insn "*cmphi_minus_1"
881 [(set (reg FLAGS_REG)
882 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
883 (match_operand:HI 1 "general_operand" "rn,mr"))
884 (const_int 0)))]
885 "ix86_match_ccmode (insn, CCGOCmode)"
886 "cmp{w}\t{%1, %0|%0, %1}"
887 [(set_attr "type" "icmp")
888 (set_attr "mode" "HI")])
889
890 (define_insn "*cmphi_1"
891 [(set (reg FLAGS_REG)
892 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
893 (match_operand:HI 1 "general_operand" "rn,mr")))]
894 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
895 && ix86_match_ccmode (insn, CCmode)"
896 "cmp{w}\t{%1, %0|%0, %1}"
897 [(set_attr "type" "icmp")
898 (set_attr "mode" "HI")])
899
900 (define_insn "*cmpqi_ccno_1"
901 [(set (reg FLAGS_REG)
902 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
903 (match_operand:QI 1 "const0_operand" "")))]
904 "ix86_match_ccmode (insn, CCNOmode)"
905 "@
906 test{b}\t%0, %0
907 cmp{b}\t{$0, %0|%0, 0}"
908 [(set_attr "type" "test,icmp")
909 (set_attr "length_immediate" "0,1")
910 (set_attr "mode" "QI")])
911
912 (define_insn "*cmpqi_1"
913 [(set (reg FLAGS_REG)
914 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
915 (match_operand:QI 1 "general_operand" "qn,mq")))]
916 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
917 && ix86_match_ccmode (insn, CCmode)"
918 "cmp{b}\t{%1, %0|%0, %1}"
919 [(set_attr "type" "icmp")
920 (set_attr "mode" "QI")])
921
922 (define_insn "*cmpqi_minus_1"
923 [(set (reg FLAGS_REG)
924 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
925 (match_operand:QI 1 "general_operand" "qn,mq"))
926 (const_int 0)))]
927 "ix86_match_ccmode (insn, CCGOCmode)"
928 "cmp{b}\t{%1, %0|%0, %1}"
929 [(set_attr "type" "icmp")
930 (set_attr "mode" "QI")])
931
932 (define_insn "*cmpqi_ext_1"
933 [(set (reg FLAGS_REG)
934 (compare
935 (match_operand:QI 0 "general_operand" "Qm")
936 (subreg:QI
937 (zero_extract:SI
938 (match_operand 1 "ext_register_operand" "Q")
939 (const_int 8)
940 (const_int 8)) 0)))]
941 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
942 "cmp{b}\t{%h1, %0|%0, %h1}"
943 [(set_attr "type" "icmp")
944 (set_attr "mode" "QI")])
945
946 (define_insn "*cmpqi_ext_1_rex64"
947 [(set (reg FLAGS_REG)
948 (compare
949 (match_operand:QI 0 "register_operand" "Q")
950 (subreg:QI
951 (zero_extract:SI
952 (match_operand 1 "ext_register_operand" "Q")
953 (const_int 8)
954 (const_int 8)) 0)))]
955 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
956 "cmp{b}\t{%h1, %0|%0, %h1}"
957 [(set_attr "type" "icmp")
958 (set_attr "mode" "QI")])
959
960 (define_insn "*cmpqi_ext_2"
961 [(set (reg FLAGS_REG)
962 (compare
963 (subreg:QI
964 (zero_extract:SI
965 (match_operand 0 "ext_register_operand" "Q")
966 (const_int 8)
967 (const_int 8)) 0)
968 (match_operand:QI 1 "const0_operand" "")))]
969 "ix86_match_ccmode (insn, CCNOmode)"
970 "test{b}\t%h0, %h0"
971 [(set_attr "type" "test")
972 (set_attr "length_immediate" "0")
973 (set_attr "mode" "QI")])
974
975 (define_expand "cmpqi_ext_3"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC
978 (subreg:QI
979 (zero_extract:SI
980 (match_operand 0 "ext_register_operand" "")
981 (const_int 8)
982 (const_int 8)) 0)
983 (match_operand:QI 1 "general_operand" "")))]
984 ""
985 "")
986
987 (define_insn "cmpqi_ext_3_insn"
988 [(set (reg FLAGS_REG)
989 (compare
990 (subreg:QI
991 (zero_extract:SI
992 (match_operand 0 "ext_register_operand" "Q")
993 (const_int 8)
994 (const_int 8)) 0)
995 (match_operand:QI 1 "general_operand" "Qmn")))]
996 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997 "cmp{b}\t{%1, %h0|%h0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "QI")])
1000
1001 (define_insn "cmpqi_ext_3_insn_rex64"
1002 [(set (reg FLAGS_REG)
1003 (compare
1004 (subreg:QI
1005 (zero_extract:SI
1006 (match_operand 0 "ext_register_operand" "Q")
1007 (const_int 8)
1008 (const_int 8)) 0)
1009 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1010 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011 "cmp{b}\t{%1, %h0|%h0, %1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "QI")])
1014
1015 (define_insn "*cmpqi_ext_4"
1016 [(set (reg FLAGS_REG)
1017 (compare
1018 (subreg:QI
1019 (zero_extract:SI
1020 (match_operand 0 "ext_register_operand" "Q")
1021 (const_int 8)
1022 (const_int 8)) 0)
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 "ix86_match_ccmode (insn, CCmode)"
1029 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1030 [(set_attr "type" "icmp")
1031 (set_attr "mode" "QI")])
1032
1033 ;; These implement float point compares.
1034 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1035 ;; which would allow mix and match FP modes on the compares. Which is what
1036 ;; the old patterns did, but with many more of them.
1037
1038 (define_expand "cmpxf"
1039 [(set (reg:CC FLAGS_REG)
1040 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1041 (match_operand:XF 1 "nonmemory_operand" "")))]
1042 "TARGET_80387"
1043 {
1044 ix86_compare_op0 = operands[0];
1045 ix86_compare_op1 = operands[1];
1046 DONE;
1047 })
1048
1049 (define_expand "cmp<mode>"
1050 [(set (reg:CC FLAGS_REG)
1051 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1052 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1053 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1054 {
1055 ix86_compare_op0 = operands[0];
1056 ix86_compare_op1 = operands[1];
1057 DONE;
1058 })
1059
1060 ;; FP compares, step 1:
1061 ;; Set the FP condition codes.
1062 ;;
1063 ;; CCFPmode compare with exceptions
1064 ;; CCFPUmode compare with no exceptions
1065
1066 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1067 ;; used to manage the reg stack popping would not be preserved.
1068
1069 (define_insn "*cmpfp_0"
1070 [(set (match_operand:HI 0 "register_operand" "=a")
1071 (unspec:HI
1072 [(compare:CCFP
1073 (match_operand 1 "register_operand" "f")
1074 (match_operand 2 "const0_operand" ""))]
1075 UNSPEC_FNSTSW))]
1076 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1077 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078 "* return output_fp_compare (insn, operands, 0, 0);"
1079 [(set_attr "type" "multi")
1080 (set_attr "unit" "i387")
1081 (set (attr "mode")
1082 (cond [(match_operand:SF 1 "" "")
1083 (const_string "SF")
1084 (match_operand:DF 1 "" "")
1085 (const_string "DF")
1086 ]
1087 (const_string "XF")))])
1088
1089 (define_insn_and_split "*cmpfp_0_cc"
1090 [(set (reg:CCFP FLAGS_REG)
1091 (compare:CCFP
1092 (match_operand 1 "register_operand" "f")
1093 (match_operand 2 "const0_operand" "")))
1094 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1095 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096 && TARGET_SAHF && !TARGET_CMOVE
1097 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1098 "#"
1099 "&& reload_completed"
1100 [(set (match_dup 0)
1101 (unspec:HI
1102 [(compare:CCFP (match_dup 1)(match_dup 2))]
1103 UNSPEC_FNSTSW))
1104 (set (reg:CC FLAGS_REG)
1105 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1106 ""
1107 [(set_attr "type" "multi")
1108 (set_attr "unit" "i387")
1109 (set (attr "mode")
1110 (cond [(match_operand:SF 1 "" "")
1111 (const_string "SF")
1112 (match_operand:DF 1 "" "")
1113 (const_string "DF")
1114 ]
1115 (const_string "XF")))])
1116
1117 (define_insn "*cmpfp_xf"
1118 [(set (match_operand:HI 0 "register_operand" "=a")
1119 (unspec:HI
1120 [(compare:CCFP
1121 (match_operand:XF 1 "register_operand" "f")
1122 (match_operand:XF 2 "register_operand" "f"))]
1123 UNSPEC_FNSTSW))]
1124 "TARGET_80387"
1125 "* return output_fp_compare (insn, operands, 0, 0);"
1126 [(set_attr "type" "multi")
1127 (set_attr "unit" "i387")
1128 (set_attr "mode" "XF")])
1129
1130 (define_insn_and_split "*cmpfp_xf_cc"
1131 [(set (reg:CCFP FLAGS_REG)
1132 (compare:CCFP
1133 (match_operand:XF 1 "register_operand" "f")
1134 (match_operand:XF 2 "register_operand" "f")))
1135 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1136 "TARGET_80387
1137 && TARGET_SAHF && !TARGET_CMOVE"
1138 "#"
1139 "&& reload_completed"
1140 [(set (match_dup 0)
1141 (unspec:HI
1142 [(compare:CCFP (match_dup 1)(match_dup 2))]
1143 UNSPEC_FNSTSW))
1144 (set (reg:CC FLAGS_REG)
1145 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1146 ""
1147 [(set_attr "type" "multi")
1148 (set_attr "unit" "i387")
1149 (set_attr "mode" "XF")])
1150
1151 (define_insn "*cmpfp_<mode>"
1152 [(set (match_operand:HI 0 "register_operand" "=a")
1153 (unspec:HI
1154 [(compare:CCFP
1155 (match_operand:MODEF 1 "register_operand" "f")
1156 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1157 UNSPEC_FNSTSW))]
1158 "TARGET_80387"
1159 "* return output_fp_compare (insn, operands, 0, 0);"
1160 [(set_attr "type" "multi")
1161 (set_attr "unit" "i387")
1162 (set_attr "mode" "<MODE>")])
1163
1164 (define_insn_and_split "*cmpfp_<mode>_cc"
1165 [(set (reg:CCFP FLAGS_REG)
1166 (compare:CCFP
1167 (match_operand:MODEF 1 "register_operand" "f")
1168 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1169 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1170 "TARGET_80387
1171 && TARGET_SAHF && !TARGET_CMOVE"
1172 "#"
1173 "&& reload_completed"
1174 [(set (match_dup 0)
1175 (unspec:HI
1176 [(compare:CCFP (match_dup 1)(match_dup 2))]
1177 UNSPEC_FNSTSW))
1178 (set (reg:CC FLAGS_REG)
1179 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1180 ""
1181 [(set_attr "type" "multi")
1182 (set_attr "unit" "i387")
1183 (set_attr "mode" "<MODE>")])
1184
1185 (define_insn "*cmpfp_u"
1186 [(set (match_operand:HI 0 "register_operand" "=a")
1187 (unspec:HI
1188 [(compare:CCFPU
1189 (match_operand 1 "register_operand" "f")
1190 (match_operand 2 "register_operand" "f"))]
1191 UNSPEC_FNSTSW))]
1192 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1193 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1194 "* return output_fp_compare (insn, operands, 0, 1);"
1195 [(set_attr "type" "multi")
1196 (set_attr "unit" "i387")
1197 (set (attr "mode")
1198 (cond [(match_operand:SF 1 "" "")
1199 (const_string "SF")
1200 (match_operand:DF 1 "" "")
1201 (const_string "DF")
1202 ]
1203 (const_string "XF")))])
1204
1205 (define_insn_and_split "*cmpfp_u_cc"
1206 [(set (reg:CCFPU FLAGS_REG)
1207 (compare:CCFPU
1208 (match_operand 1 "register_operand" "f")
1209 (match_operand 2 "register_operand" "f")))
1210 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212 && TARGET_SAHF && !TARGET_CMOVE
1213 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1214 "#"
1215 "&& reload_completed"
1216 [(set (match_dup 0)
1217 (unspec:HI
1218 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1219 UNSPEC_FNSTSW))
1220 (set (reg:CC FLAGS_REG)
1221 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1222 ""
1223 [(set_attr "type" "multi")
1224 (set_attr "unit" "i387")
1225 (set (attr "mode")
1226 (cond [(match_operand:SF 1 "" "")
1227 (const_string "SF")
1228 (match_operand:DF 1 "" "")
1229 (const_string "DF")
1230 ]
1231 (const_string "XF")))])
1232
1233 (define_insn "*cmpfp_<mode>"
1234 [(set (match_operand:HI 0 "register_operand" "=a")
1235 (unspec:HI
1236 [(compare:CCFP
1237 (match_operand 1 "register_operand" "f")
1238 (match_operator 3 "float_operator"
1239 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1240 UNSPEC_FNSTSW))]
1241 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1242 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1243 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1244 "* return output_fp_compare (insn, operands, 0, 0);"
1245 [(set_attr "type" "multi")
1246 (set_attr "unit" "i387")
1247 (set_attr "fp_int_src" "true")
1248 (set_attr "mode" "<MODE>")])
1249
1250 (define_insn_and_split "*cmpfp_<mode>_cc"
1251 [(set (reg:CCFP FLAGS_REG)
1252 (compare:CCFP
1253 (match_operand 1 "register_operand" "f")
1254 (match_operator 3 "float_operator"
1255 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1256 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1257 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1258 && TARGET_SAHF && !TARGET_CMOVE
1259 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1260 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1261 "#"
1262 "&& reload_completed"
1263 [(set (match_dup 0)
1264 (unspec:HI
1265 [(compare:CCFP
1266 (match_dup 1)
1267 (match_op_dup 3 [(match_dup 2)]))]
1268 UNSPEC_FNSTSW))
1269 (set (reg:CC FLAGS_REG)
1270 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1271 ""
1272 [(set_attr "type" "multi")
1273 (set_attr "unit" "i387")
1274 (set_attr "fp_int_src" "true")
1275 (set_attr "mode" "<MODE>")])
1276
1277 ;; FP compares, step 2
1278 ;; Move the fpsw to ax.
1279
1280 (define_insn "x86_fnstsw_1"
1281 [(set (match_operand:HI 0 "register_operand" "=a")
1282 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1283 "TARGET_80387"
1284 "fnstsw\t%0"
1285 [(set_attr "length" "2")
1286 (set_attr "mode" "SI")
1287 (set_attr "unit" "i387")])
1288
1289 ;; FP compares, step 3
1290 ;; Get ax into flags, general case.
1291
1292 (define_insn "x86_sahf_1"
1293 [(set (reg:CC FLAGS_REG)
1294 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1295 UNSPEC_SAHF))]
1296 "TARGET_SAHF"
1297 {
1298 #ifdef HAVE_AS_IX86_SAHF
1299 return "sahf";
1300 #else
1301 return ".byte\t0x9e";
1302 #endif
1303 }
1304 [(set_attr "length" "1")
1305 (set_attr "athlon_decode" "vector")
1306 (set_attr "amdfam10_decode" "direct")
1307 (set_attr "mode" "SI")])
1308
1309 ;; Pentium Pro can do steps 1 through 3 in one go.
1310 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1311 (define_insn "*cmpfp_i_mixed"
1312 [(set (reg:CCFP FLAGS_REG)
1313 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1314 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1315 "TARGET_MIX_SSE_I387
1316 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1317 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1318 "* return output_fp_compare (insn, operands, 1, 0);"
1319 [(set_attr "type" "fcmp,ssecomi")
1320 (set_attr "prefix" "orig,maybe_vex")
1321 (set (attr "mode")
1322 (if_then_else (match_operand:SF 1 "" "")
1323 (const_string "SF")
1324 (const_string "DF")))
1325 (set_attr "athlon_decode" "vector")
1326 (set_attr "amdfam10_decode" "direct")])
1327
1328 (define_insn "*cmpfp_i_sse"
1329 [(set (reg:CCFP FLAGS_REG)
1330 (compare:CCFP (match_operand 0 "register_operand" "x")
1331 (match_operand 1 "nonimmediate_operand" "xm")))]
1332 "TARGET_SSE_MATH
1333 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1334 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1335 "* return output_fp_compare (insn, operands, 1, 0);"
1336 [(set_attr "type" "ssecomi")
1337 (set_attr "prefix" "maybe_vex")
1338 (set (attr "mode")
1339 (if_then_else (match_operand:SF 1 "" "")
1340 (const_string "SF")
1341 (const_string "DF")))
1342 (set_attr "athlon_decode" "vector")
1343 (set_attr "amdfam10_decode" "direct")])
1344
1345 (define_insn "*cmpfp_i_i387"
1346 [(set (reg:CCFP FLAGS_REG)
1347 (compare:CCFP (match_operand 0 "register_operand" "f")
1348 (match_operand 1 "register_operand" "f")))]
1349 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1350 && TARGET_CMOVE
1351 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1352 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1353 "* return output_fp_compare (insn, operands, 1, 0);"
1354 [(set_attr "type" "fcmp")
1355 (set (attr "mode")
1356 (cond [(match_operand:SF 1 "" "")
1357 (const_string "SF")
1358 (match_operand:DF 1 "" "")
1359 (const_string "DF")
1360 ]
1361 (const_string "XF")))
1362 (set_attr "athlon_decode" "vector")
1363 (set_attr "amdfam10_decode" "direct")])
1364
1365 (define_insn "*cmpfp_iu_mixed"
1366 [(set (reg:CCFPU FLAGS_REG)
1367 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1368 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1369 "TARGET_MIX_SSE_I387
1370 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1371 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372 "* return output_fp_compare (insn, operands, 1, 1);"
1373 [(set_attr "type" "fcmp,ssecomi")
1374 (set_attr "prefix" "orig,maybe_vex")
1375 (set (attr "mode")
1376 (if_then_else (match_operand:SF 1 "" "")
1377 (const_string "SF")
1378 (const_string "DF")))
1379 (set_attr "athlon_decode" "vector")
1380 (set_attr "amdfam10_decode" "direct")])
1381
1382 (define_insn "*cmpfp_iu_sse"
1383 [(set (reg:CCFPU FLAGS_REG)
1384 (compare:CCFPU (match_operand 0 "register_operand" "x")
1385 (match_operand 1 "nonimmediate_operand" "xm")))]
1386 "TARGET_SSE_MATH
1387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1388 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1389 "* return output_fp_compare (insn, operands, 1, 1);"
1390 [(set_attr "type" "ssecomi")
1391 (set_attr "prefix" "maybe_vex")
1392 (set (attr "mode")
1393 (if_then_else (match_operand:SF 1 "" "")
1394 (const_string "SF")
1395 (const_string "DF")))
1396 (set_attr "athlon_decode" "vector")
1397 (set_attr "amdfam10_decode" "direct")])
1398
1399 (define_insn "*cmpfp_iu_387"
1400 [(set (reg:CCFPU FLAGS_REG)
1401 (compare:CCFPU (match_operand 0 "register_operand" "f")
1402 (match_operand 1 "register_operand" "f")))]
1403 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1404 && TARGET_CMOVE
1405 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1406 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1407 "* return output_fp_compare (insn, operands, 1, 1);"
1408 [(set_attr "type" "fcmp")
1409 (set (attr "mode")
1410 (cond [(match_operand:SF 1 "" "")
1411 (const_string "SF")
1412 (match_operand:DF 1 "" "")
1413 (const_string "DF")
1414 ]
1415 (const_string "XF")))
1416 (set_attr "athlon_decode" "vector")
1417 (set_attr "amdfam10_decode" "direct")])
1418 \f
1419 ;; Move instructions.
1420
1421 ;; General case of fullword move.
1422
1423 (define_expand "movsi"
1424 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1425 (match_operand:SI 1 "general_operand" ""))]
1426 ""
1427 "ix86_expand_move (SImode, operands); DONE;")
1428
1429 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1430 ;; general_operand.
1431 ;;
1432 ;; %%% We don't use a post-inc memory reference because x86 is not a
1433 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1434 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1435 ;; targets without our curiosities, and it is just as easy to represent
1436 ;; this differently.
1437
1438 (define_insn "*pushsi2"
1439 [(set (match_operand:SI 0 "push_operand" "=<")
1440 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1441 "!TARGET_64BIT"
1442 "push{l}\t%1"
1443 [(set_attr "type" "push")
1444 (set_attr "mode" "SI")])
1445
1446 ;; For 64BIT abi we always round up to 8 bytes.
1447 (define_insn "*pushsi2_rex64"
1448 [(set (match_operand:SI 0 "push_operand" "=X")
1449 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1450 "TARGET_64BIT"
1451 "push{q}\t%q1"
1452 [(set_attr "type" "push")
1453 (set_attr "mode" "SI")])
1454
1455 (define_insn "*pushsi2_prologue"
1456 [(set (match_operand:SI 0 "push_operand" "=<")
1457 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1458 (clobber (mem:BLK (scratch)))]
1459 "!TARGET_64BIT"
1460 "push{l}\t%1"
1461 [(set_attr "type" "push")
1462 (set_attr "mode" "SI")])
1463
1464 (define_insn "*popsi1_epilogue"
1465 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1466 (mem:SI (reg:SI SP_REG)))
1467 (set (reg:SI SP_REG)
1468 (plus:SI (reg:SI SP_REG) (const_int 4)))
1469 (clobber (mem:BLK (scratch)))]
1470 "!TARGET_64BIT"
1471 "pop{l}\t%0"
1472 [(set_attr "type" "pop")
1473 (set_attr "mode" "SI")])
1474
1475 (define_insn "popsi1"
1476 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1477 (mem:SI (reg:SI SP_REG)))
1478 (set (reg:SI SP_REG)
1479 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1480 "!TARGET_64BIT"
1481 "pop{l}\t%0"
1482 [(set_attr "type" "pop")
1483 (set_attr "mode" "SI")])
1484
1485 (define_insn "*movsi_xor"
1486 [(set (match_operand:SI 0 "register_operand" "=r")
1487 (match_operand:SI 1 "const0_operand" ""))
1488 (clobber (reg:CC FLAGS_REG))]
1489 "reload_completed"
1490 "xor{l}\t%0, %0"
1491 [(set_attr "type" "alu1")
1492 (set_attr "mode" "SI")
1493 (set_attr "length_immediate" "0")])
1494
1495 (define_insn "*movsi_or"
1496 [(set (match_operand:SI 0 "register_operand" "=r")
1497 (match_operand:SI 1 "immediate_operand" "i"))
1498 (clobber (reg:CC FLAGS_REG))]
1499 "reload_completed
1500 && operands[1] == constm1_rtx"
1501 {
1502 operands[1] = constm1_rtx;
1503 return "or{l}\t{%1, %0|%0, %1}";
1504 }
1505 [(set_attr "type" "alu1")
1506 (set_attr "mode" "SI")
1507 (set_attr "length_immediate" "1")])
1508
1509 (define_insn "*movsi_1"
1510 [(set (match_operand:SI 0 "nonimmediate_operand"
1511 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1512 (match_operand:SI 1 "general_operand"
1513 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1514 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1515 {
1516 switch (get_attr_type (insn))
1517 {
1518 case TYPE_SSELOG1:
1519 if (get_attr_mode (insn) == MODE_TI)
1520 return "%vpxor\t%0, %d0";
1521 return "%vxorps\t%0, %d0";
1522
1523 case TYPE_SSEMOV:
1524 switch (get_attr_mode (insn))
1525 {
1526 case MODE_TI:
1527 return "%vmovdqa\t{%1, %0|%0, %1}";
1528 case MODE_V4SF:
1529 return "%vmovaps\t{%1, %0|%0, %1}";
1530 case MODE_SI:
1531 return "%vmovd\t{%1, %0|%0, %1}";
1532 case MODE_SF:
1533 return "%vmovss\t{%1, %0|%0, %1}";
1534 default:
1535 gcc_unreachable ();
1536 }
1537
1538 case TYPE_MMXADD:
1539 return "pxor\t%0, %0";
1540
1541 case TYPE_MMXMOV:
1542 if (get_attr_mode (insn) == MODE_DI)
1543 return "movq\t{%1, %0|%0, %1}";
1544 return "movd\t{%1, %0|%0, %1}";
1545
1546 case TYPE_LEA:
1547 return "lea{l}\t{%1, %0|%0, %1}";
1548
1549 default:
1550 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1551 return "mov{l}\t{%1, %0|%0, %1}";
1552 }
1553 }
1554 [(set (attr "type")
1555 (cond [(eq_attr "alternative" "2")
1556 (const_string "mmxadd")
1557 (eq_attr "alternative" "3,4,5")
1558 (const_string "mmxmov")
1559 (eq_attr "alternative" "6")
1560 (const_string "sselog1")
1561 (eq_attr "alternative" "7,8,9,10,11")
1562 (const_string "ssemov")
1563 (match_operand:DI 1 "pic_32bit_operand" "")
1564 (const_string "lea")
1565 ]
1566 (const_string "imov")))
1567 (set (attr "prefix")
1568 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1569 (const_string "orig")
1570 (const_string "maybe_vex")))
1571 (set (attr "mode")
1572 (cond [(eq_attr "alternative" "2,3")
1573 (const_string "DI")
1574 (eq_attr "alternative" "6,7")
1575 (if_then_else
1576 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1577 (const_string "V4SF")
1578 (const_string "TI"))
1579 (and (eq_attr "alternative" "8,9,10,11")
1580 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1581 (const_string "SF")
1582 ]
1583 (const_string "SI")))])
1584
1585 ;; Stores and loads of ax to arbitrary constant address.
1586 ;; We fake an second form of instruction to force reload to load address
1587 ;; into register when rax is not available
1588 (define_insn "*movabssi_1_rex64"
1589 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1590 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1591 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1592 "@
1593 movabs{l}\t{%1, %P0|%P0, %1}
1594 mov{l}\t{%1, %a0|%a0, %1}"
1595 [(set_attr "type" "imov")
1596 (set_attr "modrm" "0,*")
1597 (set_attr "length_address" "8,0")
1598 (set_attr "length_immediate" "0,*")
1599 (set_attr "memory" "store")
1600 (set_attr "mode" "SI")])
1601
1602 (define_insn "*movabssi_2_rex64"
1603 [(set (match_operand:SI 0 "register_operand" "=a,r")
1604 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1605 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1606 "@
1607 movabs{l}\t{%P1, %0|%0, %P1}
1608 mov{l}\t{%a1, %0|%0, %a1}"
1609 [(set_attr "type" "imov")
1610 (set_attr "modrm" "0,*")
1611 (set_attr "length_address" "8,0")
1612 (set_attr "length_immediate" "0")
1613 (set_attr "memory" "load")
1614 (set_attr "mode" "SI")])
1615
1616 (define_insn "*swapsi"
1617 [(set (match_operand:SI 0 "register_operand" "+r")
1618 (match_operand:SI 1 "register_operand" "+r"))
1619 (set (match_dup 1)
1620 (match_dup 0))]
1621 ""
1622 "xchg{l}\t%1, %0"
1623 [(set_attr "type" "imov")
1624 (set_attr "mode" "SI")
1625 (set_attr "pent_pair" "np")
1626 (set_attr "athlon_decode" "vector")
1627 (set_attr "amdfam10_decode" "double")])
1628
1629 (define_expand "movhi"
1630 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1631 (match_operand:HI 1 "general_operand" ""))]
1632 ""
1633 "ix86_expand_move (HImode, operands); DONE;")
1634
1635 (define_insn "*pushhi2"
1636 [(set (match_operand:HI 0 "push_operand" "=X")
1637 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1638 "!TARGET_64BIT"
1639 "push{l}\t%k1"
1640 [(set_attr "type" "push")
1641 (set_attr "mode" "SI")])
1642
1643 ;; For 64BIT abi we always round up to 8 bytes.
1644 (define_insn "*pushhi2_rex64"
1645 [(set (match_operand:HI 0 "push_operand" "=X")
1646 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1647 "TARGET_64BIT"
1648 "push{q}\t%q1"
1649 [(set_attr "type" "push")
1650 (set_attr "mode" "DI")])
1651
1652 (define_insn "*movhi_1"
1653 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1654 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1655 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1656 {
1657 switch (get_attr_type (insn))
1658 {
1659 case TYPE_IMOVX:
1660 /* movzwl is faster than movw on p2 due to partial word stalls,
1661 though not as fast as an aligned movl. */
1662 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1663 default:
1664 if (get_attr_mode (insn) == MODE_SI)
1665 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1666 else
1667 return "mov{w}\t{%1, %0|%0, %1}";
1668 }
1669 }
1670 [(set (attr "type")
1671 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1672 (const_string "imov")
1673 (and (eq_attr "alternative" "0")
1674 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1675 (const_int 0))
1676 (eq (symbol_ref "TARGET_HIMODE_MATH")
1677 (const_int 0))))
1678 (const_string "imov")
1679 (and (eq_attr "alternative" "1,2")
1680 (match_operand:HI 1 "aligned_operand" ""))
1681 (const_string "imov")
1682 (and (ne (symbol_ref "TARGET_MOVX")
1683 (const_int 0))
1684 (eq_attr "alternative" "0,2"))
1685 (const_string "imovx")
1686 ]
1687 (const_string "imov")))
1688 (set (attr "mode")
1689 (cond [(eq_attr "type" "imovx")
1690 (const_string "SI")
1691 (and (eq_attr "alternative" "1,2")
1692 (match_operand:HI 1 "aligned_operand" ""))
1693 (const_string "SI")
1694 (and (eq_attr "alternative" "0")
1695 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1696 (const_int 0))
1697 (eq (symbol_ref "TARGET_HIMODE_MATH")
1698 (const_int 0))))
1699 (const_string "SI")
1700 ]
1701 (const_string "HI")))])
1702
1703 ;; Stores and loads of ax to arbitrary constant address.
1704 ;; We fake an second form of instruction to force reload to load address
1705 ;; into register when rax is not available
1706 (define_insn "*movabshi_1_rex64"
1707 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1708 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1709 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1710 "@
1711 movabs{w}\t{%1, %P0|%P0, %1}
1712 mov{w}\t{%1, %a0|%a0, %1}"
1713 [(set_attr "type" "imov")
1714 (set_attr "modrm" "0,*")
1715 (set_attr "length_address" "8,0")
1716 (set_attr "length_immediate" "0,*")
1717 (set_attr "memory" "store")
1718 (set_attr "mode" "HI")])
1719
1720 (define_insn "*movabshi_2_rex64"
1721 [(set (match_operand:HI 0 "register_operand" "=a,r")
1722 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1723 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1724 "@
1725 movabs{w}\t{%P1, %0|%0, %P1}
1726 mov{w}\t{%a1, %0|%0, %a1}"
1727 [(set_attr "type" "imov")
1728 (set_attr "modrm" "0,*")
1729 (set_attr "length_address" "8,0")
1730 (set_attr "length_immediate" "0")
1731 (set_attr "memory" "load")
1732 (set_attr "mode" "HI")])
1733
1734 (define_insn "*swaphi_1"
1735 [(set (match_operand:HI 0 "register_operand" "+r")
1736 (match_operand:HI 1 "register_operand" "+r"))
1737 (set (match_dup 1)
1738 (match_dup 0))]
1739 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1740 "xchg{l}\t%k1, %k0"
1741 [(set_attr "type" "imov")
1742 (set_attr "mode" "SI")
1743 (set_attr "pent_pair" "np")
1744 (set_attr "athlon_decode" "vector")
1745 (set_attr "amdfam10_decode" "double")])
1746
1747 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1748 (define_insn "*swaphi_2"
1749 [(set (match_operand:HI 0 "register_operand" "+r")
1750 (match_operand:HI 1 "register_operand" "+r"))
1751 (set (match_dup 1)
1752 (match_dup 0))]
1753 "TARGET_PARTIAL_REG_STALL"
1754 "xchg{w}\t%1, %0"
1755 [(set_attr "type" "imov")
1756 (set_attr "mode" "HI")
1757 (set_attr "pent_pair" "np")
1758 (set_attr "athlon_decode" "vector")])
1759
1760 (define_expand "movstricthi"
1761 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1762 (match_operand:HI 1 "general_operand" ""))]
1763 ""
1764 {
1765 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1766 FAIL;
1767 /* Don't generate memory->memory moves, go through a register */
1768 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1769 operands[1] = force_reg (HImode, operands[1]);
1770 })
1771
1772 (define_insn "*movstricthi_1"
1773 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1774 (match_operand:HI 1 "general_operand" "rn,m"))]
1775 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1776 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1777 "mov{w}\t{%1, %0|%0, %1}"
1778 [(set_attr "type" "imov")
1779 (set_attr "mode" "HI")])
1780
1781 (define_insn "*movstricthi_xor"
1782 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1783 (match_operand:HI 1 "const0_operand" ""))
1784 (clobber (reg:CC FLAGS_REG))]
1785 "reload_completed"
1786 "xor{w}\t%0, %0"
1787 [(set_attr "type" "alu1")
1788 (set_attr "mode" "HI")
1789 (set_attr "length_immediate" "0")])
1790
1791 (define_expand "movqi"
1792 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1793 (match_operand:QI 1 "general_operand" ""))]
1794 ""
1795 "ix86_expand_move (QImode, operands); DONE;")
1796
1797 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1798 ;; "push a byte". But actually we use pushl, which has the effect
1799 ;; of rounding the amount pushed up to a word.
1800
1801 (define_insn "*pushqi2"
1802 [(set (match_operand:QI 0 "push_operand" "=X")
1803 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1804 "!TARGET_64BIT"
1805 "push{l}\t%k1"
1806 [(set_attr "type" "push")
1807 (set_attr "mode" "SI")])
1808
1809 ;; For 64BIT abi we always round up to 8 bytes.
1810 (define_insn "*pushqi2_rex64"
1811 [(set (match_operand:QI 0 "push_operand" "=X")
1812 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1813 "TARGET_64BIT"
1814 "push{q}\t%q1"
1815 [(set_attr "type" "push")
1816 (set_attr "mode" "DI")])
1817
1818 ;; Situation is quite tricky about when to choose full sized (SImode) move
1819 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1820 ;; partial register dependency machines (such as AMD Athlon), where QImode
1821 ;; moves issue extra dependency and for partial register stalls machines
1822 ;; that don't use QImode patterns (and QImode move cause stall on the next
1823 ;; instruction).
1824 ;;
1825 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1826 ;; register stall machines with, where we use QImode instructions, since
1827 ;; partial register stall can be caused there. Then we use movzx.
1828 (define_insn "*movqi_1"
1829 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1830 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1831 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1832 {
1833 switch (get_attr_type (insn))
1834 {
1835 case TYPE_IMOVX:
1836 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1837 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1838 default:
1839 if (get_attr_mode (insn) == MODE_SI)
1840 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1841 else
1842 return "mov{b}\t{%1, %0|%0, %1}";
1843 }
1844 }
1845 [(set (attr "type")
1846 (cond [(and (eq_attr "alternative" "5")
1847 (not (match_operand:QI 1 "aligned_operand" "")))
1848 (const_string "imovx")
1849 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1850 (const_string "imov")
1851 (and (eq_attr "alternative" "3")
1852 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1853 (const_int 0))
1854 (eq (symbol_ref "TARGET_QIMODE_MATH")
1855 (const_int 0))))
1856 (const_string "imov")
1857 (eq_attr "alternative" "3,5")
1858 (const_string "imovx")
1859 (and (ne (symbol_ref "TARGET_MOVX")
1860 (const_int 0))
1861 (eq_attr "alternative" "2"))
1862 (const_string "imovx")
1863 ]
1864 (const_string "imov")))
1865 (set (attr "mode")
1866 (cond [(eq_attr "alternative" "3,4,5")
1867 (const_string "SI")
1868 (eq_attr "alternative" "6")
1869 (const_string "QI")
1870 (eq_attr "type" "imovx")
1871 (const_string "SI")
1872 (and (eq_attr "type" "imov")
1873 (and (eq_attr "alternative" "0,1")
1874 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1875 (const_int 0))
1876 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1877 (const_int 0))
1878 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1879 (const_int 0))))))
1880 (const_string "SI")
1881 ;; Avoid partial register stalls when not using QImode arithmetic
1882 (and (eq_attr "type" "imov")
1883 (and (eq_attr "alternative" "0,1")
1884 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1885 (const_int 0))
1886 (eq (symbol_ref "TARGET_QIMODE_MATH")
1887 (const_int 0)))))
1888 (const_string "SI")
1889 ]
1890 (const_string "QI")))])
1891
1892 (define_insn "*swapqi_1"
1893 [(set (match_operand:QI 0 "register_operand" "+r")
1894 (match_operand:QI 1 "register_operand" "+r"))
1895 (set (match_dup 1)
1896 (match_dup 0))]
1897 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1898 "xchg{l}\t%k1, %k0"
1899 [(set_attr "type" "imov")
1900 (set_attr "mode" "SI")
1901 (set_attr "pent_pair" "np")
1902 (set_attr "athlon_decode" "vector")
1903 (set_attr "amdfam10_decode" "vector")])
1904
1905 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1906 (define_insn "*swapqi_2"
1907 [(set (match_operand:QI 0 "register_operand" "+q")
1908 (match_operand:QI 1 "register_operand" "+q"))
1909 (set (match_dup 1)
1910 (match_dup 0))]
1911 "TARGET_PARTIAL_REG_STALL"
1912 "xchg{b}\t%1, %0"
1913 [(set_attr "type" "imov")
1914 (set_attr "mode" "QI")
1915 (set_attr "pent_pair" "np")
1916 (set_attr "athlon_decode" "vector")])
1917
1918 (define_expand "movstrictqi"
1919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1920 (match_operand:QI 1 "general_operand" ""))]
1921 ""
1922 {
1923 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1924 FAIL;
1925 /* Don't generate memory->memory moves, go through a register. */
1926 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1927 operands[1] = force_reg (QImode, operands[1]);
1928 })
1929
1930 (define_insn "*movstrictqi_1"
1931 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1932 (match_operand:QI 1 "general_operand" "*qn,m"))]
1933 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 "mov{b}\t{%1, %0|%0, %1}"
1936 [(set_attr "type" "imov")
1937 (set_attr "mode" "QI")])
1938
1939 (define_insn "*movstrictqi_xor"
1940 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1941 (match_operand:QI 1 "const0_operand" ""))
1942 (clobber (reg:CC FLAGS_REG))]
1943 "reload_completed"
1944 "xor{b}\t%0, %0"
1945 [(set_attr "type" "alu1")
1946 (set_attr "mode" "QI")
1947 (set_attr "length_immediate" "0")])
1948
1949 (define_insn "*movsi_extv_1"
1950 [(set (match_operand:SI 0 "register_operand" "=R")
1951 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1952 (const_int 8)
1953 (const_int 8)))]
1954 ""
1955 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1956 [(set_attr "type" "imovx")
1957 (set_attr "mode" "SI")])
1958
1959 (define_insn "*movhi_extv_1"
1960 [(set (match_operand:HI 0 "register_operand" "=R")
1961 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1962 (const_int 8)
1963 (const_int 8)))]
1964 ""
1965 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1966 [(set_attr "type" "imovx")
1967 (set_attr "mode" "SI")])
1968
1969 (define_insn "*movqi_extv_1"
1970 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1971 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1972 (const_int 8)
1973 (const_int 8)))]
1974 "!TARGET_64BIT"
1975 {
1976 switch (get_attr_type (insn))
1977 {
1978 case TYPE_IMOVX:
1979 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1980 default:
1981 return "mov{b}\t{%h1, %0|%0, %h1}";
1982 }
1983 }
1984 [(set (attr "type")
1985 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1986 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1987 (ne (symbol_ref "TARGET_MOVX")
1988 (const_int 0))))
1989 (const_string "imovx")
1990 (const_string "imov")))
1991 (set (attr "mode")
1992 (if_then_else (eq_attr "type" "imovx")
1993 (const_string "SI")
1994 (const_string "QI")))])
1995
1996 (define_insn "*movqi_extv_1_rex64"
1997 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1998 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1999 (const_int 8)
2000 (const_int 8)))]
2001 "TARGET_64BIT"
2002 {
2003 switch (get_attr_type (insn))
2004 {
2005 case TYPE_IMOVX:
2006 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2007 default:
2008 return "mov{b}\t{%h1, %0|%0, %h1}";
2009 }
2010 }
2011 [(set (attr "type")
2012 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2013 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2014 (ne (symbol_ref "TARGET_MOVX")
2015 (const_int 0))))
2016 (const_string "imovx")
2017 (const_string "imov")))
2018 (set (attr "mode")
2019 (if_then_else (eq_attr "type" "imovx")
2020 (const_string "SI")
2021 (const_string "QI")))])
2022
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsqi_1_rex64"
2027 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2029 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030 "@
2031 movabs{b}\t{%1, %P0|%P0, %1}
2032 mov{b}\t{%1, %a0|%a0, %1}"
2033 [(set_attr "type" "imov")
2034 (set_attr "modrm" "0,*")
2035 (set_attr "length_address" "8,0")
2036 (set_attr "length_immediate" "0,*")
2037 (set_attr "memory" "store")
2038 (set_attr "mode" "QI")])
2039
2040 (define_insn "*movabsqi_2_rex64"
2041 [(set (match_operand:QI 0 "register_operand" "=a,r")
2042 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044 "@
2045 movabs{b}\t{%P1, %0|%0, %P1}
2046 mov{b}\t{%a1, %0|%0, %a1}"
2047 [(set_attr "type" "imov")
2048 (set_attr "modrm" "0,*")
2049 (set_attr "length_address" "8,0")
2050 (set_attr "length_immediate" "0")
2051 (set_attr "memory" "load")
2052 (set_attr "mode" "QI")])
2053
2054 (define_insn "*movdi_extzv_1"
2055 [(set (match_operand:DI 0 "register_operand" "=R")
2056 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2057 (const_int 8)
2058 (const_int 8)))]
2059 "TARGET_64BIT"
2060 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2061 [(set_attr "type" "imovx")
2062 (set_attr "mode" "DI")])
2063
2064 (define_insn "*movsi_extzv_1"
2065 [(set (match_operand:SI 0 "register_operand" "=R")
2066 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2067 (const_int 8)
2068 (const_int 8)))]
2069 ""
2070 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2071 [(set_attr "type" "imovx")
2072 (set_attr "mode" "SI")])
2073
2074 (define_insn "*movqi_extzv_2"
2075 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2076 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2077 (const_int 8)
2078 (const_int 8)) 0))]
2079 "!TARGET_64BIT"
2080 {
2081 switch (get_attr_type (insn))
2082 {
2083 case TYPE_IMOVX:
2084 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2085 default:
2086 return "mov{b}\t{%h1, %0|%0, %h1}";
2087 }
2088 }
2089 [(set (attr "type")
2090 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2091 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2092 (ne (symbol_ref "TARGET_MOVX")
2093 (const_int 0))))
2094 (const_string "imovx")
2095 (const_string "imov")))
2096 (set (attr "mode")
2097 (if_then_else (eq_attr "type" "imovx")
2098 (const_string "SI")
2099 (const_string "QI")))])
2100
2101 (define_insn "*movqi_extzv_2_rex64"
2102 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2103 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2104 (const_int 8)
2105 (const_int 8)) 0))]
2106 "TARGET_64BIT"
2107 {
2108 switch (get_attr_type (insn))
2109 {
2110 case TYPE_IMOVX:
2111 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2112 default:
2113 return "mov{b}\t{%h1, %0|%0, %h1}";
2114 }
2115 }
2116 [(set (attr "type")
2117 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2118 (ne (symbol_ref "TARGET_MOVX")
2119 (const_int 0)))
2120 (const_string "imovx")
2121 (const_string "imov")))
2122 (set (attr "mode")
2123 (if_then_else (eq_attr "type" "imovx")
2124 (const_string "SI")
2125 (const_string "QI")))])
2126
2127 (define_insn "movsi_insv_1"
2128 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2129 (const_int 8)
2130 (const_int 8))
2131 (match_operand:SI 1 "general_operand" "Qmn"))]
2132 "!TARGET_64BIT"
2133 "mov{b}\t{%b1, %h0|%h0, %b1}"
2134 [(set_attr "type" "imov")
2135 (set_attr "mode" "QI")])
2136
2137 (define_insn "*movsi_insv_1_rex64"
2138 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2139 (const_int 8)
2140 (const_int 8))
2141 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2142 "TARGET_64BIT"
2143 "mov{b}\t{%b1, %h0|%h0, %b1}"
2144 [(set_attr "type" "imov")
2145 (set_attr "mode" "QI")])
2146
2147 (define_insn "movdi_insv_1_rex64"
2148 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2149 (const_int 8)
2150 (const_int 8))
2151 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2152 "TARGET_64BIT"
2153 "mov{b}\t{%b1, %h0|%h0, %b1}"
2154 [(set_attr "type" "imov")
2155 (set_attr "mode" "QI")])
2156
2157 (define_insn "*movqi_insv_2"
2158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2159 (const_int 8)
2160 (const_int 8))
2161 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2162 (const_int 8)))]
2163 ""
2164 "mov{b}\t{%h1, %h0|%h0, %h1}"
2165 [(set_attr "type" "imov")
2166 (set_attr "mode" "QI")])
2167
2168 (define_expand "movdi"
2169 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2170 (match_operand:DI 1 "general_operand" ""))]
2171 ""
2172 "ix86_expand_move (DImode, operands); DONE;")
2173
2174 (define_insn "*pushdi"
2175 [(set (match_operand:DI 0 "push_operand" "=<")
2176 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2177 "!TARGET_64BIT"
2178 "#")
2179
2180 (define_insn "*pushdi2_rex64"
2181 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2182 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2183 "TARGET_64BIT"
2184 "@
2185 push{q}\t%1
2186 #"
2187 [(set_attr "type" "push,multi")
2188 (set_attr "mode" "DI")])
2189
2190 ;; Convert impossible pushes of immediate to existing instructions.
2191 ;; First try to get scratch register and go through it. In case this
2192 ;; fails, push sign extended lower part first and then overwrite
2193 ;; upper part by 32bit move.
2194 (define_peephole2
2195 [(match_scratch:DI 2 "r")
2196 (set (match_operand:DI 0 "push_operand" "")
2197 (match_operand:DI 1 "immediate_operand" ""))]
2198 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2199 && !x86_64_immediate_operand (operands[1], DImode)"
2200 [(set (match_dup 2) (match_dup 1))
2201 (set (match_dup 0) (match_dup 2))]
2202 "")
2203
2204 ;; We need to define this as both peepholer and splitter for case
2205 ;; peephole2 pass is not run.
2206 ;; "&& 1" is needed to keep it from matching the previous pattern.
2207 (define_peephole2
2208 [(set (match_operand:DI 0 "push_operand" "")
2209 (match_operand:DI 1 "immediate_operand" ""))]
2210 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2211 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2212 [(set (match_dup 0) (match_dup 1))
2213 (set (match_dup 2) (match_dup 3))]
2214 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2215 operands[1] = gen_lowpart (DImode, operands[2]);
2216 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2217 GEN_INT (4)));
2218 ")
2219
2220 (define_split
2221 [(set (match_operand:DI 0 "push_operand" "")
2222 (match_operand:DI 1 "immediate_operand" ""))]
2223 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2224 ? epilogue_completed : reload_completed)
2225 && !symbolic_operand (operands[1], DImode)
2226 && !x86_64_immediate_operand (operands[1], DImode)"
2227 [(set (match_dup 0) (match_dup 1))
2228 (set (match_dup 2) (match_dup 3))]
2229 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2230 operands[1] = gen_lowpart (DImode, operands[2]);
2231 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2232 GEN_INT (4)));
2233 ")
2234
2235 (define_insn "*pushdi2_prologue_rex64"
2236 [(set (match_operand:DI 0 "push_operand" "=<")
2237 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2238 (clobber (mem:BLK (scratch)))]
2239 "TARGET_64BIT"
2240 "push{q}\t%1"
2241 [(set_attr "type" "push")
2242 (set_attr "mode" "DI")])
2243
2244 (define_insn "*popdi1_epilogue_rex64"
2245 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2246 (mem:DI (reg:DI SP_REG)))
2247 (set (reg:DI SP_REG)
2248 (plus:DI (reg:DI SP_REG) (const_int 8)))
2249 (clobber (mem:BLK (scratch)))]
2250 "TARGET_64BIT"
2251 "pop{q}\t%0"
2252 [(set_attr "type" "pop")
2253 (set_attr "mode" "DI")])
2254
2255 (define_insn "popdi1"
2256 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2257 (mem:DI (reg:DI SP_REG)))
2258 (set (reg:DI SP_REG)
2259 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2260 "TARGET_64BIT"
2261 "pop{q}\t%0"
2262 [(set_attr "type" "pop")
2263 (set_attr "mode" "DI")])
2264
2265 (define_insn "*movdi_xor_rex64"
2266 [(set (match_operand:DI 0 "register_operand" "=r")
2267 (match_operand:DI 1 "const0_operand" ""))
2268 (clobber (reg:CC FLAGS_REG))]
2269 "TARGET_64BIT
2270 && reload_completed"
2271 "xor{l}\t%k0, %k0";
2272 [(set_attr "type" "alu1")
2273 (set_attr "mode" "SI")
2274 (set_attr "length_immediate" "0")])
2275
2276 (define_insn "*movdi_or_rex64"
2277 [(set (match_operand:DI 0 "register_operand" "=r")
2278 (match_operand:DI 1 "const_int_operand" "i"))
2279 (clobber (reg:CC FLAGS_REG))]
2280 "TARGET_64BIT
2281 && reload_completed
2282 && operands[1] == constm1_rtx"
2283 {
2284 operands[1] = constm1_rtx;
2285 return "or{q}\t{%1, %0|%0, %1}";
2286 }
2287 [(set_attr "type" "alu1")
2288 (set_attr "mode" "DI")
2289 (set_attr "length_immediate" "1")])
2290
2291 (define_insn "*movdi_2"
2292 [(set (match_operand:DI 0 "nonimmediate_operand"
2293 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2294 (match_operand:DI 1 "general_operand"
2295 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2296 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2297 "@
2298 #
2299 #
2300 pxor\t%0, %0
2301 movq\t{%1, %0|%0, %1}
2302 movq\t{%1, %0|%0, %1}
2303 %vpxor\t%0, %d0
2304 %vmovq\t{%1, %0|%0, %1}
2305 %vmovdqa\t{%1, %0|%0, %1}
2306 %vmovq\t{%1, %0|%0, %1}
2307 xorps\t%0, %0
2308 movlps\t{%1, %0|%0, %1}
2309 movaps\t{%1, %0|%0, %1}
2310 movlps\t{%1, %0|%0, %1}"
2311 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2312 (set (attr "prefix")
2313 (if_then_else (eq_attr "alternative" "5,6,7,8")
2314 (const_string "vex")
2315 (const_string "orig")))
2316 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2317
2318 (define_split
2319 [(set (match_operand:DI 0 "push_operand" "")
2320 (match_operand:DI 1 "general_operand" ""))]
2321 "!TARGET_64BIT && reload_completed
2322 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2323 [(const_int 0)]
2324 "ix86_split_long_move (operands); DONE;")
2325
2326 ;; %%% This multiword shite has got to go.
2327 (define_split
2328 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2329 (match_operand:DI 1 "general_operand" ""))]
2330 "!TARGET_64BIT && reload_completed
2331 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2332 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2333 [(const_int 0)]
2334 "ix86_split_long_move (operands); DONE;")
2335
2336 (define_insn "*movdi_1_rex64"
2337 [(set (match_operand:DI 0 "nonimmediate_operand"
2338 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2339 (match_operand:DI 1 "general_operand"
2340 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2341 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2342 {
2343 switch (get_attr_type (insn))
2344 {
2345 case TYPE_SSECVT:
2346 if (SSE_REG_P (operands[0]))
2347 return "movq2dq\t{%1, %0|%0, %1}";
2348 else
2349 return "movdq2q\t{%1, %0|%0, %1}";
2350
2351 case TYPE_SSEMOV:
2352 if (TARGET_AVX)
2353 {
2354 if (get_attr_mode (insn) == MODE_TI)
2355 return "vmovdqa\t{%1, %0|%0, %1}";
2356 else
2357 return "vmovq\t{%1, %0|%0, %1}";
2358 }
2359
2360 if (get_attr_mode (insn) == MODE_TI)
2361 return "movdqa\t{%1, %0|%0, %1}";
2362 /* FALLTHRU */
2363
2364 case TYPE_MMXMOV:
2365 /* Moves from and into integer register is done using movd
2366 opcode with REX prefix. */
2367 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2368 return "movd\t{%1, %0|%0, %1}";
2369 return "movq\t{%1, %0|%0, %1}";
2370
2371 case TYPE_SSELOG1:
2372 return "%vpxor\t%0, %d0";
2373
2374 case TYPE_MMXADD:
2375 return "pxor\t%0, %0";
2376
2377 case TYPE_MULTI:
2378 return "#";
2379
2380 case TYPE_LEA:
2381 return "lea{q}\t{%a1, %0|%0, %a1}";
2382
2383 default:
2384 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2385 if (get_attr_mode (insn) == MODE_SI)
2386 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2387 else if (which_alternative == 2)
2388 return "movabs{q}\t{%1, %0|%0, %1}";
2389 else
2390 return "mov{q}\t{%1, %0|%0, %1}";
2391 }
2392 }
2393 [(set (attr "type")
2394 (cond [(eq_attr "alternative" "5")
2395 (const_string "mmxadd")
2396 (eq_attr "alternative" "6,7,8,9,10")
2397 (const_string "mmxmov")
2398 (eq_attr "alternative" "11")
2399 (const_string "sselog1")
2400 (eq_attr "alternative" "12,13,14,15,16")
2401 (const_string "ssemov")
2402 (eq_attr "alternative" "17,18")
2403 (const_string "ssecvt")
2404 (eq_attr "alternative" "4")
2405 (const_string "multi")
2406 (match_operand:DI 1 "pic_32bit_operand" "")
2407 (const_string "lea")
2408 ]
2409 (const_string "imov")))
2410 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2411 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2412 (set (attr "prefix")
2413 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2414 (const_string "maybe_vex")
2415 (const_string "orig")))
2416 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2417
2418 ;; Stores and loads of ax to arbitrary constant address.
2419 ;; We fake an second form of instruction to force reload to load address
2420 ;; into register when rax is not available
2421 (define_insn "*movabsdi_1_rex64"
2422 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2423 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2424 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2425 "@
2426 movabs{q}\t{%1, %P0|%P0, %1}
2427 mov{q}\t{%1, %a0|%a0, %1}"
2428 [(set_attr "type" "imov")
2429 (set_attr "modrm" "0,*")
2430 (set_attr "length_address" "8,0")
2431 (set_attr "length_immediate" "0,*")
2432 (set_attr "memory" "store")
2433 (set_attr "mode" "DI")])
2434
2435 (define_insn "*movabsdi_2_rex64"
2436 [(set (match_operand:DI 0 "register_operand" "=a,r")
2437 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2438 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2439 "@
2440 movabs{q}\t{%P1, %0|%0, %P1}
2441 mov{q}\t{%a1, %0|%0, %a1}"
2442 [(set_attr "type" "imov")
2443 (set_attr "modrm" "0,*")
2444 (set_attr "length_address" "8,0")
2445 (set_attr "length_immediate" "0")
2446 (set_attr "memory" "load")
2447 (set_attr "mode" "DI")])
2448
2449 ;; Convert impossible stores of immediate to existing instructions.
2450 ;; First try to get scratch register and go through it. In case this
2451 ;; fails, move by 32bit parts.
2452 (define_peephole2
2453 [(match_scratch:DI 2 "r")
2454 (set (match_operand:DI 0 "memory_operand" "")
2455 (match_operand:DI 1 "immediate_operand" ""))]
2456 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2457 && !x86_64_immediate_operand (operands[1], DImode)"
2458 [(set (match_dup 2) (match_dup 1))
2459 (set (match_dup 0) (match_dup 2))]
2460 "")
2461
2462 ;; We need to define this as both peepholer and splitter for case
2463 ;; peephole2 pass is not run.
2464 ;; "&& 1" is needed to keep it from matching the previous pattern.
2465 (define_peephole2
2466 [(set (match_operand:DI 0 "memory_operand" "")
2467 (match_operand:DI 1 "immediate_operand" ""))]
2468 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2469 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2470 [(set (match_dup 2) (match_dup 3))
2471 (set (match_dup 4) (match_dup 5))]
2472 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2473
2474 (define_split
2475 [(set (match_operand:DI 0 "memory_operand" "")
2476 (match_operand:DI 1 "immediate_operand" ""))]
2477 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2478 ? epilogue_completed : reload_completed)
2479 && !symbolic_operand (operands[1], DImode)
2480 && !x86_64_immediate_operand (operands[1], DImode)"
2481 [(set (match_dup 2) (match_dup 3))
2482 (set (match_dup 4) (match_dup 5))]
2483 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2484
2485 (define_insn "*swapdi_rex64"
2486 [(set (match_operand:DI 0 "register_operand" "+r")
2487 (match_operand:DI 1 "register_operand" "+r"))
2488 (set (match_dup 1)
2489 (match_dup 0))]
2490 "TARGET_64BIT"
2491 "xchg{q}\t%1, %0"
2492 [(set_attr "type" "imov")
2493 (set_attr "mode" "DI")
2494 (set_attr "pent_pair" "np")
2495 (set_attr "athlon_decode" "vector")
2496 (set_attr "amdfam10_decode" "double")])
2497
2498 (define_expand "movoi"
2499 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2500 (match_operand:OI 1 "general_operand" ""))]
2501 "TARGET_AVX"
2502 "ix86_expand_move (OImode, operands); DONE;")
2503
2504 (define_insn "*movoi_internal"
2505 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2506 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2507 "TARGET_AVX
2508 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2509 {
2510 switch (which_alternative)
2511 {
2512 case 0:
2513 return "vxorps\t%0, %0, %0";
2514 case 1:
2515 case 2:
2516 if (misaligned_operand (operands[0], OImode)
2517 || misaligned_operand (operands[1], OImode))
2518 return "vmovdqu\t{%1, %0|%0, %1}";
2519 else
2520 return "vmovdqa\t{%1, %0|%0, %1}";
2521 default:
2522 gcc_unreachable ();
2523 }
2524 }
2525 [(set_attr "type" "sselog1,ssemov,ssemov")
2526 (set_attr "prefix" "vex")
2527 (set_attr "mode" "OI")])
2528
2529 (define_expand "movti"
2530 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2531 (match_operand:TI 1 "nonimmediate_operand" ""))]
2532 "TARGET_SSE || TARGET_64BIT"
2533 {
2534 if (TARGET_64BIT)
2535 ix86_expand_move (TImode, operands);
2536 else if (push_operand (operands[0], TImode))
2537 ix86_expand_push (TImode, operands[1]);
2538 else
2539 ix86_expand_vector_move (TImode, operands);
2540 DONE;
2541 })
2542
2543 (define_insn "*movti_internal"
2544 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2545 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2546 "TARGET_SSE && !TARGET_64BIT
2547 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2548 {
2549 switch (which_alternative)
2550 {
2551 case 0:
2552 if (get_attr_mode (insn) == MODE_V4SF)
2553 return "%vxorps\t%0, %d0";
2554 else
2555 return "%vpxor\t%0, %d0";
2556 case 1:
2557 case 2:
2558 /* TDmode values are passed as TImode on the stack. Moving them
2559 to stack may result in unaligned memory access. */
2560 if (misaligned_operand (operands[0], TImode)
2561 || misaligned_operand (operands[1], TImode))
2562 {
2563 if (get_attr_mode (insn) == MODE_V4SF)
2564 return "%vmovups\t{%1, %0|%0, %1}";
2565 else
2566 return "%vmovdqu\t{%1, %0|%0, %1}";
2567 }
2568 else
2569 {
2570 if (get_attr_mode (insn) == MODE_V4SF)
2571 return "%vmovaps\t{%1, %0|%0, %1}";
2572 else
2573 return "%vmovdqa\t{%1, %0|%0, %1}";
2574 }
2575 default:
2576 gcc_unreachable ();
2577 }
2578 }
2579 [(set_attr "type" "sselog1,ssemov,ssemov")
2580 (set_attr "prefix" "maybe_vex")
2581 (set (attr "mode")
2582 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2583 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2584 (const_string "V4SF")
2585 (and (eq_attr "alternative" "2")
2586 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2587 (const_int 0)))
2588 (const_string "V4SF")]
2589 (const_string "TI")))])
2590
2591 (define_insn "*movti_rex64"
2592 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2593 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2594 "TARGET_64BIT
2595 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2596 {
2597 switch (which_alternative)
2598 {
2599 case 0:
2600 case 1:
2601 return "#";
2602 case 2:
2603 if (get_attr_mode (insn) == MODE_V4SF)
2604 return "%vxorps\t%0, %d0";
2605 else
2606 return "%vpxor\t%0, %d0";
2607 case 3:
2608 case 4:
2609 /* TDmode values are passed as TImode on the stack. Moving them
2610 to stack may result in unaligned memory access. */
2611 if (misaligned_operand (operands[0], TImode)
2612 || misaligned_operand (operands[1], TImode))
2613 {
2614 if (get_attr_mode (insn) == MODE_V4SF)
2615 return "%vmovups\t{%1, %0|%0, %1}";
2616 else
2617 return "%vmovdqu\t{%1, %0|%0, %1}";
2618 }
2619 else
2620 {
2621 if (get_attr_mode (insn) == MODE_V4SF)
2622 return "%vmovaps\t{%1, %0|%0, %1}";
2623 else
2624 return "%vmovdqa\t{%1, %0|%0, %1}";
2625 }
2626 default:
2627 gcc_unreachable ();
2628 }
2629 }
2630 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2631 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2632 (set (attr "mode")
2633 (cond [(eq_attr "alternative" "2,3")
2634 (if_then_else
2635 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2636 (const_int 0))
2637 (const_string "V4SF")
2638 (const_string "TI"))
2639 (eq_attr "alternative" "4")
2640 (if_then_else
2641 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2642 (const_int 0))
2643 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2644 (const_int 0)))
2645 (const_string "V4SF")
2646 (const_string "TI"))]
2647 (const_string "DI")))])
2648
2649 (define_split
2650 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2651 (match_operand:TI 1 "general_operand" ""))]
2652 "reload_completed && !SSE_REG_P (operands[0])
2653 && !SSE_REG_P (operands[1])"
2654 [(const_int 0)]
2655 "ix86_split_long_move (operands); DONE;")
2656
2657 ;; This expands to what emit_move_complex would generate if we didn't
2658 ;; have a movti pattern. Having this avoids problems with reload on
2659 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2660 ;; to have around all the time.
2661 (define_expand "movcdi"
2662 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2663 (match_operand:CDI 1 "general_operand" ""))]
2664 ""
2665 {
2666 if (push_operand (operands[0], CDImode))
2667 emit_move_complex_push (CDImode, operands[0], operands[1]);
2668 else
2669 emit_move_complex_parts (operands[0], operands[1]);
2670 DONE;
2671 })
2672
2673 (define_expand "movsf"
2674 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2675 (match_operand:SF 1 "general_operand" ""))]
2676 ""
2677 "ix86_expand_move (SFmode, operands); DONE;")
2678
2679 (define_insn "*pushsf"
2680 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2681 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2682 "!TARGET_64BIT"
2683 {
2684 /* Anything else should be already split before reg-stack. */
2685 gcc_assert (which_alternative == 1);
2686 return "push{l}\t%1";
2687 }
2688 [(set_attr "type" "multi,push,multi")
2689 (set_attr "unit" "i387,*,*")
2690 (set_attr "mode" "SF,SI,SF")])
2691
2692 (define_insn "*pushsf_rex64"
2693 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2694 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2695 "TARGET_64BIT"
2696 {
2697 /* Anything else should be already split before reg-stack. */
2698 gcc_assert (which_alternative == 1);
2699 return "push{q}\t%q1";
2700 }
2701 [(set_attr "type" "multi,push,multi")
2702 (set_attr "unit" "i387,*,*")
2703 (set_attr "mode" "SF,DI,SF")])
2704
2705 (define_split
2706 [(set (match_operand:SF 0 "push_operand" "")
2707 (match_operand:SF 1 "memory_operand" ""))]
2708 "reload_completed
2709 && MEM_P (operands[1])
2710 && (operands[2] = find_constant_src (insn))"
2711 [(set (match_dup 0)
2712 (match_dup 2))])
2713
2714
2715 ;; %%% Kill this when call knows how to work this out.
2716 (define_split
2717 [(set (match_operand:SF 0 "push_operand" "")
2718 (match_operand:SF 1 "any_fp_register_operand" ""))]
2719 "!TARGET_64BIT"
2720 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2721 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2722
2723 (define_split
2724 [(set (match_operand:SF 0 "push_operand" "")
2725 (match_operand:SF 1 "any_fp_register_operand" ""))]
2726 "TARGET_64BIT"
2727 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2728 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2729
2730 (define_insn "*movsf_1"
2731 [(set (match_operand:SF 0 "nonimmediate_operand"
2732 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2733 (match_operand:SF 1 "general_operand"
2734 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2735 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2736 && (reload_in_progress || reload_completed
2737 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2738 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2739 && standard_80387_constant_p (operands[1]))
2740 || GET_CODE (operands[1]) != CONST_DOUBLE
2741 || memory_operand (operands[0], SFmode))"
2742 {
2743 switch (which_alternative)
2744 {
2745 case 0:
2746 case 1:
2747 return output_387_reg_move (insn, operands);
2748
2749 case 2:
2750 return standard_80387_constant_opcode (operands[1]);
2751
2752 case 3:
2753 case 4:
2754 return "mov{l}\t{%1, %0|%0, %1}";
2755 case 5:
2756 if (get_attr_mode (insn) == MODE_TI)
2757 return "%vpxor\t%0, %d0";
2758 else
2759 return "%vxorps\t%0, %d0";
2760 case 6:
2761 if (get_attr_mode (insn) == MODE_V4SF)
2762 return "%vmovaps\t{%1, %0|%0, %1}";
2763 else
2764 return "%vmovss\t{%1, %d0|%d0, %1}";
2765 case 7:
2766 if (TARGET_AVX)
2767 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2768 : "vmovss\t{%1, %0|%0, %1}";
2769 else
2770 return "movss\t{%1, %0|%0, %1}";
2771 case 8:
2772 return "%vmovss\t{%1, %0|%0, %1}";
2773
2774 case 9: case 10: case 14: case 15:
2775 return "movd\t{%1, %0|%0, %1}";
2776 case 12: case 13:
2777 return "%vmovd\t{%1, %0|%0, %1}";
2778
2779 case 11:
2780 return "movq\t{%1, %0|%0, %1}";
2781
2782 default:
2783 gcc_unreachable ();
2784 }
2785 }
2786 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2787 (set (attr "prefix")
2788 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2789 (const_string "maybe_vex")
2790 (const_string "orig")))
2791 (set (attr "mode")
2792 (cond [(eq_attr "alternative" "3,4,9,10")
2793 (const_string "SI")
2794 (eq_attr "alternative" "5")
2795 (if_then_else
2796 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2797 (const_int 0))
2798 (ne (symbol_ref "TARGET_SSE2")
2799 (const_int 0)))
2800 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2801 (const_int 0)))
2802 (const_string "TI")
2803 (const_string "V4SF"))
2804 /* For architectures resolving dependencies on
2805 whole SSE registers use APS move to break dependency
2806 chains, otherwise use short move to avoid extra work.
2807
2808 Do the same for architectures resolving dependencies on
2809 the parts. While in DF mode it is better to always handle
2810 just register parts, the SF mode is different due to lack
2811 of instructions to load just part of the register. It is
2812 better to maintain the whole registers in single format
2813 to avoid problems on using packed logical operations. */
2814 (eq_attr "alternative" "6")
2815 (if_then_else
2816 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2817 (const_int 0))
2818 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2819 (const_int 0)))
2820 (const_string "V4SF")
2821 (const_string "SF"))
2822 (eq_attr "alternative" "11")
2823 (const_string "DI")]
2824 (const_string "SF")))])
2825
2826 (define_insn "*swapsf"
2827 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2828 (match_operand:SF 1 "fp_register_operand" "+f"))
2829 (set (match_dup 1)
2830 (match_dup 0))]
2831 "reload_completed || TARGET_80387"
2832 {
2833 if (STACK_TOP_P (operands[0]))
2834 return "fxch\t%1";
2835 else
2836 return "fxch\t%0";
2837 }
2838 [(set_attr "type" "fxch")
2839 (set_attr "mode" "SF")])
2840
2841 (define_expand "movdf"
2842 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2843 (match_operand:DF 1 "general_operand" ""))]
2844 ""
2845 "ix86_expand_move (DFmode, operands); DONE;")
2846
2847 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2848 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2849 ;; On the average, pushdf using integers can be still shorter. Allow this
2850 ;; pattern for optimize_size too.
2851
2852 (define_insn "*pushdf_nointeger"
2853 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2854 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2855 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2856 {
2857 /* This insn should be already split before reg-stack. */
2858 gcc_unreachable ();
2859 }
2860 [(set_attr "type" "multi")
2861 (set_attr "unit" "i387,*,*,*")
2862 (set_attr "mode" "DF,SI,SI,DF")])
2863
2864 (define_insn "*pushdf_integer"
2865 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2866 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2867 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2868 {
2869 /* This insn should be already split before reg-stack. */
2870 gcc_unreachable ();
2871 }
2872 [(set_attr "type" "multi")
2873 (set_attr "unit" "i387,*,*")
2874 (set_attr "mode" "DF,SI,DF")])
2875
2876 ;; %%% Kill this when call knows how to work this out.
2877 (define_split
2878 [(set (match_operand:DF 0 "push_operand" "")
2879 (match_operand:DF 1 "any_fp_register_operand" ""))]
2880 "reload_completed"
2881 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2882 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2883 "")
2884
2885 (define_split
2886 [(set (match_operand:DF 0 "push_operand" "")
2887 (match_operand:DF 1 "general_operand" ""))]
2888 "reload_completed"
2889 [(const_int 0)]
2890 "ix86_split_long_move (operands); DONE;")
2891
2892 ;; Moving is usually shorter when only FP registers are used. This separate
2893 ;; movdf pattern avoids the use of integer registers for FP operations
2894 ;; when optimizing for size.
2895
2896 (define_insn "*movdf_nointeger"
2897 [(set (match_operand:DF 0 "nonimmediate_operand"
2898 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2899 (match_operand:DF 1 "general_operand"
2900 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2901 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2902 && ((optimize_function_for_size_p (cfun)
2903 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2904 && (reload_in_progress || reload_completed
2905 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2906 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2907 && optimize_function_for_size_p (cfun)
2908 && !memory_operand (operands[0], DFmode)
2909 && standard_80387_constant_p (operands[1]))
2910 || GET_CODE (operands[1]) != CONST_DOUBLE
2911 || ((optimize_function_for_size_p (cfun)
2912 || !TARGET_MEMORY_MISMATCH_STALL
2913 || reload_in_progress || reload_completed)
2914 && memory_operand (operands[0], DFmode)))"
2915 {
2916 switch (which_alternative)
2917 {
2918 case 0:
2919 case 1:
2920 return output_387_reg_move (insn, operands);
2921
2922 case 2:
2923 return standard_80387_constant_opcode (operands[1]);
2924
2925 case 3:
2926 case 4:
2927 return "#";
2928 case 5:
2929 switch (get_attr_mode (insn))
2930 {
2931 case MODE_V4SF:
2932 return "%vxorps\t%0, %d0";
2933 case MODE_V2DF:
2934 return "%vxorpd\t%0, %d0";
2935 case MODE_TI:
2936 return "%vpxor\t%0, %d0";
2937 default:
2938 gcc_unreachable ();
2939 }
2940 case 6:
2941 case 7:
2942 case 8:
2943 switch (get_attr_mode (insn))
2944 {
2945 case MODE_V4SF:
2946 return "%vmovaps\t{%1, %0|%0, %1}";
2947 case MODE_V2DF:
2948 return "%vmovapd\t{%1, %0|%0, %1}";
2949 case MODE_TI:
2950 return "%vmovdqa\t{%1, %0|%0, %1}";
2951 case MODE_DI:
2952 return "%vmovq\t{%1, %0|%0, %1}";
2953 case MODE_DF:
2954 if (TARGET_AVX)
2955 {
2956 if (REG_P (operands[0]) && REG_P (operands[1]))
2957 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2958 else
2959 return "vmovsd\t{%1, %0|%0, %1}";
2960 }
2961 else
2962 return "movsd\t{%1, %0|%0, %1}";
2963 case MODE_V1DF:
2964 if (TARGET_AVX)
2965 {
2966 if (REG_P (operands[0]))
2967 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2968 else
2969 return "vmovlpd\t{%1, %0|%0, %1}";
2970 }
2971 else
2972 return "movlpd\t{%1, %0|%0, %1}";
2973 case MODE_V2SF:
2974 if (TARGET_AVX)
2975 {
2976 if (REG_P (operands[0]))
2977 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2978 else
2979 return "vmovlps\t{%1, %0|%0, %1}";
2980 }
2981 else
2982 return "movlps\t{%1, %0|%0, %1}";
2983 default:
2984 gcc_unreachable ();
2985 }
2986
2987 default:
2988 gcc_unreachable ();
2989 }
2990 }
2991 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2992 (set (attr "prefix")
2993 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2994 (const_string "orig")
2995 (const_string "maybe_vex")))
2996 (set (attr "mode")
2997 (cond [(eq_attr "alternative" "0,1,2")
2998 (const_string "DF")
2999 (eq_attr "alternative" "3,4")
3000 (const_string "SI")
3001
3002 /* For SSE1, we have many fewer alternatives. */
3003 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3004 (cond [(eq_attr "alternative" "5,6")
3005 (const_string "V4SF")
3006 ]
3007 (const_string "V2SF"))
3008
3009 /* xorps is one byte shorter. */
3010 (eq_attr "alternative" "5")
3011 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012 (const_int 0))
3013 (const_string "V4SF")
3014 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3015 (const_int 0))
3016 (const_string "TI")
3017 ]
3018 (const_string "V2DF"))
3019
3020 /* For architectures resolving dependencies on
3021 whole SSE registers use APD move to break dependency
3022 chains, otherwise use short move to avoid extra work.
3023
3024 movaps encodes one byte shorter. */
3025 (eq_attr "alternative" "6")
3026 (cond
3027 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3028 (const_int 0))
3029 (const_string "V4SF")
3030 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3031 (const_int 0))
3032 (const_string "V2DF")
3033 ]
3034 (const_string "DF"))
3035 /* For architectures resolving dependencies on register
3036 parts we may avoid extra work to zero out upper part
3037 of register. */
3038 (eq_attr "alternative" "7")
3039 (if_then_else
3040 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3041 (const_int 0))
3042 (const_string "V1DF")
3043 (const_string "DF"))
3044 ]
3045 (const_string "DF")))])
3046
3047 (define_insn "*movdf_integer_rex64"
3048 [(set (match_operand:DF 0 "nonimmediate_operand"
3049 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3050 (match_operand:DF 1 "general_operand"
3051 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3052 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3053 && (reload_in_progress || reload_completed
3054 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3055 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3056 && optimize_function_for_size_p (cfun)
3057 && standard_80387_constant_p (operands[1]))
3058 || GET_CODE (operands[1]) != CONST_DOUBLE
3059 || memory_operand (operands[0], DFmode))"
3060 {
3061 switch (which_alternative)
3062 {
3063 case 0:
3064 case 1:
3065 return output_387_reg_move (insn, operands);
3066
3067 case 2:
3068 return standard_80387_constant_opcode (operands[1]);
3069
3070 case 3:
3071 case 4:
3072 return "#";
3073
3074 case 5:
3075 switch (get_attr_mode (insn))
3076 {
3077 case MODE_V4SF:
3078 return "%vxorps\t%0, %d0";
3079 case MODE_V2DF:
3080 return "%vxorpd\t%0, %d0";
3081 case MODE_TI:
3082 return "%vpxor\t%0, %d0";
3083 default:
3084 gcc_unreachable ();
3085 }
3086 case 6:
3087 case 7:
3088 case 8:
3089 switch (get_attr_mode (insn))
3090 {
3091 case MODE_V4SF:
3092 return "%vmovaps\t{%1, %0|%0, %1}";
3093 case MODE_V2DF:
3094 return "%vmovapd\t{%1, %0|%0, %1}";
3095 case MODE_TI:
3096 return "%vmovdqa\t{%1, %0|%0, %1}";
3097 case MODE_DI:
3098 return "%vmovq\t{%1, %0|%0, %1}";
3099 case MODE_DF:
3100 if (TARGET_AVX)
3101 {
3102 if (REG_P (operands[0]) && REG_P (operands[1]))
3103 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104 else
3105 return "vmovsd\t{%1, %0|%0, %1}";
3106 }
3107 else
3108 return "movsd\t{%1, %0|%0, %1}";
3109 case MODE_V1DF:
3110 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3111 case MODE_V2SF:
3112 return "%vmovlps\t{%1, %d0|%d0, %1}";
3113 default:
3114 gcc_unreachable ();
3115 }
3116
3117 case 9:
3118 case 10:
3119 return "%vmovd\t{%1, %0|%0, %1}";
3120
3121 default:
3122 gcc_unreachable();
3123 }
3124 }
3125 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3126 (set (attr "prefix")
3127 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3128 (const_string "orig")
3129 (const_string "maybe_vex")))
3130 (set (attr "mode")
3131 (cond [(eq_attr "alternative" "0,1,2")
3132 (const_string "DF")
3133 (eq_attr "alternative" "3,4,9,10")
3134 (const_string "DI")
3135
3136 /* For SSE1, we have many fewer alternatives. */
3137 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138 (cond [(eq_attr "alternative" "5,6")
3139 (const_string "V4SF")
3140 ]
3141 (const_string "V2SF"))
3142
3143 /* xorps is one byte shorter. */
3144 (eq_attr "alternative" "5")
3145 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146 (const_int 0))
3147 (const_string "V4SF")
3148 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3149 (const_int 0))
3150 (const_string "TI")
3151 ]
3152 (const_string "V2DF"))
3153
3154 /* For architectures resolving dependencies on
3155 whole SSE registers use APD move to break dependency
3156 chains, otherwise use short move to avoid extra work.
3157
3158 movaps encodes one byte shorter. */
3159 (eq_attr "alternative" "6")
3160 (cond
3161 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162 (const_int 0))
3163 (const_string "V4SF")
3164 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165 (const_int 0))
3166 (const_string "V2DF")
3167 ]
3168 (const_string "DF"))
3169 /* For architectures resolving dependencies on register
3170 parts we may avoid extra work to zero out upper part
3171 of register. */
3172 (eq_attr "alternative" "7")
3173 (if_then_else
3174 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3175 (const_int 0))
3176 (const_string "V1DF")
3177 (const_string "DF"))
3178 ]
3179 (const_string "DF")))])
3180
3181 (define_insn "*movdf_integer"
3182 [(set (match_operand:DF 0 "nonimmediate_operand"
3183 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3184 (match_operand:DF 1 "general_operand"
3185 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3186 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3187 && optimize_function_for_speed_p (cfun)
3188 && TARGET_INTEGER_DFMODE_MOVES
3189 && (reload_in_progress || reload_completed
3190 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3191 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3192 && optimize_function_for_size_p (cfun)
3193 && standard_80387_constant_p (operands[1]))
3194 || GET_CODE (operands[1]) != CONST_DOUBLE
3195 || memory_operand (operands[0], DFmode))"
3196 {
3197 switch (which_alternative)
3198 {
3199 case 0:
3200 case 1:
3201 return output_387_reg_move (insn, operands);
3202
3203 case 2:
3204 return standard_80387_constant_opcode (operands[1]);
3205
3206 case 3:
3207 case 4:
3208 return "#";
3209
3210 case 5:
3211 switch (get_attr_mode (insn))
3212 {
3213 case MODE_V4SF:
3214 return "xorps\t%0, %0";
3215 case MODE_V2DF:
3216 return "xorpd\t%0, %0";
3217 case MODE_TI:
3218 return "pxor\t%0, %0";
3219 default:
3220 gcc_unreachable ();
3221 }
3222 case 6:
3223 case 7:
3224 case 8:
3225 switch (get_attr_mode (insn))
3226 {
3227 case MODE_V4SF:
3228 return "movaps\t{%1, %0|%0, %1}";
3229 case MODE_V2DF:
3230 return "movapd\t{%1, %0|%0, %1}";
3231 case MODE_TI:
3232 return "movdqa\t{%1, %0|%0, %1}";
3233 case MODE_DI:
3234 return "movq\t{%1, %0|%0, %1}";
3235 case MODE_DF:
3236 return "movsd\t{%1, %0|%0, %1}";
3237 case MODE_V1DF:
3238 return "movlpd\t{%1, %0|%0, %1}";
3239 case MODE_V2SF:
3240 return "movlps\t{%1, %0|%0, %1}";
3241 default:
3242 gcc_unreachable ();
3243 }
3244
3245 default:
3246 gcc_unreachable();
3247 }
3248 }
3249 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3250 (set (attr "mode")
3251 (cond [(eq_attr "alternative" "0,1,2")
3252 (const_string "DF")
3253 (eq_attr "alternative" "3,4")
3254 (const_string "SI")
3255
3256 /* For SSE1, we have many fewer alternatives. */
3257 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3258 (cond [(eq_attr "alternative" "5,6")
3259 (const_string "V4SF")
3260 ]
3261 (const_string "V2SF"))
3262
3263 /* xorps is one byte shorter. */
3264 (eq_attr "alternative" "5")
3265 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3266 (const_int 0))
3267 (const_string "V4SF")
3268 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3269 (const_int 0))
3270 (const_string "TI")
3271 ]
3272 (const_string "V2DF"))
3273
3274 /* For architectures resolving dependencies on
3275 whole SSE registers use APD move to break dependency
3276 chains, otherwise use short move to avoid extra work.
3277
3278 movaps encodes one byte shorter. */
3279 (eq_attr "alternative" "6")
3280 (cond
3281 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3282 (const_int 0))
3283 (const_string "V4SF")
3284 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285 (const_int 0))
3286 (const_string "V2DF")
3287 ]
3288 (const_string "DF"))
3289 /* For architectures resolving dependencies on register
3290 parts we may avoid extra work to zero out upper part
3291 of register. */
3292 (eq_attr "alternative" "7")
3293 (if_then_else
3294 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3295 (const_int 0))
3296 (const_string "V1DF")
3297 (const_string "DF"))
3298 ]
3299 (const_string "DF")))])
3300
3301 (define_split
3302 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3303 (match_operand:DF 1 "general_operand" ""))]
3304 "reload_completed
3305 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3306 && ! (ANY_FP_REG_P (operands[0]) ||
3307 (GET_CODE (operands[0]) == SUBREG
3308 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3309 && ! (ANY_FP_REG_P (operands[1]) ||
3310 (GET_CODE (operands[1]) == SUBREG
3311 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3312 [(const_int 0)]
3313 "ix86_split_long_move (operands); DONE;")
3314
3315 (define_insn "*swapdf"
3316 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3317 (match_operand:DF 1 "fp_register_operand" "+f"))
3318 (set (match_dup 1)
3319 (match_dup 0))]
3320 "reload_completed || TARGET_80387"
3321 {
3322 if (STACK_TOP_P (operands[0]))
3323 return "fxch\t%1";
3324 else
3325 return "fxch\t%0";
3326 }
3327 [(set_attr "type" "fxch")
3328 (set_attr "mode" "DF")])
3329
3330 (define_expand "movxf"
3331 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3332 (match_operand:XF 1 "general_operand" ""))]
3333 ""
3334 "ix86_expand_move (XFmode, operands); DONE;")
3335
3336 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3337 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3338 ;; Pushing using integer instructions is longer except for constants
3339 ;; and direct memory references.
3340 ;; (assuming that any given constant is pushed only once, but this ought to be
3341 ;; handled elsewhere).
3342
3343 (define_insn "*pushxf_nointeger"
3344 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3345 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3346 "optimize_function_for_size_p (cfun)"
3347 {
3348 /* This insn should be already split before reg-stack. */
3349 gcc_unreachable ();
3350 }
3351 [(set_attr "type" "multi")
3352 (set_attr "unit" "i387,*,*")
3353 (set_attr "mode" "XF,SI,SI")])
3354
3355 (define_insn "*pushxf_integer"
3356 [(set (match_operand:XF 0 "push_operand" "=<,<")
3357 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3358 "optimize_function_for_speed_p (cfun)"
3359 {
3360 /* This insn should be already split before reg-stack. */
3361 gcc_unreachable ();
3362 }
3363 [(set_attr "type" "multi")
3364 (set_attr "unit" "i387,*")
3365 (set_attr "mode" "XF,SI")])
3366
3367 (define_split
3368 [(set (match_operand 0 "push_operand" "")
3369 (match_operand 1 "general_operand" ""))]
3370 "reload_completed
3371 && (GET_MODE (operands[0]) == XFmode
3372 || GET_MODE (operands[0]) == DFmode)
3373 && !ANY_FP_REG_P (operands[1])"
3374 [(const_int 0)]
3375 "ix86_split_long_move (operands); DONE;")
3376
3377 (define_split
3378 [(set (match_operand:XF 0 "push_operand" "")
3379 (match_operand:XF 1 "any_fp_register_operand" ""))]
3380 ""
3381 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3382 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3383 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3384
3385 ;; Do not use integer registers when optimizing for size
3386 (define_insn "*movxf_nointeger"
3387 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3388 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3389 "optimize_function_for_size_p (cfun)
3390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3391 && (reload_in_progress || reload_completed
3392 || standard_80387_constant_p (operands[1])
3393 || GET_CODE (operands[1]) != CONST_DOUBLE
3394 || memory_operand (operands[0], XFmode))"
3395 {
3396 switch (which_alternative)
3397 {
3398 case 0:
3399 case 1:
3400 return output_387_reg_move (insn, operands);
3401
3402 case 2:
3403 return standard_80387_constant_opcode (operands[1]);
3404
3405 case 3: case 4:
3406 return "#";
3407 default:
3408 gcc_unreachable ();
3409 }
3410 }
3411 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3412 (set_attr "mode" "XF,XF,XF,SI,SI")])
3413
3414 (define_insn "*movxf_integer"
3415 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3416 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3417 "optimize_function_for_speed_p (cfun)
3418 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3419 && (reload_in_progress || reload_completed
3420 || GET_CODE (operands[1]) != CONST_DOUBLE
3421 || memory_operand (operands[0], XFmode))"
3422 {
3423 switch (which_alternative)
3424 {
3425 case 0:
3426 case 1:
3427 return output_387_reg_move (insn, operands);
3428
3429 case 2:
3430 return standard_80387_constant_opcode (operands[1]);
3431
3432 case 3: case 4:
3433 return "#";
3434
3435 default:
3436 gcc_unreachable ();
3437 }
3438 }
3439 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3440 (set_attr "mode" "XF,XF,XF,SI,SI")])
3441
3442 (define_expand "movtf"
3443 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3444 (match_operand:TF 1 "nonimmediate_operand" ""))]
3445 "TARGET_SSE2"
3446 {
3447 ix86_expand_move (TFmode, operands);
3448 DONE;
3449 })
3450
3451 (define_insn "*movtf_internal"
3452 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3453 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3454 "TARGET_SSE2
3455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3456 {
3457 switch (which_alternative)
3458 {
3459 case 0:
3460 case 1:
3461 if (get_attr_mode (insn) == MODE_V4SF)
3462 return "%vmovaps\t{%1, %0|%0, %1}";
3463 else
3464 return "%vmovdqa\t{%1, %0|%0, %1}";
3465 case 2:
3466 if (get_attr_mode (insn) == MODE_V4SF)
3467 return "%vxorps\t%0, %d0";
3468 else
3469 return "%vpxor\t%0, %d0";
3470 case 3:
3471 case 4:
3472 return "#";
3473 default:
3474 gcc_unreachable ();
3475 }
3476 }
3477 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3478 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3479 (set (attr "mode")
3480 (cond [(eq_attr "alternative" "0,2")
3481 (if_then_else
3482 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3483 (const_int 0))
3484 (const_string "V4SF")
3485 (const_string "TI"))
3486 (eq_attr "alternative" "1")
3487 (if_then_else
3488 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3489 (const_int 0))
3490 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3491 (const_int 0)))
3492 (const_string "V4SF")
3493 (const_string "TI"))]
3494 (const_string "DI")))])
3495
3496 (define_insn "*pushtf_sse"
3497 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3498 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3499 "TARGET_SSE2"
3500 {
3501 /* This insn should be already split before reg-stack. */
3502 gcc_unreachable ();
3503 }
3504 [(set_attr "type" "multi")
3505 (set_attr "unit" "sse,*,*")
3506 (set_attr "mode" "TF,SI,SI")])
3507
3508 (define_split
3509 [(set (match_operand:TF 0 "push_operand" "")
3510 (match_operand:TF 1 "general_operand" ""))]
3511 "TARGET_SSE2 && reload_completed
3512 && !SSE_REG_P (operands[1])"
3513 [(const_int 0)]
3514 "ix86_split_long_move (operands); DONE;")
3515
3516 (define_split
3517 [(set (match_operand:TF 0 "push_operand" "")
3518 (match_operand:TF 1 "any_fp_register_operand" ""))]
3519 "TARGET_SSE2"
3520 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3521 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3522 "")
3523
3524 (define_split
3525 [(set (match_operand 0 "nonimmediate_operand" "")
3526 (match_operand 1 "general_operand" ""))]
3527 "reload_completed
3528 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3529 && GET_MODE (operands[0]) == XFmode
3530 && ! (ANY_FP_REG_P (operands[0]) ||
3531 (GET_CODE (operands[0]) == SUBREG
3532 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3533 && ! (ANY_FP_REG_P (operands[1]) ||
3534 (GET_CODE (operands[1]) == SUBREG
3535 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3536 [(const_int 0)]
3537 "ix86_split_long_move (operands); DONE;")
3538
3539 (define_split
3540 [(set (match_operand 0 "register_operand" "")
3541 (match_operand 1 "memory_operand" ""))]
3542 "reload_completed
3543 && MEM_P (operands[1])
3544 && (GET_MODE (operands[0]) == TFmode
3545 || GET_MODE (operands[0]) == XFmode
3546 || GET_MODE (operands[0]) == SFmode
3547 || GET_MODE (operands[0]) == DFmode)
3548 && (operands[2] = find_constant_src (insn))"
3549 [(set (match_dup 0) (match_dup 2))]
3550 {
3551 rtx c = operands[2];
3552 rtx r = operands[0];
3553
3554 if (GET_CODE (r) == SUBREG)
3555 r = SUBREG_REG (r);
3556
3557 if (SSE_REG_P (r))
3558 {
3559 if (!standard_sse_constant_p (c))
3560 FAIL;
3561 }
3562 else if (FP_REG_P (r))
3563 {
3564 if (!standard_80387_constant_p (c))
3565 FAIL;
3566 }
3567 else if (MMX_REG_P (r))
3568 FAIL;
3569 })
3570
3571 (define_split
3572 [(set (match_operand 0 "register_operand" "")
3573 (float_extend (match_operand 1 "memory_operand" "")))]
3574 "reload_completed
3575 && MEM_P (operands[1])
3576 && (GET_MODE (operands[0]) == TFmode
3577 || GET_MODE (operands[0]) == XFmode
3578 || GET_MODE (operands[0]) == SFmode
3579 || GET_MODE (operands[0]) == DFmode)
3580 && (operands[2] = find_constant_src (insn))"
3581 [(set (match_dup 0) (match_dup 2))]
3582 {
3583 rtx c = operands[2];
3584 rtx r = operands[0];
3585
3586 if (GET_CODE (r) == SUBREG)
3587 r = SUBREG_REG (r);
3588
3589 if (SSE_REG_P (r))
3590 {
3591 if (!standard_sse_constant_p (c))
3592 FAIL;
3593 }
3594 else if (FP_REG_P (r))
3595 {
3596 if (!standard_80387_constant_p (c))
3597 FAIL;
3598 }
3599 else if (MMX_REG_P (r))
3600 FAIL;
3601 })
3602
3603 (define_insn "swapxf"
3604 [(set (match_operand:XF 0 "register_operand" "+f")
3605 (match_operand:XF 1 "register_operand" "+f"))
3606 (set (match_dup 1)
3607 (match_dup 0))]
3608 "TARGET_80387"
3609 {
3610 if (STACK_TOP_P (operands[0]))
3611 return "fxch\t%1";
3612 else
3613 return "fxch\t%0";
3614 }
3615 [(set_attr "type" "fxch")
3616 (set_attr "mode" "XF")])
3617
3618 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3619 (define_split
3620 [(set (match_operand:X87MODEF 0 "register_operand" "")
3621 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3622 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3623 && (standard_80387_constant_p (operands[1]) == 8
3624 || standard_80387_constant_p (operands[1]) == 9)"
3625 [(set (match_dup 0)(match_dup 1))
3626 (set (match_dup 0)
3627 (neg:X87MODEF (match_dup 0)))]
3628 {
3629 REAL_VALUE_TYPE r;
3630
3631 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3632 if (real_isnegzero (&r))
3633 operands[1] = CONST0_RTX (<MODE>mode);
3634 else
3635 operands[1] = CONST1_RTX (<MODE>mode);
3636 })
3637
3638 (define_split
3639 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3640 (match_operand:TF 1 "general_operand" ""))]
3641 "reload_completed
3642 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3643 [(const_int 0)]
3644 "ix86_split_long_move (operands); DONE;")
3645 \f
3646 ;; Zero extension instructions
3647
3648 (define_expand "zero_extendhisi2"
3649 [(set (match_operand:SI 0 "register_operand" "")
3650 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3651 ""
3652 {
3653 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3654 {
3655 operands[1] = force_reg (HImode, operands[1]);
3656 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3657 DONE;
3658 }
3659 })
3660
3661 (define_insn "zero_extendhisi2_and"
3662 [(set (match_operand:SI 0 "register_operand" "=r")
3663 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3664 (clobber (reg:CC FLAGS_REG))]
3665 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3666 "#"
3667 [(set_attr "type" "alu1")
3668 (set_attr "mode" "SI")])
3669
3670 (define_split
3671 [(set (match_operand:SI 0 "register_operand" "")
3672 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3673 (clobber (reg:CC FLAGS_REG))]
3674 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3675 && optimize_function_for_speed_p (cfun)"
3676 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3677 (clobber (reg:CC FLAGS_REG))])]
3678 "")
3679
3680 (define_insn "*zero_extendhisi2_movzwl"
3681 [(set (match_operand:SI 0 "register_operand" "=r")
3682 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683 "!TARGET_ZERO_EXTEND_WITH_AND
3684 || optimize_function_for_size_p (cfun)"
3685 "movz{wl|x}\t{%1, %0|%0, %1}"
3686 [(set_attr "type" "imovx")
3687 (set_attr "mode" "SI")])
3688
3689 (define_expand "zero_extendqihi2"
3690 [(parallel
3691 [(set (match_operand:HI 0 "register_operand" "")
3692 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3693 (clobber (reg:CC FLAGS_REG))])]
3694 ""
3695 "")
3696
3697 (define_insn "*zero_extendqihi2_and"
3698 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3699 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3700 (clobber (reg:CC FLAGS_REG))]
3701 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3702 "#"
3703 [(set_attr "type" "alu1")
3704 (set_attr "mode" "HI")])
3705
3706 (define_insn "*zero_extendqihi2_movzbw_and"
3707 [(set (match_operand:HI 0 "register_operand" "=r,r")
3708 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3709 (clobber (reg:CC FLAGS_REG))]
3710 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3711 "#"
3712 [(set_attr "type" "imovx,alu1")
3713 (set_attr "mode" "HI")])
3714
3715 ; zero extend to SImode here to avoid partial register stalls
3716 (define_insn "*zero_extendqihi2_movzbl"
3717 [(set (match_operand:HI 0 "register_operand" "=r")
3718 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3719 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3720 && reload_completed"
3721 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "SI")])
3724
3725 ;; For the movzbw case strip only the clobber
3726 (define_split
3727 [(set (match_operand:HI 0 "register_operand" "")
3728 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3729 (clobber (reg:CC FLAGS_REG))]
3730 "reload_completed
3731 && (!TARGET_ZERO_EXTEND_WITH_AND
3732 || optimize_function_for_size_p (cfun))
3733 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3734 [(set (match_operand:HI 0 "register_operand" "")
3735 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3736
3737 ;; When source and destination does not overlap, clear destination
3738 ;; first and then do the movb
3739 (define_split
3740 [(set (match_operand:HI 0 "register_operand" "")
3741 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3742 (clobber (reg:CC FLAGS_REG))]
3743 "reload_completed
3744 && ANY_QI_REG_P (operands[0])
3745 && (TARGET_ZERO_EXTEND_WITH_AND
3746 && optimize_function_for_speed_p (cfun))
3747 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3748 [(set (match_dup 0) (const_int 0))
3749 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3750 "operands[2] = gen_lowpart (QImode, operands[0]);")
3751
3752 ;; Rest is handled by single and.
3753 (define_split
3754 [(set (match_operand:HI 0 "register_operand" "")
3755 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3756 (clobber (reg:CC FLAGS_REG))]
3757 "reload_completed
3758 && true_regnum (operands[0]) == true_regnum (operands[1])"
3759 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3760 (clobber (reg:CC FLAGS_REG))])]
3761 "")
3762
3763 (define_expand "zero_extendqisi2"
3764 [(parallel
3765 [(set (match_operand:SI 0 "register_operand" "")
3766 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3767 (clobber (reg:CC FLAGS_REG))])]
3768 ""
3769 "")
3770
3771 (define_insn "*zero_extendqisi2_and"
3772 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3773 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3774 (clobber (reg:CC FLAGS_REG))]
3775 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3776 "#"
3777 [(set_attr "type" "alu1")
3778 (set_attr "mode" "SI")])
3779
3780 (define_insn "*zero_extendqisi2_movzbw_and"
3781 [(set (match_operand:SI 0 "register_operand" "=r,r")
3782 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3783 (clobber (reg:CC FLAGS_REG))]
3784 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3785 "#"
3786 [(set_attr "type" "imovx,alu1")
3787 (set_attr "mode" "SI")])
3788
3789 (define_insn "*zero_extendqisi2_movzbw"
3790 [(set (match_operand:SI 0 "register_operand" "=r")
3791 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3792 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3793 && reload_completed"
3794 "movz{bl|x}\t{%1, %0|%0, %1}"
3795 [(set_attr "type" "imovx")
3796 (set_attr "mode" "SI")])
3797
3798 ;; For the movzbl case strip only the clobber
3799 (define_split
3800 [(set (match_operand:SI 0 "register_operand" "")
3801 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3802 (clobber (reg:CC FLAGS_REG))]
3803 "reload_completed
3804 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3805 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3806 [(set (match_dup 0)
3807 (zero_extend:SI (match_dup 1)))])
3808
3809 ;; When source and destination does not overlap, clear destination
3810 ;; first and then do the movb
3811 (define_split
3812 [(set (match_operand:SI 0 "register_operand" "")
3813 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3814 (clobber (reg:CC FLAGS_REG))]
3815 "reload_completed
3816 && ANY_QI_REG_P (operands[0])
3817 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3818 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3819 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3820 [(set (match_dup 0) (const_int 0))
3821 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3822 "operands[2] = gen_lowpart (QImode, operands[0]);")
3823
3824 ;; Rest is handled by single and.
3825 (define_split
3826 [(set (match_operand:SI 0 "register_operand" "")
3827 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3828 (clobber (reg:CC FLAGS_REG))]
3829 "reload_completed
3830 && true_regnum (operands[0]) == true_regnum (operands[1])"
3831 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3832 (clobber (reg:CC FLAGS_REG))])]
3833 "")
3834
3835 ;; %%% Kill me once multi-word ops are sane.
3836 (define_expand "zero_extendsidi2"
3837 [(set (match_operand:DI 0 "register_operand" "")
3838 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3839 ""
3840 {
3841 if (!TARGET_64BIT)
3842 {
3843 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3844 DONE;
3845 }
3846 })
3847
3848 (define_insn "zero_extendsidi2_32"
3849 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3850 (zero_extend:DI
3851 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3852 (clobber (reg:CC FLAGS_REG))]
3853 "!TARGET_64BIT"
3854 "@
3855 #
3856 #
3857 #
3858 movd\t{%1, %0|%0, %1}
3859 movd\t{%1, %0|%0, %1}
3860 %vmovd\t{%1, %0|%0, %1}
3861 %vmovd\t{%1, %0|%0, %1}"
3862 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3863 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3864 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3865
3866 (define_insn "zero_extendsidi2_rex64"
3867 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3868 (zero_extend:DI
3869 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3870 "TARGET_64BIT"
3871 "@
3872 mov\t{%k1, %k0|%k0, %k1}
3873 #
3874 movd\t{%1, %0|%0, %1}
3875 movd\t{%1, %0|%0, %1}
3876 %vmovd\t{%1, %0|%0, %1}
3877 %vmovd\t{%1, %0|%0, %1}"
3878 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3879 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3880 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3881
3882 (define_split
3883 [(set (match_operand:DI 0 "memory_operand" "")
3884 (zero_extend:DI (match_dup 0)))]
3885 "TARGET_64BIT"
3886 [(set (match_dup 4) (const_int 0))]
3887 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3888
3889 (define_split
3890 [(set (match_operand:DI 0 "register_operand" "")
3891 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3892 (clobber (reg:CC FLAGS_REG))]
3893 "!TARGET_64BIT && reload_completed
3894 && true_regnum (operands[0]) == true_regnum (operands[1])"
3895 [(set (match_dup 4) (const_int 0))]
3896 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3897
3898 (define_split
3899 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3900 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3901 (clobber (reg:CC FLAGS_REG))]
3902 "!TARGET_64BIT && reload_completed
3903 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3904 [(set (match_dup 3) (match_dup 1))
3905 (set (match_dup 4) (const_int 0))]
3906 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3907
3908 (define_insn "zero_extendhidi2"
3909 [(set (match_operand:DI 0 "register_operand" "=r")
3910 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3911 "TARGET_64BIT"
3912 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3913 [(set_attr "type" "imovx")
3914 (set_attr "mode" "DI")])
3915
3916 (define_insn "zero_extendqidi2"
3917 [(set (match_operand:DI 0 "register_operand" "=r")
3918 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3919 "TARGET_64BIT"
3920 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3921 [(set_attr "type" "imovx")
3922 (set_attr "mode" "DI")])
3923 \f
3924 ;; Sign extension instructions
3925
3926 (define_expand "extendsidi2"
3927 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3928 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3929 (clobber (reg:CC FLAGS_REG))
3930 (clobber (match_scratch:SI 2 ""))])]
3931 ""
3932 {
3933 if (TARGET_64BIT)
3934 {
3935 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3936 DONE;
3937 }
3938 })
3939
3940 (define_insn "*extendsidi2_1"
3941 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3942 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3943 (clobber (reg:CC FLAGS_REG))
3944 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3945 "!TARGET_64BIT"
3946 "#")
3947
3948 (define_insn "extendsidi2_rex64"
3949 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3950 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3951 "TARGET_64BIT"
3952 "@
3953 {cltq|cdqe}
3954 movs{lq|x}\t{%1,%0|%0, %1}"
3955 [(set_attr "type" "imovx")
3956 (set_attr "mode" "DI")
3957 (set_attr "prefix_0f" "0")
3958 (set_attr "modrm" "0,1")])
3959
3960 (define_insn "extendhidi2"
3961 [(set (match_operand:DI 0 "register_operand" "=r")
3962 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3963 "TARGET_64BIT"
3964 "movs{wq|x}\t{%1,%0|%0, %1}"
3965 [(set_attr "type" "imovx")
3966 (set_attr "mode" "DI")])
3967
3968 (define_insn "extendqidi2"
3969 [(set (match_operand:DI 0 "register_operand" "=r")
3970 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3971 "TARGET_64BIT"
3972 "movs{bq|x}\t{%1,%0|%0, %1}"
3973 [(set_attr "type" "imovx")
3974 (set_attr "mode" "DI")])
3975
3976 ;; Extend to memory case when source register does die.
3977 (define_split
3978 [(set (match_operand:DI 0 "memory_operand" "")
3979 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3980 (clobber (reg:CC FLAGS_REG))
3981 (clobber (match_operand:SI 2 "register_operand" ""))]
3982 "(reload_completed
3983 && dead_or_set_p (insn, operands[1])
3984 && !reg_mentioned_p (operands[1], operands[0]))"
3985 [(set (match_dup 3) (match_dup 1))
3986 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3987 (clobber (reg:CC FLAGS_REG))])
3988 (set (match_dup 4) (match_dup 1))]
3989 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3990
3991 ;; Extend to memory case when source register does not die.
3992 (define_split
3993 [(set (match_operand:DI 0 "memory_operand" "")
3994 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3995 (clobber (reg:CC FLAGS_REG))
3996 (clobber (match_operand:SI 2 "register_operand" ""))]
3997 "reload_completed"
3998 [(const_int 0)]
3999 {
4000 split_di (&operands[0], 1, &operands[3], &operands[4]);
4001
4002 emit_move_insn (operands[3], operands[1]);
4003
4004 /* Generate a cltd if possible and doing so it profitable. */
4005 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4006 && true_regnum (operands[1]) == AX_REG
4007 && true_regnum (operands[2]) == DX_REG)
4008 {
4009 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4010 }
4011 else
4012 {
4013 emit_move_insn (operands[2], operands[1]);
4014 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4015 }
4016 emit_move_insn (operands[4], operands[2]);
4017 DONE;
4018 })
4019
4020 ;; Extend to register case. Optimize case where source and destination
4021 ;; registers match and cases where we can use cltd.
4022 (define_split
4023 [(set (match_operand:DI 0 "register_operand" "")
4024 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4025 (clobber (reg:CC FLAGS_REG))
4026 (clobber (match_scratch:SI 2 ""))]
4027 "reload_completed"
4028 [(const_int 0)]
4029 {
4030 split_di (&operands[0], 1, &operands[3], &operands[4]);
4031
4032 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4033 emit_move_insn (operands[3], operands[1]);
4034
4035 /* Generate a cltd if possible and doing so it profitable. */
4036 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4037 && true_regnum (operands[3]) == AX_REG)
4038 {
4039 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4040 DONE;
4041 }
4042
4043 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4044 emit_move_insn (operands[4], operands[1]);
4045
4046 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4047 DONE;
4048 })
4049
4050 (define_insn "extendhisi2"
4051 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4052 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4053 ""
4054 {
4055 switch (get_attr_prefix_0f (insn))
4056 {
4057 case 0:
4058 return "{cwtl|cwde}";
4059 default:
4060 return "movs{wl|x}\t{%1,%0|%0, %1}";
4061 }
4062 }
4063 [(set_attr "type" "imovx")
4064 (set_attr "mode" "SI")
4065 (set (attr "prefix_0f")
4066 ;; movsx is short decodable while cwtl is vector decoded.
4067 (if_then_else (and (eq_attr "cpu" "!k6")
4068 (eq_attr "alternative" "0"))
4069 (const_string "0")
4070 (const_string "1")))
4071 (set (attr "modrm")
4072 (if_then_else (eq_attr "prefix_0f" "0")
4073 (const_string "0")
4074 (const_string "1")))])
4075
4076 (define_insn "*extendhisi2_zext"
4077 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4078 (zero_extend:DI
4079 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4080 "TARGET_64BIT"
4081 {
4082 switch (get_attr_prefix_0f (insn))
4083 {
4084 case 0:
4085 return "{cwtl|cwde}";
4086 default:
4087 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4088 }
4089 }
4090 [(set_attr "type" "imovx")
4091 (set_attr "mode" "SI")
4092 (set (attr "prefix_0f")
4093 ;; movsx is short decodable while cwtl is vector decoded.
4094 (if_then_else (and (eq_attr "cpu" "!k6")
4095 (eq_attr "alternative" "0"))
4096 (const_string "0")
4097 (const_string "1")))
4098 (set (attr "modrm")
4099 (if_then_else (eq_attr "prefix_0f" "0")
4100 (const_string "0")
4101 (const_string "1")))])
4102
4103 (define_insn "extendqihi2"
4104 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4105 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4106 ""
4107 {
4108 switch (get_attr_prefix_0f (insn))
4109 {
4110 case 0:
4111 return "{cbtw|cbw}";
4112 default:
4113 return "movs{bw|x}\t{%1,%0|%0, %1}";
4114 }
4115 }
4116 [(set_attr "type" "imovx")
4117 (set_attr "mode" "HI")
4118 (set (attr "prefix_0f")
4119 ;; movsx is short decodable while cwtl is vector decoded.
4120 (if_then_else (and (eq_attr "cpu" "!k6")
4121 (eq_attr "alternative" "0"))
4122 (const_string "0")
4123 (const_string "1")))
4124 (set (attr "modrm")
4125 (if_then_else (eq_attr "prefix_0f" "0")
4126 (const_string "0")
4127 (const_string "1")))])
4128
4129 (define_insn "extendqisi2"
4130 [(set (match_operand:SI 0 "register_operand" "=r")
4131 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4132 ""
4133 "movs{bl|x}\t{%1,%0|%0, %1}"
4134 [(set_attr "type" "imovx")
4135 (set_attr "mode" "SI")])
4136
4137 (define_insn "*extendqisi2_zext"
4138 [(set (match_operand:DI 0 "register_operand" "=r")
4139 (zero_extend:DI
4140 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4141 "TARGET_64BIT"
4142 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4143 [(set_attr "type" "imovx")
4144 (set_attr "mode" "SI")])
4145 \f
4146 ;; Conversions between float and double.
4147
4148 ;; These are all no-ops in the model used for the 80387. So just
4149 ;; emit moves.
4150
4151 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4152 (define_insn "*dummy_extendsfdf2"
4153 [(set (match_operand:DF 0 "push_operand" "=<")
4154 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4155 "0"
4156 "#")
4157
4158 (define_split
4159 [(set (match_operand:DF 0 "push_operand" "")
4160 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4161 ""
4162 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4163 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4164
4165 (define_insn "*dummy_extendsfxf2"
4166 [(set (match_operand:XF 0 "push_operand" "=<")
4167 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4168 "0"
4169 "#")
4170
4171 (define_split
4172 [(set (match_operand:XF 0 "push_operand" "")
4173 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4174 ""
4175 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4176 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4177 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4178
4179 (define_split
4180 [(set (match_operand:XF 0 "push_operand" "")
4181 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4182 ""
4183 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4184 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4185 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4186
4187 (define_expand "extendsfdf2"
4188 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4189 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4190 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4191 {
4192 /* ??? Needed for compress_float_constant since all fp constants
4193 are LEGITIMATE_CONSTANT_P. */
4194 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4195 {
4196 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4197 && standard_80387_constant_p (operands[1]) > 0)
4198 {
4199 operands[1] = simplify_const_unary_operation
4200 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4201 emit_move_insn_1 (operands[0], operands[1]);
4202 DONE;
4203 }
4204 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4205 }
4206 })
4207
4208 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4209 cvtss2sd:
4210 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4211 cvtps2pd xmm2,xmm1
4212 We do the conversion post reload to avoid producing of 128bit spills
4213 that might lead to ICE on 32bit target. The sequence unlikely combine
4214 anyway. */
4215 (define_split
4216 [(set (match_operand:DF 0 "register_operand" "")
4217 (float_extend:DF
4218 (match_operand:SF 1 "nonimmediate_operand" "")))]
4219 "TARGET_USE_VECTOR_FP_CONVERTS
4220 && optimize_insn_for_speed_p ()
4221 && reload_completed && SSE_REG_P (operands[0])"
4222 [(set (match_dup 2)
4223 (float_extend:V2DF
4224 (vec_select:V2SF
4225 (match_dup 3)
4226 (parallel [(const_int 0) (const_int 1)]))))]
4227 {
4228 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4229 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4230 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4231 Try to avoid move when unpacking can be done in source. */
4232 if (REG_P (operands[1]))
4233 {
4234 /* If it is unsafe to overwrite upper half of source, we need
4235 to move to destination and unpack there. */
4236 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4237 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4238 && true_regnum (operands[0]) != true_regnum (operands[1]))
4239 {
4240 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4241 emit_move_insn (tmp, operands[1]);
4242 }
4243 else
4244 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4245 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4246 }
4247 else
4248 emit_insn (gen_vec_setv4sf_0 (operands[3],
4249 CONST0_RTX (V4SFmode), operands[1]));
4250 })
4251
4252 (define_insn "*extendsfdf2_mixed"
4253 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4254 (float_extend:DF
4255 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4256 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4257 {
4258 switch (which_alternative)
4259 {
4260 case 0:
4261 case 1:
4262 return output_387_reg_move (insn, operands);
4263
4264 case 2:
4265 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4266
4267 default:
4268 gcc_unreachable ();
4269 }
4270 }
4271 [(set_attr "type" "fmov,fmov,ssecvt")
4272 (set_attr "prefix" "orig,orig,maybe_vex")
4273 (set_attr "mode" "SF,XF,DF")])
4274
4275 (define_insn "*extendsfdf2_sse"
4276 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4277 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4278 "TARGET_SSE2 && TARGET_SSE_MATH"
4279 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4280 [(set_attr "type" "ssecvt")
4281 (set_attr "prefix" "maybe_vex")
4282 (set_attr "mode" "DF")])
4283
4284 (define_insn "*extendsfdf2_i387"
4285 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4286 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4287 "TARGET_80387"
4288 "* return output_387_reg_move (insn, operands);"
4289 [(set_attr "type" "fmov")
4290 (set_attr "mode" "SF,XF")])
4291
4292 (define_expand "extend<mode>xf2"
4293 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4294 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4295 "TARGET_80387"
4296 {
4297 /* ??? Needed for compress_float_constant since all fp constants
4298 are LEGITIMATE_CONSTANT_P. */
4299 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4300 {
4301 if (standard_80387_constant_p (operands[1]) > 0)
4302 {
4303 operands[1] = simplify_const_unary_operation
4304 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4305 emit_move_insn_1 (operands[0], operands[1]);
4306 DONE;
4307 }
4308 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4309 }
4310 })
4311
4312 (define_insn "*extend<mode>xf2_i387"
4313 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4314 (float_extend:XF
4315 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4316 "TARGET_80387"
4317 "* return output_387_reg_move (insn, operands);"
4318 [(set_attr "type" "fmov")
4319 (set_attr "mode" "<MODE>,XF")])
4320
4321 ;; %%% This seems bad bad news.
4322 ;; This cannot output into an f-reg because there is no way to be sure
4323 ;; of truncating in that case. Otherwise this is just like a simple move
4324 ;; insn. So we pretend we can output to a reg in order to get better
4325 ;; register preferencing, but we really use a stack slot.
4326
4327 ;; Conversion from DFmode to SFmode.
4328
4329 (define_expand "truncdfsf2"
4330 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4331 (float_truncate:SF
4332 (match_operand:DF 1 "nonimmediate_operand" "")))]
4333 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4334 {
4335 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4336 ;
4337 else if (flag_unsafe_math_optimizations)
4338 ;
4339 else
4340 {
4341 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4342 rtx temp = assign_386_stack_local (SFmode, slot);
4343 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4344 DONE;
4345 }
4346 })
4347
4348 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4349 cvtsd2ss:
4350 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4351 cvtpd2ps xmm2,xmm1
4352 We do the conversion post reload to avoid producing of 128bit spills
4353 that might lead to ICE on 32bit target. The sequence unlikely combine
4354 anyway. */
4355 (define_split
4356 [(set (match_operand:SF 0 "register_operand" "")
4357 (float_truncate:SF
4358 (match_operand:DF 1 "nonimmediate_operand" "")))]
4359 "TARGET_USE_VECTOR_FP_CONVERTS
4360 && optimize_insn_for_speed_p ()
4361 && reload_completed && SSE_REG_P (operands[0])"
4362 [(set (match_dup 2)
4363 (vec_concat:V4SF
4364 (float_truncate:V2SF
4365 (match_dup 4))
4366 (match_dup 3)))]
4367 {
4368 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4369 operands[3] = CONST0_RTX (V2SFmode);
4370 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4371 /* Use movsd for loading from memory, unpcklpd for registers.
4372 Try to avoid move when unpacking can be done in source, or SSE3
4373 movddup is available. */
4374 if (REG_P (operands[1]))
4375 {
4376 if (!TARGET_SSE3
4377 && true_regnum (operands[0]) != true_regnum (operands[1])
4378 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4379 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4380 {
4381 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4382 emit_move_insn (tmp, operands[1]);
4383 operands[1] = tmp;
4384 }
4385 else if (!TARGET_SSE3)
4386 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4387 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4388 }
4389 else
4390 emit_insn (gen_sse2_loadlpd (operands[4],
4391 CONST0_RTX (V2DFmode), operands[1]));
4392 })
4393
4394 (define_expand "truncdfsf2_with_temp"
4395 [(parallel [(set (match_operand:SF 0 "" "")
4396 (float_truncate:SF (match_operand:DF 1 "" "")))
4397 (clobber (match_operand:SF 2 "" ""))])]
4398 "")
4399
4400 (define_insn "*truncdfsf_fast_mixed"
4401 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4402 (float_truncate:SF
4403 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4404 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4405 {
4406 switch (which_alternative)
4407 {
4408 case 0:
4409 return output_387_reg_move (insn, operands);
4410 case 1:
4411 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4412 default:
4413 gcc_unreachable ();
4414 }
4415 }
4416 [(set_attr "type" "fmov,ssecvt")
4417 (set_attr "prefix" "orig,maybe_vex")
4418 (set_attr "mode" "SF")])
4419
4420 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4421 ;; because nothing we do here is unsafe.
4422 (define_insn "*truncdfsf_fast_sse"
4423 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4424 (float_truncate:SF
4425 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4426 "TARGET_SSE2 && TARGET_SSE_MATH"
4427 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4428 [(set_attr "type" "ssecvt")
4429 (set_attr "prefix" "maybe_vex")
4430 (set_attr "mode" "SF")])
4431
4432 (define_insn "*truncdfsf_fast_i387"
4433 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4434 (float_truncate:SF
4435 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4436 "TARGET_80387 && flag_unsafe_math_optimizations"
4437 "* return output_387_reg_move (insn, operands);"
4438 [(set_attr "type" "fmov")
4439 (set_attr "mode" "SF")])
4440
4441 (define_insn "*truncdfsf_mixed"
4442 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4443 (float_truncate:SF
4444 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4445 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4446 "TARGET_MIX_SSE_I387"
4447 {
4448 switch (which_alternative)
4449 {
4450 case 0:
4451 return output_387_reg_move (insn, operands);
4452
4453 case 1:
4454 return "#";
4455 case 2:
4456 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4457 default:
4458 gcc_unreachable ();
4459 }
4460 }
4461 [(set_attr "type" "fmov,multi,ssecvt")
4462 (set_attr "unit" "*,i387,*")
4463 (set_attr "prefix" "orig,orig,maybe_vex")
4464 (set_attr "mode" "SF")])
4465
4466 (define_insn "*truncdfsf_i387"
4467 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4468 (float_truncate:SF
4469 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4470 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4471 "TARGET_80387"
4472 {
4473 switch (which_alternative)
4474 {
4475 case 0:
4476 return output_387_reg_move (insn, operands);
4477
4478 case 1:
4479 return "#";
4480 default:
4481 gcc_unreachable ();
4482 }
4483 }
4484 [(set_attr "type" "fmov,multi")
4485 (set_attr "unit" "*,i387")
4486 (set_attr "mode" "SF")])
4487
4488 (define_insn "*truncdfsf2_i387_1"
4489 [(set (match_operand:SF 0 "memory_operand" "=m")
4490 (float_truncate:SF
4491 (match_operand:DF 1 "register_operand" "f")))]
4492 "TARGET_80387
4493 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4494 && !TARGET_MIX_SSE_I387"
4495 "* return output_387_reg_move (insn, operands);"
4496 [(set_attr "type" "fmov")
4497 (set_attr "mode" "SF")])
4498
4499 (define_split
4500 [(set (match_operand:SF 0 "register_operand" "")
4501 (float_truncate:SF
4502 (match_operand:DF 1 "fp_register_operand" "")))
4503 (clobber (match_operand 2 "" ""))]
4504 "reload_completed"
4505 [(set (match_dup 2) (match_dup 1))
4506 (set (match_dup 0) (match_dup 2))]
4507 {
4508 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4509 })
4510
4511 ;; Conversion from XFmode to {SF,DF}mode
4512
4513 (define_expand "truncxf<mode>2"
4514 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4515 (float_truncate:MODEF
4516 (match_operand:XF 1 "register_operand" "")))
4517 (clobber (match_dup 2))])]
4518 "TARGET_80387"
4519 {
4520 if (flag_unsafe_math_optimizations)
4521 {
4522 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4523 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4524 if (reg != operands[0])
4525 emit_move_insn (operands[0], reg);
4526 DONE;
4527 }
4528 else
4529 {
4530 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4531 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4532 }
4533 })
4534
4535 (define_insn "*truncxfsf2_mixed"
4536 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4537 (float_truncate:SF
4538 (match_operand:XF 1 "register_operand" "f,f")))
4539 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4540 "TARGET_80387"
4541 {
4542 gcc_assert (!which_alternative);
4543 return output_387_reg_move (insn, operands);
4544 }
4545 [(set_attr "type" "fmov,multi")
4546 (set_attr "unit" "*,i387")
4547 (set_attr "mode" "SF")])
4548
4549 (define_insn "*truncxfdf2_mixed"
4550 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4551 (float_truncate:DF
4552 (match_operand:XF 1 "register_operand" "f,f")))
4553 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4554 "TARGET_80387"
4555 {
4556 gcc_assert (!which_alternative);
4557 return output_387_reg_move (insn, operands);
4558 }
4559 [(set_attr "type" "fmov,multi")
4560 (set_attr "unit" "*,i387")
4561 (set_attr "mode" "DF")])
4562
4563 (define_insn "truncxf<mode>2_i387_noop"
4564 [(set (match_operand:MODEF 0 "register_operand" "=f")
4565 (float_truncate:MODEF
4566 (match_operand:XF 1 "register_operand" "f")))]
4567 "TARGET_80387 && flag_unsafe_math_optimizations"
4568 "* return output_387_reg_move (insn, operands);"
4569 [(set_attr "type" "fmov")
4570 (set_attr "mode" "<MODE>")])
4571
4572 (define_insn "*truncxf<mode>2_i387"
4573 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4574 (float_truncate:MODEF
4575 (match_operand:XF 1 "register_operand" "f")))]
4576 "TARGET_80387"
4577 "* return output_387_reg_move (insn, operands);"
4578 [(set_attr "type" "fmov")
4579 (set_attr "mode" "<MODE>")])
4580
4581 (define_split
4582 [(set (match_operand:MODEF 0 "register_operand" "")
4583 (float_truncate:MODEF
4584 (match_operand:XF 1 "register_operand" "")))
4585 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4586 "TARGET_80387 && reload_completed"
4587 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4588 (set (match_dup 0) (match_dup 2))]
4589 "")
4590
4591 (define_split
4592 [(set (match_operand:MODEF 0 "memory_operand" "")
4593 (float_truncate:MODEF
4594 (match_operand:XF 1 "register_operand" "")))
4595 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4596 "TARGET_80387"
4597 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4598 "")
4599 \f
4600 ;; Signed conversion to DImode.
4601
4602 (define_expand "fix_truncxfdi2"
4603 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4604 (fix:DI (match_operand:XF 1 "register_operand" "")))
4605 (clobber (reg:CC FLAGS_REG))])]
4606 "TARGET_80387"
4607 {
4608 if (TARGET_FISTTP)
4609 {
4610 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4611 DONE;
4612 }
4613 })
4614
4615 (define_expand "fix_trunc<mode>di2"
4616 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4617 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4618 (clobber (reg:CC FLAGS_REG))])]
4619 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4620 {
4621 if (TARGET_FISTTP
4622 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4623 {
4624 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4625 DONE;
4626 }
4627 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4628 {
4629 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4630 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4631 if (out != operands[0])
4632 emit_move_insn (operands[0], out);
4633 DONE;
4634 }
4635 })
4636
4637 ;; Signed conversion to SImode.
4638
4639 (define_expand "fix_truncxfsi2"
4640 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4641 (fix:SI (match_operand:XF 1 "register_operand" "")))
4642 (clobber (reg:CC FLAGS_REG))])]
4643 "TARGET_80387"
4644 {
4645 if (TARGET_FISTTP)
4646 {
4647 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4648 DONE;
4649 }
4650 })
4651
4652 (define_expand "fix_trunc<mode>si2"
4653 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4654 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4655 (clobber (reg:CC FLAGS_REG))])]
4656 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4657 {
4658 if (TARGET_FISTTP
4659 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4660 {
4661 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4662 DONE;
4663 }
4664 if (SSE_FLOAT_MODE_P (<MODE>mode))
4665 {
4666 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4667 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4668 if (out != operands[0])
4669 emit_move_insn (operands[0], out);
4670 DONE;
4671 }
4672 })
4673
4674 ;; Signed conversion to HImode.
4675
4676 (define_expand "fix_trunc<mode>hi2"
4677 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4678 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4679 (clobber (reg:CC FLAGS_REG))])]
4680 "TARGET_80387
4681 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4682 {
4683 if (TARGET_FISTTP)
4684 {
4685 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4686 DONE;
4687 }
4688 })
4689
4690 ;; Unsigned conversion to SImode.
4691
4692 (define_expand "fixuns_trunc<mode>si2"
4693 [(parallel
4694 [(set (match_operand:SI 0 "register_operand" "")
4695 (unsigned_fix:SI
4696 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4697 (use (match_dup 2))
4698 (clobber (match_scratch:<ssevecmode> 3 ""))
4699 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4700 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701 {
4702 enum machine_mode mode = <MODE>mode;
4703 enum machine_mode vecmode = <ssevecmode>mode;
4704 REAL_VALUE_TYPE TWO31r;
4705 rtx two31;
4706
4707 if (optimize_insn_for_size_p ())
4708 FAIL;
4709
4710 real_ldexp (&TWO31r, &dconst1, 31);
4711 two31 = const_double_from_real_value (TWO31r, mode);
4712 two31 = ix86_build_const_vector (mode, true, two31);
4713 operands[2] = force_reg (vecmode, two31);
4714 })
4715
4716 (define_insn_and_split "*fixuns_trunc<mode>_1"
4717 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4718 (unsigned_fix:SI
4719 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4720 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4721 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4722 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4723 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4724 && optimize_function_for_speed_p (cfun)"
4725 "#"
4726 "&& reload_completed"
4727 [(const_int 0)]
4728 {
4729 ix86_split_convert_uns_si_sse (operands);
4730 DONE;
4731 })
4732
4733 ;; Unsigned conversion to HImode.
4734 ;; Without these patterns, we'll try the unsigned SI conversion which
4735 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4736
4737 (define_expand "fixuns_trunc<mode>hi2"
4738 [(set (match_dup 2)
4739 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4740 (set (match_operand:HI 0 "nonimmediate_operand" "")
4741 (subreg:HI (match_dup 2) 0))]
4742 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4743 "operands[2] = gen_reg_rtx (SImode);")
4744
4745 ;; When SSE is available, it is always faster to use it!
4746 (define_insn "fix_trunc<mode>di_sse"
4747 [(set (match_operand:DI 0 "register_operand" "=r,r")
4748 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4749 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4750 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4751 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4752 [(set_attr "type" "sseicvt")
4753 (set_attr "prefix" "maybe_vex")
4754 (set_attr "mode" "<MODE>")
4755 (set_attr "athlon_decode" "double,vector")
4756 (set_attr "amdfam10_decode" "double,double")])
4757
4758 (define_insn "fix_trunc<mode>si_sse"
4759 [(set (match_operand:SI 0 "register_operand" "=r,r")
4760 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4761 "SSE_FLOAT_MODE_P (<MODE>mode)
4762 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4763 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4764 [(set_attr "type" "sseicvt")
4765 (set_attr "prefix" "maybe_vex")
4766 (set_attr "mode" "<MODE>")
4767 (set_attr "athlon_decode" "double,vector")
4768 (set_attr "amdfam10_decode" "double,double")])
4769
4770 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4771 (define_peephole2
4772 [(set (match_operand:MODEF 0 "register_operand" "")
4773 (match_operand:MODEF 1 "memory_operand" ""))
4774 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4775 (fix:SSEMODEI24 (match_dup 0)))]
4776 "TARGET_SHORTEN_X87_SSE
4777 && peep2_reg_dead_p (2, operands[0])"
4778 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4779 "")
4780
4781 ;; Avoid vector decoded forms of the instruction.
4782 (define_peephole2
4783 [(match_scratch:DF 2 "Y2")
4784 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4785 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4786 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4787 [(set (match_dup 2) (match_dup 1))
4788 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4789 "")
4790
4791 (define_peephole2
4792 [(match_scratch:SF 2 "x")
4793 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4794 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4795 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4796 [(set (match_dup 2) (match_dup 1))
4797 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4798 "")
4799
4800 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4801 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4802 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4803 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4804 && TARGET_FISTTP
4805 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4806 && (TARGET_64BIT || <MODE>mode != DImode))
4807 && TARGET_SSE_MATH)
4808 && !(reload_completed || reload_in_progress)"
4809 "#"
4810 "&& 1"
4811 [(const_int 0)]
4812 {
4813 if (memory_operand (operands[0], VOIDmode))
4814 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4815 else
4816 {
4817 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4818 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4819 operands[1],
4820 operands[2]));
4821 }
4822 DONE;
4823 }
4824 [(set_attr "type" "fisttp")
4825 (set_attr "mode" "<MODE>")])
4826
4827 (define_insn "fix_trunc<mode>_i387_fisttp"
4828 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4829 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4830 (clobber (match_scratch:XF 2 "=&1f"))]
4831 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4832 && TARGET_FISTTP
4833 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4834 && (TARGET_64BIT || <MODE>mode != DImode))
4835 && TARGET_SSE_MATH)"
4836 "* return output_fix_trunc (insn, operands, 1);"
4837 [(set_attr "type" "fisttp")
4838 (set_attr "mode" "<MODE>")])
4839
4840 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4841 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4842 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4843 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4844 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4845 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4846 && TARGET_FISTTP
4847 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4848 && (TARGET_64BIT || <MODE>mode != DImode))
4849 && TARGET_SSE_MATH)"
4850 "#"
4851 [(set_attr "type" "fisttp")
4852 (set_attr "mode" "<MODE>")])
4853
4854 (define_split
4855 [(set (match_operand:X87MODEI 0 "register_operand" "")
4856 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4857 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4858 (clobber (match_scratch 3 ""))]
4859 "reload_completed"
4860 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4861 (clobber (match_dup 3))])
4862 (set (match_dup 0) (match_dup 2))]
4863 "")
4864
4865 (define_split
4866 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4867 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4868 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4869 (clobber (match_scratch 3 ""))]
4870 "reload_completed"
4871 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4872 (clobber (match_dup 3))])]
4873 "")
4874
4875 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4876 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4877 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4878 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4879 ;; function in i386.c.
4880 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4881 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4882 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4883 (clobber (reg:CC FLAGS_REG))]
4884 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4885 && !TARGET_FISTTP
4886 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4887 && (TARGET_64BIT || <MODE>mode != DImode))
4888 && !(reload_completed || reload_in_progress)"
4889 "#"
4890 "&& 1"
4891 [(const_int 0)]
4892 {
4893 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4894
4895 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4896 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4897 if (memory_operand (operands[0], VOIDmode))
4898 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4899 operands[2], operands[3]));
4900 else
4901 {
4902 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4903 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4904 operands[2], operands[3],
4905 operands[4]));
4906 }
4907 DONE;
4908 }
4909 [(set_attr "type" "fistp")
4910 (set_attr "i387_cw" "trunc")
4911 (set_attr "mode" "<MODE>")])
4912
4913 (define_insn "fix_truncdi_i387"
4914 [(set (match_operand:DI 0 "memory_operand" "=m")
4915 (fix:DI (match_operand 1 "register_operand" "f")))
4916 (use (match_operand:HI 2 "memory_operand" "m"))
4917 (use (match_operand:HI 3 "memory_operand" "m"))
4918 (clobber (match_scratch:XF 4 "=&1f"))]
4919 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4920 && !TARGET_FISTTP
4921 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4922 "* return output_fix_trunc (insn, operands, 0);"
4923 [(set_attr "type" "fistp")
4924 (set_attr "i387_cw" "trunc")
4925 (set_attr "mode" "DI")])
4926
4927 (define_insn "fix_truncdi_i387_with_temp"
4928 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4929 (fix:DI (match_operand 1 "register_operand" "f,f")))
4930 (use (match_operand:HI 2 "memory_operand" "m,m"))
4931 (use (match_operand:HI 3 "memory_operand" "m,m"))
4932 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4933 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4935 && !TARGET_FISTTP
4936 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937 "#"
4938 [(set_attr "type" "fistp")
4939 (set_attr "i387_cw" "trunc")
4940 (set_attr "mode" "DI")])
4941
4942 (define_split
4943 [(set (match_operand:DI 0 "register_operand" "")
4944 (fix:DI (match_operand 1 "register_operand" "")))
4945 (use (match_operand:HI 2 "memory_operand" ""))
4946 (use (match_operand:HI 3 "memory_operand" ""))
4947 (clobber (match_operand:DI 4 "memory_operand" ""))
4948 (clobber (match_scratch 5 ""))]
4949 "reload_completed"
4950 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4951 (use (match_dup 2))
4952 (use (match_dup 3))
4953 (clobber (match_dup 5))])
4954 (set (match_dup 0) (match_dup 4))]
4955 "")
4956
4957 (define_split
4958 [(set (match_operand:DI 0 "memory_operand" "")
4959 (fix:DI (match_operand 1 "register_operand" "")))
4960 (use (match_operand:HI 2 "memory_operand" ""))
4961 (use (match_operand:HI 3 "memory_operand" ""))
4962 (clobber (match_operand:DI 4 "memory_operand" ""))
4963 (clobber (match_scratch 5 ""))]
4964 "reload_completed"
4965 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4966 (use (match_dup 2))
4967 (use (match_dup 3))
4968 (clobber (match_dup 5))])]
4969 "")
4970
4971 (define_insn "fix_trunc<mode>_i387"
4972 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4973 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4974 (use (match_operand:HI 2 "memory_operand" "m"))
4975 (use (match_operand:HI 3 "memory_operand" "m"))]
4976 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977 && !TARGET_FISTTP
4978 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4979 "* return output_fix_trunc (insn, operands, 0);"
4980 [(set_attr "type" "fistp")
4981 (set_attr "i387_cw" "trunc")
4982 (set_attr "mode" "<MODE>")])
4983
4984 (define_insn "fix_trunc<mode>_i387_with_temp"
4985 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4986 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4987 (use (match_operand:HI 2 "memory_operand" "m,m"))
4988 (use (match_operand:HI 3 "memory_operand" "m,m"))
4989 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4990 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4991 && !TARGET_FISTTP
4992 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4993 "#"
4994 [(set_attr "type" "fistp")
4995 (set_attr "i387_cw" "trunc")
4996 (set_attr "mode" "<MODE>")])
4997
4998 (define_split
4999 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5000 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5001 (use (match_operand:HI 2 "memory_operand" ""))
5002 (use (match_operand:HI 3 "memory_operand" ""))
5003 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5004 "reload_completed"
5005 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5006 (use (match_dup 2))
5007 (use (match_dup 3))])
5008 (set (match_dup 0) (match_dup 4))]
5009 "")
5010
5011 (define_split
5012 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5013 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5014 (use (match_operand:HI 2 "memory_operand" ""))
5015 (use (match_operand:HI 3 "memory_operand" ""))
5016 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5017 "reload_completed"
5018 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5019 (use (match_dup 2))
5020 (use (match_dup 3))])]
5021 "")
5022
5023 (define_insn "x86_fnstcw_1"
5024 [(set (match_operand:HI 0 "memory_operand" "=m")
5025 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5026 "TARGET_80387"
5027 "fnstcw\t%0"
5028 [(set_attr "length" "2")
5029 (set_attr "mode" "HI")
5030 (set_attr "unit" "i387")])
5031
5032 (define_insn "x86_fldcw_1"
5033 [(set (reg:HI FPCR_REG)
5034 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5035 "TARGET_80387"
5036 "fldcw\t%0"
5037 [(set_attr "length" "2")
5038 (set_attr "mode" "HI")
5039 (set_attr "unit" "i387")
5040 (set_attr "athlon_decode" "vector")
5041 (set_attr "amdfam10_decode" "vector")])
5042 \f
5043 ;; Conversion between fixed point and floating point.
5044
5045 ;; Even though we only accept memory inputs, the backend _really_
5046 ;; wants to be able to do this between registers.
5047
5048 (define_expand "floathi<mode>2"
5049 [(set (match_operand:X87MODEF 0 "register_operand" "")
5050 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5051 "TARGET_80387
5052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5053 || TARGET_MIX_SSE_I387)"
5054 "")
5055
5056 ;; Pre-reload splitter to add memory clobber to the pattern.
5057 (define_insn_and_split "*floathi<mode>2_1"
5058 [(set (match_operand:X87MODEF 0 "register_operand" "")
5059 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5060 "TARGET_80387
5061 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5062 || TARGET_MIX_SSE_I387)
5063 && !(reload_completed || reload_in_progress)"
5064 "#"
5065 "&& 1"
5066 [(parallel [(set (match_dup 0)
5067 (float:X87MODEF (match_dup 1)))
5068 (clobber (match_dup 2))])]
5069 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5070
5071 (define_insn "*floathi<mode>2_i387_with_temp"
5072 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5073 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5074 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5075 "TARGET_80387
5076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5077 || TARGET_MIX_SSE_I387)"
5078 "#"
5079 [(set_attr "type" "fmov,multi")
5080 (set_attr "mode" "<MODE>")
5081 (set_attr "unit" "*,i387")
5082 (set_attr "fp_int_src" "true")])
5083
5084 (define_insn "*floathi<mode>2_i387"
5085 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5086 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5087 "TARGET_80387
5088 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5089 || TARGET_MIX_SSE_I387)"
5090 "fild%z1\t%1"
5091 [(set_attr "type" "fmov")
5092 (set_attr "mode" "<MODE>")
5093 (set_attr "fp_int_src" "true")])
5094
5095 (define_split
5096 [(set (match_operand:X87MODEF 0 "register_operand" "")
5097 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5098 (clobber (match_operand:HI 2 "memory_operand" ""))]
5099 "TARGET_80387
5100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5101 || TARGET_MIX_SSE_I387)
5102 && reload_completed"
5103 [(set (match_dup 2) (match_dup 1))
5104 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5105 "")
5106
5107 (define_split
5108 [(set (match_operand:X87MODEF 0 "register_operand" "")
5109 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5110 (clobber (match_operand:HI 2 "memory_operand" ""))]
5111 "TARGET_80387
5112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5113 || TARGET_MIX_SSE_I387)
5114 && reload_completed"
5115 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5116 "")
5117
5118 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5119 [(set (match_operand:X87MODEF 0 "register_operand" "")
5120 (float:X87MODEF
5121 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5122 "TARGET_80387
5123 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5125 "")
5126
5127 ;; Pre-reload splitter to add memory clobber to the pattern.
5128 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5129 [(set (match_operand:X87MODEF 0 "register_operand" "")
5130 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5131 "((TARGET_80387
5132 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5133 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5134 || TARGET_MIX_SSE_I387))
5135 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5136 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5137 && ((<SSEMODEI24:MODE>mode == SImode
5138 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5139 && optimize_function_for_speed_p (cfun)
5140 && flag_trapping_math)
5141 || !(TARGET_INTER_UNIT_CONVERSIONS
5142 || optimize_function_for_size_p (cfun)))))
5143 && !(reload_completed || reload_in_progress)"
5144 "#"
5145 "&& 1"
5146 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5147 (clobber (match_dup 2))])]
5148 {
5149 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5150
5151 /* Avoid store forwarding (partial memory) stall penalty
5152 by passing DImode value through XMM registers. */
5153 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5154 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5155 && optimize_function_for_speed_p (cfun))
5156 {
5157 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5158 operands[1],
5159 operands[2]));
5160 DONE;
5161 }
5162 })
5163
5164 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5165 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5166 (float:MODEF
5167 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5168 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5169 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5170 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5171 "#"
5172 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5173 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5174 (set_attr "unit" "*,i387,*,*,*")
5175 (set_attr "athlon_decode" "*,*,double,direct,double")
5176 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5177 (set_attr "fp_int_src" "true")])
5178
5179 (define_insn "*floatsi<mode>2_vector_mixed"
5180 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5181 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5182 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5183 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5184 "@
5185 fild%z1\t%1
5186 #"
5187 [(set_attr "type" "fmov,sseicvt")
5188 (set_attr "mode" "<MODE>,<ssevecmode>")
5189 (set_attr "unit" "i387,*")
5190 (set_attr "athlon_decode" "*,direct")
5191 (set_attr "amdfam10_decode" "*,double")
5192 (set_attr "fp_int_src" "true")])
5193
5194 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5195 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5196 (float:MODEF
5197 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5198 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5199 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5200 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5201 "#"
5202 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5203 (set_attr "mode" "<MODEF:MODE>")
5204 (set_attr "unit" "*,i387,*,*")
5205 (set_attr "athlon_decode" "*,*,double,direct")
5206 (set_attr "amdfam10_decode" "*,*,vector,double")
5207 (set_attr "fp_int_src" "true")])
5208
5209 (define_split
5210 [(set (match_operand:MODEF 0 "register_operand" "")
5211 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5212 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5213 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5214 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5215 && TARGET_INTER_UNIT_CONVERSIONS
5216 && reload_completed
5217 && (SSE_REG_P (operands[0])
5218 || (GET_CODE (operands[0]) == SUBREG
5219 && SSE_REG_P (operands[0])))"
5220 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5221 "")
5222
5223 (define_split
5224 [(set (match_operand:MODEF 0 "register_operand" "")
5225 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5227 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5228 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5229 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5230 && reload_completed
5231 && (SSE_REG_P (operands[0])
5232 || (GET_CODE (operands[0]) == SUBREG
5233 && SSE_REG_P (operands[0])))"
5234 [(set (match_dup 2) (match_dup 1))
5235 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5236 "")
5237
5238 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5239 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5240 (float:MODEF
5241 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5242 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5243 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5244 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5245 "@
5246 fild%z1\t%1
5247 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5248 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5249 [(set_attr "type" "fmov,sseicvt,sseicvt")
5250 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5251 (set_attr "mode" "<MODEF:MODE>")
5252 (set_attr "unit" "i387,*,*")
5253 (set_attr "athlon_decode" "*,double,direct")
5254 (set_attr "amdfam10_decode" "*,vector,double")
5255 (set_attr "fp_int_src" "true")])
5256
5257 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5258 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5259 (float:MODEF
5260 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5261 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5262 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5263 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5264 "@
5265 fild%z1\t%1
5266 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5267 [(set_attr "type" "fmov,sseicvt")
5268 (set_attr "prefix" "orig,maybe_vex")
5269 (set_attr "mode" "<MODEF:MODE>")
5270 (set_attr "athlon_decode" "*,direct")
5271 (set_attr "amdfam10_decode" "*,double")
5272 (set_attr "fp_int_src" "true")])
5273
5274 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5275 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5276 (float:MODEF
5277 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5278 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5279 "TARGET_SSE2 && TARGET_SSE_MATH
5280 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5281 "#"
5282 [(set_attr "type" "sseicvt")
5283 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5284 (set_attr "athlon_decode" "double,direct,double")
5285 (set_attr "amdfam10_decode" "vector,double,double")
5286 (set_attr "fp_int_src" "true")])
5287
5288 (define_insn "*floatsi<mode>2_vector_sse"
5289 [(set (match_operand:MODEF 0 "register_operand" "=x")
5290 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5291 "TARGET_SSE2 && TARGET_SSE_MATH
5292 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5293 "#"
5294 [(set_attr "type" "sseicvt")
5295 (set_attr "mode" "<MODE>")
5296 (set_attr "athlon_decode" "direct")
5297 (set_attr "amdfam10_decode" "double")
5298 (set_attr "fp_int_src" "true")])
5299
5300 (define_split
5301 [(set (match_operand:MODEF 0 "register_operand" "")
5302 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5303 (clobber (match_operand:SI 2 "memory_operand" ""))]
5304 "TARGET_SSE2 && TARGET_SSE_MATH
5305 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5306 && reload_completed
5307 && (SSE_REG_P (operands[0])
5308 || (GET_CODE (operands[0]) == SUBREG
5309 && SSE_REG_P (operands[0])))"
5310 [(const_int 0)]
5311 {
5312 rtx op1 = operands[1];
5313
5314 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5315 <MODE>mode, 0);
5316 if (GET_CODE (op1) == SUBREG)
5317 op1 = SUBREG_REG (op1);
5318
5319 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5320 {
5321 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5322 emit_insn (gen_sse2_loadld (operands[4],
5323 CONST0_RTX (V4SImode), operands[1]));
5324 }
5325 /* We can ignore possible trapping value in the
5326 high part of SSE register for non-trapping math. */
5327 else if (SSE_REG_P (op1) && !flag_trapping_math)
5328 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5329 else
5330 {
5331 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5332 emit_move_insn (operands[2], operands[1]);
5333 emit_insn (gen_sse2_loadld (operands[4],
5334 CONST0_RTX (V4SImode), operands[2]));
5335 }
5336 emit_insn
5337 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5338 DONE;
5339 })
5340
5341 (define_split
5342 [(set (match_operand:MODEF 0 "register_operand" "")
5343 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5344 (clobber (match_operand:SI 2 "memory_operand" ""))]
5345 "TARGET_SSE2 && TARGET_SSE_MATH
5346 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5347 && reload_completed
5348 && (SSE_REG_P (operands[0])
5349 || (GET_CODE (operands[0]) == SUBREG
5350 && SSE_REG_P (operands[0])))"
5351 [(const_int 0)]
5352 {
5353 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5354 <MODE>mode, 0);
5355 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5356
5357 emit_insn (gen_sse2_loadld (operands[4],
5358 CONST0_RTX (V4SImode), operands[1]));
5359 emit_insn
5360 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5361 DONE;
5362 })
5363
5364 (define_split
5365 [(set (match_operand:MODEF 0 "register_operand" "")
5366 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5367 "TARGET_SSE2 && TARGET_SSE_MATH
5368 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5369 && reload_completed
5370 && (SSE_REG_P (operands[0])
5371 || (GET_CODE (operands[0]) == SUBREG
5372 && SSE_REG_P (operands[0])))"
5373 [(const_int 0)]
5374 {
5375 rtx op1 = operands[1];
5376
5377 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5378 <MODE>mode, 0);
5379 if (GET_CODE (op1) == SUBREG)
5380 op1 = SUBREG_REG (op1);
5381
5382 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5383 {
5384 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5385 emit_insn (gen_sse2_loadld (operands[4],
5386 CONST0_RTX (V4SImode), operands[1]));
5387 }
5388 /* We can ignore possible trapping value in the
5389 high part of SSE register for non-trapping math. */
5390 else if (SSE_REG_P (op1) && !flag_trapping_math)
5391 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5392 else
5393 gcc_unreachable ();
5394 emit_insn
5395 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5396 DONE;
5397 })
5398
5399 (define_split
5400 [(set (match_operand:MODEF 0 "register_operand" "")
5401 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5402 "TARGET_SSE2 && TARGET_SSE_MATH
5403 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5404 && reload_completed
5405 && (SSE_REG_P (operands[0])
5406 || (GET_CODE (operands[0]) == SUBREG
5407 && SSE_REG_P (operands[0])))"
5408 [(const_int 0)]
5409 {
5410 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5411 <MODE>mode, 0);
5412 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5413
5414 emit_insn (gen_sse2_loadld (operands[4],
5415 CONST0_RTX (V4SImode), operands[1]));
5416 emit_insn
5417 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5418 DONE;
5419 })
5420
5421 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5422 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5423 (float:MODEF
5424 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5425 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5426 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5427 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5428 "#"
5429 [(set_attr "type" "sseicvt")
5430 (set_attr "mode" "<MODEF:MODE>")
5431 (set_attr "athlon_decode" "double,direct")
5432 (set_attr "amdfam10_decode" "vector,double")
5433 (set_attr "fp_int_src" "true")])
5434
5435 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5436 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5437 (float:MODEF
5438 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5439 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5440 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5441 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5442 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5443 [(set_attr "type" "sseicvt")
5444 (set_attr "prefix" "maybe_vex")
5445 (set_attr "mode" "<MODEF:MODE>")
5446 (set_attr "athlon_decode" "double,direct")
5447 (set_attr "amdfam10_decode" "vector,double")
5448 (set_attr "fp_int_src" "true")])
5449
5450 (define_split
5451 [(set (match_operand:MODEF 0 "register_operand" "")
5452 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5453 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5454 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5455 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5456 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5457 && reload_completed
5458 && (SSE_REG_P (operands[0])
5459 || (GET_CODE (operands[0]) == SUBREG
5460 && SSE_REG_P (operands[0])))"
5461 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5462 "")
5463
5464 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5465 [(set (match_operand:MODEF 0 "register_operand" "=x")
5466 (float:MODEF
5467 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5468 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5469 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5470 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5471 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5472 [(set_attr "type" "sseicvt")
5473 (set_attr "prefix" "maybe_vex")
5474 (set_attr "mode" "<MODEF:MODE>")
5475 (set_attr "athlon_decode" "direct")
5476 (set_attr "amdfam10_decode" "double")
5477 (set_attr "fp_int_src" "true")])
5478
5479 (define_split
5480 [(set (match_operand:MODEF 0 "register_operand" "")
5481 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5482 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5483 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5484 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5485 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5486 && reload_completed
5487 && (SSE_REG_P (operands[0])
5488 || (GET_CODE (operands[0]) == SUBREG
5489 && SSE_REG_P (operands[0])))"
5490 [(set (match_dup 2) (match_dup 1))
5491 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5492 "")
5493
5494 (define_split
5495 [(set (match_operand:MODEF 0 "register_operand" "")
5496 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5497 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5498 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500 && reload_completed
5501 && (SSE_REG_P (operands[0])
5502 || (GET_CODE (operands[0]) == SUBREG
5503 && SSE_REG_P (operands[0])))"
5504 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5505 "")
5506
5507 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5508 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5509 (float:X87MODEF
5510 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5511 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5512 "TARGET_80387"
5513 "@
5514 fild%z1\t%1
5515 #"
5516 [(set_attr "type" "fmov,multi")
5517 (set_attr "mode" "<X87MODEF:MODE>")
5518 (set_attr "unit" "*,i387")
5519 (set_attr "fp_int_src" "true")])
5520
5521 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5522 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5523 (float:X87MODEF
5524 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5525 "TARGET_80387"
5526 "fild%z1\t%1"
5527 [(set_attr "type" "fmov")
5528 (set_attr "mode" "<X87MODEF:MODE>")
5529 (set_attr "fp_int_src" "true")])
5530
5531 (define_split
5532 [(set (match_operand:X87MODEF 0 "register_operand" "")
5533 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5534 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5535 "TARGET_80387
5536 && reload_completed
5537 && FP_REG_P (operands[0])"
5538 [(set (match_dup 2) (match_dup 1))
5539 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5540 "")
5541
5542 (define_split
5543 [(set (match_operand:X87MODEF 0 "register_operand" "")
5544 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5545 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5546 "TARGET_80387
5547 && reload_completed
5548 && FP_REG_P (operands[0])"
5549 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5550 "")
5551
5552 ;; Avoid store forwarding (partial memory) stall penalty
5553 ;; by passing DImode value through XMM registers. */
5554
5555 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5556 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5557 (float:X87MODEF
5558 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5559 (clobber (match_scratch:V4SI 3 "=X,x"))
5560 (clobber (match_scratch:V4SI 4 "=X,x"))
5561 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5562 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5563 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5564 "#"
5565 [(set_attr "type" "multi")
5566 (set_attr "mode" "<X87MODEF:MODE>")
5567 (set_attr "unit" "i387")
5568 (set_attr "fp_int_src" "true")])
5569
5570 (define_split
5571 [(set (match_operand:X87MODEF 0 "register_operand" "")
5572 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5573 (clobber (match_scratch:V4SI 3 ""))
5574 (clobber (match_scratch:V4SI 4 ""))
5575 (clobber (match_operand:DI 2 "memory_operand" ""))]
5576 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5577 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5578 && reload_completed
5579 && FP_REG_P (operands[0])"
5580 [(set (match_dup 2) (match_dup 3))
5581 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5582 {
5583 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5584 Assemble the 64-bit DImode value in an xmm register. */
5585 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5586 gen_rtx_SUBREG (SImode, operands[1], 0)));
5587 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5588 gen_rtx_SUBREG (SImode, operands[1], 4)));
5589 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5590
5591 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5592 })
5593
5594 (define_split
5595 [(set (match_operand:X87MODEF 0 "register_operand" "")
5596 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5597 (clobber (match_scratch:V4SI 3 ""))
5598 (clobber (match_scratch:V4SI 4 ""))
5599 (clobber (match_operand:DI 2 "memory_operand" ""))]
5600 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5601 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5602 && reload_completed
5603 && FP_REG_P (operands[0])"
5604 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5605 "")
5606
5607 ;; Avoid store forwarding (partial memory) stall penalty by extending
5608 ;; SImode value to DImode through XMM register instead of pushing two
5609 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5610 ;; targets benefit from this optimization. Also note that fild
5611 ;; loads from memory only.
5612
5613 (define_insn "*floatunssi<mode>2_1"
5614 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5615 (unsigned_float:X87MODEF
5616 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5617 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5618 (clobber (match_scratch:SI 3 "=X,x"))]
5619 "!TARGET_64BIT
5620 && TARGET_80387 && TARGET_SSE"
5621 "#"
5622 [(set_attr "type" "multi")
5623 (set_attr "mode" "<MODE>")])
5624
5625 (define_split
5626 [(set (match_operand:X87MODEF 0 "register_operand" "")
5627 (unsigned_float:X87MODEF
5628 (match_operand:SI 1 "register_operand" "")))
5629 (clobber (match_operand:DI 2 "memory_operand" ""))
5630 (clobber (match_scratch:SI 3 ""))]
5631 "!TARGET_64BIT
5632 && TARGET_80387 && TARGET_SSE
5633 && reload_completed"
5634 [(set (match_dup 2) (match_dup 1))
5635 (set (match_dup 0)
5636 (float:X87MODEF (match_dup 2)))]
5637 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5638
5639 (define_split
5640 [(set (match_operand:X87MODEF 0 "register_operand" "")
5641 (unsigned_float:X87MODEF
5642 (match_operand:SI 1 "memory_operand" "")))
5643 (clobber (match_operand:DI 2 "memory_operand" ""))
5644 (clobber (match_scratch:SI 3 ""))]
5645 "!TARGET_64BIT
5646 && TARGET_80387 && TARGET_SSE
5647 && reload_completed"
5648 [(set (match_dup 2) (match_dup 3))
5649 (set (match_dup 0)
5650 (float:X87MODEF (match_dup 2)))]
5651 {
5652 emit_move_insn (operands[3], operands[1]);
5653 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5654 })
5655
5656 (define_expand "floatunssi<mode>2"
5657 [(parallel
5658 [(set (match_operand:X87MODEF 0 "register_operand" "")
5659 (unsigned_float:X87MODEF
5660 (match_operand:SI 1 "nonimmediate_operand" "")))
5661 (clobber (match_dup 2))
5662 (clobber (match_scratch:SI 3 ""))])]
5663 "!TARGET_64BIT
5664 && ((TARGET_80387 && TARGET_SSE)
5665 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5666 {
5667 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5668 {
5669 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5670 DONE;
5671 }
5672 else
5673 {
5674 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5675 operands[2] = assign_386_stack_local (DImode, slot);
5676 }
5677 })
5678
5679 (define_expand "floatunsdisf2"
5680 [(use (match_operand:SF 0 "register_operand" ""))
5681 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5682 "TARGET_64BIT && TARGET_SSE_MATH"
5683 "x86_emit_floatuns (operands); DONE;")
5684
5685 (define_expand "floatunsdidf2"
5686 [(use (match_operand:DF 0 "register_operand" ""))
5687 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5688 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5689 && TARGET_SSE2 && TARGET_SSE_MATH"
5690 {
5691 if (TARGET_64BIT)
5692 x86_emit_floatuns (operands);
5693 else
5694 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5695 DONE;
5696 })
5697 \f
5698 ;; Add instructions
5699
5700 ;; %%% splits for addditi3
5701
5702 (define_expand "addti3"
5703 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5704 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5705 (match_operand:TI 2 "x86_64_general_operand" "")))]
5706 "TARGET_64BIT"
5707 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5708
5709 (define_insn "*addti3_1"
5710 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5711 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5712 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5713 (clobber (reg:CC FLAGS_REG))]
5714 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5715 "#")
5716
5717 (define_split
5718 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5719 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5720 (match_operand:TI 2 "x86_64_general_operand" "")))
5721 (clobber (reg:CC FLAGS_REG))]
5722 "TARGET_64BIT && reload_completed"
5723 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5724 UNSPEC_ADD_CARRY))
5725 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5726 (parallel [(set (match_dup 3)
5727 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5728 (match_dup 4))
5729 (match_dup 5)))
5730 (clobber (reg:CC FLAGS_REG))])]
5731 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5732
5733 ;; %%% splits for addsidi3
5734 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5735 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5736 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5737
5738 (define_expand "adddi3"
5739 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5740 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5741 (match_operand:DI 2 "x86_64_general_operand" "")))]
5742 ""
5743 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5744
5745 (define_insn "*adddi3_1"
5746 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5747 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5748 (match_operand:DI 2 "general_operand" "roiF,riF")))
5749 (clobber (reg:CC FLAGS_REG))]
5750 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5751 "#")
5752
5753 (define_split
5754 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5755 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5756 (match_operand:DI 2 "general_operand" "")))
5757 (clobber (reg:CC FLAGS_REG))]
5758 "!TARGET_64BIT && reload_completed"
5759 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5760 UNSPEC_ADD_CARRY))
5761 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5762 (parallel [(set (match_dup 3)
5763 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5764 (match_dup 4))
5765 (match_dup 5)))
5766 (clobber (reg:CC FLAGS_REG))])]
5767 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5768
5769 (define_insn "adddi3_carry_rex64"
5770 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5771 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5772 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5773 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5774 (clobber (reg:CC FLAGS_REG))]
5775 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5776 "adc{q}\t{%2, %0|%0, %2}"
5777 [(set_attr "type" "alu")
5778 (set_attr "pent_pair" "pu")
5779 (set_attr "mode" "DI")])
5780
5781 (define_insn "*adddi3_cc_rex64"
5782 [(set (reg:CC FLAGS_REG)
5783 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5784 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5785 UNSPEC_ADD_CARRY))
5786 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5787 (plus:DI (match_dup 1) (match_dup 2)))]
5788 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5789 "add{q}\t{%2, %0|%0, %2}"
5790 [(set_attr "type" "alu")
5791 (set_attr "mode" "DI")])
5792
5793 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5794 [(set (reg:CCC FLAGS_REG)
5795 (compare:CCC
5796 (plusminus:SWI
5797 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5798 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5799 (match_dup 1)))
5800 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5801 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5802 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5803 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5804 [(set_attr "type" "alu")
5805 (set_attr "mode" "<MODE>")])
5806
5807 (define_insn "*add<mode>3_cconly_overflow"
5808 [(set (reg:CCC FLAGS_REG)
5809 (compare:CCC
5810 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5811 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5812 (match_dup 1)))
5813 (clobber (match_scratch:SWI 0 "=<r>"))]
5814 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5815 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5816 [(set_attr "type" "alu")
5817 (set_attr "mode" "<MODE>")])
5818
5819 (define_insn "*sub<mode>3_cconly_overflow"
5820 [(set (reg:CCC FLAGS_REG)
5821 (compare:CCC
5822 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5823 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5824 (match_dup 0)))]
5825 ""
5826 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5827 [(set_attr "type" "icmp")
5828 (set_attr "mode" "<MODE>")])
5829
5830 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5831 [(set (reg:CCC FLAGS_REG)
5832 (compare:CCC
5833 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5834 (match_operand:SI 2 "general_operand" "g"))
5835 (match_dup 1)))
5836 (set (match_operand:DI 0 "register_operand" "=r")
5837 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5838 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5839 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5840 [(set_attr "type" "alu")
5841 (set_attr "mode" "SI")])
5842
5843 (define_insn "addqi3_carry"
5844 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5845 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5846 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5847 (match_operand:QI 2 "general_operand" "qn,qm")))
5848 (clobber (reg:CC FLAGS_REG))]
5849 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5850 "adc{b}\t{%2, %0|%0, %2}"
5851 [(set_attr "type" "alu")
5852 (set_attr "pent_pair" "pu")
5853 (set_attr "mode" "QI")])
5854
5855 (define_insn "addhi3_carry"
5856 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5857 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5858 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5859 (match_operand:HI 2 "general_operand" "rn,rm")))
5860 (clobber (reg:CC FLAGS_REG))]
5861 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5862 "adc{w}\t{%2, %0|%0, %2}"
5863 [(set_attr "type" "alu")
5864 (set_attr "pent_pair" "pu")
5865 (set_attr "mode" "HI")])
5866
5867 (define_insn "addsi3_carry"
5868 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5869 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5870 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5871 (match_operand:SI 2 "general_operand" "ri,rm")))
5872 (clobber (reg:CC FLAGS_REG))]
5873 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5874 "adc{l}\t{%2, %0|%0, %2}"
5875 [(set_attr "type" "alu")
5876 (set_attr "pent_pair" "pu")
5877 (set_attr "mode" "SI")])
5878
5879 (define_insn "*addsi3_carry_zext"
5880 [(set (match_operand:DI 0 "register_operand" "=r")
5881 (zero_extend:DI
5882 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5883 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5884 (match_operand:SI 2 "general_operand" "g"))))
5885 (clobber (reg:CC FLAGS_REG))]
5886 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5887 "adc{l}\t{%2, %k0|%k0, %2}"
5888 [(set_attr "type" "alu")
5889 (set_attr "pent_pair" "pu")
5890 (set_attr "mode" "SI")])
5891
5892 (define_insn "*addsi3_cc"
5893 [(set (reg:CC FLAGS_REG)
5894 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5895 (match_operand:SI 2 "general_operand" "ri,rm")]
5896 UNSPEC_ADD_CARRY))
5897 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5898 (plus:SI (match_dup 1) (match_dup 2)))]
5899 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5900 "add{l}\t{%2, %0|%0, %2}"
5901 [(set_attr "type" "alu")
5902 (set_attr "mode" "SI")])
5903
5904 (define_insn "addqi3_cc"
5905 [(set (reg:CC FLAGS_REG)
5906 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5907 (match_operand:QI 2 "general_operand" "qn,qm")]
5908 UNSPEC_ADD_CARRY))
5909 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5910 (plus:QI (match_dup 1) (match_dup 2)))]
5911 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5912 "add{b}\t{%2, %0|%0, %2}"
5913 [(set_attr "type" "alu")
5914 (set_attr "mode" "QI")])
5915
5916 (define_expand "addsi3"
5917 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5918 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5919 (match_operand:SI 2 "general_operand" "")))]
5920 ""
5921 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5922
5923 (define_insn "*lea_1"
5924 [(set (match_operand:SI 0 "register_operand" "=r")
5925 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5926 "!TARGET_64BIT"
5927 "lea{l}\t{%a1, %0|%0, %a1}"
5928 [(set_attr "type" "lea")
5929 (set_attr "mode" "SI")])
5930
5931 (define_insn "*lea_1_rex64"
5932 [(set (match_operand:SI 0 "register_operand" "=r")
5933 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5934 "TARGET_64BIT"
5935 "lea{l}\t{%a1, %0|%0, %a1}"
5936 [(set_attr "type" "lea")
5937 (set_attr "mode" "SI")])
5938
5939 (define_insn "*lea_1_zext"
5940 [(set (match_operand:DI 0 "register_operand" "=r")
5941 (zero_extend:DI
5942 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5943 "TARGET_64BIT"
5944 "lea{l}\t{%a1, %k0|%k0, %a1}"
5945 [(set_attr "type" "lea")
5946 (set_attr "mode" "SI")])
5947
5948 (define_insn "*lea_2_rex64"
5949 [(set (match_operand:DI 0 "register_operand" "=r")
5950 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5951 "TARGET_64BIT"
5952 "lea{q}\t{%a1, %0|%0, %a1}"
5953 [(set_attr "type" "lea")
5954 (set_attr "mode" "DI")])
5955
5956 ;; The lea patterns for non-Pmodes needs to be matched by several
5957 ;; insns converted to real lea by splitters.
5958
5959 (define_insn_and_split "*lea_general_1"
5960 [(set (match_operand 0 "register_operand" "=r")
5961 (plus (plus (match_operand 1 "index_register_operand" "l")
5962 (match_operand 2 "register_operand" "r"))
5963 (match_operand 3 "immediate_operand" "i")))]
5964 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5965 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5966 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5967 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5968 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5969 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5970 || GET_MODE (operands[3]) == VOIDmode)"
5971 "#"
5972 "&& reload_completed"
5973 [(const_int 0)]
5974 {
5975 rtx pat;
5976 operands[0] = gen_lowpart (SImode, operands[0]);
5977 operands[1] = gen_lowpart (Pmode, operands[1]);
5978 operands[2] = gen_lowpart (Pmode, operands[2]);
5979 operands[3] = gen_lowpart (Pmode, operands[3]);
5980 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5981 operands[3]);
5982 if (Pmode != SImode)
5983 pat = gen_rtx_SUBREG (SImode, pat, 0);
5984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5985 DONE;
5986 }
5987 [(set_attr "type" "lea")
5988 (set_attr "mode" "SI")])
5989
5990 (define_insn_and_split "*lea_general_1_zext"
5991 [(set (match_operand:DI 0 "register_operand" "=r")
5992 (zero_extend:DI
5993 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5994 (match_operand:SI 2 "register_operand" "r"))
5995 (match_operand:SI 3 "immediate_operand" "i"))))]
5996 "TARGET_64BIT"
5997 "#"
5998 "&& reload_completed"
5999 [(set (match_dup 0)
6000 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6001 (match_dup 2))
6002 (match_dup 3)) 0)))]
6003 {
6004 operands[1] = gen_lowpart (Pmode, operands[1]);
6005 operands[2] = gen_lowpart (Pmode, operands[2]);
6006 operands[3] = gen_lowpart (Pmode, operands[3]);
6007 }
6008 [(set_attr "type" "lea")
6009 (set_attr "mode" "SI")])
6010
6011 (define_insn_and_split "*lea_general_2"
6012 [(set (match_operand 0 "register_operand" "=r")
6013 (plus (mult (match_operand 1 "index_register_operand" "l")
6014 (match_operand 2 "const248_operand" "i"))
6015 (match_operand 3 "nonmemory_operand" "ri")))]
6016 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6017 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6018 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6019 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6020 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6021 || GET_MODE (operands[3]) == VOIDmode)"
6022 "#"
6023 "&& reload_completed"
6024 [(const_int 0)]
6025 {
6026 rtx pat;
6027 operands[0] = gen_lowpart (SImode, operands[0]);
6028 operands[1] = gen_lowpart (Pmode, operands[1]);
6029 operands[3] = gen_lowpart (Pmode, operands[3]);
6030 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6031 operands[3]);
6032 if (Pmode != SImode)
6033 pat = gen_rtx_SUBREG (SImode, pat, 0);
6034 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6035 DONE;
6036 }
6037 [(set_attr "type" "lea")
6038 (set_attr "mode" "SI")])
6039
6040 (define_insn_and_split "*lea_general_2_zext"
6041 [(set (match_operand:DI 0 "register_operand" "=r")
6042 (zero_extend:DI
6043 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6044 (match_operand:SI 2 "const248_operand" "n"))
6045 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6046 "TARGET_64BIT"
6047 "#"
6048 "&& reload_completed"
6049 [(set (match_dup 0)
6050 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6051 (match_dup 2))
6052 (match_dup 3)) 0)))]
6053 {
6054 operands[1] = gen_lowpart (Pmode, operands[1]);
6055 operands[3] = gen_lowpart (Pmode, operands[3]);
6056 }
6057 [(set_attr "type" "lea")
6058 (set_attr "mode" "SI")])
6059
6060 (define_insn_and_split "*lea_general_3"
6061 [(set (match_operand 0 "register_operand" "=r")
6062 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6063 (match_operand 2 "const248_operand" "i"))
6064 (match_operand 3 "register_operand" "r"))
6065 (match_operand 4 "immediate_operand" "i")))]
6066 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6067 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6068 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6069 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6070 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6071 "#"
6072 "&& reload_completed"
6073 [(const_int 0)]
6074 {
6075 rtx pat;
6076 operands[0] = gen_lowpart (SImode, operands[0]);
6077 operands[1] = gen_lowpart (Pmode, operands[1]);
6078 operands[3] = gen_lowpart (Pmode, operands[3]);
6079 operands[4] = gen_lowpart (Pmode, operands[4]);
6080 pat = gen_rtx_PLUS (Pmode,
6081 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6082 operands[2]),
6083 operands[3]),
6084 operands[4]);
6085 if (Pmode != SImode)
6086 pat = gen_rtx_SUBREG (SImode, pat, 0);
6087 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6088 DONE;
6089 }
6090 [(set_attr "type" "lea")
6091 (set_attr "mode" "SI")])
6092
6093 (define_insn_and_split "*lea_general_3_zext"
6094 [(set (match_operand:DI 0 "register_operand" "=r")
6095 (zero_extend:DI
6096 (plus:SI (plus:SI (mult:SI
6097 (match_operand:SI 1 "index_register_operand" "l")
6098 (match_operand:SI 2 "const248_operand" "n"))
6099 (match_operand:SI 3 "register_operand" "r"))
6100 (match_operand:SI 4 "immediate_operand" "i"))))]
6101 "TARGET_64BIT"
6102 "#"
6103 "&& reload_completed"
6104 [(set (match_dup 0)
6105 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6106 (match_dup 2))
6107 (match_dup 3))
6108 (match_dup 4)) 0)))]
6109 {
6110 operands[1] = gen_lowpart (Pmode, operands[1]);
6111 operands[3] = gen_lowpart (Pmode, operands[3]);
6112 operands[4] = gen_lowpart (Pmode, operands[4]);
6113 }
6114 [(set_attr "type" "lea")
6115 (set_attr "mode" "SI")])
6116
6117 (define_insn "*adddi_1_rex64"
6118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6119 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6120 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6121 (clobber (reg:CC FLAGS_REG))]
6122 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6123 {
6124 switch (get_attr_type (insn))
6125 {
6126 case TYPE_LEA:
6127 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6128 return "lea{q}\t{%a2, %0|%0, %a2}";
6129
6130 case TYPE_INCDEC:
6131 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6132 if (operands[2] == const1_rtx)
6133 return "inc{q}\t%0";
6134 else
6135 {
6136 gcc_assert (operands[2] == constm1_rtx);
6137 return "dec{q}\t%0";
6138 }
6139
6140 default:
6141 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6142
6143 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6144 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6145 if (CONST_INT_P (operands[2])
6146 /* Avoid overflows. */
6147 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6148 && (INTVAL (operands[2]) == 128
6149 || (INTVAL (operands[2]) < 0
6150 && INTVAL (operands[2]) != -128)))
6151 {
6152 operands[2] = GEN_INT (-INTVAL (operands[2]));
6153 return "sub{q}\t{%2, %0|%0, %2}";
6154 }
6155 return "add{q}\t{%2, %0|%0, %2}";
6156 }
6157 }
6158 [(set (attr "type")
6159 (cond [(eq_attr "alternative" "2")
6160 (const_string "lea")
6161 ; Current assemblers are broken and do not allow @GOTOFF in
6162 ; ought but a memory context.
6163 (match_operand:DI 2 "pic_symbolic_operand" "")
6164 (const_string "lea")
6165 (match_operand:DI 2 "incdec_operand" "")
6166 (const_string "incdec")
6167 ]
6168 (const_string "alu")))
6169 (set_attr "mode" "DI")])
6170
6171 ;; Convert lea to the lea pattern to avoid flags dependency.
6172 (define_split
6173 [(set (match_operand:DI 0 "register_operand" "")
6174 (plus:DI (match_operand:DI 1 "register_operand" "")
6175 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6176 (clobber (reg:CC FLAGS_REG))]
6177 "TARGET_64BIT && reload_completed
6178 && true_regnum (operands[0]) != true_regnum (operands[1])"
6179 [(set (match_dup 0)
6180 (plus:DI (match_dup 1)
6181 (match_dup 2)))]
6182 "")
6183
6184 (define_insn "*adddi_2_rex64"
6185 [(set (reg FLAGS_REG)
6186 (compare
6187 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6188 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6189 (const_int 0)))
6190 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6191 (plus:DI (match_dup 1) (match_dup 2)))]
6192 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6193 && ix86_binary_operator_ok (PLUS, DImode, operands)
6194 /* Current assemblers are broken and do not allow @GOTOFF in
6195 ought but a memory context. */
6196 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6197 {
6198 switch (get_attr_type (insn))
6199 {
6200 case TYPE_INCDEC:
6201 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6202 if (operands[2] == const1_rtx)
6203 return "inc{q}\t%0";
6204 else
6205 {
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{q}\t%0";
6208 }
6209
6210 default:
6211 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6212 /* ???? We ought to handle there the 32bit case too
6213 - do we need new constraint? */
6214 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6215 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6216 if (CONST_INT_P (operands[2])
6217 /* Avoid overflows. */
6218 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6219 && (INTVAL (operands[2]) == 128
6220 || (INTVAL (operands[2]) < 0
6221 && INTVAL (operands[2]) != -128)))
6222 {
6223 operands[2] = GEN_INT (-INTVAL (operands[2]));
6224 return "sub{q}\t{%2, %0|%0, %2}";
6225 }
6226 return "add{q}\t{%2, %0|%0, %2}";
6227 }
6228 }
6229 [(set (attr "type")
6230 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6231 (const_string "incdec")
6232 (const_string "alu")))
6233 (set_attr "mode" "DI")])
6234
6235 (define_insn "*adddi_3_rex64"
6236 [(set (reg FLAGS_REG)
6237 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6238 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6239 (clobber (match_scratch:DI 0 "=r"))]
6240 "TARGET_64BIT
6241 && ix86_match_ccmode (insn, CCZmode)
6242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6243 /* Current assemblers are broken and do not allow @GOTOFF in
6244 ought but a memory context. */
6245 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6246 {
6247 switch (get_attr_type (insn))
6248 {
6249 case TYPE_INCDEC:
6250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6251 if (operands[2] == const1_rtx)
6252 return "inc{q}\t%0";
6253 else
6254 {
6255 gcc_assert (operands[2] == constm1_rtx);
6256 return "dec{q}\t%0";
6257 }
6258
6259 default:
6260 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6261 /* ???? We ought to handle there the 32bit case too
6262 - do we need new constraint? */
6263 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6265 if (CONST_INT_P (operands[2])
6266 /* Avoid overflows. */
6267 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6268 && (INTVAL (operands[2]) == 128
6269 || (INTVAL (operands[2]) < 0
6270 && INTVAL (operands[2]) != -128)))
6271 {
6272 operands[2] = GEN_INT (-INTVAL (operands[2]));
6273 return "sub{q}\t{%2, %0|%0, %2}";
6274 }
6275 return "add{q}\t{%2, %0|%0, %2}";
6276 }
6277 }
6278 [(set (attr "type")
6279 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6280 (const_string "incdec")
6281 (const_string "alu")))
6282 (set_attr "mode" "DI")])
6283
6284 ; For comparisons against 1, -1 and 128, we may generate better code
6285 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6286 ; is matched then. We can't accept general immediate, because for
6287 ; case of overflows, the result is messed up.
6288 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6289 ; when negated.
6290 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6291 ; only for comparisons not depending on it.
6292 (define_insn "*adddi_4_rex64"
6293 [(set (reg FLAGS_REG)
6294 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6295 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6296 (clobber (match_scratch:DI 0 "=rm"))]
6297 "TARGET_64BIT
6298 && ix86_match_ccmode (insn, CCGCmode)"
6299 {
6300 switch (get_attr_type (insn))
6301 {
6302 case TYPE_INCDEC:
6303 if (operands[2] == constm1_rtx)
6304 return "inc{q}\t%0";
6305 else
6306 {
6307 gcc_assert (operands[2] == const1_rtx);
6308 return "dec{q}\t%0";
6309 }
6310
6311 default:
6312 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6313 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6314 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6315 if ((INTVAL (operands[2]) == -128
6316 || (INTVAL (operands[2]) > 0
6317 && INTVAL (operands[2]) != 128))
6318 /* Avoid overflows. */
6319 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6320 return "sub{q}\t{%2, %0|%0, %2}";
6321 operands[2] = GEN_INT (-INTVAL (operands[2]));
6322 return "add{q}\t{%2, %0|%0, %2}";
6323 }
6324 }
6325 [(set (attr "type")
6326 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6327 (const_string "incdec")
6328 (const_string "alu")))
6329 (set_attr "mode" "DI")])
6330
6331 (define_insn "*adddi_5_rex64"
6332 [(set (reg FLAGS_REG)
6333 (compare
6334 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6335 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6336 (const_int 0)))
6337 (clobber (match_scratch:DI 0 "=r"))]
6338 "TARGET_64BIT
6339 && ix86_match_ccmode (insn, CCGOCmode)
6340 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6341 /* Current assemblers are broken and do not allow @GOTOFF in
6342 ought but a memory context. */
6343 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6344 {
6345 switch (get_attr_type (insn))
6346 {
6347 case TYPE_INCDEC:
6348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6349 if (operands[2] == const1_rtx)
6350 return "inc{q}\t%0";
6351 else
6352 {
6353 gcc_assert (operands[2] == constm1_rtx);
6354 return "dec{q}\t%0";
6355 }
6356
6357 default:
6358 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6359 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6360 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6361 if (CONST_INT_P (operands[2])
6362 /* Avoid overflows. */
6363 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6364 && (INTVAL (operands[2]) == 128
6365 || (INTVAL (operands[2]) < 0
6366 && INTVAL (operands[2]) != -128)))
6367 {
6368 operands[2] = GEN_INT (-INTVAL (operands[2]));
6369 return "sub{q}\t{%2, %0|%0, %2}";
6370 }
6371 return "add{q}\t{%2, %0|%0, %2}";
6372 }
6373 }
6374 [(set (attr "type")
6375 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6376 (const_string "incdec")
6377 (const_string "alu")))
6378 (set_attr "mode" "DI")])
6379
6380
6381 (define_insn "*addsi_1"
6382 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6383 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6384 (match_operand:SI 2 "general_operand" "g,ri,li")))
6385 (clobber (reg:CC FLAGS_REG))]
6386 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6387 {
6388 switch (get_attr_type (insn))
6389 {
6390 case TYPE_LEA:
6391 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6392 return "lea{l}\t{%a2, %0|%0, %a2}";
6393
6394 case TYPE_INCDEC:
6395 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6396 if (operands[2] == const1_rtx)
6397 return "inc{l}\t%0";
6398 else
6399 {
6400 gcc_assert (operands[2] == constm1_rtx);
6401 return "dec{l}\t%0";
6402 }
6403
6404 default:
6405 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6406
6407 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6408 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6409 if (CONST_INT_P (operands[2])
6410 && (INTVAL (operands[2]) == 128
6411 || (INTVAL (operands[2]) < 0
6412 && INTVAL (operands[2]) != -128)))
6413 {
6414 operands[2] = GEN_INT (-INTVAL (operands[2]));
6415 return "sub{l}\t{%2, %0|%0, %2}";
6416 }
6417 return "add{l}\t{%2, %0|%0, %2}";
6418 }
6419 }
6420 [(set (attr "type")
6421 (cond [(eq_attr "alternative" "2")
6422 (const_string "lea")
6423 ; Current assemblers are broken and do not allow @GOTOFF in
6424 ; ought but a memory context.
6425 (match_operand:SI 2 "pic_symbolic_operand" "")
6426 (const_string "lea")
6427 (match_operand:SI 2 "incdec_operand" "")
6428 (const_string "incdec")
6429 ]
6430 (const_string "alu")))
6431 (set_attr "mode" "SI")])
6432
6433 ;; Convert lea to the lea pattern to avoid flags dependency.
6434 (define_split
6435 [(set (match_operand 0 "register_operand" "")
6436 (plus (match_operand 1 "register_operand" "")
6437 (match_operand 2 "nonmemory_operand" "")))
6438 (clobber (reg:CC FLAGS_REG))]
6439 "reload_completed
6440 && true_regnum (operands[0]) != true_regnum (operands[1])"
6441 [(const_int 0)]
6442 {
6443 rtx pat;
6444 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6445 may confuse gen_lowpart. */
6446 if (GET_MODE (operands[0]) != Pmode)
6447 {
6448 operands[1] = gen_lowpart (Pmode, operands[1]);
6449 operands[2] = gen_lowpart (Pmode, operands[2]);
6450 }
6451 operands[0] = gen_lowpart (SImode, operands[0]);
6452 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6453 if (Pmode != SImode)
6454 pat = gen_rtx_SUBREG (SImode, pat, 0);
6455 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6456 DONE;
6457 })
6458
6459 ;; It may seem that nonimmediate operand is proper one for operand 1.
6460 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6461 ;; we take care in ix86_binary_operator_ok to not allow two memory
6462 ;; operands so proper swapping will be done in reload. This allow
6463 ;; patterns constructed from addsi_1 to match.
6464 (define_insn "addsi_1_zext"
6465 [(set (match_operand:DI 0 "register_operand" "=r,r")
6466 (zero_extend:DI
6467 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6468 (match_operand:SI 2 "general_operand" "g,li"))))
6469 (clobber (reg:CC FLAGS_REG))]
6470 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6471 {
6472 switch (get_attr_type (insn))
6473 {
6474 case TYPE_LEA:
6475 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6476 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6477
6478 case TYPE_INCDEC:
6479 if (operands[2] == const1_rtx)
6480 return "inc{l}\t%k0";
6481 else
6482 {
6483 gcc_assert (operands[2] == constm1_rtx);
6484 return "dec{l}\t%k0";
6485 }
6486
6487 default:
6488 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6490 if (CONST_INT_P (operands[2])
6491 && (INTVAL (operands[2]) == 128
6492 || (INTVAL (operands[2]) < 0
6493 && INTVAL (operands[2]) != -128)))
6494 {
6495 operands[2] = GEN_INT (-INTVAL (operands[2]));
6496 return "sub{l}\t{%2, %k0|%k0, %2}";
6497 }
6498 return "add{l}\t{%2, %k0|%k0, %2}";
6499 }
6500 }
6501 [(set (attr "type")
6502 (cond [(eq_attr "alternative" "1")
6503 (const_string "lea")
6504 ; Current assemblers are broken and do not allow @GOTOFF in
6505 ; ought but a memory context.
6506 (match_operand:SI 2 "pic_symbolic_operand" "")
6507 (const_string "lea")
6508 (match_operand:SI 2 "incdec_operand" "")
6509 (const_string "incdec")
6510 ]
6511 (const_string "alu")))
6512 (set_attr "mode" "SI")])
6513
6514 ;; Convert lea to the lea pattern to avoid flags dependency.
6515 (define_split
6516 [(set (match_operand:DI 0 "register_operand" "")
6517 (zero_extend:DI
6518 (plus:SI (match_operand:SI 1 "register_operand" "")
6519 (match_operand:SI 2 "nonmemory_operand" ""))))
6520 (clobber (reg:CC FLAGS_REG))]
6521 "TARGET_64BIT && reload_completed
6522 && true_regnum (operands[0]) != true_regnum (operands[1])"
6523 [(set (match_dup 0)
6524 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6525 {
6526 operands[1] = gen_lowpart (Pmode, operands[1]);
6527 operands[2] = gen_lowpart (Pmode, operands[2]);
6528 })
6529
6530 (define_insn "*addsi_2"
6531 [(set (reg FLAGS_REG)
6532 (compare
6533 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6534 (match_operand:SI 2 "general_operand" "g,ri"))
6535 (const_int 0)))
6536 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6537 (plus:SI (match_dup 1) (match_dup 2)))]
6538 "ix86_match_ccmode (insn, CCGOCmode)
6539 && ix86_binary_operator_ok (PLUS, SImode, operands)
6540 /* Current assemblers are broken and do not allow @GOTOFF in
6541 ought but a memory context. */
6542 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6543 {
6544 switch (get_attr_type (insn))
6545 {
6546 case TYPE_INCDEC:
6547 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6548 if (operands[2] == const1_rtx)
6549 return "inc{l}\t%0";
6550 else
6551 {
6552 gcc_assert (operands[2] == constm1_rtx);
6553 return "dec{l}\t%0";
6554 }
6555
6556 default:
6557 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6558 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6559 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6560 if (CONST_INT_P (operands[2])
6561 && (INTVAL (operands[2]) == 128
6562 || (INTVAL (operands[2]) < 0
6563 && INTVAL (operands[2]) != -128)))
6564 {
6565 operands[2] = GEN_INT (-INTVAL (operands[2]));
6566 return "sub{l}\t{%2, %0|%0, %2}";
6567 }
6568 return "add{l}\t{%2, %0|%0, %2}";
6569 }
6570 }
6571 [(set (attr "type")
6572 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6573 (const_string "incdec")
6574 (const_string "alu")))
6575 (set_attr "mode" "SI")])
6576
6577 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6578 (define_insn "*addsi_2_zext"
6579 [(set (reg FLAGS_REG)
6580 (compare
6581 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6582 (match_operand:SI 2 "general_operand" "g"))
6583 (const_int 0)))
6584 (set (match_operand:DI 0 "register_operand" "=r")
6585 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6586 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6587 && ix86_binary_operator_ok (PLUS, SImode, operands)
6588 /* Current assemblers are broken and do not allow @GOTOFF in
6589 ought but a memory context. */
6590 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6591 {
6592 switch (get_attr_type (insn))
6593 {
6594 case TYPE_INCDEC:
6595 if (operands[2] == const1_rtx)
6596 return "inc{l}\t%k0";
6597 else
6598 {
6599 gcc_assert (operands[2] == constm1_rtx);
6600 return "dec{l}\t%k0";
6601 }
6602
6603 default:
6604 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6606 if (CONST_INT_P (operands[2])
6607 && (INTVAL (operands[2]) == 128
6608 || (INTVAL (operands[2]) < 0
6609 && INTVAL (operands[2]) != -128)))
6610 {
6611 operands[2] = GEN_INT (-INTVAL (operands[2]));
6612 return "sub{l}\t{%2, %k0|%k0, %2}";
6613 }
6614 return "add{l}\t{%2, %k0|%k0, %2}";
6615 }
6616 }
6617 [(set (attr "type")
6618 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6619 (const_string "incdec")
6620 (const_string "alu")))
6621 (set_attr "mode" "SI")])
6622
6623 (define_insn "*addsi_3"
6624 [(set (reg FLAGS_REG)
6625 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6626 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6627 (clobber (match_scratch:SI 0 "=r"))]
6628 "ix86_match_ccmode (insn, CCZmode)
6629 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6630 /* Current assemblers are broken and do not allow @GOTOFF in
6631 ought but a memory context. */
6632 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6633 {
6634 switch (get_attr_type (insn))
6635 {
6636 case TYPE_INCDEC:
6637 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6638 if (operands[2] == const1_rtx)
6639 return "inc{l}\t%0";
6640 else
6641 {
6642 gcc_assert (operands[2] == constm1_rtx);
6643 return "dec{l}\t%0";
6644 }
6645
6646 default:
6647 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6648 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6649 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6650 if (CONST_INT_P (operands[2])
6651 && (INTVAL (operands[2]) == 128
6652 || (INTVAL (operands[2]) < 0
6653 && INTVAL (operands[2]) != -128)))
6654 {
6655 operands[2] = GEN_INT (-INTVAL (operands[2]));
6656 return "sub{l}\t{%2, %0|%0, %2}";
6657 }
6658 return "add{l}\t{%2, %0|%0, %2}";
6659 }
6660 }
6661 [(set (attr "type")
6662 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6663 (const_string "incdec")
6664 (const_string "alu")))
6665 (set_attr "mode" "SI")])
6666
6667 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6668 (define_insn "*addsi_3_zext"
6669 [(set (reg FLAGS_REG)
6670 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6671 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6672 (set (match_operand:DI 0 "register_operand" "=r")
6673 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6674 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6675 && ix86_binary_operator_ok (PLUS, SImode, operands)
6676 /* Current assemblers are broken and do not allow @GOTOFF in
6677 ought but a memory context. */
6678 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6679 {
6680 switch (get_attr_type (insn))
6681 {
6682 case TYPE_INCDEC:
6683 if (operands[2] == const1_rtx)
6684 return "inc{l}\t%k0";
6685 else
6686 {
6687 gcc_assert (operands[2] == constm1_rtx);
6688 return "dec{l}\t%k0";
6689 }
6690
6691 default:
6692 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6693 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6694 if (CONST_INT_P (operands[2])
6695 && (INTVAL (operands[2]) == 128
6696 || (INTVAL (operands[2]) < 0
6697 && INTVAL (operands[2]) != -128)))
6698 {
6699 operands[2] = GEN_INT (-INTVAL (operands[2]));
6700 return "sub{l}\t{%2, %k0|%k0, %2}";
6701 }
6702 return "add{l}\t{%2, %k0|%k0, %2}";
6703 }
6704 }
6705 [(set (attr "type")
6706 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6707 (const_string "incdec")
6708 (const_string "alu")))
6709 (set_attr "mode" "SI")])
6710
6711 ; For comparisons against 1, -1 and 128, we may generate better code
6712 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6713 ; is matched then. We can't accept general immediate, because for
6714 ; case of overflows, the result is messed up.
6715 ; This pattern also don't hold of 0x80000000, since the value overflows
6716 ; when negated.
6717 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6718 ; only for comparisons not depending on it.
6719 (define_insn "*addsi_4"
6720 [(set (reg FLAGS_REG)
6721 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6722 (match_operand:SI 2 "const_int_operand" "n")))
6723 (clobber (match_scratch:SI 0 "=rm"))]
6724 "ix86_match_ccmode (insn, CCGCmode)
6725 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6726 {
6727 switch (get_attr_type (insn))
6728 {
6729 case TYPE_INCDEC:
6730 if (operands[2] == constm1_rtx)
6731 return "inc{l}\t%0";
6732 else
6733 {
6734 gcc_assert (operands[2] == const1_rtx);
6735 return "dec{l}\t%0";
6736 }
6737
6738 default:
6739 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6740 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6741 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6742 if ((INTVAL (operands[2]) == -128
6743 || (INTVAL (operands[2]) > 0
6744 && INTVAL (operands[2]) != 128)))
6745 return "sub{l}\t{%2, %0|%0, %2}";
6746 operands[2] = GEN_INT (-INTVAL (operands[2]));
6747 return "add{l}\t{%2, %0|%0, %2}";
6748 }
6749 }
6750 [(set (attr "type")
6751 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6752 (const_string "incdec")
6753 (const_string "alu")))
6754 (set_attr "mode" "SI")])
6755
6756 (define_insn "*addsi_5"
6757 [(set (reg FLAGS_REG)
6758 (compare
6759 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6760 (match_operand:SI 2 "general_operand" "g"))
6761 (const_int 0)))
6762 (clobber (match_scratch:SI 0 "=r"))]
6763 "ix86_match_ccmode (insn, CCGOCmode)
6764 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6765 /* Current assemblers are broken and do not allow @GOTOFF in
6766 ought but a memory context. */
6767 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6768 {
6769 switch (get_attr_type (insn))
6770 {
6771 case TYPE_INCDEC:
6772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6773 if (operands[2] == const1_rtx)
6774 return "inc{l}\t%0";
6775 else
6776 {
6777 gcc_assert (operands[2] == constm1_rtx);
6778 return "dec{l}\t%0";
6779 }
6780
6781 default:
6782 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6783 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6784 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6785 if (CONST_INT_P (operands[2])
6786 && (INTVAL (operands[2]) == 128
6787 || (INTVAL (operands[2]) < 0
6788 && INTVAL (operands[2]) != -128)))
6789 {
6790 operands[2] = GEN_INT (-INTVAL (operands[2]));
6791 return "sub{l}\t{%2, %0|%0, %2}";
6792 }
6793 return "add{l}\t{%2, %0|%0, %2}";
6794 }
6795 }
6796 [(set (attr "type")
6797 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6798 (const_string "incdec")
6799 (const_string "alu")))
6800 (set_attr "mode" "SI")])
6801
6802 (define_expand "addhi3"
6803 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6804 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6805 (match_operand:HI 2 "general_operand" "")))]
6806 "TARGET_HIMODE_MATH"
6807 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6808
6809 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6810 ;; type optimizations enabled by define-splits. This is not important
6811 ;; for PII, and in fact harmful because of partial register stalls.
6812
6813 (define_insn "*addhi_1_lea"
6814 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6815 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6816 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6817 (clobber (reg:CC FLAGS_REG))]
6818 "!TARGET_PARTIAL_REG_STALL
6819 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6820 {
6821 switch (get_attr_type (insn))
6822 {
6823 case TYPE_LEA:
6824 return "#";
6825 case TYPE_INCDEC:
6826 if (operands[2] == const1_rtx)
6827 return "inc{w}\t%0";
6828 else
6829 {
6830 gcc_assert (operands[2] == constm1_rtx);
6831 return "dec{w}\t%0";
6832 }
6833
6834 default:
6835 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6836 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6837 if (CONST_INT_P (operands[2])
6838 && (INTVAL (operands[2]) == 128
6839 || (INTVAL (operands[2]) < 0
6840 && INTVAL (operands[2]) != -128)))
6841 {
6842 operands[2] = GEN_INT (-INTVAL (operands[2]));
6843 return "sub{w}\t{%2, %0|%0, %2}";
6844 }
6845 return "add{w}\t{%2, %0|%0, %2}";
6846 }
6847 }
6848 [(set (attr "type")
6849 (if_then_else (eq_attr "alternative" "2")
6850 (const_string "lea")
6851 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6852 (const_string "incdec")
6853 (const_string "alu"))))
6854 (set_attr "mode" "HI,HI,SI")])
6855
6856 (define_insn "*addhi_1"
6857 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6858 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6859 (match_operand:HI 2 "general_operand" "rn,rm")))
6860 (clobber (reg:CC FLAGS_REG))]
6861 "TARGET_PARTIAL_REG_STALL
6862 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6863 {
6864 switch (get_attr_type (insn))
6865 {
6866 case TYPE_INCDEC:
6867 if (operands[2] == const1_rtx)
6868 return "inc{w}\t%0";
6869 else
6870 {
6871 gcc_assert (operands[2] == constm1_rtx);
6872 return "dec{w}\t%0";
6873 }
6874
6875 default:
6876 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6877 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6878 if (CONST_INT_P (operands[2])
6879 && (INTVAL (operands[2]) == 128
6880 || (INTVAL (operands[2]) < 0
6881 && INTVAL (operands[2]) != -128)))
6882 {
6883 operands[2] = GEN_INT (-INTVAL (operands[2]));
6884 return "sub{w}\t{%2, %0|%0, %2}";
6885 }
6886 return "add{w}\t{%2, %0|%0, %2}";
6887 }
6888 }
6889 [(set (attr "type")
6890 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6891 (const_string "incdec")
6892 (const_string "alu")))
6893 (set_attr "mode" "HI")])
6894
6895 (define_insn "*addhi_2"
6896 [(set (reg FLAGS_REG)
6897 (compare
6898 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6899 (match_operand:HI 2 "general_operand" "rmn,rn"))
6900 (const_int 0)))
6901 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6902 (plus:HI (match_dup 1) (match_dup 2)))]
6903 "ix86_match_ccmode (insn, CCGOCmode)
6904 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6905 {
6906 switch (get_attr_type (insn))
6907 {
6908 case TYPE_INCDEC:
6909 if (operands[2] == const1_rtx)
6910 return "inc{w}\t%0";
6911 else
6912 {
6913 gcc_assert (operands[2] == constm1_rtx);
6914 return "dec{w}\t%0";
6915 }
6916
6917 default:
6918 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6919 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6920 if (CONST_INT_P (operands[2])
6921 && (INTVAL (operands[2]) == 128
6922 || (INTVAL (operands[2]) < 0
6923 && INTVAL (operands[2]) != -128)))
6924 {
6925 operands[2] = GEN_INT (-INTVAL (operands[2]));
6926 return "sub{w}\t{%2, %0|%0, %2}";
6927 }
6928 return "add{w}\t{%2, %0|%0, %2}";
6929 }
6930 }
6931 [(set (attr "type")
6932 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6933 (const_string "incdec")
6934 (const_string "alu")))
6935 (set_attr "mode" "HI")])
6936
6937 (define_insn "*addhi_3"
6938 [(set (reg FLAGS_REG)
6939 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6940 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6941 (clobber (match_scratch:HI 0 "=r"))]
6942 "ix86_match_ccmode (insn, CCZmode)
6943 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944 {
6945 switch (get_attr_type (insn))
6946 {
6947 case TYPE_INCDEC:
6948 if (operands[2] == const1_rtx)
6949 return "inc{w}\t%0";
6950 else
6951 {
6952 gcc_assert (operands[2] == constm1_rtx);
6953 return "dec{w}\t%0";
6954 }
6955
6956 default:
6957 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6958 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6959 if (CONST_INT_P (operands[2])
6960 && (INTVAL (operands[2]) == 128
6961 || (INTVAL (operands[2]) < 0
6962 && INTVAL (operands[2]) != -128)))
6963 {
6964 operands[2] = GEN_INT (-INTVAL (operands[2]));
6965 return "sub{w}\t{%2, %0|%0, %2}";
6966 }
6967 return "add{w}\t{%2, %0|%0, %2}";
6968 }
6969 }
6970 [(set (attr "type")
6971 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6972 (const_string "incdec")
6973 (const_string "alu")))
6974 (set_attr "mode" "HI")])
6975
6976 ; See comments above addsi_4 for details.
6977 (define_insn "*addhi_4"
6978 [(set (reg FLAGS_REG)
6979 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6980 (match_operand:HI 2 "const_int_operand" "n")))
6981 (clobber (match_scratch:HI 0 "=rm"))]
6982 "ix86_match_ccmode (insn, CCGCmode)
6983 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6984 {
6985 switch (get_attr_type (insn))
6986 {
6987 case TYPE_INCDEC:
6988 if (operands[2] == constm1_rtx)
6989 return "inc{w}\t%0";
6990 else
6991 {
6992 gcc_assert (operands[2] == const1_rtx);
6993 return "dec{w}\t%0";
6994 }
6995
6996 default:
6997 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6998 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6999 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7000 if ((INTVAL (operands[2]) == -128
7001 || (INTVAL (operands[2]) > 0
7002 && INTVAL (operands[2]) != 128)))
7003 return "sub{w}\t{%2, %0|%0, %2}";
7004 operands[2] = GEN_INT (-INTVAL (operands[2]));
7005 return "add{w}\t{%2, %0|%0, %2}";
7006 }
7007 }
7008 [(set (attr "type")
7009 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7010 (const_string "incdec")
7011 (const_string "alu")))
7012 (set_attr "mode" "SI")])
7013
7014
7015 (define_insn "*addhi_5"
7016 [(set (reg FLAGS_REG)
7017 (compare
7018 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7019 (match_operand:HI 2 "general_operand" "rmn"))
7020 (const_int 0)))
7021 (clobber (match_scratch:HI 0 "=r"))]
7022 "ix86_match_ccmode (insn, CCGOCmode)
7023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024 {
7025 switch (get_attr_type (insn))
7026 {
7027 case TYPE_INCDEC:
7028 if (operands[2] == const1_rtx)
7029 return "inc{w}\t%0";
7030 else
7031 {
7032 gcc_assert (operands[2] == constm1_rtx);
7033 return "dec{w}\t%0";
7034 }
7035
7036 default:
7037 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7038 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7039 if (CONST_INT_P (operands[2])
7040 && (INTVAL (operands[2]) == 128
7041 || (INTVAL (operands[2]) < 0
7042 && INTVAL (operands[2]) != -128)))
7043 {
7044 operands[2] = GEN_INT (-INTVAL (operands[2]));
7045 return "sub{w}\t{%2, %0|%0, %2}";
7046 }
7047 return "add{w}\t{%2, %0|%0, %2}";
7048 }
7049 }
7050 [(set (attr "type")
7051 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7052 (const_string "incdec")
7053 (const_string "alu")))
7054 (set_attr "mode" "HI")])
7055
7056 (define_expand "addqi3"
7057 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7058 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7059 (match_operand:QI 2 "general_operand" "")))]
7060 "TARGET_QIMODE_MATH"
7061 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7062
7063 ;; %%% Potential partial reg stall on alternative 2. What to do?
7064 (define_insn "*addqi_1_lea"
7065 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7066 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7067 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7068 (clobber (reg:CC FLAGS_REG))]
7069 "!TARGET_PARTIAL_REG_STALL
7070 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7071 {
7072 int widen = (which_alternative == 2);
7073 switch (get_attr_type (insn))
7074 {
7075 case TYPE_LEA:
7076 return "#";
7077 case TYPE_INCDEC:
7078 if (operands[2] == const1_rtx)
7079 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7080 else
7081 {
7082 gcc_assert (operands[2] == constm1_rtx);
7083 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7084 }
7085
7086 default:
7087 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7088 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7089 if (CONST_INT_P (operands[2])
7090 && (INTVAL (operands[2]) == 128
7091 || (INTVAL (operands[2]) < 0
7092 && INTVAL (operands[2]) != -128)))
7093 {
7094 operands[2] = GEN_INT (-INTVAL (operands[2]));
7095 if (widen)
7096 return "sub{l}\t{%2, %k0|%k0, %2}";
7097 else
7098 return "sub{b}\t{%2, %0|%0, %2}";
7099 }
7100 if (widen)
7101 return "add{l}\t{%k2, %k0|%k0, %k2}";
7102 else
7103 return "add{b}\t{%2, %0|%0, %2}";
7104 }
7105 }
7106 [(set (attr "type")
7107 (if_then_else (eq_attr "alternative" "3")
7108 (const_string "lea")
7109 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7110 (const_string "incdec")
7111 (const_string "alu"))))
7112 (set_attr "mode" "QI,QI,SI,SI")])
7113
7114 (define_insn "*addqi_1"
7115 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7116 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7117 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7118 (clobber (reg:CC FLAGS_REG))]
7119 "TARGET_PARTIAL_REG_STALL
7120 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7121 {
7122 int widen = (which_alternative == 2);
7123 switch (get_attr_type (insn))
7124 {
7125 case TYPE_INCDEC:
7126 if (operands[2] == const1_rtx)
7127 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7128 else
7129 {
7130 gcc_assert (operands[2] == constm1_rtx);
7131 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7132 }
7133
7134 default:
7135 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7136 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7137 if (CONST_INT_P (operands[2])
7138 && (INTVAL (operands[2]) == 128
7139 || (INTVAL (operands[2]) < 0
7140 && INTVAL (operands[2]) != -128)))
7141 {
7142 operands[2] = GEN_INT (-INTVAL (operands[2]));
7143 if (widen)
7144 return "sub{l}\t{%2, %k0|%k0, %2}";
7145 else
7146 return "sub{b}\t{%2, %0|%0, %2}";
7147 }
7148 if (widen)
7149 return "add{l}\t{%k2, %k0|%k0, %k2}";
7150 else
7151 return "add{b}\t{%2, %0|%0, %2}";
7152 }
7153 }
7154 [(set (attr "type")
7155 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7156 (const_string "incdec")
7157 (const_string "alu")))
7158 (set_attr "mode" "QI,QI,SI")])
7159
7160 (define_insn "*addqi_1_slp"
7161 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7162 (plus:QI (match_dup 0)
7163 (match_operand:QI 1 "general_operand" "qn,qnm")))
7164 (clobber (reg:CC FLAGS_REG))]
7165 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7166 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7167 {
7168 switch (get_attr_type (insn))
7169 {
7170 case TYPE_INCDEC:
7171 if (operands[1] == const1_rtx)
7172 return "inc{b}\t%0";
7173 else
7174 {
7175 gcc_assert (operands[1] == constm1_rtx);
7176 return "dec{b}\t%0";
7177 }
7178
7179 default:
7180 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7181 if (CONST_INT_P (operands[1])
7182 && INTVAL (operands[1]) < 0)
7183 {
7184 operands[1] = GEN_INT (-INTVAL (operands[1]));
7185 return "sub{b}\t{%1, %0|%0, %1}";
7186 }
7187 return "add{b}\t{%1, %0|%0, %1}";
7188 }
7189 }
7190 [(set (attr "type")
7191 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7192 (const_string "incdec")
7193 (const_string "alu1")))
7194 (set (attr "memory")
7195 (if_then_else (match_operand 1 "memory_operand" "")
7196 (const_string "load")
7197 (const_string "none")))
7198 (set_attr "mode" "QI")])
7199
7200 (define_insn "*addqi_2"
7201 [(set (reg FLAGS_REG)
7202 (compare
7203 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7204 (match_operand:QI 2 "general_operand" "qmn,qn"))
7205 (const_int 0)))
7206 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7207 (plus:QI (match_dup 1) (match_dup 2)))]
7208 "ix86_match_ccmode (insn, CCGOCmode)
7209 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7210 {
7211 switch (get_attr_type (insn))
7212 {
7213 case TYPE_INCDEC:
7214 if (operands[2] == const1_rtx)
7215 return "inc{b}\t%0";
7216 else
7217 {
7218 gcc_assert (operands[2] == constm1_rtx
7219 || (CONST_INT_P (operands[2])
7220 && INTVAL (operands[2]) == 255));
7221 return "dec{b}\t%0";
7222 }
7223
7224 default:
7225 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7226 if (CONST_INT_P (operands[2])
7227 && INTVAL (operands[2]) < 0)
7228 {
7229 operands[2] = GEN_INT (-INTVAL (operands[2]));
7230 return "sub{b}\t{%2, %0|%0, %2}";
7231 }
7232 return "add{b}\t{%2, %0|%0, %2}";
7233 }
7234 }
7235 [(set (attr "type")
7236 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7237 (const_string "incdec")
7238 (const_string "alu")))
7239 (set_attr "mode" "QI")])
7240
7241 (define_insn "*addqi_3"
7242 [(set (reg FLAGS_REG)
7243 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7244 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7245 (clobber (match_scratch:QI 0 "=q"))]
7246 "ix86_match_ccmode (insn, CCZmode)
7247 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7248 {
7249 switch (get_attr_type (insn))
7250 {
7251 case TYPE_INCDEC:
7252 if (operands[2] == const1_rtx)
7253 return "inc{b}\t%0";
7254 else
7255 {
7256 gcc_assert (operands[2] == constm1_rtx
7257 || (CONST_INT_P (operands[2])
7258 && INTVAL (operands[2]) == 255));
7259 return "dec{b}\t%0";
7260 }
7261
7262 default:
7263 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7264 if (CONST_INT_P (operands[2])
7265 && INTVAL (operands[2]) < 0)
7266 {
7267 operands[2] = GEN_INT (-INTVAL (operands[2]));
7268 return "sub{b}\t{%2, %0|%0, %2}";
7269 }
7270 return "add{b}\t{%2, %0|%0, %2}";
7271 }
7272 }
7273 [(set (attr "type")
7274 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7275 (const_string "incdec")
7276 (const_string "alu")))
7277 (set_attr "mode" "QI")])
7278
7279 ; See comments above addsi_4 for details.
7280 (define_insn "*addqi_4"
7281 [(set (reg FLAGS_REG)
7282 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7283 (match_operand:QI 2 "const_int_operand" "n")))
7284 (clobber (match_scratch:QI 0 "=qm"))]
7285 "ix86_match_ccmode (insn, CCGCmode)
7286 && (INTVAL (operands[2]) & 0xff) != 0x80"
7287 {
7288 switch (get_attr_type (insn))
7289 {
7290 case TYPE_INCDEC:
7291 if (operands[2] == constm1_rtx
7292 || (CONST_INT_P (operands[2])
7293 && INTVAL (operands[2]) == 255))
7294 return "inc{b}\t%0";
7295 else
7296 {
7297 gcc_assert (operands[2] == const1_rtx);
7298 return "dec{b}\t%0";
7299 }
7300
7301 default:
7302 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7303 if (INTVAL (operands[2]) < 0)
7304 {
7305 operands[2] = GEN_INT (-INTVAL (operands[2]));
7306 return "add{b}\t{%2, %0|%0, %2}";
7307 }
7308 return "sub{b}\t{%2, %0|%0, %2}";
7309 }
7310 }
7311 [(set (attr "type")
7312 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7313 (const_string "incdec")
7314 (const_string "alu")))
7315 (set_attr "mode" "QI")])
7316
7317
7318 (define_insn "*addqi_5"
7319 [(set (reg FLAGS_REG)
7320 (compare
7321 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7322 (match_operand:QI 2 "general_operand" "qmn"))
7323 (const_int 0)))
7324 (clobber (match_scratch:QI 0 "=q"))]
7325 "ix86_match_ccmode (insn, CCGOCmode)
7326 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7327 {
7328 switch (get_attr_type (insn))
7329 {
7330 case TYPE_INCDEC:
7331 if (operands[2] == const1_rtx)
7332 return "inc{b}\t%0";
7333 else
7334 {
7335 gcc_assert (operands[2] == constm1_rtx
7336 || (CONST_INT_P (operands[2])
7337 && INTVAL (operands[2]) == 255));
7338 return "dec{b}\t%0";
7339 }
7340
7341 default:
7342 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7343 if (CONST_INT_P (operands[2])
7344 && INTVAL (operands[2]) < 0)
7345 {
7346 operands[2] = GEN_INT (-INTVAL (operands[2]));
7347 return "sub{b}\t{%2, %0|%0, %2}";
7348 }
7349 return "add{b}\t{%2, %0|%0, %2}";
7350 }
7351 }
7352 [(set (attr "type")
7353 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7354 (const_string "incdec")
7355 (const_string "alu")))
7356 (set_attr "mode" "QI")])
7357
7358
7359 (define_insn "addqi_ext_1"
7360 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7361 (const_int 8)
7362 (const_int 8))
7363 (plus:SI
7364 (zero_extract:SI
7365 (match_operand 1 "ext_register_operand" "0")
7366 (const_int 8)
7367 (const_int 8))
7368 (match_operand:QI 2 "general_operand" "Qmn")))
7369 (clobber (reg:CC FLAGS_REG))]
7370 "!TARGET_64BIT"
7371 {
7372 switch (get_attr_type (insn))
7373 {
7374 case TYPE_INCDEC:
7375 if (operands[2] == const1_rtx)
7376 return "inc{b}\t%h0";
7377 else
7378 {
7379 gcc_assert (operands[2] == constm1_rtx
7380 || (CONST_INT_P (operands[2])
7381 && INTVAL (operands[2]) == 255));
7382 return "dec{b}\t%h0";
7383 }
7384
7385 default:
7386 return "add{b}\t{%2, %h0|%h0, %2}";
7387 }
7388 }
7389 [(set (attr "type")
7390 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7391 (const_string "incdec")
7392 (const_string "alu")))
7393 (set_attr "mode" "QI")])
7394
7395 (define_insn "*addqi_ext_1_rex64"
7396 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7397 (const_int 8)
7398 (const_int 8))
7399 (plus:SI
7400 (zero_extract:SI
7401 (match_operand 1 "ext_register_operand" "0")
7402 (const_int 8)
7403 (const_int 8))
7404 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7405 (clobber (reg:CC FLAGS_REG))]
7406 "TARGET_64BIT"
7407 {
7408 switch (get_attr_type (insn))
7409 {
7410 case TYPE_INCDEC:
7411 if (operands[2] == const1_rtx)
7412 return "inc{b}\t%h0";
7413 else
7414 {
7415 gcc_assert (operands[2] == constm1_rtx
7416 || (CONST_INT_P (operands[2])
7417 && INTVAL (operands[2]) == 255));
7418 return "dec{b}\t%h0";
7419 }
7420
7421 default:
7422 return "add{b}\t{%2, %h0|%h0, %2}";
7423 }
7424 }
7425 [(set (attr "type")
7426 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7427 (const_string "incdec")
7428 (const_string "alu")))
7429 (set_attr "mode" "QI")])
7430
7431 (define_insn "*addqi_ext_2"
7432 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7433 (const_int 8)
7434 (const_int 8))
7435 (plus:SI
7436 (zero_extract:SI
7437 (match_operand 1 "ext_register_operand" "%0")
7438 (const_int 8)
7439 (const_int 8))
7440 (zero_extract:SI
7441 (match_operand 2 "ext_register_operand" "Q")
7442 (const_int 8)
7443 (const_int 8))))
7444 (clobber (reg:CC FLAGS_REG))]
7445 ""
7446 "add{b}\t{%h2, %h0|%h0, %h2}"
7447 [(set_attr "type" "alu")
7448 (set_attr "mode" "QI")])
7449
7450 ;; The patterns that match these are at the end of this file.
7451
7452 (define_expand "addxf3"
7453 [(set (match_operand:XF 0 "register_operand" "")
7454 (plus:XF (match_operand:XF 1 "register_operand" "")
7455 (match_operand:XF 2 "register_operand" "")))]
7456 "TARGET_80387"
7457 "")
7458
7459 (define_expand "add<mode>3"
7460 [(set (match_operand:MODEF 0 "register_operand" "")
7461 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7462 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7463 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7464 "")
7465 \f
7466 ;; Subtract instructions
7467
7468 ;; %%% splits for subditi3
7469
7470 (define_expand "subti3"
7471 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7472 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7473 (match_operand:TI 2 "x86_64_general_operand" "")))]
7474 "TARGET_64BIT"
7475 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7476
7477 (define_insn "*subti3_1"
7478 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7479 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7480 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7481 (clobber (reg:CC FLAGS_REG))]
7482 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7483 "#")
7484
7485 (define_split
7486 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7487 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7488 (match_operand:TI 2 "x86_64_general_operand" "")))
7489 (clobber (reg:CC FLAGS_REG))]
7490 "TARGET_64BIT && reload_completed"
7491 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7492 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7493 (parallel [(set (match_dup 3)
7494 (minus:DI (match_dup 4)
7495 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7496 (match_dup 5))))
7497 (clobber (reg:CC FLAGS_REG))])]
7498 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7499
7500 ;; %%% splits for subsidi3
7501
7502 (define_expand "subdi3"
7503 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7504 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7505 (match_operand:DI 2 "x86_64_general_operand" "")))]
7506 ""
7507 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7508
7509 (define_insn "*subdi3_1"
7510 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7511 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7512 (match_operand:DI 2 "general_operand" "roiF,riF")))
7513 (clobber (reg:CC FLAGS_REG))]
7514 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7515 "#")
7516
7517 (define_split
7518 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7519 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7520 (match_operand:DI 2 "general_operand" "")))
7521 (clobber (reg:CC FLAGS_REG))]
7522 "!TARGET_64BIT && reload_completed"
7523 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7524 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7525 (parallel [(set (match_dup 3)
7526 (minus:SI (match_dup 4)
7527 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7528 (match_dup 5))))
7529 (clobber (reg:CC FLAGS_REG))])]
7530 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7531
7532 (define_insn "subdi3_carry_rex64"
7533 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7534 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7535 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7536 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7537 (clobber (reg:CC FLAGS_REG))]
7538 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7539 "sbb{q}\t{%2, %0|%0, %2}"
7540 [(set_attr "type" "alu")
7541 (set_attr "pent_pair" "pu")
7542 (set_attr "mode" "DI")])
7543
7544 (define_insn "*subdi_1_rex64"
7545 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7546 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7547 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7548 (clobber (reg:CC FLAGS_REG))]
7549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7550 "sub{q}\t{%2, %0|%0, %2}"
7551 [(set_attr "type" "alu")
7552 (set_attr "mode" "DI")])
7553
7554 (define_insn "*subdi_2_rex64"
7555 [(set (reg FLAGS_REG)
7556 (compare
7557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7558 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7559 (const_int 0)))
7560 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7561 (minus:DI (match_dup 1) (match_dup 2)))]
7562 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7563 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7564 "sub{q}\t{%2, %0|%0, %2}"
7565 [(set_attr "type" "alu")
7566 (set_attr "mode" "DI")])
7567
7568 (define_insn "*subdi_3_rex63"
7569 [(set (reg FLAGS_REG)
7570 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7571 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7572 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7573 (minus:DI (match_dup 1) (match_dup 2)))]
7574 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7575 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7576 "sub{q}\t{%2, %0|%0, %2}"
7577 [(set_attr "type" "alu")
7578 (set_attr "mode" "DI")])
7579
7580 (define_insn "subqi3_carry"
7581 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7582 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7583 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7584 (match_operand:QI 2 "general_operand" "qn,qm"))))
7585 (clobber (reg:CC FLAGS_REG))]
7586 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7587 "sbb{b}\t{%2, %0|%0, %2}"
7588 [(set_attr "type" "alu")
7589 (set_attr "pent_pair" "pu")
7590 (set_attr "mode" "QI")])
7591
7592 (define_insn "subhi3_carry"
7593 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7594 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7595 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7596 (match_operand:HI 2 "general_operand" "rn,rm"))))
7597 (clobber (reg:CC FLAGS_REG))]
7598 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7599 "sbb{w}\t{%2, %0|%0, %2}"
7600 [(set_attr "type" "alu")
7601 (set_attr "pent_pair" "pu")
7602 (set_attr "mode" "HI")])
7603
7604 (define_insn "subsi3_carry"
7605 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7606 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7607 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7608 (match_operand:SI 2 "general_operand" "ri,rm"))))
7609 (clobber (reg:CC FLAGS_REG))]
7610 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7611 "sbb{l}\t{%2, %0|%0, %2}"
7612 [(set_attr "type" "alu")
7613 (set_attr "pent_pair" "pu")
7614 (set_attr "mode" "SI")])
7615
7616 (define_insn "subsi3_carry_zext"
7617 [(set (match_operand:DI 0 "register_operand" "=r")
7618 (zero_extend:DI
7619 (minus:SI (match_operand:SI 1 "register_operand" "0")
7620 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7621 (match_operand:SI 2 "general_operand" "g")))))
7622 (clobber (reg:CC FLAGS_REG))]
7623 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7624 "sbb{l}\t{%2, %k0|%k0, %2}"
7625 [(set_attr "type" "alu")
7626 (set_attr "pent_pair" "pu")
7627 (set_attr "mode" "SI")])
7628
7629 (define_expand "subsi3"
7630 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7631 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7632 (match_operand:SI 2 "general_operand" "")))]
7633 ""
7634 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7635
7636 (define_insn "*subsi_1"
7637 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7638 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7639 (match_operand:SI 2 "general_operand" "ri,rm")))
7640 (clobber (reg:CC FLAGS_REG))]
7641 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7642 "sub{l}\t{%2, %0|%0, %2}"
7643 [(set_attr "type" "alu")
7644 (set_attr "mode" "SI")])
7645
7646 (define_insn "*subsi_1_zext"
7647 [(set (match_operand:DI 0 "register_operand" "=r")
7648 (zero_extend:DI
7649 (minus:SI (match_operand:SI 1 "register_operand" "0")
7650 (match_operand:SI 2 "general_operand" "g"))))
7651 (clobber (reg:CC FLAGS_REG))]
7652 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7653 "sub{l}\t{%2, %k0|%k0, %2}"
7654 [(set_attr "type" "alu")
7655 (set_attr "mode" "SI")])
7656
7657 (define_insn "*subsi_2"
7658 [(set (reg FLAGS_REG)
7659 (compare
7660 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7661 (match_operand:SI 2 "general_operand" "ri,rm"))
7662 (const_int 0)))
7663 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7664 (minus:SI (match_dup 1) (match_dup 2)))]
7665 "ix86_match_ccmode (insn, CCGOCmode)
7666 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7667 "sub{l}\t{%2, %0|%0, %2}"
7668 [(set_attr "type" "alu")
7669 (set_attr "mode" "SI")])
7670
7671 (define_insn "*subsi_2_zext"
7672 [(set (reg FLAGS_REG)
7673 (compare
7674 (minus:SI (match_operand:SI 1 "register_operand" "0")
7675 (match_operand:SI 2 "general_operand" "g"))
7676 (const_int 0)))
7677 (set (match_operand:DI 0 "register_operand" "=r")
7678 (zero_extend:DI
7679 (minus:SI (match_dup 1)
7680 (match_dup 2))))]
7681 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7682 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7683 "sub{l}\t{%2, %k0|%k0, %2}"
7684 [(set_attr "type" "alu")
7685 (set_attr "mode" "SI")])
7686
7687 (define_insn "*subsi_3"
7688 [(set (reg FLAGS_REG)
7689 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7690 (match_operand:SI 2 "general_operand" "ri,rm")))
7691 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7692 (minus:SI (match_dup 1) (match_dup 2)))]
7693 "ix86_match_ccmode (insn, CCmode)
7694 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7695 "sub{l}\t{%2, %0|%0, %2}"
7696 [(set_attr "type" "alu")
7697 (set_attr "mode" "SI")])
7698
7699 (define_insn "*subsi_3_zext"
7700 [(set (reg FLAGS_REG)
7701 (compare (match_operand:SI 1 "register_operand" "0")
7702 (match_operand:SI 2 "general_operand" "g")))
7703 (set (match_operand:DI 0 "register_operand" "=r")
7704 (zero_extend:DI
7705 (minus:SI (match_dup 1)
7706 (match_dup 2))))]
7707 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7708 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7709 "sub{l}\t{%2, %1|%1, %2}"
7710 [(set_attr "type" "alu")
7711 (set_attr "mode" "DI")])
7712
7713 (define_expand "subhi3"
7714 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7715 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7716 (match_operand:HI 2 "general_operand" "")))]
7717 "TARGET_HIMODE_MATH"
7718 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7719
7720 (define_insn "*subhi_1"
7721 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7722 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7723 (match_operand:HI 2 "general_operand" "rn,rm")))
7724 (clobber (reg:CC FLAGS_REG))]
7725 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7726 "sub{w}\t{%2, %0|%0, %2}"
7727 [(set_attr "type" "alu")
7728 (set_attr "mode" "HI")])
7729
7730 (define_insn "*subhi_2"
7731 [(set (reg FLAGS_REG)
7732 (compare
7733 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7734 (match_operand:HI 2 "general_operand" "rn,rm"))
7735 (const_int 0)))
7736 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7737 (minus:HI (match_dup 1) (match_dup 2)))]
7738 "ix86_match_ccmode (insn, CCGOCmode)
7739 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7740 "sub{w}\t{%2, %0|%0, %2}"
7741 [(set_attr "type" "alu")
7742 (set_attr "mode" "HI")])
7743
7744 (define_insn "*subhi_3"
7745 [(set (reg FLAGS_REG)
7746 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7747 (match_operand:HI 2 "general_operand" "rn,rm")))
7748 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7749 (minus:HI (match_dup 1) (match_dup 2)))]
7750 "ix86_match_ccmode (insn, CCmode)
7751 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7752 "sub{w}\t{%2, %0|%0, %2}"
7753 [(set_attr "type" "alu")
7754 (set_attr "mode" "HI")])
7755
7756 (define_expand "subqi3"
7757 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7758 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7759 (match_operand:QI 2 "general_operand" "")))]
7760 "TARGET_QIMODE_MATH"
7761 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7762
7763 (define_insn "*subqi_1"
7764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7765 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7766 (match_operand:QI 2 "general_operand" "qn,qm")))
7767 (clobber (reg:CC FLAGS_REG))]
7768 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7769 "sub{b}\t{%2, %0|%0, %2}"
7770 [(set_attr "type" "alu")
7771 (set_attr "mode" "QI")])
7772
7773 (define_insn "*subqi_1_slp"
7774 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7775 (minus:QI (match_dup 0)
7776 (match_operand:QI 1 "general_operand" "qn,qm")))
7777 (clobber (reg:CC FLAGS_REG))]
7778 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7780 "sub{b}\t{%1, %0|%0, %1}"
7781 [(set_attr "type" "alu1")
7782 (set_attr "mode" "QI")])
7783
7784 (define_insn "*subqi_2"
7785 [(set (reg FLAGS_REG)
7786 (compare
7787 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7788 (match_operand:QI 2 "general_operand" "qn,qm"))
7789 (const_int 0)))
7790 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7791 (minus:QI (match_dup 1) (match_dup 2)))]
7792 "ix86_match_ccmode (insn, CCGOCmode)
7793 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7794 "sub{b}\t{%2, %0|%0, %2}"
7795 [(set_attr "type" "alu")
7796 (set_attr "mode" "QI")])
7797
7798 (define_insn "*subqi_3"
7799 [(set (reg FLAGS_REG)
7800 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7801 (match_operand:QI 2 "general_operand" "qn,qm")))
7802 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7803 (minus:QI (match_dup 1) (match_dup 2)))]
7804 "ix86_match_ccmode (insn, CCmode)
7805 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7806 "sub{b}\t{%2, %0|%0, %2}"
7807 [(set_attr "type" "alu")
7808 (set_attr "mode" "QI")])
7809
7810 ;; The patterns that match these are at the end of this file.
7811
7812 (define_expand "subxf3"
7813 [(set (match_operand:XF 0 "register_operand" "")
7814 (minus:XF (match_operand:XF 1 "register_operand" "")
7815 (match_operand:XF 2 "register_operand" "")))]
7816 "TARGET_80387"
7817 "")
7818
7819 (define_expand "sub<mode>3"
7820 [(set (match_operand:MODEF 0 "register_operand" "")
7821 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7822 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7823 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7824 "")
7825 \f
7826 ;; Multiply instructions
7827
7828 (define_expand "muldi3"
7829 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7830 (mult:DI (match_operand:DI 1 "register_operand" "")
7831 (match_operand:DI 2 "x86_64_general_operand" "")))
7832 (clobber (reg:CC FLAGS_REG))])]
7833 "TARGET_64BIT"
7834 "")
7835
7836 ;; On AMDFAM10
7837 ;; IMUL reg64, reg64, imm8 Direct
7838 ;; IMUL reg64, mem64, imm8 VectorPath
7839 ;; IMUL reg64, reg64, imm32 Direct
7840 ;; IMUL reg64, mem64, imm32 VectorPath
7841 ;; IMUL reg64, reg64 Direct
7842 ;; IMUL reg64, mem64 Direct
7843
7844 (define_insn "*muldi3_1_rex64"
7845 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7846 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7847 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "TARGET_64BIT
7850 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7851 "@
7852 imul{q}\t{%2, %1, %0|%0, %1, %2}
7853 imul{q}\t{%2, %1, %0|%0, %1, %2}
7854 imul{q}\t{%2, %0|%0, %2}"
7855 [(set_attr "type" "imul")
7856 (set_attr "prefix_0f" "0,0,1")
7857 (set (attr "athlon_decode")
7858 (cond [(eq_attr "cpu" "athlon")
7859 (const_string "vector")
7860 (eq_attr "alternative" "1")
7861 (const_string "vector")
7862 (and (eq_attr "alternative" "2")
7863 (match_operand 1 "memory_operand" ""))
7864 (const_string "vector")]
7865 (const_string "direct")))
7866 (set (attr "amdfam10_decode")
7867 (cond [(and (eq_attr "alternative" "0,1")
7868 (match_operand 1 "memory_operand" ""))
7869 (const_string "vector")]
7870 (const_string "direct")))
7871 (set_attr "mode" "DI")])
7872
7873 (define_expand "mulsi3"
7874 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7875 (mult:SI (match_operand:SI 1 "register_operand" "")
7876 (match_operand:SI 2 "general_operand" "")))
7877 (clobber (reg:CC FLAGS_REG))])]
7878 ""
7879 "")
7880
7881 ;; On AMDFAM10
7882 ;; IMUL reg32, reg32, imm8 Direct
7883 ;; IMUL reg32, mem32, imm8 VectorPath
7884 ;; IMUL reg32, reg32, imm32 Direct
7885 ;; IMUL reg32, mem32, imm32 VectorPath
7886 ;; IMUL reg32, reg32 Direct
7887 ;; IMUL reg32, mem32 Direct
7888
7889 (define_insn "*mulsi3_1"
7890 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7891 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7892 (match_operand:SI 2 "general_operand" "K,i,mr")))
7893 (clobber (reg:CC FLAGS_REG))]
7894 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7895 "@
7896 imul{l}\t{%2, %1, %0|%0, %1, %2}
7897 imul{l}\t{%2, %1, %0|%0, %1, %2}
7898 imul{l}\t{%2, %0|%0, %2}"
7899 [(set_attr "type" "imul")
7900 (set_attr "prefix_0f" "0,0,1")
7901 (set (attr "athlon_decode")
7902 (cond [(eq_attr "cpu" "athlon")
7903 (const_string "vector")
7904 (eq_attr "alternative" "1")
7905 (const_string "vector")
7906 (and (eq_attr "alternative" "2")
7907 (match_operand 1 "memory_operand" ""))
7908 (const_string "vector")]
7909 (const_string "direct")))
7910 (set (attr "amdfam10_decode")
7911 (cond [(and (eq_attr "alternative" "0,1")
7912 (match_operand 1 "memory_operand" ""))
7913 (const_string "vector")]
7914 (const_string "direct")))
7915 (set_attr "mode" "SI")])
7916
7917 (define_insn "*mulsi3_1_zext"
7918 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7919 (zero_extend:DI
7920 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7921 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7922 (clobber (reg:CC FLAGS_REG))]
7923 "TARGET_64BIT
7924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925 "@
7926 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7927 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7928 imul{l}\t{%2, %k0|%k0, %2}"
7929 [(set_attr "type" "imul")
7930 (set_attr "prefix_0f" "0,0,1")
7931 (set (attr "athlon_decode")
7932 (cond [(eq_attr "cpu" "athlon")
7933 (const_string "vector")
7934 (eq_attr "alternative" "1")
7935 (const_string "vector")
7936 (and (eq_attr "alternative" "2")
7937 (match_operand 1 "memory_operand" ""))
7938 (const_string "vector")]
7939 (const_string "direct")))
7940 (set (attr "amdfam10_decode")
7941 (cond [(and (eq_attr "alternative" "0,1")
7942 (match_operand 1 "memory_operand" ""))
7943 (const_string "vector")]
7944 (const_string "direct")))
7945 (set_attr "mode" "SI")])
7946
7947 (define_expand "mulhi3"
7948 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7949 (mult:HI (match_operand:HI 1 "register_operand" "")
7950 (match_operand:HI 2 "general_operand" "")))
7951 (clobber (reg:CC FLAGS_REG))])]
7952 "TARGET_HIMODE_MATH"
7953 "")
7954
7955 ;; On AMDFAM10
7956 ;; IMUL reg16, reg16, imm8 VectorPath
7957 ;; IMUL reg16, mem16, imm8 VectorPath
7958 ;; IMUL reg16, reg16, imm16 VectorPath
7959 ;; IMUL reg16, mem16, imm16 VectorPath
7960 ;; IMUL reg16, reg16 Direct
7961 ;; IMUL reg16, mem16 Direct
7962 (define_insn "*mulhi3_1"
7963 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7964 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7965 (match_operand:HI 2 "general_operand" "K,n,mr")))
7966 (clobber (reg:CC FLAGS_REG))]
7967 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7968 "@
7969 imul{w}\t{%2, %1, %0|%0, %1, %2}
7970 imul{w}\t{%2, %1, %0|%0, %1, %2}
7971 imul{w}\t{%2, %0|%0, %2}"
7972 [(set_attr "type" "imul")
7973 (set_attr "prefix_0f" "0,0,1")
7974 (set (attr "athlon_decode")
7975 (cond [(eq_attr "cpu" "athlon")
7976 (const_string "vector")
7977 (eq_attr "alternative" "1,2")
7978 (const_string "vector")]
7979 (const_string "direct")))
7980 (set (attr "amdfam10_decode")
7981 (cond [(eq_attr "alternative" "0,1")
7982 (const_string "vector")]
7983 (const_string "direct")))
7984 (set_attr "mode" "HI")])
7985
7986 (define_expand "mulqi3"
7987 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7988 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7989 (match_operand:QI 2 "register_operand" "")))
7990 (clobber (reg:CC FLAGS_REG))])]
7991 "TARGET_QIMODE_MATH"
7992 "")
7993
7994 ;;On AMDFAM10
7995 ;; MUL reg8 Direct
7996 ;; MUL mem8 Direct
7997
7998 (define_insn "*mulqi3_1"
7999 [(set (match_operand:QI 0 "register_operand" "=a")
8000 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8001 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8002 (clobber (reg:CC FLAGS_REG))]
8003 "TARGET_QIMODE_MATH
8004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005 "mul{b}\t%2"
8006 [(set_attr "type" "imul")
8007 (set_attr "length_immediate" "0")
8008 (set (attr "athlon_decode")
8009 (if_then_else (eq_attr "cpu" "athlon")
8010 (const_string "vector")
8011 (const_string "direct")))
8012 (set_attr "amdfam10_decode" "direct")
8013 (set_attr "mode" "QI")])
8014
8015 (define_expand "umulqihi3"
8016 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8017 (mult:HI (zero_extend:HI
8018 (match_operand:QI 1 "nonimmediate_operand" ""))
8019 (zero_extend:HI
8020 (match_operand:QI 2 "register_operand" ""))))
8021 (clobber (reg:CC FLAGS_REG))])]
8022 "TARGET_QIMODE_MATH"
8023 "")
8024
8025 (define_insn "*umulqihi3_1"
8026 [(set (match_operand:HI 0 "register_operand" "=a")
8027 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8028 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8029 (clobber (reg:CC FLAGS_REG))]
8030 "TARGET_QIMODE_MATH
8031 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8032 "mul{b}\t%2"
8033 [(set_attr "type" "imul")
8034 (set_attr "length_immediate" "0")
8035 (set (attr "athlon_decode")
8036 (if_then_else (eq_attr "cpu" "athlon")
8037 (const_string "vector")
8038 (const_string "direct")))
8039 (set_attr "amdfam10_decode" "direct")
8040 (set_attr "mode" "QI")])
8041
8042 (define_expand "mulqihi3"
8043 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8044 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8045 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8046 (clobber (reg:CC FLAGS_REG))])]
8047 "TARGET_QIMODE_MATH"
8048 "")
8049
8050 (define_insn "*mulqihi3_insn"
8051 [(set (match_operand:HI 0 "register_operand" "=a")
8052 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8053 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8054 (clobber (reg:CC FLAGS_REG))]
8055 "TARGET_QIMODE_MATH
8056 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8057 "imul{b}\t%2"
8058 [(set_attr "type" "imul")
8059 (set_attr "length_immediate" "0")
8060 (set (attr "athlon_decode")
8061 (if_then_else (eq_attr "cpu" "athlon")
8062 (const_string "vector")
8063 (const_string "direct")))
8064 (set_attr "amdfam10_decode" "direct")
8065 (set_attr "mode" "QI")])
8066
8067 (define_expand "umulditi3"
8068 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8069 (mult:TI (zero_extend:TI
8070 (match_operand:DI 1 "nonimmediate_operand" ""))
8071 (zero_extend:TI
8072 (match_operand:DI 2 "register_operand" ""))))
8073 (clobber (reg:CC FLAGS_REG))])]
8074 "TARGET_64BIT"
8075 "")
8076
8077 (define_insn "*umulditi3_insn"
8078 [(set (match_operand:TI 0 "register_operand" "=A")
8079 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8080 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8081 (clobber (reg:CC FLAGS_REG))]
8082 "TARGET_64BIT
8083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8084 "mul{q}\t%2"
8085 [(set_attr "type" "imul")
8086 (set_attr "length_immediate" "0")
8087 (set (attr "athlon_decode")
8088 (if_then_else (eq_attr "cpu" "athlon")
8089 (const_string "vector")
8090 (const_string "double")))
8091 (set_attr "amdfam10_decode" "double")
8092 (set_attr "mode" "DI")])
8093
8094 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8095 (define_expand "umulsidi3"
8096 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8097 (mult:DI (zero_extend:DI
8098 (match_operand:SI 1 "nonimmediate_operand" ""))
8099 (zero_extend:DI
8100 (match_operand:SI 2 "register_operand" ""))))
8101 (clobber (reg:CC FLAGS_REG))])]
8102 "!TARGET_64BIT"
8103 "")
8104
8105 (define_insn "*umulsidi3_insn"
8106 [(set (match_operand:DI 0 "register_operand" "=A")
8107 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8108 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8109 (clobber (reg:CC FLAGS_REG))]
8110 "!TARGET_64BIT
8111 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8112 "mul{l}\t%2"
8113 [(set_attr "type" "imul")
8114 (set_attr "length_immediate" "0")
8115 (set (attr "athlon_decode")
8116 (if_then_else (eq_attr "cpu" "athlon")
8117 (const_string "vector")
8118 (const_string "double")))
8119 (set_attr "amdfam10_decode" "double")
8120 (set_attr "mode" "SI")])
8121
8122 (define_expand "mulditi3"
8123 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8124 (mult:TI (sign_extend:TI
8125 (match_operand:DI 1 "nonimmediate_operand" ""))
8126 (sign_extend:TI
8127 (match_operand:DI 2 "register_operand" ""))))
8128 (clobber (reg:CC FLAGS_REG))])]
8129 "TARGET_64BIT"
8130 "")
8131
8132 (define_insn "*mulditi3_insn"
8133 [(set (match_operand:TI 0 "register_operand" "=A")
8134 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8135 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8136 (clobber (reg:CC FLAGS_REG))]
8137 "TARGET_64BIT
8138 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8139 "imul{q}\t%2"
8140 [(set_attr "type" "imul")
8141 (set_attr "length_immediate" "0")
8142 (set (attr "athlon_decode")
8143 (if_then_else (eq_attr "cpu" "athlon")
8144 (const_string "vector")
8145 (const_string "double")))
8146 (set_attr "amdfam10_decode" "double")
8147 (set_attr "mode" "DI")])
8148
8149 (define_expand "mulsidi3"
8150 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8151 (mult:DI (sign_extend:DI
8152 (match_operand:SI 1 "nonimmediate_operand" ""))
8153 (sign_extend:DI
8154 (match_operand:SI 2 "register_operand" ""))))
8155 (clobber (reg:CC FLAGS_REG))])]
8156 "!TARGET_64BIT"
8157 "")
8158
8159 (define_insn "*mulsidi3_insn"
8160 [(set (match_operand:DI 0 "register_operand" "=A")
8161 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8162 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8163 (clobber (reg:CC FLAGS_REG))]
8164 "!TARGET_64BIT
8165 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8166 "imul{l}\t%2"
8167 [(set_attr "type" "imul")
8168 (set_attr "length_immediate" "0")
8169 (set (attr "athlon_decode")
8170 (if_then_else (eq_attr "cpu" "athlon")
8171 (const_string "vector")
8172 (const_string "double")))
8173 (set_attr "amdfam10_decode" "double")
8174 (set_attr "mode" "SI")])
8175
8176 (define_expand "umuldi3_highpart"
8177 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8178 (truncate:DI
8179 (lshiftrt:TI
8180 (mult:TI (zero_extend:TI
8181 (match_operand:DI 1 "nonimmediate_operand" ""))
8182 (zero_extend:TI
8183 (match_operand:DI 2 "register_operand" "")))
8184 (const_int 64))))
8185 (clobber (match_scratch:DI 3 ""))
8186 (clobber (reg:CC FLAGS_REG))])]
8187 "TARGET_64BIT"
8188 "")
8189
8190 (define_insn "*umuldi3_highpart_rex64"
8191 [(set (match_operand:DI 0 "register_operand" "=d")
8192 (truncate:DI
8193 (lshiftrt:TI
8194 (mult:TI (zero_extend:TI
8195 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8196 (zero_extend:TI
8197 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8198 (const_int 64))))
8199 (clobber (match_scratch:DI 3 "=1"))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "TARGET_64BIT
8202 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8203 "mul{q}\t%2"
8204 [(set_attr "type" "imul")
8205 (set_attr "length_immediate" "0")
8206 (set (attr "athlon_decode")
8207 (if_then_else (eq_attr "cpu" "athlon")
8208 (const_string "vector")
8209 (const_string "double")))
8210 (set_attr "amdfam10_decode" "double")
8211 (set_attr "mode" "DI")])
8212
8213 (define_expand "umulsi3_highpart"
8214 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8215 (truncate:SI
8216 (lshiftrt:DI
8217 (mult:DI (zero_extend:DI
8218 (match_operand:SI 1 "nonimmediate_operand" ""))
8219 (zero_extend:DI
8220 (match_operand:SI 2 "register_operand" "")))
8221 (const_int 32))))
8222 (clobber (match_scratch:SI 3 ""))
8223 (clobber (reg:CC FLAGS_REG))])]
8224 ""
8225 "")
8226
8227 (define_insn "*umulsi3_highpart_insn"
8228 [(set (match_operand:SI 0 "register_operand" "=d")
8229 (truncate:SI
8230 (lshiftrt:DI
8231 (mult:DI (zero_extend:DI
8232 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8233 (zero_extend:DI
8234 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8235 (const_int 32))))
8236 (clobber (match_scratch:SI 3 "=1"))
8237 (clobber (reg:CC FLAGS_REG))]
8238 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8239 "mul{l}\t%2"
8240 [(set_attr "type" "imul")
8241 (set_attr "length_immediate" "0")
8242 (set (attr "athlon_decode")
8243 (if_then_else (eq_attr "cpu" "athlon")
8244 (const_string "vector")
8245 (const_string "double")))
8246 (set_attr "amdfam10_decode" "double")
8247 (set_attr "mode" "SI")])
8248
8249 (define_insn "*umulsi3_highpart_zext"
8250 [(set (match_operand:DI 0 "register_operand" "=d")
8251 (zero_extend:DI (truncate:SI
8252 (lshiftrt:DI
8253 (mult:DI (zero_extend:DI
8254 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8255 (zero_extend:DI
8256 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8257 (const_int 32)))))
8258 (clobber (match_scratch:SI 3 "=1"))
8259 (clobber (reg:CC FLAGS_REG))]
8260 "TARGET_64BIT
8261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8262 "mul{l}\t%2"
8263 [(set_attr "type" "imul")
8264 (set_attr "length_immediate" "0")
8265 (set (attr "athlon_decode")
8266 (if_then_else (eq_attr "cpu" "athlon")
8267 (const_string "vector")
8268 (const_string "double")))
8269 (set_attr "amdfam10_decode" "double")
8270 (set_attr "mode" "SI")])
8271
8272 (define_expand "smuldi3_highpart"
8273 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8274 (truncate:DI
8275 (lshiftrt:TI
8276 (mult:TI (sign_extend:TI
8277 (match_operand:DI 1 "nonimmediate_operand" ""))
8278 (sign_extend:TI
8279 (match_operand:DI 2 "register_operand" "")))
8280 (const_int 64))))
8281 (clobber (match_scratch:DI 3 ""))
8282 (clobber (reg:CC FLAGS_REG))])]
8283 "TARGET_64BIT"
8284 "")
8285
8286 (define_insn "*smuldi3_highpart_rex64"
8287 [(set (match_operand:DI 0 "register_operand" "=d")
8288 (truncate:DI
8289 (lshiftrt:TI
8290 (mult:TI (sign_extend:TI
8291 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8292 (sign_extend:TI
8293 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8294 (const_int 64))))
8295 (clobber (match_scratch:DI 3 "=1"))
8296 (clobber (reg:CC FLAGS_REG))]
8297 "TARGET_64BIT
8298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8299 "imul{q}\t%2"
8300 [(set_attr "type" "imul")
8301 (set (attr "athlon_decode")
8302 (if_then_else (eq_attr "cpu" "athlon")
8303 (const_string "vector")
8304 (const_string "double")))
8305 (set_attr "amdfam10_decode" "double")
8306 (set_attr "mode" "DI")])
8307
8308 (define_expand "smulsi3_highpart"
8309 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8310 (truncate:SI
8311 (lshiftrt:DI
8312 (mult:DI (sign_extend:DI
8313 (match_operand:SI 1 "nonimmediate_operand" ""))
8314 (sign_extend:DI
8315 (match_operand:SI 2 "register_operand" "")))
8316 (const_int 32))))
8317 (clobber (match_scratch:SI 3 ""))
8318 (clobber (reg:CC FLAGS_REG))])]
8319 ""
8320 "")
8321
8322 (define_insn "*smulsi3_highpart_insn"
8323 [(set (match_operand:SI 0 "register_operand" "=d")
8324 (truncate:SI
8325 (lshiftrt:DI
8326 (mult:DI (sign_extend:DI
8327 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8328 (sign_extend:DI
8329 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8330 (const_int 32))))
8331 (clobber (match_scratch:SI 3 "=1"))
8332 (clobber (reg:CC FLAGS_REG))]
8333 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8334 "imul{l}\t%2"
8335 [(set_attr "type" "imul")
8336 (set (attr "athlon_decode")
8337 (if_then_else (eq_attr "cpu" "athlon")
8338 (const_string "vector")
8339 (const_string "double")))
8340 (set_attr "amdfam10_decode" "double")
8341 (set_attr "mode" "SI")])
8342
8343 (define_insn "*smulsi3_highpart_zext"
8344 [(set (match_operand:DI 0 "register_operand" "=d")
8345 (zero_extend:DI (truncate:SI
8346 (lshiftrt:DI
8347 (mult:DI (sign_extend:DI
8348 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8349 (sign_extend:DI
8350 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8351 (const_int 32)))))
8352 (clobber (match_scratch:SI 3 "=1"))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "TARGET_64BIT
8355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8356 "imul{l}\t%2"
8357 [(set_attr "type" "imul")
8358 (set (attr "athlon_decode")
8359 (if_then_else (eq_attr "cpu" "athlon")
8360 (const_string "vector")
8361 (const_string "double")))
8362 (set_attr "amdfam10_decode" "double")
8363 (set_attr "mode" "SI")])
8364
8365 ;; The patterns that match these are at the end of this file.
8366
8367 (define_expand "mulxf3"
8368 [(set (match_operand:XF 0 "register_operand" "")
8369 (mult:XF (match_operand:XF 1 "register_operand" "")
8370 (match_operand:XF 2 "register_operand" "")))]
8371 "TARGET_80387"
8372 "")
8373
8374 (define_expand "mul<mode>3"
8375 [(set (match_operand:MODEF 0 "register_operand" "")
8376 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8377 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8378 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8379 "")
8380
8381 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8382
8383 \f
8384 ;; Divide instructions
8385
8386 (define_insn "divqi3"
8387 [(set (match_operand:QI 0 "register_operand" "=a")
8388 (div:QI (match_operand:HI 1 "register_operand" "0")
8389 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "TARGET_QIMODE_MATH"
8392 "idiv{b}\t%2"
8393 [(set_attr "type" "idiv")
8394 (set_attr "mode" "QI")])
8395
8396 (define_insn "udivqi3"
8397 [(set (match_operand:QI 0 "register_operand" "=a")
8398 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8399 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8400 (clobber (reg:CC FLAGS_REG))]
8401 "TARGET_QIMODE_MATH"
8402 "div{b}\t%2"
8403 [(set_attr "type" "idiv")
8404 (set_attr "mode" "QI")])
8405
8406 ;; The patterns that match these are at the end of this file.
8407
8408 (define_expand "divxf3"
8409 [(set (match_operand:XF 0 "register_operand" "")
8410 (div:XF (match_operand:XF 1 "register_operand" "")
8411 (match_operand:XF 2 "register_operand" "")))]
8412 "TARGET_80387"
8413 "")
8414
8415 (define_expand "divdf3"
8416 [(set (match_operand:DF 0 "register_operand" "")
8417 (div:DF (match_operand:DF 1 "register_operand" "")
8418 (match_operand:DF 2 "nonimmediate_operand" "")))]
8419 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8420 "")
8421
8422 (define_expand "divsf3"
8423 [(set (match_operand:SF 0 "register_operand" "")
8424 (div:SF (match_operand:SF 1 "register_operand" "")
8425 (match_operand:SF 2 "nonimmediate_operand" "")))]
8426 "TARGET_80387 || TARGET_SSE_MATH"
8427 {
8428 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8429 && flag_finite_math_only && !flag_trapping_math
8430 && flag_unsafe_math_optimizations)
8431 {
8432 ix86_emit_swdivsf (operands[0], operands[1],
8433 operands[2], SFmode);
8434 DONE;
8435 }
8436 })
8437 \f
8438 ;; Remainder instructions.
8439
8440 (define_expand "divmoddi4"
8441 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8442 (div:DI (match_operand:DI 1 "register_operand" "")
8443 (match_operand:DI 2 "nonimmediate_operand" "")))
8444 (set (match_operand:DI 3 "register_operand" "")
8445 (mod:DI (match_dup 1) (match_dup 2)))
8446 (clobber (reg:CC FLAGS_REG))])]
8447 "TARGET_64BIT"
8448 "")
8449
8450 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8451 ;; Penalize eax case slightly because it results in worse scheduling
8452 ;; of code.
8453 (define_insn "*divmoddi4_nocltd_rex64"
8454 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8455 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8456 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8457 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8458 (mod:DI (match_dup 2) (match_dup 3)))
8459 (clobber (reg:CC FLAGS_REG))]
8460 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8461 "#"
8462 [(set_attr "type" "multi")])
8463
8464 (define_insn "*divmoddi4_cltd_rex64"
8465 [(set (match_operand:DI 0 "register_operand" "=a")
8466 (div:DI (match_operand:DI 2 "register_operand" "a")
8467 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8468 (set (match_operand:DI 1 "register_operand" "=&d")
8469 (mod:DI (match_dup 2) (match_dup 3)))
8470 (clobber (reg:CC FLAGS_REG))]
8471 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8472 "#"
8473 [(set_attr "type" "multi")])
8474
8475 (define_insn "*divmoddi_noext_rex64"
8476 [(set (match_operand:DI 0 "register_operand" "=a")
8477 (div:DI (match_operand:DI 1 "register_operand" "0")
8478 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8479 (set (match_operand:DI 3 "register_operand" "=d")
8480 (mod:DI (match_dup 1) (match_dup 2)))
8481 (use (match_operand:DI 4 "register_operand" "3"))
8482 (clobber (reg:CC FLAGS_REG))]
8483 "TARGET_64BIT"
8484 "idiv{q}\t%2"
8485 [(set_attr "type" "idiv")
8486 (set_attr "mode" "DI")])
8487
8488 (define_split
8489 [(set (match_operand:DI 0 "register_operand" "")
8490 (div:DI (match_operand:DI 1 "register_operand" "")
8491 (match_operand:DI 2 "nonimmediate_operand" "")))
8492 (set (match_operand:DI 3 "register_operand" "")
8493 (mod:DI (match_dup 1) (match_dup 2)))
8494 (clobber (reg:CC FLAGS_REG))]
8495 "TARGET_64BIT && reload_completed"
8496 [(parallel [(set (match_dup 3)
8497 (ashiftrt:DI (match_dup 4) (const_int 63)))
8498 (clobber (reg:CC FLAGS_REG))])
8499 (parallel [(set (match_dup 0)
8500 (div:DI (reg:DI 0) (match_dup 2)))
8501 (set (match_dup 3)
8502 (mod:DI (reg:DI 0) (match_dup 2)))
8503 (use (match_dup 3))
8504 (clobber (reg:CC FLAGS_REG))])]
8505 {
8506 /* Avoid use of cltd in favor of a mov+shift. */
8507 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8508 {
8509 if (true_regnum (operands[1]))
8510 emit_move_insn (operands[0], operands[1]);
8511 else
8512 emit_move_insn (operands[3], operands[1]);
8513 operands[4] = operands[3];
8514 }
8515 else
8516 {
8517 gcc_assert (!true_regnum (operands[1]));
8518 operands[4] = operands[1];
8519 }
8520 })
8521
8522
8523 (define_expand "divmodsi4"
8524 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8525 (div:SI (match_operand:SI 1 "register_operand" "")
8526 (match_operand:SI 2 "nonimmediate_operand" "")))
8527 (set (match_operand:SI 3 "register_operand" "")
8528 (mod:SI (match_dup 1) (match_dup 2)))
8529 (clobber (reg:CC FLAGS_REG))])]
8530 ""
8531 "")
8532
8533 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8534 ;; Penalize eax case slightly because it results in worse scheduling
8535 ;; of code.
8536 (define_insn "*divmodsi4_nocltd"
8537 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8538 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8539 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8540 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8541 (mod:SI (match_dup 2) (match_dup 3)))
8542 (clobber (reg:CC FLAGS_REG))]
8543 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8544 "#"
8545 [(set_attr "type" "multi")])
8546
8547 (define_insn "*divmodsi4_cltd"
8548 [(set (match_operand:SI 0 "register_operand" "=a")
8549 (div:SI (match_operand:SI 2 "register_operand" "a")
8550 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8551 (set (match_operand:SI 1 "register_operand" "=&d")
8552 (mod:SI (match_dup 2) (match_dup 3)))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8555 "#"
8556 [(set_attr "type" "multi")])
8557
8558 (define_insn "*divmodsi_noext"
8559 [(set (match_operand:SI 0 "register_operand" "=a")
8560 (div:SI (match_operand:SI 1 "register_operand" "0")
8561 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8562 (set (match_operand:SI 3 "register_operand" "=d")
8563 (mod:SI (match_dup 1) (match_dup 2)))
8564 (use (match_operand:SI 4 "register_operand" "3"))
8565 (clobber (reg:CC FLAGS_REG))]
8566 ""
8567 "idiv{l}\t%2"
8568 [(set_attr "type" "idiv")
8569 (set_attr "mode" "SI")])
8570
8571 (define_split
8572 [(set (match_operand:SI 0 "register_operand" "")
8573 (div:SI (match_operand:SI 1 "register_operand" "")
8574 (match_operand:SI 2 "nonimmediate_operand" "")))
8575 (set (match_operand:SI 3 "register_operand" "")
8576 (mod:SI (match_dup 1) (match_dup 2)))
8577 (clobber (reg:CC FLAGS_REG))]
8578 "reload_completed"
8579 [(parallel [(set (match_dup 3)
8580 (ashiftrt:SI (match_dup 4) (const_int 31)))
8581 (clobber (reg:CC FLAGS_REG))])
8582 (parallel [(set (match_dup 0)
8583 (div:SI (reg:SI 0) (match_dup 2)))
8584 (set (match_dup 3)
8585 (mod:SI (reg:SI 0) (match_dup 2)))
8586 (use (match_dup 3))
8587 (clobber (reg:CC FLAGS_REG))])]
8588 {
8589 /* Avoid use of cltd in favor of a mov+shift. */
8590 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8591 {
8592 if (true_regnum (operands[1]))
8593 emit_move_insn (operands[0], operands[1]);
8594 else
8595 emit_move_insn (operands[3], operands[1]);
8596 operands[4] = operands[3];
8597 }
8598 else
8599 {
8600 gcc_assert (!true_regnum (operands[1]));
8601 operands[4] = operands[1];
8602 }
8603 })
8604 ;; %%% Split me.
8605 (define_insn "divmodhi4"
8606 [(set (match_operand:HI 0 "register_operand" "=a")
8607 (div:HI (match_operand:HI 1 "register_operand" "0")
8608 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8609 (set (match_operand:HI 3 "register_operand" "=&d")
8610 (mod:HI (match_dup 1) (match_dup 2)))
8611 (clobber (reg:CC FLAGS_REG))]
8612 "TARGET_HIMODE_MATH"
8613 "cwtd\;idiv{w}\t%2"
8614 [(set_attr "type" "multi")
8615 (set_attr "length_immediate" "0")
8616 (set_attr "mode" "SI")])
8617
8618 (define_insn "udivmoddi4"
8619 [(set (match_operand:DI 0 "register_operand" "=a")
8620 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8621 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8622 (set (match_operand:DI 3 "register_operand" "=&d")
8623 (umod:DI (match_dup 1) (match_dup 2)))
8624 (clobber (reg:CC FLAGS_REG))]
8625 "TARGET_64BIT"
8626 "xor{q}\t%3, %3\;div{q}\t%2"
8627 [(set_attr "type" "multi")
8628 (set_attr "length_immediate" "0")
8629 (set_attr "mode" "DI")])
8630
8631 (define_insn "*udivmoddi4_noext"
8632 [(set (match_operand:DI 0 "register_operand" "=a")
8633 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8634 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8635 (set (match_operand:DI 3 "register_operand" "=d")
8636 (umod:DI (match_dup 1) (match_dup 2)))
8637 (use (match_dup 3))
8638 (clobber (reg:CC FLAGS_REG))]
8639 "TARGET_64BIT"
8640 "div{q}\t%2"
8641 [(set_attr "type" "idiv")
8642 (set_attr "mode" "DI")])
8643
8644 (define_split
8645 [(set (match_operand:DI 0 "register_operand" "")
8646 (udiv:DI (match_operand:DI 1 "register_operand" "")
8647 (match_operand:DI 2 "nonimmediate_operand" "")))
8648 (set (match_operand:DI 3 "register_operand" "")
8649 (umod:DI (match_dup 1) (match_dup 2)))
8650 (clobber (reg:CC FLAGS_REG))]
8651 "TARGET_64BIT && reload_completed"
8652 [(set (match_dup 3) (const_int 0))
8653 (parallel [(set (match_dup 0)
8654 (udiv:DI (match_dup 1) (match_dup 2)))
8655 (set (match_dup 3)
8656 (umod:DI (match_dup 1) (match_dup 2)))
8657 (use (match_dup 3))
8658 (clobber (reg:CC FLAGS_REG))])]
8659 "")
8660
8661 (define_insn "udivmodsi4"
8662 [(set (match_operand:SI 0 "register_operand" "=a")
8663 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8664 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8665 (set (match_operand:SI 3 "register_operand" "=&d")
8666 (umod:SI (match_dup 1) (match_dup 2)))
8667 (clobber (reg:CC FLAGS_REG))]
8668 ""
8669 "xor{l}\t%3, %3\;div{l}\t%2"
8670 [(set_attr "type" "multi")
8671 (set_attr "length_immediate" "0")
8672 (set_attr "mode" "SI")])
8673
8674 (define_insn "*udivmodsi4_noext"
8675 [(set (match_operand:SI 0 "register_operand" "=a")
8676 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8677 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8678 (set (match_operand:SI 3 "register_operand" "=d")
8679 (umod:SI (match_dup 1) (match_dup 2)))
8680 (use (match_dup 3))
8681 (clobber (reg:CC FLAGS_REG))]
8682 ""
8683 "div{l}\t%2"
8684 [(set_attr "type" "idiv")
8685 (set_attr "mode" "SI")])
8686
8687 (define_split
8688 [(set (match_operand:SI 0 "register_operand" "")
8689 (udiv:SI (match_operand:SI 1 "register_operand" "")
8690 (match_operand:SI 2 "nonimmediate_operand" "")))
8691 (set (match_operand:SI 3 "register_operand" "")
8692 (umod:SI (match_dup 1) (match_dup 2)))
8693 (clobber (reg:CC FLAGS_REG))]
8694 "reload_completed"
8695 [(set (match_dup 3) (const_int 0))
8696 (parallel [(set (match_dup 0)
8697 (udiv:SI (match_dup 1) (match_dup 2)))
8698 (set (match_dup 3)
8699 (umod:SI (match_dup 1) (match_dup 2)))
8700 (use (match_dup 3))
8701 (clobber (reg:CC FLAGS_REG))])]
8702 "")
8703
8704 (define_expand "udivmodhi4"
8705 [(set (match_dup 4) (const_int 0))
8706 (parallel [(set (match_operand:HI 0 "register_operand" "")
8707 (udiv:HI (match_operand:HI 1 "register_operand" "")
8708 (match_operand:HI 2 "nonimmediate_operand" "")))
8709 (set (match_operand:HI 3 "register_operand" "")
8710 (umod:HI (match_dup 1) (match_dup 2)))
8711 (use (match_dup 4))
8712 (clobber (reg:CC FLAGS_REG))])]
8713 "TARGET_HIMODE_MATH"
8714 "operands[4] = gen_reg_rtx (HImode);")
8715
8716 (define_insn "*udivmodhi_noext"
8717 [(set (match_operand:HI 0 "register_operand" "=a")
8718 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8719 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8720 (set (match_operand:HI 3 "register_operand" "=d")
8721 (umod:HI (match_dup 1) (match_dup 2)))
8722 (use (match_operand:HI 4 "register_operand" "3"))
8723 (clobber (reg:CC FLAGS_REG))]
8724 ""
8725 "div{w}\t%2"
8726 [(set_attr "type" "idiv")
8727 (set_attr "mode" "HI")])
8728
8729 ;; We cannot use div/idiv for double division, because it causes
8730 ;; "division by zero" on the overflow and that's not what we expect
8731 ;; from truncate. Because true (non truncating) double division is
8732 ;; never generated, we can't create this insn anyway.
8733 ;
8734 ;(define_insn ""
8735 ; [(set (match_operand:SI 0 "register_operand" "=a")
8736 ; (truncate:SI
8737 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8738 ; (zero_extend:DI
8739 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8740 ; (set (match_operand:SI 3 "register_operand" "=d")
8741 ; (truncate:SI
8742 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8743 ; (clobber (reg:CC FLAGS_REG))]
8744 ; ""
8745 ; "div{l}\t{%2, %0|%0, %2}"
8746 ; [(set_attr "type" "idiv")])
8747 \f
8748 ;;- Logical AND instructions
8749
8750 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8751 ;; Note that this excludes ah.
8752
8753 (define_insn "*testdi_1_rex64"
8754 [(set (reg FLAGS_REG)
8755 (compare
8756 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8757 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8758 (const_int 0)))]
8759 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8761 "@
8762 test{l}\t{%k1, %k0|%k0, %k1}
8763 test{l}\t{%k1, %k0|%k0, %k1}
8764 test{q}\t{%1, %0|%0, %1}
8765 test{q}\t{%1, %0|%0, %1}
8766 test{q}\t{%1, %0|%0, %1}"
8767 [(set_attr "type" "test")
8768 (set_attr "modrm" "0,1,0,1,1")
8769 (set_attr "mode" "SI,SI,DI,DI,DI")
8770 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8771
8772 (define_insn "testsi_1"
8773 [(set (reg FLAGS_REG)
8774 (compare
8775 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8776 (match_operand:SI 1 "general_operand" "i,i,ri"))
8777 (const_int 0)))]
8778 "ix86_match_ccmode (insn, CCNOmode)
8779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8780 "test{l}\t{%1, %0|%0, %1}"
8781 [(set_attr "type" "test")
8782 (set_attr "modrm" "0,1,1")
8783 (set_attr "mode" "SI")
8784 (set_attr "pent_pair" "uv,np,uv")])
8785
8786 (define_expand "testsi_ccno_1"
8787 [(set (reg:CCNO FLAGS_REG)
8788 (compare:CCNO
8789 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8790 (match_operand:SI 1 "nonmemory_operand" ""))
8791 (const_int 0)))]
8792 ""
8793 "")
8794
8795 (define_insn "*testhi_1"
8796 [(set (reg FLAGS_REG)
8797 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8798 (match_operand:HI 1 "general_operand" "n,n,rn"))
8799 (const_int 0)))]
8800 "ix86_match_ccmode (insn, CCNOmode)
8801 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8802 "test{w}\t{%1, %0|%0, %1}"
8803 [(set_attr "type" "test")
8804 (set_attr "modrm" "0,1,1")
8805 (set_attr "mode" "HI")
8806 (set_attr "pent_pair" "uv,np,uv")])
8807
8808 (define_expand "testqi_ccz_1"
8809 [(set (reg:CCZ FLAGS_REG)
8810 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8811 (match_operand:QI 1 "nonmemory_operand" ""))
8812 (const_int 0)))]
8813 ""
8814 "")
8815
8816 (define_insn "*testqi_1_maybe_si"
8817 [(set (reg FLAGS_REG)
8818 (compare
8819 (and:QI
8820 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8821 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8822 (const_int 0)))]
8823 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8824 && ix86_match_ccmode (insn,
8825 CONST_INT_P (operands[1])
8826 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8827 {
8828 if (which_alternative == 3)
8829 {
8830 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8831 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8832 return "test{l}\t{%1, %k0|%k0, %1}";
8833 }
8834 return "test{b}\t{%1, %0|%0, %1}";
8835 }
8836 [(set_attr "type" "test")
8837 (set_attr "modrm" "0,1,1,1")
8838 (set_attr "mode" "QI,QI,QI,SI")
8839 (set_attr "pent_pair" "uv,np,uv,np")])
8840
8841 (define_insn "*testqi_1"
8842 [(set (reg FLAGS_REG)
8843 (compare
8844 (and:QI
8845 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8846 (match_operand:QI 1 "general_operand" "n,n,qn"))
8847 (const_int 0)))]
8848 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8849 && ix86_match_ccmode (insn, CCNOmode)"
8850 "test{b}\t{%1, %0|%0, %1}"
8851 [(set_attr "type" "test")
8852 (set_attr "modrm" "0,1,1")
8853 (set_attr "mode" "QI")
8854 (set_attr "pent_pair" "uv,np,uv")])
8855
8856 (define_expand "testqi_ext_ccno_0"
8857 [(set (reg:CCNO FLAGS_REG)
8858 (compare:CCNO
8859 (and:SI
8860 (zero_extract:SI
8861 (match_operand 0 "ext_register_operand" "")
8862 (const_int 8)
8863 (const_int 8))
8864 (match_operand 1 "const_int_operand" ""))
8865 (const_int 0)))]
8866 ""
8867 "")
8868
8869 (define_insn "*testqi_ext_0"
8870 [(set (reg FLAGS_REG)
8871 (compare
8872 (and:SI
8873 (zero_extract:SI
8874 (match_operand 0 "ext_register_operand" "Q")
8875 (const_int 8)
8876 (const_int 8))
8877 (match_operand 1 "const_int_operand" "n"))
8878 (const_int 0)))]
8879 "ix86_match_ccmode (insn, CCNOmode)"
8880 "test{b}\t{%1, %h0|%h0, %1}"
8881 [(set_attr "type" "test")
8882 (set_attr "mode" "QI")
8883 (set_attr "length_immediate" "1")
8884 (set_attr "pent_pair" "np")])
8885
8886 (define_insn "*testqi_ext_1"
8887 [(set (reg FLAGS_REG)
8888 (compare
8889 (and:SI
8890 (zero_extract:SI
8891 (match_operand 0 "ext_register_operand" "Q")
8892 (const_int 8)
8893 (const_int 8))
8894 (zero_extend:SI
8895 (match_operand:QI 1 "general_operand" "Qm")))
8896 (const_int 0)))]
8897 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8898 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8899 "test{b}\t{%1, %h0|%h0, %1}"
8900 [(set_attr "type" "test")
8901 (set_attr "mode" "QI")])
8902
8903 (define_insn "*testqi_ext_1_rex64"
8904 [(set (reg FLAGS_REG)
8905 (compare
8906 (and:SI
8907 (zero_extract:SI
8908 (match_operand 0 "ext_register_operand" "Q")
8909 (const_int 8)
8910 (const_int 8))
8911 (zero_extend:SI
8912 (match_operand:QI 1 "register_operand" "Q")))
8913 (const_int 0)))]
8914 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8915 "test{b}\t{%1, %h0|%h0, %1}"
8916 [(set_attr "type" "test")
8917 (set_attr "mode" "QI")])
8918
8919 (define_insn "*testqi_ext_2"
8920 [(set (reg FLAGS_REG)
8921 (compare
8922 (and:SI
8923 (zero_extract:SI
8924 (match_operand 0 "ext_register_operand" "Q")
8925 (const_int 8)
8926 (const_int 8))
8927 (zero_extract:SI
8928 (match_operand 1 "ext_register_operand" "Q")
8929 (const_int 8)
8930 (const_int 8)))
8931 (const_int 0)))]
8932 "ix86_match_ccmode (insn, CCNOmode)"
8933 "test{b}\t{%h1, %h0|%h0, %h1}"
8934 [(set_attr "type" "test")
8935 (set_attr "mode" "QI")])
8936
8937 ;; Combine likes to form bit extractions for some tests. Humor it.
8938 (define_insn "*testqi_ext_3"
8939 [(set (reg FLAGS_REG)
8940 (compare (zero_extract:SI
8941 (match_operand 0 "nonimmediate_operand" "rm")
8942 (match_operand:SI 1 "const_int_operand" "")
8943 (match_operand:SI 2 "const_int_operand" ""))
8944 (const_int 0)))]
8945 "ix86_match_ccmode (insn, CCNOmode)
8946 && INTVAL (operands[1]) > 0
8947 && INTVAL (operands[2]) >= 0
8948 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8949 && (GET_MODE (operands[0]) == SImode
8950 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8951 || GET_MODE (operands[0]) == HImode
8952 || GET_MODE (operands[0]) == QImode)"
8953 "#")
8954
8955 (define_insn "*testqi_ext_3_rex64"
8956 [(set (reg FLAGS_REG)
8957 (compare (zero_extract:DI
8958 (match_operand 0 "nonimmediate_operand" "rm")
8959 (match_operand:DI 1 "const_int_operand" "")
8960 (match_operand:DI 2 "const_int_operand" ""))
8961 (const_int 0)))]
8962 "TARGET_64BIT
8963 && ix86_match_ccmode (insn, CCNOmode)
8964 && INTVAL (operands[1]) > 0
8965 && INTVAL (operands[2]) >= 0
8966 /* Ensure that resulting mask is zero or sign extended operand. */
8967 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8968 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8969 && INTVAL (operands[1]) > 32))
8970 && (GET_MODE (operands[0]) == SImode
8971 || GET_MODE (operands[0]) == DImode
8972 || GET_MODE (operands[0]) == HImode
8973 || GET_MODE (operands[0]) == QImode)"
8974 "#")
8975
8976 (define_split
8977 [(set (match_operand 0 "flags_reg_operand" "")
8978 (match_operator 1 "compare_operator"
8979 [(zero_extract
8980 (match_operand 2 "nonimmediate_operand" "")
8981 (match_operand 3 "const_int_operand" "")
8982 (match_operand 4 "const_int_operand" ""))
8983 (const_int 0)]))]
8984 "ix86_match_ccmode (insn, CCNOmode)"
8985 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8986 {
8987 rtx val = operands[2];
8988 HOST_WIDE_INT len = INTVAL (operands[3]);
8989 HOST_WIDE_INT pos = INTVAL (operands[4]);
8990 HOST_WIDE_INT mask;
8991 enum machine_mode mode, submode;
8992
8993 mode = GET_MODE (val);
8994 if (MEM_P (val))
8995 {
8996 /* ??? Combine likes to put non-volatile mem extractions in QImode
8997 no matter the size of the test. So find a mode that works. */
8998 if (! MEM_VOLATILE_P (val))
8999 {
9000 mode = smallest_mode_for_size (pos + len, MODE_INT);
9001 val = adjust_address (val, mode, 0);
9002 }
9003 }
9004 else if (GET_CODE (val) == SUBREG
9005 && (submode = GET_MODE (SUBREG_REG (val)),
9006 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9007 && pos + len <= GET_MODE_BITSIZE (submode))
9008 {
9009 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9010 mode = submode;
9011 val = SUBREG_REG (val);
9012 }
9013 else if (mode == HImode && pos + len <= 8)
9014 {
9015 /* Small HImode tests can be converted to QImode. */
9016 mode = QImode;
9017 val = gen_lowpart (QImode, val);
9018 }
9019
9020 if (len == HOST_BITS_PER_WIDE_INT)
9021 mask = -1;
9022 else
9023 mask = ((HOST_WIDE_INT)1 << len) - 1;
9024 mask <<= pos;
9025
9026 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9027 })
9028
9029 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9030 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9031 ;; this is relatively important trick.
9032 ;; Do the conversion only post-reload to avoid limiting of the register class
9033 ;; to QI regs.
9034 (define_split
9035 [(set (match_operand 0 "flags_reg_operand" "")
9036 (match_operator 1 "compare_operator"
9037 [(and (match_operand 2 "register_operand" "")
9038 (match_operand 3 "const_int_operand" ""))
9039 (const_int 0)]))]
9040 "reload_completed
9041 && QI_REG_P (operands[2])
9042 && GET_MODE (operands[2]) != QImode
9043 && ((ix86_match_ccmode (insn, CCZmode)
9044 && !(INTVAL (operands[3]) & ~(255 << 8)))
9045 || (ix86_match_ccmode (insn, CCNOmode)
9046 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9047 [(set (match_dup 0)
9048 (match_op_dup 1
9049 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9050 (match_dup 3))
9051 (const_int 0)]))]
9052 "operands[2] = gen_lowpart (SImode, operands[2]);
9053 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9054
9055 (define_split
9056 [(set (match_operand 0 "flags_reg_operand" "")
9057 (match_operator 1 "compare_operator"
9058 [(and (match_operand 2 "nonimmediate_operand" "")
9059 (match_operand 3 "const_int_operand" ""))
9060 (const_int 0)]))]
9061 "reload_completed
9062 && GET_MODE (operands[2]) != QImode
9063 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9064 && ((ix86_match_ccmode (insn, CCZmode)
9065 && !(INTVAL (operands[3]) & ~255))
9066 || (ix86_match_ccmode (insn, CCNOmode)
9067 && !(INTVAL (operands[3]) & ~127)))"
9068 [(set (match_dup 0)
9069 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9070 (const_int 0)]))]
9071 "operands[2] = gen_lowpart (QImode, operands[2]);
9072 operands[3] = gen_lowpart (QImode, operands[3]);")
9073
9074
9075 ;; %%% This used to optimize known byte-wide and operations to memory,
9076 ;; and sometimes to QImode registers. If this is considered useful,
9077 ;; it should be done with splitters.
9078
9079 (define_expand "anddi3"
9080 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9081 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9082 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9083 "TARGET_64BIT"
9084 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9085
9086 (define_insn "*anddi_1_rex64"
9087 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9088 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9089 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9090 (clobber (reg:CC FLAGS_REG))]
9091 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9092 {
9093 switch (get_attr_type (insn))
9094 {
9095 case TYPE_IMOVX:
9096 {
9097 enum machine_mode mode;
9098
9099 gcc_assert (CONST_INT_P (operands[2]));
9100 if (INTVAL (operands[2]) == 0xff)
9101 mode = QImode;
9102 else
9103 {
9104 gcc_assert (INTVAL (operands[2]) == 0xffff);
9105 mode = HImode;
9106 }
9107
9108 operands[1] = gen_lowpart (mode, operands[1]);
9109 if (mode == QImode)
9110 return "movz{bq|x}\t{%1,%0|%0, %1}";
9111 else
9112 return "movz{wq|x}\t{%1,%0|%0, %1}";
9113 }
9114
9115 default:
9116 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9117 if (get_attr_mode (insn) == MODE_SI)
9118 return "and{l}\t{%k2, %k0|%k0, %k2}";
9119 else
9120 return "and{q}\t{%2, %0|%0, %2}";
9121 }
9122 }
9123 [(set_attr "type" "alu,alu,alu,imovx")
9124 (set_attr "length_immediate" "*,*,*,0")
9125 (set_attr "mode" "SI,DI,DI,DI")])
9126
9127 (define_insn "*anddi_2"
9128 [(set (reg FLAGS_REG)
9129 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9130 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9131 (const_int 0)))
9132 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9133 (and:DI (match_dup 1) (match_dup 2)))]
9134 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9135 && ix86_binary_operator_ok (AND, DImode, operands)"
9136 "@
9137 and{l}\t{%k2, %k0|%k0, %k2}
9138 and{q}\t{%2, %0|%0, %2}
9139 and{q}\t{%2, %0|%0, %2}"
9140 [(set_attr "type" "alu")
9141 (set_attr "mode" "SI,DI,DI")])
9142
9143 (define_expand "andsi3"
9144 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9145 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9146 (match_operand:SI 2 "general_operand" "")))]
9147 ""
9148 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9149
9150 (define_insn "*andsi_1"
9151 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9152 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9153 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9154 (clobber (reg:CC FLAGS_REG))]
9155 "ix86_binary_operator_ok (AND, SImode, operands)"
9156 {
9157 switch (get_attr_type (insn))
9158 {
9159 case TYPE_IMOVX:
9160 {
9161 enum machine_mode mode;
9162
9163 gcc_assert (CONST_INT_P (operands[2]));
9164 if (INTVAL (operands[2]) == 0xff)
9165 mode = QImode;
9166 else
9167 {
9168 gcc_assert (INTVAL (operands[2]) == 0xffff);
9169 mode = HImode;
9170 }
9171
9172 operands[1] = gen_lowpart (mode, operands[1]);
9173 if (mode == QImode)
9174 return "movz{bl|x}\t{%1,%0|%0, %1}";
9175 else
9176 return "movz{wl|x}\t{%1,%0|%0, %1}";
9177 }
9178
9179 default:
9180 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9181 return "and{l}\t{%2, %0|%0, %2}";
9182 }
9183 }
9184 [(set_attr "type" "alu,alu,imovx")
9185 (set_attr "length_immediate" "*,*,0")
9186 (set_attr "mode" "SI")])
9187
9188 (define_split
9189 [(set (match_operand 0 "register_operand" "")
9190 (and (match_dup 0)
9191 (const_int -65536)))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9194 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9195 "operands[1] = gen_lowpart (HImode, operands[0]);")
9196
9197 (define_split
9198 [(set (match_operand 0 "ext_register_operand" "")
9199 (and (match_dup 0)
9200 (const_int -256)))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9203 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9204 "operands[1] = gen_lowpart (QImode, operands[0]);")
9205
9206 (define_split
9207 [(set (match_operand 0 "ext_register_operand" "")
9208 (and (match_dup 0)
9209 (const_int -65281)))
9210 (clobber (reg:CC FLAGS_REG))]
9211 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9212 [(parallel [(set (zero_extract:SI (match_dup 0)
9213 (const_int 8)
9214 (const_int 8))
9215 (xor:SI
9216 (zero_extract:SI (match_dup 0)
9217 (const_int 8)
9218 (const_int 8))
9219 (zero_extract:SI (match_dup 0)
9220 (const_int 8)
9221 (const_int 8))))
9222 (clobber (reg:CC FLAGS_REG))])]
9223 "operands[0] = gen_lowpart (SImode, operands[0]);")
9224
9225 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9226 (define_insn "*andsi_1_zext"
9227 [(set (match_operand:DI 0 "register_operand" "=r")
9228 (zero_extend:DI
9229 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9230 (match_operand:SI 2 "general_operand" "g"))))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9233 "and{l}\t{%2, %k0|%k0, %2}"
9234 [(set_attr "type" "alu")
9235 (set_attr "mode" "SI")])
9236
9237 (define_insn "*andsi_2"
9238 [(set (reg FLAGS_REG)
9239 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9240 (match_operand:SI 2 "general_operand" "g,ri"))
9241 (const_int 0)))
9242 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9243 (and:SI (match_dup 1) (match_dup 2)))]
9244 "ix86_match_ccmode (insn, CCNOmode)
9245 && ix86_binary_operator_ok (AND, SImode, operands)"
9246 "and{l}\t{%2, %0|%0, %2}"
9247 [(set_attr "type" "alu")
9248 (set_attr "mode" "SI")])
9249
9250 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9251 (define_insn "*andsi_2_zext"
9252 [(set (reg FLAGS_REG)
9253 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9254 (match_operand:SI 2 "general_operand" "g"))
9255 (const_int 0)))
9256 (set (match_operand:DI 0 "register_operand" "=r")
9257 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9258 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9259 && ix86_binary_operator_ok (AND, SImode, operands)"
9260 "and{l}\t{%2, %k0|%k0, %2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "mode" "SI")])
9263
9264 (define_expand "andhi3"
9265 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9266 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9267 (match_operand:HI 2 "general_operand" "")))]
9268 "TARGET_HIMODE_MATH"
9269 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9270
9271 (define_insn "*andhi_1"
9272 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9273 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9274 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9275 (clobber (reg:CC FLAGS_REG))]
9276 "ix86_binary_operator_ok (AND, HImode, operands)"
9277 {
9278 switch (get_attr_type (insn))
9279 {
9280 case TYPE_IMOVX:
9281 gcc_assert (CONST_INT_P (operands[2]));
9282 gcc_assert (INTVAL (operands[2]) == 0xff);
9283 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9284
9285 default:
9286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9287
9288 return "and{w}\t{%2, %0|%0, %2}";
9289 }
9290 }
9291 [(set_attr "type" "alu,alu,imovx")
9292 (set_attr "length_immediate" "*,*,0")
9293 (set_attr "mode" "HI,HI,SI")])
9294
9295 (define_insn "*andhi_2"
9296 [(set (reg FLAGS_REG)
9297 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9298 (match_operand:HI 2 "general_operand" "rmn,rn"))
9299 (const_int 0)))
9300 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9301 (and:HI (match_dup 1) (match_dup 2)))]
9302 "ix86_match_ccmode (insn, CCNOmode)
9303 && ix86_binary_operator_ok (AND, HImode, operands)"
9304 "and{w}\t{%2, %0|%0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "HI")])
9307
9308 (define_expand "andqi3"
9309 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9310 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9311 (match_operand:QI 2 "general_operand" "")))]
9312 "TARGET_QIMODE_MATH"
9313 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9314
9315 ;; %%% Potential partial reg stall on alternative 2. What to do?
9316 (define_insn "*andqi_1"
9317 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9318 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9319 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9320 (clobber (reg:CC FLAGS_REG))]
9321 "ix86_binary_operator_ok (AND, QImode, operands)"
9322 "@
9323 and{b}\t{%2, %0|%0, %2}
9324 and{b}\t{%2, %0|%0, %2}
9325 and{l}\t{%k2, %k0|%k0, %k2}"
9326 [(set_attr "type" "alu")
9327 (set_attr "mode" "QI,QI,SI")])
9328
9329 (define_insn "*andqi_1_slp"
9330 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9331 (and:QI (match_dup 0)
9332 (match_operand:QI 1 "general_operand" "qn,qmn")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9335 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9336 "and{b}\t{%1, %0|%0, %1}"
9337 [(set_attr "type" "alu1")
9338 (set_attr "mode" "QI")])
9339
9340 (define_insn "*andqi_2_maybe_si"
9341 [(set (reg FLAGS_REG)
9342 (compare (and:QI
9343 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9344 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9345 (const_int 0)))
9346 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9347 (and:QI (match_dup 1) (match_dup 2)))]
9348 "ix86_binary_operator_ok (AND, QImode, operands)
9349 && ix86_match_ccmode (insn,
9350 CONST_INT_P (operands[2])
9351 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9352 {
9353 if (which_alternative == 2)
9354 {
9355 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9356 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9357 return "and{l}\t{%2, %k0|%k0, %2}";
9358 }
9359 return "and{b}\t{%2, %0|%0, %2}";
9360 }
9361 [(set_attr "type" "alu")
9362 (set_attr "mode" "QI,QI,SI")])
9363
9364 (define_insn "*andqi_2"
9365 [(set (reg FLAGS_REG)
9366 (compare (and:QI
9367 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9368 (match_operand:QI 2 "general_operand" "qmn,qn"))
9369 (const_int 0)))
9370 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9371 (and:QI (match_dup 1) (match_dup 2)))]
9372 "ix86_match_ccmode (insn, CCNOmode)
9373 && ix86_binary_operator_ok (AND, QImode, operands)"
9374 "and{b}\t{%2, %0|%0, %2}"
9375 [(set_attr "type" "alu")
9376 (set_attr "mode" "QI")])
9377
9378 (define_insn "*andqi_2_slp"
9379 [(set (reg FLAGS_REG)
9380 (compare (and:QI
9381 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9382 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9383 (const_int 0)))
9384 (set (strict_low_part (match_dup 0))
9385 (and:QI (match_dup 0) (match_dup 1)))]
9386 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9387 && ix86_match_ccmode (insn, CCNOmode)
9388 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9389 "and{b}\t{%1, %0|%0, %1}"
9390 [(set_attr "type" "alu1")
9391 (set_attr "mode" "QI")])
9392
9393 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9394 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9395 ;; for a QImode operand, which of course failed.
9396
9397 (define_insn "andqi_ext_0"
9398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9399 (const_int 8)
9400 (const_int 8))
9401 (and:SI
9402 (zero_extract:SI
9403 (match_operand 1 "ext_register_operand" "0")
9404 (const_int 8)
9405 (const_int 8))
9406 (match_operand 2 "const_int_operand" "n")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 ""
9409 "and{b}\t{%2, %h0|%h0, %2}"
9410 [(set_attr "type" "alu")
9411 (set_attr "length_immediate" "1")
9412 (set_attr "mode" "QI")])
9413
9414 ;; Generated by peephole translating test to and. This shows up
9415 ;; often in fp comparisons.
9416
9417 (define_insn "*andqi_ext_0_cc"
9418 [(set (reg FLAGS_REG)
9419 (compare
9420 (and:SI
9421 (zero_extract:SI
9422 (match_operand 1 "ext_register_operand" "0")
9423 (const_int 8)
9424 (const_int 8))
9425 (match_operand 2 "const_int_operand" "n"))
9426 (const_int 0)))
9427 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9428 (const_int 8)
9429 (const_int 8))
9430 (and:SI
9431 (zero_extract:SI
9432 (match_dup 1)
9433 (const_int 8)
9434 (const_int 8))
9435 (match_dup 2)))]
9436 "ix86_match_ccmode (insn, CCNOmode)"
9437 "and{b}\t{%2, %h0|%h0, %2}"
9438 [(set_attr "type" "alu")
9439 (set_attr "length_immediate" "1")
9440 (set_attr "mode" "QI")])
9441
9442 (define_insn "*andqi_ext_1"
9443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9444 (const_int 8)
9445 (const_int 8))
9446 (and:SI
9447 (zero_extract:SI
9448 (match_operand 1 "ext_register_operand" "0")
9449 (const_int 8)
9450 (const_int 8))
9451 (zero_extend:SI
9452 (match_operand:QI 2 "general_operand" "Qm"))))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "!TARGET_64BIT"
9455 "and{b}\t{%2, %h0|%h0, %2}"
9456 [(set_attr "type" "alu")
9457 (set_attr "length_immediate" "0")
9458 (set_attr "mode" "QI")])
9459
9460 (define_insn "*andqi_ext_1_rex64"
9461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9462 (const_int 8)
9463 (const_int 8))
9464 (and:SI
9465 (zero_extract:SI
9466 (match_operand 1 "ext_register_operand" "0")
9467 (const_int 8)
9468 (const_int 8))
9469 (zero_extend:SI
9470 (match_operand 2 "ext_register_operand" "Q"))))
9471 (clobber (reg:CC FLAGS_REG))]
9472 "TARGET_64BIT"
9473 "and{b}\t{%2, %h0|%h0, %2}"
9474 [(set_attr "type" "alu")
9475 (set_attr "length_immediate" "0")
9476 (set_attr "mode" "QI")])
9477
9478 (define_insn "*andqi_ext_2"
9479 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9480 (const_int 8)
9481 (const_int 8))
9482 (and:SI
9483 (zero_extract:SI
9484 (match_operand 1 "ext_register_operand" "%0")
9485 (const_int 8)
9486 (const_int 8))
9487 (zero_extract:SI
9488 (match_operand 2 "ext_register_operand" "Q")
9489 (const_int 8)
9490 (const_int 8))))
9491 (clobber (reg:CC FLAGS_REG))]
9492 ""
9493 "and{b}\t{%h2, %h0|%h0, %h2}"
9494 [(set_attr "type" "alu")
9495 (set_attr "length_immediate" "0")
9496 (set_attr "mode" "QI")])
9497
9498 ;; Convert wide AND instructions with immediate operand to shorter QImode
9499 ;; equivalents when possible.
9500 ;; Don't do the splitting with memory operands, since it introduces risk
9501 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9502 ;; for size, but that can (should?) be handled by generic code instead.
9503 (define_split
9504 [(set (match_operand 0 "register_operand" "")
9505 (and (match_operand 1 "register_operand" "")
9506 (match_operand 2 "const_int_operand" "")))
9507 (clobber (reg:CC FLAGS_REG))]
9508 "reload_completed
9509 && QI_REG_P (operands[0])
9510 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9511 && !(~INTVAL (operands[2]) & ~(255 << 8))
9512 && GET_MODE (operands[0]) != QImode"
9513 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9514 (and:SI (zero_extract:SI (match_dup 1)
9515 (const_int 8) (const_int 8))
9516 (match_dup 2)))
9517 (clobber (reg:CC FLAGS_REG))])]
9518 "operands[0] = gen_lowpart (SImode, operands[0]);
9519 operands[1] = gen_lowpart (SImode, operands[1]);
9520 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9521
9522 ;; Since AND can be encoded with sign extended immediate, this is only
9523 ;; profitable when 7th bit is not set.
9524 (define_split
9525 [(set (match_operand 0 "register_operand" "")
9526 (and (match_operand 1 "general_operand" "")
9527 (match_operand 2 "const_int_operand" "")))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "reload_completed
9530 && ANY_QI_REG_P (operands[0])
9531 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9532 && !(~INTVAL (operands[2]) & ~255)
9533 && !(INTVAL (operands[2]) & 128)
9534 && GET_MODE (operands[0]) != QImode"
9535 [(parallel [(set (strict_low_part (match_dup 0))
9536 (and:QI (match_dup 1)
9537 (match_dup 2)))
9538 (clobber (reg:CC FLAGS_REG))])]
9539 "operands[0] = gen_lowpart (QImode, operands[0]);
9540 operands[1] = gen_lowpart (QImode, operands[1]);
9541 operands[2] = gen_lowpart (QImode, operands[2]);")
9542 \f
9543 ;; Logical inclusive OR instructions
9544
9545 ;; %%% This used to optimize known byte-wide and operations to memory.
9546 ;; If this is considered useful, it should be done with splitters.
9547
9548 (define_expand "iordi3"
9549 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9550 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9551 (match_operand:DI 2 "x86_64_general_operand" "")))]
9552 "TARGET_64BIT"
9553 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9554
9555 (define_insn "*iordi_1_rex64"
9556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9557 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9558 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9559 (clobber (reg:CC FLAGS_REG))]
9560 "TARGET_64BIT
9561 && ix86_binary_operator_ok (IOR, DImode, operands)"
9562 "or{q}\t{%2, %0|%0, %2}"
9563 [(set_attr "type" "alu")
9564 (set_attr "mode" "DI")])
9565
9566 (define_insn "*iordi_2_rex64"
9567 [(set (reg FLAGS_REG)
9568 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9569 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9570 (const_int 0)))
9571 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9572 (ior:DI (match_dup 1) (match_dup 2)))]
9573 "TARGET_64BIT
9574 && ix86_match_ccmode (insn, CCNOmode)
9575 && ix86_binary_operator_ok (IOR, DImode, operands)"
9576 "or{q}\t{%2, %0|%0, %2}"
9577 [(set_attr "type" "alu")
9578 (set_attr "mode" "DI")])
9579
9580 (define_insn "*iordi_3_rex64"
9581 [(set (reg FLAGS_REG)
9582 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9583 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9584 (const_int 0)))
9585 (clobber (match_scratch:DI 0 "=r"))]
9586 "TARGET_64BIT
9587 && ix86_match_ccmode (insn, CCNOmode)
9588 && ix86_binary_operator_ok (IOR, DImode, operands)"
9589 "or{q}\t{%2, %0|%0, %2}"
9590 [(set_attr "type" "alu")
9591 (set_attr "mode" "DI")])
9592
9593
9594 (define_expand "iorsi3"
9595 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9596 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9597 (match_operand:SI 2 "general_operand" "")))]
9598 ""
9599 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9600
9601 (define_insn "*iorsi_1"
9602 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9603 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9604 (match_operand:SI 2 "general_operand" "ri,g")))
9605 (clobber (reg:CC FLAGS_REG))]
9606 "ix86_binary_operator_ok (IOR, SImode, operands)"
9607 "or{l}\t{%2, %0|%0, %2}"
9608 [(set_attr "type" "alu")
9609 (set_attr "mode" "SI")])
9610
9611 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9612 (define_insn "*iorsi_1_zext"
9613 [(set (match_operand:DI 0 "register_operand" "=r")
9614 (zero_extend:DI
9615 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9616 (match_operand:SI 2 "general_operand" "g"))))
9617 (clobber (reg:CC FLAGS_REG))]
9618 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9619 "or{l}\t{%2, %k0|%k0, %2}"
9620 [(set_attr "type" "alu")
9621 (set_attr "mode" "SI")])
9622
9623 (define_insn "*iorsi_1_zext_imm"
9624 [(set (match_operand:DI 0 "register_operand" "=r")
9625 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9626 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9627 (clobber (reg:CC FLAGS_REG))]
9628 "TARGET_64BIT"
9629 "or{l}\t{%2, %k0|%k0, %2}"
9630 [(set_attr "type" "alu")
9631 (set_attr "mode" "SI")])
9632
9633 (define_insn "*iorsi_2"
9634 [(set (reg FLAGS_REG)
9635 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9636 (match_operand:SI 2 "general_operand" "g,ri"))
9637 (const_int 0)))
9638 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9639 (ior:SI (match_dup 1) (match_dup 2)))]
9640 "ix86_match_ccmode (insn, CCNOmode)
9641 && ix86_binary_operator_ok (IOR, SImode, operands)"
9642 "or{l}\t{%2, %0|%0, %2}"
9643 [(set_attr "type" "alu")
9644 (set_attr "mode" "SI")])
9645
9646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9647 ;; ??? Special case for immediate operand is missing - it is tricky.
9648 (define_insn "*iorsi_2_zext"
9649 [(set (reg FLAGS_REG)
9650 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9651 (match_operand:SI 2 "general_operand" "g"))
9652 (const_int 0)))
9653 (set (match_operand:DI 0 "register_operand" "=r")
9654 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9655 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9656 && ix86_binary_operator_ok (IOR, SImode, operands)"
9657 "or{l}\t{%2, %k0|%k0, %2}"
9658 [(set_attr "type" "alu")
9659 (set_attr "mode" "SI")])
9660
9661 (define_insn "*iorsi_2_zext_imm"
9662 [(set (reg FLAGS_REG)
9663 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9664 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9665 (const_int 0)))
9666 (set (match_operand:DI 0 "register_operand" "=r")
9667 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9668 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9669 && ix86_binary_operator_ok (IOR, SImode, operands)"
9670 "or{l}\t{%2, %k0|%k0, %2}"
9671 [(set_attr "type" "alu")
9672 (set_attr "mode" "SI")])
9673
9674 (define_insn "*iorsi_3"
9675 [(set (reg FLAGS_REG)
9676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9677 (match_operand:SI 2 "general_operand" "g"))
9678 (const_int 0)))
9679 (clobber (match_scratch:SI 0 "=r"))]
9680 "ix86_match_ccmode (insn, CCNOmode)
9681 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9682 "or{l}\t{%2, %0|%0, %2}"
9683 [(set_attr "type" "alu")
9684 (set_attr "mode" "SI")])
9685
9686 (define_expand "iorhi3"
9687 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9688 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9689 (match_operand:HI 2 "general_operand" "")))]
9690 "TARGET_HIMODE_MATH"
9691 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9692
9693 (define_insn "*iorhi_1"
9694 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9695 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9696 (match_operand:HI 2 "general_operand" "rmn,rn")))
9697 (clobber (reg:CC FLAGS_REG))]
9698 "ix86_binary_operator_ok (IOR, HImode, operands)"
9699 "or{w}\t{%2, %0|%0, %2}"
9700 [(set_attr "type" "alu")
9701 (set_attr "mode" "HI")])
9702
9703 (define_insn "*iorhi_2"
9704 [(set (reg FLAGS_REG)
9705 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9706 (match_operand:HI 2 "general_operand" "rmn,rn"))
9707 (const_int 0)))
9708 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9709 (ior:HI (match_dup 1) (match_dup 2)))]
9710 "ix86_match_ccmode (insn, CCNOmode)
9711 && ix86_binary_operator_ok (IOR, HImode, operands)"
9712 "or{w}\t{%2, %0|%0, %2}"
9713 [(set_attr "type" "alu")
9714 (set_attr "mode" "HI")])
9715
9716 (define_insn "*iorhi_3"
9717 [(set (reg FLAGS_REG)
9718 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9719 (match_operand:HI 2 "general_operand" "rmn"))
9720 (const_int 0)))
9721 (clobber (match_scratch:HI 0 "=r"))]
9722 "ix86_match_ccmode (insn, CCNOmode)
9723 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9724 "or{w}\t{%2, %0|%0, %2}"
9725 [(set_attr "type" "alu")
9726 (set_attr "mode" "HI")])
9727
9728 (define_expand "iorqi3"
9729 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9730 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9731 (match_operand:QI 2 "general_operand" "")))]
9732 "TARGET_QIMODE_MATH"
9733 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9734
9735 ;; %%% Potential partial reg stall on alternative 2. What to do?
9736 (define_insn "*iorqi_1"
9737 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9738 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9739 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9740 (clobber (reg:CC FLAGS_REG))]
9741 "ix86_binary_operator_ok (IOR, QImode, operands)"
9742 "@
9743 or{b}\t{%2, %0|%0, %2}
9744 or{b}\t{%2, %0|%0, %2}
9745 or{l}\t{%k2, %k0|%k0, %k2}"
9746 [(set_attr "type" "alu")
9747 (set_attr "mode" "QI,QI,SI")])
9748
9749 (define_insn "*iorqi_1_slp"
9750 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9751 (ior:QI (match_dup 0)
9752 (match_operand:QI 1 "general_operand" "qmn,qn")))
9753 (clobber (reg:CC FLAGS_REG))]
9754 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9755 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9756 "or{b}\t{%1, %0|%0, %1}"
9757 [(set_attr "type" "alu1")
9758 (set_attr "mode" "QI")])
9759
9760 (define_insn "*iorqi_2"
9761 [(set (reg FLAGS_REG)
9762 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9763 (match_operand:QI 2 "general_operand" "qmn,qn"))
9764 (const_int 0)))
9765 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9766 (ior:QI (match_dup 1) (match_dup 2)))]
9767 "ix86_match_ccmode (insn, CCNOmode)
9768 && ix86_binary_operator_ok (IOR, QImode, operands)"
9769 "or{b}\t{%2, %0|%0, %2}"
9770 [(set_attr "type" "alu")
9771 (set_attr "mode" "QI")])
9772
9773 (define_insn "*iorqi_2_slp"
9774 [(set (reg FLAGS_REG)
9775 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9776 (match_operand:QI 1 "general_operand" "qmn,qn"))
9777 (const_int 0)))
9778 (set (strict_low_part (match_dup 0))
9779 (ior:QI (match_dup 0) (match_dup 1)))]
9780 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9781 && ix86_match_ccmode (insn, CCNOmode)
9782 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9783 "or{b}\t{%1, %0|%0, %1}"
9784 [(set_attr "type" "alu1")
9785 (set_attr "mode" "QI")])
9786
9787 (define_insn "*iorqi_3"
9788 [(set (reg FLAGS_REG)
9789 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9790 (match_operand:QI 2 "general_operand" "qmn"))
9791 (const_int 0)))
9792 (clobber (match_scratch:QI 0 "=q"))]
9793 "ix86_match_ccmode (insn, CCNOmode)
9794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9795 "or{b}\t{%2, %0|%0, %2}"
9796 [(set_attr "type" "alu")
9797 (set_attr "mode" "QI")])
9798
9799 (define_insn "*iorqi_ext_0"
9800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9801 (const_int 8)
9802 (const_int 8))
9803 (ior:SI
9804 (zero_extract:SI
9805 (match_operand 1 "ext_register_operand" "0")
9806 (const_int 8)
9807 (const_int 8))
9808 (match_operand 2 "const_int_operand" "n")))
9809 (clobber (reg:CC FLAGS_REG))]
9810 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9811 "or{b}\t{%2, %h0|%h0, %2}"
9812 [(set_attr "type" "alu")
9813 (set_attr "length_immediate" "1")
9814 (set_attr "mode" "QI")])
9815
9816 (define_insn "*iorqi_ext_1"
9817 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9818 (const_int 8)
9819 (const_int 8))
9820 (ior:SI
9821 (zero_extract:SI
9822 (match_operand 1 "ext_register_operand" "0")
9823 (const_int 8)
9824 (const_int 8))
9825 (zero_extend:SI
9826 (match_operand:QI 2 "general_operand" "Qm"))))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "!TARGET_64BIT
9829 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9830 "or{b}\t{%2, %h0|%h0, %2}"
9831 [(set_attr "type" "alu")
9832 (set_attr "length_immediate" "0")
9833 (set_attr "mode" "QI")])
9834
9835 (define_insn "*iorqi_ext_1_rex64"
9836 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9837 (const_int 8)
9838 (const_int 8))
9839 (ior:SI
9840 (zero_extract:SI
9841 (match_operand 1 "ext_register_operand" "0")
9842 (const_int 8)
9843 (const_int 8))
9844 (zero_extend:SI
9845 (match_operand 2 "ext_register_operand" "Q"))))
9846 (clobber (reg:CC FLAGS_REG))]
9847 "TARGET_64BIT
9848 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9849 "or{b}\t{%2, %h0|%h0, %2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "length_immediate" "0")
9852 (set_attr "mode" "QI")])
9853
9854 (define_insn "*iorqi_ext_2"
9855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9856 (const_int 8)
9857 (const_int 8))
9858 (ior:SI
9859 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9860 (const_int 8)
9861 (const_int 8))
9862 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9863 (const_int 8)
9864 (const_int 8))))
9865 (clobber (reg:CC FLAGS_REG))]
9866 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9867 "ior{b}\t{%h2, %h0|%h0, %h2}"
9868 [(set_attr "type" "alu")
9869 (set_attr "length_immediate" "0")
9870 (set_attr "mode" "QI")])
9871
9872 (define_split
9873 [(set (match_operand 0 "register_operand" "")
9874 (ior (match_operand 1 "register_operand" "")
9875 (match_operand 2 "const_int_operand" "")))
9876 (clobber (reg:CC FLAGS_REG))]
9877 "reload_completed
9878 && QI_REG_P (operands[0])
9879 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9880 && !(INTVAL (operands[2]) & ~(255 << 8))
9881 && GET_MODE (operands[0]) != QImode"
9882 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9883 (ior:SI (zero_extract:SI (match_dup 1)
9884 (const_int 8) (const_int 8))
9885 (match_dup 2)))
9886 (clobber (reg:CC FLAGS_REG))])]
9887 "operands[0] = gen_lowpart (SImode, operands[0]);
9888 operands[1] = gen_lowpart (SImode, operands[1]);
9889 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9890
9891 ;; Since OR can be encoded with sign extended immediate, this is only
9892 ;; profitable when 7th bit is set.
9893 (define_split
9894 [(set (match_operand 0 "register_operand" "")
9895 (ior (match_operand 1 "general_operand" "")
9896 (match_operand 2 "const_int_operand" "")))
9897 (clobber (reg:CC FLAGS_REG))]
9898 "reload_completed
9899 && ANY_QI_REG_P (operands[0])
9900 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9901 && !(INTVAL (operands[2]) & ~255)
9902 && (INTVAL (operands[2]) & 128)
9903 && GET_MODE (operands[0]) != QImode"
9904 [(parallel [(set (strict_low_part (match_dup 0))
9905 (ior:QI (match_dup 1)
9906 (match_dup 2)))
9907 (clobber (reg:CC FLAGS_REG))])]
9908 "operands[0] = gen_lowpart (QImode, operands[0]);
9909 operands[1] = gen_lowpart (QImode, operands[1]);
9910 operands[2] = gen_lowpart (QImode, operands[2]);")
9911 \f
9912 ;; Logical XOR instructions
9913
9914 ;; %%% This used to optimize known byte-wide and operations to memory.
9915 ;; If this is considered useful, it should be done with splitters.
9916
9917 (define_expand "xordi3"
9918 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9919 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9920 (match_operand:DI 2 "x86_64_general_operand" "")))]
9921 "TARGET_64BIT"
9922 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9923
9924 (define_insn "*xordi_1_rex64"
9925 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9926 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9927 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9928 (clobber (reg:CC FLAGS_REG))]
9929 "TARGET_64BIT
9930 && ix86_binary_operator_ok (XOR, DImode, operands)"
9931 "xor{q}\t{%2, %0|%0, %2}"
9932 [(set_attr "type" "alu")
9933 (set_attr "mode" "DI")])
9934
9935 (define_insn "*xordi_2_rex64"
9936 [(set (reg FLAGS_REG)
9937 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9938 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9939 (const_int 0)))
9940 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9941 (xor:DI (match_dup 1) (match_dup 2)))]
9942 "TARGET_64BIT
9943 && ix86_match_ccmode (insn, CCNOmode)
9944 && ix86_binary_operator_ok (XOR, DImode, operands)"
9945 "xor{q}\t{%2, %0|%0, %2}"
9946 [(set_attr "type" "alu")
9947 (set_attr "mode" "DI")])
9948
9949 (define_insn "*xordi_3_rex64"
9950 [(set (reg FLAGS_REG)
9951 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9952 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9953 (const_int 0)))
9954 (clobber (match_scratch:DI 0 "=r"))]
9955 "TARGET_64BIT
9956 && ix86_match_ccmode (insn, CCNOmode)
9957 && ix86_binary_operator_ok (XOR, DImode, operands)"
9958 "xor{q}\t{%2, %0|%0, %2}"
9959 [(set_attr "type" "alu")
9960 (set_attr "mode" "DI")])
9961
9962 (define_expand "xorsi3"
9963 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9964 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9965 (match_operand:SI 2 "general_operand" "")))]
9966 ""
9967 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9968
9969 (define_insn "*xorsi_1"
9970 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9971 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9972 (match_operand:SI 2 "general_operand" "ri,rm")))
9973 (clobber (reg:CC FLAGS_REG))]
9974 "ix86_binary_operator_ok (XOR, SImode, operands)"
9975 "xor{l}\t{%2, %0|%0, %2}"
9976 [(set_attr "type" "alu")
9977 (set_attr "mode" "SI")])
9978
9979 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9980 ;; Add speccase for immediates
9981 (define_insn "*xorsi_1_zext"
9982 [(set (match_operand:DI 0 "register_operand" "=r")
9983 (zero_extend:DI
9984 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9985 (match_operand:SI 2 "general_operand" "g"))))
9986 (clobber (reg:CC FLAGS_REG))]
9987 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9988 "xor{l}\t{%2, %k0|%k0, %2}"
9989 [(set_attr "type" "alu")
9990 (set_attr "mode" "SI")])
9991
9992 (define_insn "*xorsi_1_zext_imm"
9993 [(set (match_operand:DI 0 "register_operand" "=r")
9994 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9995 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9996 (clobber (reg:CC FLAGS_REG))]
9997 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9998 "xor{l}\t{%2, %k0|%k0, %2}"
9999 [(set_attr "type" "alu")
10000 (set_attr "mode" "SI")])
10001
10002 (define_insn "*xorsi_2"
10003 [(set (reg FLAGS_REG)
10004 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10005 (match_operand:SI 2 "general_operand" "g,ri"))
10006 (const_int 0)))
10007 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10008 (xor:SI (match_dup 1) (match_dup 2)))]
10009 "ix86_match_ccmode (insn, CCNOmode)
10010 && ix86_binary_operator_ok (XOR, SImode, operands)"
10011 "xor{l}\t{%2, %0|%0, %2}"
10012 [(set_attr "type" "alu")
10013 (set_attr "mode" "SI")])
10014
10015 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10016 ;; ??? Special case for immediate operand is missing - it is tricky.
10017 (define_insn "*xorsi_2_zext"
10018 [(set (reg FLAGS_REG)
10019 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10020 (match_operand:SI 2 "general_operand" "g"))
10021 (const_int 0)))
10022 (set (match_operand:DI 0 "register_operand" "=r")
10023 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10024 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10025 && ix86_binary_operator_ok (XOR, SImode, operands)"
10026 "xor{l}\t{%2, %k0|%k0, %2}"
10027 [(set_attr "type" "alu")
10028 (set_attr "mode" "SI")])
10029
10030 (define_insn "*xorsi_2_zext_imm"
10031 [(set (reg FLAGS_REG)
10032 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10033 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10034 (const_int 0)))
10035 (set (match_operand:DI 0 "register_operand" "=r")
10036 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10037 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10038 && ix86_binary_operator_ok (XOR, SImode, operands)"
10039 "xor{l}\t{%2, %k0|%k0, %2}"
10040 [(set_attr "type" "alu")
10041 (set_attr "mode" "SI")])
10042
10043 (define_insn "*xorsi_3"
10044 [(set (reg FLAGS_REG)
10045 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10046 (match_operand:SI 2 "general_operand" "g"))
10047 (const_int 0)))
10048 (clobber (match_scratch:SI 0 "=r"))]
10049 "ix86_match_ccmode (insn, CCNOmode)
10050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10051 "xor{l}\t{%2, %0|%0, %2}"
10052 [(set_attr "type" "alu")
10053 (set_attr "mode" "SI")])
10054
10055 (define_expand "xorhi3"
10056 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10057 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10058 (match_operand:HI 2 "general_operand" "")))]
10059 "TARGET_HIMODE_MATH"
10060 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10061
10062 (define_insn "*xorhi_1"
10063 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10064 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10065 (match_operand:HI 2 "general_operand" "rmn,rn")))
10066 (clobber (reg:CC FLAGS_REG))]
10067 "ix86_binary_operator_ok (XOR, HImode, operands)"
10068 "xor{w}\t{%2, %0|%0, %2}"
10069 [(set_attr "type" "alu")
10070 (set_attr "mode" "HI")])
10071
10072 (define_insn "*xorhi_2"
10073 [(set (reg FLAGS_REG)
10074 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10075 (match_operand:HI 2 "general_operand" "rmn,rn"))
10076 (const_int 0)))
10077 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10078 (xor:HI (match_dup 1) (match_dup 2)))]
10079 "ix86_match_ccmode (insn, CCNOmode)
10080 && ix86_binary_operator_ok (XOR, HImode, operands)"
10081 "xor{w}\t{%2, %0|%0, %2}"
10082 [(set_attr "type" "alu")
10083 (set_attr "mode" "HI")])
10084
10085 (define_insn "*xorhi_3"
10086 [(set (reg FLAGS_REG)
10087 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10088 (match_operand:HI 2 "general_operand" "rmn"))
10089 (const_int 0)))
10090 (clobber (match_scratch:HI 0 "=r"))]
10091 "ix86_match_ccmode (insn, CCNOmode)
10092 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10093 "xor{w}\t{%2, %0|%0, %2}"
10094 [(set_attr "type" "alu")
10095 (set_attr "mode" "HI")])
10096
10097 (define_expand "xorqi3"
10098 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10099 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10100 (match_operand:QI 2 "general_operand" "")))]
10101 "TARGET_QIMODE_MATH"
10102 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10103
10104 ;; %%% Potential partial reg stall on alternative 2. What to do?
10105 (define_insn "*xorqi_1"
10106 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10107 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10108 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "ix86_binary_operator_ok (XOR, QImode, operands)"
10111 "@
10112 xor{b}\t{%2, %0|%0, %2}
10113 xor{b}\t{%2, %0|%0, %2}
10114 xor{l}\t{%k2, %k0|%k0, %k2}"
10115 [(set_attr "type" "alu")
10116 (set_attr "mode" "QI,QI,SI")])
10117
10118 (define_insn "*xorqi_1_slp"
10119 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10120 (xor:QI (match_dup 0)
10121 (match_operand:QI 1 "general_operand" "qn,qmn")))
10122 (clobber (reg:CC FLAGS_REG))]
10123 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10124 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10125 "xor{b}\t{%1, %0|%0, %1}"
10126 [(set_attr "type" "alu1")
10127 (set_attr "mode" "QI")])
10128
10129 (define_insn "*xorqi_ext_0"
10130 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10131 (const_int 8)
10132 (const_int 8))
10133 (xor:SI
10134 (zero_extract:SI
10135 (match_operand 1 "ext_register_operand" "0")
10136 (const_int 8)
10137 (const_int 8))
10138 (match_operand 2 "const_int_operand" "n")))
10139 (clobber (reg:CC FLAGS_REG))]
10140 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10141 "xor{b}\t{%2, %h0|%h0, %2}"
10142 [(set_attr "type" "alu")
10143 (set_attr "length_immediate" "1")
10144 (set_attr "mode" "QI")])
10145
10146 (define_insn "*xorqi_ext_1"
10147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10148 (const_int 8)
10149 (const_int 8))
10150 (xor:SI
10151 (zero_extract:SI
10152 (match_operand 1 "ext_register_operand" "0")
10153 (const_int 8)
10154 (const_int 8))
10155 (zero_extend:SI
10156 (match_operand:QI 2 "general_operand" "Qm"))))
10157 (clobber (reg:CC FLAGS_REG))]
10158 "!TARGET_64BIT
10159 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10160 "xor{b}\t{%2, %h0|%h0, %2}"
10161 [(set_attr "type" "alu")
10162 (set_attr "length_immediate" "0")
10163 (set_attr "mode" "QI")])
10164
10165 (define_insn "*xorqi_ext_1_rex64"
10166 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10167 (const_int 8)
10168 (const_int 8))
10169 (xor:SI
10170 (zero_extract:SI
10171 (match_operand 1 "ext_register_operand" "0")
10172 (const_int 8)
10173 (const_int 8))
10174 (zero_extend:SI
10175 (match_operand 2 "ext_register_operand" "Q"))))
10176 (clobber (reg:CC FLAGS_REG))]
10177 "TARGET_64BIT
10178 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10179 "xor{b}\t{%2, %h0|%h0, %2}"
10180 [(set_attr "type" "alu")
10181 (set_attr "length_immediate" "0")
10182 (set_attr "mode" "QI")])
10183
10184 (define_insn "*xorqi_ext_2"
10185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10186 (const_int 8)
10187 (const_int 8))
10188 (xor:SI
10189 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10190 (const_int 8)
10191 (const_int 8))
10192 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10193 (const_int 8)
10194 (const_int 8))))
10195 (clobber (reg:CC FLAGS_REG))]
10196 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10197 "xor{b}\t{%h2, %h0|%h0, %h2}"
10198 [(set_attr "type" "alu")
10199 (set_attr "length_immediate" "0")
10200 (set_attr "mode" "QI")])
10201
10202 (define_insn "*xorqi_cc_1"
10203 [(set (reg FLAGS_REG)
10204 (compare
10205 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10206 (match_operand:QI 2 "general_operand" "qmn,qn"))
10207 (const_int 0)))
10208 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10209 (xor:QI (match_dup 1) (match_dup 2)))]
10210 "ix86_match_ccmode (insn, CCNOmode)
10211 && ix86_binary_operator_ok (XOR, QImode, operands)"
10212 "xor{b}\t{%2, %0|%0, %2}"
10213 [(set_attr "type" "alu")
10214 (set_attr "mode" "QI")])
10215
10216 (define_insn "*xorqi_2_slp"
10217 [(set (reg FLAGS_REG)
10218 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10219 (match_operand:QI 1 "general_operand" "qmn,qn"))
10220 (const_int 0)))
10221 (set (strict_low_part (match_dup 0))
10222 (xor:QI (match_dup 0) (match_dup 1)))]
10223 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10224 && ix86_match_ccmode (insn, CCNOmode)
10225 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10226 "xor{b}\t{%1, %0|%0, %1}"
10227 [(set_attr "type" "alu1")
10228 (set_attr "mode" "QI")])
10229
10230 (define_insn "*xorqi_cc_2"
10231 [(set (reg FLAGS_REG)
10232 (compare
10233 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10234 (match_operand:QI 2 "general_operand" "qmn"))
10235 (const_int 0)))
10236 (clobber (match_scratch:QI 0 "=q"))]
10237 "ix86_match_ccmode (insn, CCNOmode)
10238 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10239 "xor{b}\t{%2, %0|%0, %2}"
10240 [(set_attr "type" "alu")
10241 (set_attr "mode" "QI")])
10242
10243 (define_insn "*xorqi_cc_ext_1"
10244 [(set (reg FLAGS_REG)
10245 (compare
10246 (xor:SI
10247 (zero_extract:SI
10248 (match_operand 1 "ext_register_operand" "0")
10249 (const_int 8)
10250 (const_int 8))
10251 (match_operand:QI 2 "general_operand" "qmn"))
10252 (const_int 0)))
10253 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10254 (const_int 8)
10255 (const_int 8))
10256 (xor:SI
10257 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10258 (match_dup 2)))]
10259 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10260 "xor{b}\t{%2, %h0|%h0, %2}"
10261 [(set_attr "type" "alu")
10262 (set_attr "mode" "QI")])
10263
10264 (define_insn "*xorqi_cc_ext_1_rex64"
10265 [(set (reg FLAGS_REG)
10266 (compare
10267 (xor:SI
10268 (zero_extract:SI
10269 (match_operand 1 "ext_register_operand" "0")
10270 (const_int 8)
10271 (const_int 8))
10272 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10273 (const_int 0)))
10274 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10275 (const_int 8)
10276 (const_int 8))
10277 (xor:SI
10278 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10279 (match_dup 2)))]
10280 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10281 "xor{b}\t{%2, %h0|%h0, %2}"
10282 [(set_attr "type" "alu")
10283 (set_attr "mode" "QI")])
10284
10285 (define_expand "xorqi_cc_ext_1"
10286 [(parallel [
10287 (set (reg:CCNO FLAGS_REG)
10288 (compare:CCNO
10289 (xor:SI
10290 (zero_extract:SI
10291 (match_operand 1 "ext_register_operand" "")
10292 (const_int 8)
10293 (const_int 8))
10294 (match_operand:QI 2 "general_operand" ""))
10295 (const_int 0)))
10296 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10297 (const_int 8)
10298 (const_int 8))
10299 (xor:SI
10300 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10301 (match_dup 2)))])]
10302 ""
10303 "")
10304
10305 (define_split
10306 [(set (match_operand 0 "register_operand" "")
10307 (xor (match_operand 1 "register_operand" "")
10308 (match_operand 2 "const_int_operand" "")))
10309 (clobber (reg:CC FLAGS_REG))]
10310 "reload_completed
10311 && QI_REG_P (operands[0])
10312 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10313 && !(INTVAL (operands[2]) & ~(255 << 8))
10314 && GET_MODE (operands[0]) != QImode"
10315 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10316 (xor:SI (zero_extract:SI (match_dup 1)
10317 (const_int 8) (const_int 8))
10318 (match_dup 2)))
10319 (clobber (reg:CC FLAGS_REG))])]
10320 "operands[0] = gen_lowpart (SImode, operands[0]);
10321 operands[1] = gen_lowpart (SImode, operands[1]);
10322 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10323
10324 ;; Since XOR can be encoded with sign extended immediate, this is only
10325 ;; profitable when 7th bit is set.
10326 (define_split
10327 [(set (match_operand 0 "register_operand" "")
10328 (xor (match_operand 1 "general_operand" "")
10329 (match_operand 2 "const_int_operand" "")))
10330 (clobber (reg:CC FLAGS_REG))]
10331 "reload_completed
10332 && ANY_QI_REG_P (operands[0])
10333 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10334 && !(INTVAL (operands[2]) & ~255)
10335 && (INTVAL (operands[2]) & 128)
10336 && GET_MODE (operands[0]) != QImode"
10337 [(parallel [(set (strict_low_part (match_dup 0))
10338 (xor:QI (match_dup 1)
10339 (match_dup 2)))
10340 (clobber (reg:CC FLAGS_REG))])]
10341 "operands[0] = gen_lowpart (QImode, operands[0]);
10342 operands[1] = gen_lowpart (QImode, operands[1]);
10343 operands[2] = gen_lowpart (QImode, operands[2]);")
10344 \f
10345 ;; Negation instructions
10346
10347 (define_expand "negti2"
10348 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10349 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10350 "TARGET_64BIT"
10351 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10352
10353 (define_insn "*negti2_1"
10354 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10355 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10356 (clobber (reg:CC FLAGS_REG))]
10357 "TARGET_64BIT
10358 && ix86_unary_operator_ok (NEG, TImode, operands)"
10359 "#")
10360
10361 (define_split
10362 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10363 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "TARGET_64BIT && reload_completed"
10366 [(parallel
10367 [(set (reg:CCZ FLAGS_REG)
10368 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10369 (set (match_dup 0) (neg:DI (match_dup 1)))])
10370 (parallel
10371 [(set (match_dup 2)
10372 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10373 (match_dup 3))
10374 (const_int 0)))
10375 (clobber (reg:CC FLAGS_REG))])
10376 (parallel
10377 [(set (match_dup 2)
10378 (neg:DI (match_dup 2)))
10379 (clobber (reg:CC FLAGS_REG))])]
10380 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10381
10382 (define_expand "negdi2"
10383 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10384 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10385 ""
10386 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10387
10388 (define_insn "*negdi2_1"
10389 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10390 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10391 (clobber (reg:CC FLAGS_REG))]
10392 "!TARGET_64BIT
10393 && ix86_unary_operator_ok (NEG, DImode, operands)"
10394 "#")
10395
10396 (define_split
10397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10398 (neg:DI (match_operand:DI 1 "general_operand" "")))
10399 (clobber (reg:CC FLAGS_REG))]
10400 "!TARGET_64BIT && reload_completed"
10401 [(parallel
10402 [(set (reg:CCZ FLAGS_REG)
10403 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10404 (set (match_dup 0) (neg:SI (match_dup 1)))])
10405 (parallel
10406 [(set (match_dup 2)
10407 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10408 (match_dup 3))
10409 (const_int 0)))
10410 (clobber (reg:CC FLAGS_REG))])
10411 (parallel
10412 [(set (match_dup 2)
10413 (neg:SI (match_dup 2)))
10414 (clobber (reg:CC FLAGS_REG))])]
10415 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10416
10417 (define_insn "*negdi2_1_rex64"
10418 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10419 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10422 "neg{q}\t%0"
10423 [(set_attr "type" "negnot")
10424 (set_attr "mode" "DI")])
10425
10426 ;; The problem with neg is that it does not perform (compare x 0),
10427 ;; it really performs (compare 0 x), which leaves us with the zero
10428 ;; flag being the only useful item.
10429
10430 (define_insn "*negdi2_cmpz_rex64"
10431 [(set (reg:CCZ FLAGS_REG)
10432 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10433 (const_int 0)))
10434 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10435 (neg:DI (match_dup 1)))]
10436 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10437 "neg{q}\t%0"
10438 [(set_attr "type" "negnot")
10439 (set_attr "mode" "DI")])
10440
10441
10442 (define_expand "negsi2"
10443 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10444 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10445 ""
10446 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10447
10448 (define_insn "*negsi2_1"
10449 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10450 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10451 (clobber (reg:CC FLAGS_REG))]
10452 "ix86_unary_operator_ok (NEG, SImode, operands)"
10453 "neg{l}\t%0"
10454 [(set_attr "type" "negnot")
10455 (set_attr "mode" "SI")])
10456
10457 ;; Combine is quite creative about this pattern.
10458 (define_insn "*negsi2_1_zext"
10459 [(set (match_operand:DI 0 "register_operand" "=r")
10460 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10461 (const_int 32)))
10462 (const_int 32)))
10463 (clobber (reg:CC FLAGS_REG))]
10464 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10465 "neg{l}\t%k0"
10466 [(set_attr "type" "negnot")
10467 (set_attr "mode" "SI")])
10468
10469 ;; The problem with neg is that it does not perform (compare x 0),
10470 ;; it really performs (compare 0 x), which leaves us with the zero
10471 ;; flag being the only useful item.
10472
10473 (define_insn "*negsi2_cmpz"
10474 [(set (reg:CCZ FLAGS_REG)
10475 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10476 (const_int 0)))
10477 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10478 (neg:SI (match_dup 1)))]
10479 "ix86_unary_operator_ok (NEG, SImode, operands)"
10480 "neg{l}\t%0"
10481 [(set_attr "type" "negnot")
10482 (set_attr "mode" "SI")])
10483
10484 (define_insn "*negsi2_cmpz_zext"
10485 [(set (reg:CCZ FLAGS_REG)
10486 (compare:CCZ (lshiftrt:DI
10487 (neg:DI (ashift:DI
10488 (match_operand:DI 1 "register_operand" "0")
10489 (const_int 32)))
10490 (const_int 32))
10491 (const_int 0)))
10492 (set (match_operand:DI 0 "register_operand" "=r")
10493 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10494 (const_int 32)))
10495 (const_int 32)))]
10496 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10497 "neg{l}\t%k0"
10498 [(set_attr "type" "negnot")
10499 (set_attr "mode" "SI")])
10500
10501 (define_expand "neghi2"
10502 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10504 "TARGET_HIMODE_MATH"
10505 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10506
10507 (define_insn "*neghi2_1"
10508 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10509 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "ix86_unary_operator_ok (NEG, HImode, operands)"
10512 "neg{w}\t%0"
10513 [(set_attr "type" "negnot")
10514 (set_attr "mode" "HI")])
10515
10516 (define_insn "*neghi2_cmpz"
10517 [(set (reg:CCZ FLAGS_REG)
10518 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10519 (const_int 0)))
10520 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10521 (neg:HI (match_dup 1)))]
10522 "ix86_unary_operator_ok (NEG, HImode, operands)"
10523 "neg{w}\t%0"
10524 [(set_attr "type" "negnot")
10525 (set_attr "mode" "HI")])
10526
10527 (define_expand "negqi2"
10528 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10529 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10530 "TARGET_QIMODE_MATH"
10531 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10532
10533 (define_insn "*negqi2_1"
10534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10535 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10536 (clobber (reg:CC FLAGS_REG))]
10537 "ix86_unary_operator_ok (NEG, QImode, operands)"
10538 "neg{b}\t%0"
10539 [(set_attr "type" "negnot")
10540 (set_attr "mode" "QI")])
10541
10542 (define_insn "*negqi2_cmpz"
10543 [(set (reg:CCZ FLAGS_REG)
10544 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10545 (const_int 0)))
10546 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10547 (neg:QI (match_dup 1)))]
10548 "ix86_unary_operator_ok (NEG, QImode, operands)"
10549 "neg{b}\t%0"
10550 [(set_attr "type" "negnot")
10551 (set_attr "mode" "QI")])
10552
10553 ;; Changing of sign for FP values is doable using integer unit too.
10554
10555 (define_expand "<code><mode>2"
10556 [(set (match_operand:X87MODEF 0 "register_operand" "")
10557 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10558 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10559 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10560
10561 (define_insn "*absneg<mode>2_mixed"
10562 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10563 (match_operator:MODEF 3 "absneg_operator"
10564 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10565 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10566 (clobber (reg:CC FLAGS_REG))]
10567 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10568 "#")
10569
10570 (define_insn "*absneg<mode>2_sse"
10571 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10572 (match_operator:MODEF 3 "absneg_operator"
10573 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10574 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10575 (clobber (reg:CC FLAGS_REG))]
10576 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10577 "#")
10578
10579 (define_insn "*absneg<mode>2_i387"
10580 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10581 (match_operator:X87MODEF 3 "absneg_operator"
10582 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10583 (use (match_operand 2 "" ""))
10584 (clobber (reg:CC FLAGS_REG))]
10585 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10586 "#")
10587
10588 (define_expand "<code>tf2"
10589 [(set (match_operand:TF 0 "register_operand" "")
10590 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10591 "TARGET_SSE2"
10592 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10593
10594 (define_insn "*absnegtf2_sse"
10595 [(set (match_operand:TF 0 "register_operand" "=x,x")
10596 (match_operator:TF 3 "absneg_operator"
10597 [(match_operand:TF 1 "register_operand" "0,x")]))
10598 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10599 (clobber (reg:CC FLAGS_REG))]
10600 "TARGET_SSE2"
10601 "#")
10602
10603 ;; Splitters for fp abs and neg.
10604
10605 (define_split
10606 [(set (match_operand 0 "fp_register_operand" "")
10607 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10608 (use (match_operand 2 "" ""))
10609 (clobber (reg:CC FLAGS_REG))]
10610 "reload_completed"
10611 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10612
10613 (define_split
10614 [(set (match_operand 0 "register_operand" "")
10615 (match_operator 3 "absneg_operator"
10616 [(match_operand 1 "register_operand" "")]))
10617 (use (match_operand 2 "nonimmediate_operand" ""))
10618 (clobber (reg:CC FLAGS_REG))]
10619 "reload_completed && SSE_REG_P (operands[0])"
10620 [(set (match_dup 0) (match_dup 3))]
10621 {
10622 enum machine_mode mode = GET_MODE (operands[0]);
10623 enum machine_mode vmode = GET_MODE (operands[2]);
10624 rtx tmp;
10625
10626 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10627 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10628 if (operands_match_p (operands[0], operands[2]))
10629 {
10630 tmp = operands[1];
10631 operands[1] = operands[2];
10632 operands[2] = tmp;
10633 }
10634 if (GET_CODE (operands[3]) == ABS)
10635 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10636 else
10637 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10638 operands[3] = tmp;
10639 })
10640
10641 (define_split
10642 [(set (match_operand:SF 0 "register_operand" "")
10643 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10644 (use (match_operand:V4SF 2 "" ""))
10645 (clobber (reg:CC FLAGS_REG))]
10646 "reload_completed"
10647 [(parallel [(set (match_dup 0) (match_dup 1))
10648 (clobber (reg:CC FLAGS_REG))])]
10649 {
10650 rtx tmp;
10651 operands[0] = gen_lowpart (SImode, operands[0]);
10652 if (GET_CODE (operands[1]) == ABS)
10653 {
10654 tmp = gen_int_mode (0x7fffffff, SImode);
10655 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10656 }
10657 else
10658 {
10659 tmp = gen_int_mode (0x80000000, SImode);
10660 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10661 }
10662 operands[1] = tmp;
10663 })
10664
10665 (define_split
10666 [(set (match_operand:DF 0 "register_operand" "")
10667 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10668 (use (match_operand 2 "" ""))
10669 (clobber (reg:CC FLAGS_REG))]
10670 "reload_completed"
10671 [(parallel [(set (match_dup 0) (match_dup 1))
10672 (clobber (reg:CC FLAGS_REG))])]
10673 {
10674 rtx tmp;
10675 if (TARGET_64BIT)
10676 {
10677 tmp = gen_lowpart (DImode, operands[0]);
10678 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10679 operands[0] = tmp;
10680
10681 if (GET_CODE (operands[1]) == ABS)
10682 tmp = const0_rtx;
10683 else
10684 tmp = gen_rtx_NOT (DImode, tmp);
10685 }
10686 else
10687 {
10688 operands[0] = gen_highpart (SImode, operands[0]);
10689 if (GET_CODE (operands[1]) == ABS)
10690 {
10691 tmp = gen_int_mode (0x7fffffff, SImode);
10692 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10693 }
10694 else
10695 {
10696 tmp = gen_int_mode (0x80000000, SImode);
10697 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10698 }
10699 }
10700 operands[1] = tmp;
10701 })
10702
10703 (define_split
10704 [(set (match_operand:XF 0 "register_operand" "")
10705 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10706 (use (match_operand 2 "" ""))
10707 (clobber (reg:CC FLAGS_REG))]
10708 "reload_completed"
10709 [(parallel [(set (match_dup 0) (match_dup 1))
10710 (clobber (reg:CC FLAGS_REG))])]
10711 {
10712 rtx tmp;
10713 operands[0] = gen_rtx_REG (SImode,
10714 true_regnum (operands[0])
10715 + (TARGET_64BIT ? 1 : 2));
10716 if (GET_CODE (operands[1]) == ABS)
10717 {
10718 tmp = GEN_INT (0x7fff);
10719 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10720 }
10721 else
10722 {
10723 tmp = GEN_INT (0x8000);
10724 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10725 }
10726 operands[1] = tmp;
10727 })
10728
10729 ;; Conditionalize these after reload. If they match before reload, we
10730 ;; lose the clobber and ability to use integer instructions.
10731
10732 (define_insn "*<code><mode>2_1"
10733 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10734 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10735 "TARGET_80387
10736 && (reload_completed
10737 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10738 "f<absnegprefix>"
10739 [(set_attr "type" "fsgn")
10740 (set_attr "mode" "<MODE>")])
10741
10742 (define_insn "*<code>extendsfdf2"
10743 [(set (match_operand:DF 0 "register_operand" "=f")
10744 (absneg:DF (float_extend:DF
10745 (match_operand:SF 1 "register_operand" "0"))))]
10746 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10747 "f<absnegprefix>"
10748 [(set_attr "type" "fsgn")
10749 (set_attr "mode" "DF")])
10750
10751 (define_insn "*<code>extendsfxf2"
10752 [(set (match_operand:XF 0 "register_operand" "=f")
10753 (absneg:XF (float_extend:XF
10754 (match_operand:SF 1 "register_operand" "0"))))]
10755 "TARGET_80387"
10756 "f<absnegprefix>"
10757 [(set_attr "type" "fsgn")
10758 (set_attr "mode" "XF")])
10759
10760 (define_insn "*<code>extenddfxf2"
10761 [(set (match_operand:XF 0 "register_operand" "=f")
10762 (absneg:XF (float_extend:XF
10763 (match_operand:DF 1 "register_operand" "0"))))]
10764 "TARGET_80387"
10765 "f<absnegprefix>"
10766 [(set_attr "type" "fsgn")
10767 (set_attr "mode" "XF")])
10768
10769 ;; Copysign instructions
10770
10771 (define_mode_iterator CSGNMODE [SF DF TF])
10772 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10773
10774 (define_expand "copysign<mode>3"
10775 [(match_operand:CSGNMODE 0 "register_operand" "")
10776 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10777 (match_operand:CSGNMODE 2 "register_operand" "")]
10778 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10779 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10780 {
10781 ix86_expand_copysign (operands);
10782 DONE;
10783 })
10784
10785 (define_insn_and_split "copysign<mode>3_const"
10786 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10787 (unspec:CSGNMODE
10788 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10789 (match_operand:CSGNMODE 2 "register_operand" "0")
10790 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10791 UNSPEC_COPYSIGN))]
10792 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10793 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10794 "#"
10795 "&& reload_completed"
10796 [(const_int 0)]
10797 {
10798 ix86_split_copysign_const (operands);
10799 DONE;
10800 })
10801
10802 (define_insn "copysign<mode>3_var"
10803 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10804 (unspec:CSGNMODE
10805 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10806 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10807 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10808 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10809 UNSPEC_COPYSIGN))
10810 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10811 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10812 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10813 "#")
10814
10815 (define_split
10816 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10817 (unspec:CSGNMODE
10818 [(match_operand:CSGNMODE 2 "register_operand" "")
10819 (match_operand:CSGNMODE 3 "register_operand" "")
10820 (match_operand:<CSGNVMODE> 4 "" "")
10821 (match_operand:<CSGNVMODE> 5 "" "")]
10822 UNSPEC_COPYSIGN))
10823 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10824 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10825 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10826 && reload_completed"
10827 [(const_int 0)]
10828 {
10829 ix86_split_copysign_var (operands);
10830 DONE;
10831 })
10832 \f
10833 ;; One complement instructions
10834
10835 (define_expand "one_cmpldi2"
10836 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10837 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10838 "TARGET_64BIT"
10839 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10840
10841 (define_insn "*one_cmpldi2_1_rex64"
10842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10843 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10844 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10845 "not{q}\t%0"
10846 [(set_attr "type" "negnot")
10847 (set_attr "mode" "DI")])
10848
10849 (define_insn "*one_cmpldi2_2_rex64"
10850 [(set (reg FLAGS_REG)
10851 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10852 (const_int 0)))
10853 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10854 (not:DI (match_dup 1)))]
10855 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10856 && ix86_unary_operator_ok (NOT, DImode, operands)"
10857 "#"
10858 [(set_attr "type" "alu1")
10859 (set_attr "mode" "DI")])
10860
10861 (define_split
10862 [(set (match_operand 0 "flags_reg_operand" "")
10863 (match_operator 2 "compare_operator"
10864 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10865 (const_int 0)]))
10866 (set (match_operand:DI 1 "nonimmediate_operand" "")
10867 (not:DI (match_dup 3)))]
10868 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10869 [(parallel [(set (match_dup 0)
10870 (match_op_dup 2
10871 [(xor:DI (match_dup 3) (const_int -1))
10872 (const_int 0)]))
10873 (set (match_dup 1)
10874 (xor:DI (match_dup 3) (const_int -1)))])]
10875 "")
10876
10877 (define_expand "one_cmplsi2"
10878 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10879 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10880 ""
10881 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10882
10883 (define_insn "*one_cmplsi2_1"
10884 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10885 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10886 "ix86_unary_operator_ok (NOT, SImode, operands)"
10887 "not{l}\t%0"
10888 [(set_attr "type" "negnot")
10889 (set_attr "mode" "SI")])
10890
10891 ;; ??? Currently never generated - xor is used instead.
10892 (define_insn "*one_cmplsi2_1_zext"
10893 [(set (match_operand:DI 0 "register_operand" "=r")
10894 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10895 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10896 "not{l}\t%k0"
10897 [(set_attr "type" "negnot")
10898 (set_attr "mode" "SI")])
10899
10900 (define_insn "*one_cmplsi2_2"
10901 [(set (reg FLAGS_REG)
10902 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10903 (const_int 0)))
10904 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10905 (not:SI (match_dup 1)))]
10906 "ix86_match_ccmode (insn, CCNOmode)
10907 && ix86_unary_operator_ok (NOT, SImode, operands)"
10908 "#"
10909 [(set_attr "type" "alu1")
10910 (set_attr "mode" "SI")])
10911
10912 (define_split
10913 [(set (match_operand 0 "flags_reg_operand" "")
10914 (match_operator 2 "compare_operator"
10915 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10916 (const_int 0)]))
10917 (set (match_operand:SI 1 "nonimmediate_operand" "")
10918 (not:SI (match_dup 3)))]
10919 "ix86_match_ccmode (insn, CCNOmode)"
10920 [(parallel [(set (match_dup 0)
10921 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10922 (const_int 0)]))
10923 (set (match_dup 1)
10924 (xor:SI (match_dup 3) (const_int -1)))])]
10925 "")
10926
10927 ;; ??? Currently never generated - xor is used instead.
10928 (define_insn "*one_cmplsi2_2_zext"
10929 [(set (reg FLAGS_REG)
10930 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10931 (const_int 0)))
10932 (set (match_operand:DI 0 "register_operand" "=r")
10933 (zero_extend:DI (not:SI (match_dup 1))))]
10934 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10935 && ix86_unary_operator_ok (NOT, SImode, operands)"
10936 "#"
10937 [(set_attr "type" "alu1")
10938 (set_attr "mode" "SI")])
10939
10940 (define_split
10941 [(set (match_operand 0 "flags_reg_operand" "")
10942 (match_operator 2 "compare_operator"
10943 [(not:SI (match_operand:SI 3 "register_operand" ""))
10944 (const_int 0)]))
10945 (set (match_operand:DI 1 "register_operand" "")
10946 (zero_extend:DI (not:SI (match_dup 3))))]
10947 "ix86_match_ccmode (insn, CCNOmode)"
10948 [(parallel [(set (match_dup 0)
10949 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10950 (const_int 0)]))
10951 (set (match_dup 1)
10952 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10953 "")
10954
10955 (define_expand "one_cmplhi2"
10956 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10957 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10958 "TARGET_HIMODE_MATH"
10959 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10960
10961 (define_insn "*one_cmplhi2_1"
10962 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10963 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10964 "ix86_unary_operator_ok (NOT, HImode, operands)"
10965 "not{w}\t%0"
10966 [(set_attr "type" "negnot")
10967 (set_attr "mode" "HI")])
10968
10969 (define_insn "*one_cmplhi2_2"
10970 [(set (reg FLAGS_REG)
10971 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10972 (const_int 0)))
10973 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10974 (not:HI (match_dup 1)))]
10975 "ix86_match_ccmode (insn, CCNOmode)
10976 && ix86_unary_operator_ok (NEG, HImode, operands)"
10977 "#"
10978 [(set_attr "type" "alu1")
10979 (set_attr "mode" "HI")])
10980
10981 (define_split
10982 [(set (match_operand 0 "flags_reg_operand" "")
10983 (match_operator 2 "compare_operator"
10984 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10985 (const_int 0)]))
10986 (set (match_operand:HI 1 "nonimmediate_operand" "")
10987 (not:HI (match_dup 3)))]
10988 "ix86_match_ccmode (insn, CCNOmode)"
10989 [(parallel [(set (match_dup 0)
10990 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10991 (const_int 0)]))
10992 (set (match_dup 1)
10993 (xor:HI (match_dup 3) (const_int -1)))])]
10994 "")
10995
10996 ;; %%% Potential partial reg stall on alternative 1. What to do?
10997 (define_expand "one_cmplqi2"
10998 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10999 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11000 "TARGET_QIMODE_MATH"
11001 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11002
11003 (define_insn "*one_cmplqi2_1"
11004 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11005 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11006 "ix86_unary_operator_ok (NOT, QImode, operands)"
11007 "@
11008 not{b}\t%0
11009 not{l}\t%k0"
11010 [(set_attr "type" "negnot")
11011 (set_attr "mode" "QI,SI")])
11012
11013 (define_insn "*one_cmplqi2_2"
11014 [(set (reg FLAGS_REG)
11015 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11016 (const_int 0)))
11017 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11018 (not:QI (match_dup 1)))]
11019 "ix86_match_ccmode (insn, CCNOmode)
11020 && ix86_unary_operator_ok (NOT, QImode, operands)"
11021 "#"
11022 [(set_attr "type" "alu1")
11023 (set_attr "mode" "QI")])
11024
11025 (define_split
11026 [(set (match_operand 0 "flags_reg_operand" "")
11027 (match_operator 2 "compare_operator"
11028 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11029 (const_int 0)]))
11030 (set (match_operand:QI 1 "nonimmediate_operand" "")
11031 (not:QI (match_dup 3)))]
11032 "ix86_match_ccmode (insn, CCNOmode)"
11033 [(parallel [(set (match_dup 0)
11034 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11035 (const_int 0)]))
11036 (set (match_dup 1)
11037 (xor:QI (match_dup 3) (const_int -1)))])]
11038 "")
11039 \f
11040 ;; Arithmetic shift instructions
11041
11042 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11043 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11044 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11045 ;; from the assembler input.
11046 ;;
11047 ;; This instruction shifts the target reg/mem as usual, but instead of
11048 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11049 ;; is a left shift double, bits are taken from the high order bits of
11050 ;; reg, else if the insn is a shift right double, bits are taken from the
11051 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11052 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11053 ;;
11054 ;; Since sh[lr]d does not change the `reg' operand, that is done
11055 ;; separately, making all shifts emit pairs of shift double and normal
11056 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11057 ;; support a 63 bit shift, each shift where the count is in a reg expands
11058 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11059 ;;
11060 ;; If the shift count is a constant, we need never emit more than one
11061 ;; shift pair, instead using moves and sign extension for counts greater
11062 ;; than 31.
11063
11064 (define_expand "ashlti3"
11065 [(set (match_operand:TI 0 "register_operand" "")
11066 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11067 (match_operand:QI 2 "nonmemory_operand" "")))]
11068 "TARGET_64BIT"
11069 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11070
11071 ;; This pattern must be defined before *ashlti3_1 to prevent
11072 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11073
11074 (define_insn "*avx_ashlti3"
11075 [(set (match_operand:TI 0 "register_operand" "=x")
11076 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11077 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11078 "TARGET_AVX"
11079 {
11080 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11081 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11082 }
11083 [(set_attr "type" "sseishft")
11084 (set_attr "prefix" "vex")
11085 (set_attr "mode" "TI")])
11086
11087 (define_insn "sse2_ashlti3"
11088 [(set (match_operand:TI 0 "register_operand" "=x")
11089 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11090 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11091 "TARGET_SSE2"
11092 {
11093 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11094 return "pslldq\t{%2, %0|%0, %2}";
11095 }
11096 [(set_attr "type" "sseishft")
11097 (set_attr "prefix_data16" "1")
11098 (set_attr "mode" "TI")])
11099
11100 (define_insn "*ashlti3_1"
11101 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11102 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11103 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11104 (clobber (reg:CC FLAGS_REG))]
11105 "TARGET_64BIT"
11106 "#"
11107 [(set_attr "type" "multi")])
11108
11109 (define_peephole2
11110 [(match_scratch:DI 3 "r")
11111 (parallel [(set (match_operand:TI 0 "register_operand" "")
11112 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11113 (match_operand:QI 2 "nonmemory_operand" "")))
11114 (clobber (reg:CC FLAGS_REG))])
11115 (match_dup 3)]
11116 "TARGET_64BIT"
11117 [(const_int 0)]
11118 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11119
11120 (define_split
11121 [(set (match_operand:TI 0 "register_operand" "")
11122 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11123 (match_operand:QI 2 "nonmemory_operand" "")))
11124 (clobber (reg:CC FLAGS_REG))]
11125 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11126 ? epilogue_completed : reload_completed)"
11127 [(const_int 0)]
11128 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11129
11130 (define_insn "x86_64_shld"
11131 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11132 (ior:DI (ashift:DI (match_dup 0)
11133 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11134 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11135 (minus:QI (const_int 64) (match_dup 2)))))
11136 (clobber (reg:CC FLAGS_REG))]
11137 "TARGET_64BIT"
11138 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11139 [(set_attr "type" "ishift")
11140 (set_attr "prefix_0f" "1")
11141 (set_attr "mode" "DI")
11142 (set_attr "athlon_decode" "vector")
11143 (set_attr "amdfam10_decode" "vector")])
11144
11145 (define_expand "x86_64_shift_adj_1"
11146 [(set (reg:CCZ FLAGS_REG)
11147 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11148 (const_int 64))
11149 (const_int 0)))
11150 (set (match_operand:DI 0 "register_operand" "")
11151 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11152 (match_operand:DI 1 "register_operand" "")
11153 (match_dup 0)))
11154 (set (match_dup 1)
11155 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11156 (match_operand:DI 3 "register_operand" "r")
11157 (match_dup 1)))]
11158 "TARGET_64BIT"
11159 "")
11160
11161 (define_expand "x86_64_shift_adj_2"
11162 [(use (match_operand:DI 0 "register_operand" ""))
11163 (use (match_operand:DI 1 "register_operand" ""))
11164 (use (match_operand:QI 2 "register_operand" ""))]
11165 "TARGET_64BIT"
11166 {
11167 rtx label = gen_label_rtx ();
11168 rtx tmp;
11169
11170 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11171
11172 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11173 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11174 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11175 gen_rtx_LABEL_REF (VOIDmode, label),
11176 pc_rtx);
11177 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11178 JUMP_LABEL (tmp) = label;
11179
11180 emit_move_insn (operands[0], operands[1]);
11181 ix86_expand_clear (operands[1]);
11182
11183 emit_label (label);
11184 LABEL_NUSES (label) = 1;
11185
11186 DONE;
11187 })
11188
11189 (define_expand "ashldi3"
11190 [(set (match_operand:DI 0 "shiftdi_operand" "")
11191 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11192 (match_operand:QI 2 "nonmemory_operand" "")))]
11193 ""
11194 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11195
11196 (define_insn "*ashldi3_1_rex64"
11197 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11198 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11199 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11202 {
11203 switch (get_attr_type (insn))
11204 {
11205 case TYPE_ALU:
11206 gcc_assert (operands[2] == const1_rtx);
11207 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11208 return "add{q}\t%0, %0";
11209
11210 case TYPE_LEA:
11211 gcc_assert (CONST_INT_P (operands[2]));
11212 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11213 operands[1] = gen_rtx_MULT (DImode, operands[1],
11214 GEN_INT (1 << INTVAL (operands[2])));
11215 return "lea{q}\t{%a1, %0|%0, %a1}";
11216
11217 default:
11218 if (REG_P (operands[2]))
11219 return "sal{q}\t{%b2, %0|%0, %b2}";
11220 else if (operands[2] == const1_rtx
11221 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11222 return "sal{q}\t%0";
11223 else
11224 return "sal{q}\t{%2, %0|%0, %2}";
11225 }
11226 }
11227 [(set (attr "type")
11228 (cond [(eq_attr "alternative" "1")
11229 (const_string "lea")
11230 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11231 (const_int 0))
11232 (match_operand 0 "register_operand" ""))
11233 (match_operand 2 "const1_operand" ""))
11234 (const_string "alu")
11235 ]
11236 (const_string "ishift")))
11237 (set_attr "mode" "DI")])
11238
11239 ;; Convert lea to the lea pattern to avoid flags dependency.
11240 (define_split
11241 [(set (match_operand:DI 0 "register_operand" "")
11242 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11243 (match_operand:QI 2 "immediate_operand" "")))
11244 (clobber (reg:CC FLAGS_REG))]
11245 "TARGET_64BIT && reload_completed
11246 && true_regnum (operands[0]) != true_regnum (operands[1])"
11247 [(set (match_dup 0)
11248 (mult:DI (match_dup 1)
11249 (match_dup 2)))]
11250 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11251
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags. We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashldi3_cmp_rex64"
11256 [(set (reg FLAGS_REG)
11257 (compare
11258 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11259 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11260 (const_int 0)))
11261 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11262 (ashift:DI (match_dup 1) (match_dup 2)))]
11263 "TARGET_64BIT
11264 && (optimize_function_for_size_p (cfun)
11265 || !TARGET_PARTIAL_FLAG_REG_STALL
11266 || (operands[2] == const1_rtx
11267 && (TARGET_SHIFT1
11268 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11269 && ix86_match_ccmode (insn, CCGOCmode)
11270 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11271 {
11272 switch (get_attr_type (insn))
11273 {
11274 case TYPE_ALU:
11275 gcc_assert (operands[2] == const1_rtx);
11276 return "add{q}\t%0, %0";
11277
11278 default:
11279 if (REG_P (operands[2]))
11280 return "sal{q}\t{%b2, %0|%0, %b2}";
11281 else if (operands[2] == const1_rtx
11282 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11283 return "sal{q}\t%0";
11284 else
11285 return "sal{q}\t{%2, %0|%0, %2}";
11286 }
11287 }
11288 [(set (attr "type")
11289 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11290 (const_int 0))
11291 (match_operand 0 "register_operand" ""))
11292 (match_operand 2 "const1_operand" ""))
11293 (const_string "alu")
11294 ]
11295 (const_string "ishift")))
11296 (set_attr "mode" "DI")])
11297
11298 (define_insn "*ashldi3_cconly_rex64"
11299 [(set (reg FLAGS_REG)
11300 (compare
11301 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11302 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11303 (const_int 0)))
11304 (clobber (match_scratch:DI 0 "=r"))]
11305 "TARGET_64BIT
11306 && (optimize_function_for_size_p (cfun)
11307 || !TARGET_PARTIAL_FLAG_REG_STALL
11308 || (operands[2] == const1_rtx
11309 && (TARGET_SHIFT1
11310 || TARGET_DOUBLE_WITH_ADD)))
11311 && ix86_match_ccmode (insn, CCGOCmode)
11312 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11313 {
11314 switch (get_attr_type (insn))
11315 {
11316 case TYPE_ALU:
11317 gcc_assert (operands[2] == const1_rtx);
11318 return "add{q}\t%0, %0";
11319
11320 default:
11321 if (REG_P (operands[2]))
11322 return "sal{q}\t{%b2, %0|%0, %b2}";
11323 else if (operands[2] == const1_rtx
11324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11325 return "sal{q}\t%0";
11326 else
11327 return "sal{q}\t{%2, %0|%0, %2}";
11328 }
11329 }
11330 [(set (attr "type")
11331 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332 (const_int 0))
11333 (match_operand 0 "register_operand" ""))
11334 (match_operand 2 "const1_operand" ""))
11335 (const_string "alu")
11336 ]
11337 (const_string "ishift")))
11338 (set_attr "mode" "DI")])
11339
11340 (define_insn "*ashldi3_1"
11341 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11342 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11343 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11344 (clobber (reg:CC FLAGS_REG))]
11345 "!TARGET_64BIT"
11346 "#"
11347 [(set_attr "type" "multi")])
11348
11349 ;; By default we don't ask for a scratch register, because when DImode
11350 ;; values are manipulated, registers are already at a premium. But if
11351 ;; we have one handy, we won't turn it away.
11352 (define_peephole2
11353 [(match_scratch:SI 3 "r")
11354 (parallel [(set (match_operand:DI 0 "register_operand" "")
11355 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11356 (match_operand:QI 2 "nonmemory_operand" "")))
11357 (clobber (reg:CC FLAGS_REG))])
11358 (match_dup 3)]
11359 "!TARGET_64BIT && TARGET_CMOVE"
11360 [(const_int 0)]
11361 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11362
11363 (define_split
11364 [(set (match_operand:DI 0 "register_operand" "")
11365 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11366 (match_operand:QI 2 "nonmemory_operand" "")))
11367 (clobber (reg:CC FLAGS_REG))]
11368 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11369 ? epilogue_completed : reload_completed)"
11370 [(const_int 0)]
11371 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11372
11373 (define_insn "x86_shld"
11374 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11375 (ior:SI (ashift:SI (match_dup 0)
11376 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11377 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11378 (minus:QI (const_int 32) (match_dup 2)))))
11379 (clobber (reg:CC FLAGS_REG))]
11380 ""
11381 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11382 [(set_attr "type" "ishift")
11383 (set_attr "prefix_0f" "1")
11384 (set_attr "mode" "SI")
11385 (set_attr "pent_pair" "np")
11386 (set_attr "athlon_decode" "vector")
11387 (set_attr "amdfam10_decode" "vector")])
11388
11389 (define_expand "x86_shift_adj_1"
11390 [(set (reg:CCZ FLAGS_REG)
11391 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11392 (const_int 32))
11393 (const_int 0)))
11394 (set (match_operand:SI 0 "register_operand" "")
11395 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11396 (match_operand:SI 1 "register_operand" "")
11397 (match_dup 0)))
11398 (set (match_dup 1)
11399 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11400 (match_operand:SI 3 "register_operand" "r")
11401 (match_dup 1)))]
11402 "TARGET_CMOVE"
11403 "")
11404
11405 (define_expand "x86_shift_adj_2"
11406 [(use (match_operand:SI 0 "register_operand" ""))
11407 (use (match_operand:SI 1 "register_operand" ""))
11408 (use (match_operand:QI 2 "register_operand" ""))]
11409 ""
11410 {
11411 rtx label = gen_label_rtx ();
11412 rtx tmp;
11413
11414 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11415
11416 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11417 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11418 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11419 gen_rtx_LABEL_REF (VOIDmode, label),
11420 pc_rtx);
11421 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11422 JUMP_LABEL (tmp) = label;
11423
11424 emit_move_insn (operands[0], operands[1]);
11425 ix86_expand_clear (operands[1]);
11426
11427 emit_label (label);
11428 LABEL_NUSES (label) = 1;
11429
11430 DONE;
11431 })
11432
11433 (define_expand "ashlsi3"
11434 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11435 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11436 (match_operand:QI 2 "nonmemory_operand" "")))]
11437 ""
11438 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11439
11440 (define_insn "*ashlsi3_1"
11441 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11442 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11443 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11444 (clobber (reg:CC FLAGS_REG))]
11445 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11446 {
11447 switch (get_attr_type (insn))
11448 {
11449 case TYPE_ALU:
11450 gcc_assert (operands[2] == const1_rtx);
11451 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11452 return "add{l}\t%0, %0";
11453
11454 case TYPE_LEA:
11455 return "#";
11456
11457 default:
11458 if (REG_P (operands[2]))
11459 return "sal{l}\t{%b2, %0|%0, %b2}";
11460 else if (operands[2] == const1_rtx
11461 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11462 return "sal{l}\t%0";
11463 else
11464 return "sal{l}\t{%2, %0|%0, %2}";
11465 }
11466 }
11467 [(set (attr "type")
11468 (cond [(eq_attr "alternative" "1")
11469 (const_string "lea")
11470 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11471 (const_int 0))
11472 (match_operand 0 "register_operand" ""))
11473 (match_operand 2 "const1_operand" ""))
11474 (const_string "alu")
11475 ]
11476 (const_string "ishift")))
11477 (set_attr "mode" "SI")])
11478
11479 ;; Convert lea to the lea pattern to avoid flags dependency.
11480 (define_split
11481 [(set (match_operand 0 "register_operand" "")
11482 (ashift (match_operand 1 "index_register_operand" "")
11483 (match_operand:QI 2 "const_int_operand" "")))
11484 (clobber (reg:CC FLAGS_REG))]
11485 "reload_completed
11486 && true_regnum (operands[0]) != true_regnum (operands[1])
11487 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11488 [(const_int 0)]
11489 {
11490 rtx pat;
11491 enum machine_mode mode = GET_MODE (operands[0]);
11492
11493 if (GET_MODE_SIZE (mode) < 4)
11494 operands[0] = gen_lowpart (SImode, operands[0]);
11495 if (mode != Pmode)
11496 operands[1] = gen_lowpart (Pmode, operands[1]);
11497 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11498
11499 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11500 if (Pmode != SImode)
11501 pat = gen_rtx_SUBREG (SImode, pat, 0);
11502 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11503 DONE;
11504 })
11505
11506 ;; Rare case of shifting RSP is handled by generating move and shift
11507 (define_split
11508 [(set (match_operand 0 "register_operand" "")
11509 (ashift (match_operand 1 "register_operand" "")
11510 (match_operand:QI 2 "const_int_operand" "")))
11511 (clobber (reg:CC FLAGS_REG))]
11512 "reload_completed
11513 && true_regnum (operands[0]) != true_regnum (operands[1])"
11514 [(const_int 0)]
11515 {
11516 rtx pat, clob;
11517 emit_move_insn (operands[0], operands[1]);
11518 pat = gen_rtx_SET (VOIDmode, operands[0],
11519 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11520 operands[0], operands[2]));
11521 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11522 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11523 DONE;
11524 })
11525
11526 (define_insn "*ashlsi3_1_zext"
11527 [(set (match_operand:DI 0 "register_operand" "=r,r")
11528 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11529 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11530 (clobber (reg:CC FLAGS_REG))]
11531 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11532 {
11533 switch (get_attr_type (insn))
11534 {
11535 case TYPE_ALU:
11536 gcc_assert (operands[2] == const1_rtx);
11537 return "add{l}\t%k0, %k0";
11538
11539 case TYPE_LEA:
11540 return "#";
11541
11542 default:
11543 if (REG_P (operands[2]))
11544 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11545 else if (operands[2] == const1_rtx
11546 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11547 return "sal{l}\t%k0";
11548 else
11549 return "sal{l}\t{%2, %k0|%k0, %2}";
11550 }
11551 }
11552 [(set (attr "type")
11553 (cond [(eq_attr "alternative" "1")
11554 (const_string "lea")
11555 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11556 (const_int 0))
11557 (match_operand 2 "const1_operand" ""))
11558 (const_string "alu")
11559 ]
11560 (const_string "ishift")))
11561 (set_attr "mode" "SI")])
11562
11563 ;; Convert lea to the lea pattern to avoid flags dependency.
11564 (define_split
11565 [(set (match_operand:DI 0 "register_operand" "")
11566 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11567 (match_operand:QI 2 "const_int_operand" ""))))
11568 (clobber (reg:CC FLAGS_REG))]
11569 "TARGET_64BIT && reload_completed
11570 && true_regnum (operands[0]) != true_regnum (operands[1])"
11571 [(set (match_dup 0) (zero_extend:DI
11572 (subreg:SI (mult:SI (match_dup 1)
11573 (match_dup 2)) 0)))]
11574 {
11575 operands[1] = gen_lowpart (Pmode, operands[1]);
11576 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11577 })
11578
11579 ;; This pattern can't accept a variable shift count, since shifts by
11580 ;; zero don't affect the flags. We assume that shifts by constant
11581 ;; zero are optimized away.
11582 (define_insn "*ashlsi3_cmp"
11583 [(set (reg FLAGS_REG)
11584 (compare
11585 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11586 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11587 (const_int 0)))
11588 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11589 (ashift:SI (match_dup 1) (match_dup 2)))]
11590 "(optimize_function_for_size_p (cfun)
11591 || !TARGET_PARTIAL_FLAG_REG_STALL
11592 || (operands[2] == const1_rtx
11593 && (TARGET_SHIFT1
11594 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11595 && ix86_match_ccmode (insn, CCGOCmode)
11596 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11597 {
11598 switch (get_attr_type (insn))
11599 {
11600 case TYPE_ALU:
11601 gcc_assert (operands[2] == const1_rtx);
11602 return "add{l}\t%0, %0";
11603
11604 default:
11605 if (REG_P (operands[2]))
11606 return "sal{l}\t{%b2, %0|%0, %b2}";
11607 else if (operands[2] == const1_rtx
11608 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11609 return "sal{l}\t%0";
11610 else
11611 return "sal{l}\t{%2, %0|%0, %2}";
11612 }
11613 }
11614 [(set (attr "type")
11615 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11616 (const_int 0))
11617 (match_operand 0 "register_operand" ""))
11618 (match_operand 2 "const1_operand" ""))
11619 (const_string "alu")
11620 ]
11621 (const_string "ishift")))
11622 (set_attr "mode" "SI")])
11623
11624 (define_insn "*ashlsi3_cconly"
11625 [(set (reg FLAGS_REG)
11626 (compare
11627 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11628 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11629 (const_int 0)))
11630 (clobber (match_scratch:SI 0 "=r"))]
11631 "(optimize_function_for_size_p (cfun)
11632 || !TARGET_PARTIAL_FLAG_REG_STALL
11633 || (operands[2] == const1_rtx
11634 && (TARGET_SHIFT1
11635 || TARGET_DOUBLE_WITH_ADD)))
11636 && ix86_match_ccmode (insn, CCGOCmode)
11637 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11638 {
11639 switch (get_attr_type (insn))
11640 {
11641 case TYPE_ALU:
11642 gcc_assert (operands[2] == const1_rtx);
11643 return "add{l}\t%0, %0";
11644
11645 default:
11646 if (REG_P (operands[2]))
11647 return "sal{l}\t{%b2, %0|%0, %b2}";
11648 else if (operands[2] == const1_rtx
11649 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11650 return "sal{l}\t%0";
11651 else
11652 return "sal{l}\t{%2, %0|%0, %2}";
11653 }
11654 }
11655 [(set (attr "type")
11656 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11657 (const_int 0))
11658 (match_operand 0 "register_operand" ""))
11659 (match_operand 2 "const1_operand" ""))
11660 (const_string "alu")
11661 ]
11662 (const_string "ishift")))
11663 (set_attr "mode" "SI")])
11664
11665 (define_insn "*ashlsi3_cmp_zext"
11666 [(set (reg FLAGS_REG)
11667 (compare
11668 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11669 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11670 (const_int 0)))
11671 (set (match_operand:DI 0 "register_operand" "=r")
11672 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11673 "TARGET_64BIT
11674 && (optimize_function_for_size_p (cfun)
11675 || !TARGET_PARTIAL_FLAG_REG_STALL
11676 || (operands[2] == const1_rtx
11677 && (TARGET_SHIFT1
11678 || TARGET_DOUBLE_WITH_ADD)))
11679 && ix86_match_ccmode (insn, CCGOCmode)
11680 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11681 {
11682 switch (get_attr_type (insn))
11683 {
11684 case TYPE_ALU:
11685 gcc_assert (operands[2] == const1_rtx);
11686 return "add{l}\t%k0, %k0";
11687
11688 default:
11689 if (REG_P (operands[2]))
11690 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11691 else if (operands[2] == const1_rtx
11692 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11693 return "sal{l}\t%k0";
11694 else
11695 return "sal{l}\t{%2, %k0|%k0, %2}";
11696 }
11697 }
11698 [(set (attr "type")
11699 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700 (const_int 0))
11701 (match_operand 2 "const1_operand" ""))
11702 (const_string "alu")
11703 ]
11704 (const_string "ishift")))
11705 (set_attr "mode" "SI")])
11706
11707 (define_expand "ashlhi3"
11708 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11709 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11710 (match_operand:QI 2 "nonmemory_operand" "")))]
11711 "TARGET_HIMODE_MATH"
11712 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11713
11714 (define_insn "*ashlhi3_1_lea"
11715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11716 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11717 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11718 (clobber (reg:CC FLAGS_REG))]
11719 "!TARGET_PARTIAL_REG_STALL
11720 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11721 {
11722 switch (get_attr_type (insn))
11723 {
11724 case TYPE_LEA:
11725 return "#";
11726 case TYPE_ALU:
11727 gcc_assert (operands[2] == const1_rtx);
11728 return "add{w}\t%0, %0";
11729
11730 default:
11731 if (REG_P (operands[2]))
11732 return "sal{w}\t{%b2, %0|%0, %b2}";
11733 else if (operands[2] == const1_rtx
11734 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11735 return "sal{w}\t%0";
11736 else
11737 return "sal{w}\t{%2, %0|%0, %2}";
11738 }
11739 }
11740 [(set (attr "type")
11741 (cond [(eq_attr "alternative" "1")
11742 (const_string "lea")
11743 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11744 (const_int 0))
11745 (match_operand 0 "register_operand" ""))
11746 (match_operand 2 "const1_operand" ""))
11747 (const_string "alu")
11748 ]
11749 (const_string "ishift")))
11750 (set_attr "mode" "HI,SI")])
11751
11752 (define_insn "*ashlhi3_1"
11753 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11754 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11755 (match_operand:QI 2 "nonmemory_operand" "cI")))
11756 (clobber (reg:CC FLAGS_REG))]
11757 "TARGET_PARTIAL_REG_STALL
11758 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11759 {
11760 switch (get_attr_type (insn))
11761 {
11762 case TYPE_ALU:
11763 gcc_assert (operands[2] == const1_rtx);
11764 return "add{w}\t%0, %0";
11765
11766 default:
11767 if (REG_P (operands[2]))
11768 return "sal{w}\t{%b2, %0|%0, %b2}";
11769 else if (operands[2] == const1_rtx
11770 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11771 return "sal{w}\t%0";
11772 else
11773 return "sal{w}\t{%2, %0|%0, %2}";
11774 }
11775 }
11776 [(set (attr "type")
11777 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778 (const_int 0))
11779 (match_operand 0 "register_operand" ""))
11780 (match_operand 2 "const1_operand" ""))
11781 (const_string "alu")
11782 ]
11783 (const_string "ishift")))
11784 (set_attr "mode" "HI")])
11785
11786 ;; This pattern can't accept a variable shift count, since shifts by
11787 ;; zero don't affect the flags. We assume that shifts by constant
11788 ;; zero are optimized away.
11789 (define_insn "*ashlhi3_cmp"
11790 [(set (reg FLAGS_REG)
11791 (compare
11792 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11793 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11794 (const_int 0)))
11795 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11796 (ashift:HI (match_dup 1) (match_dup 2)))]
11797 "(optimize_function_for_size_p (cfun)
11798 || !TARGET_PARTIAL_FLAG_REG_STALL
11799 || (operands[2] == const1_rtx
11800 && (TARGET_SHIFT1
11801 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11802 && ix86_match_ccmode (insn, CCGOCmode)
11803 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11804 {
11805 switch (get_attr_type (insn))
11806 {
11807 case TYPE_ALU:
11808 gcc_assert (operands[2] == const1_rtx);
11809 return "add{w}\t%0, %0";
11810
11811 default:
11812 if (REG_P (operands[2]))
11813 return "sal{w}\t{%b2, %0|%0, %b2}";
11814 else if (operands[2] == const1_rtx
11815 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11816 return "sal{w}\t%0";
11817 else
11818 return "sal{w}\t{%2, %0|%0, %2}";
11819 }
11820 }
11821 [(set (attr "type")
11822 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11823 (const_int 0))
11824 (match_operand 0 "register_operand" ""))
11825 (match_operand 2 "const1_operand" ""))
11826 (const_string "alu")
11827 ]
11828 (const_string "ishift")))
11829 (set_attr "mode" "HI")])
11830
11831 (define_insn "*ashlhi3_cconly"
11832 [(set (reg FLAGS_REG)
11833 (compare
11834 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11835 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11836 (const_int 0)))
11837 (clobber (match_scratch:HI 0 "=r"))]
11838 "(optimize_function_for_size_p (cfun)
11839 || !TARGET_PARTIAL_FLAG_REG_STALL
11840 || (operands[2] == const1_rtx
11841 && (TARGET_SHIFT1
11842 || TARGET_DOUBLE_WITH_ADD)))
11843 && ix86_match_ccmode (insn, CCGOCmode)
11844 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11845 {
11846 switch (get_attr_type (insn))
11847 {
11848 case TYPE_ALU:
11849 gcc_assert (operands[2] == const1_rtx);
11850 return "add{w}\t%0, %0";
11851
11852 default:
11853 if (REG_P (operands[2]))
11854 return "sal{w}\t{%b2, %0|%0, %b2}";
11855 else if (operands[2] == const1_rtx
11856 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11857 return "sal{w}\t%0";
11858 else
11859 return "sal{w}\t{%2, %0|%0, %2}";
11860 }
11861 }
11862 [(set (attr "type")
11863 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11864 (const_int 0))
11865 (match_operand 0 "register_operand" ""))
11866 (match_operand 2 "const1_operand" ""))
11867 (const_string "alu")
11868 ]
11869 (const_string "ishift")))
11870 (set_attr "mode" "HI")])
11871
11872 (define_expand "ashlqi3"
11873 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11874 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11875 (match_operand:QI 2 "nonmemory_operand" "")))]
11876 "TARGET_QIMODE_MATH"
11877 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11878
11879 ;; %%% Potential partial reg stall on alternative 2. What to do?
11880
11881 (define_insn "*ashlqi3_1_lea"
11882 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11883 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11884 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11885 (clobber (reg:CC FLAGS_REG))]
11886 "!TARGET_PARTIAL_REG_STALL
11887 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11888 {
11889 switch (get_attr_type (insn))
11890 {
11891 case TYPE_LEA:
11892 return "#";
11893 case TYPE_ALU:
11894 gcc_assert (operands[2] == const1_rtx);
11895 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11896 return "add{l}\t%k0, %k0";
11897 else
11898 return "add{b}\t%0, %0";
11899
11900 default:
11901 if (REG_P (operands[2]))
11902 {
11903 if (get_attr_mode (insn) == MODE_SI)
11904 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11905 else
11906 return "sal{b}\t{%b2, %0|%0, %b2}";
11907 }
11908 else if (operands[2] == const1_rtx
11909 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11910 {
11911 if (get_attr_mode (insn) == MODE_SI)
11912 return "sal{l}\t%0";
11913 else
11914 return "sal{b}\t%0";
11915 }
11916 else
11917 {
11918 if (get_attr_mode (insn) == MODE_SI)
11919 return "sal{l}\t{%2, %k0|%k0, %2}";
11920 else
11921 return "sal{b}\t{%2, %0|%0, %2}";
11922 }
11923 }
11924 }
11925 [(set (attr "type")
11926 (cond [(eq_attr "alternative" "2")
11927 (const_string "lea")
11928 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11929 (const_int 0))
11930 (match_operand 0 "register_operand" ""))
11931 (match_operand 2 "const1_operand" ""))
11932 (const_string "alu")
11933 ]
11934 (const_string "ishift")))
11935 (set_attr "mode" "QI,SI,SI")])
11936
11937 (define_insn "*ashlqi3_1"
11938 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11939 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11940 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11941 (clobber (reg:CC FLAGS_REG))]
11942 "TARGET_PARTIAL_REG_STALL
11943 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11944 {
11945 switch (get_attr_type (insn))
11946 {
11947 case TYPE_ALU:
11948 gcc_assert (operands[2] == const1_rtx);
11949 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11950 return "add{l}\t%k0, %k0";
11951 else
11952 return "add{b}\t%0, %0";
11953
11954 default:
11955 if (REG_P (operands[2]))
11956 {
11957 if (get_attr_mode (insn) == MODE_SI)
11958 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11959 else
11960 return "sal{b}\t{%b2, %0|%0, %b2}";
11961 }
11962 else if (operands[2] == const1_rtx
11963 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11964 {
11965 if (get_attr_mode (insn) == MODE_SI)
11966 return "sal{l}\t%0";
11967 else
11968 return "sal{b}\t%0";
11969 }
11970 else
11971 {
11972 if (get_attr_mode (insn) == MODE_SI)
11973 return "sal{l}\t{%2, %k0|%k0, %2}";
11974 else
11975 return "sal{b}\t{%2, %0|%0, %2}";
11976 }
11977 }
11978 }
11979 [(set (attr "type")
11980 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11981 (const_int 0))
11982 (match_operand 0 "register_operand" ""))
11983 (match_operand 2 "const1_operand" ""))
11984 (const_string "alu")
11985 ]
11986 (const_string "ishift")))
11987 (set_attr "mode" "QI,SI")])
11988
11989 ;; This pattern can't accept a variable shift count, since shifts by
11990 ;; zero don't affect the flags. We assume that shifts by constant
11991 ;; zero are optimized away.
11992 (define_insn "*ashlqi3_cmp"
11993 [(set (reg FLAGS_REG)
11994 (compare
11995 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11996 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11997 (const_int 0)))
11998 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11999 (ashift:QI (match_dup 1) (match_dup 2)))]
12000 "(optimize_function_for_size_p (cfun)
12001 || !TARGET_PARTIAL_FLAG_REG_STALL
12002 || (operands[2] == const1_rtx
12003 && (TARGET_SHIFT1
12004 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12005 && ix86_match_ccmode (insn, CCGOCmode)
12006 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12007 {
12008 switch (get_attr_type (insn))
12009 {
12010 case TYPE_ALU:
12011 gcc_assert (operands[2] == const1_rtx);
12012 return "add{b}\t%0, %0";
12013
12014 default:
12015 if (REG_P (operands[2]))
12016 return "sal{b}\t{%b2, %0|%0, %b2}";
12017 else if (operands[2] == const1_rtx
12018 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12019 return "sal{b}\t%0";
12020 else
12021 return "sal{b}\t{%2, %0|%0, %2}";
12022 }
12023 }
12024 [(set (attr "type")
12025 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12026 (const_int 0))
12027 (match_operand 0 "register_operand" ""))
12028 (match_operand 2 "const1_operand" ""))
12029 (const_string "alu")
12030 ]
12031 (const_string "ishift")))
12032 (set_attr "mode" "QI")])
12033
12034 (define_insn "*ashlqi3_cconly"
12035 [(set (reg FLAGS_REG)
12036 (compare
12037 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12038 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12039 (const_int 0)))
12040 (clobber (match_scratch:QI 0 "=q"))]
12041 "(optimize_function_for_size_p (cfun)
12042 || !TARGET_PARTIAL_FLAG_REG_STALL
12043 || (operands[2] == const1_rtx
12044 && (TARGET_SHIFT1
12045 || TARGET_DOUBLE_WITH_ADD)))
12046 && ix86_match_ccmode (insn, CCGOCmode)
12047 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12048 {
12049 switch (get_attr_type (insn))
12050 {
12051 case TYPE_ALU:
12052 gcc_assert (operands[2] == const1_rtx);
12053 return "add{b}\t%0, %0";
12054
12055 default:
12056 if (REG_P (operands[2]))
12057 return "sal{b}\t{%b2, %0|%0, %b2}";
12058 else if (operands[2] == const1_rtx
12059 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12060 return "sal{b}\t%0";
12061 else
12062 return "sal{b}\t{%2, %0|%0, %2}";
12063 }
12064 }
12065 [(set (attr "type")
12066 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12067 (const_int 0))
12068 (match_operand 0 "register_operand" ""))
12069 (match_operand 2 "const1_operand" ""))
12070 (const_string "alu")
12071 ]
12072 (const_string "ishift")))
12073 (set_attr "mode" "QI")])
12074
12075 ;; See comment above `ashldi3' about how this works.
12076
12077 (define_expand "ashrti3"
12078 [(set (match_operand:TI 0 "register_operand" "")
12079 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12080 (match_operand:QI 2 "nonmemory_operand" "")))]
12081 "TARGET_64BIT"
12082 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12083
12084 (define_insn "*ashrti3_1"
12085 [(set (match_operand:TI 0 "register_operand" "=r")
12086 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12087 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12088 (clobber (reg:CC FLAGS_REG))]
12089 "TARGET_64BIT"
12090 "#"
12091 [(set_attr "type" "multi")])
12092
12093 (define_peephole2
12094 [(match_scratch:DI 3 "r")
12095 (parallel [(set (match_operand:TI 0 "register_operand" "")
12096 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12097 (match_operand:QI 2 "nonmemory_operand" "")))
12098 (clobber (reg:CC FLAGS_REG))])
12099 (match_dup 3)]
12100 "TARGET_64BIT"
12101 [(const_int 0)]
12102 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12103
12104 (define_split
12105 [(set (match_operand:TI 0 "register_operand" "")
12106 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12107 (match_operand:QI 2 "nonmemory_operand" "")))
12108 (clobber (reg:CC FLAGS_REG))]
12109 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12110 ? epilogue_completed : reload_completed)"
12111 [(const_int 0)]
12112 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12113
12114 (define_insn "x86_64_shrd"
12115 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12116 (ior:DI (ashiftrt:DI (match_dup 0)
12117 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12118 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12119 (minus:QI (const_int 64) (match_dup 2)))))
12120 (clobber (reg:CC FLAGS_REG))]
12121 "TARGET_64BIT"
12122 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12123 [(set_attr "type" "ishift")
12124 (set_attr "prefix_0f" "1")
12125 (set_attr "mode" "DI")
12126 (set_attr "athlon_decode" "vector")
12127 (set_attr "amdfam10_decode" "vector")])
12128
12129 (define_expand "ashrdi3"
12130 [(set (match_operand:DI 0 "shiftdi_operand" "")
12131 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12132 (match_operand:QI 2 "nonmemory_operand" "")))]
12133 ""
12134 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12135
12136 (define_expand "x86_64_shift_adj_3"
12137 [(use (match_operand:DI 0 "register_operand" ""))
12138 (use (match_operand:DI 1 "register_operand" ""))
12139 (use (match_operand:QI 2 "register_operand" ""))]
12140 ""
12141 {
12142 rtx label = gen_label_rtx ();
12143 rtx tmp;
12144
12145 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12146
12147 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12148 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12149 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12150 gen_rtx_LABEL_REF (VOIDmode, label),
12151 pc_rtx);
12152 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12153 JUMP_LABEL (tmp) = label;
12154
12155 emit_move_insn (operands[0], operands[1]);
12156 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12157
12158 emit_label (label);
12159 LABEL_NUSES (label) = 1;
12160
12161 DONE;
12162 })
12163
12164 (define_insn "ashrdi3_63_rex64"
12165 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12166 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12167 (match_operand:DI 2 "const_int_operand" "i,i")))
12168 (clobber (reg:CC FLAGS_REG))]
12169 "TARGET_64BIT && INTVAL (operands[2]) == 63
12170 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12171 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12172 "@
12173 {cqto|cqo}
12174 sar{q}\t{%2, %0|%0, %2}"
12175 [(set_attr "type" "imovx,ishift")
12176 (set_attr "prefix_0f" "0,*")
12177 (set_attr "length_immediate" "0,*")
12178 (set_attr "modrm" "0,1")
12179 (set_attr "mode" "DI")])
12180
12181 (define_insn "*ashrdi3_1_one_bit_rex64"
12182 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12183 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12184 (match_operand:QI 2 "const1_operand" "")))
12185 (clobber (reg:CC FLAGS_REG))]
12186 "TARGET_64BIT
12187 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12188 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12189 "sar{q}\t%0"
12190 [(set_attr "type" "ishift")
12191 (set (attr "length")
12192 (if_then_else (match_operand:DI 0 "register_operand" "")
12193 (const_string "2")
12194 (const_string "*")))])
12195
12196 (define_insn "*ashrdi3_1_rex64"
12197 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12198 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12199 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12202 "@
12203 sar{q}\t{%2, %0|%0, %2}
12204 sar{q}\t{%b2, %0|%0, %b2}"
12205 [(set_attr "type" "ishift")
12206 (set_attr "mode" "DI")])
12207
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags. We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12212 [(set (reg FLAGS_REG)
12213 (compare
12214 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12215 (match_operand:QI 2 "const1_operand" ""))
12216 (const_int 0)))
12217 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12218 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12219 "TARGET_64BIT
12220 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12221 && ix86_match_ccmode (insn, CCGOCmode)
12222 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12223 "sar{q}\t%0"
12224 [(set_attr "type" "ishift")
12225 (set (attr "length")
12226 (if_then_else (match_operand:DI 0 "register_operand" "")
12227 (const_string "2")
12228 (const_string "*")))])
12229
12230 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12231 [(set (reg FLAGS_REG)
12232 (compare
12233 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const1_operand" ""))
12235 (const_int 0)))
12236 (clobber (match_scratch:DI 0 "=r"))]
12237 "TARGET_64BIT
12238 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12239 && ix86_match_ccmode (insn, CCGOCmode)
12240 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12241 "sar{q}\t%0"
12242 [(set_attr "type" "ishift")
12243 (set_attr "length" "2")])
12244
12245 ;; This pattern can't accept a variable shift count, since shifts by
12246 ;; zero don't affect the flags. We assume that shifts by constant
12247 ;; zero are optimized away.
12248 (define_insn "*ashrdi3_cmp_rex64"
12249 [(set (reg FLAGS_REG)
12250 (compare
12251 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12252 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12253 (const_int 0)))
12254 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12255 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12256 "TARGET_64BIT
12257 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12258 && ix86_match_ccmode (insn, CCGOCmode)
12259 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12260 "sar{q}\t{%2, %0|%0, %2}"
12261 [(set_attr "type" "ishift")
12262 (set_attr "mode" "DI")])
12263
12264 (define_insn "*ashrdi3_cconly_rex64"
12265 [(set (reg FLAGS_REG)
12266 (compare
12267 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12268 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12269 (const_int 0)))
12270 (clobber (match_scratch:DI 0 "=r"))]
12271 "TARGET_64BIT
12272 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12273 && ix86_match_ccmode (insn, CCGOCmode)
12274 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12275 "sar{q}\t{%2, %0|%0, %2}"
12276 [(set_attr "type" "ishift")
12277 (set_attr "mode" "DI")])
12278
12279 (define_insn "*ashrdi3_1"
12280 [(set (match_operand:DI 0 "register_operand" "=r")
12281 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12282 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12283 (clobber (reg:CC FLAGS_REG))]
12284 "!TARGET_64BIT"
12285 "#"
12286 [(set_attr "type" "multi")])
12287
12288 ;; By default we don't ask for a scratch register, because when DImode
12289 ;; values are manipulated, registers are already at a premium. But if
12290 ;; we have one handy, we won't turn it away.
12291 (define_peephole2
12292 [(match_scratch:SI 3 "r")
12293 (parallel [(set (match_operand:DI 0 "register_operand" "")
12294 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12295 (match_operand:QI 2 "nonmemory_operand" "")))
12296 (clobber (reg:CC FLAGS_REG))])
12297 (match_dup 3)]
12298 "!TARGET_64BIT && TARGET_CMOVE"
12299 [(const_int 0)]
12300 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12301
12302 (define_split
12303 [(set (match_operand:DI 0 "register_operand" "")
12304 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12305 (match_operand:QI 2 "nonmemory_operand" "")))
12306 (clobber (reg:CC FLAGS_REG))]
12307 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12308 ? epilogue_completed : reload_completed)"
12309 [(const_int 0)]
12310 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12311
12312 (define_insn "x86_shrd"
12313 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12314 (ior:SI (ashiftrt:SI (match_dup 0)
12315 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12316 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12317 (minus:QI (const_int 32) (match_dup 2)))))
12318 (clobber (reg:CC FLAGS_REG))]
12319 ""
12320 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12321 [(set_attr "type" "ishift")
12322 (set_attr "prefix_0f" "1")
12323 (set_attr "pent_pair" "np")
12324 (set_attr "mode" "SI")])
12325
12326 (define_expand "x86_shift_adj_3"
12327 [(use (match_operand:SI 0 "register_operand" ""))
12328 (use (match_operand:SI 1 "register_operand" ""))
12329 (use (match_operand:QI 2 "register_operand" ""))]
12330 ""
12331 {
12332 rtx label = gen_label_rtx ();
12333 rtx tmp;
12334
12335 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12336
12337 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12338 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12339 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12340 gen_rtx_LABEL_REF (VOIDmode, label),
12341 pc_rtx);
12342 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12343 JUMP_LABEL (tmp) = label;
12344
12345 emit_move_insn (operands[0], operands[1]);
12346 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12347
12348 emit_label (label);
12349 LABEL_NUSES (label) = 1;
12350
12351 DONE;
12352 })
12353
12354 (define_expand "ashrsi3_31"
12355 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12356 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12357 (match_operand:SI 2 "const_int_operand" "i,i")))
12358 (clobber (reg:CC FLAGS_REG))])]
12359 "")
12360
12361 (define_insn "*ashrsi3_31"
12362 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12363 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12364 (match_operand:SI 2 "const_int_operand" "i,i")))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "INTVAL (operands[2]) == 31
12367 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12368 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12369 "@
12370 {cltd|cdq}
12371 sar{l}\t{%2, %0|%0, %2}"
12372 [(set_attr "type" "imovx,ishift")
12373 (set_attr "prefix_0f" "0,*")
12374 (set_attr "length_immediate" "0,*")
12375 (set_attr "modrm" "0,1")
12376 (set_attr "mode" "SI")])
12377
12378 (define_insn "*ashrsi3_31_zext"
12379 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12380 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12381 (match_operand:SI 2 "const_int_operand" "i,i"))))
12382 (clobber (reg:CC FLAGS_REG))]
12383 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12384 && INTVAL (operands[2]) == 31
12385 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12386 "@
12387 {cltd|cdq}
12388 sar{l}\t{%2, %k0|%k0, %2}"
12389 [(set_attr "type" "imovx,ishift")
12390 (set_attr "prefix_0f" "0,*")
12391 (set_attr "length_immediate" "0,*")
12392 (set_attr "modrm" "0,1")
12393 (set_attr "mode" "SI")])
12394
12395 (define_expand "ashrsi3"
12396 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12397 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12398 (match_operand:QI 2 "nonmemory_operand" "")))]
12399 ""
12400 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12401
12402 (define_insn "*ashrsi3_1_one_bit"
12403 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12404 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12405 (match_operand:QI 2 "const1_operand" "")))
12406 (clobber (reg:CC FLAGS_REG))]
12407 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12409 "sar{l}\t%0"
12410 [(set_attr "type" "ishift")
12411 (set (attr "length")
12412 (if_then_else (match_operand:SI 0 "register_operand" "")
12413 (const_string "2")
12414 (const_string "*")))])
12415
12416 (define_insn "*ashrsi3_1_one_bit_zext"
12417 [(set (match_operand:DI 0 "register_operand" "=r")
12418 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12419 (match_operand:QI 2 "const1_operand" ""))))
12420 (clobber (reg:CC FLAGS_REG))]
12421 "TARGET_64BIT
12422 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12423 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12424 "sar{l}\t%k0"
12425 [(set_attr "type" "ishift")
12426 (set_attr "length" "2")])
12427
12428 (define_insn "*ashrsi3_1"
12429 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12430 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12431 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12432 (clobber (reg:CC FLAGS_REG))]
12433 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12434 "@
12435 sar{l}\t{%2, %0|%0, %2}
12436 sar{l}\t{%b2, %0|%0, %b2}"
12437 [(set_attr "type" "ishift")
12438 (set_attr "mode" "SI")])
12439
12440 (define_insn "*ashrsi3_1_zext"
12441 [(set (match_operand:DI 0 "register_operand" "=r,r")
12442 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12443 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12444 (clobber (reg:CC FLAGS_REG))]
12445 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12446 "@
12447 sar{l}\t{%2, %k0|%k0, %2}
12448 sar{l}\t{%b2, %k0|%k0, %b2}"
12449 [(set_attr "type" "ishift")
12450 (set_attr "mode" "SI")])
12451
12452 ;; This pattern can't accept a variable shift count, since shifts by
12453 ;; zero don't affect the flags. We assume that shifts by constant
12454 ;; zero are optimized away.
12455 (define_insn "*ashrsi3_one_bit_cmp"
12456 [(set (reg FLAGS_REG)
12457 (compare
12458 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12459 (match_operand:QI 2 "const1_operand" ""))
12460 (const_int 0)))
12461 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12462 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12463 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12464 && ix86_match_ccmode (insn, CCGOCmode)
12465 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12466 "sar{l}\t%0"
12467 [(set_attr "type" "ishift")
12468 (set (attr "length")
12469 (if_then_else (match_operand:SI 0 "register_operand" "")
12470 (const_string "2")
12471 (const_string "*")))])
12472
12473 (define_insn "*ashrsi3_one_bit_cconly"
12474 [(set (reg FLAGS_REG)
12475 (compare
12476 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12477 (match_operand:QI 2 "const1_operand" ""))
12478 (const_int 0)))
12479 (clobber (match_scratch:SI 0 "=r"))]
12480 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12481 && ix86_match_ccmode (insn, CCGOCmode)
12482 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12483 "sar{l}\t%0"
12484 [(set_attr "type" "ishift")
12485 (set_attr "length" "2")])
12486
12487 (define_insn "*ashrsi3_one_bit_cmp_zext"
12488 [(set (reg FLAGS_REG)
12489 (compare
12490 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12491 (match_operand:QI 2 "const1_operand" ""))
12492 (const_int 0)))
12493 (set (match_operand:DI 0 "register_operand" "=r")
12494 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12495 "TARGET_64BIT
12496 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12497 && ix86_match_ccmode (insn, CCmode)
12498 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12499 "sar{l}\t%k0"
12500 [(set_attr "type" "ishift")
12501 (set_attr "length" "2")])
12502
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags. We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*ashrsi3_cmp"
12507 [(set (reg FLAGS_REG)
12508 (compare
12509 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12511 (const_int 0)))
12512 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12514 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12515 && ix86_match_ccmode (insn, CCGOCmode)
12516 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12517 "sar{l}\t{%2, %0|%0, %2}"
12518 [(set_attr "type" "ishift")
12519 (set_attr "mode" "SI")])
12520
12521 (define_insn "*ashrsi3_cconly"
12522 [(set (reg FLAGS_REG)
12523 (compare
12524 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12525 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12526 (const_int 0)))
12527 (clobber (match_scratch:SI 0 "=r"))]
12528 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12529 && ix86_match_ccmode (insn, CCGOCmode)
12530 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12531 "sar{l}\t{%2, %0|%0, %2}"
12532 [(set_attr "type" "ishift")
12533 (set_attr "mode" "SI")])
12534
12535 (define_insn "*ashrsi3_cmp_zext"
12536 [(set (reg FLAGS_REG)
12537 (compare
12538 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12539 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12540 (const_int 0)))
12541 (set (match_operand:DI 0 "register_operand" "=r")
12542 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12543 "TARGET_64BIT
12544 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12545 && ix86_match_ccmode (insn, CCGOCmode)
12546 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12547 "sar{l}\t{%2, %k0|%k0, %2}"
12548 [(set_attr "type" "ishift")
12549 (set_attr "mode" "SI")])
12550
12551 (define_expand "ashrhi3"
12552 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12553 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12554 (match_operand:QI 2 "nonmemory_operand" "")))]
12555 "TARGET_HIMODE_MATH"
12556 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12557
12558 (define_insn "*ashrhi3_1_one_bit"
12559 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12560 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12561 (match_operand:QI 2 "const1_operand" "")))
12562 (clobber (reg:CC FLAGS_REG))]
12563 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12564 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12565 "sar{w}\t%0"
12566 [(set_attr "type" "ishift")
12567 (set (attr "length")
12568 (if_then_else (match_operand 0 "register_operand" "")
12569 (const_string "2")
12570 (const_string "*")))])
12571
12572 (define_insn "*ashrhi3_1"
12573 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12574 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12575 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12576 (clobber (reg:CC FLAGS_REG))]
12577 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12578 "@
12579 sar{w}\t{%2, %0|%0, %2}
12580 sar{w}\t{%b2, %0|%0, %b2}"
12581 [(set_attr "type" "ishift")
12582 (set_attr "mode" "HI")])
12583
12584 ;; This pattern can't accept a variable shift count, since shifts by
12585 ;; zero don't affect the flags. We assume that shifts by constant
12586 ;; zero are optimized away.
12587 (define_insn "*ashrhi3_one_bit_cmp"
12588 [(set (reg FLAGS_REG)
12589 (compare
12590 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12591 (match_operand:QI 2 "const1_operand" ""))
12592 (const_int 0)))
12593 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12594 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12595 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12596 && ix86_match_ccmode (insn, CCGOCmode)
12597 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12598 "sar{w}\t%0"
12599 [(set_attr "type" "ishift")
12600 (set (attr "length")
12601 (if_then_else (match_operand 0 "register_operand" "")
12602 (const_string "2")
12603 (const_string "*")))])
12604
12605 (define_insn "*ashrhi3_one_bit_cconly"
12606 [(set (reg FLAGS_REG)
12607 (compare
12608 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12609 (match_operand:QI 2 "const1_operand" ""))
12610 (const_int 0)))
12611 (clobber (match_scratch:HI 0 "=r"))]
12612 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12613 && ix86_match_ccmode (insn, CCGOCmode)
12614 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12615 "sar{w}\t%0"
12616 [(set_attr "type" "ishift")
12617 (set_attr "length" "2")])
12618
12619 ;; This pattern can't accept a variable shift count, since shifts by
12620 ;; zero don't affect the flags. We assume that shifts by constant
12621 ;; zero are optimized away.
12622 (define_insn "*ashrhi3_cmp"
12623 [(set (reg FLAGS_REG)
12624 (compare
12625 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12626 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12627 (const_int 0)))
12628 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12629 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12630 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12631 && ix86_match_ccmode (insn, CCGOCmode)
12632 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12633 "sar{w}\t{%2, %0|%0, %2}"
12634 [(set_attr "type" "ishift")
12635 (set_attr "mode" "HI")])
12636
12637 (define_insn "*ashrhi3_cconly"
12638 [(set (reg FLAGS_REG)
12639 (compare
12640 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12642 (const_int 0)))
12643 (clobber (match_scratch:HI 0 "=r"))]
12644 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12645 && ix86_match_ccmode (insn, CCGOCmode)
12646 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12647 "sar{w}\t{%2, %0|%0, %2}"
12648 [(set_attr "type" "ishift")
12649 (set_attr "mode" "HI")])
12650
12651 (define_expand "ashrqi3"
12652 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12653 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12654 (match_operand:QI 2 "nonmemory_operand" "")))]
12655 "TARGET_QIMODE_MATH"
12656 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12657
12658 (define_insn "*ashrqi3_1_one_bit"
12659 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12660 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12661 (match_operand:QI 2 "const1_operand" "")))
12662 (clobber (reg:CC FLAGS_REG))]
12663 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12664 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12665 "sar{b}\t%0"
12666 [(set_attr "type" "ishift")
12667 (set (attr "length")
12668 (if_then_else (match_operand 0 "register_operand" "")
12669 (const_string "2")
12670 (const_string "*")))])
12671
12672 (define_insn "*ashrqi3_1_one_bit_slp"
12673 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12674 (ashiftrt:QI (match_dup 0)
12675 (match_operand:QI 1 "const1_operand" "")))
12676 (clobber (reg:CC FLAGS_REG))]
12677 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12678 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12679 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12680 "sar{b}\t%0"
12681 [(set_attr "type" "ishift1")
12682 (set (attr "length")
12683 (if_then_else (match_operand 0 "register_operand" "")
12684 (const_string "2")
12685 (const_string "*")))])
12686
12687 (define_insn "*ashrqi3_1"
12688 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12689 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12690 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12691 (clobber (reg:CC FLAGS_REG))]
12692 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12693 "@
12694 sar{b}\t{%2, %0|%0, %2}
12695 sar{b}\t{%b2, %0|%0, %b2}"
12696 [(set_attr "type" "ishift")
12697 (set_attr "mode" "QI")])
12698
12699 (define_insn "*ashrqi3_1_slp"
12700 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12701 (ashiftrt:QI (match_dup 0)
12702 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12703 (clobber (reg:CC FLAGS_REG))]
12704 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12705 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12706 "@
12707 sar{b}\t{%1, %0|%0, %1}
12708 sar{b}\t{%b1, %0|%0, %b1}"
12709 [(set_attr "type" "ishift1")
12710 (set_attr "mode" "QI")])
12711
12712 ;; This pattern can't accept a variable shift count, since shifts by
12713 ;; zero don't affect the flags. We assume that shifts by constant
12714 ;; zero are optimized away.
12715 (define_insn "*ashrqi3_one_bit_cmp"
12716 [(set (reg FLAGS_REG)
12717 (compare
12718 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12719 (match_operand:QI 2 "const1_operand" "I"))
12720 (const_int 0)))
12721 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12722 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12723 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12724 && ix86_match_ccmode (insn, CCGOCmode)
12725 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12726 "sar{b}\t%0"
12727 [(set_attr "type" "ishift")
12728 (set (attr "length")
12729 (if_then_else (match_operand 0 "register_operand" "")
12730 (const_string "2")
12731 (const_string "*")))])
12732
12733 (define_insn "*ashrqi3_one_bit_cconly"
12734 [(set (reg FLAGS_REG)
12735 (compare
12736 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12737 (match_operand:QI 2 "const1_operand" ""))
12738 (const_int 0)))
12739 (clobber (match_scratch:QI 0 "=q"))]
12740 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12741 && ix86_match_ccmode (insn, CCGOCmode)
12742 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12743 "sar{b}\t%0"
12744 [(set_attr "type" "ishift")
12745 (set_attr "length" "2")])
12746
12747 ;; This pattern can't accept a variable shift count, since shifts by
12748 ;; zero don't affect the flags. We assume that shifts by constant
12749 ;; zero are optimized away.
12750 (define_insn "*ashrqi3_cmp"
12751 [(set (reg FLAGS_REG)
12752 (compare
12753 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12754 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12755 (const_int 0)))
12756 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12757 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12758 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12759 && ix86_match_ccmode (insn, CCGOCmode)
12760 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12761 "sar{b}\t{%2, %0|%0, %2}"
12762 [(set_attr "type" "ishift")
12763 (set_attr "mode" "QI")])
12764
12765 (define_insn "*ashrqi3_cconly"
12766 [(set (reg FLAGS_REG)
12767 (compare
12768 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12769 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12770 (const_int 0)))
12771 (clobber (match_scratch:QI 0 "=q"))]
12772 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12773 && ix86_match_ccmode (insn, CCGOCmode)
12774 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12775 "sar{b}\t{%2, %0|%0, %2}"
12776 [(set_attr "type" "ishift")
12777 (set_attr "mode" "QI")])
12778
12779 \f
12780 ;; Logical shift instructions
12781
12782 ;; See comment above `ashldi3' about how this works.
12783
12784 (define_expand "lshrti3"
12785 [(set (match_operand:TI 0 "register_operand" "")
12786 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12787 (match_operand:QI 2 "nonmemory_operand" "")))]
12788 "TARGET_64BIT"
12789 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12790
12791 ;; This pattern must be defined before *lshrti3_1 to prevent
12792 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12793
12794 (define_insn "*avx_lshrti3"
12795 [(set (match_operand:TI 0 "register_operand" "=x")
12796 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12797 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12798 "TARGET_AVX"
12799 {
12800 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12801 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12802 }
12803 [(set_attr "type" "sseishft")
12804 (set_attr "prefix" "vex")
12805 (set_attr "mode" "TI")])
12806
12807 (define_insn "sse2_lshrti3"
12808 [(set (match_operand:TI 0 "register_operand" "=x")
12809 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12810 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12811 "TARGET_SSE2"
12812 {
12813 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12814 return "psrldq\t{%2, %0|%0, %2}";
12815 }
12816 [(set_attr "type" "sseishft")
12817 (set_attr "prefix_data16" "1")
12818 (set_attr "mode" "TI")])
12819
12820 (define_insn "*lshrti3_1"
12821 [(set (match_operand:TI 0 "register_operand" "=r")
12822 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12823 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12824 (clobber (reg:CC FLAGS_REG))]
12825 "TARGET_64BIT"
12826 "#"
12827 [(set_attr "type" "multi")])
12828
12829 (define_peephole2
12830 [(match_scratch:DI 3 "r")
12831 (parallel [(set (match_operand:TI 0 "register_operand" "")
12832 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12833 (match_operand:QI 2 "nonmemory_operand" "")))
12834 (clobber (reg:CC FLAGS_REG))])
12835 (match_dup 3)]
12836 "TARGET_64BIT"
12837 [(const_int 0)]
12838 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12839
12840 (define_split
12841 [(set (match_operand:TI 0 "register_operand" "")
12842 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12843 (match_operand:QI 2 "nonmemory_operand" "")))
12844 (clobber (reg:CC FLAGS_REG))]
12845 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12846 ? epilogue_completed : reload_completed)"
12847 [(const_int 0)]
12848 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12849
12850 (define_expand "lshrdi3"
12851 [(set (match_operand:DI 0 "shiftdi_operand" "")
12852 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12853 (match_operand:QI 2 "nonmemory_operand" "")))]
12854 ""
12855 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12856
12857 (define_insn "*lshrdi3_1_one_bit_rex64"
12858 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12859 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12860 (match_operand:QI 2 "const1_operand" "")))
12861 (clobber (reg:CC FLAGS_REG))]
12862 "TARGET_64BIT
12863 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12864 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12865 "shr{q}\t%0"
12866 [(set_attr "type" "ishift")
12867 (set (attr "length")
12868 (if_then_else (match_operand:DI 0 "register_operand" "")
12869 (const_string "2")
12870 (const_string "*")))])
12871
12872 (define_insn "*lshrdi3_1_rex64"
12873 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12874 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12875 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12876 (clobber (reg:CC FLAGS_REG))]
12877 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878 "@
12879 shr{q}\t{%2, %0|%0, %2}
12880 shr{q}\t{%b2, %0|%0, %b2}"
12881 [(set_attr "type" "ishift")
12882 (set_attr "mode" "DI")])
12883
12884 ;; This pattern can't accept a variable shift count, since shifts by
12885 ;; zero don't affect the flags. We assume that shifts by constant
12886 ;; zero are optimized away.
12887 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12888 [(set (reg FLAGS_REG)
12889 (compare
12890 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12891 (match_operand:QI 2 "const1_operand" ""))
12892 (const_int 0)))
12893 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12894 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12895 "TARGET_64BIT
12896 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12897 && ix86_match_ccmode (insn, CCGOCmode)
12898 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12899 "shr{q}\t%0"
12900 [(set_attr "type" "ishift")
12901 (set (attr "length")
12902 (if_then_else (match_operand:DI 0 "register_operand" "")
12903 (const_string "2")
12904 (const_string "*")))])
12905
12906 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12907 [(set (reg FLAGS_REG)
12908 (compare
12909 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12910 (match_operand:QI 2 "const1_operand" ""))
12911 (const_int 0)))
12912 (clobber (match_scratch:DI 0 "=r"))]
12913 "TARGET_64BIT
12914 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12915 && ix86_match_ccmode (insn, CCGOCmode)
12916 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12917 "shr{q}\t%0"
12918 [(set_attr "type" "ishift")
12919 (set_attr "length" "2")])
12920
12921 ;; This pattern can't accept a variable shift count, since shifts by
12922 ;; zero don't affect the flags. We assume that shifts by constant
12923 ;; zero are optimized away.
12924 (define_insn "*lshrdi3_cmp_rex64"
12925 [(set (reg FLAGS_REG)
12926 (compare
12927 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12928 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12929 (const_int 0)))
12930 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12931 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12932 "TARGET_64BIT
12933 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12934 && ix86_match_ccmode (insn, CCGOCmode)
12935 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12936 "shr{q}\t{%2, %0|%0, %2}"
12937 [(set_attr "type" "ishift")
12938 (set_attr "mode" "DI")])
12939
12940 (define_insn "*lshrdi3_cconly_rex64"
12941 [(set (reg FLAGS_REG)
12942 (compare
12943 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12944 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12945 (const_int 0)))
12946 (clobber (match_scratch:DI 0 "=r"))]
12947 "TARGET_64BIT
12948 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12949 && ix86_match_ccmode (insn, CCGOCmode)
12950 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951 "shr{q}\t{%2, %0|%0, %2}"
12952 [(set_attr "type" "ishift")
12953 (set_attr "mode" "DI")])
12954
12955 (define_insn "*lshrdi3_1"
12956 [(set (match_operand:DI 0 "register_operand" "=r")
12957 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12958 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "!TARGET_64BIT"
12961 "#"
12962 [(set_attr "type" "multi")])
12963
12964 ;; By default we don't ask for a scratch register, because when DImode
12965 ;; values are manipulated, registers are already at a premium. But if
12966 ;; we have one handy, we won't turn it away.
12967 (define_peephole2
12968 [(match_scratch:SI 3 "r")
12969 (parallel [(set (match_operand:DI 0 "register_operand" "")
12970 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12971 (match_operand:QI 2 "nonmemory_operand" "")))
12972 (clobber (reg:CC FLAGS_REG))])
12973 (match_dup 3)]
12974 "!TARGET_64BIT && TARGET_CMOVE"
12975 [(const_int 0)]
12976 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12977
12978 (define_split
12979 [(set (match_operand:DI 0 "register_operand" "")
12980 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12981 (match_operand:QI 2 "nonmemory_operand" "")))
12982 (clobber (reg:CC FLAGS_REG))]
12983 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12984 ? epilogue_completed : reload_completed)"
12985 [(const_int 0)]
12986 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12987
12988 (define_expand "lshrsi3"
12989 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12990 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12991 (match_operand:QI 2 "nonmemory_operand" "")))]
12992 ""
12993 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12994
12995 (define_insn "*lshrsi3_1_one_bit"
12996 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12997 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12998 (match_operand:QI 2 "const1_operand" "")))
12999 (clobber (reg:CC FLAGS_REG))]
13000 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13001 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13002 "shr{l}\t%0"
13003 [(set_attr "type" "ishift")
13004 (set (attr "length")
13005 (if_then_else (match_operand:SI 0 "register_operand" "")
13006 (const_string "2")
13007 (const_string "*")))])
13008
13009 (define_insn "*lshrsi3_1_one_bit_zext"
13010 [(set (match_operand:DI 0 "register_operand" "=r")
13011 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13012 (match_operand:QI 2 "const1_operand" "")))
13013 (clobber (reg:CC FLAGS_REG))]
13014 "TARGET_64BIT
13015 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13016 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13017 "shr{l}\t%k0"
13018 [(set_attr "type" "ishift")
13019 (set_attr "length" "2")])
13020
13021 (define_insn "*lshrsi3_1"
13022 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13023 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13024 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13025 (clobber (reg:CC FLAGS_REG))]
13026 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027 "@
13028 shr{l}\t{%2, %0|%0, %2}
13029 shr{l}\t{%b2, %0|%0, %b2}"
13030 [(set_attr "type" "ishift")
13031 (set_attr "mode" "SI")])
13032
13033 (define_insn "*lshrsi3_1_zext"
13034 [(set (match_operand:DI 0 "register_operand" "=r,r")
13035 (zero_extend:DI
13036 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13037 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13038 (clobber (reg:CC FLAGS_REG))]
13039 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13040 "@
13041 shr{l}\t{%2, %k0|%k0, %2}
13042 shr{l}\t{%b2, %k0|%k0, %b2}"
13043 [(set_attr "type" "ishift")
13044 (set_attr "mode" "SI")])
13045
13046 ;; This pattern can't accept a variable shift count, since shifts by
13047 ;; zero don't affect the flags. We assume that shifts by constant
13048 ;; zero are optimized away.
13049 (define_insn "*lshrsi3_one_bit_cmp"
13050 [(set (reg FLAGS_REG)
13051 (compare
13052 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13053 (match_operand:QI 2 "const1_operand" ""))
13054 (const_int 0)))
13055 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13056 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13057 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13058 && ix86_match_ccmode (insn, CCGOCmode)
13059 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060 "shr{l}\t%0"
13061 [(set_attr "type" "ishift")
13062 (set (attr "length")
13063 (if_then_else (match_operand:SI 0 "register_operand" "")
13064 (const_string "2")
13065 (const_string "*")))])
13066
13067 (define_insn "*lshrsi3_one_bit_cconly"
13068 [(set (reg FLAGS_REG)
13069 (compare
13070 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13071 (match_operand:QI 2 "const1_operand" ""))
13072 (const_int 0)))
13073 (clobber (match_scratch:SI 0 "=r"))]
13074 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13075 && ix86_match_ccmode (insn, CCGOCmode)
13076 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13077 "shr{l}\t%0"
13078 [(set_attr "type" "ishift")
13079 (set_attr "length" "2")])
13080
13081 (define_insn "*lshrsi3_cmp_one_bit_zext"
13082 [(set (reg FLAGS_REG)
13083 (compare
13084 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13085 (match_operand:QI 2 "const1_operand" ""))
13086 (const_int 0)))
13087 (set (match_operand:DI 0 "register_operand" "=r")
13088 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13089 "TARGET_64BIT
13090 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13091 && ix86_match_ccmode (insn, CCGOCmode)
13092 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13093 "shr{l}\t%k0"
13094 [(set_attr "type" "ishift")
13095 (set_attr "length" "2")])
13096
13097 ;; This pattern can't accept a variable shift count, since shifts by
13098 ;; zero don't affect the flags. We assume that shifts by constant
13099 ;; zero are optimized away.
13100 (define_insn "*lshrsi3_cmp"
13101 [(set (reg FLAGS_REG)
13102 (compare
13103 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13104 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13105 (const_int 0)))
13106 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13107 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13108 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13109 && ix86_match_ccmode (insn, CCGOCmode)
13110 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13111 "shr{l}\t{%2, %0|%0, %2}"
13112 [(set_attr "type" "ishift")
13113 (set_attr "mode" "SI")])
13114
13115 (define_insn "*lshrsi3_cconly"
13116 [(set (reg FLAGS_REG)
13117 (compare
13118 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13119 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13120 (const_int 0)))
13121 (clobber (match_scratch:SI 0 "=r"))]
13122 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13123 && ix86_match_ccmode (insn, CCGOCmode)
13124 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13125 "shr{l}\t{%2, %0|%0, %2}"
13126 [(set_attr "type" "ishift")
13127 (set_attr "mode" "SI")])
13128
13129 (define_insn "*lshrsi3_cmp_zext"
13130 [(set (reg FLAGS_REG)
13131 (compare
13132 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13133 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13134 (const_int 0)))
13135 (set (match_operand:DI 0 "register_operand" "=r")
13136 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13137 "TARGET_64BIT
13138 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13139 && ix86_match_ccmode (insn, CCGOCmode)
13140 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13141 "shr{l}\t{%2, %k0|%k0, %2}"
13142 [(set_attr "type" "ishift")
13143 (set_attr "mode" "SI")])
13144
13145 (define_expand "lshrhi3"
13146 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13147 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13148 (match_operand:QI 2 "nonmemory_operand" "")))]
13149 "TARGET_HIMODE_MATH"
13150 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13151
13152 (define_insn "*lshrhi3_1_one_bit"
13153 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13154 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13155 (match_operand:QI 2 "const1_operand" "")))
13156 (clobber (reg:CC FLAGS_REG))]
13157 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13158 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13159 "shr{w}\t%0"
13160 [(set_attr "type" "ishift")
13161 (set (attr "length")
13162 (if_then_else (match_operand 0 "register_operand" "")
13163 (const_string "2")
13164 (const_string "*")))])
13165
13166 (define_insn "*lshrhi3_1"
13167 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13168 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13169 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13170 (clobber (reg:CC FLAGS_REG))]
13171 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13172 "@
13173 shr{w}\t{%2, %0|%0, %2}
13174 shr{w}\t{%b2, %0|%0, %b2}"
13175 [(set_attr "type" "ishift")
13176 (set_attr "mode" "HI")])
13177
13178 ;; This pattern can't accept a variable shift count, since shifts by
13179 ;; zero don't affect the flags. We assume that shifts by constant
13180 ;; zero are optimized away.
13181 (define_insn "*lshrhi3_one_bit_cmp"
13182 [(set (reg FLAGS_REG)
13183 (compare
13184 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13185 (match_operand:QI 2 "const1_operand" ""))
13186 (const_int 0)))
13187 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13188 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13189 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13190 && ix86_match_ccmode (insn, CCGOCmode)
13191 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13192 "shr{w}\t%0"
13193 [(set_attr "type" "ishift")
13194 (set (attr "length")
13195 (if_then_else (match_operand:SI 0 "register_operand" "")
13196 (const_string "2")
13197 (const_string "*")))])
13198
13199 (define_insn "*lshrhi3_one_bit_cconly"
13200 [(set (reg FLAGS_REG)
13201 (compare
13202 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13203 (match_operand:QI 2 "const1_operand" ""))
13204 (const_int 0)))
13205 (clobber (match_scratch:HI 0 "=r"))]
13206 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13207 && ix86_match_ccmode (insn, CCGOCmode)
13208 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13209 "shr{w}\t%0"
13210 [(set_attr "type" "ishift")
13211 (set_attr "length" "2")])
13212
13213 ;; This pattern can't accept a variable shift count, since shifts by
13214 ;; zero don't affect the flags. We assume that shifts by constant
13215 ;; zero are optimized away.
13216 (define_insn "*lshrhi3_cmp"
13217 [(set (reg FLAGS_REG)
13218 (compare
13219 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13220 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13221 (const_int 0)))
13222 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13223 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13224 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13225 && ix86_match_ccmode (insn, CCGOCmode)
13226 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13227 "shr{w}\t{%2, %0|%0, %2}"
13228 [(set_attr "type" "ishift")
13229 (set_attr "mode" "HI")])
13230
13231 (define_insn "*lshrhi3_cconly"
13232 [(set (reg FLAGS_REG)
13233 (compare
13234 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13235 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13236 (const_int 0)))
13237 (clobber (match_scratch:HI 0 "=r"))]
13238 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13239 && ix86_match_ccmode (insn, CCGOCmode)
13240 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13241 "shr{w}\t{%2, %0|%0, %2}"
13242 [(set_attr "type" "ishift")
13243 (set_attr "mode" "HI")])
13244
13245 (define_expand "lshrqi3"
13246 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13247 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13248 (match_operand:QI 2 "nonmemory_operand" "")))]
13249 "TARGET_QIMODE_MATH"
13250 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13251
13252 (define_insn "*lshrqi3_1_one_bit"
13253 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13254 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13255 (match_operand:QI 2 "const1_operand" "")))
13256 (clobber (reg:CC FLAGS_REG))]
13257 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13258 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13259 "shr{b}\t%0"
13260 [(set_attr "type" "ishift")
13261 (set (attr "length")
13262 (if_then_else (match_operand 0 "register_operand" "")
13263 (const_string "2")
13264 (const_string "*")))])
13265
13266 (define_insn "*lshrqi3_1_one_bit_slp"
13267 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13268 (lshiftrt:QI (match_dup 0)
13269 (match_operand:QI 1 "const1_operand" "")))
13270 (clobber (reg:CC FLAGS_REG))]
13271 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13272 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13273 "shr{b}\t%0"
13274 [(set_attr "type" "ishift1")
13275 (set (attr "length")
13276 (if_then_else (match_operand 0 "register_operand" "")
13277 (const_string "2")
13278 (const_string "*")))])
13279
13280 (define_insn "*lshrqi3_1"
13281 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13282 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13283 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13284 (clobber (reg:CC FLAGS_REG))]
13285 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13286 "@
13287 shr{b}\t{%2, %0|%0, %2}
13288 shr{b}\t{%b2, %0|%0, %b2}"
13289 [(set_attr "type" "ishift")
13290 (set_attr "mode" "QI")])
13291
13292 (define_insn "*lshrqi3_1_slp"
13293 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13294 (lshiftrt:QI (match_dup 0)
13295 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13296 (clobber (reg:CC FLAGS_REG))]
13297 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13298 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13299 "@
13300 shr{b}\t{%1, %0|%0, %1}
13301 shr{b}\t{%b1, %0|%0, %b1}"
13302 [(set_attr "type" "ishift1")
13303 (set_attr "mode" "QI")])
13304
13305 ;; This pattern can't accept a variable shift count, since shifts by
13306 ;; zero don't affect the flags. We assume that shifts by constant
13307 ;; zero are optimized away.
13308 (define_insn "*lshrqi2_one_bit_cmp"
13309 [(set (reg FLAGS_REG)
13310 (compare
13311 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13312 (match_operand:QI 2 "const1_operand" ""))
13313 (const_int 0)))
13314 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13315 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13316 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13317 && ix86_match_ccmode (insn, CCGOCmode)
13318 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13319 "shr{b}\t%0"
13320 [(set_attr "type" "ishift")
13321 (set (attr "length")
13322 (if_then_else (match_operand:SI 0 "register_operand" "")
13323 (const_string "2")
13324 (const_string "*")))])
13325
13326 (define_insn "*lshrqi2_one_bit_cconly"
13327 [(set (reg FLAGS_REG)
13328 (compare
13329 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330 (match_operand:QI 2 "const1_operand" ""))
13331 (const_int 0)))
13332 (clobber (match_scratch:QI 0 "=q"))]
13333 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13334 && ix86_match_ccmode (insn, CCGOCmode)
13335 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13336 "shr{b}\t%0"
13337 [(set_attr "type" "ishift")
13338 (set_attr "length" "2")])
13339
13340 ;; This pattern can't accept a variable shift count, since shifts by
13341 ;; zero don't affect the flags. We assume that shifts by constant
13342 ;; zero are optimized away.
13343 (define_insn "*lshrqi2_cmp"
13344 [(set (reg FLAGS_REG)
13345 (compare
13346 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13347 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13348 (const_int 0)))
13349 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13350 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13351 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13352 && ix86_match_ccmode (insn, CCGOCmode)
13353 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13354 "shr{b}\t{%2, %0|%0, %2}"
13355 [(set_attr "type" "ishift")
13356 (set_attr "mode" "QI")])
13357
13358 (define_insn "*lshrqi2_cconly"
13359 [(set (reg FLAGS_REG)
13360 (compare
13361 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13362 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13363 (const_int 0)))
13364 (clobber (match_scratch:QI 0 "=q"))]
13365 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13366 && ix86_match_ccmode (insn, CCGOCmode)
13367 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13368 "shr{b}\t{%2, %0|%0, %2}"
13369 [(set_attr "type" "ishift")
13370 (set_attr "mode" "QI")])
13371 \f
13372 ;; Rotate instructions
13373
13374 (define_expand "rotldi3"
13375 [(set (match_operand:DI 0 "shiftdi_operand" "")
13376 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13377 (match_operand:QI 2 "nonmemory_operand" "")))]
13378 ""
13379 {
13380 if (TARGET_64BIT)
13381 {
13382 ix86_expand_binary_operator (ROTATE, DImode, operands);
13383 DONE;
13384 }
13385 if (!const_1_to_31_operand (operands[2], VOIDmode))
13386 FAIL;
13387 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13388 DONE;
13389 })
13390
13391 ;; Implement rotation using two double-precision shift instructions
13392 ;; and a scratch register.
13393 (define_insn_and_split "ix86_rotldi3"
13394 [(set (match_operand:DI 0 "register_operand" "=r")
13395 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13396 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13397 (clobber (reg:CC FLAGS_REG))
13398 (clobber (match_scratch:SI 3 "=&r"))]
13399 "!TARGET_64BIT"
13400 ""
13401 "&& reload_completed"
13402 [(set (match_dup 3) (match_dup 4))
13403 (parallel
13404 [(set (match_dup 4)
13405 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13406 (lshiftrt:SI (match_dup 5)
13407 (minus:QI (const_int 32) (match_dup 2)))))
13408 (clobber (reg:CC FLAGS_REG))])
13409 (parallel
13410 [(set (match_dup 5)
13411 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13412 (lshiftrt:SI (match_dup 3)
13413 (minus:QI (const_int 32) (match_dup 2)))))
13414 (clobber (reg:CC FLAGS_REG))])]
13415 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13416
13417 (define_insn "*rotlsi3_1_one_bit_rex64"
13418 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13419 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13420 (match_operand:QI 2 "const1_operand" "")))
13421 (clobber (reg:CC FLAGS_REG))]
13422 "TARGET_64BIT
13423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13424 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13425 "rol{q}\t%0"
13426 [(set_attr "type" "rotate")
13427 (set (attr "length")
13428 (if_then_else (match_operand:DI 0 "register_operand" "")
13429 (const_string "2")
13430 (const_string "*")))])
13431
13432 (define_insn "*rotldi3_1_rex64"
13433 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13434 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13435 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13436 (clobber (reg:CC FLAGS_REG))]
13437 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13438 "@
13439 rol{q}\t{%2, %0|%0, %2}
13440 rol{q}\t{%b2, %0|%0, %b2}"
13441 [(set_attr "type" "rotate")
13442 (set_attr "mode" "DI")])
13443
13444 (define_expand "rotlsi3"
13445 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13446 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13447 (match_operand:QI 2 "nonmemory_operand" "")))]
13448 ""
13449 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13450
13451 (define_insn "*rotlsi3_1_one_bit"
13452 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13453 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13454 (match_operand:QI 2 "const1_operand" "")))
13455 (clobber (reg:CC FLAGS_REG))]
13456 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13457 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13458 "rol{l}\t%0"
13459 [(set_attr "type" "rotate")
13460 (set (attr "length")
13461 (if_then_else (match_operand:SI 0 "register_operand" "")
13462 (const_string "2")
13463 (const_string "*")))])
13464
13465 (define_insn "*rotlsi3_1_one_bit_zext"
13466 [(set (match_operand:DI 0 "register_operand" "=r")
13467 (zero_extend:DI
13468 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13469 (match_operand:QI 2 "const1_operand" ""))))
13470 (clobber (reg:CC FLAGS_REG))]
13471 "TARGET_64BIT
13472 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13473 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13474 "rol{l}\t%k0"
13475 [(set_attr "type" "rotate")
13476 (set_attr "length" "2")])
13477
13478 (define_insn "*rotlsi3_1"
13479 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13480 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13481 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13482 (clobber (reg:CC FLAGS_REG))]
13483 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13484 "@
13485 rol{l}\t{%2, %0|%0, %2}
13486 rol{l}\t{%b2, %0|%0, %b2}"
13487 [(set_attr "type" "rotate")
13488 (set_attr "mode" "SI")])
13489
13490 (define_insn "*rotlsi3_1_zext"
13491 [(set (match_operand:DI 0 "register_operand" "=r,r")
13492 (zero_extend:DI
13493 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13494 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13495 (clobber (reg:CC FLAGS_REG))]
13496 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13497 "@
13498 rol{l}\t{%2, %k0|%k0, %2}
13499 rol{l}\t{%b2, %k0|%k0, %b2}"
13500 [(set_attr "type" "rotate")
13501 (set_attr "mode" "SI")])
13502
13503 (define_expand "rotlhi3"
13504 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13505 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13506 (match_operand:QI 2 "nonmemory_operand" "")))]
13507 "TARGET_HIMODE_MATH"
13508 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13509
13510 (define_insn "*rotlhi3_1_one_bit"
13511 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13512 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13513 (match_operand:QI 2 "const1_operand" "")))
13514 (clobber (reg:CC FLAGS_REG))]
13515 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13516 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13517 "rol{w}\t%0"
13518 [(set_attr "type" "rotate")
13519 (set (attr "length")
13520 (if_then_else (match_operand 0 "register_operand" "")
13521 (const_string "2")
13522 (const_string "*")))])
13523
13524 (define_insn "*rotlhi3_1"
13525 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13526 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13527 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13528 (clobber (reg:CC FLAGS_REG))]
13529 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13530 "@
13531 rol{w}\t{%2, %0|%0, %2}
13532 rol{w}\t{%b2, %0|%0, %b2}"
13533 [(set_attr "type" "rotate")
13534 (set_attr "mode" "HI")])
13535
13536 (define_split
13537 [(set (match_operand:HI 0 "register_operand" "")
13538 (rotate:HI (match_dup 0) (const_int 8)))
13539 (clobber (reg:CC FLAGS_REG))]
13540 "reload_completed"
13541 [(parallel [(set (strict_low_part (match_dup 0))
13542 (bswap:HI (match_dup 0)))
13543 (clobber (reg:CC FLAGS_REG))])]
13544 "")
13545
13546 (define_expand "rotlqi3"
13547 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13548 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13549 (match_operand:QI 2 "nonmemory_operand" "")))]
13550 "TARGET_QIMODE_MATH"
13551 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13552
13553 (define_insn "*rotlqi3_1_one_bit_slp"
13554 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13555 (rotate:QI (match_dup 0)
13556 (match_operand:QI 1 "const1_operand" "")))
13557 (clobber (reg:CC FLAGS_REG))]
13558 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13559 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13560 "rol{b}\t%0"
13561 [(set_attr "type" "rotate1")
13562 (set (attr "length")
13563 (if_then_else (match_operand 0 "register_operand" "")
13564 (const_string "2")
13565 (const_string "*")))])
13566
13567 (define_insn "*rotlqi3_1_one_bit"
13568 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13569 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13570 (match_operand:QI 2 "const1_operand" "")))
13571 (clobber (reg:CC FLAGS_REG))]
13572 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13573 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13574 "rol{b}\t%0"
13575 [(set_attr "type" "rotate")
13576 (set (attr "length")
13577 (if_then_else (match_operand 0 "register_operand" "")
13578 (const_string "2")
13579 (const_string "*")))])
13580
13581 (define_insn "*rotlqi3_1_slp"
13582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13583 (rotate:QI (match_dup 0)
13584 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13585 (clobber (reg:CC FLAGS_REG))]
13586 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13587 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13588 "@
13589 rol{b}\t{%1, %0|%0, %1}
13590 rol{b}\t{%b1, %0|%0, %b1}"
13591 [(set_attr "type" "rotate1")
13592 (set_attr "mode" "QI")])
13593
13594 (define_insn "*rotlqi3_1"
13595 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13596 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13597 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13598 (clobber (reg:CC FLAGS_REG))]
13599 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13600 "@
13601 rol{b}\t{%2, %0|%0, %2}
13602 rol{b}\t{%b2, %0|%0, %b2}"
13603 [(set_attr "type" "rotate")
13604 (set_attr "mode" "QI")])
13605
13606 (define_expand "rotrdi3"
13607 [(set (match_operand:DI 0 "shiftdi_operand" "")
13608 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13609 (match_operand:QI 2 "nonmemory_operand" "")))]
13610 ""
13611 {
13612 if (TARGET_64BIT)
13613 {
13614 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13615 DONE;
13616 }
13617 if (!const_1_to_31_operand (operands[2], VOIDmode))
13618 FAIL;
13619 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13620 DONE;
13621 })
13622
13623 ;; Implement rotation using two double-precision shift instructions
13624 ;; and a scratch register.
13625 (define_insn_and_split "ix86_rotrdi3"
13626 [(set (match_operand:DI 0 "register_operand" "=r")
13627 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13628 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13629 (clobber (reg:CC FLAGS_REG))
13630 (clobber (match_scratch:SI 3 "=&r"))]
13631 "!TARGET_64BIT"
13632 ""
13633 "&& reload_completed"
13634 [(set (match_dup 3) (match_dup 4))
13635 (parallel
13636 [(set (match_dup 4)
13637 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13638 (ashift:SI (match_dup 5)
13639 (minus:QI (const_int 32) (match_dup 2)))))
13640 (clobber (reg:CC FLAGS_REG))])
13641 (parallel
13642 [(set (match_dup 5)
13643 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13644 (ashift:SI (match_dup 3)
13645 (minus:QI (const_int 32) (match_dup 2)))))
13646 (clobber (reg:CC FLAGS_REG))])]
13647 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13648
13649 (define_insn "*rotrdi3_1_one_bit_rex64"
13650 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13651 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13652 (match_operand:QI 2 "const1_operand" "")))
13653 (clobber (reg:CC FLAGS_REG))]
13654 "TARGET_64BIT
13655 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13656 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13657 "ror{q}\t%0"
13658 [(set_attr "type" "rotate")
13659 (set (attr "length")
13660 (if_then_else (match_operand:DI 0 "register_operand" "")
13661 (const_string "2")
13662 (const_string "*")))])
13663
13664 (define_insn "*rotrdi3_1_rex64"
13665 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13666 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13667 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13668 (clobber (reg:CC FLAGS_REG))]
13669 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13670 "@
13671 ror{q}\t{%2, %0|%0, %2}
13672 ror{q}\t{%b2, %0|%0, %b2}"
13673 [(set_attr "type" "rotate")
13674 (set_attr "mode" "DI")])
13675
13676 (define_expand "rotrsi3"
13677 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13678 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13679 (match_operand:QI 2 "nonmemory_operand" "")))]
13680 ""
13681 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13682
13683 (define_insn "*rotrsi3_1_one_bit"
13684 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13685 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13686 (match_operand:QI 2 "const1_operand" "")))
13687 (clobber (reg:CC FLAGS_REG))]
13688 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13689 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13690 "ror{l}\t%0"
13691 [(set_attr "type" "rotate")
13692 (set (attr "length")
13693 (if_then_else (match_operand:SI 0 "register_operand" "")
13694 (const_string "2")
13695 (const_string "*")))])
13696
13697 (define_insn "*rotrsi3_1_one_bit_zext"
13698 [(set (match_operand:DI 0 "register_operand" "=r")
13699 (zero_extend:DI
13700 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13701 (match_operand:QI 2 "const1_operand" ""))))
13702 (clobber (reg:CC FLAGS_REG))]
13703 "TARGET_64BIT
13704 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13705 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13706 "ror{l}\t%k0"
13707 [(set_attr "type" "rotate")
13708 (set (attr "length")
13709 (if_then_else (match_operand:SI 0 "register_operand" "")
13710 (const_string "2")
13711 (const_string "*")))])
13712
13713 (define_insn "*rotrsi3_1"
13714 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13715 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13716 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13717 (clobber (reg:CC FLAGS_REG))]
13718 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13719 "@
13720 ror{l}\t{%2, %0|%0, %2}
13721 ror{l}\t{%b2, %0|%0, %b2}"
13722 [(set_attr "type" "rotate")
13723 (set_attr "mode" "SI")])
13724
13725 (define_insn "*rotrsi3_1_zext"
13726 [(set (match_operand:DI 0 "register_operand" "=r,r")
13727 (zero_extend:DI
13728 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13729 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13730 (clobber (reg:CC FLAGS_REG))]
13731 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13732 "@
13733 ror{l}\t{%2, %k0|%k0, %2}
13734 ror{l}\t{%b2, %k0|%k0, %b2}"
13735 [(set_attr "type" "rotate")
13736 (set_attr "mode" "SI")])
13737
13738 (define_expand "rotrhi3"
13739 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13740 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13741 (match_operand:QI 2 "nonmemory_operand" "")))]
13742 "TARGET_HIMODE_MATH"
13743 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13744
13745 (define_insn "*rotrhi3_one_bit"
13746 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13747 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13748 (match_operand:QI 2 "const1_operand" "")))
13749 (clobber (reg:CC FLAGS_REG))]
13750 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13751 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13752 "ror{w}\t%0"
13753 [(set_attr "type" "rotate")
13754 (set (attr "length")
13755 (if_then_else (match_operand 0 "register_operand" "")
13756 (const_string "2")
13757 (const_string "*")))])
13758
13759 (define_insn "*rotrhi3_1"
13760 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13761 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13762 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13763 (clobber (reg:CC FLAGS_REG))]
13764 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13765 "@
13766 ror{w}\t{%2, %0|%0, %2}
13767 ror{w}\t{%b2, %0|%0, %b2}"
13768 [(set_attr "type" "rotate")
13769 (set_attr "mode" "HI")])
13770
13771 (define_split
13772 [(set (match_operand:HI 0 "register_operand" "")
13773 (rotatert:HI (match_dup 0) (const_int 8)))
13774 (clobber (reg:CC FLAGS_REG))]
13775 "reload_completed"
13776 [(parallel [(set (strict_low_part (match_dup 0))
13777 (bswap:HI (match_dup 0)))
13778 (clobber (reg:CC FLAGS_REG))])]
13779 "")
13780
13781 (define_expand "rotrqi3"
13782 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13783 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13784 (match_operand:QI 2 "nonmemory_operand" "")))]
13785 "TARGET_QIMODE_MATH"
13786 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13787
13788 (define_insn "*rotrqi3_1_one_bit"
13789 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13790 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13791 (match_operand:QI 2 "const1_operand" "")))
13792 (clobber (reg:CC FLAGS_REG))]
13793 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13794 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13795 "ror{b}\t%0"
13796 [(set_attr "type" "rotate")
13797 (set (attr "length")
13798 (if_then_else (match_operand 0 "register_operand" "")
13799 (const_string "2")
13800 (const_string "*")))])
13801
13802 (define_insn "*rotrqi3_1_one_bit_slp"
13803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13804 (rotatert:QI (match_dup 0)
13805 (match_operand:QI 1 "const1_operand" "")))
13806 (clobber (reg:CC FLAGS_REG))]
13807 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13808 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13809 "ror{b}\t%0"
13810 [(set_attr "type" "rotate1")
13811 (set (attr "length")
13812 (if_then_else (match_operand 0 "register_operand" "")
13813 (const_string "2")
13814 (const_string "*")))])
13815
13816 (define_insn "*rotrqi3_1"
13817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13818 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13819 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13820 (clobber (reg:CC FLAGS_REG))]
13821 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13822 "@
13823 ror{b}\t{%2, %0|%0, %2}
13824 ror{b}\t{%b2, %0|%0, %b2}"
13825 [(set_attr "type" "rotate")
13826 (set_attr "mode" "QI")])
13827
13828 (define_insn "*rotrqi3_1_slp"
13829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13830 (rotatert:QI (match_dup 0)
13831 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13832 (clobber (reg:CC FLAGS_REG))]
13833 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13834 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13835 "@
13836 ror{b}\t{%1, %0|%0, %1}
13837 ror{b}\t{%b1, %0|%0, %b1}"
13838 [(set_attr "type" "rotate1")
13839 (set_attr "mode" "QI")])
13840 \f
13841 ;; Bit set / bit test instructions
13842
13843 (define_expand "extv"
13844 [(set (match_operand:SI 0 "register_operand" "")
13845 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13846 (match_operand:SI 2 "const8_operand" "")
13847 (match_operand:SI 3 "const8_operand" "")))]
13848 ""
13849 {
13850 /* Handle extractions from %ah et al. */
13851 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13852 FAIL;
13853
13854 /* From mips.md: extract_bit_field doesn't verify that our source
13855 matches the predicate, so check it again here. */
13856 if (! ext_register_operand (operands[1], VOIDmode))
13857 FAIL;
13858 })
13859
13860 (define_expand "extzv"
13861 [(set (match_operand:SI 0 "register_operand" "")
13862 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13863 (match_operand:SI 2 "const8_operand" "")
13864 (match_operand:SI 3 "const8_operand" "")))]
13865 ""
13866 {
13867 /* Handle extractions from %ah et al. */
13868 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13869 FAIL;
13870
13871 /* From mips.md: extract_bit_field doesn't verify that our source
13872 matches the predicate, so check it again here. */
13873 if (! ext_register_operand (operands[1], VOIDmode))
13874 FAIL;
13875 })
13876
13877 (define_expand "insv"
13878 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13879 (match_operand 1 "const8_operand" "")
13880 (match_operand 2 "const8_operand" ""))
13881 (match_operand 3 "register_operand" ""))]
13882 ""
13883 {
13884 /* Handle insertions to %ah et al. */
13885 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13886 FAIL;
13887
13888 /* From mips.md: insert_bit_field doesn't verify that our source
13889 matches the predicate, so check it again here. */
13890 if (! ext_register_operand (operands[0], VOIDmode))
13891 FAIL;
13892
13893 if (TARGET_64BIT)
13894 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13895 else
13896 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13897
13898 DONE;
13899 })
13900
13901 ;; %%% bts, btr, btc, bt.
13902 ;; In general these instructions are *slow* when applied to memory,
13903 ;; since they enforce atomic operation. When applied to registers,
13904 ;; it depends on the cpu implementation. They're never faster than
13905 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13906 ;; no point. But in 64-bit, we can't hold the relevant immediates
13907 ;; within the instruction itself, so operating on bits in the high
13908 ;; 32-bits of a register becomes easier.
13909 ;;
13910 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13911 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13912 ;; negdf respectively, so they can never be disabled entirely.
13913
13914 (define_insn "*btsq"
13915 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13916 (const_int 1)
13917 (match_operand:DI 1 "const_0_to_63_operand" ""))
13918 (const_int 1))
13919 (clobber (reg:CC FLAGS_REG))]
13920 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13921 "bts{q}\t{%1, %0|%0, %1}"
13922 [(set_attr "type" "alu1")])
13923
13924 (define_insn "*btrq"
13925 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13926 (const_int 1)
13927 (match_operand:DI 1 "const_0_to_63_operand" ""))
13928 (const_int 0))
13929 (clobber (reg:CC FLAGS_REG))]
13930 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13931 "btr{q}\t{%1, %0|%0, %1}"
13932 [(set_attr "type" "alu1")])
13933
13934 (define_insn "*btcq"
13935 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13936 (const_int 1)
13937 (match_operand:DI 1 "const_0_to_63_operand" ""))
13938 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13939 (clobber (reg:CC FLAGS_REG))]
13940 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13941 "btc{q}\t{%1, %0|%0, %1}"
13942 [(set_attr "type" "alu1")])
13943
13944 ;; Allow Nocona to avoid these instructions if a register is available.
13945
13946 (define_peephole2
13947 [(match_scratch:DI 2 "r")
13948 (parallel [(set (zero_extract:DI
13949 (match_operand:DI 0 "register_operand" "")
13950 (const_int 1)
13951 (match_operand:DI 1 "const_0_to_63_operand" ""))
13952 (const_int 1))
13953 (clobber (reg:CC FLAGS_REG))])]
13954 "TARGET_64BIT && !TARGET_USE_BT"
13955 [(const_int 0)]
13956 {
13957 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13958 rtx op1;
13959
13960 if (HOST_BITS_PER_WIDE_INT >= 64)
13961 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13962 else if (i < HOST_BITS_PER_WIDE_INT)
13963 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13964 else
13965 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13966
13967 op1 = immed_double_const (lo, hi, DImode);
13968 if (i >= 31)
13969 {
13970 emit_move_insn (operands[2], op1);
13971 op1 = operands[2];
13972 }
13973
13974 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13975 DONE;
13976 })
13977
13978 (define_peephole2
13979 [(match_scratch:DI 2 "r")
13980 (parallel [(set (zero_extract:DI
13981 (match_operand:DI 0 "register_operand" "")
13982 (const_int 1)
13983 (match_operand:DI 1 "const_0_to_63_operand" ""))
13984 (const_int 0))
13985 (clobber (reg:CC FLAGS_REG))])]
13986 "TARGET_64BIT && !TARGET_USE_BT"
13987 [(const_int 0)]
13988 {
13989 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13990 rtx op1;
13991
13992 if (HOST_BITS_PER_WIDE_INT >= 64)
13993 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13994 else if (i < HOST_BITS_PER_WIDE_INT)
13995 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13996 else
13997 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13998
13999 op1 = immed_double_const (~lo, ~hi, DImode);
14000 if (i >= 32)
14001 {
14002 emit_move_insn (operands[2], op1);
14003 op1 = operands[2];
14004 }
14005
14006 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14007 DONE;
14008 })
14009
14010 (define_peephole2
14011 [(match_scratch:DI 2 "r")
14012 (parallel [(set (zero_extract:DI
14013 (match_operand:DI 0 "register_operand" "")
14014 (const_int 1)
14015 (match_operand:DI 1 "const_0_to_63_operand" ""))
14016 (not:DI (zero_extract:DI
14017 (match_dup 0) (const_int 1) (match_dup 1))))
14018 (clobber (reg:CC FLAGS_REG))])]
14019 "TARGET_64BIT && !TARGET_USE_BT"
14020 [(const_int 0)]
14021 {
14022 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14023 rtx op1;
14024
14025 if (HOST_BITS_PER_WIDE_INT >= 64)
14026 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14027 else if (i < HOST_BITS_PER_WIDE_INT)
14028 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14029 else
14030 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14031
14032 op1 = immed_double_const (lo, hi, DImode);
14033 if (i >= 31)
14034 {
14035 emit_move_insn (operands[2], op1);
14036 op1 = operands[2];
14037 }
14038
14039 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14040 DONE;
14041 })
14042
14043 (define_insn "*btdi_rex64"
14044 [(set (reg:CCC FLAGS_REG)
14045 (compare:CCC
14046 (zero_extract:DI
14047 (match_operand:DI 0 "register_operand" "r")
14048 (const_int 1)
14049 (match_operand:DI 1 "nonmemory_operand" "rN"))
14050 (const_int 0)))]
14051 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14052 "bt{q}\t{%1, %0|%0, %1}"
14053 [(set_attr "type" "alu1")])
14054
14055 (define_insn "*btsi"
14056 [(set (reg:CCC FLAGS_REG)
14057 (compare:CCC
14058 (zero_extract:SI
14059 (match_operand:SI 0 "register_operand" "r")
14060 (const_int 1)
14061 (match_operand:SI 1 "nonmemory_operand" "rN"))
14062 (const_int 0)))]
14063 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14064 "bt{l}\t{%1, %0|%0, %1}"
14065 [(set_attr "type" "alu1")])
14066 \f
14067 ;; Store-flag instructions.
14068
14069 ;; For all sCOND expanders, also expand the compare or test insn that
14070 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14071
14072 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14073 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14074 ;; way, which can later delete the movzx if only QImode is needed.
14075
14076 (define_expand "s<code>"
14077 [(set (match_operand:QI 0 "register_operand" "")
14078 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14079 ""
14080 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14081
14082 (define_expand "s<code>"
14083 [(set (match_operand:QI 0 "register_operand" "")
14084 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14085 "TARGET_80387 || TARGET_SSE"
14086 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14087
14088 (define_insn "*setcc_1"
14089 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14090 (match_operator:QI 1 "ix86_comparison_operator"
14091 [(reg FLAGS_REG) (const_int 0)]))]
14092 ""
14093 "set%C1\t%0"
14094 [(set_attr "type" "setcc")
14095 (set_attr "mode" "QI")])
14096
14097 (define_insn "*setcc_2"
14098 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14099 (match_operator:QI 1 "ix86_comparison_operator"
14100 [(reg FLAGS_REG) (const_int 0)]))]
14101 ""
14102 "set%C1\t%0"
14103 [(set_attr "type" "setcc")
14104 (set_attr "mode" "QI")])
14105
14106 ;; In general it is not safe to assume too much about CCmode registers,
14107 ;; so simplify-rtx stops when it sees a second one. Under certain
14108 ;; conditions this is safe on x86, so help combine not create
14109 ;;
14110 ;; seta %al
14111 ;; testb %al, %al
14112 ;; sete %al
14113
14114 (define_split
14115 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14116 (ne:QI (match_operator 1 "ix86_comparison_operator"
14117 [(reg FLAGS_REG) (const_int 0)])
14118 (const_int 0)))]
14119 ""
14120 [(set (match_dup 0) (match_dup 1))]
14121 {
14122 PUT_MODE (operands[1], QImode);
14123 })
14124
14125 (define_split
14126 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14127 (ne:QI (match_operator 1 "ix86_comparison_operator"
14128 [(reg FLAGS_REG) (const_int 0)])
14129 (const_int 0)))]
14130 ""
14131 [(set (match_dup 0) (match_dup 1))]
14132 {
14133 PUT_MODE (operands[1], QImode);
14134 })
14135
14136 (define_split
14137 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14138 (eq:QI (match_operator 1 "ix86_comparison_operator"
14139 [(reg FLAGS_REG) (const_int 0)])
14140 (const_int 0)))]
14141 ""
14142 [(set (match_dup 0) (match_dup 1))]
14143 {
14144 rtx new_op1 = copy_rtx (operands[1]);
14145 operands[1] = new_op1;
14146 PUT_MODE (new_op1, QImode);
14147 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14148 GET_MODE (XEXP (new_op1, 0))));
14149
14150 /* Make sure that (a) the CCmode we have for the flags is strong
14151 enough for the reversed compare or (b) we have a valid FP compare. */
14152 if (! ix86_comparison_operator (new_op1, VOIDmode))
14153 FAIL;
14154 })
14155
14156 (define_split
14157 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14158 (eq:QI (match_operator 1 "ix86_comparison_operator"
14159 [(reg FLAGS_REG) (const_int 0)])
14160 (const_int 0)))]
14161 ""
14162 [(set (match_dup 0) (match_dup 1))]
14163 {
14164 rtx new_op1 = copy_rtx (operands[1]);
14165 operands[1] = new_op1;
14166 PUT_MODE (new_op1, QImode);
14167 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14168 GET_MODE (XEXP (new_op1, 0))));
14169
14170 /* Make sure that (a) the CCmode we have for the flags is strong
14171 enough for the reversed compare or (b) we have a valid FP compare. */
14172 if (! ix86_comparison_operator (new_op1, VOIDmode))
14173 FAIL;
14174 })
14175
14176 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14177 ;; subsequent logical operations are used to imitate conditional moves.
14178 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14179 ;; it directly.
14180
14181 (define_insn "*avx_setcc<mode>"
14182 [(set (match_operand:MODEF 0 "register_operand" "=x")
14183 (match_operator:MODEF 1 "avx_comparison_float_operator"
14184 [(match_operand:MODEF 2 "register_operand" "x")
14185 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14186 "TARGET_AVX"
14187 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14188 [(set_attr "type" "ssecmp")
14189 (set_attr "prefix" "vex")
14190 (set_attr "mode" "<MODE>")])
14191
14192 (define_insn "*sse_setcc<mode>"
14193 [(set (match_operand:MODEF 0 "register_operand" "=x")
14194 (match_operator:MODEF 1 "sse_comparison_operator"
14195 [(match_operand:MODEF 2 "register_operand" "0")
14196 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14197 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14198 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14199 [(set_attr "type" "ssecmp")
14200 (set_attr "mode" "<MODE>")])
14201
14202 (define_insn "*sse5_setcc<mode>"
14203 [(set (match_operand:MODEF 0 "register_operand" "=x")
14204 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14205 [(match_operand:MODEF 2 "register_operand" "x")
14206 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14207 "TARGET_SSE5"
14208 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14209 [(set_attr "type" "sse4arg")
14210 (set_attr "mode" "<MODE>")])
14211
14212 \f
14213 ;; Basic conditional jump instructions.
14214 ;; We ignore the overflow flag for signed branch instructions.
14215
14216 ;; For all bCOND expanders, also expand the compare or test insn that
14217 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14218
14219 (define_expand "b<code>"
14220 [(set (pc)
14221 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14222 (const_int 0))
14223 (label_ref (match_operand 0 ""))
14224 (pc)))]
14225 ""
14226 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14227
14228 (define_expand "b<code>"
14229 [(set (pc)
14230 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14231 (const_int 0))
14232 (label_ref (match_operand 0 ""))
14233 (pc)))]
14234 "TARGET_80387 || TARGET_SSE_MATH"
14235 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14236
14237 (define_insn "*jcc_1"
14238 [(set (pc)
14239 (if_then_else (match_operator 1 "ix86_comparison_operator"
14240 [(reg FLAGS_REG) (const_int 0)])
14241 (label_ref (match_operand 0 "" ""))
14242 (pc)))]
14243 ""
14244 "%+j%C1\t%l0"
14245 [(set_attr "type" "ibr")
14246 (set_attr "modrm" "0")
14247 (set (attr "length")
14248 (if_then_else (and (ge (minus (match_dup 0) (pc))
14249 (const_int -126))
14250 (lt (minus (match_dup 0) (pc))
14251 (const_int 128)))
14252 (const_int 2)
14253 (const_int 6)))])
14254
14255 (define_insn "*jcc_2"
14256 [(set (pc)
14257 (if_then_else (match_operator 1 "ix86_comparison_operator"
14258 [(reg FLAGS_REG) (const_int 0)])
14259 (pc)
14260 (label_ref (match_operand 0 "" ""))))]
14261 ""
14262 "%+j%c1\t%l0"
14263 [(set_attr "type" "ibr")
14264 (set_attr "modrm" "0")
14265 (set (attr "length")
14266 (if_then_else (and (ge (minus (match_dup 0) (pc))
14267 (const_int -126))
14268 (lt (minus (match_dup 0) (pc))
14269 (const_int 128)))
14270 (const_int 2)
14271 (const_int 6)))])
14272
14273 ;; In general it is not safe to assume too much about CCmode registers,
14274 ;; so simplify-rtx stops when it sees a second one. Under certain
14275 ;; conditions this is safe on x86, so help combine not create
14276 ;;
14277 ;; seta %al
14278 ;; testb %al, %al
14279 ;; je Lfoo
14280
14281 (define_split
14282 [(set (pc)
14283 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14284 [(reg FLAGS_REG) (const_int 0)])
14285 (const_int 0))
14286 (label_ref (match_operand 1 "" ""))
14287 (pc)))]
14288 ""
14289 [(set (pc)
14290 (if_then_else (match_dup 0)
14291 (label_ref (match_dup 1))
14292 (pc)))]
14293 {
14294 PUT_MODE (operands[0], VOIDmode);
14295 })
14296
14297 (define_split
14298 [(set (pc)
14299 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14300 [(reg FLAGS_REG) (const_int 0)])
14301 (const_int 0))
14302 (label_ref (match_operand 1 "" ""))
14303 (pc)))]
14304 ""
14305 [(set (pc)
14306 (if_then_else (match_dup 0)
14307 (label_ref (match_dup 1))
14308 (pc)))]
14309 {
14310 rtx new_op0 = copy_rtx (operands[0]);
14311 operands[0] = new_op0;
14312 PUT_MODE (new_op0, VOIDmode);
14313 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14314 GET_MODE (XEXP (new_op0, 0))));
14315
14316 /* Make sure that (a) the CCmode we have for the flags is strong
14317 enough for the reversed compare or (b) we have a valid FP compare. */
14318 if (! ix86_comparison_operator (new_op0, VOIDmode))
14319 FAIL;
14320 })
14321
14322 ;; zero_extend in SImode is correct, since this is what combine pass
14323 ;; generates from shift insn with QImode operand. Actually, the mode of
14324 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14325 ;; appropriate modulo of the bit offset value.
14326
14327 (define_insn_and_split "*jcc_btdi_rex64"
14328 [(set (pc)
14329 (if_then_else (match_operator 0 "bt_comparison_operator"
14330 [(zero_extract:DI
14331 (match_operand:DI 1 "register_operand" "r")
14332 (const_int 1)
14333 (zero_extend:SI
14334 (match_operand:QI 2 "register_operand" "r")))
14335 (const_int 0)])
14336 (label_ref (match_operand 3 "" ""))
14337 (pc)))
14338 (clobber (reg:CC FLAGS_REG))]
14339 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14340 "#"
14341 "&& 1"
14342 [(set (reg:CCC FLAGS_REG)
14343 (compare:CCC
14344 (zero_extract:DI
14345 (match_dup 1)
14346 (const_int 1)
14347 (match_dup 2))
14348 (const_int 0)))
14349 (set (pc)
14350 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14351 (label_ref (match_dup 3))
14352 (pc)))]
14353 {
14354 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14355
14356 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14357 })
14358
14359 ;; avoid useless masking of bit offset operand
14360 (define_insn_and_split "*jcc_btdi_mask_rex64"
14361 [(set (pc)
14362 (if_then_else (match_operator 0 "bt_comparison_operator"
14363 [(zero_extract:DI
14364 (match_operand:DI 1 "register_operand" "r")
14365 (const_int 1)
14366 (and:SI
14367 (match_operand:SI 2 "register_operand" "r")
14368 (match_operand:SI 3 "const_int_operand" "n")))])
14369 (label_ref (match_operand 4 "" ""))
14370 (pc)))
14371 (clobber (reg:CC FLAGS_REG))]
14372 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14373 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14374 "#"
14375 "&& 1"
14376 [(set (reg:CCC FLAGS_REG)
14377 (compare:CCC
14378 (zero_extract:DI
14379 (match_dup 1)
14380 (const_int 1)
14381 (match_dup 2))
14382 (const_int 0)))
14383 (set (pc)
14384 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14385 (label_ref (match_dup 4))
14386 (pc)))]
14387 {
14388 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14389
14390 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14391 })
14392
14393 (define_insn_and_split "*jcc_btsi"
14394 [(set (pc)
14395 (if_then_else (match_operator 0 "bt_comparison_operator"
14396 [(zero_extract:SI
14397 (match_operand:SI 1 "register_operand" "r")
14398 (const_int 1)
14399 (zero_extend:SI
14400 (match_operand:QI 2 "register_operand" "r")))
14401 (const_int 0)])
14402 (label_ref (match_operand 3 "" ""))
14403 (pc)))
14404 (clobber (reg:CC FLAGS_REG))]
14405 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14406 "#"
14407 "&& 1"
14408 [(set (reg:CCC FLAGS_REG)
14409 (compare:CCC
14410 (zero_extract:SI
14411 (match_dup 1)
14412 (const_int 1)
14413 (match_dup 2))
14414 (const_int 0)))
14415 (set (pc)
14416 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14417 (label_ref (match_dup 3))
14418 (pc)))]
14419 {
14420 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14421
14422 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14423 })
14424
14425 ;; avoid useless masking of bit offset operand
14426 (define_insn_and_split "*jcc_btsi_mask"
14427 [(set (pc)
14428 (if_then_else (match_operator 0 "bt_comparison_operator"
14429 [(zero_extract:SI
14430 (match_operand:SI 1 "register_operand" "r")
14431 (const_int 1)
14432 (and:SI
14433 (match_operand:SI 2 "register_operand" "r")
14434 (match_operand:SI 3 "const_int_operand" "n")))])
14435 (label_ref (match_operand 4 "" ""))
14436 (pc)))
14437 (clobber (reg:CC FLAGS_REG))]
14438 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14439 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14440 "#"
14441 "&& 1"
14442 [(set (reg:CCC FLAGS_REG)
14443 (compare:CCC
14444 (zero_extract:SI
14445 (match_dup 1)
14446 (const_int 1)
14447 (match_dup 2))
14448 (const_int 0)))
14449 (set (pc)
14450 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14451 (label_ref (match_dup 4))
14452 (pc)))]
14453 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14454
14455 (define_insn_and_split "*jcc_btsi_1"
14456 [(set (pc)
14457 (if_then_else (match_operator 0 "bt_comparison_operator"
14458 [(and:SI
14459 (lshiftrt:SI
14460 (match_operand:SI 1 "register_operand" "r")
14461 (match_operand:QI 2 "register_operand" "r"))
14462 (const_int 1))
14463 (const_int 0)])
14464 (label_ref (match_operand 3 "" ""))
14465 (pc)))
14466 (clobber (reg:CC FLAGS_REG))]
14467 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14468 "#"
14469 "&& 1"
14470 [(set (reg:CCC FLAGS_REG)
14471 (compare:CCC
14472 (zero_extract:SI
14473 (match_dup 1)
14474 (const_int 1)
14475 (match_dup 2))
14476 (const_int 0)))
14477 (set (pc)
14478 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14479 (label_ref (match_dup 3))
14480 (pc)))]
14481 {
14482 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14483
14484 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14485 })
14486
14487 ;; avoid useless masking of bit offset operand
14488 (define_insn_and_split "*jcc_btsi_mask_1"
14489 [(set (pc)
14490 (if_then_else
14491 (match_operator 0 "bt_comparison_operator"
14492 [(and:SI
14493 (lshiftrt:SI
14494 (match_operand:SI 1 "register_operand" "r")
14495 (subreg:QI
14496 (and:SI
14497 (match_operand:SI 2 "register_operand" "r")
14498 (match_operand:SI 3 "const_int_operand" "n")) 0))
14499 (const_int 1))
14500 (const_int 0)])
14501 (label_ref (match_operand 4 "" ""))
14502 (pc)))
14503 (clobber (reg:CC FLAGS_REG))]
14504 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14505 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14506 "#"
14507 "&& 1"
14508 [(set (reg:CCC FLAGS_REG)
14509 (compare:CCC
14510 (zero_extract:SI
14511 (match_dup 1)
14512 (const_int 1)
14513 (match_dup 2))
14514 (const_int 0)))
14515 (set (pc)
14516 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14517 (label_ref (match_dup 4))
14518 (pc)))]
14519 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14520
14521 ;; Define combination compare-and-branch fp compare instructions to use
14522 ;; during early optimization. Splitting the operation apart early makes
14523 ;; for bad code when we want to reverse the operation.
14524
14525 (define_insn "*fp_jcc_1_mixed"
14526 [(set (pc)
14527 (if_then_else (match_operator 0 "comparison_operator"
14528 [(match_operand 1 "register_operand" "f,x")
14529 (match_operand 2 "nonimmediate_operand" "f,xm")])
14530 (label_ref (match_operand 3 "" ""))
14531 (pc)))
14532 (clobber (reg:CCFP FPSR_REG))
14533 (clobber (reg:CCFP FLAGS_REG))]
14534 "TARGET_MIX_SSE_I387
14535 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14536 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14537 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14538 "#")
14539
14540 (define_insn "*fp_jcc_1_sse"
14541 [(set (pc)
14542 (if_then_else (match_operator 0 "comparison_operator"
14543 [(match_operand 1 "register_operand" "x")
14544 (match_operand 2 "nonimmediate_operand" "xm")])
14545 (label_ref (match_operand 3 "" ""))
14546 (pc)))
14547 (clobber (reg:CCFP FPSR_REG))
14548 (clobber (reg:CCFP FLAGS_REG))]
14549 "TARGET_SSE_MATH
14550 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14551 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14552 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14553 "#")
14554
14555 (define_insn "*fp_jcc_1_387"
14556 [(set (pc)
14557 (if_then_else (match_operator 0 "comparison_operator"
14558 [(match_operand 1 "register_operand" "f")
14559 (match_operand 2 "register_operand" "f")])
14560 (label_ref (match_operand 3 "" ""))
14561 (pc)))
14562 (clobber (reg:CCFP FPSR_REG))
14563 (clobber (reg:CCFP FLAGS_REG))]
14564 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14565 && TARGET_CMOVE
14566 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14567 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14568 "#")
14569
14570 (define_insn "*fp_jcc_2_mixed"
14571 [(set (pc)
14572 (if_then_else (match_operator 0 "comparison_operator"
14573 [(match_operand 1 "register_operand" "f,x")
14574 (match_operand 2 "nonimmediate_operand" "f,xm")])
14575 (pc)
14576 (label_ref (match_operand 3 "" ""))))
14577 (clobber (reg:CCFP FPSR_REG))
14578 (clobber (reg:CCFP FLAGS_REG))]
14579 "TARGET_MIX_SSE_I387
14580 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14581 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14582 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14583 "#")
14584
14585 (define_insn "*fp_jcc_2_sse"
14586 [(set (pc)
14587 (if_then_else (match_operator 0 "comparison_operator"
14588 [(match_operand 1 "register_operand" "x")
14589 (match_operand 2 "nonimmediate_operand" "xm")])
14590 (pc)
14591 (label_ref (match_operand 3 "" ""))))
14592 (clobber (reg:CCFP FPSR_REG))
14593 (clobber (reg:CCFP FLAGS_REG))]
14594 "TARGET_SSE_MATH
14595 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14596 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14597 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14598 "#")
14599
14600 (define_insn "*fp_jcc_2_387"
14601 [(set (pc)
14602 (if_then_else (match_operator 0 "comparison_operator"
14603 [(match_operand 1 "register_operand" "f")
14604 (match_operand 2 "register_operand" "f")])
14605 (pc)
14606 (label_ref (match_operand 3 "" ""))))
14607 (clobber (reg:CCFP FPSR_REG))
14608 (clobber (reg:CCFP FLAGS_REG))]
14609 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14610 && TARGET_CMOVE
14611 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14612 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14613 "#")
14614
14615 (define_insn "*fp_jcc_3_387"
14616 [(set (pc)
14617 (if_then_else (match_operator 0 "comparison_operator"
14618 [(match_operand 1 "register_operand" "f")
14619 (match_operand 2 "nonimmediate_operand" "fm")])
14620 (label_ref (match_operand 3 "" ""))
14621 (pc)))
14622 (clobber (reg:CCFP FPSR_REG))
14623 (clobber (reg:CCFP FLAGS_REG))
14624 (clobber (match_scratch:HI 4 "=a"))]
14625 "TARGET_80387
14626 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14627 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14628 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14629 && SELECT_CC_MODE (GET_CODE (operands[0]),
14630 operands[1], operands[2]) == CCFPmode
14631 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14632 "#")
14633
14634 (define_insn "*fp_jcc_4_387"
14635 [(set (pc)
14636 (if_then_else (match_operator 0 "comparison_operator"
14637 [(match_operand 1 "register_operand" "f")
14638 (match_operand 2 "nonimmediate_operand" "fm")])
14639 (pc)
14640 (label_ref (match_operand 3 "" ""))))
14641 (clobber (reg:CCFP FPSR_REG))
14642 (clobber (reg:CCFP FLAGS_REG))
14643 (clobber (match_scratch:HI 4 "=a"))]
14644 "TARGET_80387
14645 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14646 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14647 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14648 && SELECT_CC_MODE (GET_CODE (operands[0]),
14649 operands[1], operands[2]) == CCFPmode
14650 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14651 "#")
14652
14653 (define_insn "*fp_jcc_5_387"
14654 [(set (pc)
14655 (if_then_else (match_operator 0 "comparison_operator"
14656 [(match_operand 1 "register_operand" "f")
14657 (match_operand 2 "register_operand" "f")])
14658 (label_ref (match_operand 3 "" ""))
14659 (pc)))
14660 (clobber (reg:CCFP FPSR_REG))
14661 (clobber (reg:CCFP FLAGS_REG))
14662 (clobber (match_scratch:HI 4 "=a"))]
14663 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14664 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14665 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14666 "#")
14667
14668 (define_insn "*fp_jcc_6_387"
14669 [(set (pc)
14670 (if_then_else (match_operator 0 "comparison_operator"
14671 [(match_operand 1 "register_operand" "f")
14672 (match_operand 2 "register_operand" "f")])
14673 (pc)
14674 (label_ref (match_operand 3 "" ""))))
14675 (clobber (reg:CCFP FPSR_REG))
14676 (clobber (reg:CCFP FLAGS_REG))
14677 (clobber (match_scratch:HI 4 "=a"))]
14678 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14679 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14680 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14681 "#")
14682
14683 (define_insn "*fp_jcc_7_387"
14684 [(set (pc)
14685 (if_then_else (match_operator 0 "comparison_operator"
14686 [(match_operand 1 "register_operand" "f")
14687 (match_operand 2 "const0_operand" "")])
14688 (label_ref (match_operand 3 "" ""))
14689 (pc)))
14690 (clobber (reg:CCFP FPSR_REG))
14691 (clobber (reg:CCFP FLAGS_REG))
14692 (clobber (match_scratch:HI 4 "=a"))]
14693 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14694 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14695 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14696 && SELECT_CC_MODE (GET_CODE (operands[0]),
14697 operands[1], operands[2]) == CCFPmode
14698 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14699 "#")
14700
14701 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14702 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14703 ;; with a precedence over other operators and is always put in the first
14704 ;; place. Swap condition and operands to match ficom instruction.
14705
14706 (define_insn "*fp_jcc_8<mode>_387"
14707 [(set (pc)
14708 (if_then_else (match_operator 0 "comparison_operator"
14709 [(match_operator 1 "float_operator"
14710 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14711 (match_operand 3 "register_operand" "f,f")])
14712 (label_ref (match_operand 4 "" ""))
14713 (pc)))
14714 (clobber (reg:CCFP FPSR_REG))
14715 (clobber (reg:CCFP FLAGS_REG))
14716 (clobber (match_scratch:HI 5 "=a,a"))]
14717 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14718 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14719 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14720 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14721 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14722 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14723 "#")
14724
14725 (define_split
14726 [(set (pc)
14727 (if_then_else (match_operator 0 "comparison_operator"
14728 [(match_operand 1 "register_operand" "")
14729 (match_operand 2 "nonimmediate_operand" "")])
14730 (match_operand 3 "" "")
14731 (match_operand 4 "" "")))
14732 (clobber (reg:CCFP FPSR_REG))
14733 (clobber (reg:CCFP FLAGS_REG))]
14734 "reload_completed"
14735 [(const_int 0)]
14736 {
14737 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14738 operands[3], operands[4], NULL_RTX, NULL_RTX);
14739 DONE;
14740 })
14741
14742 (define_split
14743 [(set (pc)
14744 (if_then_else (match_operator 0 "comparison_operator"
14745 [(match_operand 1 "register_operand" "")
14746 (match_operand 2 "general_operand" "")])
14747 (match_operand 3 "" "")
14748 (match_operand 4 "" "")))
14749 (clobber (reg:CCFP FPSR_REG))
14750 (clobber (reg:CCFP FLAGS_REG))
14751 (clobber (match_scratch:HI 5 "=a"))]
14752 "reload_completed"
14753 [(const_int 0)]
14754 {
14755 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14756 operands[3], operands[4], operands[5], NULL_RTX);
14757 DONE;
14758 })
14759
14760 (define_split
14761 [(set (pc)
14762 (if_then_else (match_operator 0 "comparison_operator"
14763 [(match_operator 1 "float_operator"
14764 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14765 (match_operand 3 "register_operand" "")])
14766 (match_operand 4 "" "")
14767 (match_operand 5 "" "")))
14768 (clobber (reg:CCFP FPSR_REG))
14769 (clobber (reg:CCFP FLAGS_REG))
14770 (clobber (match_scratch:HI 6 "=a"))]
14771 "reload_completed"
14772 [(const_int 0)]
14773 {
14774 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14775 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14776 operands[3], operands[7],
14777 operands[4], operands[5], operands[6], NULL_RTX);
14778 DONE;
14779 })
14780
14781 ;; %%% Kill this when reload knows how to do it.
14782 (define_split
14783 [(set (pc)
14784 (if_then_else (match_operator 0 "comparison_operator"
14785 [(match_operator 1 "float_operator"
14786 [(match_operand:X87MODEI12 2 "register_operand" "")])
14787 (match_operand 3 "register_operand" "")])
14788 (match_operand 4 "" "")
14789 (match_operand 5 "" "")))
14790 (clobber (reg:CCFP FPSR_REG))
14791 (clobber (reg:CCFP FLAGS_REG))
14792 (clobber (match_scratch:HI 6 "=a"))]
14793 "reload_completed"
14794 [(const_int 0)]
14795 {
14796 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14797 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14798 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14799 operands[3], operands[7],
14800 operands[4], operands[5], operands[6], operands[2]);
14801 DONE;
14802 })
14803 \f
14804 ;; Unconditional and other jump instructions
14805
14806 (define_insn "jump"
14807 [(set (pc)
14808 (label_ref (match_operand 0 "" "")))]
14809 ""
14810 "jmp\t%l0"
14811 [(set_attr "type" "ibr")
14812 (set (attr "length")
14813 (if_then_else (and (ge (minus (match_dup 0) (pc))
14814 (const_int -126))
14815 (lt (minus (match_dup 0) (pc))
14816 (const_int 128)))
14817 (const_int 2)
14818 (const_int 5)))
14819 (set_attr "modrm" "0")])
14820
14821 (define_expand "indirect_jump"
14822 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14823 ""
14824 "")
14825
14826 (define_insn "*indirect_jump"
14827 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14828 ""
14829 "jmp\t%A0"
14830 [(set_attr "type" "ibr")
14831 (set_attr "length_immediate" "0")])
14832
14833 (define_expand "tablejump"
14834 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14835 (use (label_ref (match_operand 1 "" "")))])]
14836 ""
14837 {
14838 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14839 relative. Convert the relative address to an absolute address. */
14840 if (flag_pic)
14841 {
14842 rtx op0, op1;
14843 enum rtx_code code;
14844
14845 /* We can't use @GOTOFF for text labels on VxWorks;
14846 see gotoff_operand. */
14847 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14848 {
14849 code = PLUS;
14850 op0 = operands[0];
14851 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14852 }
14853 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14854 {
14855 code = PLUS;
14856 op0 = operands[0];
14857 op1 = pic_offset_table_rtx;
14858 }
14859 else
14860 {
14861 code = MINUS;
14862 op0 = pic_offset_table_rtx;
14863 op1 = operands[0];
14864 }
14865
14866 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14867 OPTAB_DIRECT);
14868 }
14869 })
14870
14871 (define_insn "*tablejump_1"
14872 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14873 (use (label_ref (match_operand 1 "" "")))]
14874 ""
14875 "jmp\t%A0"
14876 [(set_attr "type" "ibr")
14877 (set_attr "length_immediate" "0")])
14878 \f
14879 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14880
14881 (define_peephole2
14882 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14883 (set (match_operand:QI 1 "register_operand" "")
14884 (match_operator:QI 2 "ix86_comparison_operator"
14885 [(reg FLAGS_REG) (const_int 0)]))
14886 (set (match_operand 3 "q_regs_operand" "")
14887 (zero_extend (match_dup 1)))]
14888 "(peep2_reg_dead_p (3, operands[1])
14889 || operands_match_p (operands[1], operands[3]))
14890 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14891 [(set (match_dup 4) (match_dup 0))
14892 (set (strict_low_part (match_dup 5))
14893 (match_dup 2))]
14894 {
14895 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14896 operands[5] = gen_lowpart (QImode, operands[3]);
14897 ix86_expand_clear (operands[3]);
14898 })
14899
14900 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14901
14902 (define_peephole2
14903 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14904 (set (match_operand:QI 1 "register_operand" "")
14905 (match_operator:QI 2 "ix86_comparison_operator"
14906 [(reg FLAGS_REG) (const_int 0)]))
14907 (parallel [(set (match_operand 3 "q_regs_operand" "")
14908 (zero_extend (match_dup 1)))
14909 (clobber (reg:CC FLAGS_REG))])]
14910 "(peep2_reg_dead_p (3, operands[1])
14911 || operands_match_p (operands[1], operands[3]))
14912 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14913 [(set (match_dup 4) (match_dup 0))
14914 (set (strict_low_part (match_dup 5))
14915 (match_dup 2))]
14916 {
14917 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14918 operands[5] = gen_lowpart (QImode, operands[3]);
14919 ix86_expand_clear (operands[3]);
14920 })
14921 \f
14922 ;; Call instructions.
14923
14924 ;; The predicates normally associated with named expanders are not properly
14925 ;; checked for calls. This is a bug in the generic code, but it isn't that
14926 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14927
14928 ;; Call subroutine returning no value.
14929
14930 (define_expand "call_pop"
14931 [(parallel [(call (match_operand:QI 0 "" "")
14932 (match_operand:SI 1 "" ""))
14933 (set (reg:SI SP_REG)
14934 (plus:SI (reg:SI SP_REG)
14935 (match_operand:SI 3 "" "")))])]
14936 "!TARGET_64BIT"
14937 {
14938 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14939 DONE;
14940 })
14941
14942 (define_insn "*call_pop_0"
14943 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14944 (match_operand:SI 1 "" ""))
14945 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14946 (match_operand:SI 2 "immediate_operand" "")))]
14947 "!TARGET_64BIT"
14948 {
14949 if (SIBLING_CALL_P (insn))
14950 return "jmp\t%P0";
14951 else
14952 return "call\t%P0";
14953 }
14954 [(set_attr "type" "call")])
14955
14956 (define_insn "*call_pop_1"
14957 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14958 (match_operand:SI 1 "" ""))
14959 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14960 (match_operand:SI 2 "immediate_operand" "i")))]
14961 "!TARGET_64BIT"
14962 {
14963 if (constant_call_address_operand (operands[0], Pmode))
14964 {
14965 if (SIBLING_CALL_P (insn))
14966 return "jmp\t%P0";
14967 else
14968 return "call\t%P0";
14969 }
14970 if (SIBLING_CALL_P (insn))
14971 return "jmp\t%A0";
14972 else
14973 return "call\t%A0";
14974 }
14975 [(set_attr "type" "call")])
14976
14977 (define_expand "call"
14978 [(call (match_operand:QI 0 "" "")
14979 (match_operand 1 "" ""))
14980 (use (match_operand 2 "" ""))]
14981 ""
14982 {
14983 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14984 DONE;
14985 })
14986
14987 (define_expand "sibcall"
14988 [(call (match_operand:QI 0 "" "")
14989 (match_operand 1 "" ""))
14990 (use (match_operand 2 "" ""))]
14991 ""
14992 {
14993 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14994 DONE;
14995 })
14996
14997 (define_insn "*call_0"
14998 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14999 (match_operand 1 "" ""))]
15000 ""
15001 {
15002 if (SIBLING_CALL_P (insn))
15003 return "jmp\t%P0";
15004 else
15005 return "call\t%P0";
15006 }
15007 [(set_attr "type" "call")])
15008
15009 (define_insn "*call_1"
15010 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15011 (match_operand 1 "" ""))]
15012 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15013 {
15014 if (constant_call_address_operand (operands[0], Pmode))
15015 return "call\t%P0";
15016 return "call\t%A0";
15017 }
15018 [(set_attr "type" "call")])
15019
15020 (define_insn "*sibcall_1"
15021 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15022 (match_operand 1 "" ""))]
15023 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15024 {
15025 if (constant_call_address_operand (operands[0], Pmode))
15026 return "jmp\t%P0";
15027 return "jmp\t%A0";
15028 }
15029 [(set_attr "type" "call")])
15030
15031 (define_insn "*call_1_rex64"
15032 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15033 (match_operand 1 "" ""))]
15034 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15035 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15036 {
15037 if (constant_call_address_operand (operands[0], Pmode))
15038 return "call\t%P0";
15039 return "call\t%A0";
15040 }
15041 [(set_attr "type" "call")])
15042
15043 (define_insn "*call_1_rex64_large"
15044 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15045 (match_operand 1 "" ""))]
15046 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15047 "call\t%A0"
15048 [(set_attr "type" "call")])
15049
15050 (define_insn "*sibcall_1_rex64"
15051 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15052 (match_operand 1 "" ""))]
15053 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15054 "jmp\t%P0"
15055 [(set_attr "type" "call")])
15056
15057 (define_insn "*sibcall_1_rex64_v"
15058 [(call (mem:QI (reg:DI R11_REG))
15059 (match_operand 0 "" ""))]
15060 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15061 "jmp\t{*%%}r11"
15062 [(set_attr "type" "call")])
15063
15064
15065 ;; Call subroutine, returning value in operand 0
15066
15067 (define_expand "call_value_pop"
15068 [(parallel [(set (match_operand 0 "" "")
15069 (call (match_operand:QI 1 "" "")
15070 (match_operand:SI 2 "" "")))
15071 (set (reg:SI SP_REG)
15072 (plus:SI (reg:SI SP_REG)
15073 (match_operand:SI 4 "" "")))])]
15074 "!TARGET_64BIT"
15075 {
15076 ix86_expand_call (operands[0], operands[1], operands[2],
15077 operands[3], operands[4], 0);
15078 DONE;
15079 })
15080
15081 (define_expand "call_value"
15082 [(set (match_operand 0 "" "")
15083 (call (match_operand:QI 1 "" "")
15084 (match_operand:SI 2 "" "")))
15085 (use (match_operand:SI 3 "" ""))]
15086 ;; Operand 2 not used on the i386.
15087 ""
15088 {
15089 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15090 DONE;
15091 })
15092
15093 (define_expand "sibcall_value"
15094 [(set (match_operand 0 "" "")
15095 (call (match_operand:QI 1 "" "")
15096 (match_operand:SI 2 "" "")))
15097 (use (match_operand:SI 3 "" ""))]
15098 ;; Operand 2 not used on the i386.
15099 ""
15100 {
15101 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15102 DONE;
15103 })
15104
15105 ;; Call subroutine returning any type.
15106
15107 (define_expand "untyped_call"
15108 [(parallel [(call (match_operand 0 "" "")
15109 (const_int 0))
15110 (match_operand 1 "" "")
15111 (match_operand 2 "" "")])]
15112 ""
15113 {
15114 int i;
15115
15116 /* In order to give reg-stack an easier job in validating two
15117 coprocessor registers as containing a possible return value,
15118 simply pretend the untyped call returns a complex long double
15119 value. */
15120
15121 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15122 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15123 operands[0], const0_rtx,
15124 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15125 : X64_SSE_REGPARM_MAX)
15126 - 1),
15127 NULL, 0);
15128
15129 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15130 {
15131 rtx set = XVECEXP (operands[2], 0, i);
15132 emit_move_insn (SET_DEST (set), SET_SRC (set));
15133 }
15134
15135 /* The optimizer does not know that the call sets the function value
15136 registers we stored in the result block. We avoid problems by
15137 claiming that all hard registers are used and clobbered at this
15138 point. */
15139 emit_insn (gen_blockage ());
15140
15141 DONE;
15142 })
15143 \f
15144 ;; Prologue and epilogue instructions
15145
15146 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15147 ;; all of memory. This blocks insns from being moved across this point.
15148
15149 (define_insn "blockage"
15150 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15151 ""
15152 ""
15153 [(set_attr "length" "0")])
15154
15155 ;; As USE insns aren't meaningful after reload, this is used instead
15156 ;; to prevent deleting instructions setting registers for PIC code
15157 (define_insn "prologue_use"
15158 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15159 ""
15160 ""
15161 [(set_attr "length" "0")])
15162
15163 ;; Insn emitted into the body of a function to return from a function.
15164 ;; This is only done if the function's epilogue is known to be simple.
15165 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15166
15167 (define_expand "return"
15168 [(return)]
15169 "ix86_can_use_return_insn_p ()"
15170 {
15171 if (crtl->args.pops_args)
15172 {
15173 rtx popc = GEN_INT (crtl->args.pops_args);
15174 emit_jump_insn (gen_return_pop_internal (popc));
15175 DONE;
15176 }
15177 })
15178
15179 (define_insn "return_internal"
15180 [(return)]
15181 "reload_completed"
15182 "ret"
15183 [(set_attr "length" "1")
15184 (set_attr "length_immediate" "0")
15185 (set_attr "modrm" "0")])
15186
15187 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15188 ;; instruction Athlon and K8 have.
15189
15190 (define_insn "return_internal_long"
15191 [(return)
15192 (unspec [(const_int 0)] UNSPEC_REP)]
15193 "reload_completed"
15194 "rep\;ret"
15195 [(set_attr "length" "1")
15196 (set_attr "length_immediate" "0")
15197 (set_attr "prefix_rep" "1")
15198 (set_attr "modrm" "0")])
15199
15200 (define_insn "return_pop_internal"
15201 [(return)
15202 (use (match_operand:SI 0 "const_int_operand" ""))]
15203 "reload_completed"
15204 "ret\t%0"
15205 [(set_attr "length" "3")
15206 (set_attr "length_immediate" "2")
15207 (set_attr "modrm" "0")])
15208
15209 (define_insn "return_indirect_internal"
15210 [(return)
15211 (use (match_operand:SI 0 "register_operand" "r"))]
15212 "reload_completed"
15213 "jmp\t%A0"
15214 [(set_attr "type" "ibr")
15215 (set_attr "length_immediate" "0")])
15216
15217 (define_insn "nop"
15218 [(const_int 0)]
15219 ""
15220 "nop"
15221 [(set_attr "length" "1")
15222 (set_attr "length_immediate" "0")
15223 (set_attr "modrm" "0")])
15224
15225 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15226 ;; branch prediction penalty for the third jump in a 16-byte
15227 ;; block on K8.
15228
15229 (define_insn "align"
15230 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15231 ""
15232 {
15233 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15234 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15235 #else
15236 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15237 The align insn is used to avoid 3 jump instructions in the row to improve
15238 branch prediction and the benefits hardly outweigh the cost of extra 8
15239 nops on the average inserted by full alignment pseudo operation. */
15240 #endif
15241 return "";
15242 }
15243 [(set_attr "length" "16")])
15244
15245 (define_expand "prologue"
15246 [(const_int 0)]
15247 ""
15248 "ix86_expand_prologue (); DONE;")
15249
15250 (define_insn "set_got"
15251 [(set (match_operand:SI 0 "register_operand" "=r")
15252 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15253 (clobber (reg:CC FLAGS_REG))]
15254 "!TARGET_64BIT"
15255 { return output_set_got (operands[0], NULL_RTX); }
15256 [(set_attr "type" "multi")
15257 (set_attr "length" "12")])
15258
15259 (define_insn "set_got_labelled"
15260 [(set (match_operand:SI 0 "register_operand" "=r")
15261 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15262 UNSPEC_SET_GOT))
15263 (clobber (reg:CC FLAGS_REG))]
15264 "!TARGET_64BIT"
15265 { return output_set_got (operands[0], operands[1]); }
15266 [(set_attr "type" "multi")
15267 (set_attr "length" "12")])
15268
15269 (define_insn "set_got_rex64"
15270 [(set (match_operand:DI 0 "register_operand" "=r")
15271 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15272 "TARGET_64BIT"
15273 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15274 [(set_attr "type" "lea")
15275 (set_attr "length" "6")])
15276
15277 (define_insn "set_rip_rex64"
15278 [(set (match_operand:DI 0 "register_operand" "=r")
15279 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15280 "TARGET_64BIT"
15281 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15282 [(set_attr "type" "lea")
15283 (set_attr "length" "6")])
15284
15285 (define_insn "set_got_offset_rex64"
15286 [(set (match_operand:DI 0 "register_operand" "=r")
15287 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15288 "TARGET_64BIT"
15289 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15290 [(set_attr "type" "imov")
15291 (set_attr "length" "11")])
15292
15293 (define_expand "epilogue"
15294 [(const_int 0)]
15295 ""
15296 "ix86_expand_epilogue (1); DONE;")
15297
15298 (define_expand "sibcall_epilogue"
15299 [(const_int 0)]
15300 ""
15301 "ix86_expand_epilogue (0); DONE;")
15302
15303 (define_expand "eh_return"
15304 [(use (match_operand 0 "register_operand" ""))]
15305 ""
15306 {
15307 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15308
15309 /* Tricky bit: we write the address of the handler to which we will
15310 be returning into someone else's stack frame, one word below the
15311 stack address we wish to restore. */
15312 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15313 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15314 tmp = gen_rtx_MEM (Pmode, tmp);
15315 emit_move_insn (tmp, ra);
15316
15317 if (Pmode == SImode)
15318 emit_jump_insn (gen_eh_return_si (sa));
15319 else
15320 emit_jump_insn (gen_eh_return_di (sa));
15321 emit_barrier ();
15322 DONE;
15323 })
15324
15325 (define_insn_and_split "eh_return_<mode>"
15326 [(set (pc)
15327 (unspec [(match_operand:P 0 "register_operand" "c")]
15328 UNSPEC_EH_RETURN))]
15329 ""
15330 "#"
15331 "reload_completed"
15332 [(const_int 0)]
15333 "ix86_expand_epilogue (2); DONE;")
15334
15335 (define_insn "leave"
15336 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15337 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15338 (clobber (mem:BLK (scratch)))]
15339 "!TARGET_64BIT"
15340 "leave"
15341 [(set_attr "type" "leave")])
15342
15343 (define_insn "leave_rex64"
15344 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15345 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15346 (clobber (mem:BLK (scratch)))]
15347 "TARGET_64BIT"
15348 "leave"
15349 [(set_attr "type" "leave")])
15350 \f
15351 (define_expand "ffssi2"
15352 [(parallel
15353 [(set (match_operand:SI 0 "register_operand" "")
15354 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15355 (clobber (match_scratch:SI 2 ""))
15356 (clobber (reg:CC FLAGS_REG))])]
15357 ""
15358 {
15359 if (TARGET_CMOVE)
15360 {
15361 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15362 DONE;
15363 }
15364 })
15365
15366 (define_expand "ffs_cmove"
15367 [(set (match_dup 2) (const_int -1))
15368 (parallel [(set (reg:CCZ FLAGS_REG)
15369 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15370 (const_int 0)))
15371 (set (match_operand:SI 0 "register_operand" "")
15372 (ctz:SI (match_dup 1)))])
15373 (set (match_dup 0) (if_then_else:SI
15374 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15375 (match_dup 2)
15376 (match_dup 0)))
15377 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15378 (clobber (reg:CC FLAGS_REG))])]
15379 "TARGET_CMOVE"
15380 "operands[2] = gen_reg_rtx (SImode);")
15381
15382 (define_insn_and_split "*ffs_no_cmove"
15383 [(set (match_operand:SI 0 "register_operand" "=r")
15384 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15385 (clobber (match_scratch:SI 2 "=&q"))
15386 (clobber (reg:CC FLAGS_REG))]
15387 "!TARGET_CMOVE"
15388 "#"
15389 "&& reload_completed"
15390 [(parallel [(set (reg:CCZ FLAGS_REG)
15391 (compare:CCZ (match_dup 1) (const_int 0)))
15392 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15393 (set (strict_low_part (match_dup 3))
15394 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15395 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15396 (clobber (reg:CC FLAGS_REG))])
15397 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15398 (clobber (reg:CC FLAGS_REG))])
15399 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15400 (clobber (reg:CC FLAGS_REG))])]
15401 {
15402 operands[3] = gen_lowpart (QImode, operands[2]);
15403 ix86_expand_clear (operands[2]);
15404 })
15405
15406 (define_insn "*ffssi_1"
15407 [(set (reg:CCZ FLAGS_REG)
15408 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15409 (const_int 0)))
15410 (set (match_operand:SI 0 "register_operand" "=r")
15411 (ctz:SI (match_dup 1)))]
15412 ""
15413 "bsf{l}\t{%1, %0|%0, %1}"
15414 [(set_attr "prefix_0f" "1")])
15415
15416 (define_expand "ffsdi2"
15417 [(set (match_dup 2) (const_int -1))
15418 (parallel [(set (reg:CCZ FLAGS_REG)
15419 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15420 (const_int 0)))
15421 (set (match_operand:DI 0 "register_operand" "")
15422 (ctz:DI (match_dup 1)))])
15423 (set (match_dup 0) (if_then_else:DI
15424 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15425 (match_dup 2)
15426 (match_dup 0)))
15427 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15428 (clobber (reg:CC FLAGS_REG))])]
15429 "TARGET_64BIT"
15430 "operands[2] = gen_reg_rtx (DImode);")
15431
15432 (define_insn "*ffsdi_1"
15433 [(set (reg:CCZ FLAGS_REG)
15434 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15435 (const_int 0)))
15436 (set (match_operand:DI 0 "register_operand" "=r")
15437 (ctz:DI (match_dup 1)))]
15438 "TARGET_64BIT"
15439 "bsf{q}\t{%1, %0|%0, %1}"
15440 [(set_attr "prefix_0f" "1")])
15441
15442 (define_insn "ctzsi2"
15443 [(set (match_operand:SI 0 "register_operand" "=r")
15444 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15445 (clobber (reg:CC FLAGS_REG))]
15446 ""
15447 "bsf{l}\t{%1, %0|%0, %1}"
15448 [(set_attr "prefix_0f" "1")])
15449
15450 (define_insn "ctzdi2"
15451 [(set (match_operand:DI 0 "register_operand" "=r")
15452 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15453 (clobber (reg:CC FLAGS_REG))]
15454 "TARGET_64BIT"
15455 "bsf{q}\t{%1, %0|%0, %1}"
15456 [(set_attr "prefix_0f" "1")])
15457
15458 (define_expand "clzsi2"
15459 [(parallel
15460 [(set (match_operand:SI 0 "register_operand" "")
15461 (minus:SI (const_int 31)
15462 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15463 (clobber (reg:CC FLAGS_REG))])
15464 (parallel
15465 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15466 (clobber (reg:CC FLAGS_REG))])]
15467 ""
15468 {
15469 if (TARGET_ABM)
15470 {
15471 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15472 DONE;
15473 }
15474 })
15475
15476 (define_insn "clzsi2_abm"
15477 [(set (match_operand:SI 0 "register_operand" "=r")
15478 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15479 (clobber (reg:CC FLAGS_REG))]
15480 "TARGET_ABM"
15481 "lzcnt{l}\t{%1, %0|%0, %1}"
15482 [(set_attr "prefix_rep" "1")
15483 (set_attr "type" "bitmanip")
15484 (set_attr "mode" "SI")])
15485
15486 (define_insn "*bsr"
15487 [(set (match_operand:SI 0 "register_operand" "=r")
15488 (minus:SI (const_int 31)
15489 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15490 (clobber (reg:CC FLAGS_REG))]
15491 ""
15492 "bsr{l}\t{%1, %0|%0, %1}"
15493 [(set_attr "prefix_0f" "1")
15494 (set_attr "mode" "SI")])
15495
15496 (define_insn "popcountsi2"
15497 [(set (match_operand:SI 0 "register_operand" "=r")
15498 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15499 (clobber (reg:CC FLAGS_REG))]
15500 "TARGET_POPCNT"
15501 "popcnt{l}\t{%1, %0|%0, %1}"
15502 [(set_attr "prefix_rep" "1")
15503 (set_attr "type" "bitmanip")
15504 (set_attr "mode" "SI")])
15505
15506 (define_insn "*popcountsi2_cmp"
15507 [(set (reg FLAGS_REG)
15508 (compare
15509 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15510 (const_int 0)))
15511 (set (match_operand:SI 0 "register_operand" "=r")
15512 (popcount:SI (match_dup 1)))]
15513 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15514 "popcnt{l}\t{%1, %0|%0, %1}"
15515 [(set_attr "prefix_rep" "1")
15516 (set_attr "type" "bitmanip")
15517 (set_attr "mode" "SI")])
15518
15519 (define_insn "*popcountsi2_cmp_zext"
15520 [(set (reg FLAGS_REG)
15521 (compare
15522 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15523 (const_int 0)))
15524 (set (match_operand:DI 0 "register_operand" "=r")
15525 (zero_extend:DI(popcount:SI (match_dup 1))))]
15526 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15527 "popcnt{l}\t{%1, %0|%0, %1}"
15528 [(set_attr "prefix_rep" "1")
15529 (set_attr "type" "bitmanip")
15530 (set_attr "mode" "SI")])
15531
15532 (define_expand "bswapsi2"
15533 [(set (match_operand:SI 0 "register_operand" "")
15534 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15535 ""
15536 {
15537 if (!TARGET_BSWAP)
15538 {
15539 rtx x = operands[0];
15540
15541 emit_move_insn (x, operands[1]);
15542 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15543 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15544 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15545 DONE;
15546 }
15547 })
15548
15549 (define_insn "*bswapsi_1"
15550 [(set (match_operand:SI 0 "register_operand" "=r")
15551 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15552 "TARGET_BSWAP"
15553 "bswap\t%0"
15554 [(set_attr "prefix_0f" "1")
15555 (set_attr "length" "2")])
15556
15557 (define_insn "*bswaphi_lowpart_1"
15558 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15559 (bswap:HI (match_dup 0)))
15560 (clobber (reg:CC FLAGS_REG))]
15561 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15562 "@
15563 xchg{b}\t{%h0, %b0|%b0, %h0}
15564 rol{w}\t{$8, %0|%0, 8}"
15565 [(set_attr "length" "2,4")
15566 (set_attr "mode" "QI,HI")])
15567
15568 (define_insn "bswaphi_lowpart"
15569 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15570 (bswap:HI (match_dup 0)))
15571 (clobber (reg:CC FLAGS_REG))]
15572 ""
15573 "rol{w}\t{$8, %0|%0, 8}"
15574 [(set_attr "length" "4")
15575 (set_attr "mode" "HI")])
15576
15577 (define_insn "bswapdi2"
15578 [(set (match_operand:DI 0 "register_operand" "=r")
15579 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15580 "TARGET_64BIT"
15581 "bswap\t%0"
15582 [(set_attr "prefix_0f" "1")
15583 (set_attr "length" "3")])
15584
15585 (define_expand "clzdi2"
15586 [(parallel
15587 [(set (match_operand:DI 0 "register_operand" "")
15588 (minus:DI (const_int 63)
15589 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15590 (clobber (reg:CC FLAGS_REG))])
15591 (parallel
15592 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15593 (clobber (reg:CC FLAGS_REG))])]
15594 "TARGET_64BIT"
15595 {
15596 if (TARGET_ABM)
15597 {
15598 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15599 DONE;
15600 }
15601 })
15602
15603 (define_insn "clzdi2_abm"
15604 [(set (match_operand:DI 0 "register_operand" "=r")
15605 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15606 (clobber (reg:CC FLAGS_REG))]
15607 "TARGET_64BIT && TARGET_ABM"
15608 "lzcnt{q}\t{%1, %0|%0, %1}"
15609 [(set_attr "prefix_rep" "1")
15610 (set_attr "type" "bitmanip")
15611 (set_attr "mode" "DI")])
15612
15613 (define_insn "*bsr_rex64"
15614 [(set (match_operand:DI 0 "register_operand" "=r")
15615 (minus:DI (const_int 63)
15616 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15617 (clobber (reg:CC FLAGS_REG))]
15618 "TARGET_64BIT"
15619 "bsr{q}\t{%1, %0|%0, %1}"
15620 [(set_attr "prefix_0f" "1")
15621 (set_attr "mode" "DI")])
15622
15623 (define_insn "popcountdi2"
15624 [(set (match_operand:DI 0 "register_operand" "=r")
15625 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15626 (clobber (reg:CC FLAGS_REG))]
15627 "TARGET_64BIT && TARGET_POPCNT"
15628 "popcnt{q}\t{%1, %0|%0, %1}"
15629 [(set_attr "prefix_rep" "1")
15630 (set_attr "type" "bitmanip")
15631 (set_attr "mode" "DI")])
15632
15633 (define_insn "*popcountdi2_cmp"
15634 [(set (reg FLAGS_REG)
15635 (compare
15636 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15637 (const_int 0)))
15638 (set (match_operand:DI 0 "register_operand" "=r")
15639 (popcount:DI (match_dup 1)))]
15640 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15641 "popcnt{q}\t{%1, %0|%0, %1}"
15642 [(set_attr "prefix_rep" "1")
15643 (set_attr "type" "bitmanip")
15644 (set_attr "mode" "DI")])
15645
15646 (define_expand "clzhi2"
15647 [(parallel
15648 [(set (match_operand:HI 0 "register_operand" "")
15649 (minus:HI (const_int 15)
15650 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15651 (clobber (reg:CC FLAGS_REG))])
15652 (parallel
15653 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15654 (clobber (reg:CC FLAGS_REG))])]
15655 ""
15656 {
15657 if (TARGET_ABM)
15658 {
15659 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15660 DONE;
15661 }
15662 })
15663
15664 (define_insn "clzhi2_abm"
15665 [(set (match_operand:HI 0 "register_operand" "=r")
15666 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15667 (clobber (reg:CC FLAGS_REG))]
15668 "TARGET_ABM"
15669 "lzcnt{w}\t{%1, %0|%0, %1}"
15670 [(set_attr "prefix_rep" "1")
15671 (set_attr "type" "bitmanip")
15672 (set_attr "mode" "HI")])
15673
15674 (define_insn "*bsrhi"
15675 [(set (match_operand:HI 0 "register_operand" "=r")
15676 (minus:HI (const_int 15)
15677 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15678 (clobber (reg:CC FLAGS_REG))]
15679 ""
15680 "bsr{w}\t{%1, %0|%0, %1}"
15681 [(set_attr "prefix_0f" "1")
15682 (set_attr "mode" "HI")])
15683
15684 (define_insn "popcounthi2"
15685 [(set (match_operand:HI 0 "register_operand" "=r")
15686 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15687 (clobber (reg:CC FLAGS_REG))]
15688 "TARGET_POPCNT"
15689 "popcnt{w}\t{%1, %0|%0, %1}"
15690 [(set_attr "prefix_rep" "1")
15691 (set_attr "type" "bitmanip")
15692 (set_attr "mode" "HI")])
15693
15694 (define_insn "*popcounthi2_cmp"
15695 [(set (reg FLAGS_REG)
15696 (compare
15697 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15698 (const_int 0)))
15699 (set (match_operand:HI 0 "register_operand" "=r")
15700 (popcount:HI (match_dup 1)))]
15701 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15702 "popcnt{w}\t{%1, %0|%0, %1}"
15703 [(set_attr "prefix_rep" "1")
15704 (set_attr "type" "bitmanip")
15705 (set_attr "mode" "HI")])
15706
15707 (define_expand "paritydi2"
15708 [(set (match_operand:DI 0 "register_operand" "")
15709 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15710 "! TARGET_POPCNT"
15711 {
15712 rtx scratch = gen_reg_rtx (QImode);
15713 rtx cond;
15714
15715 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15716 NULL_RTX, operands[1]));
15717
15718 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15719 gen_rtx_REG (CCmode, FLAGS_REG),
15720 const0_rtx);
15721 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15722
15723 if (TARGET_64BIT)
15724 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15725 else
15726 {
15727 rtx tmp = gen_reg_rtx (SImode);
15728
15729 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15730 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15731 }
15732 DONE;
15733 })
15734
15735 (define_insn_and_split "paritydi2_cmp"
15736 [(set (reg:CC FLAGS_REG)
15737 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15738 (clobber (match_scratch:DI 0 "=r"))
15739 (clobber (match_scratch:SI 1 "=&r"))
15740 (clobber (match_scratch:HI 2 "=Q"))]
15741 "! TARGET_POPCNT"
15742 "#"
15743 "&& reload_completed"
15744 [(parallel
15745 [(set (match_dup 1)
15746 (xor:SI (match_dup 1) (match_dup 4)))
15747 (clobber (reg:CC FLAGS_REG))])
15748 (parallel
15749 [(set (reg:CC FLAGS_REG)
15750 (parity:CC (match_dup 1)))
15751 (clobber (match_dup 1))
15752 (clobber (match_dup 2))])]
15753 {
15754 operands[4] = gen_lowpart (SImode, operands[3]);
15755
15756 if (TARGET_64BIT)
15757 {
15758 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15759 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15760 }
15761 else
15762 operands[1] = gen_highpart (SImode, operands[3]);
15763 })
15764
15765 (define_expand "paritysi2"
15766 [(set (match_operand:SI 0 "register_operand" "")
15767 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15768 "! TARGET_POPCNT"
15769 {
15770 rtx scratch = gen_reg_rtx (QImode);
15771 rtx cond;
15772
15773 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15774
15775 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15776 gen_rtx_REG (CCmode, FLAGS_REG),
15777 const0_rtx);
15778 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15779
15780 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15781 DONE;
15782 })
15783
15784 (define_insn_and_split "paritysi2_cmp"
15785 [(set (reg:CC FLAGS_REG)
15786 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15787 (clobber (match_scratch:SI 0 "=r"))
15788 (clobber (match_scratch:HI 1 "=&Q"))]
15789 "! TARGET_POPCNT"
15790 "#"
15791 "&& reload_completed"
15792 [(parallel
15793 [(set (match_dup 1)
15794 (xor:HI (match_dup 1) (match_dup 3)))
15795 (clobber (reg:CC FLAGS_REG))])
15796 (parallel
15797 [(set (reg:CC FLAGS_REG)
15798 (parity:CC (match_dup 1)))
15799 (clobber (match_dup 1))])]
15800 {
15801 operands[3] = gen_lowpart (HImode, operands[2]);
15802
15803 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15804 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15805 })
15806
15807 (define_insn "*parityhi2_cmp"
15808 [(set (reg:CC FLAGS_REG)
15809 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15810 (clobber (match_scratch:HI 0 "=Q"))]
15811 "! TARGET_POPCNT"
15812 "xor{b}\t{%h0, %b0|%b0, %h0}"
15813 [(set_attr "length" "2")
15814 (set_attr "mode" "HI")])
15815
15816 (define_insn "*parityqi2_cmp"
15817 [(set (reg:CC FLAGS_REG)
15818 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15819 "! TARGET_POPCNT"
15820 "test{b}\t%0, %0"
15821 [(set_attr "length" "2")
15822 (set_attr "mode" "QI")])
15823 \f
15824 ;; Thread-local storage patterns for ELF.
15825 ;;
15826 ;; Note that these code sequences must appear exactly as shown
15827 ;; in order to allow linker relaxation.
15828
15829 (define_insn "*tls_global_dynamic_32_gnu"
15830 [(set (match_operand:SI 0 "register_operand" "=a")
15831 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15832 (match_operand:SI 2 "tls_symbolic_operand" "")
15833 (match_operand:SI 3 "call_insn_operand" "")]
15834 UNSPEC_TLS_GD))
15835 (clobber (match_scratch:SI 4 "=d"))
15836 (clobber (match_scratch:SI 5 "=c"))
15837 (clobber (reg:CC FLAGS_REG))]
15838 "!TARGET_64BIT && TARGET_GNU_TLS"
15839 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15840 [(set_attr "type" "multi")
15841 (set_attr "length" "12")])
15842
15843 (define_insn "*tls_global_dynamic_32_sun"
15844 [(set (match_operand:SI 0 "register_operand" "=a")
15845 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15846 (match_operand:SI 2 "tls_symbolic_operand" "")
15847 (match_operand:SI 3 "call_insn_operand" "")]
15848 UNSPEC_TLS_GD))
15849 (clobber (match_scratch:SI 4 "=d"))
15850 (clobber (match_scratch:SI 5 "=c"))
15851 (clobber (reg:CC FLAGS_REG))]
15852 "!TARGET_64BIT && TARGET_SUN_TLS"
15853 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15854 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15855 [(set_attr "type" "multi")
15856 (set_attr "length" "14")])
15857
15858 (define_expand "tls_global_dynamic_32"
15859 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15860 (unspec:SI
15861 [(match_dup 2)
15862 (match_operand:SI 1 "tls_symbolic_operand" "")
15863 (match_dup 3)]
15864 UNSPEC_TLS_GD))
15865 (clobber (match_scratch:SI 4 ""))
15866 (clobber (match_scratch:SI 5 ""))
15867 (clobber (reg:CC FLAGS_REG))])]
15868 ""
15869 {
15870 if (flag_pic)
15871 operands[2] = pic_offset_table_rtx;
15872 else
15873 {
15874 operands[2] = gen_reg_rtx (Pmode);
15875 emit_insn (gen_set_got (operands[2]));
15876 }
15877 if (TARGET_GNU2_TLS)
15878 {
15879 emit_insn (gen_tls_dynamic_gnu2_32
15880 (operands[0], operands[1], operands[2]));
15881 DONE;
15882 }
15883 operands[3] = ix86_tls_get_addr ();
15884 })
15885
15886 (define_insn "*tls_global_dynamic_64"
15887 [(set (match_operand:DI 0 "register_operand" "=a")
15888 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15889 (match_operand:DI 3 "" "")))
15890 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15891 UNSPEC_TLS_GD)]
15892 "TARGET_64BIT"
15893 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15894 [(set_attr "type" "multi")
15895 (set_attr "length" "16")])
15896
15897 (define_expand "tls_global_dynamic_64"
15898 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15899 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15900 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15901 UNSPEC_TLS_GD)])]
15902 ""
15903 {
15904 if (TARGET_GNU2_TLS)
15905 {
15906 emit_insn (gen_tls_dynamic_gnu2_64
15907 (operands[0], operands[1]));
15908 DONE;
15909 }
15910 operands[2] = ix86_tls_get_addr ();
15911 })
15912
15913 (define_insn "*tls_local_dynamic_base_32_gnu"
15914 [(set (match_operand:SI 0 "register_operand" "=a")
15915 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15916 (match_operand:SI 2 "call_insn_operand" "")]
15917 UNSPEC_TLS_LD_BASE))
15918 (clobber (match_scratch:SI 3 "=d"))
15919 (clobber (match_scratch:SI 4 "=c"))
15920 (clobber (reg:CC FLAGS_REG))]
15921 "!TARGET_64BIT && TARGET_GNU_TLS"
15922 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15923 [(set_attr "type" "multi")
15924 (set_attr "length" "11")])
15925
15926 (define_insn "*tls_local_dynamic_base_32_sun"
15927 [(set (match_operand:SI 0 "register_operand" "=a")
15928 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15929 (match_operand:SI 2 "call_insn_operand" "")]
15930 UNSPEC_TLS_LD_BASE))
15931 (clobber (match_scratch:SI 3 "=d"))
15932 (clobber (match_scratch:SI 4 "=c"))
15933 (clobber (reg:CC FLAGS_REG))]
15934 "!TARGET_64BIT && TARGET_SUN_TLS"
15935 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15936 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15937 [(set_attr "type" "multi")
15938 (set_attr "length" "13")])
15939
15940 (define_expand "tls_local_dynamic_base_32"
15941 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15942 (unspec:SI [(match_dup 1) (match_dup 2)]
15943 UNSPEC_TLS_LD_BASE))
15944 (clobber (match_scratch:SI 3 ""))
15945 (clobber (match_scratch:SI 4 ""))
15946 (clobber (reg:CC FLAGS_REG))])]
15947 ""
15948 {
15949 if (flag_pic)
15950 operands[1] = pic_offset_table_rtx;
15951 else
15952 {
15953 operands[1] = gen_reg_rtx (Pmode);
15954 emit_insn (gen_set_got (operands[1]));
15955 }
15956 if (TARGET_GNU2_TLS)
15957 {
15958 emit_insn (gen_tls_dynamic_gnu2_32
15959 (operands[0], ix86_tls_module_base (), operands[1]));
15960 DONE;
15961 }
15962 operands[2] = ix86_tls_get_addr ();
15963 })
15964
15965 (define_insn "*tls_local_dynamic_base_64"
15966 [(set (match_operand:DI 0 "register_operand" "=a")
15967 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15968 (match_operand:DI 2 "" "")))
15969 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15970 "TARGET_64BIT"
15971 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15972 [(set_attr "type" "multi")
15973 (set_attr "length" "12")])
15974
15975 (define_expand "tls_local_dynamic_base_64"
15976 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15977 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15978 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15979 ""
15980 {
15981 if (TARGET_GNU2_TLS)
15982 {
15983 emit_insn (gen_tls_dynamic_gnu2_64
15984 (operands[0], ix86_tls_module_base ()));
15985 DONE;
15986 }
15987 operands[1] = ix86_tls_get_addr ();
15988 })
15989
15990 ;; Local dynamic of a single variable is a lose. Show combine how
15991 ;; to convert that back to global dynamic.
15992
15993 (define_insn_and_split "*tls_local_dynamic_32_once"
15994 [(set (match_operand:SI 0 "register_operand" "=a")
15995 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15996 (match_operand:SI 2 "call_insn_operand" "")]
15997 UNSPEC_TLS_LD_BASE)
15998 (const:SI (unspec:SI
15999 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16000 UNSPEC_DTPOFF))))
16001 (clobber (match_scratch:SI 4 "=d"))
16002 (clobber (match_scratch:SI 5 "=c"))
16003 (clobber (reg:CC FLAGS_REG))]
16004 ""
16005 "#"
16006 ""
16007 [(parallel [(set (match_dup 0)
16008 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16009 UNSPEC_TLS_GD))
16010 (clobber (match_dup 4))
16011 (clobber (match_dup 5))
16012 (clobber (reg:CC FLAGS_REG))])]
16013 "")
16014
16015 ;; Load and add the thread base pointer from %gs:0.
16016
16017 (define_insn "*load_tp_si"
16018 [(set (match_operand:SI 0 "register_operand" "=r")
16019 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16020 "!TARGET_64BIT"
16021 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16022 [(set_attr "type" "imov")
16023 (set_attr "modrm" "0")
16024 (set_attr "length" "7")
16025 (set_attr "memory" "load")
16026 (set_attr "imm_disp" "false")])
16027
16028 (define_insn "*add_tp_si"
16029 [(set (match_operand:SI 0 "register_operand" "=r")
16030 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16031 (match_operand:SI 1 "register_operand" "0")))
16032 (clobber (reg:CC FLAGS_REG))]
16033 "!TARGET_64BIT"
16034 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16035 [(set_attr "type" "alu")
16036 (set_attr "modrm" "0")
16037 (set_attr "length" "7")
16038 (set_attr "memory" "load")
16039 (set_attr "imm_disp" "false")])
16040
16041 (define_insn "*load_tp_di"
16042 [(set (match_operand:DI 0 "register_operand" "=r")
16043 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16044 "TARGET_64BIT"
16045 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16046 [(set_attr "type" "imov")
16047 (set_attr "modrm" "0")
16048 (set_attr "length" "7")
16049 (set_attr "memory" "load")
16050 (set_attr "imm_disp" "false")])
16051
16052 (define_insn "*add_tp_di"
16053 [(set (match_operand:DI 0 "register_operand" "=r")
16054 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16055 (match_operand:DI 1 "register_operand" "0")))
16056 (clobber (reg:CC FLAGS_REG))]
16057 "TARGET_64BIT"
16058 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16059 [(set_attr "type" "alu")
16060 (set_attr "modrm" "0")
16061 (set_attr "length" "7")
16062 (set_attr "memory" "load")
16063 (set_attr "imm_disp" "false")])
16064
16065 ;; GNU2 TLS patterns can be split.
16066
16067 (define_expand "tls_dynamic_gnu2_32"
16068 [(set (match_dup 3)
16069 (plus:SI (match_operand:SI 2 "register_operand" "")
16070 (const:SI
16071 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16072 UNSPEC_TLSDESC))))
16073 (parallel
16074 [(set (match_operand:SI 0 "register_operand" "")
16075 (unspec:SI [(match_dup 1) (match_dup 3)
16076 (match_dup 2) (reg:SI SP_REG)]
16077 UNSPEC_TLSDESC))
16078 (clobber (reg:CC FLAGS_REG))])]
16079 "!TARGET_64BIT && TARGET_GNU2_TLS"
16080 {
16081 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16082 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16083 })
16084
16085 (define_insn "*tls_dynamic_lea_32"
16086 [(set (match_operand:SI 0 "register_operand" "=r")
16087 (plus:SI (match_operand:SI 1 "register_operand" "b")
16088 (const:SI
16089 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16090 UNSPEC_TLSDESC))))]
16091 "!TARGET_64BIT && TARGET_GNU2_TLS"
16092 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16093 [(set_attr "type" "lea")
16094 (set_attr "mode" "SI")
16095 (set_attr "length" "6")
16096 (set_attr "length_address" "4")])
16097
16098 (define_insn "*tls_dynamic_call_32"
16099 [(set (match_operand:SI 0 "register_operand" "=a")
16100 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16101 (match_operand:SI 2 "register_operand" "0")
16102 ;; we have to make sure %ebx still points to the GOT
16103 (match_operand:SI 3 "register_operand" "b")
16104 (reg:SI SP_REG)]
16105 UNSPEC_TLSDESC))
16106 (clobber (reg:CC FLAGS_REG))]
16107 "!TARGET_64BIT && TARGET_GNU2_TLS"
16108 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16109 [(set_attr "type" "call")
16110 (set_attr "length" "2")
16111 (set_attr "length_address" "0")])
16112
16113 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16114 [(set (match_operand:SI 0 "register_operand" "=&a")
16115 (plus:SI
16116 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16117 (match_operand:SI 4 "" "")
16118 (match_operand:SI 2 "register_operand" "b")
16119 (reg:SI SP_REG)]
16120 UNSPEC_TLSDESC)
16121 (const:SI (unspec:SI
16122 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16123 UNSPEC_DTPOFF))))
16124 (clobber (reg:CC FLAGS_REG))]
16125 "!TARGET_64BIT && TARGET_GNU2_TLS"
16126 "#"
16127 ""
16128 [(set (match_dup 0) (match_dup 5))]
16129 {
16130 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16131 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16132 })
16133
16134 (define_expand "tls_dynamic_gnu2_64"
16135 [(set (match_dup 2)
16136 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16137 UNSPEC_TLSDESC))
16138 (parallel
16139 [(set (match_operand:DI 0 "register_operand" "")
16140 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16141 UNSPEC_TLSDESC))
16142 (clobber (reg:CC FLAGS_REG))])]
16143 "TARGET_64BIT && TARGET_GNU2_TLS"
16144 {
16145 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16146 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16147 })
16148
16149 (define_insn "*tls_dynamic_lea_64"
16150 [(set (match_operand:DI 0 "register_operand" "=r")
16151 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16152 UNSPEC_TLSDESC))]
16153 "TARGET_64BIT && TARGET_GNU2_TLS"
16154 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16155 [(set_attr "type" "lea")
16156 (set_attr "mode" "DI")
16157 (set_attr "length" "7")
16158 (set_attr "length_address" "4")])
16159
16160 (define_insn "*tls_dynamic_call_64"
16161 [(set (match_operand:DI 0 "register_operand" "=a")
16162 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16163 (match_operand:DI 2 "register_operand" "0")
16164 (reg:DI SP_REG)]
16165 UNSPEC_TLSDESC))
16166 (clobber (reg:CC FLAGS_REG))]
16167 "TARGET_64BIT && TARGET_GNU2_TLS"
16168 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16169 [(set_attr "type" "call")
16170 (set_attr "length" "2")
16171 (set_attr "length_address" "0")])
16172
16173 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16174 [(set (match_operand:DI 0 "register_operand" "=&a")
16175 (plus:DI
16176 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16177 (match_operand:DI 3 "" "")
16178 (reg:DI SP_REG)]
16179 UNSPEC_TLSDESC)
16180 (const:DI (unspec:DI
16181 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16182 UNSPEC_DTPOFF))))
16183 (clobber (reg:CC FLAGS_REG))]
16184 "TARGET_64BIT && TARGET_GNU2_TLS"
16185 "#"
16186 ""
16187 [(set (match_dup 0) (match_dup 4))]
16188 {
16189 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16190 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16191 })
16192
16193 ;;
16194 \f
16195 ;; These patterns match the binary 387 instructions for addM3, subM3,
16196 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16197 ;; SFmode. The first is the normal insn, the second the same insn but
16198 ;; with one operand a conversion, and the third the same insn but with
16199 ;; the other operand a conversion. The conversion may be SFmode or
16200 ;; SImode if the target mode DFmode, but only SImode if the target mode
16201 ;; is SFmode.
16202
16203 ;; Gcc is slightly more smart about handling normal two address instructions
16204 ;; so use special patterns for add and mull.
16205
16206 (define_insn "*fop_<mode>_comm_mixed_avx"
16207 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16208 (match_operator:MODEF 3 "binary_fp_operator"
16209 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16210 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16211 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16212 && COMMUTATIVE_ARITH_P (operands[3])
16213 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16214 "* return output_387_binary_op (insn, operands);"
16215 [(set (attr "type")
16216 (if_then_else (eq_attr "alternative" "1")
16217 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16218 (const_string "ssemul")
16219 (const_string "sseadd"))
16220 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16221 (const_string "fmul")
16222 (const_string "fop"))))
16223 (set_attr "prefix" "orig,maybe_vex")
16224 (set_attr "mode" "<MODE>")])
16225
16226 (define_insn "*fop_<mode>_comm_mixed"
16227 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16228 (match_operator:MODEF 3 "binary_fp_operator"
16229 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16230 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16231 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16232 && COMMUTATIVE_ARITH_P (operands[3])
16233 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16234 "* return output_387_binary_op (insn, operands);"
16235 [(set (attr "type")
16236 (if_then_else (eq_attr "alternative" "1")
16237 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16238 (const_string "ssemul")
16239 (const_string "sseadd"))
16240 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16241 (const_string "fmul")
16242 (const_string "fop"))))
16243 (set_attr "mode" "<MODE>")])
16244
16245 (define_insn "*fop_<mode>_comm_avx"
16246 [(set (match_operand:MODEF 0 "register_operand" "=x")
16247 (match_operator:MODEF 3 "binary_fp_operator"
16248 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16249 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16250 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16251 && COMMUTATIVE_ARITH_P (operands[3])
16252 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16253 "* return output_387_binary_op (insn, operands);"
16254 [(set (attr "type")
16255 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16256 (const_string "ssemul")
16257 (const_string "sseadd")))
16258 (set_attr "prefix" "vex")
16259 (set_attr "mode" "<MODE>")])
16260
16261 (define_insn "*fop_<mode>_comm_sse"
16262 [(set (match_operand:MODEF 0 "register_operand" "=x")
16263 (match_operator:MODEF 3 "binary_fp_operator"
16264 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16265 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16266 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16267 && COMMUTATIVE_ARITH_P (operands[3])
16268 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16269 "* return output_387_binary_op (insn, operands);"
16270 [(set (attr "type")
16271 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16272 (const_string "ssemul")
16273 (const_string "sseadd")))
16274 (set_attr "mode" "<MODE>")])
16275
16276 (define_insn "*fop_<mode>_comm_i387"
16277 [(set (match_operand:MODEF 0 "register_operand" "=f")
16278 (match_operator:MODEF 3 "binary_fp_operator"
16279 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16280 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16281 "TARGET_80387
16282 && COMMUTATIVE_ARITH_P (operands[3])
16283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16284 "* return output_387_binary_op (insn, operands);"
16285 [(set (attr "type")
16286 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16287 (const_string "fmul")
16288 (const_string "fop")))
16289 (set_attr "mode" "<MODE>")])
16290
16291 (define_insn "*fop_<mode>_1_mixed_avx"
16292 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16293 (match_operator:MODEF 3 "binary_fp_operator"
16294 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16295 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16296 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16297 && !COMMUTATIVE_ARITH_P (operands[3])
16298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16299 "* return output_387_binary_op (insn, operands);"
16300 [(set (attr "type")
16301 (cond [(and (eq_attr "alternative" "2")
16302 (match_operand:MODEF 3 "mult_operator" ""))
16303 (const_string "ssemul")
16304 (and (eq_attr "alternative" "2")
16305 (match_operand:MODEF 3 "div_operator" ""))
16306 (const_string "ssediv")
16307 (eq_attr "alternative" "2")
16308 (const_string "sseadd")
16309 (match_operand:MODEF 3 "mult_operator" "")
16310 (const_string "fmul")
16311 (match_operand:MODEF 3 "div_operator" "")
16312 (const_string "fdiv")
16313 ]
16314 (const_string "fop")))
16315 (set_attr "prefix" "orig,orig,maybe_vex")
16316 (set_attr "mode" "<MODE>")])
16317
16318 (define_insn "*fop_<mode>_1_mixed"
16319 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16320 (match_operator:MODEF 3 "binary_fp_operator"
16321 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16322 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16324 && !COMMUTATIVE_ARITH_P (operands[3])
16325 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16326 "* return output_387_binary_op (insn, operands);"
16327 [(set (attr "type")
16328 (cond [(and (eq_attr "alternative" "2")
16329 (match_operand:MODEF 3 "mult_operator" ""))
16330 (const_string "ssemul")
16331 (and (eq_attr "alternative" "2")
16332 (match_operand:MODEF 3 "div_operator" ""))
16333 (const_string "ssediv")
16334 (eq_attr "alternative" "2")
16335 (const_string "sseadd")
16336 (match_operand:MODEF 3 "mult_operator" "")
16337 (const_string "fmul")
16338 (match_operand:MODEF 3 "div_operator" "")
16339 (const_string "fdiv")
16340 ]
16341 (const_string "fop")))
16342 (set_attr "mode" "<MODE>")])
16343
16344 (define_insn "*rcpsf2_sse"
16345 [(set (match_operand:SF 0 "register_operand" "=x")
16346 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16347 UNSPEC_RCP))]
16348 "TARGET_SSE_MATH"
16349 "%vrcpss\t{%1, %d0|%d0, %1}"
16350 [(set_attr "type" "sse")
16351 (set_attr "prefix" "maybe_vex")
16352 (set_attr "mode" "SF")])
16353
16354 (define_insn "*fop_<mode>_1_avx"
16355 [(set (match_operand:MODEF 0 "register_operand" "=x")
16356 (match_operator:MODEF 3 "binary_fp_operator"
16357 [(match_operand:MODEF 1 "register_operand" "x")
16358 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16359 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16360 && !COMMUTATIVE_ARITH_P (operands[3])"
16361 "* return output_387_binary_op (insn, operands);"
16362 [(set (attr "type")
16363 (cond [(match_operand:MODEF 3 "mult_operator" "")
16364 (const_string "ssemul")
16365 (match_operand:MODEF 3 "div_operator" "")
16366 (const_string "ssediv")
16367 ]
16368 (const_string "sseadd")))
16369 (set_attr "prefix" "vex")
16370 (set_attr "mode" "<MODE>")])
16371
16372 (define_insn "*fop_<mode>_1_sse"
16373 [(set (match_operand:MODEF 0 "register_operand" "=x")
16374 (match_operator:MODEF 3 "binary_fp_operator"
16375 [(match_operand:MODEF 1 "register_operand" "0")
16376 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16377 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378 && !COMMUTATIVE_ARITH_P (operands[3])"
16379 "* return output_387_binary_op (insn, operands);"
16380 [(set (attr "type")
16381 (cond [(match_operand:MODEF 3 "mult_operator" "")
16382 (const_string "ssemul")
16383 (match_operand:MODEF 3 "div_operator" "")
16384 (const_string "ssediv")
16385 ]
16386 (const_string "sseadd")))
16387 (set_attr "mode" "<MODE>")])
16388
16389 ;; This pattern is not fully shadowed by the pattern above.
16390 (define_insn "*fop_<mode>_1_i387"
16391 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16392 (match_operator:MODEF 3 "binary_fp_operator"
16393 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16394 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16395 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16396 && !COMMUTATIVE_ARITH_P (operands[3])
16397 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16398 "* return output_387_binary_op (insn, operands);"
16399 [(set (attr "type")
16400 (cond [(match_operand:MODEF 3 "mult_operator" "")
16401 (const_string "fmul")
16402 (match_operand:MODEF 3 "div_operator" "")
16403 (const_string "fdiv")
16404 ]
16405 (const_string "fop")))
16406 (set_attr "mode" "<MODE>")])
16407
16408 ;; ??? Add SSE splitters for these!
16409 (define_insn "*fop_<MODEF:mode>_2_i387"
16410 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16411 (match_operator:MODEF 3 "binary_fp_operator"
16412 [(float:MODEF
16413 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16414 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16415 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16416 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16417 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16418 [(set (attr "type")
16419 (cond [(match_operand:MODEF 3 "mult_operator" "")
16420 (const_string "fmul")
16421 (match_operand:MODEF 3 "div_operator" "")
16422 (const_string "fdiv")
16423 ]
16424 (const_string "fop")))
16425 (set_attr "fp_int_src" "true")
16426 (set_attr "mode" "<X87MODEI12:MODE>")])
16427
16428 (define_insn "*fop_<MODEF:mode>_3_i387"
16429 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16430 (match_operator:MODEF 3 "binary_fp_operator"
16431 [(match_operand:MODEF 1 "register_operand" "0,0")
16432 (float:MODEF
16433 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16434 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16435 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16436 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16437 [(set (attr "type")
16438 (cond [(match_operand:MODEF 3 "mult_operator" "")
16439 (const_string "fmul")
16440 (match_operand:MODEF 3 "div_operator" "")
16441 (const_string "fdiv")
16442 ]
16443 (const_string "fop")))
16444 (set_attr "fp_int_src" "true")
16445 (set_attr "mode" "<MODE>")])
16446
16447 (define_insn "*fop_df_4_i387"
16448 [(set (match_operand:DF 0 "register_operand" "=f,f")
16449 (match_operator:DF 3 "binary_fp_operator"
16450 [(float_extend:DF
16451 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16452 (match_operand:DF 2 "register_operand" "0,f")]))]
16453 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16454 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16455 "* return output_387_binary_op (insn, operands);"
16456 [(set (attr "type")
16457 (cond [(match_operand:DF 3 "mult_operator" "")
16458 (const_string "fmul")
16459 (match_operand:DF 3 "div_operator" "")
16460 (const_string "fdiv")
16461 ]
16462 (const_string "fop")))
16463 (set_attr "mode" "SF")])
16464
16465 (define_insn "*fop_df_5_i387"
16466 [(set (match_operand:DF 0 "register_operand" "=f,f")
16467 (match_operator:DF 3 "binary_fp_operator"
16468 [(match_operand:DF 1 "register_operand" "0,f")
16469 (float_extend:DF
16470 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16471 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16472 "* return output_387_binary_op (insn, operands);"
16473 [(set (attr "type")
16474 (cond [(match_operand:DF 3 "mult_operator" "")
16475 (const_string "fmul")
16476 (match_operand:DF 3 "div_operator" "")
16477 (const_string "fdiv")
16478 ]
16479 (const_string "fop")))
16480 (set_attr "mode" "SF")])
16481
16482 (define_insn "*fop_df_6_i387"
16483 [(set (match_operand:DF 0 "register_operand" "=f,f")
16484 (match_operator:DF 3 "binary_fp_operator"
16485 [(float_extend:DF
16486 (match_operand:SF 1 "register_operand" "0,f"))
16487 (float_extend:DF
16488 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16489 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16490 "* return output_387_binary_op (insn, operands);"
16491 [(set (attr "type")
16492 (cond [(match_operand:DF 3 "mult_operator" "")
16493 (const_string "fmul")
16494 (match_operand:DF 3 "div_operator" "")
16495 (const_string "fdiv")
16496 ]
16497 (const_string "fop")))
16498 (set_attr "mode" "SF")])
16499
16500 (define_insn "*fop_xf_comm_i387"
16501 [(set (match_operand:XF 0 "register_operand" "=f")
16502 (match_operator:XF 3 "binary_fp_operator"
16503 [(match_operand:XF 1 "register_operand" "%0")
16504 (match_operand:XF 2 "register_operand" "f")]))]
16505 "TARGET_80387
16506 && COMMUTATIVE_ARITH_P (operands[3])"
16507 "* return output_387_binary_op (insn, operands);"
16508 [(set (attr "type")
16509 (if_then_else (match_operand:XF 3 "mult_operator" "")
16510 (const_string "fmul")
16511 (const_string "fop")))
16512 (set_attr "mode" "XF")])
16513
16514 (define_insn "*fop_xf_1_i387"
16515 [(set (match_operand:XF 0 "register_operand" "=f,f")
16516 (match_operator:XF 3 "binary_fp_operator"
16517 [(match_operand:XF 1 "register_operand" "0,f")
16518 (match_operand:XF 2 "register_operand" "f,0")]))]
16519 "TARGET_80387
16520 && !COMMUTATIVE_ARITH_P (operands[3])"
16521 "* return output_387_binary_op (insn, operands);"
16522 [(set (attr "type")
16523 (cond [(match_operand:XF 3 "mult_operator" "")
16524 (const_string "fmul")
16525 (match_operand:XF 3 "div_operator" "")
16526 (const_string "fdiv")
16527 ]
16528 (const_string "fop")))
16529 (set_attr "mode" "XF")])
16530
16531 (define_insn "*fop_xf_2_i387"
16532 [(set (match_operand:XF 0 "register_operand" "=f,f")
16533 (match_operator:XF 3 "binary_fp_operator"
16534 [(float:XF
16535 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16536 (match_operand:XF 2 "register_operand" "0,0")]))]
16537 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16538 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16539 [(set (attr "type")
16540 (cond [(match_operand:XF 3 "mult_operator" "")
16541 (const_string "fmul")
16542 (match_operand:XF 3 "div_operator" "")
16543 (const_string "fdiv")
16544 ]
16545 (const_string "fop")))
16546 (set_attr "fp_int_src" "true")
16547 (set_attr "mode" "<MODE>")])
16548
16549 (define_insn "*fop_xf_3_i387"
16550 [(set (match_operand:XF 0 "register_operand" "=f,f")
16551 (match_operator:XF 3 "binary_fp_operator"
16552 [(match_operand:XF 1 "register_operand" "0,0")
16553 (float:XF
16554 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16555 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16556 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16557 [(set (attr "type")
16558 (cond [(match_operand:XF 3 "mult_operator" "")
16559 (const_string "fmul")
16560 (match_operand:XF 3 "div_operator" "")
16561 (const_string "fdiv")
16562 ]
16563 (const_string "fop")))
16564 (set_attr "fp_int_src" "true")
16565 (set_attr "mode" "<MODE>")])
16566
16567 (define_insn "*fop_xf_4_i387"
16568 [(set (match_operand:XF 0 "register_operand" "=f,f")
16569 (match_operator:XF 3 "binary_fp_operator"
16570 [(float_extend:XF
16571 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16572 (match_operand:XF 2 "register_operand" "0,f")]))]
16573 "TARGET_80387"
16574 "* return output_387_binary_op (insn, operands);"
16575 [(set (attr "type")
16576 (cond [(match_operand:XF 3 "mult_operator" "")
16577 (const_string "fmul")
16578 (match_operand:XF 3 "div_operator" "")
16579 (const_string "fdiv")
16580 ]
16581 (const_string "fop")))
16582 (set_attr "mode" "<MODE>")])
16583
16584 (define_insn "*fop_xf_5_i387"
16585 [(set (match_operand:XF 0 "register_operand" "=f,f")
16586 (match_operator:XF 3 "binary_fp_operator"
16587 [(match_operand:XF 1 "register_operand" "0,f")
16588 (float_extend:XF
16589 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16590 "TARGET_80387"
16591 "* return output_387_binary_op (insn, operands);"
16592 [(set (attr "type")
16593 (cond [(match_operand:XF 3 "mult_operator" "")
16594 (const_string "fmul")
16595 (match_operand:XF 3 "div_operator" "")
16596 (const_string "fdiv")
16597 ]
16598 (const_string "fop")))
16599 (set_attr "mode" "<MODE>")])
16600
16601 (define_insn "*fop_xf_6_i387"
16602 [(set (match_operand:XF 0 "register_operand" "=f,f")
16603 (match_operator:XF 3 "binary_fp_operator"
16604 [(float_extend:XF
16605 (match_operand:MODEF 1 "register_operand" "0,f"))
16606 (float_extend:XF
16607 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16608 "TARGET_80387"
16609 "* return output_387_binary_op (insn, operands);"
16610 [(set (attr "type")
16611 (cond [(match_operand:XF 3 "mult_operator" "")
16612 (const_string "fmul")
16613 (match_operand:XF 3 "div_operator" "")
16614 (const_string "fdiv")
16615 ]
16616 (const_string "fop")))
16617 (set_attr "mode" "<MODE>")])
16618
16619 (define_split
16620 [(set (match_operand 0 "register_operand" "")
16621 (match_operator 3 "binary_fp_operator"
16622 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16623 (match_operand 2 "register_operand" "")]))]
16624 "reload_completed
16625 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16626 [(const_int 0)]
16627 {
16628 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16629 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16630 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16631 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16632 GET_MODE (operands[3]),
16633 operands[4],
16634 operands[2])));
16635 ix86_free_from_memory (GET_MODE (operands[1]));
16636 DONE;
16637 })
16638
16639 (define_split
16640 [(set (match_operand 0 "register_operand" "")
16641 (match_operator 3 "binary_fp_operator"
16642 [(match_operand 1 "register_operand" "")
16643 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16644 "reload_completed
16645 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16646 [(const_int 0)]
16647 {
16648 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16649 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16650 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16651 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16652 GET_MODE (operands[3]),
16653 operands[1],
16654 operands[4])));
16655 ix86_free_from_memory (GET_MODE (operands[2]));
16656 DONE;
16657 })
16658 \f
16659 ;; FPU special functions.
16660
16661 ;; This pattern implements a no-op XFmode truncation for
16662 ;; all fancy i386 XFmode math functions.
16663
16664 (define_insn "truncxf<mode>2_i387_noop_unspec"
16665 [(set (match_operand:MODEF 0 "register_operand" "=f")
16666 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16667 UNSPEC_TRUNC_NOOP))]
16668 "TARGET_USE_FANCY_MATH_387"
16669 "* return output_387_reg_move (insn, operands);"
16670 [(set_attr "type" "fmov")
16671 (set_attr "mode" "<MODE>")])
16672
16673 (define_insn "sqrtxf2"
16674 [(set (match_operand:XF 0 "register_operand" "=f")
16675 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16676 "TARGET_USE_FANCY_MATH_387"
16677 "fsqrt"
16678 [(set_attr "type" "fpspc")
16679 (set_attr "mode" "XF")
16680 (set_attr "athlon_decode" "direct")
16681 (set_attr "amdfam10_decode" "direct")])
16682
16683 (define_insn "sqrt_extend<mode>xf2_i387"
16684 [(set (match_operand:XF 0 "register_operand" "=f")
16685 (sqrt:XF
16686 (float_extend:XF
16687 (match_operand:MODEF 1 "register_operand" "0"))))]
16688 "TARGET_USE_FANCY_MATH_387"
16689 "fsqrt"
16690 [(set_attr "type" "fpspc")
16691 (set_attr "mode" "XF")
16692 (set_attr "athlon_decode" "direct")
16693 (set_attr "amdfam10_decode" "direct")])
16694
16695 (define_insn "*rsqrtsf2_sse"
16696 [(set (match_operand:SF 0 "register_operand" "=x")
16697 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16698 UNSPEC_RSQRT))]
16699 "TARGET_SSE_MATH"
16700 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16701 [(set_attr "type" "sse")
16702 (set_attr "prefix" "maybe_vex")
16703 (set_attr "mode" "SF")])
16704
16705 (define_expand "rsqrtsf2"
16706 [(set (match_operand:SF 0 "register_operand" "")
16707 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16708 UNSPEC_RSQRT))]
16709 "TARGET_SSE_MATH"
16710 {
16711 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16712 DONE;
16713 })
16714
16715 (define_insn "*sqrt<mode>2_sse"
16716 [(set (match_operand:MODEF 0 "register_operand" "=x")
16717 (sqrt:MODEF
16718 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16719 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16720 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16721 [(set_attr "type" "sse")
16722 (set_attr "prefix" "maybe_vex")
16723 (set_attr "mode" "<MODE>")
16724 (set_attr "athlon_decode" "*")
16725 (set_attr "amdfam10_decode" "*")])
16726
16727 (define_expand "sqrt<mode>2"
16728 [(set (match_operand:MODEF 0 "register_operand" "")
16729 (sqrt:MODEF
16730 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16731 "TARGET_USE_FANCY_MATH_387
16732 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16733 {
16734 if (<MODE>mode == SFmode
16735 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16736 && flag_finite_math_only && !flag_trapping_math
16737 && flag_unsafe_math_optimizations)
16738 {
16739 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16740 DONE;
16741 }
16742
16743 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16744 {
16745 rtx op0 = gen_reg_rtx (XFmode);
16746 rtx op1 = force_reg (<MODE>mode, operands[1]);
16747
16748 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16749 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16750 DONE;
16751 }
16752 })
16753
16754 (define_insn "fpremxf4_i387"
16755 [(set (match_operand:XF 0 "register_operand" "=f")
16756 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16757 (match_operand:XF 3 "register_operand" "1")]
16758 UNSPEC_FPREM_F))
16759 (set (match_operand:XF 1 "register_operand" "=u")
16760 (unspec:XF [(match_dup 2) (match_dup 3)]
16761 UNSPEC_FPREM_U))
16762 (set (reg:CCFP FPSR_REG)
16763 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16764 UNSPEC_C2_FLAG))]
16765 "TARGET_USE_FANCY_MATH_387"
16766 "fprem"
16767 [(set_attr "type" "fpspc")
16768 (set_attr "mode" "XF")])
16769
16770 (define_expand "fmodxf3"
16771 [(use (match_operand:XF 0 "register_operand" ""))
16772 (use (match_operand:XF 1 "general_operand" ""))
16773 (use (match_operand:XF 2 "general_operand" ""))]
16774 "TARGET_USE_FANCY_MATH_387"
16775 {
16776 rtx label = gen_label_rtx ();
16777
16778 rtx op1 = gen_reg_rtx (XFmode);
16779 rtx op2 = gen_reg_rtx (XFmode);
16780
16781 emit_move_insn (op2, operands[2]);
16782 emit_move_insn (op1, operands[1]);
16783
16784 emit_label (label);
16785 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16786 ix86_emit_fp_unordered_jump (label);
16787 LABEL_NUSES (label) = 1;
16788
16789 emit_move_insn (operands[0], op1);
16790 DONE;
16791 })
16792
16793 (define_expand "fmod<mode>3"
16794 [(use (match_operand:MODEF 0 "register_operand" ""))
16795 (use (match_operand:MODEF 1 "general_operand" ""))
16796 (use (match_operand:MODEF 2 "general_operand" ""))]
16797 "TARGET_USE_FANCY_MATH_387"
16798 {
16799 rtx label = gen_label_rtx ();
16800
16801 rtx op1 = gen_reg_rtx (XFmode);
16802 rtx op2 = gen_reg_rtx (XFmode);
16803
16804 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16805 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16806
16807 emit_label (label);
16808 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16809 ix86_emit_fp_unordered_jump (label);
16810 LABEL_NUSES (label) = 1;
16811
16812 /* Truncate the result properly for strict SSE math. */
16813 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16814 && !TARGET_MIX_SSE_I387)
16815 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16816 else
16817 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16818
16819 DONE;
16820 })
16821
16822 (define_insn "fprem1xf4_i387"
16823 [(set (match_operand:XF 0 "register_operand" "=f")
16824 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16825 (match_operand:XF 3 "register_operand" "1")]
16826 UNSPEC_FPREM1_F))
16827 (set (match_operand:XF 1 "register_operand" "=u")
16828 (unspec:XF [(match_dup 2) (match_dup 3)]
16829 UNSPEC_FPREM1_U))
16830 (set (reg:CCFP FPSR_REG)
16831 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16832 UNSPEC_C2_FLAG))]
16833 "TARGET_USE_FANCY_MATH_387"
16834 "fprem1"
16835 [(set_attr "type" "fpspc")
16836 (set_attr "mode" "XF")])
16837
16838 (define_expand "remainderxf3"
16839 [(use (match_operand:XF 0 "register_operand" ""))
16840 (use (match_operand:XF 1 "general_operand" ""))
16841 (use (match_operand:XF 2 "general_operand" ""))]
16842 "TARGET_USE_FANCY_MATH_387"
16843 {
16844 rtx label = gen_label_rtx ();
16845
16846 rtx op1 = gen_reg_rtx (XFmode);
16847 rtx op2 = gen_reg_rtx (XFmode);
16848
16849 emit_move_insn (op2, operands[2]);
16850 emit_move_insn (op1, operands[1]);
16851
16852 emit_label (label);
16853 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16854 ix86_emit_fp_unordered_jump (label);
16855 LABEL_NUSES (label) = 1;
16856
16857 emit_move_insn (operands[0], op1);
16858 DONE;
16859 })
16860
16861 (define_expand "remainder<mode>3"
16862 [(use (match_operand:MODEF 0 "register_operand" ""))
16863 (use (match_operand:MODEF 1 "general_operand" ""))
16864 (use (match_operand:MODEF 2 "general_operand" ""))]
16865 "TARGET_USE_FANCY_MATH_387"
16866 {
16867 rtx label = gen_label_rtx ();
16868
16869 rtx op1 = gen_reg_rtx (XFmode);
16870 rtx op2 = gen_reg_rtx (XFmode);
16871
16872 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16873 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16874
16875 emit_label (label);
16876
16877 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16878 ix86_emit_fp_unordered_jump (label);
16879 LABEL_NUSES (label) = 1;
16880
16881 /* Truncate the result properly for strict SSE math. */
16882 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16883 && !TARGET_MIX_SSE_I387)
16884 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16885 else
16886 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16887
16888 DONE;
16889 })
16890
16891 (define_insn "*sinxf2_i387"
16892 [(set (match_operand:XF 0 "register_operand" "=f")
16893 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16894 "TARGET_USE_FANCY_MATH_387
16895 && flag_unsafe_math_optimizations"
16896 "fsin"
16897 [(set_attr "type" "fpspc")
16898 (set_attr "mode" "XF")])
16899
16900 (define_insn "*sin_extend<mode>xf2_i387"
16901 [(set (match_operand:XF 0 "register_operand" "=f")
16902 (unspec:XF [(float_extend:XF
16903 (match_operand:MODEF 1 "register_operand" "0"))]
16904 UNSPEC_SIN))]
16905 "TARGET_USE_FANCY_MATH_387
16906 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16907 || TARGET_MIX_SSE_I387)
16908 && flag_unsafe_math_optimizations"
16909 "fsin"
16910 [(set_attr "type" "fpspc")
16911 (set_attr "mode" "XF")])
16912
16913 (define_insn "*cosxf2_i387"
16914 [(set (match_operand:XF 0 "register_operand" "=f")
16915 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16916 "TARGET_USE_FANCY_MATH_387
16917 && flag_unsafe_math_optimizations"
16918 "fcos"
16919 [(set_attr "type" "fpspc")
16920 (set_attr "mode" "XF")])
16921
16922 (define_insn "*cos_extend<mode>xf2_i387"
16923 [(set (match_operand:XF 0 "register_operand" "=f")
16924 (unspec:XF [(float_extend:XF
16925 (match_operand:MODEF 1 "register_operand" "0"))]
16926 UNSPEC_COS))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16929 || TARGET_MIX_SSE_I387)
16930 && flag_unsafe_math_optimizations"
16931 "fcos"
16932 [(set_attr "type" "fpspc")
16933 (set_attr "mode" "XF")])
16934
16935 ;; When sincos pattern is defined, sin and cos builtin functions will be
16936 ;; expanded to sincos pattern with one of its outputs left unused.
16937 ;; CSE pass will figure out if two sincos patterns can be combined,
16938 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16939 ;; depending on the unused output.
16940
16941 (define_insn "sincosxf3"
16942 [(set (match_operand:XF 0 "register_operand" "=f")
16943 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16944 UNSPEC_SINCOS_COS))
16945 (set (match_operand:XF 1 "register_operand" "=u")
16946 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16947 "TARGET_USE_FANCY_MATH_387
16948 && flag_unsafe_math_optimizations"
16949 "fsincos"
16950 [(set_attr "type" "fpspc")
16951 (set_attr "mode" "XF")])
16952
16953 (define_split
16954 [(set (match_operand:XF 0 "register_operand" "")
16955 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16956 UNSPEC_SINCOS_COS))
16957 (set (match_operand:XF 1 "register_operand" "")
16958 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16959 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16960 && !(reload_completed || reload_in_progress)"
16961 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16962 "")
16963
16964 (define_split
16965 [(set (match_operand:XF 0 "register_operand" "")
16966 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16967 UNSPEC_SINCOS_COS))
16968 (set (match_operand:XF 1 "register_operand" "")
16969 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16970 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16971 && !(reload_completed || reload_in_progress)"
16972 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16973 "")
16974
16975 (define_insn "sincos_extend<mode>xf3_i387"
16976 [(set (match_operand:XF 0 "register_operand" "=f")
16977 (unspec:XF [(float_extend:XF
16978 (match_operand:MODEF 2 "register_operand" "0"))]
16979 UNSPEC_SINCOS_COS))
16980 (set (match_operand:XF 1 "register_operand" "=u")
16981 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16982 "TARGET_USE_FANCY_MATH_387
16983 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16984 || TARGET_MIX_SSE_I387)
16985 && flag_unsafe_math_optimizations"
16986 "fsincos"
16987 [(set_attr "type" "fpspc")
16988 (set_attr "mode" "XF")])
16989
16990 (define_split
16991 [(set (match_operand:XF 0 "register_operand" "")
16992 (unspec:XF [(float_extend:XF
16993 (match_operand:MODEF 2 "register_operand" ""))]
16994 UNSPEC_SINCOS_COS))
16995 (set (match_operand:XF 1 "register_operand" "")
16996 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16997 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16998 && !(reload_completed || reload_in_progress)"
16999 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17000 "")
17001
17002 (define_split
17003 [(set (match_operand:XF 0 "register_operand" "")
17004 (unspec:XF [(float_extend:XF
17005 (match_operand:MODEF 2 "register_operand" ""))]
17006 UNSPEC_SINCOS_COS))
17007 (set (match_operand:XF 1 "register_operand" "")
17008 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17009 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17010 && !(reload_completed || reload_in_progress)"
17011 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17012 "")
17013
17014 (define_expand "sincos<mode>3"
17015 [(use (match_operand:MODEF 0 "register_operand" ""))
17016 (use (match_operand:MODEF 1 "register_operand" ""))
17017 (use (match_operand:MODEF 2 "register_operand" ""))]
17018 "TARGET_USE_FANCY_MATH_387
17019 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17020 || TARGET_MIX_SSE_I387)
17021 && flag_unsafe_math_optimizations"
17022 {
17023 rtx op0 = gen_reg_rtx (XFmode);
17024 rtx op1 = gen_reg_rtx (XFmode);
17025
17026 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17027 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17028 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17029 DONE;
17030 })
17031
17032 (define_insn "fptanxf4_i387"
17033 [(set (match_operand:XF 0 "register_operand" "=f")
17034 (match_operand:XF 3 "const_double_operand" "F"))
17035 (set (match_operand:XF 1 "register_operand" "=u")
17036 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17037 UNSPEC_TAN))]
17038 "TARGET_USE_FANCY_MATH_387
17039 && flag_unsafe_math_optimizations
17040 && standard_80387_constant_p (operands[3]) == 2"
17041 "fptan"
17042 [(set_attr "type" "fpspc")
17043 (set_attr "mode" "XF")])
17044
17045 (define_insn "fptan_extend<mode>xf4_i387"
17046 [(set (match_operand:MODEF 0 "register_operand" "=f")
17047 (match_operand:MODEF 3 "const_double_operand" "F"))
17048 (set (match_operand:XF 1 "register_operand" "=u")
17049 (unspec:XF [(float_extend:XF
17050 (match_operand:MODEF 2 "register_operand" "0"))]
17051 UNSPEC_TAN))]
17052 "TARGET_USE_FANCY_MATH_387
17053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17054 || TARGET_MIX_SSE_I387)
17055 && flag_unsafe_math_optimizations
17056 && standard_80387_constant_p (operands[3]) == 2"
17057 "fptan"
17058 [(set_attr "type" "fpspc")
17059 (set_attr "mode" "XF")])
17060
17061 (define_expand "tanxf2"
17062 [(use (match_operand:XF 0 "register_operand" ""))
17063 (use (match_operand:XF 1 "register_operand" ""))]
17064 "TARGET_USE_FANCY_MATH_387
17065 && flag_unsafe_math_optimizations"
17066 {
17067 rtx one = gen_reg_rtx (XFmode);
17068 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17069
17070 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17071 DONE;
17072 })
17073
17074 (define_expand "tan<mode>2"
17075 [(use (match_operand:MODEF 0 "register_operand" ""))
17076 (use (match_operand:MODEF 1 "register_operand" ""))]
17077 "TARGET_USE_FANCY_MATH_387
17078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17079 || TARGET_MIX_SSE_I387)
17080 && flag_unsafe_math_optimizations"
17081 {
17082 rtx op0 = gen_reg_rtx (XFmode);
17083
17084 rtx one = gen_reg_rtx (<MODE>mode);
17085 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17086
17087 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17088 operands[1], op2));
17089 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17090 DONE;
17091 })
17092
17093 (define_insn "*fpatanxf3_i387"
17094 [(set (match_operand:XF 0 "register_operand" "=f")
17095 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17096 (match_operand:XF 2 "register_operand" "u")]
17097 UNSPEC_FPATAN))
17098 (clobber (match_scratch:XF 3 "=2"))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && flag_unsafe_math_optimizations"
17101 "fpatan"
17102 [(set_attr "type" "fpspc")
17103 (set_attr "mode" "XF")])
17104
17105 (define_insn "fpatan_extend<mode>xf3_i387"
17106 [(set (match_operand:XF 0 "register_operand" "=f")
17107 (unspec:XF [(float_extend:XF
17108 (match_operand:MODEF 1 "register_operand" "0"))
17109 (float_extend:XF
17110 (match_operand:MODEF 2 "register_operand" "u"))]
17111 UNSPEC_FPATAN))
17112 (clobber (match_scratch:XF 3 "=2"))]
17113 "TARGET_USE_FANCY_MATH_387
17114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17115 || TARGET_MIX_SSE_I387)
17116 && flag_unsafe_math_optimizations"
17117 "fpatan"
17118 [(set_attr "type" "fpspc")
17119 (set_attr "mode" "XF")])
17120
17121 (define_expand "atan2xf3"
17122 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17123 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17124 (match_operand:XF 1 "register_operand" "")]
17125 UNSPEC_FPATAN))
17126 (clobber (match_scratch:XF 3 ""))])]
17127 "TARGET_USE_FANCY_MATH_387
17128 && flag_unsafe_math_optimizations"
17129 "")
17130
17131 (define_expand "atan2<mode>3"
17132 [(use (match_operand:MODEF 0 "register_operand" ""))
17133 (use (match_operand:MODEF 1 "register_operand" ""))
17134 (use (match_operand:MODEF 2 "register_operand" ""))]
17135 "TARGET_USE_FANCY_MATH_387
17136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17137 || TARGET_MIX_SSE_I387)
17138 && flag_unsafe_math_optimizations"
17139 {
17140 rtx op0 = gen_reg_rtx (XFmode);
17141
17142 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17143 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17144 DONE;
17145 })
17146
17147 (define_expand "atanxf2"
17148 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17149 (unspec:XF [(match_dup 2)
17150 (match_operand:XF 1 "register_operand" "")]
17151 UNSPEC_FPATAN))
17152 (clobber (match_scratch:XF 3 ""))])]
17153 "TARGET_USE_FANCY_MATH_387
17154 && flag_unsafe_math_optimizations"
17155 {
17156 operands[2] = gen_reg_rtx (XFmode);
17157 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17158 })
17159
17160 (define_expand "atan<mode>2"
17161 [(use (match_operand:MODEF 0 "register_operand" ""))
17162 (use (match_operand:MODEF 1 "register_operand" ""))]
17163 "TARGET_USE_FANCY_MATH_387
17164 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17165 || TARGET_MIX_SSE_I387)
17166 && flag_unsafe_math_optimizations"
17167 {
17168 rtx op0 = gen_reg_rtx (XFmode);
17169
17170 rtx op2 = gen_reg_rtx (<MODE>mode);
17171 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17172
17173 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17175 DONE;
17176 })
17177
17178 (define_expand "asinxf2"
17179 [(set (match_dup 2)
17180 (mult:XF (match_operand:XF 1 "register_operand" "")
17181 (match_dup 1)))
17182 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17183 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17184 (parallel [(set (match_operand:XF 0 "register_operand" "")
17185 (unspec:XF [(match_dup 5) (match_dup 1)]
17186 UNSPEC_FPATAN))
17187 (clobber (match_scratch:XF 6 ""))])]
17188 "TARGET_USE_FANCY_MATH_387
17189 && flag_unsafe_math_optimizations"
17190 {
17191 int i;
17192
17193 if (optimize_insn_for_size_p ())
17194 FAIL;
17195
17196 for (i = 2; i < 6; i++)
17197 operands[i] = gen_reg_rtx (XFmode);
17198
17199 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17200 })
17201
17202 (define_expand "asin<mode>2"
17203 [(use (match_operand:MODEF 0 "register_operand" ""))
17204 (use (match_operand:MODEF 1 "general_operand" ""))]
17205 "TARGET_USE_FANCY_MATH_387
17206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17207 || TARGET_MIX_SSE_I387)
17208 && flag_unsafe_math_optimizations"
17209 {
17210 rtx op0 = gen_reg_rtx (XFmode);
17211 rtx op1 = gen_reg_rtx (XFmode);
17212
17213 if (optimize_insn_for_size_p ())
17214 FAIL;
17215
17216 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17217 emit_insn (gen_asinxf2 (op0, op1));
17218 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17219 DONE;
17220 })
17221
17222 (define_expand "acosxf2"
17223 [(set (match_dup 2)
17224 (mult:XF (match_operand:XF 1 "register_operand" "")
17225 (match_dup 1)))
17226 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17227 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17228 (parallel [(set (match_operand:XF 0 "register_operand" "")
17229 (unspec:XF [(match_dup 1) (match_dup 5)]
17230 UNSPEC_FPATAN))
17231 (clobber (match_scratch:XF 6 ""))])]
17232 "TARGET_USE_FANCY_MATH_387
17233 && flag_unsafe_math_optimizations"
17234 {
17235 int i;
17236
17237 if (optimize_insn_for_size_p ())
17238 FAIL;
17239
17240 for (i = 2; i < 6; i++)
17241 operands[i] = gen_reg_rtx (XFmode);
17242
17243 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17244 })
17245
17246 (define_expand "acos<mode>2"
17247 [(use (match_operand:MODEF 0 "register_operand" ""))
17248 (use (match_operand:MODEF 1 "general_operand" ""))]
17249 "TARGET_USE_FANCY_MATH_387
17250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17251 || TARGET_MIX_SSE_I387)
17252 && flag_unsafe_math_optimizations"
17253 {
17254 rtx op0 = gen_reg_rtx (XFmode);
17255 rtx op1 = gen_reg_rtx (XFmode);
17256
17257 if (optimize_insn_for_size_p ())
17258 FAIL;
17259
17260 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17261 emit_insn (gen_acosxf2 (op0, op1));
17262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17263 DONE;
17264 })
17265
17266 (define_insn "fyl2xxf3_i387"
17267 [(set (match_operand:XF 0 "register_operand" "=f")
17268 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17269 (match_operand:XF 2 "register_operand" "u")]
17270 UNSPEC_FYL2X))
17271 (clobber (match_scratch:XF 3 "=2"))]
17272 "TARGET_USE_FANCY_MATH_387
17273 && flag_unsafe_math_optimizations"
17274 "fyl2x"
17275 [(set_attr "type" "fpspc")
17276 (set_attr "mode" "XF")])
17277
17278 (define_insn "fyl2x_extend<mode>xf3_i387"
17279 [(set (match_operand:XF 0 "register_operand" "=f")
17280 (unspec:XF [(float_extend:XF
17281 (match_operand:MODEF 1 "register_operand" "0"))
17282 (match_operand:XF 2 "register_operand" "u")]
17283 UNSPEC_FYL2X))
17284 (clobber (match_scratch:XF 3 "=2"))]
17285 "TARGET_USE_FANCY_MATH_387
17286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17287 || TARGET_MIX_SSE_I387)
17288 && flag_unsafe_math_optimizations"
17289 "fyl2x"
17290 [(set_attr "type" "fpspc")
17291 (set_attr "mode" "XF")])
17292
17293 (define_expand "logxf2"
17294 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17295 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17296 (match_dup 2)] UNSPEC_FYL2X))
17297 (clobber (match_scratch:XF 3 ""))])]
17298 "TARGET_USE_FANCY_MATH_387
17299 && flag_unsafe_math_optimizations"
17300 {
17301 operands[2] = gen_reg_rtx (XFmode);
17302 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17303 })
17304
17305 (define_expand "log<mode>2"
17306 [(use (match_operand:MODEF 0 "register_operand" ""))
17307 (use (match_operand:MODEF 1 "register_operand" ""))]
17308 "TARGET_USE_FANCY_MATH_387
17309 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17310 || TARGET_MIX_SSE_I387)
17311 && flag_unsafe_math_optimizations"
17312 {
17313 rtx op0 = gen_reg_rtx (XFmode);
17314
17315 rtx op2 = gen_reg_rtx (XFmode);
17316 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17317
17318 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17319 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17320 DONE;
17321 })
17322
17323 (define_expand "log10xf2"
17324 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17325 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17326 (match_dup 2)] UNSPEC_FYL2X))
17327 (clobber (match_scratch:XF 3 ""))])]
17328 "TARGET_USE_FANCY_MATH_387
17329 && flag_unsafe_math_optimizations"
17330 {
17331 operands[2] = gen_reg_rtx (XFmode);
17332 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17333 })
17334
17335 (define_expand "log10<mode>2"
17336 [(use (match_operand:MODEF 0 "register_operand" ""))
17337 (use (match_operand:MODEF 1 "register_operand" ""))]
17338 "TARGET_USE_FANCY_MATH_387
17339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17340 || TARGET_MIX_SSE_I387)
17341 && flag_unsafe_math_optimizations"
17342 {
17343 rtx op0 = gen_reg_rtx (XFmode);
17344
17345 rtx op2 = gen_reg_rtx (XFmode);
17346 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17347
17348 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17349 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17350 DONE;
17351 })
17352
17353 (define_expand "log2xf2"
17354 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17355 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17356 (match_dup 2)] UNSPEC_FYL2X))
17357 (clobber (match_scratch:XF 3 ""))])]
17358 "TARGET_USE_FANCY_MATH_387
17359 && flag_unsafe_math_optimizations"
17360 {
17361 operands[2] = gen_reg_rtx (XFmode);
17362 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17363 })
17364
17365 (define_expand "log2<mode>2"
17366 [(use (match_operand:MODEF 0 "register_operand" ""))
17367 (use (match_operand:MODEF 1 "register_operand" ""))]
17368 "TARGET_USE_FANCY_MATH_387
17369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370 || TARGET_MIX_SSE_I387)
17371 && flag_unsafe_math_optimizations"
17372 {
17373 rtx op0 = gen_reg_rtx (XFmode);
17374
17375 rtx op2 = gen_reg_rtx (XFmode);
17376 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17377
17378 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17379 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17380 DONE;
17381 })
17382
17383 (define_insn "fyl2xp1xf3_i387"
17384 [(set (match_operand:XF 0 "register_operand" "=f")
17385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17386 (match_operand:XF 2 "register_operand" "u")]
17387 UNSPEC_FYL2XP1))
17388 (clobber (match_scratch:XF 3 "=2"))]
17389 "TARGET_USE_FANCY_MATH_387
17390 && flag_unsafe_math_optimizations"
17391 "fyl2xp1"
17392 [(set_attr "type" "fpspc")
17393 (set_attr "mode" "XF")])
17394
17395 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17396 [(set (match_operand:XF 0 "register_operand" "=f")
17397 (unspec:XF [(float_extend:XF
17398 (match_operand:MODEF 1 "register_operand" "0"))
17399 (match_operand:XF 2 "register_operand" "u")]
17400 UNSPEC_FYL2XP1))
17401 (clobber (match_scratch:XF 3 "=2"))]
17402 "TARGET_USE_FANCY_MATH_387
17403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17404 || TARGET_MIX_SSE_I387)
17405 && flag_unsafe_math_optimizations"
17406 "fyl2xp1"
17407 [(set_attr "type" "fpspc")
17408 (set_attr "mode" "XF")])
17409
17410 (define_expand "log1pxf2"
17411 [(use (match_operand:XF 0 "register_operand" ""))
17412 (use (match_operand:XF 1 "register_operand" ""))]
17413 "TARGET_USE_FANCY_MATH_387
17414 && flag_unsafe_math_optimizations"
17415 {
17416 if (optimize_insn_for_size_p ())
17417 FAIL;
17418
17419 ix86_emit_i387_log1p (operands[0], operands[1]);
17420 DONE;
17421 })
17422
17423 (define_expand "log1p<mode>2"
17424 [(use (match_operand:MODEF 0 "register_operand" ""))
17425 (use (match_operand:MODEF 1 "register_operand" ""))]
17426 "TARGET_USE_FANCY_MATH_387
17427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17428 || TARGET_MIX_SSE_I387)
17429 && flag_unsafe_math_optimizations"
17430 {
17431 rtx op0;
17432
17433 if (optimize_insn_for_size_p ())
17434 FAIL;
17435
17436 op0 = gen_reg_rtx (XFmode);
17437
17438 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17439
17440 ix86_emit_i387_log1p (op0, operands[1]);
17441 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17442 DONE;
17443 })
17444
17445 (define_insn "fxtractxf3_i387"
17446 [(set (match_operand:XF 0 "register_operand" "=f")
17447 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17448 UNSPEC_XTRACT_FRACT))
17449 (set (match_operand:XF 1 "register_operand" "=u")
17450 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17451 "TARGET_USE_FANCY_MATH_387
17452 && flag_unsafe_math_optimizations"
17453 "fxtract"
17454 [(set_attr "type" "fpspc")
17455 (set_attr "mode" "XF")])
17456
17457 (define_insn "fxtract_extend<mode>xf3_i387"
17458 [(set (match_operand:XF 0 "register_operand" "=f")
17459 (unspec:XF [(float_extend:XF
17460 (match_operand:MODEF 2 "register_operand" "0"))]
17461 UNSPEC_XTRACT_FRACT))
17462 (set (match_operand:XF 1 "register_operand" "=u")
17463 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17464 "TARGET_USE_FANCY_MATH_387
17465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17466 || TARGET_MIX_SSE_I387)
17467 && flag_unsafe_math_optimizations"
17468 "fxtract"
17469 [(set_attr "type" "fpspc")
17470 (set_attr "mode" "XF")])
17471
17472 (define_expand "logbxf2"
17473 [(parallel [(set (match_dup 2)
17474 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17475 UNSPEC_XTRACT_FRACT))
17476 (set (match_operand:XF 0 "register_operand" "")
17477 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17478 "TARGET_USE_FANCY_MATH_387
17479 && flag_unsafe_math_optimizations"
17480 {
17481 operands[2] = gen_reg_rtx (XFmode);
17482 })
17483
17484 (define_expand "logb<mode>2"
17485 [(use (match_operand:MODEF 0 "register_operand" ""))
17486 (use (match_operand:MODEF 1 "register_operand" ""))]
17487 "TARGET_USE_FANCY_MATH_387
17488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17489 || TARGET_MIX_SSE_I387)
17490 && flag_unsafe_math_optimizations"
17491 {
17492 rtx op0 = gen_reg_rtx (XFmode);
17493 rtx op1 = gen_reg_rtx (XFmode);
17494
17495 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17496 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17497 DONE;
17498 })
17499
17500 (define_expand "ilogbxf2"
17501 [(use (match_operand:SI 0 "register_operand" ""))
17502 (use (match_operand:XF 1 "register_operand" ""))]
17503 "TARGET_USE_FANCY_MATH_387
17504 && flag_unsafe_math_optimizations"
17505 {
17506 rtx op0, op1;
17507
17508 if (optimize_insn_for_size_p ())
17509 FAIL;
17510
17511 op0 = gen_reg_rtx (XFmode);
17512 op1 = gen_reg_rtx (XFmode);
17513
17514 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17515 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17516 DONE;
17517 })
17518
17519 (define_expand "ilogb<mode>2"
17520 [(use (match_operand:SI 0 "register_operand" ""))
17521 (use (match_operand:MODEF 1 "register_operand" ""))]
17522 "TARGET_USE_FANCY_MATH_387
17523 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17524 || TARGET_MIX_SSE_I387)
17525 && flag_unsafe_math_optimizations"
17526 {
17527 rtx op0, op1;
17528
17529 if (optimize_insn_for_size_p ())
17530 FAIL;
17531
17532 op0 = gen_reg_rtx (XFmode);
17533 op1 = gen_reg_rtx (XFmode);
17534
17535 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17536 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17537 DONE;
17538 })
17539
17540 (define_insn "*f2xm1xf2_i387"
17541 [(set (match_operand:XF 0 "register_operand" "=f")
17542 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17543 UNSPEC_F2XM1))]
17544 "TARGET_USE_FANCY_MATH_387
17545 && flag_unsafe_math_optimizations"
17546 "f2xm1"
17547 [(set_attr "type" "fpspc")
17548 (set_attr "mode" "XF")])
17549
17550 (define_insn "*fscalexf4_i387"
17551 [(set (match_operand:XF 0 "register_operand" "=f")
17552 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17553 (match_operand:XF 3 "register_operand" "1")]
17554 UNSPEC_FSCALE_FRACT))
17555 (set (match_operand:XF 1 "register_operand" "=u")
17556 (unspec:XF [(match_dup 2) (match_dup 3)]
17557 UNSPEC_FSCALE_EXP))]
17558 "TARGET_USE_FANCY_MATH_387
17559 && flag_unsafe_math_optimizations"
17560 "fscale"
17561 [(set_attr "type" "fpspc")
17562 (set_attr "mode" "XF")])
17563
17564 (define_expand "expNcorexf3"
17565 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17566 (match_operand:XF 2 "register_operand" "")))
17567 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17568 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17569 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17570 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17571 (parallel [(set (match_operand:XF 0 "register_operand" "")
17572 (unspec:XF [(match_dup 8) (match_dup 4)]
17573 UNSPEC_FSCALE_FRACT))
17574 (set (match_dup 9)
17575 (unspec:XF [(match_dup 8) (match_dup 4)]
17576 UNSPEC_FSCALE_EXP))])]
17577 "TARGET_USE_FANCY_MATH_387
17578 && flag_unsafe_math_optimizations"
17579 {
17580 int i;
17581
17582 if (optimize_insn_for_size_p ())
17583 FAIL;
17584
17585 for (i = 3; i < 10; i++)
17586 operands[i] = gen_reg_rtx (XFmode);
17587
17588 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17589 })
17590
17591 (define_expand "expxf2"
17592 [(use (match_operand:XF 0 "register_operand" ""))
17593 (use (match_operand:XF 1 "register_operand" ""))]
17594 "TARGET_USE_FANCY_MATH_387
17595 && flag_unsafe_math_optimizations"
17596 {
17597 rtx op2;
17598
17599 if (optimize_insn_for_size_p ())
17600 FAIL;
17601
17602 op2 = gen_reg_rtx (XFmode);
17603 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17604
17605 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17606 DONE;
17607 })
17608
17609 (define_expand "exp<mode>2"
17610 [(use (match_operand:MODEF 0 "register_operand" ""))
17611 (use (match_operand:MODEF 1 "general_operand" ""))]
17612 "TARGET_USE_FANCY_MATH_387
17613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614 || TARGET_MIX_SSE_I387)
17615 && flag_unsafe_math_optimizations"
17616 {
17617 rtx op0, op1;
17618
17619 if (optimize_insn_for_size_p ())
17620 FAIL;
17621
17622 op0 = gen_reg_rtx (XFmode);
17623 op1 = gen_reg_rtx (XFmode);
17624
17625 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17626 emit_insn (gen_expxf2 (op0, op1));
17627 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17628 DONE;
17629 })
17630
17631 (define_expand "exp10xf2"
17632 [(use (match_operand:XF 0 "register_operand" ""))
17633 (use (match_operand:XF 1 "register_operand" ""))]
17634 "TARGET_USE_FANCY_MATH_387
17635 && flag_unsafe_math_optimizations"
17636 {
17637 rtx op2;
17638
17639 if (optimize_insn_for_size_p ())
17640 FAIL;
17641
17642 op2 = gen_reg_rtx (XFmode);
17643 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17644
17645 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17646 DONE;
17647 })
17648
17649 (define_expand "exp10<mode>2"
17650 [(use (match_operand:MODEF 0 "register_operand" ""))
17651 (use (match_operand:MODEF 1 "general_operand" ""))]
17652 "TARGET_USE_FANCY_MATH_387
17653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17654 || TARGET_MIX_SSE_I387)
17655 && flag_unsafe_math_optimizations"
17656 {
17657 rtx op0, op1;
17658
17659 if (optimize_insn_for_size_p ())
17660 FAIL;
17661
17662 op0 = gen_reg_rtx (XFmode);
17663 op1 = gen_reg_rtx (XFmode);
17664
17665 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17666 emit_insn (gen_exp10xf2 (op0, op1));
17667 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17668 DONE;
17669 })
17670
17671 (define_expand "exp2xf2"
17672 [(use (match_operand:XF 0 "register_operand" ""))
17673 (use (match_operand:XF 1 "register_operand" ""))]
17674 "TARGET_USE_FANCY_MATH_387
17675 && flag_unsafe_math_optimizations"
17676 {
17677 rtx op2;
17678
17679 if (optimize_insn_for_size_p ())
17680 FAIL;
17681
17682 op2 = gen_reg_rtx (XFmode);
17683 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17684
17685 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17686 DONE;
17687 })
17688
17689 (define_expand "exp2<mode>2"
17690 [(use (match_operand:MODEF 0 "register_operand" ""))
17691 (use (match_operand:MODEF 1 "general_operand" ""))]
17692 "TARGET_USE_FANCY_MATH_387
17693 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17694 || TARGET_MIX_SSE_I387)
17695 && flag_unsafe_math_optimizations"
17696 {
17697 rtx op0, op1;
17698
17699 if (optimize_insn_for_size_p ())
17700 FAIL;
17701
17702 op0 = gen_reg_rtx (XFmode);
17703 op1 = gen_reg_rtx (XFmode);
17704
17705 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17706 emit_insn (gen_exp2xf2 (op0, op1));
17707 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17708 DONE;
17709 })
17710
17711 (define_expand "expm1xf2"
17712 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17713 (match_dup 2)))
17714 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17715 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17716 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17717 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17718 (parallel [(set (match_dup 7)
17719 (unspec:XF [(match_dup 6) (match_dup 4)]
17720 UNSPEC_FSCALE_FRACT))
17721 (set (match_dup 8)
17722 (unspec:XF [(match_dup 6) (match_dup 4)]
17723 UNSPEC_FSCALE_EXP))])
17724 (parallel [(set (match_dup 10)
17725 (unspec:XF [(match_dup 9) (match_dup 8)]
17726 UNSPEC_FSCALE_FRACT))
17727 (set (match_dup 11)
17728 (unspec:XF [(match_dup 9) (match_dup 8)]
17729 UNSPEC_FSCALE_EXP))])
17730 (set (match_dup 12) (minus:XF (match_dup 10)
17731 (float_extend:XF (match_dup 13))))
17732 (set (match_operand:XF 0 "register_operand" "")
17733 (plus:XF (match_dup 12) (match_dup 7)))]
17734 "TARGET_USE_FANCY_MATH_387
17735 && flag_unsafe_math_optimizations"
17736 {
17737 int i;
17738
17739 if (optimize_insn_for_size_p ())
17740 FAIL;
17741
17742 for (i = 2; i < 13; i++)
17743 operands[i] = gen_reg_rtx (XFmode);
17744
17745 operands[13]
17746 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17747
17748 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17749 })
17750
17751 (define_expand "expm1<mode>2"
17752 [(use (match_operand:MODEF 0 "register_operand" ""))
17753 (use (match_operand:MODEF 1 "general_operand" ""))]
17754 "TARGET_USE_FANCY_MATH_387
17755 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17756 || TARGET_MIX_SSE_I387)
17757 && flag_unsafe_math_optimizations"
17758 {
17759 rtx op0, op1;
17760
17761 if (optimize_insn_for_size_p ())
17762 FAIL;
17763
17764 op0 = gen_reg_rtx (XFmode);
17765 op1 = gen_reg_rtx (XFmode);
17766
17767 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17768 emit_insn (gen_expm1xf2 (op0, op1));
17769 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17770 DONE;
17771 })
17772
17773 (define_expand "ldexpxf3"
17774 [(set (match_dup 3)
17775 (float:XF (match_operand:SI 2 "register_operand" "")))
17776 (parallel [(set (match_operand:XF 0 " register_operand" "")
17777 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17778 (match_dup 3)]
17779 UNSPEC_FSCALE_FRACT))
17780 (set (match_dup 4)
17781 (unspec:XF [(match_dup 1) (match_dup 3)]
17782 UNSPEC_FSCALE_EXP))])]
17783 "TARGET_USE_FANCY_MATH_387
17784 && flag_unsafe_math_optimizations"
17785 {
17786 if (optimize_insn_for_size_p ())
17787 FAIL;
17788
17789 operands[3] = gen_reg_rtx (XFmode);
17790 operands[4] = gen_reg_rtx (XFmode);
17791 })
17792
17793 (define_expand "ldexp<mode>3"
17794 [(use (match_operand:MODEF 0 "register_operand" ""))
17795 (use (match_operand:MODEF 1 "general_operand" ""))
17796 (use (match_operand:SI 2 "register_operand" ""))]
17797 "TARGET_USE_FANCY_MATH_387
17798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17799 || TARGET_MIX_SSE_I387)
17800 && flag_unsafe_math_optimizations"
17801 {
17802 rtx op0, op1;
17803
17804 if (optimize_insn_for_size_p ())
17805 FAIL;
17806
17807 op0 = gen_reg_rtx (XFmode);
17808 op1 = gen_reg_rtx (XFmode);
17809
17810 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17811 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17813 DONE;
17814 })
17815
17816 (define_expand "scalbxf3"
17817 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17818 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17819 (match_operand:XF 2 "register_operand" "")]
17820 UNSPEC_FSCALE_FRACT))
17821 (set (match_dup 3)
17822 (unspec:XF [(match_dup 1) (match_dup 2)]
17823 UNSPEC_FSCALE_EXP))])]
17824 "TARGET_USE_FANCY_MATH_387
17825 && flag_unsafe_math_optimizations"
17826 {
17827 if (optimize_insn_for_size_p ())
17828 FAIL;
17829
17830 operands[3] = gen_reg_rtx (XFmode);
17831 })
17832
17833 (define_expand "scalb<mode>3"
17834 [(use (match_operand:MODEF 0 "register_operand" ""))
17835 (use (match_operand:MODEF 1 "general_operand" ""))
17836 (use (match_operand:MODEF 2 "register_operand" ""))]
17837 "TARGET_USE_FANCY_MATH_387
17838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17839 || TARGET_MIX_SSE_I387)
17840 && flag_unsafe_math_optimizations"
17841 {
17842 rtx op0, op1, op2;
17843
17844 if (optimize_insn_for_size_p ())
17845 FAIL;
17846
17847 op0 = gen_reg_rtx (XFmode);
17848 op1 = gen_reg_rtx (XFmode);
17849 op2 = gen_reg_rtx (XFmode);
17850
17851 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17852 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17853 emit_insn (gen_scalbxf3 (op0, op1, op2));
17854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17855 DONE;
17856 })
17857 \f
17858
17859 (define_insn "sse4_1_round<mode>2"
17860 [(set (match_operand:MODEF 0 "register_operand" "=x")
17861 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17862 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17863 UNSPEC_ROUND))]
17864 "TARGET_ROUND"
17865 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17866 [(set_attr "type" "ssecvt")
17867 (set_attr "prefix_extra" "1")
17868 (set_attr "prefix" "maybe_vex")
17869 (set_attr "mode" "<MODE>")])
17870
17871 (define_insn "rintxf2"
17872 [(set (match_operand:XF 0 "register_operand" "=f")
17873 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17874 UNSPEC_FRNDINT))]
17875 "TARGET_USE_FANCY_MATH_387
17876 && flag_unsafe_math_optimizations"
17877 "frndint"
17878 [(set_attr "type" "fpspc")
17879 (set_attr "mode" "XF")])
17880
17881 (define_expand "rint<mode>2"
17882 [(use (match_operand:MODEF 0 "register_operand" ""))
17883 (use (match_operand:MODEF 1 "register_operand" ""))]
17884 "(TARGET_USE_FANCY_MATH_387
17885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17886 || TARGET_MIX_SSE_I387)
17887 && flag_unsafe_math_optimizations)
17888 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17889 && !flag_trapping_math)"
17890 {
17891 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17892 && !flag_trapping_math)
17893 {
17894 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17895 FAIL;
17896 if (TARGET_ROUND)
17897 emit_insn (gen_sse4_1_round<mode>2
17898 (operands[0], operands[1], GEN_INT (0x04)));
17899 else
17900 ix86_expand_rint (operand0, operand1);
17901 }
17902 else
17903 {
17904 rtx op0 = gen_reg_rtx (XFmode);
17905 rtx op1 = gen_reg_rtx (XFmode);
17906
17907 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17908 emit_insn (gen_rintxf2 (op0, op1));
17909
17910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17911 }
17912 DONE;
17913 })
17914
17915 (define_expand "round<mode>2"
17916 [(match_operand:MODEF 0 "register_operand" "")
17917 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17918 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17919 && !flag_trapping_math && !flag_rounding_math"
17920 {
17921 if (optimize_insn_for_size_p ())
17922 FAIL;
17923 if (TARGET_64BIT || (<MODE>mode != DFmode))
17924 ix86_expand_round (operand0, operand1);
17925 else
17926 ix86_expand_rounddf_32 (operand0, operand1);
17927 DONE;
17928 })
17929
17930 (define_insn_and_split "*fistdi2_1"
17931 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17932 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17933 UNSPEC_FIST))]
17934 "TARGET_USE_FANCY_MATH_387
17935 && !(reload_completed || reload_in_progress)"
17936 "#"
17937 "&& 1"
17938 [(const_int 0)]
17939 {
17940 if (memory_operand (operands[0], VOIDmode))
17941 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17942 else
17943 {
17944 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17945 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17946 operands[2]));
17947 }
17948 DONE;
17949 }
17950 [(set_attr "type" "fpspc")
17951 (set_attr "mode" "DI")])
17952
17953 (define_insn "fistdi2"
17954 [(set (match_operand:DI 0 "memory_operand" "=m")
17955 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17956 UNSPEC_FIST))
17957 (clobber (match_scratch:XF 2 "=&1f"))]
17958 "TARGET_USE_FANCY_MATH_387"
17959 "* return output_fix_trunc (insn, operands, 0);"
17960 [(set_attr "type" "fpspc")
17961 (set_attr "mode" "DI")])
17962
17963 (define_insn "fistdi2_with_temp"
17964 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17965 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17966 UNSPEC_FIST))
17967 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17968 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17969 "TARGET_USE_FANCY_MATH_387"
17970 "#"
17971 [(set_attr "type" "fpspc")
17972 (set_attr "mode" "DI")])
17973
17974 (define_split
17975 [(set (match_operand:DI 0 "register_operand" "")
17976 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17977 UNSPEC_FIST))
17978 (clobber (match_operand:DI 2 "memory_operand" ""))
17979 (clobber (match_scratch 3 ""))]
17980 "reload_completed"
17981 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17982 (clobber (match_dup 3))])
17983 (set (match_dup 0) (match_dup 2))]
17984 "")
17985
17986 (define_split
17987 [(set (match_operand:DI 0 "memory_operand" "")
17988 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17989 UNSPEC_FIST))
17990 (clobber (match_operand:DI 2 "memory_operand" ""))
17991 (clobber (match_scratch 3 ""))]
17992 "reload_completed"
17993 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17994 (clobber (match_dup 3))])]
17995 "")
17996
17997 (define_insn_and_split "*fist<mode>2_1"
17998 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17999 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18000 UNSPEC_FIST))]
18001 "TARGET_USE_FANCY_MATH_387
18002 && !(reload_completed || reload_in_progress)"
18003 "#"
18004 "&& 1"
18005 [(const_int 0)]
18006 {
18007 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18008 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18009 operands[2]));
18010 DONE;
18011 }
18012 [(set_attr "type" "fpspc")
18013 (set_attr "mode" "<MODE>")])
18014
18015 (define_insn "fist<mode>2"
18016 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18017 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18018 UNSPEC_FIST))]
18019 "TARGET_USE_FANCY_MATH_387"
18020 "* return output_fix_trunc (insn, operands, 0);"
18021 [(set_attr "type" "fpspc")
18022 (set_attr "mode" "<MODE>")])
18023
18024 (define_insn "fist<mode>2_with_temp"
18025 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18026 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18027 UNSPEC_FIST))
18028 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18029 "TARGET_USE_FANCY_MATH_387"
18030 "#"
18031 [(set_attr "type" "fpspc")
18032 (set_attr "mode" "<MODE>")])
18033
18034 (define_split
18035 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18036 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18037 UNSPEC_FIST))
18038 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18039 "reload_completed"
18040 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18041 (set (match_dup 0) (match_dup 2))]
18042 "")
18043
18044 (define_split
18045 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18046 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18047 UNSPEC_FIST))
18048 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18049 "reload_completed"
18050 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18051 "")
18052
18053 (define_expand "lrintxf<mode>2"
18054 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18055 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18056 UNSPEC_FIST))]
18057 "TARGET_USE_FANCY_MATH_387"
18058 "")
18059
18060 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18061 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18062 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18063 UNSPEC_FIX_NOTRUNC))]
18064 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18065 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18066 "")
18067
18068 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18069 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18070 (match_operand:MODEF 1 "register_operand" "")]
18071 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18072 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18073 && !flag_trapping_math && !flag_rounding_math"
18074 {
18075 if (optimize_insn_for_size_p ())
18076 FAIL;
18077 ix86_expand_lround (operand0, operand1);
18078 DONE;
18079 })
18080
18081 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18082 (define_insn_and_split "frndintxf2_floor"
18083 [(set (match_operand:XF 0 "register_operand" "")
18084 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18085 UNSPEC_FRNDINT_FLOOR))
18086 (clobber (reg:CC FLAGS_REG))]
18087 "TARGET_USE_FANCY_MATH_387
18088 && flag_unsafe_math_optimizations
18089 && !(reload_completed || reload_in_progress)"
18090 "#"
18091 "&& 1"
18092 [(const_int 0)]
18093 {
18094 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18095
18096 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18097 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18098
18099 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18100 operands[2], operands[3]));
18101 DONE;
18102 }
18103 [(set_attr "type" "frndint")
18104 (set_attr "i387_cw" "floor")
18105 (set_attr "mode" "XF")])
18106
18107 (define_insn "frndintxf2_floor_i387"
18108 [(set (match_operand:XF 0 "register_operand" "=f")
18109 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18110 UNSPEC_FRNDINT_FLOOR))
18111 (use (match_operand:HI 2 "memory_operand" "m"))
18112 (use (match_operand:HI 3 "memory_operand" "m"))]
18113 "TARGET_USE_FANCY_MATH_387
18114 && flag_unsafe_math_optimizations"
18115 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18116 [(set_attr "type" "frndint")
18117 (set_attr "i387_cw" "floor")
18118 (set_attr "mode" "XF")])
18119
18120 (define_expand "floorxf2"
18121 [(use (match_operand:XF 0 "register_operand" ""))
18122 (use (match_operand:XF 1 "register_operand" ""))]
18123 "TARGET_USE_FANCY_MATH_387
18124 && flag_unsafe_math_optimizations"
18125 {
18126 if (optimize_insn_for_size_p ())
18127 FAIL;
18128 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18129 DONE;
18130 })
18131
18132 (define_expand "floor<mode>2"
18133 [(use (match_operand:MODEF 0 "register_operand" ""))
18134 (use (match_operand:MODEF 1 "register_operand" ""))]
18135 "(TARGET_USE_FANCY_MATH_387
18136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18137 || TARGET_MIX_SSE_I387)
18138 && flag_unsafe_math_optimizations)
18139 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18140 && !flag_trapping_math)"
18141 {
18142 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18143 && !flag_trapping_math
18144 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18145 {
18146 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18147 FAIL;
18148 if (TARGET_ROUND)
18149 emit_insn (gen_sse4_1_round<mode>2
18150 (operands[0], operands[1], GEN_INT (0x01)));
18151 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18152 ix86_expand_floorceil (operand0, operand1, true);
18153 else
18154 ix86_expand_floorceildf_32 (operand0, operand1, true);
18155 }
18156 else
18157 {
18158 rtx op0, op1;
18159
18160 if (optimize_insn_for_size_p ())
18161 FAIL;
18162
18163 op0 = gen_reg_rtx (XFmode);
18164 op1 = gen_reg_rtx (XFmode);
18165 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18166 emit_insn (gen_frndintxf2_floor (op0, op1));
18167
18168 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18169 }
18170 DONE;
18171 })
18172
18173 (define_insn_and_split "*fist<mode>2_floor_1"
18174 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18175 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18176 UNSPEC_FIST_FLOOR))
18177 (clobber (reg:CC FLAGS_REG))]
18178 "TARGET_USE_FANCY_MATH_387
18179 && flag_unsafe_math_optimizations
18180 && !(reload_completed || reload_in_progress)"
18181 "#"
18182 "&& 1"
18183 [(const_int 0)]
18184 {
18185 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18186
18187 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18188 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18189 if (memory_operand (operands[0], VOIDmode))
18190 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18191 operands[2], operands[3]));
18192 else
18193 {
18194 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18195 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18196 operands[2], operands[3],
18197 operands[4]));
18198 }
18199 DONE;
18200 }
18201 [(set_attr "type" "fistp")
18202 (set_attr "i387_cw" "floor")
18203 (set_attr "mode" "<MODE>")])
18204
18205 (define_insn "fistdi2_floor"
18206 [(set (match_operand:DI 0 "memory_operand" "=m")
18207 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18208 UNSPEC_FIST_FLOOR))
18209 (use (match_operand:HI 2 "memory_operand" "m"))
18210 (use (match_operand:HI 3 "memory_operand" "m"))
18211 (clobber (match_scratch:XF 4 "=&1f"))]
18212 "TARGET_USE_FANCY_MATH_387
18213 && flag_unsafe_math_optimizations"
18214 "* return output_fix_trunc (insn, operands, 0);"
18215 [(set_attr "type" "fistp")
18216 (set_attr "i387_cw" "floor")
18217 (set_attr "mode" "DI")])
18218
18219 (define_insn "fistdi2_floor_with_temp"
18220 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18221 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18222 UNSPEC_FIST_FLOOR))
18223 (use (match_operand:HI 2 "memory_operand" "m,m"))
18224 (use (match_operand:HI 3 "memory_operand" "m,m"))
18225 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18226 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18227 "TARGET_USE_FANCY_MATH_387
18228 && flag_unsafe_math_optimizations"
18229 "#"
18230 [(set_attr "type" "fistp")
18231 (set_attr "i387_cw" "floor")
18232 (set_attr "mode" "DI")])
18233
18234 (define_split
18235 [(set (match_operand:DI 0 "register_operand" "")
18236 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18237 UNSPEC_FIST_FLOOR))
18238 (use (match_operand:HI 2 "memory_operand" ""))
18239 (use (match_operand:HI 3 "memory_operand" ""))
18240 (clobber (match_operand:DI 4 "memory_operand" ""))
18241 (clobber (match_scratch 5 ""))]
18242 "reload_completed"
18243 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18244 (use (match_dup 2))
18245 (use (match_dup 3))
18246 (clobber (match_dup 5))])
18247 (set (match_dup 0) (match_dup 4))]
18248 "")
18249
18250 (define_split
18251 [(set (match_operand:DI 0 "memory_operand" "")
18252 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18253 UNSPEC_FIST_FLOOR))
18254 (use (match_operand:HI 2 "memory_operand" ""))
18255 (use (match_operand:HI 3 "memory_operand" ""))
18256 (clobber (match_operand:DI 4 "memory_operand" ""))
18257 (clobber (match_scratch 5 ""))]
18258 "reload_completed"
18259 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18260 (use (match_dup 2))
18261 (use (match_dup 3))
18262 (clobber (match_dup 5))])]
18263 "")
18264
18265 (define_insn "fist<mode>2_floor"
18266 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18267 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18268 UNSPEC_FIST_FLOOR))
18269 (use (match_operand:HI 2 "memory_operand" "m"))
18270 (use (match_operand:HI 3 "memory_operand" "m"))]
18271 "TARGET_USE_FANCY_MATH_387
18272 && flag_unsafe_math_optimizations"
18273 "* return output_fix_trunc (insn, operands, 0);"
18274 [(set_attr "type" "fistp")
18275 (set_attr "i387_cw" "floor")
18276 (set_attr "mode" "<MODE>")])
18277
18278 (define_insn "fist<mode>2_floor_with_temp"
18279 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18280 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18281 UNSPEC_FIST_FLOOR))
18282 (use (match_operand:HI 2 "memory_operand" "m,m"))
18283 (use (match_operand:HI 3 "memory_operand" "m,m"))
18284 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18285 "TARGET_USE_FANCY_MATH_387
18286 && flag_unsafe_math_optimizations"
18287 "#"
18288 [(set_attr "type" "fistp")
18289 (set_attr "i387_cw" "floor")
18290 (set_attr "mode" "<MODE>")])
18291
18292 (define_split
18293 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18294 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18295 UNSPEC_FIST_FLOOR))
18296 (use (match_operand:HI 2 "memory_operand" ""))
18297 (use (match_operand:HI 3 "memory_operand" ""))
18298 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18299 "reload_completed"
18300 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18301 UNSPEC_FIST_FLOOR))
18302 (use (match_dup 2))
18303 (use (match_dup 3))])
18304 (set (match_dup 0) (match_dup 4))]
18305 "")
18306
18307 (define_split
18308 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18309 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18310 UNSPEC_FIST_FLOOR))
18311 (use (match_operand:HI 2 "memory_operand" ""))
18312 (use (match_operand:HI 3 "memory_operand" ""))
18313 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18314 "reload_completed"
18315 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18316 UNSPEC_FIST_FLOOR))
18317 (use (match_dup 2))
18318 (use (match_dup 3))])]
18319 "")
18320
18321 (define_expand "lfloorxf<mode>2"
18322 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18323 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18324 UNSPEC_FIST_FLOOR))
18325 (clobber (reg:CC FLAGS_REG))])]
18326 "TARGET_USE_FANCY_MATH_387
18327 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18328 && flag_unsafe_math_optimizations"
18329 "")
18330
18331 (define_expand "lfloor<mode>di2"
18332 [(match_operand:DI 0 "nonimmediate_operand" "")
18333 (match_operand:MODEF 1 "register_operand" "")]
18334 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18335 && !flag_trapping_math"
18336 {
18337 if (optimize_insn_for_size_p ())
18338 FAIL;
18339 ix86_expand_lfloorceil (operand0, operand1, true);
18340 DONE;
18341 })
18342
18343 (define_expand "lfloor<mode>si2"
18344 [(match_operand:SI 0 "nonimmediate_operand" "")
18345 (match_operand:MODEF 1 "register_operand" "")]
18346 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18347 && !flag_trapping_math"
18348 {
18349 if (optimize_insn_for_size_p () && TARGET_64BIT)
18350 FAIL;
18351 ix86_expand_lfloorceil (operand0, operand1, true);
18352 DONE;
18353 })
18354
18355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18356 (define_insn_and_split "frndintxf2_ceil"
18357 [(set (match_operand:XF 0 "register_operand" "")
18358 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18359 UNSPEC_FRNDINT_CEIL))
18360 (clobber (reg:CC FLAGS_REG))]
18361 "TARGET_USE_FANCY_MATH_387
18362 && flag_unsafe_math_optimizations
18363 && !(reload_completed || reload_in_progress)"
18364 "#"
18365 "&& 1"
18366 [(const_int 0)]
18367 {
18368 ix86_optimize_mode_switching[I387_CEIL] = 1;
18369
18370 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18371 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18372
18373 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18374 operands[2], operands[3]));
18375 DONE;
18376 }
18377 [(set_attr "type" "frndint")
18378 (set_attr "i387_cw" "ceil")
18379 (set_attr "mode" "XF")])
18380
18381 (define_insn "frndintxf2_ceil_i387"
18382 [(set (match_operand:XF 0 "register_operand" "=f")
18383 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18384 UNSPEC_FRNDINT_CEIL))
18385 (use (match_operand:HI 2 "memory_operand" "m"))
18386 (use (match_operand:HI 3 "memory_operand" "m"))]
18387 "TARGET_USE_FANCY_MATH_387
18388 && flag_unsafe_math_optimizations"
18389 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18390 [(set_attr "type" "frndint")
18391 (set_attr "i387_cw" "ceil")
18392 (set_attr "mode" "XF")])
18393
18394 (define_expand "ceilxf2"
18395 [(use (match_operand:XF 0 "register_operand" ""))
18396 (use (match_operand:XF 1 "register_operand" ""))]
18397 "TARGET_USE_FANCY_MATH_387
18398 && flag_unsafe_math_optimizations"
18399 {
18400 if (optimize_insn_for_size_p ())
18401 FAIL;
18402 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18403 DONE;
18404 })
18405
18406 (define_expand "ceil<mode>2"
18407 [(use (match_operand:MODEF 0 "register_operand" ""))
18408 (use (match_operand:MODEF 1 "register_operand" ""))]
18409 "(TARGET_USE_FANCY_MATH_387
18410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18411 || TARGET_MIX_SSE_I387)
18412 && flag_unsafe_math_optimizations)
18413 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18414 && !flag_trapping_math)"
18415 {
18416 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18417 && !flag_trapping_math
18418 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18419 {
18420 if (TARGET_ROUND)
18421 emit_insn (gen_sse4_1_round<mode>2
18422 (operands[0], operands[1], GEN_INT (0x02)));
18423 else if (optimize_insn_for_size_p ())
18424 FAIL;
18425 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18426 ix86_expand_floorceil (operand0, operand1, false);
18427 else
18428 ix86_expand_floorceildf_32 (operand0, operand1, false);
18429 }
18430 else
18431 {
18432 rtx op0, op1;
18433
18434 if (optimize_insn_for_size_p ())
18435 FAIL;
18436
18437 op0 = gen_reg_rtx (XFmode);
18438 op1 = gen_reg_rtx (XFmode);
18439 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18440 emit_insn (gen_frndintxf2_ceil (op0, op1));
18441
18442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18443 }
18444 DONE;
18445 })
18446
18447 (define_insn_and_split "*fist<mode>2_ceil_1"
18448 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18449 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18450 UNSPEC_FIST_CEIL))
18451 (clobber (reg:CC FLAGS_REG))]
18452 "TARGET_USE_FANCY_MATH_387
18453 && flag_unsafe_math_optimizations
18454 && !(reload_completed || reload_in_progress)"
18455 "#"
18456 "&& 1"
18457 [(const_int 0)]
18458 {
18459 ix86_optimize_mode_switching[I387_CEIL] = 1;
18460
18461 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18462 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18463 if (memory_operand (operands[0], VOIDmode))
18464 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18465 operands[2], operands[3]));
18466 else
18467 {
18468 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18469 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18470 operands[2], operands[3],
18471 operands[4]));
18472 }
18473 DONE;
18474 }
18475 [(set_attr "type" "fistp")
18476 (set_attr "i387_cw" "ceil")
18477 (set_attr "mode" "<MODE>")])
18478
18479 (define_insn "fistdi2_ceil"
18480 [(set (match_operand:DI 0 "memory_operand" "=m")
18481 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18482 UNSPEC_FIST_CEIL))
18483 (use (match_operand:HI 2 "memory_operand" "m"))
18484 (use (match_operand:HI 3 "memory_operand" "m"))
18485 (clobber (match_scratch:XF 4 "=&1f"))]
18486 "TARGET_USE_FANCY_MATH_387
18487 && flag_unsafe_math_optimizations"
18488 "* return output_fix_trunc (insn, operands, 0);"
18489 [(set_attr "type" "fistp")
18490 (set_attr "i387_cw" "ceil")
18491 (set_attr "mode" "DI")])
18492
18493 (define_insn "fistdi2_ceil_with_temp"
18494 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18495 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18496 UNSPEC_FIST_CEIL))
18497 (use (match_operand:HI 2 "memory_operand" "m,m"))
18498 (use (match_operand:HI 3 "memory_operand" "m,m"))
18499 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18500 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18501 "TARGET_USE_FANCY_MATH_387
18502 && flag_unsafe_math_optimizations"
18503 "#"
18504 [(set_attr "type" "fistp")
18505 (set_attr "i387_cw" "ceil")
18506 (set_attr "mode" "DI")])
18507
18508 (define_split
18509 [(set (match_operand:DI 0 "register_operand" "")
18510 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18511 UNSPEC_FIST_CEIL))
18512 (use (match_operand:HI 2 "memory_operand" ""))
18513 (use (match_operand:HI 3 "memory_operand" ""))
18514 (clobber (match_operand:DI 4 "memory_operand" ""))
18515 (clobber (match_scratch 5 ""))]
18516 "reload_completed"
18517 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18518 (use (match_dup 2))
18519 (use (match_dup 3))
18520 (clobber (match_dup 5))])
18521 (set (match_dup 0) (match_dup 4))]
18522 "")
18523
18524 (define_split
18525 [(set (match_operand:DI 0 "memory_operand" "")
18526 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18527 UNSPEC_FIST_CEIL))
18528 (use (match_operand:HI 2 "memory_operand" ""))
18529 (use (match_operand:HI 3 "memory_operand" ""))
18530 (clobber (match_operand:DI 4 "memory_operand" ""))
18531 (clobber (match_scratch 5 ""))]
18532 "reload_completed"
18533 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18534 (use (match_dup 2))
18535 (use (match_dup 3))
18536 (clobber (match_dup 5))])]
18537 "")
18538
18539 (define_insn "fist<mode>2_ceil"
18540 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18541 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18542 UNSPEC_FIST_CEIL))
18543 (use (match_operand:HI 2 "memory_operand" "m"))
18544 (use (match_operand:HI 3 "memory_operand" "m"))]
18545 "TARGET_USE_FANCY_MATH_387
18546 && flag_unsafe_math_optimizations"
18547 "* return output_fix_trunc (insn, operands, 0);"
18548 [(set_attr "type" "fistp")
18549 (set_attr "i387_cw" "ceil")
18550 (set_attr "mode" "<MODE>")])
18551
18552 (define_insn "fist<mode>2_ceil_with_temp"
18553 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18554 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18555 UNSPEC_FIST_CEIL))
18556 (use (match_operand:HI 2 "memory_operand" "m,m"))
18557 (use (match_operand:HI 3 "memory_operand" "m,m"))
18558 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18559 "TARGET_USE_FANCY_MATH_387
18560 && flag_unsafe_math_optimizations"
18561 "#"
18562 [(set_attr "type" "fistp")
18563 (set_attr "i387_cw" "ceil")
18564 (set_attr "mode" "<MODE>")])
18565
18566 (define_split
18567 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18568 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18569 UNSPEC_FIST_CEIL))
18570 (use (match_operand:HI 2 "memory_operand" ""))
18571 (use (match_operand:HI 3 "memory_operand" ""))
18572 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18573 "reload_completed"
18574 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18575 UNSPEC_FIST_CEIL))
18576 (use (match_dup 2))
18577 (use (match_dup 3))])
18578 (set (match_dup 0) (match_dup 4))]
18579 "")
18580
18581 (define_split
18582 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18583 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18584 UNSPEC_FIST_CEIL))
18585 (use (match_operand:HI 2 "memory_operand" ""))
18586 (use (match_operand:HI 3 "memory_operand" ""))
18587 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18588 "reload_completed"
18589 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18590 UNSPEC_FIST_CEIL))
18591 (use (match_dup 2))
18592 (use (match_dup 3))])]
18593 "")
18594
18595 (define_expand "lceilxf<mode>2"
18596 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18597 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18598 UNSPEC_FIST_CEIL))
18599 (clobber (reg:CC FLAGS_REG))])]
18600 "TARGET_USE_FANCY_MATH_387
18601 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18602 && flag_unsafe_math_optimizations"
18603 "")
18604
18605 (define_expand "lceil<mode>di2"
18606 [(match_operand:DI 0 "nonimmediate_operand" "")
18607 (match_operand:MODEF 1 "register_operand" "")]
18608 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18609 && !flag_trapping_math"
18610 {
18611 ix86_expand_lfloorceil (operand0, operand1, false);
18612 DONE;
18613 })
18614
18615 (define_expand "lceil<mode>si2"
18616 [(match_operand:SI 0 "nonimmediate_operand" "")
18617 (match_operand:MODEF 1 "register_operand" "")]
18618 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18619 && !flag_trapping_math"
18620 {
18621 ix86_expand_lfloorceil (operand0, operand1, false);
18622 DONE;
18623 })
18624
18625 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18626 (define_insn_and_split "frndintxf2_trunc"
18627 [(set (match_operand:XF 0 "register_operand" "")
18628 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18629 UNSPEC_FRNDINT_TRUNC))
18630 (clobber (reg:CC FLAGS_REG))]
18631 "TARGET_USE_FANCY_MATH_387
18632 && flag_unsafe_math_optimizations
18633 && !(reload_completed || reload_in_progress)"
18634 "#"
18635 "&& 1"
18636 [(const_int 0)]
18637 {
18638 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18639
18640 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18641 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18642
18643 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18644 operands[2], operands[3]));
18645 DONE;
18646 }
18647 [(set_attr "type" "frndint")
18648 (set_attr "i387_cw" "trunc")
18649 (set_attr "mode" "XF")])
18650
18651 (define_insn "frndintxf2_trunc_i387"
18652 [(set (match_operand:XF 0 "register_operand" "=f")
18653 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18654 UNSPEC_FRNDINT_TRUNC))
18655 (use (match_operand:HI 2 "memory_operand" "m"))
18656 (use (match_operand:HI 3 "memory_operand" "m"))]
18657 "TARGET_USE_FANCY_MATH_387
18658 && flag_unsafe_math_optimizations"
18659 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18660 [(set_attr "type" "frndint")
18661 (set_attr "i387_cw" "trunc")
18662 (set_attr "mode" "XF")])
18663
18664 (define_expand "btruncxf2"
18665 [(use (match_operand:XF 0 "register_operand" ""))
18666 (use (match_operand:XF 1 "register_operand" ""))]
18667 "TARGET_USE_FANCY_MATH_387
18668 && flag_unsafe_math_optimizations"
18669 {
18670 if (optimize_insn_for_size_p ())
18671 FAIL;
18672 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18673 DONE;
18674 })
18675
18676 (define_expand "btrunc<mode>2"
18677 [(use (match_operand:MODEF 0 "register_operand" ""))
18678 (use (match_operand:MODEF 1 "register_operand" ""))]
18679 "(TARGET_USE_FANCY_MATH_387
18680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18681 || TARGET_MIX_SSE_I387)
18682 && flag_unsafe_math_optimizations)
18683 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18684 && !flag_trapping_math)"
18685 {
18686 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18687 && !flag_trapping_math
18688 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18689 {
18690 if (TARGET_ROUND)
18691 emit_insn (gen_sse4_1_round<mode>2
18692 (operands[0], operands[1], GEN_INT (0x03)));
18693 else if (optimize_insn_for_size_p ())
18694 FAIL;
18695 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18696 ix86_expand_trunc (operand0, operand1);
18697 else
18698 ix86_expand_truncdf_32 (operand0, operand1);
18699 }
18700 else
18701 {
18702 rtx op0, op1;
18703
18704 if (optimize_insn_for_size_p ())
18705 FAIL;
18706
18707 op0 = gen_reg_rtx (XFmode);
18708 op1 = gen_reg_rtx (XFmode);
18709 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18710 emit_insn (gen_frndintxf2_trunc (op0, op1));
18711
18712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18713 }
18714 DONE;
18715 })
18716
18717 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18718 (define_insn_and_split "frndintxf2_mask_pm"
18719 [(set (match_operand:XF 0 "register_operand" "")
18720 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18721 UNSPEC_FRNDINT_MASK_PM))
18722 (clobber (reg:CC FLAGS_REG))]
18723 "TARGET_USE_FANCY_MATH_387
18724 && flag_unsafe_math_optimizations
18725 && !(reload_completed || reload_in_progress)"
18726 "#"
18727 "&& 1"
18728 [(const_int 0)]
18729 {
18730 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18731
18732 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18733 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18734
18735 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18736 operands[2], operands[3]));
18737 DONE;
18738 }
18739 [(set_attr "type" "frndint")
18740 (set_attr "i387_cw" "mask_pm")
18741 (set_attr "mode" "XF")])
18742
18743 (define_insn "frndintxf2_mask_pm_i387"
18744 [(set (match_operand:XF 0 "register_operand" "=f")
18745 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18746 UNSPEC_FRNDINT_MASK_PM))
18747 (use (match_operand:HI 2 "memory_operand" "m"))
18748 (use (match_operand:HI 3 "memory_operand" "m"))]
18749 "TARGET_USE_FANCY_MATH_387
18750 && flag_unsafe_math_optimizations"
18751 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18752 [(set_attr "type" "frndint")
18753 (set_attr "i387_cw" "mask_pm")
18754 (set_attr "mode" "XF")])
18755
18756 (define_expand "nearbyintxf2"
18757 [(use (match_operand:XF 0 "register_operand" ""))
18758 (use (match_operand:XF 1 "register_operand" ""))]
18759 "TARGET_USE_FANCY_MATH_387
18760 && flag_unsafe_math_optimizations"
18761 {
18762 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18763
18764 DONE;
18765 })
18766
18767 (define_expand "nearbyint<mode>2"
18768 [(use (match_operand:MODEF 0 "register_operand" ""))
18769 (use (match_operand:MODEF 1 "register_operand" ""))]
18770 "TARGET_USE_FANCY_MATH_387
18771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18772 || TARGET_MIX_SSE_I387)
18773 && flag_unsafe_math_optimizations"
18774 {
18775 rtx op0 = gen_reg_rtx (XFmode);
18776 rtx op1 = gen_reg_rtx (XFmode);
18777
18778 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18779 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18780
18781 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18782 DONE;
18783 })
18784
18785 (define_insn "fxam<mode>2_i387"
18786 [(set (match_operand:HI 0 "register_operand" "=a")
18787 (unspec:HI
18788 [(match_operand:X87MODEF 1 "register_operand" "f")]
18789 UNSPEC_FXAM))]
18790 "TARGET_USE_FANCY_MATH_387"
18791 "fxam\n\tfnstsw\t%0"
18792 [(set_attr "type" "multi")
18793 (set_attr "unit" "i387")
18794 (set_attr "mode" "<MODE>")])
18795
18796 (define_expand "isinf<mode>2"
18797 [(use (match_operand:SI 0 "register_operand" ""))
18798 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18799 "TARGET_USE_FANCY_MATH_387
18800 && TARGET_C99_FUNCTIONS
18801 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18802 {
18803 rtx mask = GEN_INT (0x45);
18804 rtx val = GEN_INT (0x05);
18805
18806 rtx cond;
18807
18808 rtx scratch = gen_reg_rtx (HImode);
18809 rtx res = gen_reg_rtx (QImode);
18810
18811 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18812 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18813 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18814 cond = gen_rtx_fmt_ee (EQ, QImode,
18815 gen_rtx_REG (CCmode, FLAGS_REG),
18816 const0_rtx);
18817 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18818 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18819 DONE;
18820 })
18821
18822 (define_expand "signbit<mode>2"
18823 [(use (match_operand:SI 0 "register_operand" ""))
18824 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18825 "TARGET_USE_FANCY_MATH_387
18826 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18827 {
18828 rtx mask = GEN_INT (0x0200);
18829
18830 rtx scratch = gen_reg_rtx (HImode);
18831
18832 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18833 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18834 DONE;
18835 })
18836 \f
18837 ;; Block operation instructions
18838
18839 (define_insn "cld"
18840 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18841 ""
18842 "cld"
18843 [(set_attr "length" "1")
18844 (set_attr "length_immediate" "0")
18845 (set_attr "modrm" "0")])
18846
18847 (define_expand "movmemsi"
18848 [(use (match_operand:BLK 0 "memory_operand" ""))
18849 (use (match_operand:BLK 1 "memory_operand" ""))
18850 (use (match_operand:SI 2 "nonmemory_operand" ""))
18851 (use (match_operand:SI 3 "const_int_operand" ""))
18852 (use (match_operand:SI 4 "const_int_operand" ""))
18853 (use (match_operand:SI 5 "const_int_operand" ""))]
18854 ""
18855 {
18856 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18857 operands[4], operands[5]))
18858 DONE;
18859 else
18860 FAIL;
18861 })
18862
18863 (define_expand "movmemdi"
18864 [(use (match_operand:BLK 0 "memory_operand" ""))
18865 (use (match_operand:BLK 1 "memory_operand" ""))
18866 (use (match_operand:DI 2 "nonmemory_operand" ""))
18867 (use (match_operand:DI 3 "const_int_operand" ""))
18868 (use (match_operand:SI 4 "const_int_operand" ""))
18869 (use (match_operand:SI 5 "const_int_operand" ""))]
18870 "TARGET_64BIT"
18871 {
18872 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18873 operands[4], operands[5]))
18874 DONE;
18875 else
18876 FAIL;
18877 })
18878
18879 ;; Most CPUs don't like single string operations
18880 ;; Handle this case here to simplify previous expander.
18881
18882 (define_expand "strmov"
18883 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18884 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18885 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18886 (clobber (reg:CC FLAGS_REG))])
18887 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18888 (clobber (reg:CC FLAGS_REG))])]
18889 ""
18890 {
18891 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18892
18893 /* If .md ever supports :P for Pmode, these can be directly
18894 in the pattern above. */
18895 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18896 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18897
18898 /* Can't use this if the user has appropriated esi or edi. */
18899 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18900 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18901 {
18902 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18903 operands[2], operands[3],
18904 operands[5], operands[6]));
18905 DONE;
18906 }
18907
18908 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18909 })
18910
18911 (define_expand "strmov_singleop"
18912 [(parallel [(set (match_operand 1 "memory_operand" "")
18913 (match_operand 3 "memory_operand" ""))
18914 (set (match_operand 0 "register_operand" "")
18915 (match_operand 4 "" ""))
18916 (set (match_operand 2 "register_operand" "")
18917 (match_operand 5 "" ""))])]
18918 ""
18919 "ix86_current_function_needs_cld = 1;")
18920
18921 (define_insn "*strmovdi_rex_1"
18922 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18923 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18924 (set (match_operand:DI 0 "register_operand" "=D")
18925 (plus:DI (match_dup 2)
18926 (const_int 8)))
18927 (set (match_operand:DI 1 "register_operand" "=S")
18928 (plus:DI (match_dup 3)
18929 (const_int 8)))]
18930 "TARGET_64BIT"
18931 "movsq"
18932 [(set_attr "type" "str")
18933 (set_attr "mode" "DI")
18934 (set_attr "memory" "both")])
18935
18936 (define_insn "*strmovsi_1"
18937 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18938 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18939 (set (match_operand:SI 0 "register_operand" "=D")
18940 (plus:SI (match_dup 2)
18941 (const_int 4)))
18942 (set (match_operand:SI 1 "register_operand" "=S")
18943 (plus:SI (match_dup 3)
18944 (const_int 4)))]
18945 "!TARGET_64BIT"
18946 "movs{l|d}"
18947 [(set_attr "type" "str")
18948 (set_attr "mode" "SI")
18949 (set_attr "memory" "both")])
18950
18951 (define_insn "*strmovsi_rex_1"
18952 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18953 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18954 (set (match_operand:DI 0 "register_operand" "=D")
18955 (plus:DI (match_dup 2)
18956 (const_int 4)))
18957 (set (match_operand:DI 1 "register_operand" "=S")
18958 (plus:DI (match_dup 3)
18959 (const_int 4)))]
18960 "TARGET_64BIT"
18961 "movs{l|d}"
18962 [(set_attr "type" "str")
18963 (set_attr "mode" "SI")
18964 (set_attr "memory" "both")])
18965
18966 (define_insn "*strmovhi_1"
18967 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18968 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18969 (set (match_operand:SI 0 "register_operand" "=D")
18970 (plus:SI (match_dup 2)
18971 (const_int 2)))
18972 (set (match_operand:SI 1 "register_operand" "=S")
18973 (plus:SI (match_dup 3)
18974 (const_int 2)))]
18975 "!TARGET_64BIT"
18976 "movsw"
18977 [(set_attr "type" "str")
18978 (set_attr "memory" "both")
18979 (set_attr "mode" "HI")])
18980
18981 (define_insn "*strmovhi_rex_1"
18982 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18983 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18984 (set (match_operand:DI 0 "register_operand" "=D")
18985 (plus:DI (match_dup 2)
18986 (const_int 2)))
18987 (set (match_operand:DI 1 "register_operand" "=S")
18988 (plus:DI (match_dup 3)
18989 (const_int 2)))]
18990 "TARGET_64BIT"
18991 "movsw"
18992 [(set_attr "type" "str")
18993 (set_attr "memory" "both")
18994 (set_attr "mode" "HI")])
18995
18996 (define_insn "*strmovqi_1"
18997 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18998 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18999 (set (match_operand:SI 0 "register_operand" "=D")
19000 (plus:SI (match_dup 2)
19001 (const_int 1)))
19002 (set (match_operand:SI 1 "register_operand" "=S")
19003 (plus:SI (match_dup 3)
19004 (const_int 1)))]
19005 "!TARGET_64BIT"
19006 "movsb"
19007 [(set_attr "type" "str")
19008 (set_attr "memory" "both")
19009 (set_attr "mode" "QI")])
19010
19011 (define_insn "*strmovqi_rex_1"
19012 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19013 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19014 (set (match_operand:DI 0 "register_operand" "=D")
19015 (plus:DI (match_dup 2)
19016 (const_int 1)))
19017 (set (match_operand:DI 1 "register_operand" "=S")
19018 (plus:DI (match_dup 3)
19019 (const_int 1)))]
19020 "TARGET_64BIT"
19021 "movsb"
19022 [(set_attr "type" "str")
19023 (set_attr "memory" "both")
19024 (set_attr "mode" "QI")])
19025
19026 (define_expand "rep_mov"
19027 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19028 (set (match_operand 0 "register_operand" "")
19029 (match_operand 5 "" ""))
19030 (set (match_operand 2 "register_operand" "")
19031 (match_operand 6 "" ""))
19032 (set (match_operand 1 "memory_operand" "")
19033 (match_operand 3 "memory_operand" ""))
19034 (use (match_dup 4))])]
19035 ""
19036 "ix86_current_function_needs_cld = 1;")
19037
19038 (define_insn "*rep_movdi_rex64"
19039 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19040 (set (match_operand:DI 0 "register_operand" "=D")
19041 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19042 (const_int 3))
19043 (match_operand:DI 3 "register_operand" "0")))
19044 (set (match_operand:DI 1 "register_operand" "=S")
19045 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19046 (match_operand:DI 4 "register_operand" "1")))
19047 (set (mem:BLK (match_dup 3))
19048 (mem:BLK (match_dup 4)))
19049 (use (match_dup 5))]
19050 "TARGET_64BIT"
19051 "rep movsq"
19052 [(set_attr "type" "str")
19053 (set_attr "prefix_rep" "1")
19054 (set_attr "memory" "both")
19055 (set_attr "mode" "DI")])
19056
19057 (define_insn "*rep_movsi"
19058 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19059 (set (match_operand:SI 0 "register_operand" "=D")
19060 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19061 (const_int 2))
19062 (match_operand:SI 3 "register_operand" "0")))
19063 (set (match_operand:SI 1 "register_operand" "=S")
19064 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19065 (match_operand:SI 4 "register_operand" "1")))
19066 (set (mem:BLK (match_dup 3))
19067 (mem:BLK (match_dup 4)))
19068 (use (match_dup 5))]
19069 "!TARGET_64BIT"
19070 "rep movs{l|d}"
19071 [(set_attr "type" "str")
19072 (set_attr "prefix_rep" "1")
19073 (set_attr "memory" "both")
19074 (set_attr "mode" "SI")])
19075
19076 (define_insn "*rep_movsi_rex64"
19077 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19078 (set (match_operand:DI 0 "register_operand" "=D")
19079 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19080 (const_int 2))
19081 (match_operand:DI 3 "register_operand" "0")))
19082 (set (match_operand:DI 1 "register_operand" "=S")
19083 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19084 (match_operand:DI 4 "register_operand" "1")))
19085 (set (mem:BLK (match_dup 3))
19086 (mem:BLK (match_dup 4)))
19087 (use (match_dup 5))]
19088 "TARGET_64BIT"
19089 "rep movs{l|d}"
19090 [(set_attr "type" "str")
19091 (set_attr "prefix_rep" "1")
19092 (set_attr "memory" "both")
19093 (set_attr "mode" "SI")])
19094
19095 (define_insn "*rep_movqi"
19096 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19097 (set (match_operand:SI 0 "register_operand" "=D")
19098 (plus:SI (match_operand:SI 3 "register_operand" "0")
19099 (match_operand:SI 5 "register_operand" "2")))
19100 (set (match_operand:SI 1 "register_operand" "=S")
19101 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19102 (set (mem:BLK (match_dup 3))
19103 (mem:BLK (match_dup 4)))
19104 (use (match_dup 5))]
19105 "!TARGET_64BIT"
19106 "rep movsb"
19107 [(set_attr "type" "str")
19108 (set_attr "prefix_rep" "1")
19109 (set_attr "memory" "both")
19110 (set_attr "mode" "SI")])
19111
19112 (define_insn "*rep_movqi_rex64"
19113 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19114 (set (match_operand:DI 0 "register_operand" "=D")
19115 (plus:DI (match_operand:DI 3 "register_operand" "0")
19116 (match_operand:DI 5 "register_operand" "2")))
19117 (set (match_operand:DI 1 "register_operand" "=S")
19118 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19119 (set (mem:BLK (match_dup 3))
19120 (mem:BLK (match_dup 4)))
19121 (use (match_dup 5))]
19122 "TARGET_64BIT"
19123 "rep movsb"
19124 [(set_attr "type" "str")
19125 (set_attr "prefix_rep" "1")
19126 (set_attr "memory" "both")
19127 (set_attr "mode" "SI")])
19128
19129 (define_expand "setmemsi"
19130 [(use (match_operand:BLK 0 "memory_operand" ""))
19131 (use (match_operand:SI 1 "nonmemory_operand" ""))
19132 (use (match_operand 2 "const_int_operand" ""))
19133 (use (match_operand 3 "const_int_operand" ""))
19134 (use (match_operand:SI 4 "const_int_operand" ""))
19135 (use (match_operand:SI 5 "const_int_operand" ""))]
19136 ""
19137 {
19138 if (ix86_expand_setmem (operands[0], operands[1],
19139 operands[2], operands[3],
19140 operands[4], operands[5]))
19141 DONE;
19142 else
19143 FAIL;
19144 })
19145
19146 (define_expand "setmemdi"
19147 [(use (match_operand:BLK 0 "memory_operand" ""))
19148 (use (match_operand:DI 1 "nonmemory_operand" ""))
19149 (use (match_operand 2 "const_int_operand" ""))
19150 (use (match_operand 3 "const_int_operand" ""))
19151 (use (match_operand 4 "const_int_operand" ""))
19152 (use (match_operand 5 "const_int_operand" ""))]
19153 "TARGET_64BIT"
19154 {
19155 if (ix86_expand_setmem (operands[0], operands[1],
19156 operands[2], operands[3],
19157 operands[4], operands[5]))
19158 DONE;
19159 else
19160 FAIL;
19161 })
19162
19163 ;; Most CPUs don't like single string operations
19164 ;; Handle this case here to simplify previous expander.
19165
19166 (define_expand "strset"
19167 [(set (match_operand 1 "memory_operand" "")
19168 (match_operand 2 "register_operand" ""))
19169 (parallel [(set (match_operand 0 "register_operand" "")
19170 (match_dup 3))
19171 (clobber (reg:CC FLAGS_REG))])]
19172 ""
19173 {
19174 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19175 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19176
19177 /* If .md ever supports :P for Pmode, this can be directly
19178 in the pattern above. */
19179 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19180 GEN_INT (GET_MODE_SIZE (GET_MODE
19181 (operands[2]))));
19182 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19183 {
19184 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19185 operands[3]));
19186 DONE;
19187 }
19188 })
19189
19190 (define_expand "strset_singleop"
19191 [(parallel [(set (match_operand 1 "memory_operand" "")
19192 (match_operand 2 "register_operand" ""))
19193 (set (match_operand 0 "register_operand" "")
19194 (match_operand 3 "" ""))])]
19195 ""
19196 "ix86_current_function_needs_cld = 1;")
19197
19198 (define_insn "*strsetdi_rex_1"
19199 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19200 (match_operand:DI 2 "register_operand" "a"))
19201 (set (match_operand:DI 0 "register_operand" "=D")
19202 (plus:DI (match_dup 1)
19203 (const_int 8)))]
19204 "TARGET_64BIT"
19205 "stosq"
19206 [(set_attr "type" "str")
19207 (set_attr "memory" "store")
19208 (set_attr "mode" "DI")])
19209
19210 (define_insn "*strsetsi_1"
19211 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19212 (match_operand:SI 2 "register_operand" "a"))
19213 (set (match_operand:SI 0 "register_operand" "=D")
19214 (plus:SI (match_dup 1)
19215 (const_int 4)))]
19216 "!TARGET_64BIT"
19217 "stos{l|d}"
19218 [(set_attr "type" "str")
19219 (set_attr "memory" "store")
19220 (set_attr "mode" "SI")])
19221
19222 (define_insn "*strsetsi_rex_1"
19223 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19224 (match_operand:SI 2 "register_operand" "a"))
19225 (set (match_operand:DI 0 "register_operand" "=D")
19226 (plus:DI (match_dup 1)
19227 (const_int 4)))]
19228 "TARGET_64BIT"
19229 "stos{l|d}"
19230 [(set_attr "type" "str")
19231 (set_attr "memory" "store")
19232 (set_attr "mode" "SI")])
19233
19234 (define_insn "*strsethi_1"
19235 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19236 (match_operand:HI 2 "register_operand" "a"))
19237 (set (match_operand:SI 0 "register_operand" "=D")
19238 (plus:SI (match_dup 1)
19239 (const_int 2)))]
19240 "!TARGET_64BIT"
19241 "stosw"
19242 [(set_attr "type" "str")
19243 (set_attr "memory" "store")
19244 (set_attr "mode" "HI")])
19245
19246 (define_insn "*strsethi_rex_1"
19247 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19248 (match_operand:HI 2 "register_operand" "a"))
19249 (set (match_operand:DI 0 "register_operand" "=D")
19250 (plus:DI (match_dup 1)
19251 (const_int 2)))]
19252 "TARGET_64BIT"
19253 "stosw"
19254 [(set_attr "type" "str")
19255 (set_attr "memory" "store")
19256 (set_attr "mode" "HI")])
19257
19258 (define_insn "*strsetqi_1"
19259 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19260 (match_operand:QI 2 "register_operand" "a"))
19261 (set (match_operand:SI 0 "register_operand" "=D")
19262 (plus:SI (match_dup 1)
19263 (const_int 1)))]
19264 "!TARGET_64BIT"
19265 "stosb"
19266 [(set_attr "type" "str")
19267 (set_attr "memory" "store")
19268 (set_attr "mode" "QI")])
19269
19270 (define_insn "*strsetqi_rex_1"
19271 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19272 (match_operand:QI 2 "register_operand" "a"))
19273 (set (match_operand:DI 0 "register_operand" "=D")
19274 (plus:DI (match_dup 1)
19275 (const_int 1)))]
19276 "TARGET_64BIT"
19277 "stosb"
19278 [(set_attr "type" "str")
19279 (set_attr "memory" "store")
19280 (set_attr "mode" "QI")])
19281
19282 (define_expand "rep_stos"
19283 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19284 (set (match_operand 0 "register_operand" "")
19285 (match_operand 4 "" ""))
19286 (set (match_operand 2 "memory_operand" "") (const_int 0))
19287 (use (match_operand 3 "register_operand" ""))
19288 (use (match_dup 1))])]
19289 ""
19290 "ix86_current_function_needs_cld = 1;")
19291
19292 (define_insn "*rep_stosdi_rex64"
19293 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19294 (set (match_operand:DI 0 "register_operand" "=D")
19295 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19296 (const_int 3))
19297 (match_operand:DI 3 "register_operand" "0")))
19298 (set (mem:BLK (match_dup 3))
19299 (const_int 0))
19300 (use (match_operand:DI 2 "register_operand" "a"))
19301 (use (match_dup 4))]
19302 "TARGET_64BIT"
19303 "rep stosq"
19304 [(set_attr "type" "str")
19305 (set_attr "prefix_rep" "1")
19306 (set_attr "memory" "store")
19307 (set_attr "mode" "DI")])
19308
19309 (define_insn "*rep_stossi"
19310 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19311 (set (match_operand:SI 0 "register_operand" "=D")
19312 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19313 (const_int 2))
19314 (match_operand:SI 3 "register_operand" "0")))
19315 (set (mem:BLK (match_dup 3))
19316 (const_int 0))
19317 (use (match_operand:SI 2 "register_operand" "a"))
19318 (use (match_dup 4))]
19319 "!TARGET_64BIT"
19320 "rep stos{l|d}"
19321 [(set_attr "type" "str")
19322 (set_attr "prefix_rep" "1")
19323 (set_attr "memory" "store")
19324 (set_attr "mode" "SI")])
19325
19326 (define_insn "*rep_stossi_rex64"
19327 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19328 (set (match_operand:DI 0 "register_operand" "=D")
19329 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19330 (const_int 2))
19331 (match_operand:DI 3 "register_operand" "0")))
19332 (set (mem:BLK (match_dup 3))
19333 (const_int 0))
19334 (use (match_operand:SI 2 "register_operand" "a"))
19335 (use (match_dup 4))]
19336 "TARGET_64BIT"
19337 "rep stos{l|d}"
19338 [(set_attr "type" "str")
19339 (set_attr "prefix_rep" "1")
19340 (set_attr "memory" "store")
19341 (set_attr "mode" "SI")])
19342
19343 (define_insn "*rep_stosqi"
19344 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19345 (set (match_operand:SI 0 "register_operand" "=D")
19346 (plus:SI (match_operand:SI 3 "register_operand" "0")
19347 (match_operand:SI 4 "register_operand" "1")))
19348 (set (mem:BLK (match_dup 3))
19349 (const_int 0))
19350 (use (match_operand:QI 2 "register_operand" "a"))
19351 (use (match_dup 4))]
19352 "!TARGET_64BIT"
19353 "rep stosb"
19354 [(set_attr "type" "str")
19355 (set_attr "prefix_rep" "1")
19356 (set_attr "memory" "store")
19357 (set_attr "mode" "QI")])
19358
19359 (define_insn "*rep_stosqi_rex64"
19360 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19361 (set (match_operand:DI 0 "register_operand" "=D")
19362 (plus:DI (match_operand:DI 3 "register_operand" "0")
19363 (match_operand:DI 4 "register_operand" "1")))
19364 (set (mem:BLK (match_dup 3))
19365 (const_int 0))
19366 (use (match_operand:QI 2 "register_operand" "a"))
19367 (use (match_dup 4))]
19368 "TARGET_64BIT"
19369 "rep stosb"
19370 [(set_attr "type" "str")
19371 (set_attr "prefix_rep" "1")
19372 (set_attr "memory" "store")
19373 (set_attr "mode" "QI")])
19374
19375 (define_expand "cmpstrnsi"
19376 [(set (match_operand:SI 0 "register_operand" "")
19377 (compare:SI (match_operand:BLK 1 "general_operand" "")
19378 (match_operand:BLK 2 "general_operand" "")))
19379 (use (match_operand 3 "general_operand" ""))
19380 (use (match_operand 4 "immediate_operand" ""))]
19381 ""
19382 {
19383 rtx addr1, addr2, out, outlow, count, countreg, align;
19384
19385 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19386 FAIL;
19387
19388 /* Can't use this if the user has appropriated esi or edi. */
19389 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19390 FAIL;
19391
19392 out = operands[0];
19393 if (!REG_P (out))
19394 out = gen_reg_rtx (SImode);
19395
19396 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19397 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19398 if (addr1 != XEXP (operands[1], 0))
19399 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19400 if (addr2 != XEXP (operands[2], 0))
19401 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19402
19403 count = operands[3];
19404 countreg = ix86_zero_extend_to_Pmode (count);
19405
19406 /* %%% Iff we are testing strict equality, we can use known alignment
19407 to good advantage. This may be possible with combine, particularly
19408 once cc0 is dead. */
19409 align = operands[4];
19410
19411 if (CONST_INT_P (count))
19412 {
19413 if (INTVAL (count) == 0)
19414 {
19415 emit_move_insn (operands[0], const0_rtx);
19416 DONE;
19417 }
19418 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19419 operands[1], operands[2]));
19420 }
19421 else
19422 {
19423 if (TARGET_64BIT)
19424 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19425 else
19426 emit_insn (gen_cmpsi_1 (countreg, countreg));
19427 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19428 operands[1], operands[2]));
19429 }
19430
19431 outlow = gen_lowpart (QImode, out);
19432 emit_insn (gen_cmpintqi (outlow));
19433 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19434
19435 if (operands[0] != out)
19436 emit_move_insn (operands[0], out);
19437
19438 DONE;
19439 })
19440
19441 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19442
19443 (define_expand "cmpintqi"
19444 [(set (match_dup 1)
19445 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19446 (set (match_dup 2)
19447 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19448 (parallel [(set (match_operand:QI 0 "register_operand" "")
19449 (minus:QI (match_dup 1)
19450 (match_dup 2)))
19451 (clobber (reg:CC FLAGS_REG))])]
19452 ""
19453 "operands[1] = gen_reg_rtx (QImode);
19454 operands[2] = gen_reg_rtx (QImode);")
19455
19456 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19457 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19458
19459 (define_expand "cmpstrnqi_nz_1"
19460 [(parallel [(set (reg:CC FLAGS_REG)
19461 (compare:CC (match_operand 4 "memory_operand" "")
19462 (match_operand 5 "memory_operand" "")))
19463 (use (match_operand 2 "register_operand" ""))
19464 (use (match_operand:SI 3 "immediate_operand" ""))
19465 (clobber (match_operand 0 "register_operand" ""))
19466 (clobber (match_operand 1 "register_operand" ""))
19467 (clobber (match_dup 2))])]
19468 ""
19469 "ix86_current_function_needs_cld = 1;")
19470
19471 (define_insn "*cmpstrnqi_nz_1"
19472 [(set (reg:CC FLAGS_REG)
19473 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19474 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19475 (use (match_operand:SI 6 "register_operand" "2"))
19476 (use (match_operand:SI 3 "immediate_operand" "i"))
19477 (clobber (match_operand:SI 0 "register_operand" "=S"))
19478 (clobber (match_operand:SI 1 "register_operand" "=D"))
19479 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19480 "!TARGET_64BIT"
19481 "repz cmpsb"
19482 [(set_attr "type" "str")
19483 (set_attr "mode" "QI")
19484 (set_attr "prefix_rep" "1")])
19485
19486 (define_insn "*cmpstrnqi_nz_rex_1"
19487 [(set (reg:CC FLAGS_REG)
19488 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19489 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19490 (use (match_operand:DI 6 "register_operand" "2"))
19491 (use (match_operand:SI 3 "immediate_operand" "i"))
19492 (clobber (match_operand:DI 0 "register_operand" "=S"))
19493 (clobber (match_operand:DI 1 "register_operand" "=D"))
19494 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19495 "TARGET_64BIT"
19496 "repz cmpsb"
19497 [(set_attr "type" "str")
19498 (set_attr "mode" "QI")
19499 (set_attr "prefix_rep" "1")])
19500
19501 ;; The same, but the count is not known to not be zero.
19502
19503 (define_expand "cmpstrnqi_1"
19504 [(parallel [(set (reg:CC FLAGS_REG)
19505 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19506 (const_int 0))
19507 (compare:CC (match_operand 4 "memory_operand" "")
19508 (match_operand 5 "memory_operand" ""))
19509 (const_int 0)))
19510 (use (match_operand:SI 3 "immediate_operand" ""))
19511 (use (reg:CC FLAGS_REG))
19512 (clobber (match_operand 0 "register_operand" ""))
19513 (clobber (match_operand 1 "register_operand" ""))
19514 (clobber (match_dup 2))])]
19515 ""
19516 "ix86_current_function_needs_cld = 1;")
19517
19518 (define_insn "*cmpstrnqi_1"
19519 [(set (reg:CC FLAGS_REG)
19520 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19521 (const_int 0))
19522 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19523 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19524 (const_int 0)))
19525 (use (match_operand:SI 3 "immediate_operand" "i"))
19526 (use (reg:CC FLAGS_REG))
19527 (clobber (match_operand:SI 0 "register_operand" "=S"))
19528 (clobber (match_operand:SI 1 "register_operand" "=D"))
19529 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19530 "!TARGET_64BIT"
19531 "repz cmpsb"
19532 [(set_attr "type" "str")
19533 (set_attr "mode" "QI")
19534 (set_attr "prefix_rep" "1")])
19535
19536 (define_insn "*cmpstrnqi_rex_1"
19537 [(set (reg:CC FLAGS_REG)
19538 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19539 (const_int 0))
19540 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19541 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19542 (const_int 0)))
19543 (use (match_operand:SI 3 "immediate_operand" "i"))
19544 (use (reg:CC FLAGS_REG))
19545 (clobber (match_operand:DI 0 "register_operand" "=S"))
19546 (clobber (match_operand:DI 1 "register_operand" "=D"))
19547 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19548 "TARGET_64BIT"
19549 "repz cmpsb"
19550 [(set_attr "type" "str")
19551 (set_attr "mode" "QI")
19552 (set_attr "prefix_rep" "1")])
19553
19554 (define_expand "strlensi"
19555 [(set (match_operand:SI 0 "register_operand" "")
19556 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19557 (match_operand:QI 2 "immediate_operand" "")
19558 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19559 ""
19560 {
19561 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19562 DONE;
19563 else
19564 FAIL;
19565 })
19566
19567 (define_expand "strlendi"
19568 [(set (match_operand:DI 0 "register_operand" "")
19569 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19570 (match_operand:QI 2 "immediate_operand" "")
19571 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19572 ""
19573 {
19574 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19575 DONE;
19576 else
19577 FAIL;
19578 })
19579
19580 (define_expand "strlenqi_1"
19581 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19582 (clobber (match_operand 1 "register_operand" ""))
19583 (clobber (reg:CC FLAGS_REG))])]
19584 ""
19585 "ix86_current_function_needs_cld = 1;")
19586
19587 (define_insn "*strlenqi_1"
19588 [(set (match_operand:SI 0 "register_operand" "=&c")
19589 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19590 (match_operand:QI 2 "register_operand" "a")
19591 (match_operand:SI 3 "immediate_operand" "i")
19592 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19593 (clobber (match_operand:SI 1 "register_operand" "=D"))
19594 (clobber (reg:CC FLAGS_REG))]
19595 "!TARGET_64BIT"
19596 "repnz scasb"
19597 [(set_attr "type" "str")
19598 (set_attr "mode" "QI")
19599 (set_attr "prefix_rep" "1")])
19600
19601 (define_insn "*strlenqi_rex_1"
19602 [(set (match_operand:DI 0 "register_operand" "=&c")
19603 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19604 (match_operand:QI 2 "register_operand" "a")
19605 (match_operand:DI 3 "immediate_operand" "i")
19606 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19607 (clobber (match_operand:DI 1 "register_operand" "=D"))
19608 (clobber (reg:CC FLAGS_REG))]
19609 "TARGET_64BIT"
19610 "repnz scasb"
19611 [(set_attr "type" "str")
19612 (set_attr "mode" "QI")
19613 (set_attr "prefix_rep" "1")])
19614
19615 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19616 ;; handled in combine, but it is not currently up to the task.
19617 ;; When used for their truth value, the cmpstrn* expanders generate
19618 ;; code like this:
19619 ;;
19620 ;; repz cmpsb
19621 ;; seta %al
19622 ;; setb %dl
19623 ;; cmpb %al, %dl
19624 ;; jcc label
19625 ;;
19626 ;; The intermediate three instructions are unnecessary.
19627
19628 ;; This one handles cmpstrn*_nz_1...
19629 (define_peephole2
19630 [(parallel[
19631 (set (reg:CC FLAGS_REG)
19632 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19633 (mem:BLK (match_operand 5 "register_operand" ""))))
19634 (use (match_operand 6 "register_operand" ""))
19635 (use (match_operand:SI 3 "immediate_operand" ""))
19636 (clobber (match_operand 0 "register_operand" ""))
19637 (clobber (match_operand 1 "register_operand" ""))
19638 (clobber (match_operand 2 "register_operand" ""))])
19639 (set (match_operand:QI 7 "register_operand" "")
19640 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19641 (set (match_operand:QI 8 "register_operand" "")
19642 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19643 (set (reg FLAGS_REG)
19644 (compare (match_dup 7) (match_dup 8)))
19645 ]
19646 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19647 [(parallel[
19648 (set (reg:CC FLAGS_REG)
19649 (compare:CC (mem:BLK (match_dup 4))
19650 (mem:BLK (match_dup 5))))
19651 (use (match_dup 6))
19652 (use (match_dup 3))
19653 (clobber (match_dup 0))
19654 (clobber (match_dup 1))
19655 (clobber (match_dup 2))])]
19656 "")
19657
19658 ;; ...and this one handles cmpstrn*_1.
19659 (define_peephole2
19660 [(parallel[
19661 (set (reg:CC FLAGS_REG)
19662 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19663 (const_int 0))
19664 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19665 (mem:BLK (match_operand 5 "register_operand" "")))
19666 (const_int 0)))
19667 (use (match_operand:SI 3 "immediate_operand" ""))
19668 (use (reg:CC FLAGS_REG))
19669 (clobber (match_operand 0 "register_operand" ""))
19670 (clobber (match_operand 1 "register_operand" ""))
19671 (clobber (match_operand 2 "register_operand" ""))])
19672 (set (match_operand:QI 7 "register_operand" "")
19673 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19674 (set (match_operand:QI 8 "register_operand" "")
19675 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19676 (set (reg FLAGS_REG)
19677 (compare (match_dup 7) (match_dup 8)))
19678 ]
19679 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19680 [(parallel[
19681 (set (reg:CC FLAGS_REG)
19682 (if_then_else:CC (ne (match_dup 6)
19683 (const_int 0))
19684 (compare:CC (mem:BLK (match_dup 4))
19685 (mem:BLK (match_dup 5)))
19686 (const_int 0)))
19687 (use (match_dup 3))
19688 (use (reg:CC FLAGS_REG))
19689 (clobber (match_dup 0))
19690 (clobber (match_dup 1))
19691 (clobber (match_dup 2))])]
19692 "")
19693
19694
19695 \f
19696 ;; Conditional move instructions.
19697
19698 (define_expand "movdicc"
19699 [(set (match_operand:DI 0 "register_operand" "")
19700 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19701 (match_operand:DI 2 "general_operand" "")
19702 (match_operand:DI 3 "general_operand" "")))]
19703 "TARGET_64BIT"
19704 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19705
19706 (define_insn "x86_movdicc_0_m1_rex64"
19707 [(set (match_operand:DI 0 "register_operand" "=r")
19708 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19709 (const_int -1)
19710 (const_int 0)))
19711 (clobber (reg:CC FLAGS_REG))]
19712 "TARGET_64BIT"
19713 "sbb{q}\t%0, %0"
19714 ; Since we don't have the proper number of operands for an alu insn,
19715 ; fill in all the blanks.
19716 [(set_attr "type" "alu")
19717 (set_attr "pent_pair" "pu")
19718 (set_attr "memory" "none")
19719 (set_attr "imm_disp" "false")
19720 (set_attr "mode" "DI")
19721 (set_attr "length_immediate" "0")])
19722
19723 (define_insn "*x86_movdicc_0_m1_se"
19724 [(set (match_operand:DI 0 "register_operand" "=r")
19725 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19726 (const_int 1)
19727 (const_int 0)))
19728 (clobber (reg:CC FLAGS_REG))]
19729 ""
19730 "sbb{q}\t%0, %0"
19731 [(set_attr "type" "alu")
19732 (set_attr "pent_pair" "pu")
19733 (set_attr "memory" "none")
19734 (set_attr "imm_disp" "false")
19735 (set_attr "mode" "DI")
19736 (set_attr "length_immediate" "0")])
19737
19738 (define_insn "*movdicc_c_rex64"
19739 [(set (match_operand:DI 0 "register_operand" "=r,r")
19740 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19741 [(reg FLAGS_REG) (const_int 0)])
19742 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19743 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19744 "TARGET_64BIT && TARGET_CMOVE
19745 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19746 "@
19747 cmov%O2%C1\t{%2, %0|%0, %2}
19748 cmov%O2%c1\t{%3, %0|%0, %3}"
19749 [(set_attr "type" "icmov")
19750 (set_attr "mode" "DI")])
19751
19752 (define_expand "movsicc"
19753 [(set (match_operand:SI 0 "register_operand" "")
19754 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19755 (match_operand:SI 2 "general_operand" "")
19756 (match_operand:SI 3 "general_operand" "")))]
19757 ""
19758 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19759
19760 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19761 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19762 ;; So just document what we're doing explicitly.
19763
19764 (define_insn "x86_movsicc_0_m1"
19765 [(set (match_operand:SI 0 "register_operand" "=r")
19766 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19767 (const_int -1)
19768 (const_int 0)))
19769 (clobber (reg:CC FLAGS_REG))]
19770 ""
19771 "sbb{l}\t%0, %0"
19772 ; Since we don't have the proper number of operands for an alu insn,
19773 ; fill in all the blanks.
19774 [(set_attr "type" "alu")
19775 (set_attr "pent_pair" "pu")
19776 (set_attr "memory" "none")
19777 (set_attr "imm_disp" "false")
19778 (set_attr "mode" "SI")
19779 (set_attr "length_immediate" "0")])
19780
19781 (define_insn "*x86_movsicc_0_m1_se"
19782 [(set (match_operand:SI 0 "register_operand" "=r")
19783 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19784 (const_int 1)
19785 (const_int 0)))
19786 (clobber (reg:CC FLAGS_REG))]
19787 ""
19788 "sbb{l}\t%0, %0"
19789 [(set_attr "type" "alu")
19790 (set_attr "pent_pair" "pu")
19791 (set_attr "memory" "none")
19792 (set_attr "imm_disp" "false")
19793 (set_attr "mode" "SI")
19794 (set_attr "length_immediate" "0")])
19795
19796 (define_insn "*movsicc_noc"
19797 [(set (match_operand:SI 0 "register_operand" "=r,r")
19798 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19799 [(reg FLAGS_REG) (const_int 0)])
19800 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19801 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19802 "TARGET_CMOVE
19803 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19804 "@
19805 cmov%O2%C1\t{%2, %0|%0, %2}
19806 cmov%O2%c1\t{%3, %0|%0, %3}"
19807 [(set_attr "type" "icmov")
19808 (set_attr "mode" "SI")])
19809
19810 (define_expand "movhicc"
19811 [(set (match_operand:HI 0 "register_operand" "")
19812 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19813 (match_operand:HI 2 "general_operand" "")
19814 (match_operand:HI 3 "general_operand" "")))]
19815 "TARGET_HIMODE_MATH"
19816 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19817
19818 (define_insn "*movhicc_noc"
19819 [(set (match_operand:HI 0 "register_operand" "=r,r")
19820 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19821 [(reg FLAGS_REG) (const_int 0)])
19822 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19823 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19824 "TARGET_CMOVE
19825 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19826 "@
19827 cmov%O2%C1\t{%2, %0|%0, %2}
19828 cmov%O2%c1\t{%3, %0|%0, %3}"
19829 [(set_attr "type" "icmov")
19830 (set_attr "mode" "HI")])
19831
19832 (define_expand "movqicc"
19833 [(set (match_operand:QI 0 "register_operand" "")
19834 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19835 (match_operand:QI 2 "general_operand" "")
19836 (match_operand:QI 3 "general_operand" "")))]
19837 "TARGET_QIMODE_MATH"
19838 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19839
19840 (define_insn_and_split "*movqicc_noc"
19841 [(set (match_operand:QI 0 "register_operand" "=r,r")
19842 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19843 [(match_operand 4 "flags_reg_operand" "")
19844 (const_int 0)])
19845 (match_operand:QI 2 "register_operand" "r,0")
19846 (match_operand:QI 3 "register_operand" "0,r")))]
19847 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19848 "#"
19849 "&& reload_completed"
19850 [(set (match_dup 0)
19851 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19852 (match_dup 2)
19853 (match_dup 3)))]
19854 "operands[0] = gen_lowpart (SImode, operands[0]);
19855 operands[2] = gen_lowpart (SImode, operands[2]);
19856 operands[3] = gen_lowpart (SImode, operands[3]);"
19857 [(set_attr "type" "icmov")
19858 (set_attr "mode" "SI")])
19859
19860 (define_expand "mov<mode>cc"
19861 [(set (match_operand:X87MODEF 0 "register_operand" "")
19862 (if_then_else:X87MODEF
19863 (match_operand 1 "comparison_operator" "")
19864 (match_operand:X87MODEF 2 "register_operand" "")
19865 (match_operand:X87MODEF 3 "register_operand" "")))]
19866 "(TARGET_80387 && TARGET_CMOVE)
19867 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19868 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19869
19870 (define_insn "*movsfcc_1_387"
19871 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19872 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19873 [(reg FLAGS_REG) (const_int 0)])
19874 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19875 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19876 "TARGET_80387 && TARGET_CMOVE
19877 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19878 "@
19879 fcmov%F1\t{%2, %0|%0, %2}
19880 fcmov%f1\t{%3, %0|%0, %3}
19881 cmov%O2%C1\t{%2, %0|%0, %2}
19882 cmov%O2%c1\t{%3, %0|%0, %3}"
19883 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19884 (set_attr "mode" "SF,SF,SI,SI")])
19885
19886 (define_insn "*movdfcc_1"
19887 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19888 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19889 [(reg FLAGS_REG) (const_int 0)])
19890 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19891 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19892 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19893 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19894 "@
19895 fcmov%F1\t{%2, %0|%0, %2}
19896 fcmov%f1\t{%3, %0|%0, %3}
19897 #
19898 #"
19899 [(set_attr "type" "fcmov,fcmov,multi,multi")
19900 (set_attr "mode" "DF")])
19901
19902 (define_insn "*movdfcc_1_rex64"
19903 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19904 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19905 [(reg FLAGS_REG) (const_int 0)])
19906 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19907 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19908 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19909 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19910 "@
19911 fcmov%F1\t{%2, %0|%0, %2}
19912 fcmov%f1\t{%3, %0|%0, %3}
19913 cmov%O2%C1\t{%2, %0|%0, %2}
19914 cmov%O2%c1\t{%3, %0|%0, %3}"
19915 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19916 (set_attr "mode" "DF")])
19917
19918 (define_split
19919 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19920 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19921 [(match_operand 4 "flags_reg_operand" "")
19922 (const_int 0)])
19923 (match_operand:DF 2 "nonimmediate_operand" "")
19924 (match_operand:DF 3 "nonimmediate_operand" "")))]
19925 "!TARGET_64BIT && reload_completed"
19926 [(set (match_dup 2)
19927 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19928 (match_dup 5)
19929 (match_dup 6)))
19930 (set (match_dup 3)
19931 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19932 (match_dup 7)
19933 (match_dup 8)))]
19934 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19935 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19936
19937 (define_insn "*movxfcc_1"
19938 [(set (match_operand:XF 0 "register_operand" "=f,f")
19939 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19940 [(reg FLAGS_REG) (const_int 0)])
19941 (match_operand:XF 2 "register_operand" "f,0")
19942 (match_operand:XF 3 "register_operand" "0,f")))]
19943 "TARGET_80387 && TARGET_CMOVE"
19944 "@
19945 fcmov%F1\t{%2, %0|%0, %2}
19946 fcmov%f1\t{%3, %0|%0, %3}"
19947 [(set_attr "type" "fcmov")
19948 (set_attr "mode" "XF")])
19949
19950 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19951 ;; the scalar versions to have only XMM registers as operands.
19952
19953 ;; SSE5 conditional move
19954 (define_insn "*sse5_pcmov_<mode>"
19955 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19956 (if_then_else:MODEF
19957 (match_operand:MODEF 1 "register_operand" "x,0")
19958 (match_operand:MODEF 2 "register_operand" "0,x")
19959 (match_operand:MODEF 3 "register_operand" "x,x")))]
19960 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19961 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19962 [(set_attr "type" "sse4arg")])
19963
19964 ;; These versions of the min/max patterns are intentionally ignorant of
19965 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19966 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19967 ;; are undefined in this condition, we're certain this is correct.
19968
19969 (define_insn "*avx_<code><mode>3"
19970 [(set (match_operand:MODEF 0 "register_operand" "=x")
19971 (smaxmin:MODEF
19972 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19973 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19974 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19975 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19976 [(set_attr "type" "sseadd")
19977 (set_attr "prefix" "vex")
19978 (set_attr "mode" "<MODE>")])
19979
19980 (define_insn "<code><mode>3"
19981 [(set (match_operand:MODEF 0 "register_operand" "=x")
19982 (smaxmin:MODEF
19983 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19984 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19985 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19986 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19987 [(set_attr "type" "sseadd")
19988 (set_attr "mode" "<MODE>")])
19989
19990 ;; These versions of the min/max patterns implement exactly the operations
19991 ;; min = (op1 < op2 ? op1 : op2)
19992 ;; max = (!(op1 < op2) ? op1 : op2)
19993 ;; Their operands are not commutative, and thus they may be used in the
19994 ;; presence of -0.0 and NaN.
19995
19996 (define_insn "*avx_ieee_smin<mode>3"
19997 [(set (match_operand:MODEF 0 "register_operand" "=x")
19998 (unspec:MODEF
19999 [(match_operand:MODEF 1 "register_operand" "x")
20000 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20001 UNSPEC_IEEE_MIN))]
20002 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20003 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20004 [(set_attr "type" "sseadd")
20005 (set_attr "prefix" "vex")
20006 (set_attr "mode" "<MODE>")])
20007
20008 (define_insn "*ieee_smin<mode>3"
20009 [(set (match_operand:MODEF 0 "register_operand" "=x")
20010 (unspec:MODEF
20011 [(match_operand:MODEF 1 "register_operand" "0")
20012 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20013 UNSPEC_IEEE_MIN))]
20014 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20015 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20016 [(set_attr "type" "sseadd")
20017 (set_attr "mode" "<MODE>")])
20018
20019 (define_insn "*avx_ieee_smax<mode>3"
20020 [(set (match_operand:MODEF 0 "register_operand" "=x")
20021 (unspec:MODEF
20022 [(match_operand:MODEF 1 "register_operand" "0")
20023 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20024 UNSPEC_IEEE_MAX))]
20025 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20026 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20027 [(set_attr "type" "sseadd")
20028 (set_attr "prefix" "vex")
20029 (set_attr "mode" "<MODE>")])
20030
20031 (define_insn "*ieee_smax<mode>3"
20032 [(set (match_operand:MODEF 0 "register_operand" "=x")
20033 (unspec:MODEF
20034 [(match_operand:MODEF 1 "register_operand" "0")
20035 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20036 UNSPEC_IEEE_MAX))]
20037 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20038 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20039 [(set_attr "type" "sseadd")
20040 (set_attr "mode" "<MODE>")])
20041
20042 ;; Make two stack loads independent:
20043 ;; fld aa fld aa
20044 ;; fld %st(0) -> fld bb
20045 ;; fmul bb fmul %st(1), %st
20046 ;;
20047 ;; Actually we only match the last two instructions for simplicity.
20048 (define_peephole2
20049 [(set (match_operand 0 "fp_register_operand" "")
20050 (match_operand 1 "fp_register_operand" ""))
20051 (set (match_dup 0)
20052 (match_operator 2 "binary_fp_operator"
20053 [(match_dup 0)
20054 (match_operand 3 "memory_operand" "")]))]
20055 "REGNO (operands[0]) != REGNO (operands[1])"
20056 [(set (match_dup 0) (match_dup 3))
20057 (set (match_dup 0) (match_dup 4))]
20058
20059 ;; The % modifier is not operational anymore in peephole2's, so we have to
20060 ;; swap the operands manually in the case of addition and multiplication.
20061 "if (COMMUTATIVE_ARITH_P (operands[2]))
20062 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20063 operands[0], operands[1]);
20064 else
20065 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20066 operands[1], operands[0]);")
20067
20068 ;; Conditional addition patterns
20069 (define_expand "add<mode>cc"
20070 [(match_operand:SWI 0 "register_operand" "")
20071 (match_operand 1 "comparison_operator" "")
20072 (match_operand:SWI 2 "register_operand" "")
20073 (match_operand:SWI 3 "const_int_operand" "")]
20074 ""
20075 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20076
20077 \f
20078 ;; Misc patterns (?)
20079
20080 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20081 ;; Otherwise there will be nothing to keep
20082 ;;
20083 ;; [(set (reg ebp) (reg esp))]
20084 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20085 ;; (clobber (eflags)]
20086 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20087 ;;
20088 ;; in proper program order.
20089 (define_insn "pro_epilogue_adjust_stack_1"
20090 [(set (match_operand:SI 0 "register_operand" "=r,r")
20091 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20092 (match_operand:SI 2 "immediate_operand" "i,i")))
20093 (clobber (reg:CC FLAGS_REG))
20094 (clobber (mem:BLK (scratch)))]
20095 "!TARGET_64BIT"
20096 {
20097 switch (get_attr_type (insn))
20098 {
20099 case TYPE_IMOV:
20100 return "mov{l}\t{%1, %0|%0, %1}";
20101
20102 case TYPE_ALU:
20103 if (CONST_INT_P (operands[2])
20104 && (INTVAL (operands[2]) == 128
20105 || (INTVAL (operands[2]) < 0
20106 && INTVAL (operands[2]) != -128)))
20107 {
20108 operands[2] = GEN_INT (-INTVAL (operands[2]));
20109 return "sub{l}\t{%2, %0|%0, %2}";
20110 }
20111 return "add{l}\t{%2, %0|%0, %2}";
20112
20113 case TYPE_LEA:
20114 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20115 return "lea{l}\t{%a2, %0|%0, %a2}";
20116
20117 default:
20118 gcc_unreachable ();
20119 }
20120 }
20121 [(set (attr "type")
20122 (cond [(eq_attr "alternative" "0")
20123 (const_string "alu")
20124 (match_operand:SI 2 "const0_operand" "")
20125 (const_string "imov")
20126 ]
20127 (const_string "lea")))
20128 (set_attr "mode" "SI")])
20129
20130 (define_insn "pro_epilogue_adjust_stack_rex64"
20131 [(set (match_operand:DI 0 "register_operand" "=r,r")
20132 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20133 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20134 (clobber (reg:CC FLAGS_REG))
20135 (clobber (mem:BLK (scratch)))]
20136 "TARGET_64BIT"
20137 {
20138 switch (get_attr_type (insn))
20139 {
20140 case TYPE_IMOV:
20141 return "mov{q}\t{%1, %0|%0, %1}";
20142
20143 case TYPE_ALU:
20144 if (CONST_INT_P (operands[2])
20145 /* Avoid overflows. */
20146 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20147 && (INTVAL (operands[2]) == 128
20148 || (INTVAL (operands[2]) < 0
20149 && INTVAL (operands[2]) != -128)))
20150 {
20151 operands[2] = GEN_INT (-INTVAL (operands[2]));
20152 return "sub{q}\t{%2, %0|%0, %2}";
20153 }
20154 return "add{q}\t{%2, %0|%0, %2}";
20155
20156 case TYPE_LEA:
20157 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20158 return "lea{q}\t{%a2, %0|%0, %a2}";
20159
20160 default:
20161 gcc_unreachable ();
20162 }
20163 }
20164 [(set (attr "type")
20165 (cond [(eq_attr "alternative" "0")
20166 (const_string "alu")
20167 (match_operand:DI 2 "const0_operand" "")
20168 (const_string "imov")
20169 ]
20170 (const_string "lea")))
20171 (set_attr "mode" "DI")])
20172
20173 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20174 [(set (match_operand:DI 0 "register_operand" "=r,r")
20175 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20176 (match_operand:DI 3 "immediate_operand" "i,i")))
20177 (use (match_operand:DI 2 "register_operand" "r,r"))
20178 (clobber (reg:CC FLAGS_REG))
20179 (clobber (mem:BLK (scratch)))]
20180 "TARGET_64BIT"
20181 {
20182 switch (get_attr_type (insn))
20183 {
20184 case TYPE_ALU:
20185 return "add{q}\t{%2, %0|%0, %2}";
20186
20187 case TYPE_LEA:
20188 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20189 return "lea{q}\t{%a2, %0|%0, %a2}";
20190
20191 default:
20192 gcc_unreachable ();
20193 }
20194 }
20195 [(set_attr "type" "alu,lea")
20196 (set_attr "mode" "DI")])
20197
20198 (define_insn "allocate_stack_worker_32"
20199 [(set (match_operand:SI 0 "register_operand" "+a")
20200 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
20201 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
20202 (clobber (reg:CC FLAGS_REG))]
20203 "!TARGET_64BIT && TARGET_STACK_PROBE"
20204 "call\t___chkstk"
20205 [(set_attr "type" "multi")
20206 (set_attr "length" "5")])
20207
20208 (define_insn "allocate_stack_worker_64"
20209 [(set (match_operand:DI 0 "register_operand" "+a")
20210 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
20211 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
20212 (clobber (reg:DI R10_REG))
20213 (clobber (reg:DI R11_REG))
20214 (clobber (reg:CC FLAGS_REG))]
20215 "TARGET_64BIT && TARGET_STACK_PROBE"
20216 "call\t___chkstk"
20217 [(set_attr "type" "multi")
20218 (set_attr "length" "5")])
20219
20220 (define_expand "allocate_stack"
20221 [(match_operand 0 "register_operand" "")
20222 (match_operand 1 "general_operand" "")]
20223 "TARGET_STACK_PROBE"
20224 {
20225 rtx x;
20226
20227 #ifndef CHECK_STACK_LIMIT
20228 #define CHECK_STACK_LIMIT 0
20229 #endif
20230
20231 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20232 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20233 {
20234 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20235 stack_pointer_rtx, 0, OPTAB_DIRECT);
20236 if (x != stack_pointer_rtx)
20237 emit_move_insn (stack_pointer_rtx, x);
20238 }
20239 else
20240 {
20241 x = copy_to_mode_reg (Pmode, operands[1]);
20242 if (TARGET_64BIT)
20243 x = gen_allocate_stack_worker_64 (x);
20244 else
20245 x = gen_allocate_stack_worker_32 (x);
20246 emit_insn (x);
20247 }
20248
20249 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20250 DONE;
20251 })
20252
20253 (define_expand "builtin_setjmp_receiver"
20254 [(label_ref (match_operand 0 "" ""))]
20255 "!TARGET_64BIT && flag_pic"
20256 {
20257 #if TARGET_MACHO
20258 if (TARGET_MACHO)
20259 {
20260 rtx xops[3];
20261 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20262 rtx label_rtx = gen_label_rtx ();
20263 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20264 xops[0] = xops[1] = picreg;
20265 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20266 ix86_expand_binary_operator (MINUS, SImode, xops);
20267 }
20268 else
20269 #endif
20270 emit_insn (gen_set_got (pic_offset_table_rtx));
20271 DONE;
20272 })
20273 \f
20274 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20275
20276 (define_split
20277 [(set (match_operand 0 "register_operand" "")
20278 (match_operator 3 "promotable_binary_operator"
20279 [(match_operand 1 "register_operand" "")
20280 (match_operand 2 "aligned_operand" "")]))
20281 (clobber (reg:CC FLAGS_REG))]
20282 "! TARGET_PARTIAL_REG_STALL && reload_completed
20283 && ((GET_MODE (operands[0]) == HImode
20284 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20285 /* ??? next two lines just !satisfies_constraint_K (...) */
20286 || !CONST_INT_P (operands[2])
20287 || satisfies_constraint_K (operands[2])))
20288 || (GET_MODE (operands[0]) == QImode
20289 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20290 [(parallel [(set (match_dup 0)
20291 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20292 (clobber (reg:CC FLAGS_REG))])]
20293 "operands[0] = gen_lowpart (SImode, operands[0]);
20294 operands[1] = gen_lowpart (SImode, operands[1]);
20295 if (GET_CODE (operands[3]) != ASHIFT)
20296 operands[2] = gen_lowpart (SImode, operands[2]);
20297 PUT_MODE (operands[3], SImode);")
20298
20299 ; Promote the QImode tests, as i386 has encoding of the AND
20300 ; instruction with 32-bit sign-extended immediate and thus the
20301 ; instruction size is unchanged, except in the %eax case for
20302 ; which it is increased by one byte, hence the ! optimize_size.
20303 (define_split
20304 [(set (match_operand 0 "flags_reg_operand" "")
20305 (match_operator 2 "compare_operator"
20306 [(and (match_operand 3 "aligned_operand" "")
20307 (match_operand 4 "const_int_operand" ""))
20308 (const_int 0)]))
20309 (set (match_operand 1 "register_operand" "")
20310 (and (match_dup 3) (match_dup 4)))]
20311 "! TARGET_PARTIAL_REG_STALL && reload_completed
20312 && optimize_insn_for_speed_p ()
20313 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20314 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20315 /* Ensure that the operand will remain sign-extended immediate. */
20316 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20317 [(parallel [(set (match_dup 0)
20318 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20319 (const_int 0)]))
20320 (set (match_dup 1)
20321 (and:SI (match_dup 3) (match_dup 4)))])]
20322 {
20323 operands[4]
20324 = gen_int_mode (INTVAL (operands[4])
20325 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20326 operands[1] = gen_lowpart (SImode, operands[1]);
20327 operands[3] = gen_lowpart (SImode, operands[3]);
20328 })
20329
20330 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20331 ; the TEST instruction with 32-bit sign-extended immediate and thus
20332 ; the instruction size would at least double, which is not what we
20333 ; want even with ! optimize_size.
20334 (define_split
20335 [(set (match_operand 0 "flags_reg_operand" "")
20336 (match_operator 1 "compare_operator"
20337 [(and (match_operand:HI 2 "aligned_operand" "")
20338 (match_operand:HI 3 "const_int_operand" ""))
20339 (const_int 0)]))]
20340 "! TARGET_PARTIAL_REG_STALL && reload_completed
20341 && ! TARGET_FAST_PREFIX
20342 && optimize_insn_for_speed_p ()
20343 /* Ensure that the operand will remain sign-extended immediate. */
20344 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20345 [(set (match_dup 0)
20346 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20347 (const_int 0)]))]
20348 {
20349 operands[3]
20350 = gen_int_mode (INTVAL (operands[3])
20351 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20352 operands[2] = gen_lowpart (SImode, operands[2]);
20353 })
20354
20355 (define_split
20356 [(set (match_operand 0 "register_operand" "")
20357 (neg (match_operand 1 "register_operand" "")))
20358 (clobber (reg:CC FLAGS_REG))]
20359 "! TARGET_PARTIAL_REG_STALL && reload_completed
20360 && (GET_MODE (operands[0]) == HImode
20361 || (GET_MODE (operands[0]) == QImode
20362 && (TARGET_PROMOTE_QImode
20363 || optimize_insn_for_size_p ())))"
20364 [(parallel [(set (match_dup 0)
20365 (neg:SI (match_dup 1)))
20366 (clobber (reg:CC FLAGS_REG))])]
20367 "operands[0] = gen_lowpart (SImode, operands[0]);
20368 operands[1] = gen_lowpart (SImode, operands[1]);")
20369
20370 (define_split
20371 [(set (match_operand 0 "register_operand" "")
20372 (not (match_operand 1 "register_operand" "")))]
20373 "! TARGET_PARTIAL_REG_STALL && reload_completed
20374 && (GET_MODE (operands[0]) == HImode
20375 || (GET_MODE (operands[0]) == QImode
20376 && (TARGET_PROMOTE_QImode
20377 || optimize_insn_for_size_p ())))"
20378 [(set (match_dup 0)
20379 (not:SI (match_dup 1)))]
20380 "operands[0] = gen_lowpart (SImode, operands[0]);
20381 operands[1] = gen_lowpart (SImode, operands[1]);")
20382
20383 (define_split
20384 [(set (match_operand 0 "register_operand" "")
20385 (if_then_else (match_operator 1 "comparison_operator"
20386 [(reg FLAGS_REG) (const_int 0)])
20387 (match_operand 2 "register_operand" "")
20388 (match_operand 3 "register_operand" "")))]
20389 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20390 && (GET_MODE (operands[0]) == HImode
20391 || (GET_MODE (operands[0]) == QImode
20392 && (TARGET_PROMOTE_QImode
20393 || optimize_insn_for_size_p ())))"
20394 [(set (match_dup 0)
20395 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20396 "operands[0] = gen_lowpart (SImode, operands[0]);
20397 operands[2] = gen_lowpart (SImode, operands[2]);
20398 operands[3] = gen_lowpart (SImode, operands[3]);")
20399
20400 \f
20401 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20402 ;; transform a complex memory operation into two memory to register operations.
20403
20404 ;; Don't push memory operands
20405 (define_peephole2
20406 [(set (match_operand:SI 0 "push_operand" "")
20407 (match_operand:SI 1 "memory_operand" ""))
20408 (match_scratch:SI 2 "r")]
20409 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20410 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20411 [(set (match_dup 2) (match_dup 1))
20412 (set (match_dup 0) (match_dup 2))]
20413 "")
20414
20415 (define_peephole2
20416 [(set (match_operand:DI 0 "push_operand" "")
20417 (match_operand:DI 1 "memory_operand" ""))
20418 (match_scratch:DI 2 "r")]
20419 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20420 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20421 [(set (match_dup 2) (match_dup 1))
20422 (set (match_dup 0) (match_dup 2))]
20423 "")
20424
20425 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20426 ;; SImode pushes.
20427 (define_peephole2
20428 [(set (match_operand:SF 0 "push_operand" "")
20429 (match_operand:SF 1 "memory_operand" ""))
20430 (match_scratch:SF 2 "r")]
20431 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20432 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20433 [(set (match_dup 2) (match_dup 1))
20434 (set (match_dup 0) (match_dup 2))]
20435 "")
20436
20437 (define_peephole2
20438 [(set (match_operand:HI 0 "push_operand" "")
20439 (match_operand:HI 1 "memory_operand" ""))
20440 (match_scratch:HI 2 "r")]
20441 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20442 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20443 [(set (match_dup 2) (match_dup 1))
20444 (set (match_dup 0) (match_dup 2))]
20445 "")
20446
20447 (define_peephole2
20448 [(set (match_operand:QI 0 "push_operand" "")
20449 (match_operand:QI 1 "memory_operand" ""))
20450 (match_scratch:QI 2 "q")]
20451 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20452 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20453 [(set (match_dup 2) (match_dup 1))
20454 (set (match_dup 0) (match_dup 2))]
20455 "")
20456
20457 ;; Don't move an immediate directly to memory when the instruction
20458 ;; gets too big.
20459 (define_peephole2
20460 [(match_scratch:SI 1 "r")
20461 (set (match_operand:SI 0 "memory_operand" "")
20462 (const_int 0))]
20463 "optimize_insn_for_speed_p ()
20464 && ! TARGET_USE_MOV0
20465 && TARGET_SPLIT_LONG_MOVES
20466 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20467 && peep2_regno_dead_p (0, FLAGS_REG)"
20468 [(parallel [(set (match_dup 1) (const_int 0))
20469 (clobber (reg:CC FLAGS_REG))])
20470 (set (match_dup 0) (match_dup 1))]
20471 "")
20472
20473 (define_peephole2
20474 [(match_scratch:HI 1 "r")
20475 (set (match_operand:HI 0 "memory_operand" "")
20476 (const_int 0))]
20477 "optimize_insn_for_speed_p ()
20478 && ! TARGET_USE_MOV0
20479 && TARGET_SPLIT_LONG_MOVES
20480 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20481 && peep2_regno_dead_p (0, FLAGS_REG)"
20482 [(parallel [(set (match_dup 2) (const_int 0))
20483 (clobber (reg:CC FLAGS_REG))])
20484 (set (match_dup 0) (match_dup 1))]
20485 "operands[2] = gen_lowpart (SImode, operands[1]);")
20486
20487 (define_peephole2
20488 [(match_scratch:QI 1 "q")
20489 (set (match_operand:QI 0 "memory_operand" "")
20490 (const_int 0))]
20491 "optimize_insn_for_speed_p ()
20492 && ! TARGET_USE_MOV0
20493 && TARGET_SPLIT_LONG_MOVES
20494 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20495 && peep2_regno_dead_p (0, FLAGS_REG)"
20496 [(parallel [(set (match_dup 2) (const_int 0))
20497 (clobber (reg:CC FLAGS_REG))])
20498 (set (match_dup 0) (match_dup 1))]
20499 "operands[2] = gen_lowpart (SImode, operands[1]);")
20500
20501 (define_peephole2
20502 [(match_scratch:SI 2 "r")
20503 (set (match_operand:SI 0 "memory_operand" "")
20504 (match_operand:SI 1 "immediate_operand" ""))]
20505 "optimize_insn_for_speed_p ()
20506 && TARGET_SPLIT_LONG_MOVES
20507 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20508 [(set (match_dup 2) (match_dup 1))
20509 (set (match_dup 0) (match_dup 2))]
20510 "")
20511
20512 (define_peephole2
20513 [(match_scratch:HI 2 "r")
20514 (set (match_operand:HI 0 "memory_operand" "")
20515 (match_operand:HI 1 "immediate_operand" ""))]
20516 "optimize_insn_for_speed_p ()
20517 && TARGET_SPLIT_LONG_MOVES
20518 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20519 [(set (match_dup 2) (match_dup 1))
20520 (set (match_dup 0) (match_dup 2))]
20521 "")
20522
20523 (define_peephole2
20524 [(match_scratch:QI 2 "q")
20525 (set (match_operand:QI 0 "memory_operand" "")
20526 (match_operand:QI 1 "immediate_operand" ""))]
20527 "optimize_insn_for_speed_p ()
20528 && TARGET_SPLIT_LONG_MOVES
20529 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20530 [(set (match_dup 2) (match_dup 1))
20531 (set (match_dup 0) (match_dup 2))]
20532 "")
20533
20534 ;; Don't compare memory with zero, load and use a test instead.
20535 (define_peephole2
20536 [(set (match_operand 0 "flags_reg_operand" "")
20537 (match_operator 1 "compare_operator"
20538 [(match_operand:SI 2 "memory_operand" "")
20539 (const_int 0)]))
20540 (match_scratch:SI 3 "r")]
20541 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20542 [(set (match_dup 3) (match_dup 2))
20543 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20544 "")
20545
20546 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20547 ;; Don't split NOTs with a displacement operand, because resulting XOR
20548 ;; will not be pairable anyway.
20549 ;;
20550 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20551 ;; represented using a modRM byte. The XOR replacement is long decoded,
20552 ;; so this split helps here as well.
20553 ;;
20554 ;; Note: Can't do this as a regular split because we can't get proper
20555 ;; lifetime information then.
20556
20557 (define_peephole2
20558 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20559 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20560 "optimize_insn_for_speed_p ()
20561 && ((TARGET_NOT_UNPAIRABLE
20562 && (!MEM_P (operands[0])
20563 || !memory_displacement_operand (operands[0], SImode)))
20564 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20565 && peep2_regno_dead_p (0, FLAGS_REG)"
20566 [(parallel [(set (match_dup 0)
20567 (xor:SI (match_dup 1) (const_int -1)))
20568 (clobber (reg:CC FLAGS_REG))])]
20569 "")
20570
20571 (define_peephole2
20572 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20573 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20574 "optimize_insn_for_speed_p ()
20575 && ((TARGET_NOT_UNPAIRABLE
20576 && (!MEM_P (operands[0])
20577 || !memory_displacement_operand (operands[0], HImode)))
20578 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20579 && peep2_regno_dead_p (0, FLAGS_REG)"
20580 [(parallel [(set (match_dup 0)
20581 (xor:HI (match_dup 1) (const_int -1)))
20582 (clobber (reg:CC FLAGS_REG))])]
20583 "")
20584
20585 (define_peephole2
20586 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20587 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20588 "optimize_insn_for_speed_p ()
20589 && ((TARGET_NOT_UNPAIRABLE
20590 && (!MEM_P (operands[0])
20591 || !memory_displacement_operand (operands[0], QImode)))
20592 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20593 && peep2_regno_dead_p (0, FLAGS_REG)"
20594 [(parallel [(set (match_dup 0)
20595 (xor:QI (match_dup 1) (const_int -1)))
20596 (clobber (reg:CC FLAGS_REG))])]
20597 "")
20598
20599 ;; Non pairable "test imm, reg" instructions can be translated to
20600 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20601 ;; byte opcode instead of two, have a short form for byte operands),
20602 ;; so do it for other CPUs as well. Given that the value was dead,
20603 ;; this should not create any new dependencies. Pass on the sub-word
20604 ;; versions if we're concerned about partial register stalls.
20605
20606 (define_peephole2
20607 [(set (match_operand 0 "flags_reg_operand" "")
20608 (match_operator 1 "compare_operator"
20609 [(and:SI (match_operand:SI 2 "register_operand" "")
20610 (match_operand:SI 3 "immediate_operand" ""))
20611 (const_int 0)]))]
20612 "ix86_match_ccmode (insn, CCNOmode)
20613 && (true_regnum (operands[2]) != AX_REG
20614 || satisfies_constraint_K (operands[3]))
20615 && peep2_reg_dead_p (1, operands[2])"
20616 [(parallel
20617 [(set (match_dup 0)
20618 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20619 (const_int 0)]))
20620 (set (match_dup 2)
20621 (and:SI (match_dup 2) (match_dup 3)))])]
20622 "")
20623
20624 ;; We don't need to handle HImode case, because it will be promoted to SImode
20625 ;; on ! TARGET_PARTIAL_REG_STALL
20626
20627 (define_peephole2
20628 [(set (match_operand 0 "flags_reg_operand" "")
20629 (match_operator 1 "compare_operator"
20630 [(and:QI (match_operand:QI 2 "register_operand" "")
20631 (match_operand:QI 3 "immediate_operand" ""))
20632 (const_int 0)]))]
20633 "! TARGET_PARTIAL_REG_STALL
20634 && ix86_match_ccmode (insn, CCNOmode)
20635 && true_regnum (operands[2]) != AX_REG
20636 && peep2_reg_dead_p (1, operands[2])"
20637 [(parallel
20638 [(set (match_dup 0)
20639 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20640 (const_int 0)]))
20641 (set (match_dup 2)
20642 (and:QI (match_dup 2) (match_dup 3)))])]
20643 "")
20644
20645 (define_peephole2
20646 [(set (match_operand 0 "flags_reg_operand" "")
20647 (match_operator 1 "compare_operator"
20648 [(and:SI
20649 (zero_extract:SI
20650 (match_operand 2 "ext_register_operand" "")
20651 (const_int 8)
20652 (const_int 8))
20653 (match_operand 3 "const_int_operand" ""))
20654 (const_int 0)]))]
20655 "! TARGET_PARTIAL_REG_STALL
20656 && ix86_match_ccmode (insn, CCNOmode)
20657 && true_regnum (operands[2]) != AX_REG
20658 && peep2_reg_dead_p (1, operands[2])"
20659 [(parallel [(set (match_dup 0)
20660 (match_op_dup 1
20661 [(and:SI
20662 (zero_extract:SI
20663 (match_dup 2)
20664 (const_int 8)
20665 (const_int 8))
20666 (match_dup 3))
20667 (const_int 0)]))
20668 (set (zero_extract:SI (match_dup 2)
20669 (const_int 8)
20670 (const_int 8))
20671 (and:SI
20672 (zero_extract:SI
20673 (match_dup 2)
20674 (const_int 8)
20675 (const_int 8))
20676 (match_dup 3)))])]
20677 "")
20678
20679 ;; Don't do logical operations with memory inputs.
20680 (define_peephole2
20681 [(match_scratch:SI 2 "r")
20682 (parallel [(set (match_operand:SI 0 "register_operand" "")
20683 (match_operator:SI 3 "arith_or_logical_operator"
20684 [(match_dup 0)
20685 (match_operand:SI 1 "memory_operand" "")]))
20686 (clobber (reg:CC FLAGS_REG))])]
20687 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20688 [(set (match_dup 2) (match_dup 1))
20689 (parallel [(set (match_dup 0)
20690 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20691 (clobber (reg:CC FLAGS_REG))])]
20692 "")
20693
20694 (define_peephole2
20695 [(match_scratch:SI 2 "r")
20696 (parallel [(set (match_operand:SI 0 "register_operand" "")
20697 (match_operator:SI 3 "arith_or_logical_operator"
20698 [(match_operand:SI 1 "memory_operand" "")
20699 (match_dup 0)]))
20700 (clobber (reg:CC FLAGS_REG))])]
20701 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20702 [(set (match_dup 2) (match_dup 1))
20703 (parallel [(set (match_dup 0)
20704 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20705 (clobber (reg:CC FLAGS_REG))])]
20706 "")
20707
20708 ; Don't do logical operations with memory outputs
20709 ;
20710 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20711 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20712 ; the same decoder scheduling characteristics as the original.
20713
20714 (define_peephole2
20715 [(match_scratch:SI 2 "r")
20716 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20717 (match_operator:SI 3 "arith_or_logical_operator"
20718 [(match_dup 0)
20719 (match_operand:SI 1 "nonmemory_operand" "")]))
20720 (clobber (reg:CC FLAGS_REG))])]
20721 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20722 [(set (match_dup 2) (match_dup 0))
20723 (parallel [(set (match_dup 2)
20724 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20725 (clobber (reg:CC FLAGS_REG))])
20726 (set (match_dup 0) (match_dup 2))]
20727 "")
20728
20729 (define_peephole2
20730 [(match_scratch:SI 2 "r")
20731 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20732 (match_operator:SI 3 "arith_or_logical_operator"
20733 [(match_operand:SI 1 "nonmemory_operand" "")
20734 (match_dup 0)]))
20735 (clobber (reg:CC FLAGS_REG))])]
20736 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20737 [(set (match_dup 2) (match_dup 0))
20738 (parallel [(set (match_dup 2)
20739 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20740 (clobber (reg:CC FLAGS_REG))])
20741 (set (match_dup 0) (match_dup 2))]
20742 "")
20743
20744 ;; Attempt to always use XOR for zeroing registers.
20745 (define_peephole2
20746 [(set (match_operand 0 "register_operand" "")
20747 (match_operand 1 "const0_operand" ""))]
20748 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20749 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20750 && GENERAL_REG_P (operands[0])
20751 && peep2_regno_dead_p (0, FLAGS_REG)"
20752 [(parallel [(set (match_dup 0) (const_int 0))
20753 (clobber (reg:CC FLAGS_REG))])]
20754 {
20755 operands[0] = gen_lowpart (word_mode, operands[0]);
20756 })
20757
20758 (define_peephole2
20759 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20760 (const_int 0))]
20761 "(GET_MODE (operands[0]) == QImode
20762 || GET_MODE (operands[0]) == HImode)
20763 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20764 && peep2_regno_dead_p (0, FLAGS_REG)"
20765 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20766 (clobber (reg:CC FLAGS_REG))])])
20767
20768 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20769 (define_peephole2
20770 [(set (match_operand 0 "register_operand" "")
20771 (const_int -1))]
20772 "(GET_MODE (operands[0]) == HImode
20773 || GET_MODE (operands[0]) == SImode
20774 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20775 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20776 && peep2_regno_dead_p (0, FLAGS_REG)"
20777 [(parallel [(set (match_dup 0) (const_int -1))
20778 (clobber (reg:CC FLAGS_REG))])]
20779 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20780 operands[0]);")
20781
20782 ;; Attempt to convert simple leas to adds. These can be created by
20783 ;; move expanders.
20784 (define_peephole2
20785 [(set (match_operand:SI 0 "register_operand" "")
20786 (plus:SI (match_dup 0)
20787 (match_operand:SI 1 "nonmemory_operand" "")))]
20788 "peep2_regno_dead_p (0, FLAGS_REG)"
20789 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20790 (clobber (reg:CC FLAGS_REG))])]
20791 "")
20792
20793 (define_peephole2
20794 [(set (match_operand:SI 0 "register_operand" "")
20795 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20796 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20797 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20798 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20799 (clobber (reg:CC FLAGS_REG))])]
20800 "operands[2] = gen_lowpart (SImode, operands[2]);")
20801
20802 (define_peephole2
20803 [(set (match_operand:DI 0 "register_operand" "")
20804 (plus:DI (match_dup 0)
20805 (match_operand:DI 1 "x86_64_general_operand" "")))]
20806 "peep2_regno_dead_p (0, FLAGS_REG)"
20807 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20808 (clobber (reg:CC FLAGS_REG))])]
20809 "")
20810
20811 (define_peephole2
20812 [(set (match_operand:SI 0 "register_operand" "")
20813 (mult:SI (match_dup 0)
20814 (match_operand:SI 1 "const_int_operand" "")))]
20815 "exact_log2 (INTVAL (operands[1])) >= 0
20816 && peep2_regno_dead_p (0, FLAGS_REG)"
20817 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20818 (clobber (reg:CC FLAGS_REG))])]
20819 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20820
20821 (define_peephole2
20822 [(set (match_operand:DI 0 "register_operand" "")
20823 (mult:DI (match_dup 0)
20824 (match_operand:DI 1 "const_int_operand" "")))]
20825 "exact_log2 (INTVAL (operands[1])) >= 0
20826 && peep2_regno_dead_p (0, FLAGS_REG)"
20827 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20828 (clobber (reg:CC FLAGS_REG))])]
20829 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20830
20831 (define_peephole2
20832 [(set (match_operand:SI 0 "register_operand" "")
20833 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20834 (match_operand:DI 2 "const_int_operand" "")) 0))]
20835 "exact_log2 (INTVAL (operands[2])) >= 0
20836 && REGNO (operands[0]) == REGNO (operands[1])
20837 && peep2_regno_dead_p (0, FLAGS_REG)"
20838 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20839 (clobber (reg:CC FLAGS_REG))])]
20840 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20841
20842 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20843 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20844 ;; many CPUs it is also faster, since special hardware to avoid esp
20845 ;; dependencies is present.
20846
20847 ;; While some of these conversions may be done using splitters, we use peepholes
20848 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20849
20850 ;; Convert prologue esp subtractions to push.
20851 ;; We need register to push. In order to keep verify_flow_info happy we have
20852 ;; two choices
20853 ;; - use scratch and clobber it in order to avoid dependencies
20854 ;; - use already live register
20855 ;; We can't use the second way right now, since there is no reliable way how to
20856 ;; verify that given register is live. First choice will also most likely in
20857 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20858 ;; call clobbered registers are dead. We may want to use base pointer as an
20859 ;; alternative when no register is available later.
20860
20861 (define_peephole2
20862 [(match_scratch:SI 0 "r")
20863 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20864 (clobber (reg:CC FLAGS_REG))
20865 (clobber (mem:BLK (scratch)))])]
20866 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20867 [(clobber (match_dup 0))
20868 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20869 (clobber (mem:BLK (scratch)))])])
20870
20871 (define_peephole2
20872 [(match_scratch:SI 0 "r")
20873 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20874 (clobber (reg:CC FLAGS_REG))
20875 (clobber (mem:BLK (scratch)))])]
20876 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20877 [(clobber (match_dup 0))
20878 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20879 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20880 (clobber (mem:BLK (scratch)))])])
20881
20882 ;; Convert esp subtractions to push.
20883 (define_peephole2
20884 [(match_scratch:SI 0 "r")
20885 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20886 (clobber (reg:CC FLAGS_REG))])]
20887 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20888 [(clobber (match_dup 0))
20889 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20890
20891 (define_peephole2
20892 [(match_scratch:SI 0 "r")
20893 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20894 (clobber (reg:CC FLAGS_REG))])]
20895 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20896 [(clobber (match_dup 0))
20897 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20898 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20899
20900 ;; Convert epilogue deallocator to pop.
20901 (define_peephole2
20902 [(match_scratch:SI 0 "r")
20903 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20904 (clobber (reg:CC FLAGS_REG))
20905 (clobber (mem:BLK (scratch)))])]
20906 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20907 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20908 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20909 (clobber (mem:BLK (scratch)))])]
20910 "")
20911
20912 ;; Two pops case is tricky, since pop causes dependency on destination register.
20913 ;; We use two registers if available.
20914 (define_peephole2
20915 [(match_scratch:SI 0 "r")
20916 (match_scratch:SI 1 "r")
20917 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20918 (clobber (reg:CC FLAGS_REG))
20919 (clobber (mem:BLK (scratch)))])]
20920 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20921 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20922 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20923 (clobber (mem:BLK (scratch)))])
20924 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20925 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20926 "")
20927
20928 (define_peephole2
20929 [(match_scratch:SI 0 "r")
20930 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20931 (clobber (reg:CC FLAGS_REG))
20932 (clobber (mem:BLK (scratch)))])]
20933 "optimize_insn_for_size_p ()"
20934 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20935 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20936 (clobber (mem:BLK (scratch)))])
20937 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20938 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20939 "")
20940
20941 ;; Convert esp additions to pop.
20942 (define_peephole2
20943 [(match_scratch:SI 0 "r")
20944 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20945 (clobber (reg:CC FLAGS_REG))])]
20946 ""
20947 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20948 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20949 "")
20950
20951 ;; Two pops case is tricky, since pop causes dependency on destination register.
20952 ;; We use two registers if available.
20953 (define_peephole2
20954 [(match_scratch:SI 0 "r")
20955 (match_scratch:SI 1 "r")
20956 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20957 (clobber (reg:CC FLAGS_REG))])]
20958 ""
20959 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20960 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20961 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20962 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20963 "")
20964
20965 (define_peephole2
20966 [(match_scratch:SI 0 "r")
20967 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20968 (clobber (reg:CC FLAGS_REG))])]
20969 "optimize_insn_for_size_p ()"
20970 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20971 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20972 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20973 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20974 "")
20975 \f
20976 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20977 ;; required and register dies. Similarly for 128 to -128.
20978 (define_peephole2
20979 [(set (match_operand 0 "flags_reg_operand" "")
20980 (match_operator 1 "compare_operator"
20981 [(match_operand 2 "register_operand" "")
20982 (match_operand 3 "const_int_operand" "")]))]
20983 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20984 && incdec_operand (operands[3], GET_MODE (operands[3])))
20985 || (!TARGET_FUSE_CMP_AND_BRANCH
20986 && INTVAL (operands[3]) == 128))
20987 && ix86_match_ccmode (insn, CCGCmode)
20988 && peep2_reg_dead_p (1, operands[2])"
20989 [(parallel [(set (match_dup 0)
20990 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20991 (clobber (match_dup 2))])]
20992 "")
20993 \f
20994 (define_peephole2
20995 [(match_scratch:DI 0 "r")
20996 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20997 (clobber (reg:CC FLAGS_REG))
20998 (clobber (mem:BLK (scratch)))])]
20999 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21000 [(clobber (match_dup 0))
21001 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21002 (clobber (mem:BLK (scratch)))])])
21003
21004 (define_peephole2
21005 [(match_scratch:DI 0 "r")
21006 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21007 (clobber (reg:CC FLAGS_REG))
21008 (clobber (mem:BLK (scratch)))])]
21009 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21010 [(clobber (match_dup 0))
21011 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21012 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21013 (clobber (mem:BLK (scratch)))])])
21014
21015 ;; Convert esp subtractions to push.
21016 (define_peephole2
21017 [(match_scratch:DI 0 "r")
21018 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21019 (clobber (reg:CC FLAGS_REG))])]
21020 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21021 [(clobber (match_dup 0))
21022 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21023
21024 (define_peephole2
21025 [(match_scratch:DI 0 "r")
21026 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21027 (clobber (reg:CC FLAGS_REG))])]
21028 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21029 [(clobber (match_dup 0))
21030 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21031 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21032
21033 ;; Convert epilogue deallocator to pop.
21034 (define_peephole2
21035 [(match_scratch:DI 0 "r")
21036 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21037 (clobber (reg:CC FLAGS_REG))
21038 (clobber (mem:BLK (scratch)))])]
21039 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21040 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21041 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21042 (clobber (mem:BLK (scratch)))])]
21043 "")
21044
21045 ;; Two pops case is tricky, since pop causes dependency on destination register.
21046 ;; We use two registers if available.
21047 (define_peephole2
21048 [(match_scratch:DI 0 "r")
21049 (match_scratch:DI 1 "r")
21050 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21051 (clobber (reg:CC FLAGS_REG))
21052 (clobber (mem:BLK (scratch)))])]
21053 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21054 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21055 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21056 (clobber (mem:BLK (scratch)))])
21057 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21058 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21059 "")
21060
21061 (define_peephole2
21062 [(match_scratch:DI 0 "r")
21063 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21064 (clobber (reg:CC FLAGS_REG))
21065 (clobber (mem:BLK (scratch)))])]
21066 "optimize_insn_for_size_p ()"
21067 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21068 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21069 (clobber (mem:BLK (scratch)))])
21070 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21071 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21072 "")
21073
21074 ;; Convert esp additions to pop.
21075 (define_peephole2
21076 [(match_scratch:DI 0 "r")
21077 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21078 (clobber (reg:CC FLAGS_REG))])]
21079 ""
21080 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21081 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21082 "")
21083
21084 ;; Two pops case is tricky, since pop causes dependency on destination register.
21085 ;; We use two registers if available.
21086 (define_peephole2
21087 [(match_scratch:DI 0 "r")
21088 (match_scratch:DI 1 "r")
21089 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21090 (clobber (reg:CC FLAGS_REG))])]
21091 ""
21092 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21093 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21094 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21095 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21096 "")
21097
21098 (define_peephole2
21099 [(match_scratch:DI 0 "r")
21100 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21101 (clobber (reg:CC FLAGS_REG))])]
21102 "optimize_insn_for_size_p ()"
21103 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21104 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21105 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21106 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21107 "")
21108 \f
21109 ;; Convert imul by three, five and nine into lea
21110 (define_peephole2
21111 [(parallel
21112 [(set (match_operand:SI 0 "register_operand" "")
21113 (mult:SI (match_operand:SI 1 "register_operand" "")
21114 (match_operand:SI 2 "const_int_operand" "")))
21115 (clobber (reg:CC FLAGS_REG))])]
21116 "INTVAL (operands[2]) == 3
21117 || INTVAL (operands[2]) == 5
21118 || INTVAL (operands[2]) == 9"
21119 [(set (match_dup 0)
21120 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21121 (match_dup 1)))]
21122 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21123
21124 (define_peephole2
21125 [(parallel
21126 [(set (match_operand:SI 0 "register_operand" "")
21127 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21128 (match_operand:SI 2 "const_int_operand" "")))
21129 (clobber (reg:CC FLAGS_REG))])]
21130 "optimize_insn_for_speed_p ()
21131 && (INTVAL (operands[2]) == 3
21132 || INTVAL (operands[2]) == 5
21133 || INTVAL (operands[2]) == 9)"
21134 [(set (match_dup 0) (match_dup 1))
21135 (set (match_dup 0)
21136 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21137 (match_dup 0)))]
21138 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21139
21140 (define_peephole2
21141 [(parallel
21142 [(set (match_operand:DI 0 "register_operand" "")
21143 (mult:DI (match_operand:DI 1 "register_operand" "")
21144 (match_operand:DI 2 "const_int_operand" "")))
21145 (clobber (reg:CC FLAGS_REG))])]
21146 "TARGET_64BIT
21147 && (INTVAL (operands[2]) == 3
21148 || INTVAL (operands[2]) == 5
21149 || INTVAL (operands[2]) == 9)"
21150 [(set (match_dup 0)
21151 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21152 (match_dup 1)))]
21153 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21154
21155 (define_peephole2
21156 [(parallel
21157 [(set (match_operand:DI 0 "register_operand" "")
21158 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21159 (match_operand:DI 2 "const_int_operand" "")))
21160 (clobber (reg:CC FLAGS_REG))])]
21161 "TARGET_64BIT
21162 && optimize_insn_for_speed_p ()
21163 && (INTVAL (operands[2]) == 3
21164 || INTVAL (operands[2]) == 5
21165 || INTVAL (operands[2]) == 9)"
21166 [(set (match_dup 0) (match_dup 1))
21167 (set (match_dup 0)
21168 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21169 (match_dup 0)))]
21170 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21171
21172 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21173 ;; imul $32bit_imm, reg, reg is direct decoded.
21174 (define_peephole2
21175 [(match_scratch:DI 3 "r")
21176 (parallel [(set (match_operand:DI 0 "register_operand" "")
21177 (mult:DI (match_operand:DI 1 "memory_operand" "")
21178 (match_operand:DI 2 "immediate_operand" "")))
21179 (clobber (reg:CC FLAGS_REG))])]
21180 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21181 && !satisfies_constraint_K (operands[2])"
21182 [(set (match_dup 3) (match_dup 1))
21183 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21184 (clobber (reg:CC FLAGS_REG))])]
21185 "")
21186
21187 (define_peephole2
21188 [(match_scratch:SI 3 "r")
21189 (parallel [(set (match_operand:SI 0 "register_operand" "")
21190 (mult:SI (match_operand:SI 1 "memory_operand" "")
21191 (match_operand:SI 2 "immediate_operand" "")))
21192 (clobber (reg:CC FLAGS_REG))])]
21193 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21194 && !satisfies_constraint_K (operands[2])"
21195 [(set (match_dup 3) (match_dup 1))
21196 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21197 (clobber (reg:CC FLAGS_REG))])]
21198 "")
21199
21200 (define_peephole2
21201 [(match_scratch:SI 3 "r")
21202 (parallel [(set (match_operand:DI 0 "register_operand" "")
21203 (zero_extend:DI
21204 (mult:SI (match_operand:SI 1 "memory_operand" "")
21205 (match_operand:SI 2 "immediate_operand" ""))))
21206 (clobber (reg:CC FLAGS_REG))])]
21207 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21208 && !satisfies_constraint_K (operands[2])"
21209 [(set (match_dup 3) (match_dup 1))
21210 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21211 (clobber (reg:CC FLAGS_REG))])]
21212 "")
21213
21214 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21215 ;; Convert it into imul reg, reg
21216 ;; It would be better to force assembler to encode instruction using long
21217 ;; immediate, but there is apparently no way to do so.
21218 (define_peephole2
21219 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21220 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21221 (match_operand:DI 2 "const_int_operand" "")))
21222 (clobber (reg:CC FLAGS_REG))])
21223 (match_scratch:DI 3 "r")]
21224 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21225 && satisfies_constraint_K (operands[2])"
21226 [(set (match_dup 3) (match_dup 2))
21227 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21228 (clobber (reg:CC FLAGS_REG))])]
21229 {
21230 if (!rtx_equal_p (operands[0], operands[1]))
21231 emit_move_insn (operands[0], operands[1]);
21232 })
21233
21234 (define_peephole2
21235 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21236 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21237 (match_operand:SI 2 "const_int_operand" "")))
21238 (clobber (reg:CC FLAGS_REG))])
21239 (match_scratch:SI 3 "r")]
21240 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21241 && satisfies_constraint_K (operands[2])"
21242 [(set (match_dup 3) (match_dup 2))
21243 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21244 (clobber (reg:CC FLAGS_REG))])]
21245 {
21246 if (!rtx_equal_p (operands[0], operands[1]))
21247 emit_move_insn (operands[0], operands[1]);
21248 })
21249
21250 (define_peephole2
21251 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21252 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21253 (match_operand:HI 2 "immediate_operand" "")))
21254 (clobber (reg:CC FLAGS_REG))])
21255 (match_scratch:HI 3 "r")]
21256 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21257 [(set (match_dup 3) (match_dup 2))
21258 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21259 (clobber (reg:CC FLAGS_REG))])]
21260 {
21261 if (!rtx_equal_p (operands[0], operands[1]))
21262 emit_move_insn (operands[0], operands[1]);
21263 })
21264
21265 ;; After splitting up read-modify operations, array accesses with memory
21266 ;; operands might end up in form:
21267 ;; sall $2, %eax
21268 ;; movl 4(%esp), %edx
21269 ;; addl %edx, %eax
21270 ;; instead of pre-splitting:
21271 ;; sall $2, %eax
21272 ;; addl 4(%esp), %eax
21273 ;; Turn it into:
21274 ;; movl 4(%esp), %edx
21275 ;; leal (%edx,%eax,4), %eax
21276
21277 (define_peephole2
21278 [(parallel [(set (match_operand 0 "register_operand" "")
21279 (ashift (match_operand 1 "register_operand" "")
21280 (match_operand 2 "const_int_operand" "")))
21281 (clobber (reg:CC FLAGS_REG))])
21282 (set (match_operand 3 "register_operand")
21283 (match_operand 4 "x86_64_general_operand" ""))
21284 (parallel [(set (match_operand 5 "register_operand" "")
21285 (plus (match_operand 6 "register_operand" "")
21286 (match_operand 7 "register_operand" "")))
21287 (clobber (reg:CC FLAGS_REG))])]
21288 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21289 /* Validate MODE for lea. */
21290 && ((!TARGET_PARTIAL_REG_STALL
21291 && (GET_MODE (operands[0]) == QImode
21292 || GET_MODE (operands[0]) == HImode))
21293 || GET_MODE (operands[0]) == SImode
21294 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21295 /* We reorder load and the shift. */
21296 && !rtx_equal_p (operands[1], operands[3])
21297 && !reg_overlap_mentioned_p (operands[0], operands[4])
21298 /* Last PLUS must consist of operand 0 and 3. */
21299 && !rtx_equal_p (operands[0], operands[3])
21300 && (rtx_equal_p (operands[3], operands[6])
21301 || rtx_equal_p (operands[3], operands[7]))
21302 && (rtx_equal_p (operands[0], operands[6])
21303 || rtx_equal_p (operands[0], operands[7]))
21304 /* The intermediate operand 0 must die or be same as output. */
21305 && (rtx_equal_p (operands[0], operands[5])
21306 || peep2_reg_dead_p (3, operands[0]))"
21307 [(set (match_dup 3) (match_dup 4))
21308 (set (match_dup 0) (match_dup 1))]
21309 {
21310 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21311 int scale = 1 << INTVAL (operands[2]);
21312 rtx index = gen_lowpart (Pmode, operands[1]);
21313 rtx base = gen_lowpart (Pmode, operands[3]);
21314 rtx dest = gen_lowpart (mode, operands[5]);
21315
21316 operands[1] = gen_rtx_PLUS (Pmode, base,
21317 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21318 if (mode != Pmode)
21319 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21320 operands[0] = dest;
21321 })
21322 \f
21323 ;; Call-value patterns last so that the wildcard operand does not
21324 ;; disrupt insn-recog's switch tables.
21325
21326 (define_insn "*call_value_pop_0"
21327 [(set (match_operand 0 "" "")
21328 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21329 (match_operand:SI 2 "" "")))
21330 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21331 (match_operand:SI 3 "immediate_operand" "")))]
21332 "!TARGET_64BIT"
21333 {
21334 if (SIBLING_CALL_P (insn))
21335 return "jmp\t%P1";
21336 else
21337 return "call\t%P1";
21338 }
21339 [(set_attr "type" "callv")])
21340
21341 (define_insn "*call_value_pop_1"
21342 [(set (match_operand 0 "" "")
21343 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21344 (match_operand:SI 2 "" "")))
21345 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21346 (match_operand:SI 3 "immediate_operand" "i")))]
21347 "!TARGET_64BIT"
21348 {
21349 if (constant_call_address_operand (operands[1], Pmode))
21350 {
21351 if (SIBLING_CALL_P (insn))
21352 return "jmp\t%P1";
21353 else
21354 return "call\t%P1";
21355 }
21356 if (SIBLING_CALL_P (insn))
21357 return "jmp\t%A1";
21358 else
21359 return "call\t%A1";
21360 }
21361 [(set_attr "type" "callv")])
21362
21363 (define_insn "*call_value_0"
21364 [(set (match_operand 0 "" "")
21365 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21366 (match_operand:SI 2 "" "")))]
21367 "!TARGET_64BIT"
21368 {
21369 if (SIBLING_CALL_P (insn))
21370 return "jmp\t%P1";
21371 else
21372 return "call\t%P1";
21373 }
21374 [(set_attr "type" "callv")])
21375
21376 (define_insn "*call_value_0_rex64"
21377 [(set (match_operand 0 "" "")
21378 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21379 (match_operand:DI 2 "const_int_operand" "")))]
21380 "TARGET_64BIT"
21381 {
21382 if (SIBLING_CALL_P (insn))
21383 return "jmp\t%P1";
21384 else
21385 return "call\t%P1";
21386 }
21387 [(set_attr "type" "callv")])
21388
21389 (define_insn "*call_value_1"
21390 [(set (match_operand 0 "" "")
21391 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21392 (match_operand:SI 2 "" "")))]
21393 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21394 {
21395 if (constant_call_address_operand (operands[1], Pmode))
21396 return "call\t%P1";
21397 return "call\t%A1";
21398 }
21399 [(set_attr "type" "callv")])
21400
21401 (define_insn "*sibcall_value_1"
21402 [(set (match_operand 0 "" "")
21403 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21404 (match_operand:SI 2 "" "")))]
21405 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21406 {
21407 if (constant_call_address_operand (operands[1], Pmode))
21408 return "jmp\t%P1";
21409 return "jmp\t%A1";
21410 }
21411 [(set_attr "type" "callv")])
21412
21413 (define_insn "*call_value_1_rex64"
21414 [(set (match_operand 0 "" "")
21415 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21416 (match_operand:DI 2 "" "")))]
21417 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21418 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21419 {
21420 if (constant_call_address_operand (operands[1], Pmode))
21421 return "call\t%P1";
21422 return "call\t%A1";
21423 }
21424 [(set_attr "type" "callv")])
21425
21426 (define_insn "*call_value_1_rex64_large"
21427 [(set (match_operand 0 "" "")
21428 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21429 (match_operand:DI 2 "" "")))]
21430 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21431 "call\t%A1"
21432 [(set_attr "type" "callv")])
21433
21434 (define_insn "*sibcall_value_1_rex64"
21435 [(set (match_operand 0 "" "")
21436 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21437 (match_operand:DI 2 "" "")))]
21438 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21439 "jmp\t%P1"
21440 [(set_attr "type" "callv")])
21441
21442 (define_insn "*sibcall_value_1_rex64_v"
21443 [(set (match_operand 0 "" "")
21444 (call (mem:QI (reg:DI R11_REG))
21445 (match_operand:DI 1 "" "")))]
21446 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21447 "jmp\t{*%%}r11"
21448 [(set_attr "type" "callv")])
21449 \f
21450 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21451 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21452 ;; caught for use by garbage collectors and the like. Using an insn that
21453 ;; maps to SIGILL makes it more likely the program will rightfully die.
21454 ;; Keeping with tradition, "6" is in honor of #UD.
21455 (define_insn "trap"
21456 [(trap_if (const_int 1) (const_int 6))]
21457 ""
21458 { return ASM_SHORT "0x0b0f"; }
21459 [(set_attr "length" "2")])
21460
21461 (define_expand "sse_prologue_save"
21462 [(parallel [(set (match_operand:BLK 0 "" "")
21463 (unspec:BLK [(reg:DI 21)
21464 (reg:DI 22)
21465 (reg:DI 23)
21466 (reg:DI 24)
21467 (reg:DI 25)
21468 (reg:DI 26)
21469 (reg:DI 27)
21470 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21471 (use (match_operand:DI 1 "register_operand" ""))
21472 (use (match_operand:DI 2 "immediate_operand" ""))
21473 (use (label_ref:DI (match_operand 3 "" "")))])]
21474 "TARGET_64BIT"
21475 "")
21476
21477 (define_insn "*sse_prologue_save_insn"
21478 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21479 (match_operand:DI 4 "const_int_operand" "n")))
21480 (unspec:BLK [(reg:DI 21)
21481 (reg:DI 22)
21482 (reg:DI 23)
21483 (reg:DI 24)
21484 (reg:DI 25)
21485 (reg:DI 26)
21486 (reg:DI 27)
21487 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21488 (use (match_operand:DI 1 "register_operand" "r"))
21489 (use (match_operand:DI 2 "const_int_operand" "i"))
21490 (use (label_ref:DI (match_operand 3 "" "X")))]
21491 "TARGET_64BIT
21492 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21493 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21494 {
21495 int i;
21496 operands[0] = gen_rtx_MEM (Pmode,
21497 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21498 /* VEX instruction with a REX prefix will #UD. */
21499 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21500 gcc_unreachable ();
21501
21502 output_asm_insn ("jmp\t%A1", operands);
21503 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21504 {
21505 operands[4] = adjust_address (operands[0], DImode, i*16);
21506 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21507 PUT_MODE (operands[4], TImode);
21508 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21509 output_asm_insn ("rex", operands);
21510 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21511 }
21512 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21513 CODE_LABEL_NUMBER (operands[3]));
21514 return "";
21515 }
21516 [(set_attr "type" "other")
21517 (set_attr "length_immediate" "0")
21518 (set_attr "length_address" "0")
21519 (set (attr "length")
21520 (if_then_else
21521 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21522 (const_string "34")
21523 (const_string "42")))
21524 (set_attr "memory" "store")
21525 (set_attr "modrm" "0")
21526 (set_attr "prefix" "maybe_vex")
21527 (set_attr "mode" "DI")])
21528
21529 (define_expand "prefetch"
21530 [(prefetch (match_operand 0 "address_operand" "")
21531 (match_operand:SI 1 "const_int_operand" "")
21532 (match_operand:SI 2 "const_int_operand" ""))]
21533 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21534 {
21535 int rw = INTVAL (operands[1]);
21536 int locality = INTVAL (operands[2]);
21537
21538 gcc_assert (rw == 0 || rw == 1);
21539 gcc_assert (locality >= 0 && locality <= 3);
21540 gcc_assert (GET_MODE (operands[0]) == Pmode
21541 || GET_MODE (operands[0]) == VOIDmode);
21542
21543 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21544 supported by SSE counterpart or the SSE prefetch is not available
21545 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21546 of locality. */
21547 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21548 operands[2] = GEN_INT (3);
21549 else
21550 operands[1] = const0_rtx;
21551 })
21552
21553 (define_insn "*prefetch_sse"
21554 [(prefetch (match_operand:SI 0 "address_operand" "p")
21555 (const_int 0)
21556 (match_operand:SI 1 "const_int_operand" ""))]
21557 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21558 {
21559 static const char * const patterns[4] = {
21560 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21561 };
21562
21563 int locality = INTVAL (operands[1]);
21564 gcc_assert (locality >= 0 && locality <= 3);
21565
21566 return patterns[locality];
21567 }
21568 [(set_attr "type" "sse")
21569 (set_attr "memory" "none")])
21570
21571 (define_insn "*prefetch_sse_rex"
21572 [(prefetch (match_operand:DI 0 "address_operand" "p")
21573 (const_int 0)
21574 (match_operand:SI 1 "const_int_operand" ""))]
21575 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21576 {
21577 static const char * const patterns[4] = {
21578 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21579 };
21580
21581 int locality = INTVAL (operands[1]);
21582 gcc_assert (locality >= 0 && locality <= 3);
21583
21584 return patterns[locality];
21585 }
21586 [(set_attr "type" "sse")
21587 (set_attr "memory" "none")])
21588
21589 (define_insn "*prefetch_3dnow"
21590 [(prefetch (match_operand:SI 0 "address_operand" "p")
21591 (match_operand:SI 1 "const_int_operand" "n")
21592 (const_int 3))]
21593 "TARGET_3DNOW && !TARGET_64BIT"
21594 {
21595 if (INTVAL (operands[1]) == 0)
21596 return "prefetch\t%a0";
21597 else
21598 return "prefetchw\t%a0";
21599 }
21600 [(set_attr "type" "mmx")
21601 (set_attr "memory" "none")])
21602
21603 (define_insn "*prefetch_3dnow_rex"
21604 [(prefetch (match_operand:DI 0 "address_operand" "p")
21605 (match_operand:SI 1 "const_int_operand" "n")
21606 (const_int 3))]
21607 "TARGET_3DNOW && TARGET_64BIT"
21608 {
21609 if (INTVAL (operands[1]) == 0)
21610 return "prefetch\t%a0";
21611 else
21612 return "prefetchw\t%a0";
21613 }
21614 [(set_attr "type" "mmx")
21615 (set_attr "memory" "none")])
21616
21617 (define_expand "stack_protect_set"
21618 [(match_operand 0 "memory_operand" "")
21619 (match_operand 1 "memory_operand" "")]
21620 ""
21621 {
21622 #ifdef TARGET_THREAD_SSP_OFFSET
21623 if (TARGET_64BIT)
21624 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21625 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21626 else
21627 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21628 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21629 #else
21630 if (TARGET_64BIT)
21631 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21632 else
21633 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21634 #endif
21635 DONE;
21636 })
21637
21638 (define_insn "stack_protect_set_si"
21639 [(set (match_operand:SI 0 "memory_operand" "=m")
21640 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21641 (set (match_scratch:SI 2 "=&r") (const_int 0))
21642 (clobber (reg:CC FLAGS_REG))]
21643 ""
21644 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21645 [(set_attr "type" "multi")])
21646
21647 (define_insn "stack_protect_set_di"
21648 [(set (match_operand:DI 0 "memory_operand" "=m")
21649 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21650 (set (match_scratch:DI 2 "=&r") (const_int 0))
21651 (clobber (reg:CC FLAGS_REG))]
21652 "TARGET_64BIT"
21653 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21654 [(set_attr "type" "multi")])
21655
21656 (define_insn "stack_tls_protect_set_si"
21657 [(set (match_operand:SI 0 "memory_operand" "=m")
21658 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21659 (set (match_scratch:SI 2 "=&r") (const_int 0))
21660 (clobber (reg:CC FLAGS_REG))]
21661 ""
21662 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21663 [(set_attr "type" "multi")])
21664
21665 (define_insn "stack_tls_protect_set_di"
21666 [(set (match_operand:DI 0 "memory_operand" "=m")
21667 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21668 (set (match_scratch:DI 2 "=&r") (const_int 0))
21669 (clobber (reg:CC FLAGS_REG))]
21670 "TARGET_64BIT"
21671 {
21672 /* The kernel uses a different segment register for performance reasons; a
21673 system call would not have to trash the userspace segment register,
21674 which would be expensive */
21675 if (ix86_cmodel != CM_KERNEL)
21676 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21677 else
21678 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21679 }
21680 [(set_attr "type" "multi")])
21681
21682 (define_expand "stack_protect_test"
21683 [(match_operand 0 "memory_operand" "")
21684 (match_operand 1 "memory_operand" "")
21685 (match_operand 2 "" "")]
21686 ""
21687 {
21688 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21689 ix86_compare_op0 = operands[0];
21690 ix86_compare_op1 = operands[1];
21691 ix86_compare_emitted = flags;
21692
21693 #ifdef TARGET_THREAD_SSP_OFFSET
21694 if (TARGET_64BIT)
21695 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21696 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21697 else
21698 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21699 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21700 #else
21701 if (TARGET_64BIT)
21702 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21703 else
21704 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21705 #endif
21706 emit_jump_insn (gen_beq (operands[2]));
21707 DONE;
21708 })
21709
21710 (define_insn "stack_protect_test_si"
21711 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21712 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21713 (match_operand:SI 2 "memory_operand" "m")]
21714 UNSPEC_SP_TEST))
21715 (clobber (match_scratch:SI 3 "=&r"))]
21716 ""
21717 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21718 [(set_attr "type" "multi")])
21719
21720 (define_insn "stack_protect_test_di"
21721 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21722 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21723 (match_operand:DI 2 "memory_operand" "m")]
21724 UNSPEC_SP_TEST))
21725 (clobber (match_scratch:DI 3 "=&r"))]
21726 "TARGET_64BIT"
21727 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21728 [(set_attr "type" "multi")])
21729
21730 (define_insn "stack_tls_protect_test_si"
21731 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21732 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21733 (match_operand:SI 2 "const_int_operand" "i")]
21734 UNSPEC_SP_TLS_TEST))
21735 (clobber (match_scratch:SI 3 "=r"))]
21736 ""
21737 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21738 [(set_attr "type" "multi")])
21739
21740 (define_insn "stack_tls_protect_test_di"
21741 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21742 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21743 (match_operand:DI 2 "const_int_operand" "i")]
21744 UNSPEC_SP_TLS_TEST))
21745 (clobber (match_scratch:DI 3 "=r"))]
21746 "TARGET_64BIT"
21747 {
21748 /* The kernel uses a different segment register for performance reasons; a
21749 system call would not have to trash the userspace segment register,
21750 which would be expensive */
21751 if (ix86_cmodel != CM_KERNEL)
21752 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21753 else
21754 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21755 }
21756 [(set_attr "type" "multi")])
21757
21758 (define_mode_iterator CRC32MODE [QI HI SI])
21759 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21760 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21761
21762 (define_insn "sse4_2_crc32<mode>"
21763 [(set (match_operand:SI 0 "register_operand" "=r")
21764 (unspec:SI
21765 [(match_operand:SI 1 "register_operand" "0")
21766 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21767 UNSPEC_CRC32))]
21768 "TARGET_SSE4_2"
21769 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21770 [(set_attr "type" "sselog1")
21771 (set_attr "prefix_rep" "1")
21772 (set_attr "prefix_extra" "1")
21773 (set_attr "mode" "SI")])
21774
21775 (define_insn "sse4_2_crc32di"
21776 [(set (match_operand:DI 0 "register_operand" "=r")
21777 (unspec:DI
21778 [(match_operand:DI 1 "register_operand" "0")
21779 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21780 UNSPEC_CRC32))]
21781 "TARGET_SSE4_2 && TARGET_64BIT"
21782 "crc32q\t{%2, %0|%0, %2}"
21783 [(set_attr "type" "sselog1")
21784 (set_attr "prefix_rep" "1")
21785 (set_attr "prefix_extra" "1")
21786 (set_attr "mode" "DI")])
21787
21788 (include "mmx.md")
21789 (include "sse.md")
21790 (include "sync.md")
This page took 1.042224 seconds and 5 git commands to generate.